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.

1299 lines
33 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: init.c
  7. //
  8. // Description: This module contains code to intialize and de-initialize
  9. // the AFP Server, RPC server, the security object and
  10. // other global vriables.
  11. //
  12. // History:
  13. // May 11,1992. NarenG Created original version.
  14. //
  15. //
  16. #include "afpsvcp.h"
  17. // Prototypes of functions used only within this module.
  18. //
  19. DWORD
  20. AfpInitServerVolumes(
  21. VOID
  22. );
  23. DWORD
  24. AfpInitServerParameters(
  25. VOID
  26. );
  27. DWORD
  28. AfpInitServerIcons(
  29. VOID
  30. );
  31. DWORD
  32. AfpInitETCMaps(
  33. VOID
  34. );
  35. DWORD
  36. AfpInitRPC(
  37. VOID
  38. );
  39. DWORD
  40. AfpInitServerDomainOffsets(
  41. VOID
  42. );
  43. VOID
  44. AfpTerminateRPC(
  45. VOID
  46. );
  47. VOID
  48. AfpIniLsa(
  49. VOID
  50. );
  51. BOOL
  52. IsAfpGuestAccountEnabled(
  53. VOID
  54. );
  55. //**
  56. //
  57. // Call: AfpInitialize
  58. //
  59. // Returns: NO_ERROR
  60. //
  61. // Description: Will do all server intialization.
  62. // 1) Create the security object.
  63. // 2) Set up the server for RPC.
  64. // 3) Open all the registry keys that store AFP data.
  65. // 4) Get the handle to the FSD.
  66. // 5) Get default server parameters
  67. // 6) It will initialize the AFP Server with volume, ETC, icon
  68. // and server parameter information.
  69. // 7) IOCTL the FSD to start the server.
  70. //
  71. DWORD
  72. AfpInitialize(
  73. VOID
  74. )
  75. {
  76. AFP_REQUEST_PACKET AfpRequestPkt;
  77. DWORD dwRetCode;
  78. BOOL fFirstThread;
  79. DWORD nThreads;
  80. // Load strings from resource file
  81. //
  82. if (( !LoadString( GetModuleHandle( NULL ), 1, AfpGlobals.wchUnknown, 100 ))
  83. ||
  84. ( !LoadString( GetModuleHandle( NULL ), 2, AfpGlobals.wchInvalid, 100 ))
  85. ||
  86. ( !LoadString( GetModuleHandle( NULL ), 3, AfpGlobals.wchDeleted, 100 ))
  87. ||
  88. ( !LoadString( GetModuleHandle( NULL ), 4, AfpGlobals.wchDefTCComment,
  89. AFP_ETC_COMMENT_LEN+1 )))
  90. AfpLogEvent( AFPLOG_CANT_LOAD_RESOURCE, 0, NULL,
  91. GetLastError(), EVENTLOG_WARNING_TYPE );
  92. //
  93. // Create the security object
  94. //
  95. if ( dwRetCode = AfpSecObjCreate() ) {
  96. AfpLogEvent( AFPLOG_CANT_CREATE_SECOBJ, 0, NULL,
  97. dwRetCode, EVENTLOG_ERROR_TYPE );
  98. return( dwRetCode );
  99. }
  100. // Initialize the server to accept RPC calls
  101. //
  102. if ( dwRetCode = AfpInitRPC() ) {
  103. AfpLogEvent( AFPLOG_CANT_INIT_RPC, 0, NULL,
  104. dwRetCode, EVENTLOG_ERROR_TYPE );
  105. return( dwRetCode );
  106. }
  107. AfpGlobals.dwServerState |= AFPSTATE_RPC_STARTED;
  108. // Open the registry keys where AFP Server information is stored
  109. //
  110. if ( dwRetCode = AfpRegOpen() ) {
  111. AfpLogEvent( AFPLOG_CANT_OPEN_REGKEY, 0, NULL,
  112. dwRetCode, EVENTLOG_ERROR_TYPE );
  113. return( dwRetCode );
  114. }
  115. AfpGlobals.ServiceStatus.dwCheckPoint++;
  116. AfpAnnounceServiceStatus();
  117. // Open and load the AFP Server FSD and obtain a handle to it
  118. //
  119. if ( dwRetCode = AfpFSDLoad() ) {
  120. AfpLogEvent( AFPLOG_CANT_LOAD_FSD, 0, NULL,
  121. dwRetCode, EVENTLOG_ERROR_TYPE );
  122. return( dwRetCode );
  123. }
  124. AfpGlobals.dwServerState |= AFPSTATE_FSD_LOADED;
  125. if ( dwRetCode = AfpFSDOpen( &(AfpGlobals.hFSD) ) ) {
  126. AfpLogEvent( AFPLOG_CANT_OPEN_FSD, 0, NULL,
  127. dwRetCode, EVENTLOG_ERROR_TYPE );
  128. return( dwRetCode );
  129. }
  130. // Query the product type of server.
  131. //
  132. AfpGlobals.pSidNone = NULL;
  133. RtlGetNtProductType ( &(AfpGlobals.NtProductType) );
  134. // Create the event object for the server helper thread.
  135. //
  136. if ( (AfpGlobals.heventSrvrHlprThread =
  137. CreateEvent( NULL, FALSE, FALSE, NULL ) ) == NULL){
  138. AfpLogEvent( AFPLOG_CANT_START, 0, NULL, GetLastError(),
  139. EVENTLOG_ERROR_TYPE );
  140. return( GetLastError() );
  141. }
  142. // Create the event object for the server helper thread termination.
  143. //
  144. if ( (AfpGlobals.heventSrvrHlprThreadTerminate =
  145. CreateEvent( NULL, FALSE, FALSE, NULL ) ) == NULL){
  146. AfpLogEvent( AFPLOG_CANT_START, 0, NULL, GetLastError(),
  147. EVENTLOG_ERROR_TYPE );
  148. return( GetLastError() );
  149. }
  150. // Create the event object for the "special case" unblocking of server helper thread
  151. //
  152. if ( (AfpGlobals.heventSrvrHlprSpecial =
  153. CreateEvent( NULL, FALSE, FALSE, NULL ) ) == NULL){
  154. AfpLogEvent( AFPLOG_CANT_START, 0, NULL, GetLastError(),
  155. EVENTLOG_ERROR_TYPE );
  156. return( GetLastError() );
  157. }
  158. // Create server helper threads. The parameter indicates if this is the
  159. // first thread that is being created.
  160. //
  161. fFirstThread = TRUE;
  162. nThreads = 0;
  163. do {
  164. if ( ( dwRetCode = AfpCreateServerHelperThread( fFirstThread ) )
  165. != NO_ERROR ) {
  166. AfpLogEvent( AFPLOG_CANT_CREATE_SRVRHLPR, 0, NULL,
  167. dwRetCode, EVENTLOG_ERROR_TYPE );
  168. if ( fFirstThread ) {
  169. AfpLogEvent( AFPLOG_CANT_START, 0, NULL,
  170. dwRetCode, EVENTLOG_ERROR_TYPE );
  171. return( dwRetCode );
  172. }
  173. }
  174. // Wait for the server helper thread to indicate if it successfully
  175. // initialized itself.
  176. //
  177. WaitForSingleObject( AfpGlobals.heventSrvrHlprThread, INFINITE );
  178. if ( AfpGlobals.dwSrvrHlprCode != NO_ERROR ) {
  179. AfpLogEvent(AFPLOG_CANT_INIT_SRVRHLPR,
  180. 0,
  181. NULL,
  182. AfpGlobals.dwSrvrHlprCode,
  183. EVENTLOG_ERROR_TYPE );
  184. if ( fFirstThread )
  185. {
  186. AFP_PRINT( ( "SFMSVC: can't start macfile, first thread failed %ld\n",
  187. AfpGlobals.dwSrvrHlprCode));
  188. AfpLogEvent( AFPLOG_CANT_START, 0, NULL, dwRetCode,
  189. EVENTLOG_ERROR_TYPE );
  190. return( AfpGlobals.dwSrvrHlprCode );
  191. }
  192. }
  193. fFirstThread = FALSE;
  194. }while( ++nThreads < NUM_SECURITY_UTILITY_THREADS );
  195. // Read in server parameters from the registry and intialize the
  196. // server with them.
  197. //
  198. if ( dwRetCode = AfpInitServerParameters())
  199. {
  200. AFP_PRINT( ( "SFMSVC: AfpInitServerParameters failed %ld\n",dwRetCode));
  201. AfpLogEvent( AFPLOG_CANT_INIT_SRVR_PARAMS, 0, NULL, dwRetCode,EVENTLOG_ERROR_TYPE );
  202. return( dwRetCode );
  203. }
  204. AfpGlobals.ServiceStatus.dwCheckPoint++;
  205. AfpAnnounceServiceStatus();
  206. // Read in the ETC Mappings and initialize the AFP Server with them
  207. // Also create a private cache of this information.
  208. //
  209. if ( dwRetCode = AfpInitETCMaps() )
  210. {
  211. AFP_PRINT( ( "SFMSVC: AfpInitETCMaps failed %ld\n",dwRetCode));
  212. AfpLogEvent( AFPLOG_CANT_INIT_ETCINFO, 0, NULL, dwRetCode,EVENTLOG_ERROR_TYPE );
  213. return( dwRetCode );
  214. }
  215. if ( dwRetCode = AfpInitServerIcons() )
  216. {
  217. AFP_PRINT( ( "SFMSVC: AfpInitServerIcons failed %ld\n",dwRetCode));
  218. AfpLogEvent( AFPLOG_CANT_INIT_ICONS, 0, NULL, dwRetCode ,EVENTLOG_ERROR_TYPE );
  219. return( dwRetCode );
  220. }
  221. AfpGlobals.ServiceStatus.dwCheckPoint++;
  222. AfpAnnounceServiceStatus();
  223. // Read in any volumes and initialize the server with them
  224. //
  225. if ( dwRetCode = AfpInitServerVolumes() )
  226. {
  227. AFP_PRINT( ( "SFMSVC: AfpInitServerVolumes failed %ld\n",dwRetCode));
  228. AfpLogEvent( AFPLOG_CANT_INIT_VOLUMES, 0, NULL, dwRetCode,EVENTLOG_ERROR_TYPE );
  229. return( dwRetCode );
  230. }
  231. // Create mutex objects around volume operations to avoid simultaneous
  232. // writing in the registry.
  233. //
  234. if ( (AfpGlobals.hmutexVolume = CreateMutex( NULL, FALSE, NULL ) ) == NULL)
  235. {
  236. AFP_PRINT( ( "SFMSVC: CreateMutex failed in AfpInitialize\n"));
  237. AfpLogEvent( AFPLOG_CANT_START, 0, NULL, dwRetCode,EVENTLOG_ERROR_TYPE );
  238. return( GetLastError() );
  239. }
  240. // Create mutex objects around ETCMap operations.
  241. //
  242. if ( (AfpGlobals.hmutexETCMap = CreateMutex( NULL, FALSE, NULL ) ) == NULL)
  243. {
  244. AFP_PRINT( ( "SFMSVC: CreateMutex 2 failed in AfpInitialize\n"));
  245. AfpLogEvent( AFPLOG_CANT_START, 0, NULL, GetLastError(),EVENTLOG_ERROR_TYPE );
  246. return( GetLastError() );
  247. }
  248. // OK we are all set to go so lets tell the AFP Server to start
  249. //
  250. AfpRequestPkt.dwRequestCode = OP_SERVICE_START;
  251. AfpRequestPkt.dwApiType = AFP_API_TYPE_COMMAND;
  252. AFP_PRINT( ( "SFMSVC: ioctling sfmsrv to start\n"));
  253. if ( dwRetCode = AfpServerIOCtrl( &AfpRequestPkt ) )
  254. {
  255. AFP_PRINT( ( "SFMSVC: AfpServerIOCtrl to start sfmsrv failed %ld\n",dwRetCode));
  256. AfpLogEvent( AFPLOG_CANT_START,0,NULL,dwRetCode,EVENTLOG_ERROR_TYPE);
  257. return( dwRetCode );
  258. }
  259. AfpIniLsa();
  260. return( NO_ERROR );
  261. }
  262. //**
  263. //
  264. // Call: AfpTerminate
  265. //
  266. // Returns: none.
  267. //
  268. // Description: This procedure will shut down the server, and do any
  269. // clean up if required.
  270. //
  271. VOID
  272. AfpTerminate(
  273. VOID
  274. )
  275. {
  276. AFP_REQUEST_PACKET AfpRequestPkt;
  277. DWORD dwRetCode;
  278. // If the FSD was loaded
  279. //
  280. if ( AfpGlobals.dwServerState & AFPSTATE_FSD_LOADED ) {
  281. // Tell the server to shut down
  282. //
  283. AfpRequestPkt.dwRequestCode = OP_SERVICE_STOP;
  284. AfpRequestPkt.dwApiType = AFP_API_TYPE_COMMAND;
  285. if ( dwRetCode = AfpServerIOCtrl( &AfpRequestPkt ) )
  286. AfpLogEvent( AFPLOG_CANT_STOP, 0, NULL,
  287. dwRetCode, EVENTLOG_ERROR_TYPE );
  288. }
  289. AfpGlobals.ServiceStatus.dwCheckPoint++;
  290. AfpAnnounceServiceStatus();
  291. // Try to close the FSD
  292. //
  293. if ( AfpGlobals.hFSD != NULL )
  294. {
  295. if ( dwRetCode = AfpFSDClose( AfpGlobals.hFSD ) )
  296. {
  297. AfpLogEvent( AFPLOG_CANT_STOP, 0, NULL,
  298. dwRetCode, EVENTLOG_ERROR_TYPE );
  299. }
  300. // Try to unload the FSD
  301. //
  302. if ( dwRetCode = AfpFSDUnload() )
  303. {
  304. AfpLogEvent( AFPLOG_CANT_STOP, 0, NULL,
  305. dwRetCode, EVENTLOG_ERROR_TYPE);
  306. }
  307. }
  308. AfpGlobals.ServiceStatus.dwCheckPoint++;
  309. AfpAnnounceServiceStatus();
  310. // Delete the security object.
  311. //
  312. AfpSecObjDelete();
  313. // De-initialize the RPC server
  314. //
  315. AfpTerminateRPC();
  316. // Close the registry keys.
  317. //
  318. AfpRegClose();
  319. // Free the pSidNone if we allocated it for standalone
  320. //
  321. if (AfpGlobals.pSidNone != NULL)
  322. {
  323. LocalFree(AfpGlobals.pSidNone);
  324. AfpGlobals.pSidNone = NULL;
  325. }
  326. if (SfmLsaHandle != NULL)
  327. {
  328. LsaDeregisterLogonProcess( SfmLsaHandle );
  329. SfmLsaHandle = NULL;
  330. }
  331. return;
  332. }
  333. //**
  334. //
  335. // Call: AfpInitServerParameters
  336. //
  337. // Returns: NO_ERROR
  338. // non-zero return codes from the IOCTL or other system calls.
  339. //
  340. // Description: This procedure will set default values for parameters. It
  341. // will then call AfpRegServerGetInfo to override these defaults
  342. // with any parameters that may be stored in the registry. It
  343. // will then initialize the FSD with these parameters.
  344. //
  345. DWORD
  346. AfpInitServerParameters(
  347. VOID
  348. )
  349. {
  350. AFP_SERVER_INFO AfpServerInfo;
  351. DWORD cbServerNameSize;
  352. DWORD dwRetCode;
  353. AFP_REQUEST_PACKET AfpRequestPkt;
  354. // Initialize all the server parameters with defaults
  355. //
  356. cbServerNameSize = sizeof( AfpGlobals.wchServerName );
  357. if ( !GetComputerName( AfpGlobals.wchServerName, &cbServerNameSize ) )
  358. return( GetLastError() );
  359. AfpGlobals.dwMaxSessions = AFP_DEF_MAXSESSIONS;
  360. AfpGlobals.dwServerOptions = AFP_DEF_SRVOPTIONS;
  361. AfpGlobals.wchLoginMsg[0] = TEXT('\0');
  362. AfpGlobals.dwMaxPagedMem = AFP_DEF_MAXPAGEDMEM;
  363. AfpGlobals.dwMaxNonPagedMem = AFP_DEF_MAXNONPAGEDMEM;
  364. // Read in any server parameters in the registry. Registry parameters
  365. // will override the defaults set above.
  366. //
  367. if ( dwRetCode = AfpRegServerGetInfo() )
  368. return( dwRetCode );
  369. if (IsAfpGuestAccountEnabled())
  370. {
  371. AfpGlobals.dwServerOptions |= AFP_SRVROPT_GUESTLOGONALLOWED;
  372. }
  373. else
  374. {
  375. AfpGlobals.dwServerOptions &= ~AFP_SRVROPT_GUESTLOGONALLOWED;
  376. }
  377. // Get the path to the codepage
  378. //
  379. if ( dwRetCode = AfpRegServerGetCodePagePath() )
  380. return( dwRetCode );
  381. // Set up server info structure
  382. //
  383. AfpServerInfo.afpsrv_name = AfpGlobals.wchServerName;
  384. AfpServerInfo.afpsrv_max_sessions = AfpGlobals.dwMaxSessions;
  385. AfpServerInfo.afpsrv_options = AfpGlobals.dwServerOptions;
  386. if (AfpGlobals.NtProductType != NtProductLanManNt)
  387. {
  388. AfpServerInfo.afpsrv_options |= AFP_SRVROPT_STANDALONE;
  389. }
  390. AfpServerInfo.afpsrv_login_msg = AfpGlobals.wchLoginMsg;
  391. AfpServerInfo.afpsrv_max_paged_mem = AfpGlobals.dwMaxPagedMem;
  392. AfpServerInfo.afpsrv_max_nonpaged_mem = AfpGlobals.dwMaxNonPagedMem;
  393. AfpServerInfo.afpsrv_codepage = AfpGlobals.wchCodePagePath;
  394. // Make this buffer self-relative.
  395. //
  396. if ( dwRetCode = AfpBufMakeFSDRequest(
  397. (LPBYTE)&AfpServerInfo,
  398. sizeof(SETINFOREQPKT),
  399. AFP_SERVER_STRUCT,
  400. (LPBYTE*)&(AfpRequestPkt.Type.SetInfo.pInputBuf),
  401. &(AfpRequestPkt.Type.SetInfo.cbInputBufSize)))
  402. {
  403. return( dwRetCode );
  404. }
  405. // IOCTL the FSD to set the server parameters
  406. //
  407. AfpRequestPkt.dwRequestCode = OP_SERVER_SET_INFO;
  408. AfpRequestPkt.dwApiType = AFP_API_TYPE_SETINFO;
  409. AfpRequestPkt.Type.SetInfo.dwParmNum = AFP_SERVER_PARMNUM_ALL;
  410. dwRetCode = AfpServerIOCtrl( &AfpRequestPkt );
  411. LocalFree( AfpRequestPkt.Type.SetInfo.pInputBuf );
  412. return( dwRetCode );
  413. }
  414. //**
  415. //
  416. // Call: AfpInitServerVolumes
  417. //
  418. // Returns: NO_ERROR - success
  419. // ERROR_NOT_ENOUGH_MEMORY
  420. // non-zero return codes from registry apis.
  421. //
  422. // Description: This procedure will read in a volume at a time from the
  423. // registry, and then register this volume with the server.
  424. // This procedure will only return fatal errors that will
  425. // require that the service to fail initialization. All other
  426. // error will be logged by this routine. All returns from the
  427. // the FSD are treated as non-fatal.
  428. //
  429. DWORD
  430. AfpInitServerVolumes(
  431. VOID
  432. )
  433. {
  434. DWORD dwRetCode;
  435. LPWSTR lpwsValName, lpwsSrcIconPath, lpwsDstIconPath;
  436. DWORD dwMaxValNameLen;
  437. DWORD dwValNameBufSize;
  438. DWORD dwNumValues;
  439. DWORD dwMaxValueDataSize;
  440. DWORD dwIndex;
  441. DWORD dwType;
  442. DWORD dwBufSize;
  443. AFP_REQUEST_PACKET AfpRequestPkt;
  444. AFP_VOLUME_INFO VolumeInfo;
  445. LPBYTE lpbMultiSz;
  446. LPBYTE lpbFSDBuf;
  447. DWORD dwLength;
  448. DWORD dwCount;
  449. WCHAR wchServerIconFile[AFPSERVER_VOLUME_ICON_FILE_SIZE] = AFPSERVER_VOLUME_ICON_FILE;
  450. BOOLEAN fCopiedIcon;
  451. DWORD dwLastDstCharIndex;
  452. // Find out the size of the largest data value and the largest
  453. // value name.
  454. //
  455. if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyVolumesList,
  456. &dwMaxValNameLen,
  457. &dwNumValues,
  458. &dwMaxValueDataSize
  459. ))
  460. return( dwRetCode );
  461. // If there are no volumes to add then simply return
  462. //
  463. if ( dwNumValues == 0 )
  464. return( NO_ERROR );
  465. if (( lpwsValName = (LPWSTR)LocalAlloc( LPTR, dwMaxValNameLen ) ) == NULL )
  466. return( ERROR_NOT_ENOUGH_MEMORY );
  467. if ((lpbMultiSz = (LPBYTE)LocalAlloc( LPTR, dwMaxValueDataSize )) == NULL ){
  468. LocalFree( lpwsValName );
  469. return( ERROR_NOT_ENOUGH_MEMORY );
  470. }
  471. if (( lpwsSrcIconPath = (LPWSTR)LocalAlloc( LPTR, MAX_PATH * sizeof(WCHAR) ) ) == NULL )
  472. {
  473. LocalFree( lpwsValName );
  474. LocalFree( lpbMultiSz );
  475. return( ERROR_NOT_ENOUGH_MEMORY );
  476. }
  477. if (( lpwsDstIconPath = (LPWSTR)LocalAlloc( LPTR, (MAX_PATH +
  478. AFPSERVER_VOLUME_ICON_FILE_SIZE + 1 +
  479. (sizeof(AFPSERVER_RESOURCE_STREAM)/sizeof(WCHAR))) *
  480. sizeof(WCHAR)) ) == NULL )
  481. {
  482. LocalFree( lpwsValName );
  483. LocalFree( lpbMultiSz );
  484. LocalFree( lpwsSrcIconPath );
  485. return( ERROR_NOT_ENOUGH_MEMORY );
  486. }
  487. // Construct a path to the NTSFM volume custom icon
  488. //
  489. *lpwsSrcIconPath = 0;
  490. if ( GetSystemDirectory( lpwsSrcIconPath, MAX_PATH * sizeof(WCHAR) ))
  491. {
  492. wcscat( lpwsSrcIconPath, AFP_DEF_VOLICON_SRCNAME );
  493. }
  494. for ( dwIndex = 0,
  495. dwBufSize = dwMaxValueDataSize,
  496. dwValNameBufSize = dwMaxValNameLen;
  497. dwIndex < dwNumValues;
  498. dwIndex++,
  499. dwBufSize = dwMaxValueDataSize,
  500. dwValNameBufSize = dwMaxValNameLen ) {
  501. ZeroMemory( lpbMultiSz, dwBufSize );
  502. // Get the volume info from the registry in multi-sz form.
  503. //
  504. if ( dwRetCode = RegEnumValue( AfpGlobals.hkeyVolumesList,
  505. dwIndex,
  506. lpwsValName,
  507. &dwValNameBufSize,
  508. NULL,
  509. &dwType,
  510. lpbMultiSz,
  511. &dwBufSize
  512. ))
  513. break;
  514. // Parse the mult sz and extract info into volume info structure
  515. //
  516. if ( dwRetCode = AfpBufParseMultiSz(
  517. AFP_VOLUME_STRUCT,
  518. lpbMultiSz,
  519. (LPBYTE)&VolumeInfo ) ) {
  520. // If this volume contained invalid registry information then log
  521. // it and store the volume name in the list of invalid volumes.
  522. //
  523. AfpAddInvalidVolume( lpwsValName, NULL );
  524. AfpLogEvent( AFPLOG_INVALID_VOL_REG,1,&lpwsValName,
  525. dwRetCode, EVENTLOG_WARNING_TYPE );
  526. dwRetCode = NO_ERROR;
  527. continue;
  528. }
  529. // Insert the volume name viz. the valuename
  530. //
  531. VolumeInfo.afpvol_name = lpwsValName;
  532. // Validate the volume info structure
  533. //
  534. if ( !IsAfpVolumeInfoValid( AFP_VALIDATE_ALL_FIELDS, &VolumeInfo ) ) {
  535. // If this volume contained invalid registry information then log
  536. // it and store the volume name in the list of invalid volumes.
  537. //
  538. AfpAddInvalidVolume( lpwsValName, NULL );
  539. AfpLogEvent( AFPLOG_INVALID_VOL_REG,1,&lpwsValName,
  540. dwRetCode, EVENTLOG_WARNING_TYPE );
  541. dwRetCode = NO_ERROR;
  542. continue;
  543. }
  544. // If there is a password then decrypt it
  545. //
  546. if ( VolumeInfo.afpvol_password != (LPWSTR)NULL ){
  547. dwLength = STRLEN( VolumeInfo.afpvol_password );
  548. for ( dwCount = 0; dwCount < dwLength; dwCount++ )
  549. VolumeInfo.afpvol_password[dwCount] ^= 0xF000;
  550. }
  551. //
  552. // Construct a path to the destination volume "Icon<0D>" file
  553. //
  554. fCopiedIcon = FALSE;
  555. wcscpy( lpwsDstIconPath, VolumeInfo.afpvol_path );
  556. if (lpwsDstIconPath[wcslen(lpwsDstIconPath) - 1] != TEXT('\\'))
  557. {
  558. wcscat( lpwsDstIconPath, TEXT("\\") );
  559. }
  560. wcscat( lpwsDstIconPath, wchServerIconFile );
  561. // Keep track of end of name without the resource fork tacked on
  562. //
  563. dwLastDstCharIndex = wcslen(lpwsDstIconPath);
  564. wcscat( lpwsDstIconPath, AFPSERVER_RESOURCE_STREAM );
  565. // Copy the icon file to the root of the volume (do not overwrite)
  566. //
  567. if ((fCopiedIcon = (BOOLEAN)CopyFile( lpwsSrcIconPath, lpwsDstIconPath, TRUE )) ||
  568. (GetLastError() == ERROR_FILE_EXISTS))
  569. {
  570. VolumeInfo.afpvol_props_mask |= AFP_VOLUME_HAS_CUSTOM_ICON;
  571. // Make sure the file is hidden
  572. SetFileAttributes( lpwsDstIconPath,
  573. FILE_ATTRIBUTE_HIDDEN |
  574. FILE_ATTRIBUTE_ARCHIVE );
  575. }
  576. // Make this a self relative buffer
  577. //
  578. if ( dwRetCode = AfpBufMakeFSDRequest(
  579. (LPBYTE)&VolumeInfo,
  580. 0,
  581. AFP_VOLUME_STRUCT,
  582. &lpbFSDBuf,
  583. &dwBufSize
  584. ))
  585. break;
  586. // Initialize the FSD with this volume
  587. //
  588. AfpRequestPkt.dwRequestCode = OP_VOLUME_ADD;
  589. AfpRequestPkt.dwApiType = AFP_API_TYPE_ADD;
  590. AfpRequestPkt.Type.Add.pInputBuf = lpbFSDBuf;
  591. AfpRequestPkt.Type.Add.cbInputBufSize = dwBufSize;
  592. dwRetCode = AfpServerIOCtrl( &AfpRequestPkt );
  593. if ( dwRetCode ) {
  594. // If this volume could not be added by the FSD then we errorlog
  595. // this and insert this volume into the list of invalid volumes.
  596. //
  597. AfpAddInvalidVolume( lpwsValName, VolumeInfo.afpvol_path );
  598. AfpLogEvent( AFPLOG_CANT_ADD_VOL, 1, &lpwsValName,
  599. dwRetCode, EVENTLOG_WARNING_TYPE );
  600. dwRetCode = NO_ERROR;
  601. // Delete the icon file we just copied if the volume add failed
  602. //
  603. if ( fCopiedIcon )
  604. {
  605. // Truncate the resource fork name so we delete the whole file
  606. lpwsDstIconPath[dwLastDstCharIndex] = 0;
  607. DeleteFile( lpwsDstIconPath );
  608. }
  609. }
  610. LocalFree( lpbFSDBuf );
  611. }
  612. LocalFree( lpwsValName );
  613. LocalFree( lpbMultiSz );
  614. LocalFree( lpwsSrcIconPath );
  615. LocalFree( lpwsDstIconPath );
  616. return( dwRetCode );
  617. }
  618. //**
  619. //
  620. // Call: AfpInitETCMaps
  621. //
  622. // Returns: NO_ERROR success
  623. // non-zero returns from the IOCTL
  624. // non-zero returns from the AfpRegXXX apis.
  625. //
  626. //
  627. // Description: This routine will read in all the type/creators and extensions
  628. // from the registry and store them in a cache. It will then
  629. // create a list of mappings from the cache and then IOCTL the
  630. // the FSD to add them. If the default is not in the registry,
  631. // a hardcoded one is used. All non-zero returns from this
  632. // routine are fatal. All non-fatal errors will be logged.
  633. //
  634. //
  635. DWORD
  636. AfpInitETCMaps(
  637. VOID
  638. )
  639. {
  640. DWORD dwRetCode;
  641. AFP_REQUEST_PACKET AfpSrp;
  642. AFP_EXTENSION DefExtension;
  643. AFP_TYPE_CREATOR DefTypeCreator;
  644. BYTE bDefaultETC[sizeof(ETCMAPINFO2)+sizeof(SETINFOREQPKT)];
  645. PAFP_TYPE_CREATOR pTypeCreator;
  646. DWORD dwNumTypeCreators;
  647. AFP_TYPE_CREATOR AfpTypeCreatorKey;
  648. // Get all type-creators from the registry and store them in a global cache.
  649. //
  650. if ( dwRetCode = AfpRegTypeCreatorEnum() )
  651. return( dwRetCode );
  652. // Get all extensions from the registry and store them in a global cache.
  653. //
  654. if ( dwRetCode = AfpRegExtensionEnum() )
  655. return( dwRetCode );
  656. // If there are no mappings do not IOCTL.
  657. //
  658. if ( AfpGlobals.AfpETCMapInfo.afpetc_num_extensions > 0 ) {
  659. // IOCTL the FSD to Add these mappings
  660. //
  661. AfpSrp.dwRequestCode = OP_SERVER_ADD_ETC;
  662. AfpSrp.dwApiType = AFP_API_TYPE_ADD;
  663. // Make a buffer with the type/creator mappings in the form as required
  664. // by the FSD
  665. //
  666. if ( dwRetCode = AfpBufMakeFSDETCMappings(
  667. (PSRVETCPKT*)&(AfpSrp.Type.Add.pInputBuf),
  668. &(AfpSrp.Type.Add.cbInputBufSize) ) )
  669. return( dwRetCode );
  670. if ( AfpSrp.Type.Add.cbInputBufSize > 0 ) {
  671. dwRetCode = AfpServerIOCtrl( &AfpSrp );
  672. LocalFree( AfpSrp.Type.Add.pInputBuf );
  673. if ( dwRetCode )
  674. return( dwRetCode );
  675. }
  676. else
  677. LocalFree( AfpSrp.Type.Add.pInputBuf );
  678. }
  679. // Check to see if the default type/creator is in the registry
  680. //
  681. AfpTypeCreatorKey.afptc_id = AFP_DEF_TCID;
  682. dwNumTypeCreators = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
  683. pTypeCreator = _lfind( &AfpTypeCreatorKey,
  684. AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
  685. (unsigned int *)&dwNumTypeCreators,
  686. sizeof(AFP_TYPE_CREATOR),
  687. AfpLCompareTypeCreator );
  688. // If the default is not in the registry use the hard-coded defaults.
  689. //
  690. if ( pTypeCreator == NULL ) {
  691. STRCPY( DefTypeCreator.afptc_type, AFP_DEF_TYPE );
  692. STRCPY( DefTypeCreator.afptc_creator, AFP_DEF_CREATOR );
  693. STRCPY( DefTypeCreator.afptc_comment, AfpGlobals.wchDefTCComment );
  694. DefTypeCreator.afptc_id = AFP_DEF_TCID;
  695. }
  696. else
  697. DefTypeCreator = *pTypeCreator;
  698. ZeroMemory( (LPBYTE)(DefExtension.afpe_extension),
  699. AFP_FIELD_SIZE( AFP_EXTENSION, afpe_extension) );
  700. STRCPY( DefExtension.afpe_extension, AFP_DEF_EXTENSION_W );
  701. AfpBufCopyFSDETCMapInfo( &DefTypeCreator,
  702. &DefExtension,
  703. (PETCMAPINFO2)(bDefaultETC+sizeof(SETINFOREQPKT)));
  704. // IOCTL the FSD to set the default
  705. //
  706. AfpSrp.dwRequestCode = OP_SERVER_SET_ETC;
  707. AfpSrp.dwApiType = AFP_API_TYPE_SETINFO;
  708. AfpSrp.Type.SetInfo.pInputBuf = bDefaultETC;
  709. AfpSrp.Type.SetInfo.cbInputBufSize = sizeof( bDefaultETC );
  710. if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
  711. return( dwRetCode );
  712. // If the default was not in the cache, add it now.
  713. //
  714. if ( pTypeCreator == NULL ) {
  715. // Grow the cache size by one entry.
  716. //
  717. pTypeCreator = AfpGlobals.AfpETCMapInfo.afpetc_type_creator;
  718. dwNumTypeCreators = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
  719. pTypeCreator = (PAFP_TYPE_CREATOR)LocalReAlloc(
  720. pTypeCreator,
  721. (dwNumTypeCreators+1)*sizeof(AFP_TYPE_CREATOR),
  722. LMEM_MOVEABLE );
  723. if ( pTypeCreator == NULL )
  724. return( ERROR_NOT_ENOUGH_MEMORY );
  725. pTypeCreator[dwNumTypeCreators++] = DefTypeCreator;
  726. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators = dwNumTypeCreators;
  727. AfpGlobals.AfpETCMapInfo.afpetc_type_creator = pTypeCreator;
  728. // Sort the table
  729. //
  730. qsort( pTypeCreator,
  731. dwNumTypeCreators,
  732. sizeof(AFP_TYPE_CREATOR),
  733. AfpBCompareTypeCreator );
  734. }
  735. return( NO_ERROR );
  736. }
  737. //**
  738. //
  739. // Call: AfpInitServerIcons
  740. //
  741. // Returns: NO_ERROR - success
  742. // ERROR_NOT_ENOUGH_MEMORY
  743. // non-zero return codes from registry apis.
  744. //
  745. // Description: This procedure will read in an icon at a time from the
  746. // registry, and then register this icon with the server.
  747. // This procedure will only return fatal errors that will
  748. // require that the service fail initialization. All other
  749. // error will be logged by this routine. All returns from the
  750. // the FSD are treated as non-fatal.
  751. //
  752. //
  753. DWORD
  754. AfpInitServerIcons(
  755. VOID
  756. )
  757. {
  758. DWORD dwRetCode;
  759. LPWSTR lpwsValName;
  760. DWORD dwMaxValNameLen;
  761. DWORD dwNumValues;
  762. DWORD dwMaxValueDataSize;
  763. DWORD dwIndex;
  764. DWORD dwType;
  765. DWORD dwBufSize;
  766. DWORD dwValNameBufSize;
  767. AFP_REQUEST_PACKET AfpRequestPkt;
  768. LPBYTE lpbMultiSz;
  769. AFP_ICON_INFO IconInfo;
  770. // Find out the size of the largest data value and the largest
  771. // value name.
  772. //
  773. if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyIcons,
  774. &dwMaxValNameLen,
  775. &dwNumValues,
  776. &dwMaxValueDataSize
  777. ))
  778. return( dwRetCode );
  779. // If there are no icons in the registry then simply return
  780. //
  781. if ( dwNumValues == 0 )
  782. return( NO_ERROR );
  783. if (( lpwsValName = (LPWSTR)LocalAlloc( LPTR, dwMaxValNameLen )) == NULL )
  784. return( ERROR_NOT_ENOUGH_MEMORY );
  785. if (( lpbMultiSz = (LPBYTE)LocalAlloc( LPTR, dwMaxValueDataSize))== NULL){
  786. LocalFree( lpwsValName );
  787. return( ERROR_NOT_ENOUGH_MEMORY );
  788. }
  789. for ( dwIndex = 0,
  790. dwBufSize = dwMaxValueDataSize,
  791. dwValNameBufSize = dwMaxValNameLen;
  792. dwIndex < dwNumValues;
  793. dwIndex++,
  794. dwBufSize = dwMaxValueDataSize,
  795. dwValNameBufSize = dwMaxValNameLen ) {
  796. ZeroMemory( lpbMultiSz, dwBufSize );
  797. // Get the icon from the registry.
  798. //
  799. if ( dwRetCode = RegEnumValue( AfpGlobals.hkeyIcons,
  800. dwIndex,
  801. lpwsValName,
  802. &dwValNameBufSize,
  803. NULL,
  804. &dwType,
  805. lpbMultiSz,
  806. &dwBufSize
  807. ))
  808. break;
  809. // Parse the mult sz and extract info into icon info structure
  810. //
  811. if ( dwRetCode = AfpBufParseMultiSz(
  812. AFP_ICON_STRUCT,
  813. lpbMultiSz,
  814. (LPBYTE)&IconInfo
  815. )) {
  816. AfpLogEvent( AFPLOG_CANT_ADD_ICON, 1, &lpwsValName,
  817. dwRetCode, EVENTLOG_WARNING_TYPE );
  818. dwRetCode = NO_ERROR;
  819. continue;
  820. }
  821. if ( dwRetCode = AfpBufUnicodeToNibble((LPWSTR)IconInfo.afpicon_data)){
  822. AfpLogEvent( AFPLOG_CANT_ADD_ICON, 1, &lpwsValName,
  823. dwRetCode, EVENTLOG_WARNING_TYPE );
  824. dwRetCode = NO_ERROR;
  825. continue;
  826. }
  827. // Validate the icon info structure
  828. //
  829. if ( !IsAfpIconValid( &IconInfo ) ) {
  830. AfpLogEvent( AFPLOG_CANT_ADD_ICON, 1, &lpwsValName,
  831. dwRetCode, EVENTLOG_WARNING_TYPE );
  832. dwRetCode = NO_ERROR;
  833. continue;
  834. }
  835. // Copy the icon info into an FSD icon structure.
  836. // NOTE: Re-use lpbMultiSz to store the FSD Icon structure. We know
  837. // it is big enough, because the FSD icon structure HAS to be
  838. // smaller than the MultiSz that contains the same information.
  839. //
  840. AfpBufMakeFSDIcon( &IconInfo, lpbMultiSz, &dwBufSize );
  841. // Initialize the FSD with this icon
  842. //
  843. AfpRequestPkt.dwRequestCode = OP_SERVER_ADD_ICON;
  844. AfpRequestPkt.dwApiType = AFP_API_TYPE_ADD;
  845. AfpRequestPkt.Type.Add.pInputBuf = lpbMultiSz;
  846. AfpRequestPkt.Type.Add.cbInputBufSize = dwBufSize;
  847. if ( dwRetCode = AfpServerIOCtrl( &AfpRequestPkt ) ) {
  848. AfpLogEvent( AFPLOG_CANT_ADD_ICON, 1, &lpwsValName,
  849. dwRetCode, EVENTLOG_WARNING_TYPE );
  850. dwRetCode = NO_ERROR;
  851. continue;
  852. }
  853. }
  854. LocalFree( lpwsValName );
  855. LocalFree( lpbMultiSz );
  856. return( dwRetCode );
  857. }
  858. //**
  859. //
  860. // Call: AfpInitRPC
  861. //
  862. // Returns: NO_ERROR - success
  863. // ERROR_NOT_ENOUGH_MEMORY
  864. // nonzero returns from RPC APIs
  865. // RpcServerRegisterIf()
  866. // RpcServerUseProtseqEp()
  867. //
  868. // Description: Starts an RPC Server, adds the address (or port/pipe),
  869. // and adds the interface (dispatch table).
  870. //
  871. DWORD
  872. AfpInitRPC( VOID )
  873. {
  874. RPC_STATUS RpcStatus;
  875. LPWSTR lpwsEndpoint = NULL;
  876. BOOL Bool;
  877. // We need to concatenate \pipe\ to the front of the interface name.
  878. //
  879. lpwsEndpoint = (LPWSTR)LocalAlloc( LPTR, sizeof(NT_PIPE_PREFIX) +
  880. ((STRLEN(AFP_SERVICE_NAME)+1)*sizeof(WCHAR)));
  881. if ( lpwsEndpoint == NULL)
  882. return( ERROR_NOT_ENOUGH_MEMORY );
  883. STRCPY( lpwsEndpoint, NT_PIPE_PREFIX );
  884. STRCAT( lpwsEndpoint, AFP_SERVICE_NAME );
  885. // Ignore the second argument for now.
  886. //
  887. RpcStatus = RpcServerUseProtseqEpW( TEXT("ncacn_np"),
  888. 10,
  889. lpwsEndpoint,
  890. NULL );
  891. if ( RpcStatus != RPC_S_OK )
  892. {
  893. LocalFree( lpwsEndpoint );
  894. return( I_RpcMapWin32Status( RpcStatus ) );
  895. }
  896. RpcStatus = RpcServerRegisterIf( afpsvc_v0_0_s_ifspec, 0, 0);
  897. LocalFree( lpwsEndpoint );
  898. if ( RpcStatus == RPC_S_OK )
  899. return( NO_ERROR );
  900. else
  901. return( I_RpcMapWin32Status( RpcStatus ) );
  902. }
  903. //**
  904. //
  905. // Call: AfpTerminateRPC
  906. //
  907. // Returns: none
  908. //
  909. // Description: Deletes the interface.
  910. //
  911. VOID
  912. AfpTerminateRPC(
  913. VOID
  914. )
  915. {
  916. RPC_STATUS RpcStatus;
  917. if ( AfpGlobals.dwServerState & AFPSTATE_RPC_STARTED )
  918. {
  919. RpcStatus = RpcServerUnregisterIf( afpsvc_v0_0_s_ifspec, 0, 0 );
  920. if (RpcStatus != RPC_S_OK)
  921. {
  922. AFP_PRINT(("RpcServerUnregisterIf failed %ld\n", I_RpcMapWin32Status( RpcStatus )));
  923. }
  924. }
  925. return;
  926. }
  927. //**
  928. //
  929. // Call: AfpIniLsa
  930. //
  931. // Returns: none.
  932. //
  933. // Description: This procedure will register our process with LSA, needed for
  934. // change-password
  935. //
  936. VOID
  937. AfpIniLsa(
  938. VOID
  939. )
  940. {
  941. NTSTATUS ntstatus;
  942. STRING LsaName;
  943. LSA_OPERATIONAL_MODE SecurityMode;
  944. //
  945. // register with Lsa as a logon process
  946. //
  947. RtlInitString(&LsaName, LOGON_PROCESS_NAME);
  948. ntstatus = LsaRegisterLogonProcess(&LsaName, &SfmLsaHandle, &SecurityMode);
  949. if (ntstatus != STATUS_SUCCESS)
  950. {
  951. SfmLsaHandle = NULL;
  952. return;
  953. }
  954. //
  955. // call Lsa to get the MSV1_0's pkg id, which we need during logon
  956. //
  957. RtlInitString(&LsaName, MSV1_0_PACKAGE_NAME);
  958. ntstatus = LsaLookupAuthenticationPackage(SfmLsaHandle, &LsaName, &SfmAuthPkgId);
  959. if (ntstatus != STATUS_SUCCESS)
  960. {
  961. LsaDeregisterLogonProcess( SfmLsaHandle );
  962. SfmLsaHandle = NULL;
  963. return;
  964. }
  965. return;
  966. }
  967. BOOL
  968. IsAfpGuestAccountEnabled(
  969. VOID
  970. )
  971. {
  972. NTSTATUS rc;
  973. LSA_HANDLE hLsa;
  974. PPOLICY_ACCOUNT_DOMAIN_INFO pAcctDomainInfo;
  975. SECURITY_QUALITY_OF_SERVICE QOS;
  976. OBJECT_ATTRIBUTES ObjAttribs;
  977. NTSTATUS status;
  978. SAM_HANDLE SamHandle;
  979. SAM_HANDLE DomainHandle;
  980. PUSER_ACCOUNT_INFORMATION UserAccount = NULL;
  981. BOOLEAN fGuestEnabled;
  982. SAMPR_HANDLE GuestAcctHandle;
  983. // for now
  984. fGuestEnabled = FALSE;
  985. //
  986. // Open the LSA and obtain a handle to it.
  987. //
  988. QOS.Length = sizeof(QOS);
  989. QOS.ImpersonationLevel = SecurityImpersonation;
  990. QOS.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  991. QOS.EffectiveOnly = FALSE;
  992. InitializeObjectAttributes(&ObjAttribs, NULL, 0L, NULL, NULL);
  993. ObjAttribs.SecurityQualityOfService = &QOS;
  994. status = LsaOpenPolicy(NULL,
  995. &ObjAttribs,
  996. POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES,
  997. &hLsa);
  998. if (!NT_SUCCESS(status))
  999. {
  1000. AFP_PRINT(("LsaOpenPolicy failed %lx\n",status));
  1001. return(fGuestEnabled);
  1002. }
  1003. //
  1004. // get the Domain Sid for the local domain: we'll need it very shortly
  1005. //
  1006. rc = LsaQueryInformationPolicy(hLsa,
  1007. PolicyAccountDomainInformation,
  1008. (PVOID) &pAcctDomainInfo);
  1009. if (!NT_SUCCESS(rc))
  1010. {
  1011. AFP_PRINT(("InitLSA: LsaQueryInfo... failed (%lx)\n",rc));
  1012. LsaClose(hLsa);
  1013. return(fGuestEnabled);
  1014. }
  1015. InitializeObjectAttributes(&ObjAttribs, NULL, 0L, NULL, NULL);
  1016. status = SamConnect(NULL, &SamHandle, MAXIMUM_ALLOWED, &ObjAttribs);
  1017. if (!NT_SUCCESS(status))
  1018. {
  1019. AFP_PRINT(("SamConnect failed %lx\n",status));
  1020. LsaFreeMemory(pAcctDomainInfo);
  1021. LsaClose(hLsa);
  1022. return(fGuestEnabled);
  1023. }
  1024. status = SamOpenDomain(
  1025. SamHandle,
  1026. MAXIMUM_ALLOWED,
  1027. pAcctDomainInfo->DomainSid,
  1028. &DomainHandle);
  1029. LsaFreeMemory(pAcctDomainInfo);
  1030. LsaClose(hLsa);
  1031. if (!NT_SUCCESS(status))
  1032. {
  1033. AFP_PRINT(("SamOpenDomain failed %lx\n",status));
  1034. SamCloseHandle(SamHandle);
  1035. return(fGuestEnabled);
  1036. }
  1037. status = SamOpenUser(
  1038. DomainHandle,
  1039. MAXIMUM_ALLOWED,
  1040. DOMAIN_USER_RID_GUEST,
  1041. &GuestAcctHandle);
  1042. if (!NT_SUCCESS(status))
  1043. {
  1044. AFP_PRINT(("SamOpenUser failed %lx\n",status));
  1045. SamCloseHandle(SamHandle);
  1046. return(fGuestEnabled);
  1047. }
  1048. status = SamQueryInformationUser(
  1049. GuestAcctHandle,
  1050. UserAccountInformation,
  1051. (PVOID *) &UserAccount );
  1052. if (!NT_SUCCESS(status))
  1053. {
  1054. AFP_PRINT(("SamQueryInformationUser failed %lx\n",status));
  1055. SamCloseHandle(SamHandle);
  1056. return(fGuestEnabled);
  1057. }
  1058. //
  1059. // now, see if the guest account is enabled.
  1060. //
  1061. if (!(UserAccount->UserAccountControl & USER_ACCOUNT_DISABLED))
  1062. {
  1063. fGuestEnabled = TRUE;
  1064. }
  1065. SamFreeMemory(UserAccount);
  1066. SamCloseHandle(GuestAcctHandle);
  1067. SamCloseHandle(SamHandle);
  1068. return(fGuestEnabled);
  1069. }