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.

729 lines
16 KiB

  1. #include "precomp.h"
  2. BOOL
  3. UserServerInfoIsInit(
  4. IN RASMON_SERVERINFO * pServerInfo)
  5. {
  6. return ((pServerInfo->hServer) ||
  7. (pServerInfo->dwBuild == RASMONTR_OS_BUILD_NT40));
  8. }
  9. DWORD
  10. UserServerInfoInit(
  11. IN RASMON_SERVERINFO * pServerInfo)
  12. {
  13. DWORD dwErr = NO_ERROR;
  14. BOOL bInit = UserServerInfoIsInit(pServerInfo);
  15. // If we're already initailized, return
  16. //
  17. if (bInit)
  18. {
  19. return NO_ERROR;
  20. }
  21. if ((pServerInfo->dwBuild != RASMONTR_OS_BUILD_NT40) &&
  22. (pServerInfo->hServer == NULL))
  23. {
  24. //
  25. // first time connecting to user server
  26. //
  27. MprAdminUserServerConnect (
  28. pServerInfo->pszServer,
  29. TRUE,
  30. &(pServerInfo->hServer));
  31. }
  32. return dwErr;
  33. }
  34. DWORD
  35. UserServerInfoUninit(
  36. IN RASMON_SERVERINFO * pServerInfo)
  37. {
  38. // Release the reference to the user server
  39. if (g_pServerInfo->hServer)
  40. {
  41. MprAdminUserServerDisconnect(g_pServerInfo->hServer);
  42. g_pServerInfo->hServer = NULL;
  43. }
  44. return NO_ERROR;
  45. }
  46. DWORD
  47. UserGetRasProperties (
  48. IN RASMON_SERVERINFO * pServerInfo,
  49. IN LPCWSTR pwszUser,
  50. IN RAS_USER_0* pUser0)
  51. {
  52. HANDLE hUser = NULL;
  53. DWORD dwErr;
  54. BOOL bInit = UserServerInfoIsInit(pServerInfo);
  55. do
  56. {
  57. UserServerInfoInit(pServerInfo);
  58. // Get the information using nt40 apis
  59. //
  60. if (pServerInfo->dwBuild == RASMONTR_OS_BUILD_NT40)
  61. {
  62. dwErr = MprAdminUserGetInfo(
  63. pServerInfo->pszServer,
  64. pwszUser,
  65. 0,
  66. (LPBYTE)pUser0);
  67. if (dwErr != NO_ERROR)
  68. {
  69. break;
  70. }
  71. }
  72. // Or get it using nt50 apis
  73. else
  74. {
  75. // Get a reference to the given user
  76. //
  77. dwErr = MprAdminUserOpen(
  78. pServerInfo->hServer,
  79. (LPWSTR)pwszUser,
  80. &hUser);
  81. if (dwErr isnot NO_ERROR)
  82. {
  83. break;
  84. }
  85. // Set the information
  86. //
  87. dwErr = MprAdminUserRead(
  88. hUser,
  89. 1, // Gives us RASPRIV_DialinPolicy
  90. (LPBYTE)pUser0);
  91. if (dwErr isnot NO_ERROR)
  92. {
  93. break;
  94. }
  95. }
  96. } while (FALSE);
  97. // Cleanup
  98. //
  99. {
  100. if(hUser)
  101. {
  102. MprAdminUserClose(hUser);
  103. }
  104. if (!bInit)
  105. {
  106. UserServerInfoUninit(pServerInfo);
  107. }
  108. }
  109. return dwErr;
  110. }
  111. DWORD
  112. UserSetRasProperties (
  113. IN RASMON_SERVERINFO * pServerInfo,
  114. IN LPCWSTR pwszUser,
  115. IN RAS_USER_0* pUser0)
  116. {
  117. HANDLE hUser = NULL;
  118. DWORD dwErr;
  119. BOOL bInit = UserServerInfoIsInit(pServerInfo);
  120. do
  121. {
  122. UserServerInfoInit(pServerInfo);
  123. // Set the information using nt40 apis
  124. //
  125. if (pServerInfo->dwBuild == RASMONTR_OS_BUILD_NT40)
  126. {
  127. dwErr = MprAdminUserSetInfo(
  128. pServerInfo->pszServer,
  129. pwszUser,
  130. 0,
  131. (LPBYTE)pUser0);
  132. if (dwErr != NO_ERROR)
  133. {
  134. break;
  135. }
  136. }
  137. // Or get it using nt50 apis
  138. else
  139. {
  140. // Get a reference to the given user
  141. //
  142. dwErr = MprAdminUserOpen(
  143. pServerInfo->hServer,
  144. (LPWSTR)pwszUser,
  145. &hUser);
  146. if (dwErr isnot NO_ERROR)
  147. {
  148. break;
  149. }
  150. // Set the information
  151. //
  152. dwErr = MprAdminUserWrite(
  153. hUser,
  154. 1, // Gives us RASPRIV_DialinPolicy
  155. (LPBYTE)pUser0);
  156. if (dwErr isnot NO_ERROR)
  157. {
  158. break;
  159. }
  160. }
  161. } while (FALSE);
  162. // Cleanup
  163. //
  164. {
  165. if(hUser)
  166. {
  167. MprAdminUserClose(hUser);
  168. }
  169. if (!bInit)
  170. {
  171. UserServerInfoUninit(pServerInfo);
  172. }
  173. }
  174. return dwErr;
  175. }
  176. DWORD
  177. UserAdd(
  178. IN LPCWSTR pwszServer,
  179. IN PRASUSER_DATA pUser)
  180. /*++
  181. Routine Description:
  182. Adds the given user to the system
  183. --*/
  184. {
  185. NET_API_STATUS nStatus;
  186. USER_INFO_2 * pUser2;
  187. LPCWSTR pwszFmtServer = pwszServer;
  188. // Initialize the base user information
  189. USER_INFO_1 UserInfo1 =
  190. {
  191. pUser->pszUsername,
  192. pUser->pszPassword,
  193. 0,
  194. USER_PRIV_USER,
  195. L"",
  196. L"",
  197. UF_SCRIPT | UF_DONT_EXPIRE_PASSWD | UF_NORMAL_ACCOUNT,
  198. L""
  199. };
  200. // Add the user
  201. nStatus = NetUserAdd(
  202. pwszFmtServer,
  203. 1,
  204. (LPBYTE)&UserInfo1,
  205. NULL);
  206. // If the user wasn't added, find out why
  207. if (nStatus != NERR_Success)
  208. {
  209. switch (nStatus)
  210. {
  211. case ERROR_ACCESS_DENIED:
  212. return ERROR_ACCESS_DENIED;
  213. case NERR_UserExists:
  214. return ERROR_USER_EXISTS;
  215. case NERR_PasswordTooShort:
  216. return ERROR_INVALID_PASSWORDNAME;
  217. }
  218. return ERROR_CAN_NOT_COMPLETE;
  219. }
  220. // Add the user's full name if provided
  221. if (pUser->pszFullname)
  222. {
  223. // add the user's full name
  224. nStatus = NetUserGetInfo(
  225. pwszFmtServer,
  226. pUser->pszUsername,
  227. 2,
  228. (LPBYTE*)&pUser2);
  229. if (nStatus is NERR_Success)
  230. {
  231. // Modify the full name in the structure
  232. pUser2->usri2_full_name = pUser->pszFullname;
  233. NetUserSetInfo(
  234. pwszFmtServer,
  235. pUser->pszUsername,
  236. 2,
  237. (LPBYTE)pUser2,
  238. NULL);
  239. NetApiBufferFree((LPBYTE)pUser2);
  240. return NO_ERROR;
  241. }
  242. return ERROR_CAN_NOT_COMPLETE;
  243. }
  244. return NO_ERROR;
  245. }
  246. DWORD
  247. UserDelete(
  248. IN LPCWSTR pwszServer,
  249. IN PRASUSER_DATA pUser)
  250. /*++
  251. Routine Description:
  252. Deletes the given user from the system
  253. --*/
  254. {
  255. NET_API_STATUS nStatus;
  256. // Delete the user and return the status code. If the
  257. // specified user is not in the user database, consider
  258. // it a success
  259. nStatus = NetUserDel(
  260. pwszServer,
  261. pUser->pszUsername);
  262. if (nStatus is NERR_UserNotFound)
  263. {
  264. return NO_ERROR;
  265. }
  266. return (nStatus is NERR_Success) ? NO_ERROR : ERROR_CAN_NOT_COMPLETE;
  267. }
  268. DWORD
  269. UserDumpConfig(
  270. IN HANDLE hFile
  271. )
  272. /*++
  273. Routine Description:
  274. Dumps a script to set the ras USER information to
  275. the given text file.
  276. Arguments:
  277. Return Value:
  278. NO_ERROR
  279. --*/
  280. {
  281. DWORD dwErr;
  282. // Enumerate the users dumping them as we go
  283. dwErr = UserEnumUsers(
  284. g_pServerInfo,
  285. UserShowSet,
  286. (HANDLE)hFile);
  287. if (dwErr isnot NO_ERROR)
  288. {
  289. DisplayMessage(
  290. g_hModule,
  291. EMSG_UNABLE_TO_ENUM_USERS);
  292. }
  293. return dwErr;
  294. }
  295. BOOL
  296. UserShowReport(
  297. IN PRASUSER_DATA pUser,
  298. IN HANDLE hFile
  299. )
  300. /*++
  301. Routine Description:
  302. Prints ras user information to the display or a file if specified.
  303. This function can be used as a callback function (see UserEnumUsers).
  304. Arguments:
  305. pUser - The user
  306. hFile - The file
  307. Return Value:
  308. TRUE - continue enumeration
  309. FALSE - stop enumeration
  310. --*/
  311. {
  312. DWORD dwErr, dwSize;
  313. WCHAR rgwcIfDesc[MAX_INTERFACE_NAME_LEN + 1];
  314. PWCHAR pwszDialin = NULL,
  315. pwszCbPolicy = NULL,
  316. pwszCbNumber = NULL,
  317. pwszSetCmd = NULL;
  318. // Initialize the set command
  319. //
  320. pwszSetCmd = DMP_RASUSER_SET;
  321. // Initialize the dialin string
  322. //
  323. if (pUser->User0.bfPrivilege & RASPRIV_DialinPolicy)
  324. {
  325. pwszDialin = TOKEN_POLICY;
  326. }
  327. else if (pUser->User0.bfPrivilege & RASPRIV_DialinPrivilege)
  328. {
  329. pwszDialin = TOKEN_PERMIT;
  330. }
  331. else
  332. {
  333. pwszDialin = TOKEN_DENY;
  334. }
  335. // Initialize the callback policy string
  336. //
  337. if (pUser->User0.bfPrivilege & RASPRIV_NoCallback)
  338. {
  339. pwszCbPolicy = TOKEN_NONE;
  340. }
  341. else if (pUser->User0.bfPrivilege & RASPRIV_CallerSetCallback)
  342. {
  343. pwszCbPolicy = TOKEN_CALLER;
  344. }
  345. else
  346. {
  347. pwszCbPolicy = TOKEN_ADMIN;
  348. }
  349. // Initialize the callback number string
  350. //
  351. pwszCbNumber = pUser->User0.wszPhoneNumber;
  352. do
  353. {
  354. if(!pwszSetCmd or
  355. !pUser->pszUsername or
  356. !pwszDialin or
  357. !pwszCbNumber
  358. )
  359. {
  360. DisplayError(NULL,
  361. ERROR_NOT_ENOUGH_MEMORY);
  362. break;
  363. }
  364. DisplayMessage(g_hModule,
  365. MSG_RASUSER_RASINFO,
  366. pUser->pszUsername,
  367. pwszDialin,
  368. pwszCbPolicy,
  369. pwszCbNumber);
  370. } while(FALSE);
  371. return TRUE;
  372. }
  373. BOOL
  374. UserShowSet(
  375. IN PRASUSER_DATA pUser,
  376. IN HANDLE hFile
  377. )
  378. /*++
  379. Routine Description:
  380. Prints ras user information to the display or a file if specified.
  381. This function can be used as a callback function (see UserEnumUsers).
  382. Arguments:
  383. pUser - The user
  384. hFile - The file
  385. Return Value:
  386. TRUE - continue enumeration
  387. FALSE - stop enumeration
  388. --*/
  389. {
  390. DWORD dwErr, dwSize;
  391. WCHAR rgwcIfDesc[MAX_INTERFACE_NAME_LEN + 1];
  392. PWCHAR pwszName = NULL,
  393. pwszDialin = NULL,
  394. pwszCbPolicy = NULL,
  395. pwszCbNumber = NULL,
  396. pwszSetCmd = NULL;
  397. // Initialize the set command
  398. //
  399. pwszSetCmd = DMP_RASUSER_SET;
  400. // Initialize the dialin string
  401. //
  402. if (pUser->User0.bfPrivilege & RASPRIV_DialinPolicy)
  403. {
  404. pwszDialin = RutlAssignmentFromTokens(
  405. g_hModule,
  406. TOKEN_DIALIN,
  407. TOKEN_POLICY);
  408. }
  409. else if (pUser->User0.bfPrivilege & RASPRIV_DialinPrivilege)
  410. {
  411. pwszDialin = RutlAssignmentFromTokens(
  412. g_hModule,
  413. TOKEN_DIALIN,
  414. TOKEN_PERMIT);
  415. }
  416. else
  417. {
  418. pwszDialin = RutlAssignmentFromTokens(
  419. g_hModule,
  420. TOKEN_DIALIN,
  421. TOKEN_DENY);
  422. }
  423. // Initialize the callback policy string
  424. //
  425. if (pUser->User0.bfPrivilege & RASPRIV_NoCallback)
  426. {
  427. pwszCbPolicy = RutlAssignmentFromTokens(
  428. g_hModule,
  429. TOKEN_CBPOLICY,
  430. TOKEN_NONE);
  431. }
  432. else if (pUser->User0.bfPrivilege & RASPRIV_CallerSetCallback)
  433. {
  434. pwszCbPolicy = RutlAssignmentFromTokens(
  435. g_hModule,
  436. TOKEN_CBPOLICY,
  437. TOKEN_CALLER);
  438. }
  439. else
  440. {
  441. pwszCbPolicy = RutlAssignmentFromTokens(
  442. g_hModule,
  443. TOKEN_CBPOLICY,
  444. TOKEN_CALLER);
  445. }
  446. // Initialize the callback number string
  447. //
  448. if (*(pUser->User0.wszPhoneNumber))
  449. {
  450. pwszCbNumber = RutlAssignmentFromTokens(
  451. g_hModule,
  452. TOKEN_CBNUMBER,
  453. pUser->User0.wszPhoneNumber);
  454. }
  455. else
  456. {
  457. pwszCbNumber = NULL;
  458. }
  459. pwszName = RutlAssignmentFromTokens(
  460. g_hModule,
  461. TOKEN_NAME,
  462. pUser->pszUsername);
  463. do
  464. {
  465. if(!pwszSetCmd or
  466. !pwszName or
  467. !pwszDialin or
  468. !pwszCbPolicy
  469. )
  470. {
  471. DisplayError(NULL,
  472. ERROR_NOT_ENOUGH_MEMORY);
  473. break;
  474. }
  475. DisplayMessage(g_hModule,
  476. MSG_RASUSER_SET_CMD,
  477. pwszSetCmd,
  478. pwszName,
  479. pwszDialin,
  480. pwszCbPolicy,
  481. (pwszCbNumber) ? pwszCbNumber : L"");
  482. } while(FALSE);
  483. // Callback
  484. {
  485. if (pwszDialin)
  486. {
  487. RutlFree(pwszDialin);
  488. }
  489. if (pwszCbPolicy)
  490. {
  491. RutlFree(pwszCbPolicy);
  492. }
  493. if (pwszCbNumber)
  494. {
  495. RutlFree(pwszCbNumber);
  496. }
  497. if (pwszName)
  498. {
  499. RutlFree(pwszName);
  500. }
  501. }
  502. return TRUE;
  503. }
  504. BOOL
  505. UserShowPermit(
  506. IN PRASUSER_DATA pUser,
  507. IN HANDLE hFile
  508. )
  509. {
  510. if (pUser->User0.bfPrivilege & RASPRIV_DialinPrivilege)
  511. {
  512. return UserShowReport(pUser, hFile);
  513. }
  514. return TRUE;
  515. }
  516. DWORD
  517. UserEnumUsers(
  518. IN RASMON_SERVERINFO* pServerInfo,
  519. IN PFN_RASUSER_ENUM_CB pEnumFn,
  520. IN HANDLE hData
  521. )
  522. /*++
  523. Routine Description:
  524. Enumerates all users by calling the given callback function and
  525. passing it the user information and some user defined data.
  526. Enumeration stops when all the users have been enumerated or when
  527. the enumeration function returns FALSE.
  528. Arguments:
  529. pwszServer - The server on which the users should be enumerated
  530. pEnumFn - Enumeration function
  531. hData - Caller defined opaque data blob
  532. Return Value:
  533. NO_ERROR
  534. --*/
  535. {
  536. DWORD dwErr, dwIndex = 0, dwCount = 100, dwEntriesRead, i;
  537. NET_DISPLAY_USER * pUsers;
  538. NET_API_STATUS nStatus;
  539. RAS_USER_0 RasUser0;
  540. HANDLE hUser = NULL;
  541. RASUSER_DATA UserData, *pUserData = &UserData;
  542. BOOL bInit = UserServerInfoIsInit(pServerInfo);
  543. UserServerInfoInit(pServerInfo);
  544. // Enumerate the users
  545. //
  546. while (TRUE)
  547. {
  548. // Read in the next block of user names
  549. nStatus = NetQueryDisplayInformation(
  550. pServerInfo->pszServer,
  551. 1,
  552. dwIndex,
  553. dwCount,
  554. dwCount * sizeof(NET_DISPLAY_USER),
  555. &dwEntriesRead,
  556. &pUsers);
  557. // Get out if there's an error getting user names
  558. if ((nStatus isnot NERR_Success) and
  559. (nStatus isnot ERROR_MORE_DATA))
  560. {
  561. break;
  562. }
  563. for (i = 0; i < dwEntriesRead; i++)
  564. {
  565. // Initialize the user data
  566. ZeroMemory(pUserData, sizeof(RASUSER_DATA));
  567. // Read in the old information
  568. dwErr = UserGetRasProperties (
  569. pServerInfo,
  570. pUsers[i].usri1_name,
  571. &(pUserData->User0));
  572. if (dwErr isnot NO_ERROR)
  573. {
  574. continue;
  575. }
  576. // Initialize the rest of the data structure
  577. pUserData->pszUsername = pUsers[i].usri1_name;
  578. pUserData->pszFullname = pUsers[i].usri1_full_name;
  579. // Call the enumeration callback
  580. if (! ((*(pEnumFn))(pUserData, hData)))
  581. {
  582. nStatus = NO_ERROR;
  583. break;
  584. }
  585. }
  586. // Set the index to read in the next set of users
  587. dwIndex = pUsers[dwEntriesRead - 1].usri1_next_index;
  588. // Free the users buffer
  589. NetApiBufferFree (pUsers);
  590. // If we've read in everybody, go ahead and break
  591. if (nStatus isnot ERROR_MORE_DATA)
  592. {
  593. break;
  594. }
  595. }
  596. if (!bInit)
  597. {
  598. UserServerInfoUninit(pServerInfo);
  599. }
  600. return NO_ERROR;
  601. }