Leaked source code of windows server 2003
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.

1492 lines
48 KiB

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