Source code of Windows XP (NT5)
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.

1552 lines
58 KiB

  1. #include "stdafx.h"
  2. #include "svc.h"
  3. #include "setuser.h"
  4. #include "dcomperm.h"
  5. #ifndef _CHICAGO_
  6. int GetGuestUserName_SlowWay(LPWSTR lpGuestUsrName)
  7. {
  8. LPWSTR ServerName = NULL; // default to local machine
  9. DWORD Level = 1; // to retrieve info of all local and global normal user accounts
  10. DWORD Index = 0;
  11. DWORD EntriesRequested = 5;
  12. DWORD PreferredMaxLength = 1024;
  13. DWORD ReturnedEntryCount = 0;
  14. PVOID SortedBuffer = NULL;
  15. NET_DISPLAY_USER *p = NULL;
  16. DWORD i=0;
  17. int err = 0;
  18. BOOL fStatus = TRUE;
  19. while (fStatus)
  20. {
  21. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetQueryDisplayInformation().Start.")));
  22. err = NetQueryDisplayInformation(ServerName, Level, Index, EntriesRequested, PreferredMaxLength, &ReturnedEntryCount, &SortedBuffer);
  23. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetQueryDisplayInformation().End.")));
  24. if (err == NERR_Success)
  25. fStatus = FALSE;
  26. if (err == NERR_Success || err == ERROR_MORE_DATA)
  27. {
  28. p = (NET_DISPLAY_USER *)SortedBuffer;
  29. i = 0;
  30. while (i < ReturnedEntryCount && (p[i].usri1_user_id != DOMAIN_USER_RID_GUEST))
  31. i++;
  32. if (i == ReturnedEntryCount)
  33. {
  34. if (err == ERROR_MORE_DATA)
  35. { // need to get more entries
  36. Index = p[i-1].usri1_next_index;
  37. }
  38. }
  39. else
  40. {
  41. wcscpy(lpGuestUsrName, p[i].usri1_name);
  42. fStatus = FALSE;
  43. }
  44. }
  45. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start.")));
  46. NetApiBufferFree(SortedBuffer);
  47. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
  48. }
  49. return 0;
  50. }
  51. int GetGuestGrpName(LPTSTR lpGuestGrpName)
  52. {
  53. LPCTSTR ServerName = NULL; // local machine
  54. DWORD cbName = UNLEN+1;
  55. TCHAR ReferencedDomainName[200];
  56. DWORD cbReferencedDomainName = sizeof(ReferencedDomainName);
  57. SID_NAME_USE sidNameUse = SidTypeUser;
  58. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  59. PSID GuestsSid = NULL;
  60. AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS,0,0,0,0,0,0, &GuestsSid);
  61. LookupAccountSid(ServerName, GuestsSid, lpGuestGrpName, &cbName, ReferencedDomainName, &cbReferencedDomainName, &sidNameUse);
  62. if (GuestsSid)
  63. FreeSid(GuestsSid);
  64. return 0;
  65. }
  66. void InitLsaString(PLSA_UNICODE_STRING LsaString,LPWSTR String)
  67. {
  68. DWORD StringLength;
  69. if (String == NULL)
  70. {
  71. LsaString->Buffer = NULL;
  72. LsaString->Length = 0;
  73. LsaString->MaximumLength = 0;
  74. return;
  75. }
  76. StringLength = wcslen(String);
  77. LsaString->Buffer = String;
  78. LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
  79. LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
  80. }
  81. DWORD OpenPolicy(LPTSTR ServerName,DWORD DesiredAccess,PLSA_HANDLE PolicyHandle)
  82. {
  83. DWORD Error;
  84. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  85. LSA_UNICODE_STRING ServerString;
  86. PLSA_UNICODE_STRING Server = NULL;
  87. SECURITY_QUALITY_OF_SERVICE QualityOfService;
  88. QualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  89. QualityOfService.ImpersonationLevel = SecurityImpersonation;
  90. QualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  91. QualityOfService.EffectiveOnly = FALSE;
  92. //
  93. // The two fields that must be set are length and the quality of service.
  94. //
  95. ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
  96. ObjectAttributes.RootDirectory = NULL;
  97. ObjectAttributes.ObjectName = NULL;
  98. ObjectAttributes.Attributes = 0;
  99. ObjectAttributes.SecurityDescriptor = NULL;
  100. ObjectAttributes.SecurityQualityOfService = &QualityOfService;
  101. if (ServerName != NULL)
  102. {
  103. //
  104. // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
  105. //
  106. InitLsaString(&ServerString,ServerName);
  107. Server = &ServerString;
  108. }
  109. //
  110. // Attempt to open the policy for all access
  111. //
  112. Error = LsaOpenPolicy(Server,&ObjectAttributes,DesiredAccess,PolicyHandle);
  113. return(Error);
  114. }
  115. INT RegisterAccountToLocalGroup(LPCTSTR szAccountName, LPCTSTR szLocalGroupName, BOOL fAction)
  116. {
  117. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("RegisterAccountToLocalGroup:Action=%d,Account=%s\n"), fAction, szAccountName));
  118. int err;
  119. // get the sid of szAccountName
  120. PSID pSID = NULL;
  121. BOOL bWellKnownSID = FALSE;
  122. err = GetPrincipalSID ((LPTSTR)szAccountName, &pSID, &bWellKnownSID);
  123. if (err != ERROR_SUCCESS)
  124. {
  125. iisDebugOut((LOG_TYPE_ERROR, _T("RegisterAccountToLocalGroup:GetPrincipalSID:fAction=%d, Account=%s, Group=%s, err=%d.\n"), fAction, szAccountName, szLocalGroupName, err));
  126. return (err);
  127. }
  128. // Get the localized LocalGroupName
  129. TCHAR szLocalizedLocalGroupName[GNLEN + 1];
  130. if (_tcsicmp(szLocalGroupName, _T("Guests")) == 0)
  131. {
  132. GetGuestGrpName(szLocalizedLocalGroupName);
  133. }
  134. else
  135. {
  136. _tcscpy(szLocalizedLocalGroupName, szLocalGroupName);
  137. }
  138. // transfer szLocalGroupName to WCHAR
  139. WCHAR wszLocalGroupName[_MAX_PATH];
  140. #if defined(UNICODE) || defined(_UNICODE)
  141. _tcscpy(wszLocalGroupName, szLocalizedLocalGroupName);
  142. #else
  143. MultiByteToWideChar( CP_ACP, 0, szLocalizedLocalGroupName, -1, wszLocalGroupName, _MAX_PATH);
  144. #endif
  145. LOCALGROUP_MEMBERS_INFO_0 buf;
  146. buf.lgrmi0_sid = pSID;
  147. if (fAction)
  148. {
  149. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetLocalGroupAddMembers().Start.")));
  150. err = NetLocalGroupAddMembers(NULL, wszLocalGroupName, 0, (LPBYTE)&buf, 1);
  151. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetLocalGroupAddMembers().End.")));
  152. }
  153. else
  154. {
  155. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetLocalGroupDelMembers().Start.")));
  156. err = NetLocalGroupDelMembers(NULL, wszLocalGroupName, 0, (LPBYTE)&buf, 1);
  157. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetLocalGroupDelMembers().End.")));
  158. }
  159. iisDebugOut((LOG_TYPE_TRACE, _T("RegisterAccountToLocalGroup:fAction=%d, Account=%s, Group=%s, err=%d.\n"), fAction, szAccountName, szLocalGroupName, err));
  160. if (pSID)
  161. {
  162. if (bWellKnownSID)
  163. FreeSid (pSID);
  164. else
  165. free (pSID);
  166. }
  167. return (err);
  168. }
  169. INT RegisterAccountUserRights(LPCTSTR szAccountName, BOOL fAction, BOOL fSpecicaliwamaccount)
  170. {
  171. iisDebugOut((LOG_TYPE_TRACE, _T("RegisterAccountUserRights:Action=%d,Account=%s,iwam=%d\n"), fAction, szAccountName,fSpecicaliwamaccount));
  172. int err;
  173. // get the sid of szAccountName
  174. PSID pSID = NULL;
  175. BOOL bWellKnownSID = FALSE;
  176. err = GetPrincipalSID ((LPTSTR)szAccountName, &pSID, &bWellKnownSID);
  177. if (err != ERROR_SUCCESS)
  178. {
  179. iisDebugOut((LOG_TYPE_ERROR, _T("RegisterAccountUserRights:GetPrincipalSID:fAction=%d, Account=%s, err=%d.\n"), fAction, szAccountName, err));
  180. return (err);
  181. }
  182. LSA_UNICODE_STRING UserRightString;
  183. LSA_HANDLE PolicyHandle = NULL;
  184. err = OpenPolicy(NULL, POLICY_ALL_ACCESS,&PolicyHandle);
  185. if ( err == NERR_Success )
  186. {
  187. if (fAction)
  188. {
  189. // defined in ntsecapi.h and ntlsa.h
  190. //#define SE_INTERACTIVE_LOGON_NAME TEXT("SeInteractiveLogonRight")
  191. //#define SE_NETWORK_LOGON_NAME TEXT("SeNetworkLogonRight")
  192. //#define SE_BATCH_LOGON_NAME TEXT("SeBatchLogonRight")
  193. //#define SE_SERVICE_LOGON_NAME TEXT("SeServiceLogonRight")
  194. // Defined in winnt.h
  195. //#define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege")
  196. //#define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege")
  197. //#define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege")
  198. //#define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege")
  199. //#define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege")
  200. //#define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege")
  201. //#define SE_TCB_NAME TEXT("SeTcbPrivilege")
  202. //#define SE_SECURITY_NAME TEXT("SeSecurityPrivilege")
  203. //#define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege")
  204. //#define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege")
  205. //#define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege")
  206. //#define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege")
  207. //#define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege")
  208. //#define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege")
  209. //#define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege")
  210. //#define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege")
  211. //#define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
  212. //#define SE_RESTORE_NAME TEXT("SeRestorePrivilege")
  213. //#define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")
  214. //#define SE_DEBUG_NAME TEXT("SeDebugPrivilege")
  215. //#define SE_AUDIT_NAME TEXT("SeAuditPrivilege")
  216. //#define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege")
  217. //#define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege")
  218. //#define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege")
  219. //#define SE_UNDOCK_NAME TEXT("SeUndockPrivilege")
  220. //#define SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege")
  221. //#define SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege")
  222. if (fSpecicaliwamaccount)
  223. {
  224. InitLsaString(&UserRightString, SE_NETWORK_LOGON_NAME);
  225. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  226. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  227. // For NT5 -- the Iwam account will not have a ton of priveleges like was first decided.
  228. // for security reasons it was trimmed.
  229. InitLsaString(&UserRightString, SE_BATCH_LOGON_NAME);
  230. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  231. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  232. // For NT51 (Whistler)
  233. // iwam should have additional rights, per bug277113 "SeAssignPrimaryTokenPrivilege","SeIncreaseQuotaPrivilege"
  234. InitLsaString(&UserRightString, SE_ASSIGNPRIMARYTOKEN_NAME);
  235. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  236. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  237. InitLsaString(&UserRightString, SE_INCREASE_QUOTA_NAME);
  238. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  239. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  240. /* Old stuff that was taken out post NT5 Beta3
  241. // Per Bug 291206 - IWAM account should not have the "log on locally" right, as it currently does
  242. // So make sure it is not there -- since this is a potential security hole!
  243. InitLsaString(&UserRightString, SE_INTERACTIVE_LOGON_NAME);
  244. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  245. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  246. // stuff for nt5 Beta3
  247. InitLsaString(&UserRightString, SE_TCB_NAME);
  248. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  249. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  250. InitLsaString(&UserRightString, SE_CREATE_PAGEFILE_NAME);
  251. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  252. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  253. InitLsaString(&UserRightString, SE_CREATE_TOKEN_NAME);
  254. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  255. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  256. InitLsaString(&UserRightString, SE_CREATE_PERMANENT_NAME);
  257. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  258. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  259. InitLsaString(&UserRightString, SE_DEBUG_NAME);
  260. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  261. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  262. InitLsaString(&UserRightString, SE_AUDIT_NAME);
  263. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  264. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  265. InitLsaString(&UserRightString, SE_INCREASE_QUOTA_NAME);
  266. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  267. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  268. InitLsaString(&UserRightString, SE_INC_BASE_PRIORITY_NAME);
  269. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  270. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  271. InitLsaString(&UserRightString, SE_LOAD_DRIVER_NAME);
  272. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  273. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  274. InitLsaString(&UserRightString, SE_LOCK_MEMORY_NAME);
  275. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  276. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  277. InitLsaString(&UserRightString, SE_SYSTEM_ENVIRONMENT_NAME);
  278. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  279. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  280. InitLsaString(&UserRightString, SE_PROF_SINGLE_PROCESS_NAME);
  281. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  282. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  283. InitLsaString(&UserRightString, SE_ASSIGNPRIMARYTOKEN_NAME);
  284. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  285. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  286. */
  287. }
  288. else
  289. {
  290. InitLsaString(&UserRightString, SE_INTERACTIVE_LOGON_NAME);
  291. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  292. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  293. InitLsaString(&UserRightString, SE_NETWORK_LOGON_NAME);
  294. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  295. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  296. InitLsaString(&UserRightString, SE_BATCH_LOGON_NAME);
  297. err = LsaAddAccountRights(PolicyHandle, pSID, &UserRightString, 1);
  298. if (err != STATUS_SUCCESS){iisDebugOut((LOG_TYPE_WARN, _T("RegisterAccountUserRights:LsaAddAccountRights FAILED. err=0x%x\n"), err));}
  299. }
  300. }
  301. else
  302. {
  303. InitLsaString(&UserRightString, SE_INTERACTIVE_LOGON_NAME);
  304. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  305. InitLsaString(&UserRightString, SE_NETWORK_LOGON_NAME);
  306. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  307. InitLsaString(&UserRightString, SE_BATCH_LOGON_NAME);
  308. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  309. InitLsaString(&UserRightString, SE_ASSIGNPRIMARYTOKEN_NAME);
  310. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  311. InitLsaString(&UserRightString, SE_INCREASE_QUOTA_NAME);
  312. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  313. /* Old stuff that was taken out post NT5 Beta3
  314. // if special iwam account or not, let's remove these rights from the iusr or iwam user
  315. InitLsaString(&UserRightString, SE_TCB_NAME);
  316. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  317. InitLsaString(&UserRightString, SE_CREATE_PAGEFILE_NAME);
  318. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  319. InitLsaString(&UserRightString, SE_CREATE_TOKEN_NAME);
  320. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  321. InitLsaString(&UserRightString, SE_CREATE_PERMANENT_NAME);
  322. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  323. InitLsaString(&UserRightString, SE_DEBUG_NAME);
  324. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  325. InitLsaString(&UserRightString, SE_AUDIT_NAME);
  326. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  327. InitLsaString(&UserRightString, SE_INCREASE_QUOTA_NAME);
  328. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  329. InitLsaString(&UserRightString, SE_INC_BASE_PRIORITY_NAME);
  330. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  331. InitLsaString(&UserRightString, SE_LOAD_DRIVER_NAME);
  332. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  333. InitLsaString(&UserRightString, SE_LOCK_MEMORY_NAME);
  334. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  335. InitLsaString(&UserRightString, SE_SYSTEM_ENVIRONMENT_NAME);
  336. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  337. InitLsaString(&UserRightString, SE_PROF_SINGLE_PROCESS_NAME);
  338. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  339. InitLsaString(&UserRightString, SE_ASSIGNPRIMARYTOKEN_NAME);
  340. err = LsaRemoveAccountRights(PolicyHandle, pSID, FALSE, &UserRightString,1);
  341. */
  342. }
  343. LsaClose(PolicyHandle);
  344. }
  345. else
  346. {
  347. iisDebugOut((LOG_TYPE_TRACE, _T("RegisterAccountUserRights:Action=%d,Account=%s,iwam=%d,err=0x%x\n"), fAction, szAccountName,fSpecicaliwamaccount,err));
  348. }
  349. if (pSID)
  350. {
  351. if (bWellKnownSID)
  352. FreeSid (pSID);
  353. else
  354. free (pSID);
  355. }
  356. if (err)
  357. {
  358. iisDebugOut((LOG_TYPE_TRACE, _T("RegisterAccountUserRights:Action=%d,Account=%s,iwam=%d,err=0x%x\n"), fAction, szAccountName,fSpecicaliwamaccount,err));
  359. }
  360. return (err);
  361. }
  362. BOOL IsUserExist( LPWSTR strUsername )
  363. {
  364. BYTE *pBuffer;
  365. INT err = NERR_Success;
  366. do
  367. {
  368. WCHAR *pMachineName = NULL;
  369. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().Start.")));
  370. err = NetServerGetInfo( NULL, 101, &pBuffer );
  371. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().End.")));
  372. // make sure we are not backup docmain first
  373. if (err != NERR_Success )
  374. {
  375. // if this call returns that the service is not running, then let's just assume that the user does exist!!!!
  376. if (err == NERR_ServerNotStarted)
  377. {
  378. // Try to start the server service.
  379. err = InetStartService(_T("LanmanServer"));
  380. if (err == 0 || err == ERROR_SERVICE_ALREADY_RUNNING)
  381. {
  382. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().Start.")));
  383. err = NetServerGetInfo( NULL, 101, &pBuffer );
  384. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().End.")));
  385. if (err != NERR_Success )
  386. {
  387. if (err == NERR_ServerNotStarted)
  388. {
  389. iisDebugOut((LOG_TYPE_WARN, _T("NetServerGetInfo:failed.The Server service is not started. assume that %s exists.err=0x%x.\n"),strUsername,err));
  390. err = NERR_Success;
  391. }
  392. }
  393. }
  394. else
  395. {
  396. iisDebugOut((LOG_TYPE_ERROR, _T("NetServerGetInfo:failed.The Server service is not started. assume that %s exists.err=0x%x.\n"),strUsername,err));
  397. err = NERR_Success;
  398. }
  399. }
  400. else
  401. {
  402. 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));
  403. }
  404. break;
  405. }
  406. LPSERVER_INFO_101 pInfo = (LPSERVER_INFO_101)pBuffer;
  407. if (( pInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL ) != 0 )
  408. {
  409. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetGetDCName().Start.")));
  410. NetGetDCName( NULL, NULL, (LPBYTE*)&pMachineName );
  411. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetGetDCName().End.")));
  412. }
  413. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start.")));
  414. NetApiBufferFree( pBuffer );
  415. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
  416. if (pMachineName){iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NetUserGetInfo:[%s\\%s].Start.\n"),pMachineName,strUsername));}
  417. else{iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NetUserGetInfo:[(null)\\%s].Start.\n"),strUsername));}
  418. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetUserGetInfo().Start.")));
  419. err = NetUserGetInfo( pMachineName, strUsername, 3, &pBuffer );
  420. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetUserGetInfo().End.")));
  421. if (pMachineName){iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NetUserGetInfo:[%s\\%s].End.Ret=0x%x.\n"),pMachineName,strUsername,err));}
  422. else{iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NetUserGetInfo:[(null)\\%s].End.\n"),strUsername));}
  423. if ( err == NERR_Success )
  424. {
  425. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start.")));
  426. NetApiBufferFree( pBuffer );
  427. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
  428. }
  429. if ( pMachineName != NULL )
  430. {
  431. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start.")));
  432. NetApiBufferFree( pMachineName );
  433. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
  434. }
  435. } while (FALSE);
  436. return(err == NERR_Success );
  437. }
  438. //
  439. // Create InternetGuest Account
  440. //
  441. INT CreateUser( LPCTSTR szUsername, LPCTSTR szPassword, LPCTSTR szComment, LPCTSTR szFullName, BOOL fiWamUser,INT *NewlyCreated)
  442. {
  443. iisDebugOut((LOG_TYPE_TRACE, _T("CreateUser: %s\n"), szUsername));
  444. INT iTheUserAlreadyExists = FALSE;
  445. INT err = NERR_Success;
  446. INT iTheUserIsMissingARight = FALSE;
  447. BYTE *pBuffer;
  448. WCHAR defGuest[UNLEN+1];
  449. TCHAR defGuestGroup[GNLEN+1];
  450. WCHAR wchGuestGroup[GNLEN+1];
  451. WCHAR wchUsername[UNLEN+1];
  452. WCHAR wchPassword[LM20_PWLEN+1];
  453. WCHAR *pMachineName = NULL;
  454. *NewlyCreated = 0;
  455. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserName:Start.\n")));
  456. GetGuestUserName(defGuest);
  457. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserName:End.\n")));
  458. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestGrpName:Start.\n")));
  459. GetGuestGrpName(defGuestGroup);
  460. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestGrpName:End.\n")));
  461. iisDebugOut((LOG_TYPE_TRACE, _T("defGuest=%s, defGuestGroup=%s\n"), defGuest, defGuestGroup));
  462. memset((PVOID)wchUsername, 0, sizeof(wchUsername));
  463. memset((PVOID)wchPassword, 0, sizeof(wchPassword));
  464. #if defined(UNICODE) || defined(_UNICODE)
  465. wcsncpy(wchGuestGroup, defGuestGroup, GNLEN);
  466. wcsncpy(wchUsername, szUsername, UNLEN);
  467. wcsncpy(wchPassword, szPassword, LM20_PWLEN);
  468. #else
  469. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)defGuestGroup, -1, (LPWSTR)wchGuestGroup, GNLEN);
  470. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szUsername, -1, (LPWSTR)wchUsername, UNLEN);
  471. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szPassword, -1, (LPWSTR)wchPassword, LM20_PWLEN);
  472. #endif
  473. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserGetInfo:(%s) Start.\n"),defGuest));
  474. err = NetUserGetInfo( NULL, defGuest, 3, &pBuffer );
  475. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserGetInfo:(%s) End.Ret=0x%x.\n"),defGuest,err));
  476. if ( err == NERR_Success )
  477. {
  478. do
  479. {
  480. WCHAR wchComment[MAXCOMMENTSZ+1];
  481. WCHAR wchFullName[UNLEN+1];
  482. memset((PVOID)wchComment, 0, sizeof(wchComment));
  483. memset((PVOID)wchFullName, 0, sizeof(wchFullName));
  484. #if defined(UNICODE) || defined(_UNICODE)
  485. wcsncpy(wchComment, szComment, MAXCOMMENTSZ);
  486. wcsncpy(wchFullName, szFullName, UNLEN);
  487. #else
  488. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szComment, -1, (LPWSTR)wchComment, MAXCOMMENTSZ);
  489. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szFullName, -1, (LPWSTR)wchFullName, UNLEN);
  490. #endif
  491. USER_INFO_3 *lpui3 = (USER_INFO_3 *)pBuffer;
  492. lpui3->usri3_name = wchUsername;
  493. lpui3->usri3_password = wchPassword;
  494. lpui3->usri3_flags &= ~ UF_ACCOUNTDISABLE;
  495. lpui3->usri3_flags |= UF_DONT_EXPIRE_PASSWD;
  496. lpui3->usri3_acct_expires = TIMEQ_FOREVER;
  497. lpui3->usri3_comment = wchComment;
  498. lpui3->usri3_usr_comment = wchComment;
  499. lpui3->usri3_full_name = wchFullName;
  500. lpui3->usri3_primary_group_id = DOMAIN_GROUP_RID_USERS;
  501. DWORD parm_err;
  502. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserAdd():Start.\n")));
  503. err = NetUserAdd( NULL, 3, pBuffer, &parm_err );
  504. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserAdd():End.Ret=0x%x.\n"),err));
  505. if ( err == NERR_NotPrimary )
  506. {
  507. // it is a backup dc
  508. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():Start.\n")));
  509. err = NetGetDCName( NULL, NULL, (LPBYTE *)&pMachineName );
  510. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():End.Ret=0x%x\n"),err));
  511. if (err != NERR_Success)
  512. {
  513. MyMessageBox(NULL, _T("CreateUser:NetGetDCName"), err, MB_OK | MB_SETFOREGROUND);
  514. break;
  515. }
  516. else
  517. {
  518. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserAdd().Start.")));
  519. err = NetUserAdd( pMachineName, 3, pBuffer, &parm_err );
  520. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserAdd().End.")));
  521. }
  522. }
  523. else if ( err == NERR_UserExists )
  524. {
  525. iTheUserAlreadyExists = TRUE;
  526. iisDebugOut((LOG_TYPE_TRACE, _T("CreateUser:User Already exists. reusing.")));
  527. // see if we can just change the password.
  528. if (TRUE == ChangeUserPassword((LPTSTR) szUsername, (LPTSTR) szPassword))
  529. {
  530. err = NERR_Success;
  531. }
  532. }
  533. if ( err != NERR_Success )
  534. {
  535. MyMessageBox(NULL, _T("CreateUser:NetUserAdd"), err, MB_OK | MB_SETFOREGROUND);
  536. break;
  537. }
  538. } while (FALSE);
  539. if ( pMachineName != NULL )
  540. {
  541. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start.")));
  542. NetApiBufferFree( pMachineName );
  543. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
  544. }
  545. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start.")));
  546. NetApiBufferFree( pBuffer );
  547. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
  548. }
  549. if ( err == NERR_Success )
  550. {
  551. if (iTheUserAlreadyExists)
  552. {
  553. // if the user already exists, then
  554. // don't change any rights or the group that its in leave it alone.
  555. TCHAR PrivilegeName[256];
  556. iTheUserIsMissingARight = FALSE;
  557. //#define SE_INTERACTIVE_LOGON_NAME TEXT("SeInteractiveLogonRight")
  558. //#define SE_NETWORK_LOGON_NAME TEXT("SeNetworkLogonRight")
  559. //#define SE_BATCH_LOGON_NAME TEXT("SeBatchLogonRight")
  560. _tcscpy(PrivilegeName, _T("SeNetworkLogonRight"));
  561. if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName))
  562. {
  563. iTheUserIsMissingARight = TRUE;
  564. }
  565. else
  566. {
  567. _tcscpy(PrivilegeName, _T("SeBatchLogonRight"));
  568. if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName))
  569. {
  570. iTheUserIsMissingARight = TRUE;
  571. }
  572. else
  573. {
  574. if (fiWamUser)
  575. {
  576. // make sure the iwam user has these additional rights
  577. // AssignPrimaryToken and IncreaseQuota privileges
  578. _tcscpy(PrivilegeName, _T("SeAssignPrimaryTokenPrivilege"));
  579. if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName))
  580. {
  581. iTheUserIsMissingARight = TRUE;
  582. }
  583. else
  584. {
  585. _tcscpy(PrivilegeName, _T("SeIncreaseQuotaPrivilege"));
  586. if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName))
  587. {
  588. iTheUserIsMissingARight = TRUE;
  589. }
  590. }
  591. }
  592. else
  593. {
  594. // make sure the iusr user has these additional rights
  595. _tcscpy(PrivilegeName, _T("SeInteractiveLogonRight"));
  596. if (FALSE == DoesUserHaveThisRight(szUsername, PrivilegeName))
  597. {
  598. iTheUserIsMissingARight = TRUE;
  599. }
  600. }
  601. }
  602. }
  603. // nope, we have to make sure that our iusr\iwam user has at least these
  604. // rights, because otherwise it won't work bug#361833
  605. if (iTheUserIsMissingARight == TRUE)
  606. {
  607. iisDebugOut((LOG_TYPE_TRACE, _T("Missing user right[%s]:resetting it."),PrivilegeName));
  608. RegisterAccountUserRights(szUsername, TRUE, fiWamUser);
  609. }
  610. // if its the the iwam user, then make sure they are not part of the Guests Group by removing them
  611. if (fiWamUser)
  612. {
  613. RegisterAccountToLocalGroup(szUsername, _T("Guests"), FALSE);
  614. }
  615. }
  616. else
  617. {
  618. // User was successfully newly created
  619. *NewlyCreated = 1;
  620. // add it to the guests group
  621. // (but don't do it for the iwam user)
  622. if (!fiWamUser)
  623. {
  624. RegisterAccountToLocalGroup(szUsername, _T("Guests"), TRUE);
  625. }
  626. // add certain user rights to this account
  627. RegisterAccountUserRights(szUsername, TRUE, fiWamUser);
  628. }
  629. }
  630. if (TRUE == iTheUserAlreadyExists)
  631. {*NewlyCreated = 2;}
  632. return err;
  633. }
  634. INT DeleteGuestUser(LPCTSTR szUsername, INT *UserWasDeleted)
  635. {
  636. iisDebugOut((LOG_TYPE_TRACE, _T("DeleteGuestUser:%s\n"), szUsername));
  637. INT err = NERR_Success;
  638. BYTE *pBuffer;
  639. *UserWasDeleted = 0;
  640. WCHAR wchUsername[UNLEN+1];
  641. #if defined(UNICODE) || defined(_UNICODE)
  642. wcsncpy(wchUsername, szUsername, UNLEN);
  643. #else
  644. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szUsername, -1, (LPWSTR)wchUsername, UNLEN);
  645. #endif
  646. if (FALSE == IsUserExist(wchUsername))
  647. {
  648. *UserWasDeleted = 1;
  649. iisDebugOut((LOG_TYPE_TRACE, _T("DeleteGuestUser return. %s doesn't exist.\n"), szUsername));
  650. return err;
  651. }
  652. // remove it from the guests group
  653. RegisterAccountToLocalGroup(szUsername, _T("Guests"), FALSE);
  654. // remove certain user rights of this account
  655. RegisterAccountUserRights(szUsername, FALSE, TRUE);
  656. do
  657. {
  658. WCHAR *pMachine = NULL;
  659. // make sure we are not backup docmain first
  660. iisDebugOut((LOG_TYPE_TRACE, _T("NetServerGetInfo:Start.\n")));
  661. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().Start.")));
  662. err = NetServerGetInfo( NULL, 101, &pBuffer );
  663. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetServerGetInfo().End.")));
  664. if (err != NERR_Success )
  665. {
  666. iisDebugOut((LOG_TYPE_ERROR, _T("NetServerGetInfo:failed.err=0x%x.\n"),err));
  667. break;
  668. }
  669. iisDebugOut((LOG_TYPE_TRACE, _T("NetServerGetInfo:End.\n")));
  670. LPSERVER_INFO_101 pInfo = (LPSERVER_INFO_101)pBuffer;
  671. if (( pInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL ) != 0 )
  672. {
  673. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():Start.\n")));
  674. NetGetDCName( NULL, NULL, (LPBYTE *)&pMachine);
  675. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():End.\n")));
  676. }
  677. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start.")));
  678. NetApiBufferFree( pBuffer );
  679. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
  680. iisDebugOut((LOG_TYPE_TRACE, _T("NetUserDel:Start.\n")));
  681. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetUserDel().Start.")));
  682. INT err = ::NetUserDel( pMachine, wchUsername );
  683. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetUserDel().End.")));
  684. iisDebugOut((LOG_TYPE_TRACE, _T("NetUserDel:End.Ret=0x%x.\n"),err));
  685. if (err == NERR_Success)
  686. {
  687. *UserWasDeleted = 1;
  688. }
  689. if ( pMachine != NULL )
  690. {
  691. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().Start.")));
  692. NetApiBufferFree( pMachine );
  693. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("NETAPI32.dll:NetApiBufferFree().End.")));
  694. }
  695. } while(FALSE);
  696. iisDebugOut((LOG_TYPE_TRACE, _T("DeleteGuestUser:%s. End. Return 0x%x\n"), szUsername, err));
  697. return err;
  698. }
  699. BOOL GuestAccEnabled()
  700. {
  701. BOOL fEnabled = FALSE;
  702. INT err = NERR_Success;
  703. BYTE *pBuffer;
  704. WCHAR defGuest[UNLEN+1];
  705. GetGuestUserName(defGuest);
  706. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserGetInfo:Start.\n")));
  707. err = NetUserGetInfo( NULL, defGuest, 3, &pBuffer );
  708. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetUserGetInfo:End.Ret=0x%x.\n"),err));
  709. if ( err == NERR_Success )
  710. {
  711. USER_INFO_3 *lpui3 = (USER_INFO_3 *)pBuffer;
  712. fEnabled = ( lpui3->usri3_flags & UF_ACCOUNTDISABLE ) == 0;
  713. }
  714. return fEnabled;
  715. }
  716. NET_API_STATUS
  717. NetpNtStatusToApiStatus (
  718. IN NTSTATUS NtStatus
  719. )
  720. /*++
  721. Routine Description:
  722. This function takes an NT status code and maps it to the appropriate
  723. LAN Man error code.
  724. Arguments:
  725. NtStatus - Supplies the NT status.
  726. Return Value:
  727. Returns the appropriate LAN Man error code for the NT status.
  728. --*/
  729. {
  730. NET_API_STATUS error;
  731. //
  732. // A small optimization for the most common case.
  733. //
  734. if ( NtStatus == STATUS_SUCCESS ) {
  735. return NERR_Success;
  736. }
  737. switch ( NtStatus ) {
  738. case STATUS_BUFFER_TOO_SMALL :
  739. return NERR_BufTooSmall;
  740. case STATUS_FILES_OPEN :
  741. return NERR_OpenFiles;
  742. case STATUS_CONNECTION_IN_USE :
  743. return NERR_DevInUse;
  744. case STATUS_INVALID_LOGON_HOURS :
  745. return NERR_InvalidLogonHours;
  746. case STATUS_INVALID_WORKSTATION :
  747. return NERR_InvalidWorkstation;
  748. case STATUS_PASSWORD_EXPIRED :
  749. return NERR_PasswordExpired;
  750. case STATUS_ACCOUNT_EXPIRED :
  751. return NERR_AccountExpired;
  752. case STATUS_REDIRECTOR_NOT_STARTED :
  753. return NERR_NetNotStarted;
  754. case STATUS_GROUP_EXISTS:
  755. return NERR_GroupExists;
  756. case STATUS_INTERNAL_DB_CORRUPTION:
  757. return NERR_InvalidDatabase;
  758. case STATUS_INVALID_ACCOUNT_NAME:
  759. return NERR_BadUsername;
  760. case STATUS_INVALID_DOMAIN_ROLE:
  761. case STATUS_INVALID_SERVER_STATE:
  762. case STATUS_BACKUP_CONTROLLER:
  763. return NERR_NotPrimary;
  764. case STATUS_INVALID_DOMAIN_STATE:
  765. return NERR_ACFNotLoaded;
  766. case STATUS_MEMBER_IN_GROUP:
  767. return NERR_UserInGroup;
  768. case STATUS_MEMBER_NOT_IN_GROUP:
  769. return NERR_UserNotInGroup;
  770. case STATUS_NONE_MAPPED:
  771. case STATUS_NO_SUCH_GROUP:
  772. return NERR_GroupNotFound;
  773. case STATUS_SPECIAL_GROUP:
  774. case STATUS_MEMBERS_PRIMARY_GROUP:
  775. return NERR_SpeGroupOp;
  776. case STATUS_USER_EXISTS:
  777. return NERR_UserExists;
  778. case STATUS_NO_SUCH_USER:
  779. return NERR_UserNotFound;
  780. case STATUS_PRIVILEGE_NOT_HELD:
  781. return ERROR_ACCESS_DENIED;
  782. case STATUS_LOGON_SERVER_CONFLICT:
  783. return NERR_LogonServerConflict;
  784. case STATUS_TIME_DIFFERENCE_AT_DC:
  785. return NERR_TimeDiffAtDC;
  786. case STATUS_SYNCHRONIZATION_REQUIRED:
  787. return NERR_SyncRequired;
  788. case STATUS_WRONG_PASSWORD_CORE:
  789. return NERR_BadPasswordCore;
  790. case STATUS_DOMAIN_CONTROLLER_NOT_FOUND:
  791. return NERR_DCNotFound;
  792. case STATUS_PASSWORD_RESTRICTION:
  793. return NERR_PasswordTooShort;
  794. case STATUS_ALREADY_DISCONNECTED:
  795. return NERR_Success;
  796. default:
  797. //
  798. // Use the system routine to do the mapping to ERROR_ codes.
  799. //
  800. #ifndef WIN32_CHICAGO
  801. error = RtlNtStatusToDosError( NtStatus );
  802. if ( error != (NET_API_STATUS)NtStatus ) {
  803. return error;
  804. }
  805. #endif // WIN32_CHICAGO
  806. //
  807. // Could not map the NT status to anything appropriate.
  808. // Write this to the eventlog file
  809. //
  810. return NERR_InternalError;
  811. }
  812. } // NetpNtStatusToApiStatus
  813. NET_API_STATUS
  814. UaspGetDomainId(
  815. IN LPCWSTR ServerName OPTIONAL,
  816. OUT PSAM_HANDLE SamServerHandle OPTIONAL,
  817. OUT PPOLICY_ACCOUNT_DOMAIN_INFO * AccountDomainInfo
  818. )
  819. /*++
  820. Routine Description:
  821. Return a domain ID of the account domain of a server.
  822. Arguments:
  823. ServerName - A pointer to a string containing the name of the
  824. Domain Controller (DC) to query. A NULL pointer
  825. or string specifies the local machine.
  826. SamServerHandle - Returns the SAM connection handle if the caller wants it.
  827. DomainId - Receives a pointer to the domain ID.
  828. Caller must deallocate buffer using NetpMemoryFree.
  829. Return Value:
  830. Error code for the operation.
  831. --*/
  832. {
  833. NET_API_STATUS NetStatus;
  834. NTSTATUS Status;
  835. SAM_HANDLE LocalSamHandle = NULL;
  836. ACCESS_MASK LSADesiredAccess;
  837. LSA_HANDLE LSAPolicyHandle = NULL;
  838. OBJECT_ATTRIBUTES LSAObjectAttributes;
  839. UNICODE_STRING ServerNameString;
  840. //
  841. // Connect to the SAM server
  842. //
  843. RtlInitUnicodeString( &ServerNameString, ServerName );
  844. Status = SamConnect(
  845. &ServerNameString,
  846. &LocalSamHandle,
  847. SAM_SERVER_LOOKUP_DOMAIN,
  848. NULL);
  849. if ( !NT_SUCCESS(Status))
  850. {
  851. LocalSamHandle = NULL;
  852. NetStatus = NetpNtStatusToApiStatus( Status );
  853. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("UaspGetDomainId: Cannot connect to Sam. err=0x%x\n"),NetStatus));
  854. goto Cleanup;
  855. }
  856. //
  857. // Open LSA to read account domain info.
  858. //
  859. if ( AccountDomainInfo != NULL) {
  860. //
  861. // set desired access mask.
  862. //
  863. LSADesiredAccess = POLICY_VIEW_LOCAL_INFORMATION;
  864. InitializeObjectAttributes( &LSAObjectAttributes,
  865. NULL, // Name
  866. 0, // Attributes
  867. NULL, // Root
  868. NULL ); // Security Descriptor
  869. Status = LsaOpenPolicy( &ServerNameString,
  870. &LSAObjectAttributes,
  871. LSADesiredAccess,
  872. &LSAPolicyHandle );
  873. if( !NT_SUCCESS(Status) ) {
  874. NetStatus = NetpNtStatusToApiStatus( Status );
  875. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("UaspGetDomainId: Cannot open LSA Policy %lX\n"),NetStatus));
  876. goto Cleanup;
  877. }
  878. //
  879. // now read account domain info from LSA.
  880. //
  881. Status = LsaQueryInformationPolicy(
  882. LSAPolicyHandle,
  883. PolicyAccountDomainInformation,
  884. (PVOID *) AccountDomainInfo );
  885. if( !NT_SUCCESS(Status) ) {
  886. NetStatus = NetpNtStatusToApiStatus( Status );
  887. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("UaspGetDomainId: Cannot read LSA.Err=0x%x.\n"),NetStatus));
  888. goto Cleanup;
  889. }
  890. }
  891. //
  892. // Return the SAM connection handle to the caller if he wants it.
  893. // Otherwise, disconnect from SAM.
  894. //
  895. if ( ARGUMENT_PRESENT( SamServerHandle ) ) {
  896. *SamServerHandle = LocalSamHandle;
  897. LocalSamHandle = NULL;
  898. }
  899. NetStatus = NERR_Success;
  900. //
  901. // Cleanup locally used resources
  902. //
  903. Cleanup:
  904. if ( LocalSamHandle != NULL ) {
  905. (VOID) SamCloseHandle( LocalSamHandle );
  906. }
  907. if( LSAPolicyHandle != NULL ) {
  908. LsaClose( LSAPolicyHandle );
  909. }
  910. return NetStatus;
  911. } // UaspGetDomainId
  912. NET_API_STATUS
  913. SampCreateFullSid(
  914. IN PSID DomainSid,
  915. IN ULONG Rid,
  916. OUT PSID *AccountSid
  917. )
  918. /*++
  919. Routine Description:
  920. This function creates a domain account sid given a domain sid and
  921. the relative id of the account within the domain.
  922. The returned Sid may be freed with LocalFree.
  923. --*/
  924. {
  925. NET_API_STATUS NetStatus;
  926. NTSTATUS IgnoreStatus;
  927. UCHAR AccountSubAuthorityCount;
  928. ULONG AccountSidLength;
  929. PULONG RidLocation;
  930. //
  931. // Calculate the size of the new sid
  932. //
  933. AccountSubAuthorityCount = *RtlSubAuthorityCountSid(DomainSid) + (UCHAR)1;
  934. AccountSidLength = RtlLengthRequiredSid(AccountSubAuthorityCount);
  935. //
  936. // Allocate space for the account sid
  937. //
  938. *AccountSid = LocalAlloc(LMEM_ZEROINIT,AccountSidLength);
  939. if (*AccountSid == NULL)
  940. {
  941. NetStatus = ERROR_NOT_ENOUGH_MEMORY;
  942. }
  943. else
  944. {
  945. //
  946. // Copy the domain sid into the first part of the account sid
  947. //
  948. IgnoreStatus = RtlCopySid(AccountSidLength, *AccountSid, DomainSid);
  949. ASSERT(NT_SUCCESS(IgnoreStatus));
  950. //
  951. // Increment the account sid sub-authority count
  952. //
  953. *RtlSubAuthorityCountSid(*AccountSid) = AccountSubAuthorityCount;
  954. //
  955. // Add the rid as the final sub-authority
  956. //
  957. RidLocation = RtlSubAuthoritySid(*AccountSid, AccountSubAuthorityCount-1);
  958. *RidLocation = Rid;
  959. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("AccountSid=0x%x"),*AccountSid));
  960. NetStatus = NERR_Success;
  961. }
  962. return(NetStatus);
  963. }
  964. int GetGuestUserNameForDomain_FastWay(LPTSTR szDomainToLookUp,LPTSTR lpGuestUsrName)
  965. {
  966. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain_FastWay.start.domain=%s\n"),szDomainToLookUp));
  967. int iReturn = FALSE;
  968. NET_API_STATUS NetStatus;
  969. // for UaspGetDomainId()
  970. SAM_HANDLE SamServerHandle = NULL;
  971. PPOLICY_ACCOUNT_DOMAIN_INFO pAccountDomainInfo;
  972. PSID pAccountSid = NULL;
  973. PSID pDomainSid = NULL;
  974. // for LookupAccountSid()
  975. SID_NAME_USE sidNameUse = SidTypeUser;
  976. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  977. TCHAR szUserName[UNLEN+1];
  978. DWORD cbName = UNLEN+1;
  979. // must be big enough to hold something bigger than DNLen since LookupAccountSid may returnn something really big.
  980. TCHAR szReferencedDomainName[200];
  981. DWORD cbReferencedDomainName = sizeof(szReferencedDomainName);
  982. ASSERT(lpGuestUsrName);
  983. // make sure not to return back gobble-d-gook
  984. _tcscpy(lpGuestUsrName, _T(""));
  985. //
  986. // Get the Sid for the specified Domain
  987. //
  988. // szDomainToLookUp=NULL for local machine
  989. NetStatus = UaspGetDomainId( szDomainToLookUp,&SamServerHandle,&pAccountDomainInfo );
  990. if ( NetStatus != NERR_Success )
  991. {
  992. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain:UaspGetDomainId failed.ret=0x%x."),NetStatus));
  993. goto GetGuestUserNameForDomain_FastWay_Exit;
  994. }
  995. pDomainSid = pAccountDomainInfo->DomainSid;
  996. //
  997. // Use the Domain Sid and the well known Guest RID to create the Real Guest Sid
  998. //
  999. // Well-known users ...
  1000. // DOMAIN_USER_RID_ADMIN (0x000001F4L)
  1001. // DOMAIN_USER_RID_GUEST (0x000001F5L)
  1002. NetStatus = NERR_InternalError;
  1003. NetStatus = SampCreateFullSid(pDomainSid, DOMAIN_USER_RID_GUEST, &pAccountSid);
  1004. if ( NetStatus != NERR_Success )
  1005. {
  1006. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain:SampCreateFullSid failed.ret=0x%x."),NetStatus));
  1007. goto GetGuestUserNameForDomain_FastWay_Exit;
  1008. }
  1009. //
  1010. // Check if the SID is valid
  1011. //
  1012. if (0 == IsValidSid(pAccountSid))
  1013. {
  1014. DWORD dwErr = GetLastError();
  1015. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain:IsValidSid FAILED. GetLastError()= 0x%x\n"), dwErr));
  1016. goto GetGuestUserNameForDomain_FastWay_Exit;
  1017. }
  1018. //
  1019. // Retrieve the UserName for the specified SID
  1020. //
  1021. _tcscpy(szUserName, _T(""));
  1022. _tcscpy(szReferencedDomainName, _T(""));
  1023. // szDomainToLookUp=NULL for local machine
  1024. if (!LookupAccountSid(szDomainToLookUp, pAccountSid, szUserName, &cbName, szReferencedDomainName, &cbReferencedDomainName, &sidNameUse))
  1025. {
  1026. DWORD dwErr = GetLastError();
  1027. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("GetGuestUserNameForDomain:LookupAccountSid FAILED. GetLastError()= 0x%x\n"), dwErr));
  1028. goto GetGuestUserNameForDomain_FastWay_Exit;
  1029. }
  1030. //iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain:szDomainToLookUp=%s\n"),szDomainToLookUp));
  1031. //iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain:pAccountSid=0x%x\n"),pAccountSid));
  1032. //iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain:szUserName=%s\n"),szUserName));
  1033. //iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain:szReferencedDomainName=%s\n"),szReferencedDomainName));
  1034. // Return the guest user name that we got.
  1035. _tcscpy(lpGuestUsrName, szUserName);
  1036. // Wow, after all that, we must have succeeded
  1037. iReturn = TRUE;
  1038. GetGuestUserNameForDomain_FastWay_Exit:
  1039. // Free the Domain info if we got some
  1040. if (pAccountDomainInfo) {NetpMemoryFree(pAccountDomainInfo);}
  1041. // Free the sid if we had allocated one
  1042. if (pAccountSid) {LocalFree(pAccountSid);}
  1043. iisDebugOut((LOG_TYPE_TRACE, _T("GetGuestUserNameForDomain_FastWay.end.domain=%s.ret=%d.\n"),szDomainToLookUp,iReturn));
  1044. return iReturn;
  1045. }
  1046. void GetGuestUserName(LPTSTR lpOutGuestUsrName)
  1047. {
  1048. // try to retrieve the guest username the fast way
  1049. // meaning = lookup the domain sid, and the well known guest rid, to get the guest sid.
  1050. // then look it up. The reason for this function is that on large domains with mega users
  1051. // the account can be quickly looked up.
  1052. TCHAR szGuestUsrName[UNLEN+1];
  1053. LPTSTR pszComputerName = NULL;
  1054. if (!GetGuestUserNameForDomain_FastWay(pszComputerName,szGuestUsrName))
  1055. {
  1056. iisDebugOut((LOG_TYPE_WARN, _T("GetGuestUserNameForDomain_FastWay:Did not succeed use slow way. WARNING.")));
  1057. // if the fast way failed for some reason, then let's do it
  1058. // the slow way, since this way always used to work, only on large domains (1 mil users)
  1059. // it could take 24hrs (since this function actually enumerates thru the domain)
  1060. GetGuestUserName_SlowWay(szGuestUsrName);
  1061. }
  1062. // Return back the username
  1063. _tcscpy(lpOutGuestUsrName,szGuestUsrName);
  1064. return;
  1065. }
  1066. int ChangeUserPassword(IN LPTSTR szUserName, IN LPTSTR szNewPassword)
  1067. {
  1068. int iReturn = TRUE;
  1069. USER_INFO_1003 pi1003;
  1070. NET_API_STATUS nas;
  1071. TCHAR szRawComputerName[CNLEN + 10];
  1072. DWORD dwLen = CNLEN + 10;
  1073. TCHAR szComputerName[CNLEN + 10];
  1074. TCHAR szCopyOfUserName[UNLEN+10];
  1075. TCHAR szTempFullUserName[(CNLEN + 10) + (DNLEN+1)];
  1076. LPTSTR pch = NULL;
  1077. _tcscpy(szCopyOfUserName, szUserName);
  1078. //iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeUserPassword().Start.name=%s,pass=%s"),szCopyOfUserName,szNewPassword));
  1079. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeUserPassword().Start.name=%s"),szCopyOfUserName));
  1080. if ( !GetComputerName( szRawComputerName, &dwLen ))
  1081. {goto ChangeUserPassword_Exit;}
  1082. // Make a copy to be sure not to move the pointer around.
  1083. _tcscpy(szTempFullUserName, szCopyOfUserName);
  1084. // Check if there is a "\" in there.
  1085. pch = _tcschr(szTempFullUserName, _T('\\'));
  1086. if (pch)
  1087. {
  1088. // szCopyOfUserName should now go from something like this:
  1089. // mycomputer\myuser
  1090. // to this myuser
  1091. _tcscpy(szCopyOfUserName,pch+1);
  1092. // trim off the '\' character to leave just the domain\computername so we can check against it.
  1093. *pch = _T('\0');
  1094. // compare the szTempFullUserName with the local computername.
  1095. if (0 == _tcsicmp(szRawComputerName, szTempFullUserName))
  1096. {
  1097. // the computername\username has a hardcoded computername in it.
  1098. // lets try to get only the username
  1099. // look szCopyOfusername is already set
  1100. }
  1101. else
  1102. {
  1103. // the local computer machine name
  1104. // and the specified username are different, so get out
  1105. // and don't even try to change this user\password since
  1106. // it's probably a domain\username
  1107. // return true -- saying that we did in fact change the passoword.
  1108. // we really didn't but we can't
  1109. iReturn = TRUE;
  1110. goto ChangeUserPassword_Exit;
  1111. }
  1112. }
  1113. // Make sure the computername has a \\ in front of it
  1114. if ( szRawComputerName[0] != _T('\\') )
  1115. {_tcscpy(szComputerName,_T("\\\\"));}
  1116. _tcscat(szComputerName,szRawComputerName);
  1117. //
  1118. // administrative over-ride of existing password
  1119. //
  1120. // by this time szCopyOfUserName
  1121. // should not look like mycomputername\username but it should look like username.
  1122. pi1003.usri1003_password = szNewPassword;
  1123. nas = NetUserSetInfo(
  1124. szComputerName, // computer name
  1125. szCopyOfUserName, // username
  1126. 1003, // info level
  1127. (LPBYTE)&pi1003, // new info
  1128. NULL
  1129. );
  1130. if(nas != NERR_Success)
  1131. {
  1132. iReturn = FALSE;
  1133. goto ChangeUserPassword_Exit;
  1134. }
  1135. ChangeUserPassword_Exit:
  1136. iisDebugOut((LOG_TYPE_TRACE_WIN32_API, _T("ChangeUserPassword().End.Ret=%d"),iReturn));
  1137. return iReturn;
  1138. }
  1139. BOOL DoesUserHaveThisRight(LPCTSTR szAccountName, LPTSTR PrivilegeName)
  1140. {
  1141. iisDebugOut((LOG_TYPE_TRACE, _T("DoesUserHaveBasicRights:Account=%s\n"), szAccountName));
  1142. int err;
  1143. BOOL fEnabled = FALSE;
  1144. NTSTATUS status;
  1145. LSA_UNICODE_STRING UserRightString;
  1146. // Create a LSA_UNICODE_STRING for the privilege name.
  1147. InitLsaString(&UserRightString, PrivilegeName);
  1148. // get the sid of szAccountName
  1149. PSID pSID = NULL;
  1150. BOOL bWellKnownSID = FALSE;
  1151. err = GetPrincipalSID ((LPTSTR)szAccountName, &pSID, &bWellKnownSID);
  1152. if (err != ERROR_SUCCESS)
  1153. {
  1154. iisDebugOut((LOG_TYPE_ERROR, _T("DoesUserHaveBasicRights:GetPrincipalSID:Account=%s, err=%d.\n"), szAccountName, err));
  1155. return (err);
  1156. }
  1157. LSA_HANDLE PolicyHandle = NULL;
  1158. err = OpenPolicy(NULL, POLICY_ALL_ACCESS,&PolicyHandle);
  1159. if ( err == NERR_Success )
  1160. {
  1161. UINT i;
  1162. LSA_UNICODE_STRING *rgUserRights = NULL;
  1163. ULONG cRights;
  1164. status = LsaEnumerateAccountRights(
  1165. PolicyHandle,
  1166. pSID,
  1167. &rgUserRights,
  1168. &cRights);
  1169. if (status==STATUS_OBJECT_NAME_NOT_FOUND)
  1170. {
  1171. // no rights/privileges for this account
  1172. fEnabled = FALSE;
  1173. }
  1174. else if (!NT_SUCCESS(status))
  1175. {
  1176. iisDebugOut((LOG_TYPE_ERROR, _T("DoesUserHaveBasicRights:GetPrincipalSID:Failed to enumerate rights: status 0x%08lx\n"), status));
  1177. goto DoesUserHaveBasicRights_Exit;
  1178. }
  1179. for(i=0; i < cRights; i++)
  1180. {
  1181. if ( RtlEqualUnicodeString(&rgUserRights[i],&UserRightString,FALSE) )
  1182. {
  1183. fEnabled = TRUE;
  1184. break;
  1185. }
  1186. }
  1187. if (rgUserRights) {LsaFreeMemory(rgUserRights);}
  1188. }
  1189. DoesUserHaveBasicRights_Exit:
  1190. if (PolicyHandle){LsaClose(PolicyHandle);}
  1191. if (pSID)
  1192. {
  1193. if (bWellKnownSID){FreeSid (pSID);}
  1194. else{free (pSID);}
  1195. }
  1196. return (fEnabled);
  1197. }
  1198. HRESULT CreateGroup(LPTSTR szGroupName, LPCTSTR szGroupComment, int iAction)
  1199. {
  1200. HRESULT hr = S_OK;
  1201. NET_API_STATUS dwRes;
  1202. LOCALGROUP_INFO_1 MyLocalGroup;
  1203. WCHAR wszLocalGroupName[_MAX_PATH];
  1204. WCHAR wszLocalGroupComment[_MAX_PATH];
  1205. memset(&MyLocalGroup, 0, sizeof(MyLocalGroup));
  1206. #if defined(UNICODE) || defined(_UNICODE)
  1207. _tcscpy(wszLocalGroupName, szGroupName);
  1208. _tcscpy(wszLocalGroupComment, szGroupComment);
  1209. #else
  1210. MultiByteToWideChar( CP_ACP, 0, szGroupName, -1, wszLocalGroupName, _MAX_PATH);
  1211. MultiByteToWideChar( CP_ACP, 0, szGroupComment, -1, wszLocalGroupComment, _MAX_PATH);
  1212. #endif
  1213. MyLocalGroup.lgrpi1_name = (LPWSTR)szGroupName;
  1214. MyLocalGroup.lgrpi1_comment = (LPWSTR)szGroupComment;
  1215. if (iAction)
  1216. {
  1217. dwRes = ::NetLocalGroupAdd( NULL, 1, (LPBYTE)&MyLocalGroup, NULL );
  1218. if(dwRes != NERR_Success &&
  1219. dwRes != NERR_GroupExists &&
  1220. dwRes != ERROR_ALIAS_EXISTS )
  1221. {
  1222. hr = HRESULT_FROM_WIN32(dwRes);
  1223. }
  1224. }
  1225. else
  1226. {
  1227. dwRes = ::NetLocalGroupDel( NULL, wszLocalGroupName);
  1228. if(dwRes != NERR_Success &&
  1229. dwRes != NERR_GroupNotFound &&
  1230. dwRes != ERROR_NO_SUCH_ALIAS )
  1231. {
  1232. hr = HRESULT_FROM_WIN32(dwRes);
  1233. }
  1234. }
  1235. return hr;
  1236. }
  1237. int CreateGroupDC(LPTSTR szGroupName, LPCTSTR szGroupComment)
  1238. {
  1239. int iReturn = FALSE;
  1240. GROUP_INFO_1 GI1;
  1241. ULONG BadParm;
  1242. WCHAR * pMachineName = NULL;
  1243. ULONG ulErr = ERROR_SUCCESS;
  1244. WCHAR wszLocalGroupName[_MAX_PATH];
  1245. WCHAR wszLocalGroupComment[_MAX_PATH];
  1246. memset(&GI1, 0, sizeof(GROUP_INFO_1));
  1247. #if defined(UNICODE) || defined(_UNICODE)
  1248. _tcscpy(wszLocalGroupName, szGroupName);
  1249. _tcscpy(wszLocalGroupComment, szGroupComment);
  1250. #else
  1251. MultiByteToWideChar( CP_ACP, 0, szGroupName, -1, wszLocalGroupName, _MAX_PATH);
  1252. MultiByteToWideChar( CP_ACP, 0, szGroupComment, -1, wszLocalGroupComment, _MAX_PATH);
  1253. #endif
  1254. GI1.grpi1_name = wszLocalGroupName;
  1255. GI1.grpi1_comment = wszLocalGroupComment;
  1256. iisDebugOut((LOG_TYPE_TRACE, _T("CreateGroup:NetGroupAdd\n")));
  1257. ulErr = NetGroupAdd(NULL,1,(PBYTE)&GI1,&BadParm);
  1258. iisDebugOut((LOG_TYPE_TRACE, _T("CreateGroup:NetGroupAdd,ret=0x%x\n"),ulErr));
  1259. switch (ulErr)
  1260. {
  1261. case NERR_Success:
  1262. iisDebugOut((LOG_TYPE_TRACE, _T("CreateGroup:NetGroupAdd,success\n"),ulErr));
  1263. iReturn = TRUE;
  1264. break;
  1265. case NERR_GroupExists:
  1266. iReturn = TRUE;
  1267. break;
  1268. case NERR_InvalidComputer:
  1269. iReturn = FALSE;
  1270. break;
  1271. case NERR_NotPrimary:
  1272. {
  1273. // it is a backup dc
  1274. int err;
  1275. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():Start.\n")));
  1276. err = NetGetDCName( NULL, NULL, (LPBYTE *)&pMachineName );
  1277. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGetDCName():End.Ret=0x%x\n"),err));
  1278. if (err != NERR_Success)
  1279. {
  1280. MyMessageBox(NULL, _T("CreateUser:NetGetDCName"), err, MB_OK | MB_SETFOREGROUND);
  1281. }
  1282. else
  1283. {
  1284. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGroupAdd().Start.")));
  1285. ulErr = NetGroupAdd(pMachineName,1,(PBYTE)&GI1,&BadParm);
  1286. iisDebugOut((LOG_TYPE_TRACE, _T("NETAPI32.dll:NetGroupAdd().End.")));
  1287. if (NERR_Success == ulErr || NERR_GroupExists == ulErr)
  1288. {
  1289. iReturn = TRUE;
  1290. }
  1291. }
  1292. }
  1293. break;
  1294. case ERROR_ACCESS_DENIED:
  1295. iReturn = FALSE;
  1296. break;
  1297. default:
  1298. iReturn = FALSE;
  1299. break;
  1300. }
  1301. return iReturn;
  1302. }
  1303. #endif //_CHICAGO_