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.

641 lines
16 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1992 **/
  4. /**********************************************************************/
  5. /*
  6. perms.cxx
  7. Contains the dialog for setting permissions on directories
  8. DIRECTORY_PERMISSIONS_DLG
  9. FILE HISTORY:
  10. NarenG 11/30/92 Created
  11. */
  12. extern "C"
  13. {
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <ntseapi.h>
  17. #include <nturtl.h>
  18. }
  19. #define INCL_WINDOWS_GDI
  20. #define INCL_WINDOWS
  21. #define INCL_DOSERRORS
  22. #define INCL_NETERRORS
  23. #define INCL_NETSERVER
  24. #define INCL_NETSHARE
  25. #define INCL_NETCONS
  26. #define INCL_NETLIB
  27. #include <lmui.hxx>
  28. #define INCL_BLT_WINDOW
  29. #define INCL_BLT_DIALOG
  30. #define INCL_BLT_CONTROL
  31. #define INCL_BLT_MISC
  32. #define INCL_BLT_CLIENT
  33. #define INCL_BLT_MSGPOPUP
  34. #define INCL_BLT_SPIN_GROUP
  35. #define INCL_BLT_GROUP
  36. #include <blt.hxx>
  37. extern "C"
  38. {
  39. #include <afpmgr.h>
  40. #include <macfile.h>
  41. #define _NTSEAPI_ // This prevents getuser.h from including
  42. // ntseapi.h again.
  43. #include <getuser.h> // the user-browser dialog
  44. }
  45. #include <netname.hxx>
  46. #include <string.hxx>
  47. #include <uitrace.hxx>
  48. #include "util.hxx"
  49. #include "perms.hxx"
  50. /*******************************************************************
  51. NAME: DIRECTORY_PERMISSIONS_DLG::DIRECTORY_PERMISSIONS_DLG
  52. SYNOPSIS: Constructor
  53. ENTRY: hwndParent - hwnd of the parent window
  54. hServer - handle to the AFP server
  55. pszDirPath - Absolute path relative to the server that
  56. is being administered.
  57. pszDisplayPath - Path as the user typed it in or as was
  58. selected from the filemgr,
  59. fDirInVolume - If TRUE then the directory path must be
  60. part of a volume. If FALSE then it may
  61. not and the directory information is not
  62. set. Instead, the information is returned
  63. in the follwing fields.
  64. pnlsOwner - Owner of the directory.
  65. pnlsGroup - Primary Group of the directory.
  66. lpdwPerms - Various directory permissions.
  67. EXIT:
  68. RETURNS:
  69. NOTES:
  70. HISTORY:
  71. NarenG 11/30/92 Created
  72. ********************************************************************/
  73. DIRECTORY_PERMISSIONS_DLG::DIRECTORY_PERMISSIONS_DLG(
  74. HWND hwndOwner,
  75. AFP_SERVER_HANDLE hServer,
  76. const TCHAR *pszServerName,
  77. BOOL fCalledBySrvMgr,
  78. const TCHAR *pszDirPath,
  79. const TCHAR *pszDisplayPath,
  80. BOOL fDirInVolume,
  81. NLS_STR *pnlsOwner,
  82. NLS_STR *pnlsGroup,
  83. DWORD *lpdwPerms )
  84. : DIALOG_WINDOW( MAKEINTRESOURCE( IDD_DIRECTORY_PERMISSIONS_DLG ),
  85. hwndOwner ),
  86. _chkOwnerSeeFiles( this, IDDP_CHK_OWNER_FILE ),
  87. _chkOwnerSeeFolders( this,IDDP_CHK_OWNER_FOLDER ),
  88. _chkOwnerMakeChanges( this,IDDP_CHK_OWNER_CHANGES ),
  89. _chkGroupSeeFiles( this,IDDP_CHK_GROUP_FILE ),
  90. _chkGroupSeeFolders( this,IDDP_CHK_GROUP_FOLDER ),
  91. _chkGroupMakeChanges( this,IDDP_CHK_GROUP_CHANGES ),
  92. _chkWorldSeeFiles( this,IDDP_CHK_WORLD_FILE ),
  93. _chkWorldSeeFolders( this,IDDP_CHK_WORLD_FOLDER ),
  94. _chkWorldMakeChanges( this,IDDP_CHK_WORLD_CHANGES ),
  95. _chkReadOnly( this,IDDP_CHK_READONLY ),
  96. _chkRecursePerms( this, IDDP_CHK_RECURSE ),
  97. _sltpPath( this, IDDP_SLT_PATH, ELLIPSIS_PATH ),
  98. _sleOwner( this, IDDP_SLE_OWNER, UNLEN ),
  99. _slePrimaryGroup( this, IDDP_SLE_PRIMARYGROUP, GNLEN ),
  100. _pszDirPath( pszDirPath ),
  101. _pbOwner( this, IDDP_PB_OWNER ),
  102. _pbGroup( this, IDDP_PB_GROUP ),
  103. _fDirInVolume( fDirInVolume ),
  104. _pnlsOwner( pnlsOwner ),
  105. _pnlsGroup( pnlsGroup ),
  106. _lpdwPerms( lpdwPerms ),
  107. _nlsServerName( pszServerName ),
  108. _hServer( hServer )
  109. {
  110. //
  111. // Make sure everything constructed OK
  112. //
  113. if ( QueryError() != NERR_Success )
  114. return;
  115. APIERR err;
  116. if ( (( err = _chkOwnerSeeFiles.QueryError() ) != NERR_Success ) ||
  117. (( err = _chkOwnerSeeFolders.QueryError() ) != NERR_Success ) ||
  118. (( err = _chkOwnerMakeChanges.QueryError() ) != NERR_Success ) ||
  119. (( err = _chkGroupSeeFiles.QueryError() ) != NERR_Success ) ||
  120. (( err = _chkGroupSeeFolders.QueryError() ) != NERR_Success ) ||
  121. (( err = _chkGroupMakeChanges.QueryError() ) != NERR_Success ) ||
  122. (( err = _chkWorldSeeFiles.QueryError() ) != NERR_Success ) ||
  123. (( err = _chkWorldSeeFolders.QueryError() ) != NERR_Success ) ||
  124. (( err = _chkWorldMakeChanges.QueryError() ) != NERR_Success ) ||
  125. (( err = _chkReadOnly.QueryError() ) != NERR_Success ) ||
  126. (( err = _chkRecursePerms.QueryError() ) != NERR_Success ) ||
  127. (( err = _sltpPath.QueryError() ) != NERR_Success ) ||
  128. (( err = _sleOwner.QueryError() ) != NERR_Success ) ||
  129. (( err = _nlsServerName.QueryError() ) != NERR_Success ) ||
  130. (( err = _slePrimaryGroup.QueryError() ) != NERR_Success ) )
  131. {
  132. ReportError( err );
  133. return;
  134. }
  135. //
  136. // This may take a while..
  137. //
  138. AUTO_CURSOR Cursor;
  139. if ( fCalledBySrvMgr )
  140. {
  141. //
  142. // Set the caption.
  143. //
  144. err = ::SetCaption( this,
  145. IDS_CAPTION_DIRECTORY_PERMS,
  146. pszServerName);
  147. if( err != NERR_Success )
  148. {
  149. ReportError( err );
  150. return;
  151. }
  152. }
  153. //
  154. // Get the directory information
  155. //
  156. PAFP_DIRECTORY_INFO pAfpDirInfo;
  157. err = ::AfpAdminDirectoryGetInfo( _hServer,
  158. (LPWSTR)pszDirPath,
  159. (LPBYTE*)&pAfpDirInfo );
  160. if ( err != NO_ERROR )
  161. {
  162. ReportError( err );
  163. return;
  164. }
  165. //
  166. // Set the path, search for & and add another & to it
  167. //
  168. NLS_STR nlsDisplayPath( pszDisplayPath );
  169. if ( ( err = nlsDisplayPath.QueryError() ) != NERR_Success )
  170. {
  171. ReportError( err );
  172. return;
  173. }
  174. //
  175. // Add an extra & for every & found in the path, otherwise the character
  176. // following the & will become a hotkey.
  177. //
  178. NLS_STR nlsAmp( TEXT("&") );
  179. if ( ( err = nlsAmp.QueryError() ) != NERR_Success )
  180. {
  181. ReportError( err );
  182. return;
  183. }
  184. ISTR istrPos( nlsDisplayPath );
  185. ISTR istrStart( nlsDisplayPath );
  186. while ( nlsDisplayPath.strstr( &istrPos, nlsAmp, istrStart ) )
  187. {
  188. nlsDisplayPath.InsertStr( nlsAmp, ++istrPos );
  189. istrStart = ++istrPos;
  190. }
  191. _sltpPath.SetText( nlsDisplayPath );
  192. //
  193. // If the directory must be within the volume and it is not then
  194. // we return the error
  195. //
  196. if ( fDirInVolume && (!pAfpDirInfo->afpdir_in_volume) )
  197. {
  198. ::AfpAdminBufferFree( pAfpDirInfo );
  199. ReportError( AFPERR_DirectoryNotInVolume );
  200. return;
  201. }
  202. //
  203. // Ok, we have all the information we need so set all the controls
  204. //
  205. _sleOwner.SetText( pAfpDirInfo->afpdir_owner );
  206. _slePrimaryGroup.SetText( pAfpDirInfo->afpdir_group );
  207. _chkOwnerSeeFiles.SetCheck((INT)( pAfpDirInfo->afpdir_perms
  208. & AFP_PERM_OWNER_SFI ));
  209. _chkOwnerSeeFolders.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  210. & AFP_PERM_OWNER_SFO ));
  211. _chkOwnerMakeChanges.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  212. & AFP_PERM_OWNER_MC ));
  213. _chkGroupSeeFiles.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  214. & AFP_PERM_GROUP_SFI ));
  215. _chkGroupSeeFolders.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  216. & AFP_PERM_GROUP_SFO ));
  217. _chkGroupMakeChanges.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  218. & AFP_PERM_GROUP_MC ));
  219. _chkWorldSeeFiles.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  220. & AFP_PERM_WORLD_SFI ));
  221. _chkWorldSeeFolders.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  222. & AFP_PERM_WORLD_SFO ));
  223. _chkWorldMakeChanges.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  224. & AFP_PERM_WORLD_MC ));
  225. _chkReadOnly.SetCheck( (INT)( pAfpDirInfo->afpdir_perms
  226. & AFP_PERM_INHIBIT_MOVE_DELETE ));
  227. _sleOwner.ClaimFocus();
  228. ::AfpAdminBufferFree( pAfpDirInfo );
  229. }
  230. /*******************************************************************
  231. NAME: DIRECTORY_PERMISSIONS_DLG :: OnCommand
  232. SYNOPSIS: This method is called whenever a WM_COMMAND message
  233. is sent to the dialog procedure.
  234. ENTRY: cid - The control ID from the
  235. generating control.
  236. EXIT: The command has been handled.
  237. RETURNS: BOOL - TRUE if we handled the command.
  238. FALSE if we did not handle
  239. the command.
  240. HISTORY:
  241. NarenG 11/30/92 Created
  242. ********************************************************************/
  243. BOOL DIRECTORY_PERMISSIONS_DLG :: OnCommand( const CONTROL_EVENT & event )
  244. {
  245. if( ( event.QueryCid() == _pbOwner.QueryCid() ) ||
  246. ( event.QueryCid() == _pbGroup.QueryCid() ) )
  247. {
  248. USERBROWSER UserBrowser;
  249. HUSERBROW hUserBrowser;
  250. BYTE Buffer[3000];
  251. LPUSERDETAILS lpUserDetails = (LPUSERDETAILS)&Buffer;
  252. DWORD dwBufferSize = sizeof( Buffer );
  253. NLS_STR nlsHelpFileName;
  254. NLS_STR nlsCaption;
  255. APIERR err;
  256. NTSTATUS ntStatus;
  257. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  258. PSID pSid;
  259. //
  260. // This may take a while..
  261. //
  262. AUTO_CURSOR Cursor;
  263. if ( ( ( err = nlsCaption.QueryError() ) != NERR_Success ) ||
  264. ( ( err = nlsHelpFileName.QueryError() ) != NERR_Success ) )
  265. {
  266. ::MsgPopup( this, err );
  267. return FALSE;
  268. }
  269. if ( (err = nlsHelpFileName.Load(IDS_AFPMGR_HELPFILENAME ) )
  270. != NERR_Success ) {
  271. ::MsgPopup( this, err );
  272. return FALSE;
  273. }
  274. INT ids = (( event.QueryCid() == _pbOwner.QueryCid() )
  275. ? IDS_CAPTION_OWNER
  276. : IDS_CAPTION_GROUP );
  277. if ( (err = nlsCaption.Load( ids ) ) != NERR_Success )
  278. {
  279. ::MsgPopup( this, err );
  280. return FALSE;
  281. }
  282. UserBrowser.fExpandNames = TRUE;
  283. UserBrowser.ulStructSize = sizeof( UserBrowser );
  284. UserBrowser.pszInitialDomain = (LPWSTR)(_nlsServerName.QueryPch());
  285. UserBrowser.pszHelpFileName = (LPWSTR)(nlsHelpFileName.QueryPch());
  286. UserBrowser.ulHelpContext = HC_SELECT_OWNER_GROUP;
  287. UserBrowser.hwndOwner = QueryHwnd();
  288. UserBrowser.Flags = ( USRBROWS_SINGLE_SELECT |
  289. USRBROWS_INCL_ALL |
  290. USRBROWS_SHOW_GROUPS |
  291. USRBROWS_SHOW_USERS |
  292. USRBROWS_SHOW_ALIASES |
  293. USRBROWS_EXPAND_USERS );
  294. UserBrowser.pszTitle = (WCHAR *)(nlsCaption.QueryPch());
  295. hUserBrowser = ::OpenUserBrowser( &UserBrowser );
  296. if ( UserBrowser.fUserCancelled )
  297. {
  298. return FALSE;
  299. }
  300. if ( hUserBrowser == NULL )
  301. {
  302. ::MsgPopup( this, ::GetLastError() );
  303. return FALSE;
  304. }
  305. if ( ::EnumUserBrowserSelection( hUserBrowser,
  306. lpUserDetails,
  307. &dwBufferSize ) == FALSE )
  308. {
  309. err = ::GetLastError();
  310. if ( err != ERROR_NO_MORE_ITEMS )
  311. {
  312. ::MsgPopup( this, ::GetLastError() );
  313. }
  314. return FALSE;
  315. }
  316. if ( ::CloseUserBrowser( hUserBrowser ) == FALSE )
  317. {
  318. ::MsgPopup( this, ::GetLastError() );
  319. return FALSE;
  320. }
  321. NLS_STR nlsDomainName;
  322. NLS_STR nlsAccountName;
  323. if ( (( err = nlsDomainName.QueryError() ) != NERR_Success ) ||
  324. (( err = nlsAccountName.QueryError() ) != NERR_Success ) )
  325. {
  326. ::MsgPopup( this, err );
  327. return FALSE;
  328. }
  329. //
  330. // This is really a workaround for a bug in the user browser.
  331. // It prepends the account domain name for all built-in accounts.
  332. // So we have to check the SID to see if it is a built-in account,
  333. // and if it is we do not copy the domain name.
  334. //
  335. ntStatus = RtlAllocateAndInitializeSid( &NtAuthority,
  336. 1,
  337. SECURITY_BUILTIN_DOMAIN_RID,
  338. 0,0,0,0,0,0,0,
  339. &pSid );
  340. if ( !NT_SUCCESS(ntStatus) )
  341. {
  342. ::MsgPopup( this, RtlNtStatusToDosError( ntStatus ) );
  343. return FALSE;
  344. }
  345. if ( !RtlEqualSid( pSid, lpUserDetails->psidDomain ) )
  346. {
  347. if ( ( (lpUserDetails->pszDomainName) != NULL ) &&
  348. ( ::wcslen(lpUserDetails->pszDomainName) > 0 ) )
  349. {
  350. nlsDomainName.CopyFrom((TCHAR *)(lpUserDetails->pszDomainName));
  351. nlsDomainName.AppendChar( TEXT('\\') );
  352. }
  353. }
  354. RtlFreeSid( pSid );
  355. nlsAccountName.CopyFrom( (TCHAR *)(lpUserDetails->pszAccountName) );
  356. nlsDomainName.Append( nlsAccountName );
  357. if( event.QueryCid() == _pbOwner.QueryCid() )
  358. {
  359. _sleOwner.SetText( nlsDomainName.QueryPch() );
  360. }
  361. else
  362. {
  363. _slePrimaryGroup.SetText( nlsDomainName.QueryPch() );
  364. }
  365. }
  366. return DIALOG_WINDOW::OnCommand( event );
  367. }
  368. /*******************************************************************
  369. NAME: DIRECTORY_PERMISSIONS_DLG::OnOK
  370. SYNOPSIS: Called when user pushes OK button.
  371. ENTRY:
  372. EXIT:
  373. RETURNS:
  374. NOTES:
  375. HISTORY:
  376. NarenG 11/18/92 Modified for AFPMGR
  377. ********************************************************************/
  378. BOOL DIRECTORY_PERMISSIONS_DLG::OnOK( VOID )
  379. {
  380. //
  381. // This may take a while..
  382. //
  383. AUTO_CURSOR Cursor;
  384. //
  385. // This is not a loop
  386. //
  387. DWORD err;
  388. do {
  389. NLS_STR nlsOwner;
  390. NLS_STR nlsPrimaryGroup;
  391. DWORD dwPerms;
  392. if (( err = nlsOwner.QueryError()) != NERR_Success )
  393. break;
  394. if (( err = _sleOwner.QueryText( &nlsOwner )) != NERR_Success )
  395. break;
  396. if (( err = nlsPrimaryGroup.QueryError()) != NERR_Success )
  397. break;
  398. if (( err = _slePrimaryGroup.QueryText( &nlsPrimaryGroup ))
  399. != NERR_Success )
  400. break;
  401. //
  402. // Make sure user supplied an owner and a primary group
  403. //
  404. if ( nlsOwner.strlen() == 0 )
  405. {
  406. ::MsgPopup( this,IDS_NEED_OWNER );
  407. _sleOwner.ClaimFocus();
  408. return TRUE;
  409. }
  410. if ( nlsPrimaryGroup.strlen() == 0 )
  411. {
  412. ::MsgPopup( this, IDS_NEED_PRIMARY_GROUP );
  413. _slePrimaryGroup.ClaimFocus();
  414. return TRUE;
  415. }
  416. //
  417. // Get the directory(folder) permssions
  418. //
  419. dwPerms = 0;
  420. dwPerms |= _chkOwnerSeeFiles.QueryCheck() ? AFP_PERM_OWNER_SFI : 0;
  421. dwPerms |= _chkOwnerSeeFolders.QueryCheck() ? AFP_PERM_OWNER_SFO : 0;
  422. dwPerms |= _chkOwnerMakeChanges.QueryCheck() ? AFP_PERM_OWNER_MC : 0;
  423. dwPerms |= _chkGroupSeeFiles.QueryCheck() ? AFP_PERM_GROUP_SFI : 0;
  424. dwPerms |= _chkGroupSeeFolders.QueryCheck() ? AFP_PERM_GROUP_SFO : 0;
  425. dwPerms |= _chkGroupMakeChanges.QueryCheck() ? AFP_PERM_GROUP_MC : 0;
  426. dwPerms |= _chkWorldSeeFiles.QueryCheck() ? AFP_PERM_WORLD_SFI : 0;
  427. dwPerms |= _chkWorldSeeFolders.QueryCheck() ? AFP_PERM_WORLD_SFO : 0;
  428. dwPerms |= _chkWorldMakeChanges.QueryCheck() ? AFP_PERM_WORLD_MC : 0;
  429. dwPerms |= _chkReadOnly.QueryCheck() ? AFP_PERM_INHIBIT_MOVE_DELETE : 0;
  430. dwPerms |= _chkRecursePerms.QueryCheck() ? AFP_PERM_SET_SUBDIRS: 0;
  431. //
  432. // If the directory has to be a part of a volume then we set the
  433. // information at this point, otherwise we return the information
  434. // to the caller.
  435. //
  436. if ( _fDirInVolume )
  437. {
  438. AFP_DIRECTORY_INFO AfpDirInfo;
  439. AfpDirInfo.afpdir_path = (LPWSTR)_pszDirPath;
  440. AfpDirInfo.afpdir_owner = (LPWSTR)nlsOwner.QueryPch();
  441. AfpDirInfo.afpdir_group = (LPWSTR)nlsPrimaryGroup.QueryPch();
  442. AfpDirInfo.afpdir_perms = dwPerms;
  443. err = ::AfpAdminDirectorySetInfo( _hServer,
  444. (LPBYTE)&AfpDirInfo,
  445. AFP_DIR_PARMNUM_ALL );
  446. }
  447. else
  448. {
  449. _pnlsOwner->CopyFrom( nlsOwner );
  450. _pnlsGroup->CopyFrom( nlsPrimaryGroup );
  451. *_lpdwPerms = dwPerms;
  452. }
  453. } while ( FALSE );
  454. if ( err == NO_ERROR )
  455. {
  456. Dismiss( TRUE );
  457. }
  458. else
  459. {
  460. ::MsgPopup( this, AFPERR_TO_STRINGID( err ) );
  461. if ( err == AFPERR_NoSuchGroup )
  462. _slePrimaryGroup.ClaimFocus();
  463. else
  464. _sleOwner.ClaimFocus();
  465. }
  466. return TRUE;
  467. }
  468. /*******************************************************************
  469. NAME: DIRECTORY_PERMISSIONS_DLG::QueryHelpContext
  470. SYNOPSIS: Query the help context of the dialog
  471. ENTRY:
  472. EXIT:
  473. RETURNS: Return the help context of the dialog
  474. NOTES:
  475. HISTORY:
  476. NarenG 11/30/92 Created
  477. ********************************************************************/
  478. ULONG DIRECTORY_PERMISSIONS_DLG::QueryHelpContext( VOID )
  479. {
  480. return HC_DIRECTORY_PERMISSIONS_DLG;
  481. }