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.

1533 lines
42 KiB

  1. /*
  2. File userdb.c
  3. Implementation of the local user database object.
  4. Paul Mayfield, 10/8/97
  5. */
  6. #include "rassrv.h"
  7. // Registry values
  8. extern WCHAR pszregRasParameters[];
  9. extern WCHAR pszregServerFlags[];
  10. extern WCHAR pszregPure[];
  11. // Cached values for users
  12. typedef struct _RASSRV_USERINFO
  13. {
  14. HANDLE hUser; // Handle to user
  15. PWCHAR pszName;
  16. PWCHAR pszFullName; // Only loaded if requested
  17. //gangz for secure password bug
  18. //Change this for the new safe encoding password functions
  19. WCHAR szPassword[PWLEN+1]; // Only non-null if this is new password to be committed
  20. WCHAR wszPhoneNumber[MAX_PHONE_NUMBER_LEN + 1];
  21. BYTE bfPrivilege;
  22. BYTE bDirty;
  23. } RASSRV_USERINFO;
  24. // Structure used to implement/manipulate the local user database
  25. typedef struct _RASSRV_USERDB
  26. {
  27. HANDLE hServer; // Handle to user server
  28. DWORD dwUserCount; // Number of users in the database
  29. DWORD dwCacheSize; // Number of users can be stored in cache
  30. BOOL bEncrypt; // Whether encryption should be used
  31. BOOL bDccBypass; // Whether dcc connections can bypass auth.
  32. BOOL bPure; // Whether database is "Pure"
  33. BOOL bEncSettingLoaded; // Whether we've read in the enc setting
  34. BOOL bFlushOnClose;
  35. RASSRV_USERINFO ** pUserCache; // Cache of users
  36. } RASSRV_USERDB;
  37. // Defines a callback for enumerating users. Returns TRUE to continue the enueration
  38. // FALSE to stop it.
  39. typedef
  40. BOOL
  41. (* pEnumUserCb)(
  42. IN NET_DISPLAY_USER* pUser,
  43. IN HANDLE hData);
  44. // We use this to guess the size of the the user array
  45. // (so we can grow it when new users are added)
  46. #define USR_ARRAY_GROW_SIZE 50
  47. // Dirty flags
  48. #define USR_RASPROPS_DIRTY 0x1 // whether callback is dirty
  49. #define USR_FULLNAME_DIRTY 0x2 // whether full name needs to be flushed
  50. #define USR_PASSWORD_DIRTY 0x4 // whether password needs to be flushed
  51. #define USR_ADD_DIRTY 0x8 // whether user needs to be added
  52. // Helper macros for dealing with dirty flags
  53. #define usrDirtyRasProps(pUser) ((pUser)->bDirty |= USR_RASPROPS_DIRTY)
  54. #define usrDirtyFullname(pUser) ((pUser)->bDirty |= USR_FULLNAME_DIRTY)
  55. #define usrDirtyPassword(pUser) ((pUser)->bDirty |= USR_PASSWORD_DIRTY)
  56. #define usrDirtyAdd(pUser) ((pUser)->bDirty |= USR_ADD_DIRTY)
  57. #define usrIsDirty(pUser) ((pUser)->bDirty)
  58. #define usrIsRasPropsDirty(pUser) ((pUser)->bDirty & USR_RASPROPS_DIRTY)
  59. #define usrIsFullNameDirty(pUser) ((pUser)->bDirty & USR_FULLNAME_DIRTY)
  60. #define usrIsPasswordDirty(pUser) ((pUser)->bDirty & USR_PASSWORD_DIRTY)
  61. #define usrIsAddDirty(pUser) ((pUser)->bDirty & USR_ADD_DIRTY)
  62. #define usrClearDirty(pUser) ((pUser)->bDirty = 0)
  63. #define usrClearRasPropsDirty(pUser) ((pUser)->bDirty &= ~USR_CALLBACK_DIRTY)
  64. #define usrClearFullNameDirty(pUser) ((pUser)->bDirty &= ~USR_FULLNAME_DIRTY)
  65. #define usrClearPasswordDirty(pUser) ((pUser)->bDirty &= ~USR_PASSWORD_DIRTY)
  66. #define usrClearAddDirty(pUser) ((pUser)->bDirty &= ~USR_ADD_DIRTY)
  67. #define usrFlagIsSet(_val, _flag) (((_val) & (_flag)) != 0)
  68. #define usrFlagIsClear(_val, _flag) (((_val) & (_flag)) == 0)
  69. //
  70. // Reads in server flags and determines whether encrypted
  71. // password and data are required.
  72. //
  73. // lpdwFlags is assigned one of the following on success
  74. // 0 = data and pwd enc not required
  75. // MPR_USER_PROF_FLAG_SECURE = data and pwd enc required
  76. // MPR_USER_PROF_FLAG_UNDETERMINED = Can't say for sure
  77. //
  78. DWORD
  79. usrGetServerEnc(
  80. OUT LPDWORD lpdwFlags)
  81. {
  82. DWORD dwFlags = 0;
  83. if (!lpdwFlags)
  84. return ERROR_INVALID_PARAMETER;
  85. // Read in the flags
  86. RassrvRegGetDw(&dwFlags,
  87. 0,
  88. (const PWCHAR)pszregRasParameters,
  89. (const PWCHAR)pszregServerFlags);
  90. // The following bits will be set for secure auth.
  91. //
  92. if (
  93. (usrFlagIsSet (dwFlags, PPPCFG_NegotiateMSCHAP)) &&
  94. (usrFlagIsSet (dwFlags, PPPCFG_NegotiateStrongMSCHAP)) &&
  95. (usrFlagIsClear (dwFlags, PPPCFG_NegotiateMD5CHAP)) &&
  96. (usrFlagIsClear (dwFlags, PPPCFG_NegotiateSPAP)) &&
  97. (usrFlagIsClear (dwFlags, PPPCFG_NegotiateEAP)) &&
  98. (usrFlagIsClear (dwFlags, PPPCFG_NegotiatePAP))
  99. )
  100. {
  101. *lpdwFlags = MPR_USER_PROF_FLAG_SECURE;
  102. return NO_ERROR;
  103. }
  104. // The following bits will be set for insecure auth.
  105. //
  106. else if (
  107. (usrFlagIsSet (dwFlags, PPPCFG_NegotiateMSCHAP)) &&
  108. (usrFlagIsSet (dwFlags, PPPCFG_NegotiateStrongMSCHAP)) &&
  109. (usrFlagIsSet (dwFlags, PPPCFG_NegotiateSPAP)) &&
  110. (usrFlagIsSet (dwFlags, PPPCFG_NegotiatePAP)) &&
  111. (usrFlagIsClear (dwFlags, PPPCFG_NegotiateEAP)) &&
  112. (usrFlagIsClear (dwFlags, PPPCFG_NegotiateMD5CHAP))
  113. )
  114. {
  115. *lpdwFlags = 0; // data and pwd enc not required
  116. return NO_ERROR;
  117. }
  118. // Otherwise, we are undetermined
  119. *lpdwFlags = MPR_USER_PROF_FLAG_UNDETERMINED;
  120. return NO_ERROR;
  121. }
  122. //
  123. // Sets the encryption policy for the server
  124. //
  125. DWORD
  126. usrSetServerEnc(
  127. IN DWORD dwFlags)
  128. {
  129. DWORD dwSvrFlags = 0;
  130. // Read in the old flags
  131. RassrvRegGetDw(&dwSvrFlags,
  132. 0,
  133. (const PWCHAR)pszregRasParameters,
  134. (const PWCHAR)pszregServerFlags);
  135. // If the user requires encryption then set MSCHAP
  136. // and CHAP as the only authentication types and
  137. // set the ipsec flag.
  138. if (dwFlags & MPR_USER_PROF_FLAG_SECURE)
  139. {
  140. dwSvrFlags |= PPPCFG_NegotiateMSCHAP;
  141. dwSvrFlags |= PPPCFG_NegotiateStrongMSCHAP;
  142. dwSvrFlags &= ~PPPCFG_NegotiateMD5CHAP;
  143. dwSvrFlags &= ~PPPCFG_NegotiateSPAP;
  144. dwSvrFlags &= ~PPPCFG_NegotiateEAP;
  145. dwSvrFlags &= ~PPPCFG_NegotiatePAP;
  146. }
  147. // Otherwise, the user does require encryption,
  148. // so enable all authentication types and disable
  149. // the requirement to use IPSEC
  150. else
  151. {
  152. dwSvrFlags &= ~PPPCFG_NegotiateMD5CHAP;
  153. dwSvrFlags &= ~PPPCFG_NegotiateEAP;
  154. dwSvrFlags |= PPPCFG_NegotiateMSCHAP;
  155. dwSvrFlags |= PPPCFG_NegotiateStrongMSCHAP;
  156. dwSvrFlags |= PPPCFG_NegotiateSPAP;
  157. dwSvrFlags |= PPPCFG_NegotiatePAP;
  158. }
  159. // Commit changes to the registry
  160. RassrvRegSetDw(dwSvrFlags,
  161. (const PWCHAR)pszregRasParameters,
  162. (const PWCHAR)pszregServerFlags);
  163. return NO_ERROR;
  164. }
  165. // Enumerates the local users
  166. //
  167. DWORD
  168. usrEnumLocalUsers(
  169. IN pEnumUserCb pCbFunction,
  170. IN HANDLE hData)
  171. {
  172. DWORD dwErr, dwIndex = 0, dwCount = 100, dwEntriesRead, i;
  173. NET_DISPLAY_USER * pUsers;
  174. NET_API_STATUS nStatus;
  175. RAS_USER_0 RasUser0;
  176. HANDLE hUser = NULL, hServer = NULL;
  177. // Enumerate the users,
  178. while (TRUE)
  179. {
  180. // Read in the first block of user names
  181. nStatus = NetQueryDisplayInformation(
  182. NULL,
  183. 1,
  184. dwIndex,
  185. dwCount,
  186. dwCount * sizeof(NET_DISPLAY_USER),
  187. &dwEntriesRead,
  188. &pUsers);
  189. // Get out if there's an error getting user names
  190. if ((nStatus != NERR_Success) &&
  191. (nStatus != ERROR_MORE_DATA))
  192. {
  193. break;
  194. }
  195. // For each user read in, call the callback function
  196. for (i = 0; i < dwEntriesRead; i++)
  197. {
  198. BOOL bOk;
  199. //For whistler bug 243874 gangz
  200. //On whistler Personal version, we wont show the Administrator
  201. //in the user's listview on the Incoming connection's User Tab
  202. //
  203. if ( (DOMAIN_USER_RID_ADMIN == pUsers[i].usri1_user_id) &&
  204. IsPersonalPlatform() )
  205. {
  206. continue;
  207. }
  208. bOk = (*pCbFunction)(&(pUsers[i]), hData);
  209. if (bOk == FALSE)
  210. {
  211. nStatus = NERR_Success;
  212. break;
  213. }
  214. }
  215. // Set the index to read in the next set of users
  216. dwIndex = pUsers[dwEntriesRead - 1].usri1_next_index;
  217. // Free the users buffer
  218. NetApiBufferFree (pUsers);
  219. // If we've read in everybody, go ahead and break
  220. if (nStatus != ERROR_MORE_DATA)
  221. {
  222. break;
  223. }
  224. }
  225. return NO_ERROR;
  226. }
  227. // Copies the data in pRassrvUser to its equivalent in UserInfo
  228. DWORD
  229. usrSyncRasProps(
  230. IN RASSRV_USERINFO * pRassrvUser,
  231. OUT RAS_USER_0 * UserInfo)
  232. {
  233. UserInfo->bfPrivilege = pRassrvUser->bfPrivilege;
  234. lstrcpynW( UserInfo->wszPhoneNumber,
  235. pRassrvUser->wszPhoneNumber,
  236. MAX_PHONE_NUMBER_LEN);
  237. UserInfo->wszPhoneNumber[MAX_PHONE_NUMBER_LEN] = (WCHAR)0;
  238. return NO_ERROR;
  239. }
  240. // Commits the data for the given user to the local user database
  241. DWORD
  242. usrCommitRasProps(
  243. IN RASSRV_USERINFO * pRassrvUser)
  244. {
  245. DWORD dwErr = NO_ERROR;
  246. RAS_USER_0 UserInfo;
  247. dwErr = usrSyncRasProps(pRassrvUser, &UserInfo);
  248. if (dwErr != NO_ERROR)
  249. return dwErr;
  250. dwErr = MprAdminUserWrite(pRassrvUser->hUser, 0, (LPBYTE)&UserInfo);
  251. if (dwErr != NO_ERROR)
  252. DbgOutputTrace ("usrCommitRasProps: unable to commit %S (0x%08x)",
  253. pRassrvUser->pszName, dwErr);
  254. return dwErr;
  255. }
  256. // Simple bounds checking
  257. BOOL
  258. usrBoundsCheck(
  259. IN RASSRV_USERDB * This,
  260. IN DWORD dwIndex)
  261. {
  262. // Dwords are unsigned, so no need to check < 0
  263. if (This->dwUserCount <= dwIndex)
  264. return FALSE;
  265. return TRUE;
  266. }
  267. // Frees an array of users
  268. DWORD
  269. usrFreeUserArray(
  270. IN RASSRV_USERINFO ** pUsers,
  271. IN DWORD dwCount)
  272. {
  273. DWORD i;
  274. if (!pUsers)
  275. return ERROR_INVALID_PARAMETER;
  276. for (i=0; i < dwCount; i++) {
  277. if (pUsers[i]) {
  278. if (pUsers[i]->hUser)
  279. MprAdminUserClose(pUsers[i]->hUser);
  280. if (pUsers[i]->pszName)
  281. RassrvFree (pUsers[i]->pszName);
  282. if (pUsers[i]->pszFullName)
  283. RassrvFree (pUsers[i]->pszFullName);
  284. //Wipe password before free memory, if CryptProtectData() is used
  285. //this will also release the memory allocated by it
  286. SafeWipePasswordBuf(pUsers[i]->szPassword);
  287. RassrvFree(pUsers[i]);
  288. }
  289. }
  290. return NO_ERROR;
  291. }
  292. // Standard user comparison function used for sorting
  293. int _cdecl
  294. usrCompareUsers(
  295. IN const void * elem1,
  296. IN const void * elem2)
  297. {
  298. RASSRV_USERINFO* p1 = *((RASSRV_USERINFO**)elem1);
  299. RASSRV_USERINFO* p2 = *((RASSRV_USERINFO**)elem2);
  300. return lstrcmpi(p1->pszName, p2->pszName);
  301. }
  302. // Returns whether a given user exists
  303. BOOL
  304. usrUserExists (
  305. IN RASSRV_USERDB * This,
  306. IN PWCHAR pszName)
  307. {
  308. DWORD i;
  309. int iCmp;
  310. for (i = 0; i < This->dwUserCount; i++) {
  311. iCmp = lstrcmpi(This->pUserCache[i]->pszName, pszName);
  312. if (iCmp == 0)
  313. return TRUE;
  314. if (iCmp > 0)
  315. return FALSE;
  316. }
  317. return FALSE;
  318. }
  319. // Resorts the cache
  320. DWORD
  321. usrResortCache(
  322. IN RASSRV_USERDB * This)
  323. {
  324. qsort(
  325. This->pUserCache,
  326. This->dwUserCount,
  327. sizeof(RASSRV_USERINFO*),
  328. usrCompareUsers);
  329. return NO_ERROR;
  330. }
  331. // Resizes the user cache to allow for added users
  332. DWORD
  333. usrResizeCache(
  334. IN RASSRV_USERDB * This,
  335. IN DWORD dwNewSize)
  336. {
  337. RASSRV_USERINFO ** pNewCache;
  338. DWORD i;
  339. // Only resize bigger (this could be changed)
  340. if ((!This) || (dwNewSize <= This->dwCacheSize))
  341. return ERROR_INVALID_PARAMETER;
  342. // Allocate the new cache
  343. pNewCache = RassrvAlloc(dwNewSize * sizeof (RASSRV_USERINFO*), TRUE);
  344. if (pNewCache == NULL)
  345. return ERROR_NOT_ENOUGH_MEMORY;
  346. // Copy over the old entries and free the old cache
  347. if (This->pUserCache)
  348. {
  349. CopyMemory( (PVOID)pNewCache,
  350. (CONST VOID *)(This->pUserCache),
  351. This->dwCacheSize * sizeof(RASSRV_USERINFO*));
  352. RassrvFree(This->pUserCache);
  353. }
  354. // Reassign the new cache and update the cache size
  355. This->pUserCache = pNewCache;
  356. This->dwCacheSize = dwNewSize;
  357. return NO_ERROR;
  358. }
  359. // Enumeration callback that adds users to the local database
  360. // as they are read from the system.
  361. BOOL
  362. usrInitializeUser(
  363. NET_DISPLAY_USER * pNetUser,
  364. HANDLE hUserDatabase)
  365. {
  366. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  367. RASSRV_USERINFO * pRasUser = NULL;
  368. DWORD dwErr = NO_ERROR, dwSize;
  369. RAS_USER_0 UserInfo;
  370. // Make sure we have a valid database
  371. if (!This)
  372. {
  373. return FALSE;
  374. }
  375. // Resize the cache to accomodate more users if needed
  376. if (This->dwUserCount >= This->dwCacheSize)
  377. {
  378. dwErr = usrResizeCache(
  379. This,
  380. This->dwCacheSize + USR_ARRAY_GROW_SIZE);
  381. if (dwErr != NO_ERROR)
  382. {
  383. return FALSE;
  384. }
  385. }
  386. // Allocate this user
  387. pRasUser = RassrvAlloc(sizeof(RASSRV_USERINFO), TRUE);
  388. if (pRasUser == NULL)
  389. {
  390. return FALSE;
  391. }
  392. do
  393. {
  394. // Point to the user name
  395. dwSize = (wcslen(pNetUser->usri1_name) + 1) * sizeof(WCHAR);
  396. pRasUser->pszName = RassrvAlloc(dwSize, FALSE);
  397. if (!pRasUser->pszName)
  398. {
  399. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  400. break;
  401. }
  402. wcscpy(pRasUser->pszName, pNetUser->usri1_name);
  403. // Open the user handle
  404. dwErr = MprAdminUserOpen (
  405. This->hServer,
  406. pRasUser->pszName,
  407. &(pRasUser->hUser));
  408. if (dwErr != NO_ERROR)
  409. {
  410. break;
  411. }
  412. // Get the ras user info
  413. dwErr = MprAdminUserRead(pRasUser->hUser, 0, (LPBYTE)&UserInfo);
  414. if (dwErr != NO_ERROR)
  415. {
  416. break;
  417. }
  418. // Clear any dirty flags
  419. usrClearDirty(pRasUser);
  420. // Copy the phone number
  421. lstrcpynW(
  422. pRasUser->wszPhoneNumber,
  423. UserInfo.wszPhoneNumber,
  424. MAX_PHONE_NUMBER_LEN);
  425. pRasUser->wszPhoneNumber[MAX_PHONE_NUMBER_LEN] = (WCHAR)0;
  426. // Copy the privelege flags
  427. pRasUser->bfPrivilege = UserInfo.bfPrivilege;
  428. // Assign the user in the cache
  429. This->pUserCache[This->dwUserCount] = pRasUser;
  430. // Update the user count
  431. This->dwUserCount += 1;
  432. } while (FALSE);
  433. // Cleanup
  434. {
  435. if (dwErr != NO_ERROR)
  436. {
  437. if (pRasUser)
  438. {
  439. if (pRasUser->pszName)
  440. {
  441. RassrvFree(pRasUser->pszName);
  442. }
  443. RassrvFree(pRasUser);
  444. }
  445. }
  446. }
  447. return (dwErr == NO_ERROR) ? TRUE : FALSE;
  448. }
  449. //
  450. // Loads the global encryption setting. Because the operation opens
  451. // up .mdb files to read profiles, etc. it is put in its own function
  452. // and is called only when absolutely needed.
  453. //
  454. DWORD
  455. usrLoadEncryptionSetting(
  456. IN RASSRV_USERDB * This)
  457. {
  458. DWORD dwErr = NO_ERROR;
  459. DWORD dwSvrFlags, dwProfFlags;
  460. if (This->bEncSettingLoaded)
  461. {
  462. return NO_ERROR;
  463. }
  464. // Read in the encryption setting by combining the
  465. // server flags with the values in the default
  466. // profile.
  467. dwSvrFlags = MPR_USER_PROF_FLAG_UNDETERMINED;
  468. dwProfFlags = MPR_USER_PROF_FLAG_UNDETERMINED;
  469. MprAdminUserReadProfFlags (This->hServer, &dwProfFlags);
  470. usrGetServerEnc (&dwSvrFlags);
  471. // If both sources confirm the encryption requirement
  472. // then we require encryption
  473. if ((dwProfFlags & MPR_USER_PROF_FLAG_SECURE) &&
  474. (dwSvrFlags & MPR_USER_PROF_FLAG_SECURE))
  475. {
  476. This->bEncrypt = TRUE;
  477. }
  478. else
  479. {
  480. This->bEncrypt = FALSE;
  481. }
  482. This->bEncSettingLoaded = TRUE;
  483. return dwErr;
  484. }
  485. // Creates a user data base object, initializing it from the local
  486. // user database and returning a handle to it.
  487. DWORD
  488. usrOpenLocalDatabase (
  489. IN HANDLE * hUserDatabase)
  490. {
  491. RASSRV_USERDB * This = NULL;
  492. DWORD dwErr;
  493. if (!hUserDatabase)
  494. return ERROR_INVALID_PARAMETER;
  495. // Allocate the database
  496. if ((This = RassrvAlloc(sizeof(RASSRV_USERDB), TRUE)) == NULL)
  497. return ERROR_NOT_ENOUGH_MEMORY;
  498. // Connect to the user server
  499. dwErr = MprAdminUserServerConnect(NULL, TRUE, &(This->hServer));
  500. if (dwErr != NO_ERROR)
  501. {
  502. RassrvFree(This);
  503. return dwErr;
  504. }
  505. // Load in the data from the system
  506. if ((dwErr = usrReloadLocalDatabase((HANDLE)This)) == NO_ERROR) {
  507. *hUserDatabase = (HANDLE)This;
  508. This->bFlushOnClose = FALSE;
  509. return NO_ERROR;
  510. }
  511. DbgOutputTrace ("usrOpenLocalDb: unable to load user db 0x%08x",
  512. dwErr);
  513. RassrvFree(This);
  514. *hUserDatabase = NULL;
  515. return dwErr;
  516. }
  517. // Reloads the user information cached in the user database obj
  518. // from the system. This can be used to implement a refresh in the ui.
  519. //
  520. DWORD
  521. usrReloadLocalDatabase (
  522. IN HANDLE hUserDatabase)
  523. {
  524. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  525. DWORD dwErr;
  526. // Validate
  527. if (!This)
  528. {
  529. return ERROR_INVALID_PARAMETER;
  530. }
  531. // Cleanup the old database
  532. if (This->pUserCache)
  533. {
  534. usrFreeUserArray(This->pUserCache, This->dwUserCount);
  535. RassrvFree(This->pUserCache);
  536. }
  537. // The encryption setting is loaded on demand from the
  538. // usrGetEncryption/usrSetEncryption api's. This is a performance
  539. // tune so that the IC wizard wouldn't have to wait for
  540. // the profile to be loaded even though it doesn't use the result.
  541. // Read in the purity of the system
  542. {
  543. DWORD dwPure = 0;
  544. RassrvRegGetDw(&dwPure,
  545. 0,
  546. (const PWCHAR)pszregRasParameters,
  547. (const PWCHAR)pszregPure);
  548. if (dwPure == 1)
  549. This->bPure = FALSE;
  550. else
  551. This->bPure = TRUE;
  552. }
  553. // Read in whether dcc connections can be bypassed
  554. {
  555. DWORD dwSvrFlags = 0;
  556. RassrvRegGetDw(
  557. &dwSvrFlags,
  558. dwSvrFlags,
  559. (const PWCHAR)pszregRasParameters,
  560. (const PWCHAR)pszregServerFlags);
  561. if (dwSvrFlags & PPPCFG_AllowNoAuthOnDCPorts)
  562. This->bDccBypass = TRUE;
  563. else
  564. This->bDccBypass = FALSE;
  565. }
  566. // Enumerate the local users from the system adding them
  567. // to this database.
  568. dwErr = usrEnumLocalUsers(usrInitializeUser, hUserDatabase);
  569. if (dwErr != NO_ERROR)
  570. {
  571. return NO_ERROR;
  572. }
  573. return NO_ERROR;
  574. }
  575. // Frees up the resources held by a user database object.
  576. DWORD
  577. usrCloseLocalDatabase (
  578. IN HANDLE hUserDatabase)
  579. {
  580. DWORD i;
  581. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  582. // Make sure we were passed a valid handle
  583. if (!This)
  584. return ERROR_INVALID_PARAMETER;
  585. // We're done if there are no users
  586. if (!This->dwUserCount)
  587. return NO_ERROR;
  588. // Commit any settings as appropriate
  589. if (This->bFlushOnClose)
  590. usrFlushLocalDatabase(hUserDatabase);
  591. // Free the user cache
  592. usrFreeUserArray(This->pUserCache, This->dwUserCount);
  593. RassrvFree(This->pUserCache);
  594. // Disconnect from the user server
  595. MprAdminUserServerDisconnect (This->hServer);
  596. // Free This
  597. RassrvFree(This);
  598. return NO_ERROR;
  599. }
  600. // Flushes the data written to the database object
  601. DWORD
  602. usrFlushLocalDatabase (
  603. IN HANDLE hUserDatabase)
  604. {
  605. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  606. RASSRV_USERINFO * pUser;
  607. DWORD dwErr, dwRet = NO_ERROR, dwCount, i, dwLength;
  608. dwErr = usrGetUserCount (This, &dwCount);
  609. if (dwErr != NO_ERROR)
  610. return dwErr;
  611. for (i=0; i<dwCount; i++) {
  612. pUser = This->pUserCache[i];
  613. // Flush any dirty settings
  614. if (usrIsDirty(pUser)) {
  615. // Add the user to the local user database if it hasn't
  616. // already been done
  617. if (usrIsAddDirty(pUser))
  618. {
  619. //For secure password bug .Net 754400
  620. SafeDecodePasswordBuf(pUser->szPassword);
  621. dwErr = RasSrvAddUser (
  622. pUser->pszName,
  623. (pUser->pszFullName) ? pUser->pszFullName : L"",
  624. (L'\0'!=pUser->szPassword[0]) ? pUser->szPassword : L"");
  625. SafeEncodePasswordBuf(pUser->szPassword);
  626. if (dwErr != NO_ERROR)
  627. dwRet = dwErr;
  628. // Now get the SDO handle to the user
  629. // so we can commit ras properties below.
  630. dwErr = MprAdminUserOpen (
  631. This->hServer,
  632. pUser->pszName,
  633. &(pUser->hUser));
  634. if (dwErr != NO_ERROR)
  635. continue;
  636. }
  637. // Flush dirty callback properties
  638. if (usrIsRasPropsDirty(pUser)) {
  639. if ((dwErr = usrCommitRasProps(This->pUserCache[i])) != NO_ERROR)
  640. dwRet = dwErr;
  641. }
  642. // Flush dirty password and full name settings
  643. if (usrIsFullNameDirty(pUser) || usrIsPasswordDirty(pUser)) {
  644. SafeDecodePasswordBuf(pUser->szPassword);
  645. RasSrvEditUser (
  646. pUser->pszName,
  647. (usrIsFullNameDirty(pUser)) ? pUser->pszFullName : NULL,
  648. (usrIsPasswordDirty(pUser)) ? pUser->szPassword : NULL);
  649. SafeEncodePasswordBuf(pUser->szPassword);
  650. }
  651. // Reset the user as not being dirty
  652. usrClearDirty(pUser);
  653. }
  654. }
  655. // Flush the encryption setting if it has been read
  656. if (This->bEncSettingLoaded)
  657. {
  658. DWORD dwFlags;
  659. if (This->bEncrypt)
  660. dwFlags = MPR_USER_PROF_FLAG_SECURE;
  661. else
  662. dwFlags = 0;
  663. MprAdminUserWriteProfFlags (This->hServer, dwFlags);
  664. usrSetServerEnc(dwFlags);
  665. }
  666. // Flush out the purity of the system
  667. {
  668. DWORD dwPure = 0;
  669. if (This->bPure)
  670. dwPure = 0;
  671. else
  672. dwPure = 1;
  673. RassrvRegSetDw(dwPure,
  674. (const PWCHAR)pszregRasParameters,
  675. (const PWCHAR)pszregPure);
  676. }
  677. // Flush out whether dcc connections can be bypassed
  678. {
  679. DWORD dwSvrFlags = 0;
  680. RassrvRegGetDw(
  681. &dwSvrFlags,
  682. dwSvrFlags,
  683. (const PWCHAR)pszregRasParameters,
  684. (const PWCHAR)pszregServerFlags);
  685. if (This->bDccBypass)
  686. dwSvrFlags |= PPPCFG_AllowNoAuthOnDCPorts;
  687. else
  688. dwSvrFlags &= ~PPPCFG_AllowNoAuthOnDCPorts;
  689. RassrvRegSetDw(
  690. dwSvrFlags,
  691. (const PWCHAR)pszregRasParameters,
  692. (const PWCHAR)pszregServerFlags);
  693. }
  694. return dwRet;
  695. }
  696. // Rolls back the local user database so that no
  697. // changes will be committed when Flush is called.
  698. DWORD
  699. usrRollbackLocalDatabase (
  700. IN HANDLE hUserDatabase)
  701. {
  702. DWORD i, dwIndex, dwErr;
  703. BOOL bCommit;
  704. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  705. if (!This)
  706. return ERROR_INVALID_PARAMETER;
  707. if (!This->dwUserCount)
  708. return NO_ERROR;
  709. // Go through the database, marking each user as not dirty
  710. for (i = 0; i < This->dwUserCount; i++)
  711. usrClearDirty(This->pUserCache[i]);
  712. This->bFlushOnClose = FALSE;
  713. return NO_ERROR;
  714. }
  715. //
  716. // Determines whether all users are required to encrypt
  717. // their data and passwords.
  718. //
  719. DWORD usrGetEncryption (
  720. IN HANDLE hUserDatabase,
  721. OUT PBOOL pbEncrypted)
  722. {
  723. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  724. if (!This)
  725. {
  726. return ERROR_INVALID_PARAMETER;
  727. }
  728. // Load in the encryption setting
  729. usrLoadEncryptionSetting(This);
  730. *pbEncrypted = This->bEncrypt;
  731. return NO_ERROR;
  732. }
  733. // Gets user encryption setting
  734. DWORD
  735. usrSetEncryption (
  736. IN HANDLE hUserDatabase,
  737. IN BOOL bEncrypt)
  738. {
  739. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  740. if (!This)
  741. {
  742. return ERROR_INVALID_PARAMETER;
  743. }
  744. // Load in the encryption setting
  745. usrLoadEncryptionSetting(This);
  746. This->bEncrypt = bEncrypt;
  747. return NO_ERROR;
  748. }
  749. // Returns whether dcc connections are allowed to
  750. // bypass authentication
  751. DWORD
  752. usrGetDccBypass (
  753. IN HANDLE hUserDatabase,
  754. OUT PBOOL pbBypass)
  755. {
  756. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  757. if (!This)
  758. return ERROR_INVALID_PARAMETER;
  759. *pbBypass = This->bDccBypass;
  760. return NO_ERROR;
  761. }
  762. // Sets whether dcc connections are allowed to
  763. // bypass authentication
  764. DWORD
  765. usrSetDccBypass (
  766. IN HANDLE hUserDatabase,
  767. IN BOOL bBypass)
  768. {
  769. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  770. if (!This)
  771. return ERROR_INVALID_PARAMETER;
  772. This->bDccBypass = bBypass;
  773. return NO_ERROR;
  774. }
  775. // Reports whether the user database is pure. (i.e. nobody has
  776. // gone into MMC and messed with it).
  777. DWORD
  778. usrIsDatabasePure (
  779. IN HANDLE hUserDatabase,
  780. OUT PBOOL pbPure)
  781. {
  782. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  783. if (!This)
  784. return ERROR_INVALID_PARAMETER;
  785. *pbPure = This->bPure;
  786. return NO_ERROR;
  787. }
  788. // Marks the user database's purity
  789. DWORD
  790. usrSetDatabasePure(
  791. IN HANDLE hUserDatabase,
  792. IN BOOL bPure)
  793. {
  794. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  795. if (!This)
  796. return ERROR_INVALID_PARAMETER;
  797. This->bPure = bPure;
  798. return NO_ERROR;
  799. }
  800. // Returns the number of users cached in this database
  801. DWORD
  802. usrGetUserCount (
  803. IN HANDLE hUserDatabase,
  804. OUT LPDWORD lpdwCount)
  805. {
  806. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  807. if (!This || !lpdwCount)
  808. return ERROR_INVALID_PARAMETER;
  809. *lpdwCount = This->dwUserCount;
  810. return NO_ERROR;
  811. }
  812. // Adds a user to the given database. This user will not be
  813. // added to the system's local user database until this database
  814. // object is flushed (and as long as Rollback is not called on
  815. // this database object)
  816. //
  817. // On success, an optional handle to the user is returned
  818. //
  819. DWORD usrAddUser (
  820. IN HANDLE hUserDatabase,
  821. IN PWCHAR pszName,
  822. OUT OPTIONAL HANDLE * phUser)
  823. {
  824. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  825. RASSRV_USERINFO * pUser;
  826. DWORD dwErr, dwLength;
  827. // Validate the parameters
  828. if (!This || !pszName)
  829. return ERROR_INVALID_PARAMETER;
  830. // If the user already exists, don't add him
  831. if (usrUserExists(This, pszName))
  832. return ERROR_ALREADY_EXISTS;
  833. // Resize the cache to accomodate if neccessary
  834. if (This->dwUserCount + 1 >= This->dwCacheSize) {
  835. dwErr = usrResizeCache(This, This->dwCacheSize + USR_ARRAY_GROW_SIZE);
  836. if (dwErr != NO_ERROR)
  837. return dwErr;
  838. }
  839. // Allocate the new user control block
  840. if ((pUser = RassrvAlloc(sizeof(RASSRV_USERINFO), TRUE)) == NULL)
  841. return ERROR_NOT_ENOUGH_MEMORY;
  842. // Allocate space for the name
  843. dwLength = wcslen(pszName);
  844. pUser->pszName = RassrvAlloc((dwLength + 1) * sizeof(WCHAR), FALSE);
  845. if (pUser->pszName == NULL)
  846. return ERROR_NOT_ENOUGH_MEMORY;
  847. // Copy the name
  848. wcscpy(pUser->pszName, pszName);
  849. // Enable the user for dialin by default
  850. usrEnableDialin ((HANDLE)pUser, TRUE);
  851. // Dirty the user
  852. usrDirtyAdd(pUser);
  853. usrDirtyRasProps(pUser);
  854. // Put the user in the array and re-sort it
  855. This->pUserCache[This->dwUserCount++] = pUser;
  856. usrResortCache(This);
  857. // Return the handle
  858. if (phUser)
  859. *phUser = (HANDLE)pUser;
  860. //Need this zero memory to tell if a password is set in the future.
  861. RtlSecureZeroMemory(pUser->szPassword,sizeof(pUser->szPassword));
  862. //Other place will always assume the password is encrypted
  863. //So encrypt even the empty password
  864. SafeEncodePasswordBuf(pUser->szPassword);
  865. return NO_ERROR;
  866. }
  867. // Gives the count of users stored in the user database object
  868. // Deletes the given user
  869. DWORD
  870. usrDeleteUser (
  871. IN HANDLE hUserDatabase,
  872. IN DWORD dwIndex)
  873. {
  874. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  875. RASSRV_USERINFO * pUser;
  876. DWORD dwErr, dwMoveElemCount;
  877. // Validate the parameters
  878. if (!This)
  879. return ERROR_INVALID_PARAMETER;
  880. // Bounds Check
  881. if (!usrBoundsCheck(This, dwIndex))
  882. return ERROR_INVALID_INDEX;
  883. // Get a reference to the user in question and remove him
  884. // from the cache
  885. pUser = This->pUserCache[dwIndex];
  886. //Need this to clear password area and any memory allocated(if CryptProtectData() is used)
  887. //
  888. SafeWipePasswordBuf(pUser->szPassword);
  889. // Attempt to delete the user from the system
  890. if ((dwErr = RasSrvDeleteUser(pUser->pszName)) != NO_ERROR)
  891. return dwErr;
  892. // Remove the user from the cache
  893. This->pUserCache[dwIndex] = NULL;
  894. // Pull down every thing in the cache so that there are no holes
  895. dwMoveElemCount = This->dwUserCount - dwIndex;
  896. if (dwMoveElemCount) {
  897. MoveMemory(&(This->pUserCache[dwIndex]),
  898. &(This->pUserCache[dwIndex + 1]),
  899. dwMoveElemCount * sizeof(RASSRV_USERINFO*));
  900. }
  901. // Decrement the number of users
  902. This->dwUserCount--;
  903. // Cleanup the user
  904. usrFreeUserArray(&pUser, 1);
  905. return NO_ERROR;
  906. }
  907. // Gives a handle to the user at the given index
  908. DWORD
  909. usrGetUserHandle (
  910. IN HANDLE hUserDatabase,
  911. IN DWORD dwIndex,
  912. OUT HANDLE * hUser)
  913. {
  914. RASSRV_USERDB * This = (RASSRV_USERDB*)hUserDatabase;
  915. if (!This || !hUser)
  916. return ERROR_INVALID_PARAMETER;
  917. if (!usrBoundsCheck(This, dwIndex))
  918. return ERROR_INVALID_INDEX;
  919. *hUser = (HANDLE)(This->pUserCache[dwIndex]);
  920. return NO_ERROR;
  921. }
  922. // Gets a pointer to the name of the user (do not modify this)
  923. DWORD
  924. usrGetName (
  925. IN HANDLE hUser,
  926. OUT PWCHAR* pszName)
  927. {
  928. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  929. if (!pRassrvUser || !pszName)
  930. return ERROR_INVALID_PARAMETER;
  931. *pszName = pRassrvUser->pszName;
  932. return NO_ERROR;
  933. }
  934. // Fills the given buffer with a friendly display name
  935. // (in the form username (fullname))
  936. //*lpdwBuffSize is the number of Characters, NOT including the ending NULL
  937. DWORD
  938. usrGetDisplayName (
  939. IN HANDLE hUser,
  940. IN PWCHAR pszBuffer,
  941. IN OUT LPDWORD lpdwBufSize)
  942. {
  943. RASSRV_USERINFO * pRassrvUser = (RASSRV_USERINFO*)hUser;
  944. NET_API_STATUS nStatus;
  945. DWORD dwUserNameLength, dwFullLength, dwSizeRequired;
  946. WCHAR pszTemp[IC_USERFULLNAME]; // For whistler bug 39081 gangz
  947. DWORD dwErr = NO_ERROR;
  948. // Sanity check the params
  949. if (!pRassrvUser || !pszBuffer || !lpdwBufSize)
  950. {
  951. return ERROR_INVALID_PARAMETER;
  952. }
  953. do
  954. {
  955. // Get the full name of the user
  956. // For whistler bug 39081 gangz
  957. // This is size in bytes
  958. dwFullLength = sizeof(pszTemp)/sizeof(pszTemp[0]);
  959. dwErr = usrGetFullName(hUser, pszTemp, &dwFullLength);
  960. if (dwErr != NO_ERROR)
  961. {
  962. break;
  963. }
  964. // Make sure the buffer is big enough
  965. dwUserNameLength = wcslen(pRassrvUser->pszName);
  966. dwSizeRequired = dwUserNameLength +
  967. dwFullLength +
  968. ((dwFullLength) ? 3 : 0);
  969. if (*lpdwBufSize < dwSizeRequired)
  970. {
  971. dwErr = ERROR_INSUFFICIENT_BUFFER;
  972. break;
  973. }
  974. if (dwFullLength)
  975. {
  976. wsprintfW(
  977. pszBuffer,
  978. L"%s (%s)",
  979. pRassrvUser->pszName,
  980. pszTemp);
  981. }
  982. else
  983. {
  984. wcscpy(pszBuffer, pRassrvUser->pszName);
  985. }
  986. } while (FALSE);
  987. // Cleanup
  988. {
  989. // The number of characters required, NOT including ending NULL
  990. *lpdwBufSize = dwSizeRequired;
  991. }
  992. return dwErr;
  993. }
  994. // Fills the given buffer with a friendly display name
  995. // (in the form username (fullname))
  996. // *lpdwBufSize is the number of characters, NOT including ending NULL
  997. DWORD
  998. usrGetFullName (
  999. IN HANDLE hUser,
  1000. IN PWCHAR pszBuffer,
  1001. IN OUT LPDWORD lpdwBufSize)
  1002. {
  1003. RASSRV_USERINFO * pRassrvUser = (RASSRV_USERINFO*)hUser;
  1004. NET_API_STATUS nStatus;
  1005. USER_INFO_2 * pUserInfo = NULL;
  1006. DWORD dwLength;
  1007. PWCHAR pszFullName;
  1008. DWORD dwErr = NO_ERROR;
  1009. // Sanity check the params
  1010. if (!pRassrvUser || !pszBuffer || !lpdwBufSize)
  1011. return ERROR_INVALID_PARAMETER;
  1012. // If the full name is already loaded, return it
  1013. if (pRassrvUser->pszFullName)
  1014. pszFullName = pRassrvUser->pszFullName;
  1015. // or if this is a new user, get the name from memory
  1016. else if (usrIsAddDirty(pRassrvUser)) {
  1017. pszFullName = (pRassrvUser->pszFullName) ?
  1018. pRassrvUser->pszFullName : L"";
  1019. }
  1020. // Load the full name of the user
  1021. else {
  1022. nStatus = NetUserGetInfo(
  1023. NULL,
  1024. pRassrvUser->pszName,
  1025. 2,
  1026. (LPBYTE*)&pUserInfo);
  1027. if (nStatus != NERR_Success) {
  1028. DbgOutputTrace (
  1029. "usrGetFullName: %x returned from NetUserGetInfo for %S",
  1030. nStatus,
  1031. pRassrvUser->pszName);
  1032. return nStatus;
  1033. }
  1034. pszFullName = (PWCHAR)pUserInfo->usri2_full_name;
  1035. }
  1036. do
  1037. {
  1038. // Make sure the length is ok
  1039. dwLength = wcslen(pszFullName);
  1040. // Assign the full name here if it hasn't already been done
  1041. if (dwLength && !pRassrvUser->pszFullName)
  1042. {
  1043. DWORD dwSize = dwLength * sizeof(WCHAR) + sizeof(WCHAR);
  1044. pRassrvUser->pszFullName = RassrvAlloc(dwSize, FALSE);
  1045. if (pRassrvUser->pszFullName)
  1046. {
  1047. wcscpy(pRassrvUser->pszFullName, pszFullName);
  1048. }
  1049. }
  1050. // Check the size NOT including ending NULL
  1051. if (*lpdwBufSize < dwLength )
  1052. {
  1053. dwErr = ERROR_INSUFFICIENT_BUFFER;
  1054. break;
  1055. }
  1056. // Copy in the full name
  1057. wcscpy(pszBuffer, pszFullName);
  1058. } while (FALSE);
  1059. // Cleanup
  1060. {
  1061. // report the size in number of characters ( NOT include ending NULL)
  1062. *lpdwBufSize = dwLength;
  1063. if (pUserInfo)
  1064. {
  1065. NetApiBufferFree((LPBYTE)pUserInfo);
  1066. }
  1067. }
  1068. return dwErr;
  1069. }
  1070. // Commits the full name of a user
  1071. DWORD usrSetFullName (
  1072. IN HANDLE hUser,
  1073. IN PWCHAR pszFullName)
  1074. {
  1075. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  1076. DWORD dwLength;
  1077. if (!pRassrvUser || !pszFullName)
  1078. return ERROR_INVALID_PARAMETER;
  1079. // If this is not a new name, don't do anything
  1080. if (pRassrvUser->pszFullName) {
  1081. if (wcscmp(pRassrvUser->pszFullName, pszFullName) == 0)
  1082. return NO_ERROR;
  1083. RassrvFree(pRassrvUser->pszFullName);
  1084. }
  1085. // Allocate a new one
  1086. dwLength = wcslen(pszFullName);
  1087. pRassrvUser->pszFullName = RassrvAlloc(dwLength * sizeof(WCHAR) + sizeof(WCHAR),
  1088. FALSE);
  1089. if (!pRassrvUser->pszFullName)
  1090. return ERROR_NOT_ENOUGH_MEMORY;
  1091. // Copy it over
  1092. wcscpy(pRassrvUser->pszFullName, pszFullName);
  1093. // Mark it dirty -- a newly added user has his/her full name commited
  1094. // whenever it exists automatically
  1095. if (!usrIsAddDirty(pRassrvUser))
  1096. usrDirtyFullname(pRassrvUser);
  1097. return NO_ERROR;
  1098. }
  1099. // Commits the password of a user
  1100. //pszNewPassword is not encoded
  1101. DWORD
  1102. usrSetPassword (
  1103. IN HANDLE hUser,
  1104. IN PWCHAR pszNewPassword)
  1105. {
  1106. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  1107. DWORD dwLength;
  1108. if (!pRassrvUser || !pszNewPassword)
  1109. return ERROR_INVALID_PARAMETER;
  1110. // Cleanup the old password if it exists
  1111. SafeWipePasswordBuf(pRassrvUser->szPassword);
  1112. // Allocate a new one
  1113. dwLength = wcslen(pszNewPassword);
  1114. // Copy it over
  1115. lstrcpynW(pRassrvUser->szPassword, pszNewPassword,
  1116. sizeof(pRassrvUser->szPassword)/sizeof(pRassrvUser->szPassword[0]) );
  1117. // Encrypt it
  1118. SafeEncodePasswordBuf( pRassrvUser->szPassword );
  1119. // Mark it dirty -- a newly added user has his/her full name commited
  1120. // whenever it exists automatically
  1121. if (!usrIsAddDirty(pRassrvUser))
  1122. usrDirtyPassword(pRassrvUser);
  1123. return NO_ERROR;
  1124. }
  1125. // Determines whether users have callback/dialin priveleges.
  1126. DWORD
  1127. usrGetDialin (
  1128. IN HANDLE hUser,
  1129. OUT BOOL* bEnabled)
  1130. {
  1131. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  1132. DWORD dwErr;
  1133. RAS_USER_0 UserInfo;
  1134. if (!pRassrvUser || !bEnabled)
  1135. return ERROR_INVALID_PARAMETER;
  1136. // Get the user info
  1137. *bEnabled = (pRassrvUser->bfPrivilege & RASPRIV_DialinPrivilege);
  1138. return NO_ERROR;
  1139. }
  1140. // Determines which if any callback priveleges are granted to a given user.
  1141. // Either (or both) of bAdminOnly and bUserSettable can be null
  1142. DWORD
  1143. usrGetCallback (
  1144. IN HANDLE hUser,
  1145. OUT BOOL* bAdminOnly,
  1146. OUT BOOL* bUserSettable)
  1147. {
  1148. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  1149. DWORD dwErr;
  1150. if (!pRassrvUser || !bAdminOnly || !bUserSettable)
  1151. return ERROR_INVALID_PARAMETER;
  1152. // Return whether we have callback privelege
  1153. if (bAdminOnly)
  1154. {
  1155. *bAdminOnly =
  1156. (pRassrvUser->bfPrivilege & RASPRIV_AdminSetCallback);
  1157. }
  1158. if (bUserSettable)
  1159. {
  1160. *bUserSettable =
  1161. (pRassrvUser->bfPrivilege & RASPRIV_CallerSetCallback);
  1162. }
  1163. return NO_ERROR;
  1164. }
  1165. // Enable/disable dialin privelege.
  1166. DWORD
  1167. usrEnableDialin (
  1168. IN HANDLE hUser,
  1169. IN BOOL bEnable)
  1170. {
  1171. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  1172. DWORD dwErr = NO_ERROR;
  1173. BOOL bIsEnabled;
  1174. if (!pRassrvUser)
  1175. return ERROR_INVALID_PARAMETER;
  1176. // If the dialin privelege is already set as requested return success
  1177. bIsEnabled = pRassrvUser->bfPrivilege & RASPRIV_DialinPrivilege;
  1178. if ((!!bIsEnabled) == (!!bEnable))
  1179. return NO_ERROR;
  1180. // Otherwise reset the privelege
  1181. if (bEnable)
  1182. pRassrvUser->bfPrivilege |= RASPRIV_DialinPrivilege;
  1183. else
  1184. pRassrvUser->bfPrivilege &= ~RASPRIV_DialinPrivilege;
  1185. // Dirty the user (cause him/her to be flushed at apply time)
  1186. usrDirtyRasProps(pRassrvUser);
  1187. return dwErr;
  1188. }
  1189. // The flags are evaluated in the following order with whichever condition
  1190. // being satisfied fist defining the behavior of the function.
  1191. // bNone == TRUE => Callback is disabled for the user
  1192. // bCaller == TRUE => Callback is set to caller-settable
  1193. // bAdmin == TRUE => Callback is set to a predefine callback number set
  1194. // All 3 are FALSE => No op
  1195. DWORD
  1196. usrEnableCallback (
  1197. IN HANDLE hUser,
  1198. IN BOOL bNone,
  1199. IN BOOL bCaller,
  1200. IN BOOL bAdmin)
  1201. {
  1202. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  1203. DWORD dwErr = NO_ERROR;
  1204. BOOL bIsEnabled;
  1205. if (!pRassrvUser)
  1206. return ERROR_INVALID_PARAMETER;
  1207. if (bNone) {
  1208. pRassrvUser->bfPrivilege |= RASPRIV_NoCallback;
  1209. pRassrvUser->bfPrivilege &= ~RASPRIV_CallerSetCallback;
  1210. pRassrvUser->bfPrivilege &= ~RASPRIV_AdminSetCallback;
  1211. }
  1212. else if (bCaller) {
  1213. pRassrvUser->bfPrivilege &= ~RASPRIV_NoCallback;
  1214. pRassrvUser->bfPrivilege |= RASPRIV_CallerSetCallback;
  1215. pRassrvUser->bfPrivilege &= ~RASPRIV_AdminSetCallback;
  1216. }
  1217. else if (bAdmin) {
  1218. pRassrvUser->bfPrivilege &= ~RASPRIV_NoCallback;
  1219. pRassrvUser->bfPrivilege &= ~RASPRIV_CallerSetCallback;
  1220. pRassrvUser->bfPrivilege |= RASPRIV_AdminSetCallback;
  1221. }
  1222. else
  1223. return NO_ERROR;
  1224. // Dirty the user (cause him/her to be flushed at apply time)
  1225. usrDirtyRasProps(pRassrvUser);
  1226. return dwErr;
  1227. }
  1228. // Retreives a pointer to the callback number of the given user
  1229. DWORD
  1230. usrGetCallbackNumber(
  1231. IN HANDLE hUser,
  1232. OUT PWCHAR * lpzNumber)
  1233. {
  1234. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  1235. if (!pRassrvUser || !lpzNumber)
  1236. return ERROR_INVALID_PARAMETER;
  1237. // Return the pointer to the callback number
  1238. *lpzNumber = pRassrvUser->wszPhoneNumber;
  1239. return NO_ERROR;
  1240. }
  1241. // Sets the callback number of the given user. If lpzNumber is NULL,
  1242. // an empty phone number is copied.
  1243. DWORD
  1244. usrSetCallbackNumber(
  1245. IN HANDLE hUser,
  1246. IN PWCHAR lpzNumber)
  1247. {
  1248. RASSRV_USERINFO* pRassrvUser = (RASSRV_USERINFO*)hUser;
  1249. DWORD dwErr = NO_ERROR;
  1250. if (!pRassrvUser)
  1251. return ERROR_INVALID_PARAMETER;
  1252. // Modify the phone number appropriately
  1253. if (!lpzNumber)
  1254. wcscpy(pRassrvUser->wszPhoneNumber, L"");
  1255. else {
  1256. lstrcpynW(pRassrvUser->wszPhoneNumber, lpzNumber, MAX_PHONE_NUMBER_LEN);
  1257. pRassrvUser->wszPhoneNumber[MAX_PHONE_NUMBER_LEN] = (WCHAR)0;
  1258. }
  1259. // Dirty the user (cause him/her to be flushed at apply time)
  1260. usrDirtyRasProps(pRassrvUser);
  1261. return dwErr;
  1262. }