You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
8.9 KiB

/*
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 <windows.h>
#include <lm.h>
#include <time.h>
#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;
}