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.

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