/* Copyright (C) 2003 Olaf Flebbe, Science and Computing AG o.flebbe@science-computing.de Copyright (C) 2013 Timothy Pearson, Northern Illinois University kb9vqf@pearsoncomputing.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define WINDOWS_MEAN_AND_LEAN #define UNICODE #include #include #include #include "netusergroup.h" int addUserToGroup( const mystring& userName, const mystring& groupName) { if (addGroup( groupName)) { return 1; } LOCALGROUP_MEMBERS_INFO_3 gmember; gmember.lgrmi3_domainandname = (LPWSTR) userName.c_str(); int ret = NetLocalGroupAddMembers( NULL, groupName.c_str(), 3, (LPBYTE )&gmember, 1); if (!(ret == NERR_Success || ret == ERROR_MEMBER_IN_ALIAS)) return 1; return 0; } int delUserFromGroup( const mystring& userName, const mystring& groupName) { LOCALGROUP_MEMBERS_INFO_3 gmember; gmember.lgrmi3_domainandname = (LPWSTR) userName.c_str(); int ret = NetLocalGroupDelMembers( NULL, groupName.c_str(), 3, (LPBYTE )&gmember, 1); if (!(ret == NERR_Success || ret == ERROR_MEMBER_IN_ALIAS)) return 1; return 0; } int addGroup( const mystring& groupName) { LOCALGROUP_INFO_0 gent; gent.lgrpi0_name = _wcsdup( groupName.c_str()); int ret = NetLocalGroupAdd( NULL, 0, (LPBYTE )&gent, NULL); free( gent.lgrpi0_name); if (!(ret == NERR_Success || ret == NERR_GroupExists || ret == ERROR_ALIAS_EXISTS)) { return 1; } return 0; } int addUser( const mystring& userName) { USER_INFO_1 ui; ui.usri1_name = (LPWSTR) userName.c_str(); ui.usri1_password = L"xyzzy"; ui.usri1_flags = UF_SCRIPT | UF_PASSWD_CANT_CHANGE | UF_ACCOUNTDISABLE; ui.usri1_script_path = NULL; ui.usri1_priv = USER_PRIV_USER; ui.usri1_comment = NULL; ui.usri1_home_dir = NULL; ui.usri1_password_age = 0; int ret = NetUserAdd( NULL,1, (LPBYTE )&ui, NULL); return (!(ret == NERR_Success || ret == NERR_UserExists)); } int addUser( const mystring& userName, const mystring& password, const mystring& homepath, const mystring& homedrive, const mystring& profile, const mystring& script) { USER_INFO_4 ui; /* INFO_3 für 2000? */ memset( &ui, 0, sizeof( ui)); ui.usri4_name = (LPWSTR) userName.c_str(); ui.usri4_password = (LPWSTR) password.c_str(); ui.usri4_priv = USER_PRIV_USER; ui.usri4_home_dir = (LPWSTR) homepath.c_str(); ui.usri4_flags = UF_SCRIPT | UF_PASSWD_CANT_CHANGE | UF_ACCOUNTDISABLE; ui.usri4_script_path = (LPWSTR) script.c_str(); ui.usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; ui.usri4_country_code = 0; /* Arghhh! not documented*/ ui.usri4_code_page = 1252; ui.usri4_primary_group_id = DOMAIN_GROUP_RID_USERS; ui.usri4_profile = (LPWSTR) profile.c_str(); ui.usri4_home_dir_drive = (LPWSTR) homedrive.c_str(); int ret = NetUserAdd( NULL, 4, (LPBYTE )&ui, NULL); return (!(ret == NERR_Success || ret == NERR_UserExists)); } int modifyUser( const mystring& userName, const mystring& password, const mystring& homepath, const mystring& homedrive, const mystring& profile, const mystring& script) { LPUSER_INFO_4 ui = NULL; if (NERR_Success == NetUserGetInfo( NULL, userName.c_str(), 4, (LPBYTE *)&ui)) { ui->usri4_name = (LPWSTR) userName.c_str(); ui->usri4_home_dir = (LPWSTR) homepath.c_str(); ui->usri4_script_path = (LPWSTR) script.c_str(); ui->usri4_profile = (LPWSTR) profile.c_str(); ui->usri4_home_dir_drive = (LPWSTR) homedrive.c_str(); int ret = NetUserSetInfo( NULL, userName.c_str(), 4, (LPBYTE )ui, NULL); return (!(ret == NERR_Success || ret == NERR_UserExists)); } else { return 1; } } int resetAccountExpiry( const mystring& userName, const mystring& password, FILE *fp) { if (fp) { fprintf( fp, "resetting account expiration for user '%S'\n", userName.c_str()); fflush(fp); } LPUSER_INFO_4 ui = NULL; if (NERR_Success == NetUserGetInfo( NULL, userName.c_str(), 4, (LPBYTE *)&ui)) { ui->usri4_acct_expires = (DWORD)time(0) + 10; /* only allow login for up to 10 seconds after Kerberized authentication */ //ui->usri4_acct_expires = TIMEQ_FOREVER; ui->usri4_password = (LPWSTR) password.c_str(); ui->usri4_flags = (ui->usri4_flags & (~UF_ACCOUNTDISABLE)); /* ensure account is enabled */ int ret = NetUserSetInfo( NULL, userName.c_str(), 4, (LPBYTE )ui, NULL); if (fp) { fprintf( fp, "new time %d: commit returned %d\n", ui->usri4_acct_expires, ret); fflush(fp); } return (!(ret == NERR_Success || ret == NERR_UserExists)); } else { return 1; } } // return 1: User exists and disabled // return 0: User exists and enabled // return -1: User does not exist int isDisabledUser( const mystring& userName) { // This API is sick LPUSER_INFO_1 ui = NULL; int flag = -1; if (NERR_Success == NetUserGetInfo( NULL, userName.c_str(), 1, (LPBYTE *)&ui)) { flag = (ui->usri1_flags & UF_ACCOUNTDISABLE) == UF_ACCOUNTDISABLE; } if (ui != NULL) NetApiBufferFree( ui); return flag; } int delUser( const mystring& userName) { return NetUserDel( NULL, userName.c_str()); } stringSet listGroups( const mystring& user) { LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; LPLOCALGROUP_USERS_INFO_0 pTmpBuf; DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; DWORD i; DWORD dwTotalCount = 0; NET_API_STATUS nStatus; stringSet groupList; do { if (pBuf != NULL) { NetApiBufferFree(pBuf); pBuf = NULL; } nStatus = NetUserGetLocalGroups( NULL, user.c_str(), 0, 0, (LPBYTE*)&pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); dwPrefMaxLen = dwTotalEntries; // TODO: Endless loop possible? } while (nStatus == ERROR_MORE_DATA); // // If the call succeeds, // if (nStatus == NERR_Success) { if ((pTmpBuf = pBuf) != NULL) { // // Loop through the entries. // for (i = 0; (i < dwEntriesRead); i++) { groupList.insert( mystring( pTmpBuf->lgrui0_name)); pTmpBuf++; } } else return groupList; } // // Free the allocated buffer. // if (pBuf != NULL) { NetApiBufferFree(pBuf); pBuf = NULL; } return groupList; } stringSet listUsers() { LPUSER_INFO_0 pBuf = NULL; LPUSER_INFO_0 pTmpBuf; DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; DWORD dwResumeHandle = 0; DWORD i; DWORD dwTotalCount = 0; NET_API_STATUS nStatus; stringSet userList; // // Call the NetUserEnum function, specifying level 0; // enumerate global user account types only. // do // begin do { if (pBuf != NULL) { NetApiBufferFree(pBuf); pBuf = NULL; } nStatus = NetUserEnum( NULL, 0, FILTER_NORMAL_ACCOUNT, // global users (LPBYTE*)&pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); // // If the call succeeds, // if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) { if ((pTmpBuf = pBuf) != NULL) { // // Loop through the entries. // for (i = 0; (i < dwEntriesRead); i++) { userList.insert( mystring( pTmpBuf->usri0_name)); pTmpBuf++; dwTotalCount++; } } } else return userList; // // Free the allocated buffer. // if (pBuf != NULL) { NetApiBufferFree(pBuf); pBuf = NULL; } } // Continue to call NetUserEnum while // there are more entries. // while (nStatus == ERROR_MORE_DATA); // end do // // Check again for allocated memory. // if (pBuf != NULL) NetApiBufferFree(pBuf); return userList; }