|
|
#include "stdafx.h"
#include "svc.h"
#include "setuser.h"
#include "dcomperm.h"
#ifndef _CHICAGO_
int GetGuestUserName_SlowWay(LPWSTR lpGuestUsrName) { LPWSTR ServerName = NULL; // default to local machine
DWORD Level = 1; // to retrieve info of all local and global normal user accounts
DWORD Index = 0; DWORD EntriesRequested = 5; DWORD PreferredMaxLength = 1024; DWORD ReturnedEntryCount = 0; PVOID SortedBuffer = NULL; NET_DISPLAY_USER *p = NULL; DWORD i=0; int err = 0; BOOL fStatus = TRUE;
while (fStatus) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetQueryDisplayInformation().Start."))); err = NetQueryDisplayInformation(ServerName, Level, Index, EntriesRequested, PreferredMaxLength, &ReturnedEntryCount, &SortedBuffer); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetQueryDisplayInformation().End."))); if (err == NERR_Success) fStatus = FALSE; if (err == NERR_Success || err == ERROR_MORE_DATA) { p = (NET_DISPLAY_USER *)SortedBuffer; i = 0; while (i < ReturnedEntryCount && (p[i].usri1_user_id != DOMAIN_USER_RID_GUEST)) i++; if (i == ReturnedEntryCount) { if (err == ERROR_MORE_DATA) { // need to get more entries
Index = p[i-1].usri1_next_index; } } else { wcscpy(lpGuestUsrName, p[i].usri1_name); fStatus = FALSE; } } iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start."))); NetApiBufferFree(SortedBuffer); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End."))); }
return 0; }
int GetGuestGrpName(LPTSTR lpGuestGrpName) { LPCTSTR ServerName = NULL; // local machine
DWORD cbName = UNLEN+1; TCHAR ReferencedDomainName[200]; DWORD cbReferencedDomainName = sizeof(ReferencedDomainName); SID_NAME_USE sidNameUse = SidTypeUser;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; PSID GuestsSid = NULL;
AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS,0,0,0,0,0,0, &GuestsSid);
LookupAccountSid(ServerName, GuestsSid, lpGuestGrpName, &cbName, ReferencedDomainName, &cbReferencedDomainName, &sidNameUse);
if (GuestsSid) FreeSid(GuestsSid);
return 0; }
void InitLsaString(PLSA_UNICODE_STRING LsaString,LPWSTR String) { DWORD StringLength; if (String == NULL) { LsaString->Buffer = NULL; LsaString->Length = 0; LsaString->MaximumLength = 0; return; } StringLength = wcslen(String); LsaString->Buffer = String; LsaString->Length = (USHORT) StringLength * sizeof(WCHAR); LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR); }
DWORD OpenPolicy(LPTSTR ServerName,DWORD DesiredAccess,PLSA_HANDLE PolicyHandle) { DWORD Error; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_UNICODE_STRING ServerString; PLSA_UNICODE_STRING Server = NULL; SECURITY_QUALITY_OF_SERVICE QualityOfService;
QualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); QualityOfService.ImpersonationLevel = SecurityImpersonation; QualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; QualityOfService.EffectiveOnly = FALSE;
//
// The two fields that must be set are length and the quality of service.
//
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory = NULL; ObjectAttributes.ObjectName = NULL; ObjectAttributes.Attributes = 0; ObjectAttributes.SecurityDescriptor = NULL; ObjectAttributes.SecurityQualityOfService = &QualityOfService;
if (ServerName != NULL) { //
// Make a LSA_UNICODE_STRING out of the LPWSTR passed in
//
InitLsaString(&ServerString,ServerName); Server = &ServerString; } //
// Attempt to open the policy for all access
//
Error = LsaOpenPolicy(Server,&ObjectAttributes,DesiredAccess,PolicyHandle); return(Error);
}
INT RegisterAccountToLocalGroup(LPCTSTR szAccountName, LPCTSTR szLocalGroupName, BOOL fAction) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("RegisterAccountToLocalGroup:Action=%d,Account=%s\n"), fAction, szAccountName));
int err;
// get the sid of szAccountName
PSID pSID = NULL; BOOL bWellKnownSID = FALSE; err = GetPrincipalSID ((LPTSTR)szAccountName, &pSID, &bWellKnownSID); if (err != ERROR_SUCCESS) { iisDebugOut((LOG_TYPE_ERROR, _T("RegisterAccountToLocalGroup:GetPrincipalSID:fAction=%d, Account=%s, Group=%s, err=%d.\n"), fAction, szAccountName, szLocalGroupName, err)); return (err); }
// Get the localized LocalGroupName
TCHAR szLocalizedLocalGroupName[GNLEN + 1]; if (_tcsicmp(szLocalGroupName, _T("Guests")) == 0) { GetGuestGrpName(szLocalizedLocalGroupName); } else { _tcscpy(szLocalizedLocalGroupName, szLocalGroupName); } // transfer szLocalGroupName to WCHAR
WCHAR wszLocalGroupName[_MAX_PATH]; #if defined(UNICODE) || defined(_UNICODE)
_tcscpy(wszLocalGroupName, szLocalizedLocalGroupName); #else
MultiByteToWideChar( CP_ACP, 0, szLocalizedLocalGroupName, -1, wszLocalGroupName, _MAX_PATH); #endif
LOCALGROUP_MEMBERS_INFO_0 buf;
buf.lgrmi0_sid = pSID;
if (fAction) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetLocalGroupAddMembers().Start."))); err = NetLocalGroupAddMembers(NULL, wszLocalGroupName, 0, (LPBYTE)&buf, 1); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetLocalGroupAddMembers().End."))); } else { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetLocalGroupDelMembers().Start."))); err = NetLocalGroupDelMembers(NULL, wszLocalGroupName, 0, (LPBYTE)&buf, 1); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetLocalGroupDelMembers().End."))); }
iisDebugOut((LOG_TYPE_TRACE, _T("RegisterAccountToLocalGroup:fAction=%d, Account=%s, Group=%s, err=%d.\n"), fAction, szAccountName, szLocalGroupName, err));
if (pSID) { if (bWellKnownSID) FreeSid (pSID); else free (pSID); }
return (err); }
INT RegisterAccountUserRights(LPCTSTR szAccountName, BOOL fAction, BOOL fSpecicaliwamaccount) { iisDebugOut((LOG_TYPE_TRACE, _T("RegisterAccountUserRights:Action=%d,Account=%s,iwam=%d\n"), fAction, szAccountName,fSpecicaliwamaccount));
int err;
// get the sid of szAccountName
PSID pSID = NULL; BOOL bWellKnownSID = FALSE; err = GetPrincipalSID ((LPTSTR)szAccountName, &pSID, &bWellKnownSID); if (err != ERROR_SUCCESS) { iisDebugOut((LOG_TYPE_ERROR, _T("RegisterAccountUserRights:GetPrincipalSID:fAction=%d, Account=%s, err=%d.\n"), fAction, szAccountName, err)); return (err); }
LSA_UNICODE_STRING UserRightString; LSA_HANDLE PolicyHandle = NULL;
err = OpenPolicy(NULL, POLICY_ALL_ACCESS,&PolicyHandle); if ( err == NERR_Success ) { if (fAction) { // defined in ntsecapi.h and ntlsa.h
//#define SE_INTERACTIVE_LOGON_NAME TEXT("SeInteractiveLogonRight")
//#define SE_NETWORK_LOGON_NAME TEXT("SeNetworkLogonRight")
//#define SE_BATCH_LOGON_NAME TEXT("SeBatchLogonRight")
//#define SE_SERVICE_LOGON_NAME TEXT("SeServiceLogonRight")
// Defined in winnt.h
//#define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege")
//#define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege")
//#define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege")
//#define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege")
//#define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege")
//#define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege")
//#define SE_TCB_NAME TEXT("SeTcbPrivilege")
//#define SE_SECURITY_NAME TEXT("SeSecurityPrivilege")
//#define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege")
//#define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege")
//#define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege")
//#define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege")
//#define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege")
//#define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege")
//#define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege")
//#define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege")
//#define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
//#define SE_RESTORE_NAME TEXT("SeRestorePrivilege")
//#define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")
//#define SE_DEBUG_NAME TEXT("SeDebugPrivilege")
//#define SE_AUDIT_NAME TEXT("SeAuditPrivilege")
//#define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege")
//#define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege")
//#define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege")
//#define SE_UNDOCK_NAME TEXT("SeUndockPrivilege")
//#define SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege")
//#define SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege")
if (fSpecicaliwamaccount) { InitLsaString(&UserRightString, SE_NETWORK_LOGON_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
// For NT5 -- the Iwam account will not have a ton of priveleges like was first decided.
// for security reasons it was trimmed.
InitLsaString(&UserRightString, SE_BATCH_LOGON_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
// For NT51 (Whistler)
// iwam should have additional rights, per bug277113 "SeAssignPrimaryTokenPrivilege","SeIncreaseQuotaPrivilege"
InitLsaString(&UserRightString, SE_ASSIGNPRIMARYTOKEN_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
InitLsaString(&UserRightString, SE_INCREASE_QUOTA_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
/* Old stuff that was taken out post NT5 Beta3
// Per Bug 291206 - IWAM account should not have the "log on locally" right, as it currently does
// So make sure it is not there -- since this is a potential security hole!
InitLsaString(&UserRightString, SE_INTERACTIVE_LOGON_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} // stuff for nt5 Beta3
InitLsaString(&UserRightString, SE_TCB_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_CREATE_PAGEFILE_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_CREATE_TOKEN_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_CREATE_PERMANENT_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_DEBUG_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_AUDIT_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_INCREASE_QUOTA_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_INC_BASE_PRIORITY_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_LOAD_DRIVER_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_LOCK_MEMORY_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_SYSTEM_ENVIRONMENT_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_PROF_SINGLE_PROCESS_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_ASSIGNPRIMARYTOKEN_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} */ } else { InitLsaString(&UserRightString, SE_INTERACTIVE_LOGON_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_NETWORK_LOGON_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} InitLsaString(&UserRightString, SE_BATCH_LOGON_NAME); err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1); if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));} } } else { InitLsaString(&UserRightString, SE_INTERACTIVE_LOGON_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_NETWORK_LOGON_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_BATCH_LOGON_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_ASSIGNPRIMARYTOKEN_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_INCREASE_QUOTA_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
/* Old stuff that was taken out post NT5 Beta3
// if special iwam account or not, let's remove these rights from the iusr or iwam user
InitLsaString(&UserRightString, SE_TCB_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_CREATE_PAGEFILE_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_CREATE_TOKEN_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_CREATE_PERMANENT_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_DEBUG_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_AUDIT_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_INCREASE_QUOTA_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_INC_BASE_PRIORITY_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_LOAD_DRIVER_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_LOCK_MEMORY_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_SYSTEM_ENVIRONMENT_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_PROF_SINGLE_PROCESS_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); InitLsaString(&UserRightString, SE_ASSIGNPRIMARYTOKEN_NAME); err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1); */ }
LsaClose(PolicyHandle); } else { iisDebugOut((LOG_TYPE_TRACE, _T("RegisterAccountUserRights:Action=%d,Account=%s,iwam=%d,err=0x%x\n"), fAction, szAccountName,fSpecicaliwamaccount,err)); }
if (pSID) { if (bWellKnownSID) FreeSid (pSID); else free (pSID); }
if (err) { iisDebugOut((LOG_TYPE_TRACE, _T("RegisterAccountUserRights:Action=%d,Account=%s,iwam=%d,err=0x%x\n"), fAction, szAccountName,fSpecicaliwamaccount,err)); } return (err); }
BOOL IsUserExist( LPWSTR strUsername ) { BYTE *pBuffer; INT err = NERR_Success; do { WCHAR *pMachineName = NULL;
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().Start."))); err = NetServerGetInfo( NULL, 101, &pBuffer ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().End."))); // make sure we are not backup docmain first
if (err != NERR_Success ) { // if this call returns that the service is not running, then let's just assume that the user does exist!!!!
if (err == NERR_ServerNotStarted) { // Try to start the server service.
err = InetStartService(_T("LanmanServer")); if (err == 0 || err == ERROR_SERVICE_ALREADY_RUNNING) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().Start."))); err = NetServerGetInfo( NULL, 101, &pBuffer ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().End."))); if (err != NERR_Success ) { if (err == NERR_ServerNotStarted) { iisDebugOut((LOG_TYPE_WARN, _T("NetServerGetInfo:failed.The Server service is not started. assume that %s exists.err=0x%x.\n"),strUsername,err)); err = NERR_Success; } } } else { iisDebugOut((LOG_TYPE_ERROR, _T("NetServerGetInfo:failed.The Server service is not started. assume that %s exists.err=0x%x.\n"),strUsername,err)); err = NERR_Success; } } else { iisDebugOut((LOG_TYPE_ERROR, _T("NetServerGetInfo:failed.Do not call this on PDC or BDC takes too long.This must be a PDC or BDC.err=0x%x.\n"),err)); } break; }
LPSERVER_INFO_101 pInfo = (LPSERVER_INFO_101)pBuffer; if (( pInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL ) != 0 ) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetGetDCName().Start."))); NetGetDCName( NULL, NULL, (LPBYTE*)&pMachineName ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetGetDCName().End."))); }
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start."))); NetApiBufferFree( pBuffer ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
if (pMachineName){iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NetUserGetInfo:[%s\\%s].Start.\n"),pMachineName,strUsername));} else{iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NetUserGetInfo:[(null)\\%s].Start.\n"),strUsername));} iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetUserGetInfo().Start."))); err = NetUserGetInfo( pMachineName, strUsername, 3, &pBuffer ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetUserGetInfo().End.")));
if (pMachineName){iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NetUserGetInfo:[%s\\%s].End.Ret=0x%x.\n"),pMachineName,strUsername,err));} else{iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NetUserGetInfo:[(null)\\%s].End.\n"),strUsername));}
if ( err == NERR_Success ) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start."))); NetApiBufferFree( pBuffer ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End."))); } if ( pMachineName != NULL ) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start."))); NetApiBufferFree( pMachineName ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End."))); }
} while (FALSE);
return(err == NERR_Success ); }
//
// Create InternetGuest Account
//
INT CreateUser( LPCTSTR szUsername, LPCTSTR szPassword, LPCTSTR szComment, LPCTSTR szFullName, BOOL fiWamUser,INT *NewlyCreated) { iisDebugOut((LOG_TYPE_TRACE, _T("CreateUser: %s\n"), szUsername)); INT iTheUserAlreadyExists = FALSE; INT err = NERR_Success;
INT iTheUserIsMissingARight = FALSE;
BYTE *pBuffer; WCHAR defGuest[UNLEN+1]; TCHAR defGuestGroup[GNLEN+1]; WCHAR wchGuestGroup[GNLEN+1]; WCHAR wchUsername[UNLEN+1]; WCHAR wchPassword[LM20_PWLEN+1]; WCHAR *pMachineName = NULL;
*NewlyCreated = 0; iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserName:Start.\n"))); GetGuestUserName(defGuest); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserName:End.\n")));
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestGrpName:Start.\n"))); GetGuestGrpName(defGuestGroup); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestGrpName:End.\n")));
iisDebugOut((LOG_TYPE_TRACE, _T("defGuest=%s, defGuestGroup=%s\n"), defGuest, defGuestGroup));
memset((PVOID)wchUsername, 0, sizeof(wchUsername)); memset((PVOID)wchPassword, 0, sizeof(wchPassword)); #if defined(UNICODE) || defined(_UNICODE)
wcsncpy(wchGuestGroup, defGuestGroup, GNLEN); wcsncpy(wchUsername, szUsername, UNLEN); wcsncpy(wchPassword, szPassword, LM20_PWLEN); #else
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)defGuestGroup, -1, (LPWSTR)wchGuestGroup, GNLEN); MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szUsername, -1, (LPWSTR)wchUsername, UNLEN); MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szPassword, -1, (LPWSTR)wchPassword, LM20_PWLEN); #endif
iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserGetInfo:(%s) Start.\n"),defGuest)); err = NetUserGetInfo( NULL, defGuest, 3, &pBuffer ); iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserGetInfo:(%s) End.Ret=0x%x.\n"),defGuest,err));
if ( err == NERR_Success ) { do { WCHAR wchComment[MAXCOMMENTSZ+1]; WCHAR wchFullName[UNLEN+1];
memset((PVOID)wchComment, 0, sizeof(wchComment)); memset((PVOID)wchFullName, 0, sizeof(wchFullName)); #if defined(UNICODE) || defined(_UNICODE)
wcsncpy(wchComment, szComment, MAXCOMMENTSZ); wcsncpy(wchFullName, szFullName, UNLEN); #else
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szComment, -1, (LPWSTR)wchComment, MAXCOMMENTSZ); MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szFullName, -1, (LPWSTR)wchFullName, UNLEN); #endif
USER_INFO_3 *lpui3 = (USER_INFO_3 *)pBuffer;
lpui3->usri3_name = wchUsername; lpui3->usri3_password = wchPassword; lpui3->usri3_flags &= ~ UF_ACCOUNTDISABLE; lpui3->usri3_flags |= UF_DONT_EXPIRE_PASSWD; lpui3->usri3_acct_expires = TIMEQ_FOREVER;
lpui3->usri3_comment = wchComment; lpui3->usri3_usr_comment = wchComment; lpui3->usri3_full_name = wchFullName; lpui3->usri3_primary_group_id = DOMAIN_GROUP_RID_USERS;
DWORD parm_err;
iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserAdd():Start.\n"))); err = NetUserAdd( NULL, 3, pBuffer, &parm_err ); iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserAdd():End.Ret=0x%x.\n"),err));
if ( err == NERR_NotPrimary ) { // it is a backup dc
iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():Start.\n"))); err = NetGetDCName( NULL, NULL, (LPBYTE *)&pMachineName ); iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():End.Ret=0x%x\n"),err));
if (err != NERR_Success) { MyMessageBox(NULL, _T("CreateUser:NetGetDCName"), err, MB_OK | MB_SETFOREGROUND); break; } else { iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserAdd().Start."))); err = NetUserAdd( pMachineName, 3, pBuffer, &parm_err ); iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserAdd().End."))); } } else if ( err == NERR_UserExists ) { iTheUserAlreadyExists = TRUE; iisDebugOut((LOG_TYPE_TRACE, _T("CreateUser:User Already exists. reusing."))); // see if we can just change the password.
if (TRUE == ChangeUserPassword((LPTSTR) szUsername, (LPTSTR) szPassword)) { err = NERR_Success; } }
if ( err != NERR_Success ) { MyMessageBox(NULL, _T("CreateUser:NetUserAdd"), err, MB_OK | MB_SETFOREGROUND); break; }
} while (FALSE); if ( pMachineName != NULL ) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start."))); NetApiBufferFree( pMachineName ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End."))); } iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start."))); NetApiBufferFree( pBuffer ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End."))); } if ( err == NERR_Success ) { if (iTheUserAlreadyExists) { // if the user already exists, then
// don't change any rights or the group that its in leave it alone.
TCHAR PrivilegeName[256]; iTheUserIsMissingARight = FALSE;
//#define SE_INTERACTIVE_LOGON_NAME TEXT("SeInteractiveLogonRight")
//#define SE_NETWORK_LOGON_NAME TEXT("SeNetworkLogonRight")
//#define SE_BATCH_LOGON_NAME TEXT("SeBatchLogonRight")
_tcscpy(PrivilegeName, _T("SeNetworkLogonRight")); if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName)) { iTheUserIsMissingARight = TRUE; } else { _tcscpy(PrivilegeName, _T("SeBatchLogonRight")); if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName)) { iTheUserIsMissingARight = TRUE; } else { if (fiWamUser) { // make sure the iwam user has these additional rights
// AssignPrimaryToken and IncreaseQuota privileges
_tcscpy(PrivilegeName, _T("SeAssignPrimaryTokenPrivilege")); if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName)) { iTheUserIsMissingARight = TRUE; } else { _tcscpy(PrivilegeName, _T("SeIncreaseQuotaPrivilege")); if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName)) { iTheUserIsMissingARight = TRUE; } } } else { // make sure the iusr user has these additional rights
_tcscpy(PrivilegeName, _T("SeInteractiveLogonRight")); if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName)) { iTheUserIsMissingARight = TRUE; } } } }
// nope, we have to make sure that our iusr\iwam user has at least these
// rights, because otherwise it won't work bug#361833
if (iTheUserIsMissingARight == TRUE) { iisDebugOut((LOG_TYPE_TRACE, _T("Missing user right[%s]:resetting it."),PrivilegeName)); RegisterAccountUserRights(szUsername, TRUE, fiWamUser); }
// if its the the iwam user, then make sure they are not part of the Guests Group by removing them
if (fiWamUser) { RegisterAccountToLocalGroup(szUsername, _T("Guests"), FALSE); }
} else { // User was successfully newly created
*NewlyCreated = 1;
// add it to the guests group
// (but don't do it for the iwam user)
if (!fiWamUser) { RegisterAccountToLocalGroup(szUsername, _T("Guests"), TRUE); }
// add certain user rights to this account
RegisterAccountUserRights(szUsername, TRUE, fiWamUser); } }
if (TRUE == iTheUserAlreadyExists) {*NewlyCreated = 2;}
return err; }
INT DeleteGuestUser(LPCTSTR szUsername, INT *UserWasDeleted) { iisDebugOut((LOG_TYPE_TRACE, _T("DeleteGuestUser:%s\n"), szUsername));
INT err = NERR_Success; BYTE *pBuffer; *UserWasDeleted = 0;
WCHAR wchUsername[UNLEN+1]; #if defined(UNICODE) || defined(_UNICODE)
wcsncpy(wchUsername, szUsername, UNLEN); #else
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szUsername, -1, (LPWSTR)wchUsername, UNLEN); #endif
if (FALSE == IsUserExist(wchUsername)) { *UserWasDeleted = 1; iisDebugOut((LOG_TYPE_TRACE, _T("DeleteGuestUser return. %s doesn't exist.\n"), szUsername)); return err; }
// remove it from the guests group
RegisterAccountToLocalGroup(szUsername, _T("Guests"), FALSE);
// remove certain user rights of this account
RegisterAccountUserRights(szUsername, FALSE, TRUE);
do { WCHAR *pMachine = NULL;
// make sure we are not backup docmain first
iisDebugOut((LOG_TYPE_TRACE, _T("NetServerGetInfo:Start.\n"))); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().Start."))); err = NetServerGetInfo( NULL, 101, &pBuffer ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().End."))); if (err != NERR_Success ) { iisDebugOut((LOG_TYPE_ERROR, _T("NetServerGetInfo:failed.err=0x%x.\n"),err)); break; } iisDebugOut((LOG_TYPE_TRACE, _T("NetServerGetInfo:End.\n")));
LPSERVER_INFO_101 pInfo = (LPSERVER_INFO_101)pBuffer; if (( pInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL ) != 0 ) { iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():Start.\n"))); NetGetDCName( NULL, NULL, (LPBYTE *)&pMachine); iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():End.\n"))); }
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start."))); NetApiBufferFree( pBuffer ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
iisDebugOut((LOG_TYPE_TRACE, _T("NetUserDel:Start.\n"))); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetUserDel().Start."))); INT err = ::NetUserDel( pMachine, wchUsername ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetUserDel().End."))); iisDebugOut((LOG_TYPE_TRACE, _T("NetUserDel:End.Ret=0x%x.\n"),err));
if (err == NERR_Success) { *UserWasDeleted = 1; } if ( pMachine != NULL ) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start."))); NetApiBufferFree( pMachine ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End."))); } } while(FALSE);
iisDebugOut((LOG_TYPE_TRACE, _T("DeleteGuestUser:%s. End. Return 0x%x\n"), szUsername, err)); return err; }
BOOL GuestAccEnabled() { BOOL fEnabled = FALSE; INT err = NERR_Success;
BYTE *pBuffer; WCHAR defGuest[UNLEN+1]; GetGuestUserName(defGuest);
iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserGetInfo:Start.\n"))); err = NetUserGetInfo( NULL, defGuest, 3, &pBuffer ); iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserGetInfo:End.Ret=0x%x.\n"),err));
if ( err == NERR_Success ) { USER_INFO_3 *lpui3 = (USER_INFO_3 *)pBuffer; fEnabled = ( lpui3->usri3_flags & UF_ACCOUNTDISABLE ) == 0; } return fEnabled; }
NET_API_STATUS NetpNtStatusToApiStatus ( IN NTSTATUS NtStatus )
/*++
Routine Description:
This function takes an NT status code and maps it to the appropriate LAN Man error code.
Arguments:
NtStatus - Supplies the NT status.
Return Value:
Returns the appropriate LAN Man error code for the NT status.
--*/ { NET_API_STATUS error;
//
// A small optimization for the most common case.
//
if ( NtStatus == STATUS_SUCCESS ) { return NERR_Success; }
switch ( NtStatus ) {
case STATUS_BUFFER_TOO_SMALL : return NERR_BufTooSmall;
case STATUS_FILES_OPEN : return NERR_OpenFiles;
case STATUS_CONNECTION_IN_USE : return NERR_DevInUse;
case STATUS_INVALID_LOGON_HOURS : return NERR_InvalidLogonHours;
case STATUS_INVALID_WORKSTATION : return NERR_InvalidWorkstation;
case STATUS_PASSWORD_EXPIRED : return NERR_PasswordExpired;
case STATUS_ACCOUNT_EXPIRED : return NERR_AccountExpired;
case STATUS_REDIRECTOR_NOT_STARTED : return NERR_NetNotStarted;
case STATUS_GROUP_EXISTS: return NERR_GroupExists;
case STATUS_INTERNAL_DB_CORRUPTION: return NERR_InvalidDatabase;
case STATUS_INVALID_ACCOUNT_NAME: return NERR_BadUsername;
case STATUS_INVALID_DOMAIN_ROLE: case STATUS_INVALID_SERVER_STATE: case STATUS_BACKUP_CONTROLLER: return NERR_NotPrimary;
case STATUS_INVALID_DOMAIN_STATE: return NERR_ACFNotLoaded;
case STATUS_MEMBER_IN_GROUP: return NERR_UserInGroup;
case STATUS_MEMBER_NOT_IN_GROUP: return NERR_UserNotInGroup;
case STATUS_NONE_MAPPED: case STATUS_NO_SUCH_GROUP: return NERR_GroupNotFound;
case STATUS_SPECIAL_GROUP: case STATUS_MEMBERS_PRIMARY_GROUP: return NERR_SpeGroupOp;
case STATUS_USER_EXISTS: return NERR_UserExists;
case STATUS_NO_SUCH_USER: return NERR_UserNotFound;
case STATUS_PRIVILEGE_NOT_HELD: return ERROR_ACCESS_DENIED;
case STATUS_LOGON_SERVER_CONFLICT: return NERR_LogonServerConflict;
case STATUS_TIME_DIFFERENCE_AT_DC: return NERR_TimeDiffAtDC;
case STATUS_SYNCHRONIZATION_REQUIRED: return NERR_SyncRequired;
case STATUS_WRONG_PASSWORD_CORE: return NERR_BadPasswordCore;
case STATUS_DOMAIN_CONTROLLER_NOT_FOUND: return NERR_DCNotFound;
case STATUS_PASSWORD_RESTRICTION: return NERR_PasswordTooShort;
case STATUS_ALREADY_DISCONNECTED: return NERR_Success;
default:
//
// Use the system routine to do the mapping to ERROR_ codes.
//
#ifndef WIN32_CHICAGO
error = RtlNtStatusToDosError( NtStatus );
if ( error != (NET_API_STATUS)NtStatus ) { return error; } #endif // WIN32_CHICAGO
//
// Could not map the NT status to anything appropriate.
// Write this to the eventlog file
//
return NERR_InternalError; } } // NetpNtStatusToApiStatus
NET_API_STATUS UaspGetDomainId( IN LPCWSTR ServerName OPTIONAL, OUT PSAM_HANDLE SamServerHandle OPTIONAL, OUT PPOLICY_ACCOUNT_DOMAIN_INFO * AccountDomainInfo ) /*++
Routine Description: Return a domain ID of the account domain of a server. Arguments: ServerName - A pointer to a string containing the name of the Domain Controller (DC) to query. A NULL pointer or string specifies the local machine. SamServerHandle - Returns the SAM connection handle if the caller wants it. DomainId - Receives a pointer to the domain ID. Caller must deallocate buffer using NetpMemoryFree. Return Value: Error code for the operation. --*/ { NET_API_STATUS NetStatus; NTSTATUS Status;
SAM_HANDLE LocalSamHandle = NULL;
ACCESS_MASK LSADesiredAccess; LSA_HANDLE LSAPolicyHandle = NULL; OBJECT_ATTRIBUTES LSAObjectAttributes;
UNICODE_STRING ServerNameString;
//
// Connect to the SAM server
//
RtlInitUnicodeString( &ServerNameString, ServerName );
Status = SamConnect( &ServerNameString, &LocalSamHandle, SAM_SERVER_LOOKUP_DOMAIN, NULL);
if ( !NT_SUCCESS(Status)) { LocalSamHandle = NULL; NetStatus = NetpNtStatusToApiStatus( Status ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("UaspGetDomainId: Cannot connect to Sam. err=0x%x\n"),NetStatus)); goto Cleanup; }
//
// Open LSA to read account domain info.
//
if ( AccountDomainInfo != NULL) { //
// set desired access mask.
//
LSADesiredAccess = POLICY_VIEW_LOCAL_INFORMATION;
InitializeObjectAttributes( &LSAObjectAttributes, NULL, // Name
0, // Attributes
NULL, // Root
NULL ); // Security Descriptor
Status = LsaOpenPolicy( &ServerNameString, &LSAObjectAttributes, LSADesiredAccess, &LSAPolicyHandle );
if( !NT_SUCCESS(Status) ) { NetStatus = NetpNtStatusToApiStatus( Status ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("UaspGetDomainId: Cannot open LSA Policy %lX\n"),NetStatus)); goto Cleanup; }
//
// now read account domain info from LSA.
//
Status = LsaQueryInformationPolicy( LSAPolicyHandle, PolicyAccountDomainInformation, (PVOID *) AccountDomainInfo );
if( !NT_SUCCESS(Status) ) { NetStatus = NetpNtStatusToApiStatus( Status ); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("UaspGetDomainId: Cannot read LSA.Err=0x%x.\n"),NetStatus)); goto Cleanup; } }
//
// Return the SAM connection handle to the caller if he wants it.
// Otherwise, disconnect from SAM.
//
if ( ARGUMENT_PRESENT( SamServerHandle ) ) { *SamServerHandle = LocalSamHandle; LocalSamHandle = NULL; }
NetStatus = NERR_Success;
//
// Cleanup locally used resources
//
Cleanup: if ( LocalSamHandle != NULL ) { (VOID) SamCloseHandle( LocalSamHandle ); }
if( LSAPolicyHandle != NULL ) { LsaClose( LSAPolicyHandle ); }
return NetStatus; } // UaspGetDomainId
NET_API_STATUS SampCreateFullSid( IN PSID DomainSid, IN ULONG Rid, OUT PSID *AccountSid ) /*++
Routine Description: This function creates a domain account sid given a domain sid and the relative id of the account within the domain. The returned Sid may be freed with LocalFree. --*/ { NET_API_STATUS NetStatus; NTSTATUS IgnoreStatus; UCHAR AccountSubAuthorityCount; ULONG AccountSidLength; PULONG RidLocation;
//
// Calculate the size of the new sid
//
AccountSubAuthorityCount = *RtlSubAuthorityCountSid(DomainSid) + (UCHAR)1; AccountSidLength = RtlLengthRequiredSid(AccountSubAuthorityCount);
//
// Allocate space for the account sid
//
*AccountSid = LocalAlloc(LMEM_ZEROINIT,AccountSidLength); if (*AccountSid == NULL) { NetStatus = ERROR_NOT_ENOUGH_MEMORY; } else { //
// Copy the domain sid into the first part of the account sid
//
IgnoreStatus = RtlCopySid(AccountSidLength, *AccountSid, DomainSid); ASSERT(NT_SUCCESS(IgnoreStatus));
//
// Increment the account sid sub-authority count
//
*RtlSubAuthorityCountSid(*AccountSid) = AccountSubAuthorityCount;
//
// Add the rid as the final sub-authority
//
RidLocation = RtlSubAuthoritySid(*AccountSid, AccountSubAuthorityCount-1); *RidLocation = Rid;
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("AccountSid=0x%x"),*AccountSid));
NetStatus = NERR_Success; }
return(NetStatus); }
int GetGuestUserNameForDomain_FastWay(LPTSTR szDomainToLookUp,LPTSTR lpGuestUsrName) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain_FastWay.start.domain=%s\n"),szDomainToLookUp)); int iReturn = FALSE; NET_API_STATUS NetStatus;
// for UaspGetDomainId()
SAM_HANDLE SamServerHandle = NULL; PPOLICY_ACCOUNT_DOMAIN_INFO pAccountDomainInfo;
PSID pAccountSid = NULL; PSID pDomainSid = NULL;
// for LookupAccountSid()
SID_NAME_USE sidNameUse = SidTypeUser; SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; TCHAR szUserName[UNLEN+1]; DWORD cbName = UNLEN+1; // must be big enough to hold something bigger than DNLen since LookupAccountSid may returnn something really big.
TCHAR szReferencedDomainName[200]; DWORD cbReferencedDomainName = sizeof(szReferencedDomainName);
ASSERT(lpGuestUsrName);
// make sure not to return back gobble-d-gook
_tcscpy(lpGuestUsrName, _T(""));
//
// Get the Sid for the specified Domain
//
// szDomainToLookUp=NULL for local machine
NetStatus = UaspGetDomainId( szDomainToLookUp,&SamServerHandle,&pAccountDomainInfo ); if ( NetStatus != NERR_Success ) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain:UaspGetDomainId failed.ret=0x%x."),NetStatus)); goto GetGuestUserNameForDomain_FastWay_Exit; } pDomainSid = pAccountDomainInfo->DomainSid; //
// Use the Domain Sid and the well known Guest RID to create the Real Guest Sid
//
// Well-known users ...
// DOMAIN_USER_RID_ADMIN (0x000001F4L)
// DOMAIN_USER_RID_GUEST (0x000001F5L)
NetStatus = NERR_InternalError; NetStatus = SampCreateFullSid(pDomainSid, DOMAIN_USER_RID_GUEST, &pAccountSid); if ( NetStatus != NERR_Success ) { iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain:SampCreateFullSid failed.ret=0x%x."),NetStatus)); goto GetGuestUserNameForDomain_FastWay_Exit; }
//
// Check if the SID is valid
//
if (0 == IsValidSid(pAccountSid)) { DWORD dwErr = GetLastError(); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain:IsValidSid FAILED. GetLastError()= 0x%x\n"), dwErr)); goto GetGuestUserNameForDomain_FastWay_Exit; }
//
// Retrieve the UserName for the specified SID
//
_tcscpy(szUserName, _T("")); _tcscpy(szReferencedDomainName, _T("")); // szDomainToLookUp=NULL for local machine
if (!LookupAccountSid(szDomainToLookUp, pAccountSid, szUserName, &cbName, szReferencedDomainName, &cbReferencedDomainName, &sidNameUse)) { DWORD dwErr = GetLastError(); iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain:LookupAccountSid FAILED. GetLastError()= 0x%x\n"), dwErr)); goto GetGuestUserNameForDomain_FastWay_Exit; }
//iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain:szDomainToLookUp=%s\n"),szDomainToLookUp));
//iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain:pAccountSid=0x%x\n"),pAccountSid));
//iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain:szUserName=%s\n"),szUserName));
//iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain:szReferencedDomainName=%s\n"),szReferencedDomainName));
// Return the guest user name that we got.
_tcscpy(lpGuestUsrName, szUserName);
// Wow, after all that, we must have succeeded
iReturn = TRUE;
GetGuestUserNameForDomain_FastWay_Exit: // Free the Domain info if we got some
if (pAccountDomainInfo) {NetpMemoryFree(pAccountDomainInfo);} // Free the sid if we had allocated one
if (pAccountSid) {LocalFree(pAccountSid);} iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain_FastWay.end.domain=%s.ret=%d.\n"),szDomainToLookUp,iReturn)); return iReturn; }
void GetGuestUserName(LPTSTR lpOutGuestUsrName) { // try to retrieve the guest username the fast way
// meaning = lookup the domain sid, and the well known guest rid, to get the guest sid.
// then look it up. The reason for this function is that on large domains with mega users
// the account can be quickly looked up.
TCHAR szGuestUsrName[UNLEN+1]; LPTSTR pszComputerName = NULL; if (!GetGuestUserNameForDomain_FastWay(pszComputerName,szGuestUsrName)) { iisDebugOut((LOG_TYPE_WARN, _T("GetGuestUserNameForDomain_FastWay:Did not succeed use slow way. WARNING.")));
// if the fast way failed for some reason, then let's do it
// the slow way, since this way always used to work, only on large domains (1 mil users)
// it could take 24hrs (since this function actually enumerates thru the domain)
GetGuestUserName_SlowWay(szGuestUsrName); }
// Return back the username
_tcscpy(lpOutGuestUsrName,szGuestUsrName);
return; }
int ChangeUserPassword(IN LPTSTR szUserName, IN LPTSTR szNewPassword) { int iReturn = TRUE; USER_INFO_1003 pi1003; NET_API_STATUS nas;
TCHAR szRawComputerName[CNLEN + 10]; DWORD dwLen = CNLEN + 10; TCHAR szComputerName[CNLEN + 10]; TCHAR szCopyOfUserName[UNLEN+10]; TCHAR szTempFullUserName[(CNLEN + 10) + (DNLEN+1)]; LPTSTR pch = NULL;
_tcscpy(szCopyOfUserName, szUserName);
//iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeUserPassword().Start.name=%s,pass=%s"),szCopyOfUserName,szNewPassword));
iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeUserPassword().Start.name=%s"),szCopyOfUserName));
if ( !GetComputerName( szRawComputerName, &dwLen )) {goto ChangeUserPassword_Exit;}
// Make a copy to be sure not to move the pointer around.
_tcscpy(szTempFullUserName, szCopyOfUserName); // Check if there is a "\" in there.
pch = _tcschr(szTempFullUserName, _T('\\')); if (pch) { // szCopyOfUserName should now go from something like this:
// mycomputer\myuser
// to this myuser
_tcscpy(szCopyOfUserName,pch+1); // trim off the '\' character to leave just the domain\computername so we can check against it.
*pch = _T('\0'); // compare the szTempFullUserName with the local computername.
if (0 == _tcsicmp(szRawComputerName, szTempFullUserName)) { // the computername\username has a hardcoded computername in it.
// lets try to get only the username
// look szCopyOfusername is already set
} else { // the local computer machine name
// and the specified username are different, so get out
// and don't even try to change this user\password since
// it's probably a domain\username
// return true -- saying that we did in fact change the passoword.
// we really didn't but we can't
iReturn = TRUE; goto ChangeUserPassword_Exit; } }
// Make sure the computername has a \\ in front of it
if ( szRawComputerName[0] != _T('\\') ) {_tcscpy(szComputerName,_T("\\\\"));} _tcscat(szComputerName,szRawComputerName); //
// administrative over-ride of existing password
//
// by this time szCopyOfUserName
// should not look like mycomputername\username but it should look like username.
pi1003.usri1003_password = szNewPassword; nas = NetUserSetInfo( szComputerName, // computer name
szCopyOfUserName, // username
1003, // info level
(LPBYTE)&pi1003, // new info
NULL );
if(nas != NERR_Success) { iReturn = FALSE; goto ChangeUserPassword_Exit; }
ChangeUserPassword_Exit: iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeUserPassword().End.Ret=%d"),iReturn)); return iReturn; }
BOOL DoesUserHaveThisRight(LPCTSTR szAccountName, LPTSTR PrivilegeName) { iisDebugOut((LOG_TYPE_TRACE, _T("DoesUserHaveBasicRights:Account=%s\n"), szAccountName)); int err; BOOL fEnabled = FALSE; NTSTATUS status;
LSA_UNICODE_STRING UserRightString; // Create a LSA_UNICODE_STRING for the privilege name.
InitLsaString(&UserRightString, PrivilegeName);
// get the sid of szAccountName
PSID pSID = NULL; BOOL bWellKnownSID = FALSE; err = GetPrincipalSID ((LPTSTR)szAccountName, &pSID, &bWellKnownSID); if (err != ERROR_SUCCESS) { iisDebugOut((LOG_TYPE_ERROR, _T("DoesUserHaveBasicRights:GetPrincipalSID:Account=%s, err=%d.\n"), szAccountName, err)); return (err); }
LSA_HANDLE PolicyHandle = NULL;
err = OpenPolicy(NULL, POLICY_ALL_ACCESS,&PolicyHandle); if ( err == NERR_Success ) { UINT i; LSA_UNICODE_STRING *rgUserRights = NULL; ULONG cRights; status = LsaEnumerateAccountRights( PolicyHandle, pSID, &rgUserRights, &cRights);
if (status==STATUS_OBJECT_NAME_NOT_FOUND) { // no rights/privileges for this account
fEnabled = FALSE; } else if (!NT_SUCCESS(status)) { iisDebugOut((LOG_TYPE_ERROR, _T("DoesUserHaveBasicRights:GetPrincipalSID:Failed to enumerate rights: status 0x%08lx\n"), status)); goto DoesUserHaveBasicRights_Exit; }
for(i=0; i < cRights; i++) { if ( RtlEqualUnicodeString(&rgUserRights[i],&UserRightString,FALSE) ) { fEnabled = TRUE; break; } } if (rgUserRights) {LsaFreeMemory(rgUserRights);} }
DoesUserHaveBasicRights_Exit: if (PolicyHandle){LsaClose(PolicyHandle);} if (pSID) { if (bWellKnownSID){FreeSid (pSID);} else{free (pSID);} } return (fEnabled); }
HRESULT CreateGroup(LPTSTR szGroupName, LPCTSTR szGroupComment, int iAction) { HRESULT hr = S_OK; NET_API_STATUS dwRes; LOCALGROUP_INFO_1 MyLocalGroup;
WCHAR wszLocalGroupName[_MAX_PATH]; WCHAR wszLocalGroupComment[_MAX_PATH];
memset(&MyLocalGroup, 0, sizeof(MyLocalGroup));
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(wszLocalGroupName, szGroupName); _tcscpy(wszLocalGroupComment, szGroupComment); #else
MultiByteToWideChar( CP_ACP, 0, szGroupName, -1, wszLocalGroupName, _MAX_PATH); MultiByteToWideChar( CP_ACP, 0, szGroupComment, -1, wszLocalGroupComment, _MAX_PATH); #endif
MyLocalGroup.lgrpi1_name = (LPWSTR)szGroupName; MyLocalGroup.lgrpi1_comment = (LPWSTR)szGroupComment;
if (iAction) { dwRes = ::NetLocalGroupAdd( NULL, 1, (LPBYTE)&MyLocalGroup, NULL ); if(dwRes != NERR_Success && dwRes != NERR_GroupExists && dwRes != ERROR_ALIAS_EXISTS ) { hr = HRESULT_FROM_WIN32(dwRes); } } else { dwRes = ::NetLocalGroupDel( NULL, wszLocalGroupName); if(dwRes != NERR_Success && dwRes != NERR_GroupNotFound && dwRes != ERROR_NO_SUCH_ALIAS ) { hr = HRESULT_FROM_WIN32(dwRes); }
}
return hr; }
int CreateGroupDC(LPTSTR szGroupName, LPCTSTR szGroupComment) { int iReturn = FALSE; GROUP_INFO_1 GI1; ULONG BadParm; WCHAR * pMachineName = NULL; ULONG ulErr = ERROR_SUCCESS; WCHAR wszLocalGroupName[_MAX_PATH]; WCHAR wszLocalGroupComment[_MAX_PATH];
memset(&GI1, 0, sizeof(GROUP_INFO_1));
#if defined(UNICODE) || defined(_UNICODE)
_tcscpy(wszLocalGroupName, szGroupName); _tcscpy(wszLocalGroupComment, szGroupComment); #else
MultiByteToWideChar( CP_ACP, 0, szGroupName, -1, wszLocalGroupName, _MAX_PATH); MultiByteToWideChar( CP_ACP, 0, szGroupComment, -1, wszLocalGroupComment, _MAX_PATH); #endif
GI1.grpi1_name = wszLocalGroupName; GI1.grpi1_comment = wszLocalGroupComment;
iisDebugOut((LOG_TYPE_TRACE, _T("CreateGroup:NetGroupAdd\n"))); ulErr = NetGroupAdd(NULL,1,(PBYTE)&GI1,&BadParm); iisDebugOut((LOG_TYPE_TRACE, _T("CreateGroup:NetGroupAdd,ret=0x%x\n"),ulErr)); switch (ulErr) { case NERR_Success: iisDebugOut((LOG_TYPE_TRACE, _T("CreateGroup:NetGroupAdd,success\n"),ulErr)); iReturn = TRUE; break; case NERR_GroupExists: iReturn = TRUE; break; case NERR_InvalidComputer: iReturn = FALSE; break; case NERR_NotPrimary: { // it is a backup dc
int err; iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():Start.\n"))); err = NetGetDCName( NULL, NULL, (LPBYTE *)&pMachineName ); iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():End.Ret=0x%x\n"),err)); if (err != NERR_Success) { MyMessageBox(NULL, _T("CreateUser:NetGetDCName"), err, MB_OK | MB_SETFOREGROUND); } else { iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGroupAdd().Start."))); ulErr = NetGroupAdd(pMachineName,1,(PBYTE)&GI1,&BadParm); iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGroupAdd().End."))); if (NERR_Success == ulErr || NERR_GroupExists == ulErr) { iReturn = TRUE; } } } break; case ERROR_ACCESS_DENIED: iReturn = FALSE; break; default: iReturn = FALSE; break; }
return iReturn; }
#endif //_CHICAGO_
|