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.

1610 lines
47 KiB

  1. /*++
  2. Copyright (c) 1996 - 1998 Microsoft Corporation
  3. Module Name:
  4. dsacls.c
  5. Abstract:
  6. This Module implements the delegation tool, which allows for the management
  7. of access to DS objects
  8. Author:
  9. Mac McLain (MacM) 10-15-96
  10. Environment:
  11. User Mode
  12. Revision History:
  13. Hitesh Raigandhi (hiteshr 6-29-98)
  14. 1: Changed the code to Old NTMART API's
  15. 2: Redesigned the structure
  16. --*/
  17. #include "stdafx.h"
  18. #include "utils.h"
  19. #include "dsace.h"
  20. #include "dsacls.h"
  21. #define DSACL_DBG 1
  22. //
  23. // Local helper macros
  24. //
  25. #define FLAG_ON(flag,bits) ((flag) & (bits))
  26. #define IS_CMD_FLAG( string ) (*(string) == L'-' || *(string) == L'/' )
  27. DSACLS_ARG DsAclsArgs[] = {
  28. { MSG_TAG_CI, NULL, 0, 0, MSG_TAG_CI, 0, FALSE, DSACLS_EXTRA_INFO_REQUIRED },
  29. { MSG_TAG_CN, NULL, 0, 0, MSG_TAG_CN, 0, FALSE, DSACLS_EXTRA_INFO_NONE },
  30. { MSG_TAG_CP, NULL, 0, 0, MSG_TAG_CP, 0, FALSE, DSACLS_EXTRA_INFO_REQUIRED },
  31. { MSG_TAG_CG, NULL, 0, 0, MSG_TAG_CG, 0, TRUE, DSACLS_EXTRA_INFO_NONE },
  32. { MSG_TAG_CD, NULL, 0, 0, MSG_TAG_CD, 0, TRUE, DSACLS_EXTRA_INFO_NONE },
  33. { MSG_TAG_CR, NULL, 0, 0, MSG_TAG_CR, 0, TRUE, DSACLS_EXTRA_INFO_NONE },
  34. { MSG_TAG_CS, NULL, 0, 0, MSG_TAG_CS, 0, FALSE, DSACLS_EXTRA_INFO_NONE },
  35. { MSG_TAG_CT, NULL, 0, 0, MSG_TAG_CT, 0, FALSE, DSACLS_EXTRA_INFO_NONE },
  36. { MSG_TAG_CA, NULL, 0, 0, MSG_TAG_CA, 0, FALSE, DSACLS_EXTRA_INFO_NONE },
  37. { MSG_TAG_GETSDDL,NULL, 0, 0, MSG_TAG_GETSDDL, 0, FALSE, DSACLS_EXTRA_INFO_OPTIONAL },
  38. { MSG_TAG_SETSDDL,NULL, 0, 0, MSG_TAG_SETSDDL, 0, FALSE, DSACLS_EXTRA_INFO_REQUIRED }
  39. };
  40. DSACLS_INHERIT DsAclsInherit[] = {
  41. { MSG_TAG_IS, NULL, 0, TRUE, CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE},
  42. { MSG_TAG_IT, NULL, 0, TRUE, CONTAINER_INHERIT_ACE },
  43. { MSG_TAG_IP, NULL, 0, TRUE, INHERIT_NO_PROPAGATE },
  44. { MSG_TAG_ID, NULL, 0, FALSE, INHERITED_ACCESS_ENTRY }
  45. };
  46. DSACLS_RIGHTS DsAclsRights[] = {
  47. { MSG_TAG_GR, NULL,MSG_TAG_GR_EX,NULL, 0, GENERIC_READ },
  48. { MSG_TAG_GE, NULL,MSG_TAG_GE_EX,NULL, 0, GENERIC_EXECUTE },
  49. { MSG_TAG_GW, NULL,MSG_TAG_GW_EX,NULL, 0, GENERIC_WRITE },
  50. { MSG_TAG_GA, NULL,MSG_TAG_GA_EX,NULL, 0, GENERIC_ALL },
  51. { MSG_TAG_SD, NULL,MSG_TAG_SD_EX,NULL, 0, DELETE },
  52. { MSG_TAG_RC, NULL,MSG_TAG_RC_EX,NULL, 0, READ_CONTROL },
  53. { MSG_TAG_WD, NULL,MSG_TAG_WD_EX,NULL, 0, WRITE_DAC },
  54. { MSG_TAG_WO, NULL,MSG_TAG_WO_EX,NULL, 0, WRITE_OWNER },
  55. { MSG_TAG_CC, NULL,MSG_TAG_CC_EX,NULL, 0, ACTRL_DS_CREATE_CHILD },
  56. { MSG_TAG_DC, NULL,MSG_TAG_DC_EX,NULL, 0, ACTRL_DS_DELETE_CHILD },
  57. { MSG_TAG_LC, NULL,MSG_TAG_LC_EX,NULL, 0, ACTRL_DS_LIST },
  58. { MSG_TAG_WS, NULL,MSG_TAG_WS_EX,NULL, 0, ACTRL_DS_SELF },
  59. { MSG_TAG_WP, NULL,MSG_TAG_WP_EX,NULL, 0, ACTRL_DS_WRITE_PROP },
  60. { MSG_TAG_RP, NULL,MSG_TAG_RP_EX,NULL, 0, ACTRL_DS_READ_PROP },
  61. { MSG_TAG_DT, NULL,MSG_TAG_DT_EX,NULL, 0, ACTRL_DS_DELETE_TREE },
  62. { MSG_TAG_LO, NULL,MSG_TAG_LO_EX,NULL, 0, ACTRL_DS_LIST_OBJECT },
  63. { MSG_TAG_AC, NULL,MSG_TAG_AC_EX,NULL, 0, ACTRL_DS_CONTROL_ACCESS } //This is only for input
  64. };
  65. DSACLS_PROTECT DsAclsProtect[] = {
  66. { MSG_TAG_PY, NULL, 0, PROTECTED_DACL_SECURITY_INFORMATION },
  67. { MSG_TAG_PN, NULL, 0, UNPROTECTED_DACL_SECURITY_INFORMATION }
  68. };
  69. /*
  70. Displays The security Descriptor
  71. */
  72. DWORD
  73. DumpAccess (
  74. IN PSECURITY_DESCRIPTOR pSD,
  75. IN BOOL bDisplayAuditAndOwner
  76. )
  77. {
  78. DWORD dwErr = ERROR_SUCCESS;
  79. SECURITY_DESCRIPTOR_CONTROL wSDControl = 0;
  80. DWORD dwRevision;
  81. PSID psidOwner = NULL;
  82. PSID psidGroup = NULL;
  83. PACL pDacl = NULL;
  84. PACL pSacl = NULL;
  85. BOOL bDefaulted;
  86. BOOL bPresent;
  87. LPWSTR pOwnerName = NULL;
  88. LPWSTR pGroupName = NULL;
  89. CAcl * pCSacl = NULL;
  90. CAcl * pCDacl = NULL;
  91. UINT nLen1 = 0;
  92. UINT nLen2 = 0;
  93. UINT nAllowDeny = 0;
  94. UINT nAudit = 0;
  95. WCHAR szLoadBuffer[1024];
  96. if( !GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision) )
  97. {
  98. dwErr = GetLastError();
  99. goto CLEAN_RETURN;
  100. }
  101. if( !GetSecurityDescriptorOwner(pSD, &psidOwner, &bDefaulted) )
  102. {
  103. dwErr = GetLastError();
  104. goto CLEAN_RETURN;
  105. }
  106. if( !GetSecurityDescriptorGroup(pSD, &psidGroup, &bDefaulted) )
  107. {
  108. dwErr = GetLastError();
  109. goto CLEAN_RETURN;
  110. }
  111. if( !GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefaulted) )
  112. {
  113. dwErr = GetLastError();
  114. goto CLEAN_RETURN;
  115. }
  116. if( !GetSecurityDescriptorSacl(pSD, &bPresent, &pSacl, &bDefaulted) )
  117. {
  118. dwErr = GetLastError();
  119. goto CLEAN_RETURN;
  120. }
  121. //Find out the Max len out of ( ALLOW, DENY ) and ( FAILURE, SUCCESS, BOTH)
  122. nLen1 = LoadStringW( g_hInstance, MSG_DSACLS_ALLOW, szLoadBuffer, 1023 );
  123. nLen2 = LoadStringW( g_hInstance, MSG_DSACLS_DENY, szLoadBuffer, 1023 );
  124. nAllowDeny = ( nLen1 > nLen2 ) ? nLen1 : nLen2;
  125. nLen1 = LoadStringW( g_hInstance, MSG_DSACLS_AUDIT_SUCCESS, szLoadBuffer, 1023 );
  126. nLen2 = LoadStringW( g_hInstance, MSG_DSACLS_AUDIT_FAILURE, szLoadBuffer, 1023 );
  127. nAudit = ( nLen1 > nLen2 ) ? nLen1 : nLen2;
  128. nLen1 = LoadStringW( g_hInstance, MSG_DSACLS_AUDIT_ALL, szLoadBuffer, 1023 );
  129. nAudit = ( nLen1 > nAudit ) ? nLen1 : nAudit;
  130. if( bDisplayAuditAndOwner )
  131. {
  132. pCSacl = new CAcl();
  133. CHECK_NULL( pCSacl, CLEAN_RETURN );
  134. dwErr = pCSacl->Initialize(wSDControl & SE_SACL_PROTECTED,
  135. pSacl,
  136. nAllowDeny,
  137. nAudit );
  138. if( dwErr != ERROR_SUCCESS )
  139. return dwErr;
  140. }
  141. pCDacl = new CAcl();
  142. CHECK_NULL( pCDacl,CLEAN_RETURN );
  143. dwErr = pCDacl->Initialize(wSDControl & SE_DACL_PROTECTED,
  144. pDacl,
  145. nAllowDeny,
  146. nAudit);
  147. if( dwErr != ERROR_SUCCESS )
  148. return dwErr;
  149. if( ( dwErr = g_Cache->BuildCache() ) != ERROR_SUCCESS )
  150. return dwErr;
  151. pCDacl->GetInfoFromCache();
  152. if( bDisplayAuditAndOwner )
  153. {
  154. if( ( dwErr = GetAccountNameFromSid( g_szServerName, psidOwner, &pOwnerName ) ) != ERROR_SUCCESS )
  155. goto CLEAN_RETURN;
  156. DisplayMessageEx( 0, MSG_DSACLS_OWNER, pOwnerName );
  157. if( ( dwErr = GetAccountNameFromSid( g_szServerName, psidGroup, &pGroupName ) ) != ERROR_SUCCESS )
  158. goto CLEAN_RETURN;
  159. DisplayMessageEx( 0, MSG_DSACLS_GROUP, pGroupName );
  160. DisplayNewLine();
  161. DisplayMessageEx( 0, MSG_DSACLS_AUDIT );
  162. pCSacl->Display();
  163. DisplayNewLine();
  164. }
  165. DisplayMessageEx( 0, MSG_DSACLS_ACCESS );
  166. pCDacl->Display();
  167. CLEAN_RETURN:
  168. if( pOwnerName )
  169. LocalFree( pOwnerName );
  170. if( pGroupName )
  171. LocalFree( pGroupName );
  172. if( pCSacl )
  173. delete pCSacl;
  174. if( pCDacl )
  175. delete pCDacl;
  176. return dwErr;
  177. }
  178. /*
  179. This Function process the command line argument for /D /R /G
  180. options and add the corresponding aces to pAcl.
  181. */
  182. DWORD
  183. ProcessCmdlineUsers ( IN WCHAR *argv[],
  184. IN PDSACLS_ARG AclsArg,
  185. IN DSACLS_OP Op,
  186. IN ULONG Inheritance,
  187. IN ULONG RightsListCount,
  188. IN PDSACLS_RIGHTS RightsList,
  189. OUT CAcl *pAcl )
  190. {
  191. DWORD dwErr = ERROR_SUCCESS;
  192. ULONG i, j;
  193. ULONG AccIndex, Access;
  194. PEXPLICIT_ACCESS pListOfExplicitEntries = NULL;
  195. PWSTR pObjectId = NULL;
  196. PWSTR pTrustee = NULL;
  197. PWSTR pInheritId = NULL;
  198. ACCESS_MODE AccessMode;
  199. CAce * pAce = NULL;
  200. switch ( Op ) {
  201. case REVOKE:
  202. AccessMode = REVOKE_ACCESS;
  203. break;
  204. case GRANT:
  205. AccessMode = GRANT_ACCESS;
  206. break;
  207. case DENY:
  208. AccessMode = DENY_ACCESS;
  209. break;
  210. default:
  211. dwErr = ERROR_INVALID_PARAMETER;
  212. break;
  213. }
  214. if ( dwErr != ERROR_SUCCESS )
  215. goto FAILURE_RETURN;
  216. for ( i = 0; i < AclsArg->SkipCount && dwErr == ERROR_SUCCESS; i++ )
  217. {
  218. dwErr = ParseUserAndPermissons( argv[AclsArg->StartIndex + 1 + i],
  219. Op,
  220. RightsListCount,
  221. RightsList,
  222. &pTrustee,
  223. &Access,
  224. &pObjectId,
  225. &pInheritId );
  226. if( dwErr != ERROR_SUCCESS )
  227. goto FAILURE_RETURN;
  228. pAce = new CAce();
  229. CHECK_NULL( pAce , FAILURE_RETURN);
  230. dwErr= pAce->Initialize( pTrustee,
  231. pObjectId,
  232. pInheritId,
  233. AccessMode,
  234. Access,
  235. Inheritance );
  236. if( dwErr != ERROR_SUCCESS )
  237. return dwErr;
  238. pAcl->AddAce( pAce );
  239. if( pObjectId )
  240. {
  241. LocalFree( pObjectId );
  242. pObjectId = NULL;
  243. }
  244. if( pInheritId )
  245. {
  246. LocalFree( pInheritId );
  247. pInheritId = NULL;
  248. }
  249. if( pTrustee )
  250. {
  251. LocalFree( pTrustee );
  252. pTrustee = NULL;
  253. }
  254. }
  255. FAILURE_RETURN:
  256. if( pObjectId )
  257. {
  258. LocalFree( pObjectId );
  259. pObjectId = NULL;
  260. }
  261. if( pInheritId )
  262. {
  263. LocalFree( pInheritId );
  264. pInheritId = NULL;
  265. }
  266. if( pTrustee )
  267. {
  268. LocalFree( pTrustee );
  269. pTrustee = NULL;
  270. }
  271. return( dwErr );
  272. }
  273. //These five are global variables used by the dsacls
  274. LPWSTR g_szSchemaNamingContext;
  275. LPWSTR g_szConfigurationNamingContext;
  276. HMODULE g_hInstance;
  277. LPWSTR g_szServerName;
  278. CCache *g_Cache;
  279. __cdecl
  280. main (
  281. IN INT argc,
  282. IN CHAR *argv[]
  283. )
  284. {
  285. DWORD dwErr = ERROR_SUCCESS;
  286. ULONG Length, Options = 0;
  287. PWSTR pszObjectPath = NULL;
  288. PWSTR pszLDAPObjectPath = NULL;
  289. PSTR SddlString = NULL, TempString;
  290. LPWSTR FileName = NULL;
  291. CHAR ReadString[ 512 ];
  292. BOOLEAN Mapped;
  293. LPWSTR CurrentInherit = NULL;
  294. LPWSTR CurrentProtect = NULL;
  295. ULONG Inheritance = 0;
  296. SECURITY_INFORMATION Protection = 0;
  297. ULONG SddlStringLength = 0;
  298. WCHAR ** wargv = NULL;
  299. ULONG i = 0;
  300. ULONG j = 0;
  301. PSECURITY_DESCRIPTOR pSD = NULL;
  302. PACL pDacl = NULL;
  303. SECURITY_INFORMATION SecurityInformation = DACL_SECURITY_INFORMATION;
  304. PSECURITY_DESCRIPTOR pTempSD = NULL;
  305. PACL pNewDacl = NULL;
  306. CAcl * pCAclOld = NULL;
  307. CAcl *pCAclNew = NULL;
  308. BOOL bErrorShown = FALSE;
  309. //Initialize Com Library
  310. HRESULT hr = CoInitialize(NULL);
  311. CHECK_HR(hr, CLEAN_RETURN);
  312. //Get Instance Handle
  313. g_hInstance = GetModuleHandle(NULL);
  314. //Create global instance of Cache
  315. g_Cache = new CCache();
  316. CHECK_NULL(g_Cache,CLEAN_RETURN);
  317. setlocale( LC_CTYPE, "" );
  318. //Initialize Global Arrays
  319. if( ( dwErr = InitializeGlobalArrays() ) != ERROR_SUCCESS )
  320. goto CLEAN_RETURN;
  321. if ( argc == 1 )
  322. {
  323. DisplayMessage( 0, MSG_DSACLS_USAGE );
  324. goto CLEAN_RETURN;
  325. }
  326. //Convert argv to Unicode
  327. wargv = (LPWSTR*)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, argc * sizeof(LPWSTR) );
  328. CHECK_NULL(wargv, CLEAN_RETURN );
  329. if( ( dwErr = ConvertArgvToUnicode( wargv, argv, argc ) ) != ERROR_SUCCESS )
  330. goto CLEAN_RETURN;
  331. //First Argument is Object Path or /?
  332. if( IS_CMD_FLAG( wargv[ 1 ] ) )
  333. {
  334. if ( _wcsicmp( wargv[ 1 ] + 1, L"?" ) != 0 )
  335. DisplayMessageEx( 0, MSG_DSACLS_PARAM_UNEXPECTED, wargv[1] );
  336. DisplayMessage(0,MSG_DSACLS_USAGE);
  337. goto CLEAN_RETURN;
  338. }
  339. Length = wcslen( wargv[1] );
  340. pszObjectPath = (LPWSTR)LocalAlloc( LMEM_FIXED,
  341. ( Length + 1 ) * sizeof( WCHAR ) );
  342. if ( !pszObjectPath )
  343. {
  344. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  345. goto CLEAN_RETURN;
  346. } else
  347. {
  348. wcscpy( pszObjectPath,
  349. wargv[ 1 ] );
  350. }
  351. //Get the name of server
  352. dwErr = GetServerName( pszObjectPath, &g_szServerName );
  353. if( dwErr != ERROR_SUCCESS )
  354. goto CLEAN_RETURN;
  355. if( ( dwErr = BuildLdapPath( &pszLDAPObjectPath,
  356. g_szServerName,
  357. pszObjectPath ) ) != ERROR_SUCCESS )
  358. goto CLEAN_RETURN;
  359. //Get Schema and Configuration naming context
  360. dwErr = GetGlobalNamingContexts( g_szServerName,
  361. &g_szSchemaNamingContext,
  362. &g_szConfigurationNamingContext );
  363. if( dwErr != ERROR_SUCCESS )
  364. goto CLEAN_RETURN;
  365. //
  366. // Parse the command line
  367. //
  368. i = 2;
  369. while ( i < ( ULONG )argc && dwErr == ERROR_SUCCESS )
  370. {
  371. if ( IS_CMD_FLAG( wargv[ i ] ) )
  372. {
  373. if ( !_wcsicmp( wargv[ i ] + 1, L"?" ) ) {
  374. DisplayMessage( 0, MSG_DSACLS_USAGE );
  375. goto CLEAN_RETURN;
  376. }
  377. Mapped = FALSE;
  378. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ )
  379. {
  380. if ( !wcsncmp( wargv[ i ] + 1, DsAclsArgs[ j ].String,DsAclsArgs[ j ].Length ) )
  381. {
  382. if( DsAclsArgs[ j ].ExtraInfo )
  383. {
  384. if( ( DsAclsArgs[ j ].ExtraInfo == DSACLS_EXTRA_INFO_REQUIRED &&
  385. wargv[ i ][ DsAclsArgs[ j ].Length + 1 ] == ':' &&
  386. wargv[ i ][ DsAclsArgs[ j ].Length + 2 ] != '\0' ) ||
  387. (DsAclsArgs[ j ].ExtraInfo == DSACLS_EXTRA_INFO_OPTIONAL &&
  388. ( ( wargv[ i ][ DsAclsArgs[ j ].Length + 1 ] == ':' &&
  389. wargv[ i ][ DsAclsArgs[ j ].Length + 2 ] != '\0' ) ||
  390. wargv[ i ][ DsAclsArgs[ j ].Length + 1 ] == '\0' ) ) )
  391. {
  392. Mapped = TRUE;
  393. }
  394. } else
  395. {
  396. Mapped = TRUE;
  397. }
  398. break;
  399. }
  400. }//For
  401. if ( Mapped )
  402. {
  403. DsAclsArgs[ j ].StartIndex = i;
  404. Options |= DsAclsArgs[ j ].Flag;
  405. if ( DsAclsArgs[ j ].SkipNonFlag )
  406. {
  407. while ( i + 1 < ( ULONG )argc && !IS_CMD_FLAG( wargv[ i + 1 ] ) )
  408. {
  409. i++;
  410. DsAclsArgs[ j ].SkipCount++;
  411. }
  412. if ( DsAclsArgs[ j ].SkipCount == 0 )
  413. {
  414. DisplayMessageEx( 0, MSG_DSACLS_NO_UA,
  415. wargv[i] );
  416. dwErr = ERROR_INVALID_PARAMETER;
  417. goto CLEAN_RETURN;
  418. }
  419. }
  420. }
  421. else
  422. {
  423. DisplayMessageEx( 0, MSG_DSACLS_PARAM_UNEXPECTED, wargv[i] );
  424. dwErr = ERROR_INVALID_PARAMETER;
  425. goto CLEAN_RETURN;
  426. }
  427. } else
  428. {
  429. DisplayMessageEx( 0, MSG_DSACLS_PARAM_UNEXPECTED, wargv[i] );
  430. dwErr = ERROR_INVALID_PARAMETER;
  431. goto CLEAN_RETURN;
  432. }
  433. i++;
  434. }//While
  435. //Validate the command line argument
  436. /*
  437. if ( !FLAG_ON( Options, MSG_TAG_CR | MSG_TAG_CD | MSG_TAG_CG | MSG_TAG_CT | MSG_TAG_CS ) )
  438. {
  439. if ( FLAG_ON( Options, MSG_TAG_GETSDDL ) )
  440. {
  441. if ( dwErr == ERROR_SUCCESS )
  442. {
  443. if ( !ConvertSecurityDescriptorToStringSecurityDescriptorA( pSD,
  444. SDDL_REVISION,
  445. SecurityInformation,
  446. &SddlString,
  447. NULL ) )
  448. {
  449. dwErr = GetLastError();
  450. } else
  451. {
  452. //
  453. // Get the file name to write it to if necessary
  454. //
  455. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ )
  456. {
  457. if ( DsAclsArgs[ j ].Flag == MSG_TAG_GETSDDL )
  458. {
  459. FileName = wcschr( wargv[ DsAclsArgs[ j ].StartIndex ] , L':' );
  460. if ( FileName )
  461. {
  462. FileName++;
  463. }
  464. break;
  465. }
  466. }
  467. if ( FileName )
  468. {
  469. HANDLE FileHandle = CreateFile( FileName,
  470. GENERIC_WRITE,
  471. 0,
  472. NULL,
  473. CREATE_ALWAYS,
  474. FILE_ATTRIBUTE_NORMAL,
  475. NULL );
  476. if ( FileHandle == INVALID_HANDLE_VALUE )
  477. {
  478. dwErr = GetLastError();
  479. } else
  480. {
  481. ULONG BytesWritten;
  482. if ( WriteFile( FileHandle,
  483. ( PVOID )SddlString,
  484. strlen( SddlString ),
  485. &BytesWritten,
  486. NULL ) == FALSE )
  487. {
  488. dwErr = GetLastError();
  489. } else
  490. {
  491. ASSERT( strlen( SddlString ) == BytesWritten );
  492. }
  493. CloseHandle( FileHandle );
  494. }
  495. } else
  496. {
  497. printf( "%s\n", SddlString );
  498. }
  499. LocalFree( SddlString );
  500. }
  501. //LocalFree( SD );
  502. }
  503. } else {
  504. DumpAccess( pSD,
  505. FLAG_ON( Options, MSG_TAG_CA ),
  506. sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ),
  507. DsAclsInherit,
  508. sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ),
  509. DsAclsRights );
  510. }
  511. }
  512. */
  513. /*
  514. //
  515. // If we are parsing an SDDL file, go ahead and do that now...
  516. //
  517. if ( FLAG_ON( Options, MSG_TAG_SETSDDL ) )
  518. {
  519. //
  520. // First, open the file
  521. //
  522. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  523. //
  524. // Get the file name to write it to if necessary
  525. //
  526. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
  527. if ( DsAclsArgs[ j ].Flag == MSG_TAG_SETSDDL ) {
  528. FileName = wcschr( wargv[ DsAclsArgs[ j ].StartIndex ] , L':' );
  529. if ( FileName ) {
  530. FileName++;
  531. }
  532. break;
  533. }
  534. }
  535. if ( !FileName ) {
  536. dwErr = ERROR_INVALID_PARAMETER;
  537. goto CLEAN_RETURN;
  538. }
  539. FileHandle = CreateFile( FileName,
  540. GENERIC_READ,
  541. FILE_SHARE_READ,
  542. NULL,
  543. OPEN_EXISTING,
  544. FILE_ATTRIBUTE_NORMAL,
  545. NULL );
  546. if ( FileHandle == INVALID_HANDLE_VALUE ) {
  547. dwErr = GetLastError();
  548. goto CLEAN_RETURN;
  549. }
  550. //
  551. // Now, parse it...
  552. //
  553. SddlStringLength = 0;
  554. SddlString = NULL;
  555. while ( TRUE ) {
  556. ULONG Read = 0, Len = 0;
  557. PSTR ReadPtr, TempPtr;
  558. if ( ReadFile( FileHandle,
  559. ReadString,
  560. sizeof( ReadString ) / sizeof( CHAR ),
  561. &Read,
  562. NULL ) == FALSE ) {
  563. dwErr = GetLastError();
  564. break;
  565. }
  566. if ( Read == 0 ) {
  567. break;
  568. }
  569. if ( *ReadString == ';' ) {
  570. continue;
  571. }
  572. Len = SddlStringLength + ( Read / sizeof( CHAR ) );
  573. TempString = (LPSTR)LocalAlloc( LMEM_FIXED,
  574. Len + sizeof( CHAR ) );
  575. if ( TempString ) {
  576. if ( SddlString ) {
  577. strcpy( TempString, SddlString );
  578. } else {
  579. *TempString = '\0';
  580. }
  581. TempPtr = TempString + SddlStringLength;
  582. ReadPtr = ReadString;
  583. while( Read-- > 0 ) {
  584. if ( !isspace( *ReadPtr ) ) {
  585. *TempPtr++ = *ReadPtr;
  586. SddlStringLength++;
  587. }
  588. ReadPtr++;
  589. }
  590. *TempPtr = '\0';
  591. LocalFree( SddlString );
  592. SddlString = TempString;
  593. } else {
  594. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  595. break;
  596. }
  597. }
  598. if ( dwErr == ERROR_SUCCESS ) {
  599. //
  600. // Convert it to a security descriptor, then to an access list, then set it.
  601. //
  602. if ( ConvertStringSecurityDescriptorToSecurityDescriptorA( SddlString,
  603. SDDL_REVISION,
  604. &pTempSD,
  605. NULL ) == FALSE ) {
  606. dwErr = GetLastError();
  607. } else {
  608. dwErr = WriteObjectSecurity( pszObjectPath,
  609. DACL_SECURITY_INFORMATION,
  610. pTempSD );
  611. LocalFree( pTempSD );
  612. }
  613. }
  614. LocalFree( SddlString );
  615. if ( FileHandle != INVALID_HANDLE_VALUE ) {
  616. CloseHandle( FileHandle );
  617. }
  618. goto CLEAN_RETURN;
  619. }
  620. */
  621. //
  622. // Get the inheritance flags set
  623. //
  624. if ( FLAG_ON( Options, MSG_TAG_CI ) )
  625. {
  626. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ )
  627. {
  628. if ( DsAclsArgs[ j ].Flag == MSG_TAG_CI )
  629. {
  630. CurrentInherit = wargv[ DsAclsArgs[ j ].StartIndex ] + 3;
  631. while ( CurrentInherit && *CurrentInherit && dwErr == ERROR_SUCCESS )
  632. {
  633. for ( i = 0; i < ( sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ) ); i++ )
  634. {
  635. if ( !_wcsnicmp( CurrentInherit,
  636. DsAclsInherit[ i ].String,
  637. DsAclsInherit[ i ].Length ) )
  638. {
  639. if ( !DsAclsInherit[ i ].ValidForInput )
  640. {
  641. dwErr = ERROR_INVALID_PARAMETER;
  642. break;
  643. }
  644. Inheritance |= DsAclsInherit[ i ].InheritFlag;
  645. CurrentInherit += DsAclsInherit[ i ].Length;
  646. break;
  647. }
  648. }
  649. if ( i == ( sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ) ) )
  650. {
  651. dwErr = ERROR_INVALID_PARAMETER;
  652. goto CLEAN_RETURN;
  653. }
  654. }
  655. break;
  656. }
  657. }
  658. }
  659. //Get the protection flag
  660. if ( FLAG_ON( Options, MSG_TAG_CP ) )
  661. {
  662. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ )
  663. {
  664. if ( DsAclsArgs[ j ].Flag == MSG_TAG_CP )
  665. {
  666. CurrentProtect = wargv[ DsAclsArgs[ j ].StartIndex ] + DsAclsArgs[ j ].Length + 2;
  667. while ( CurrentProtect && *CurrentProtect )
  668. {
  669. for ( i = 0; i < ( sizeof( DsAclsProtect ) / sizeof( DSACLS_PROTECT ) ); i++ )
  670. {
  671. if ( !_wcsnicmp( CurrentProtect,
  672. DsAclsProtect[ i ].String,
  673. DsAclsProtect[ i ].Length ) )
  674. {
  675. Protection |= DsAclsProtect[ i ].Right;
  676. CurrentProtect += DsAclsProtect[ i ].Length;
  677. break;
  678. }
  679. }
  680. if ( i == ( sizeof( DsAclsProtect ) / sizeof( DSACLS_PROTECT ) ) )
  681. {
  682. dwErr = ERROR_INVALID_PARAMETER;
  683. goto CLEAN_RETURN;
  684. }
  685. }
  686. break;
  687. }
  688. }
  689. }
  690. //
  691. // Start processing them in order
  692. //
  693. if ( FLAG_ON( Options, MSG_TAG_CR | MSG_TAG_CD | MSG_TAG_CG | MSG_TAG_CP ) )
  694. {
  695. //
  696. // Get the current information, if required
  697. //
  698. if( !FLAG_ON( Options, MSG_TAG_CN ) )
  699. {
  700. SecurityInformation = DACL_SECURITY_INFORMATION;
  701. dwErr = GetNamedSecurityInfo( pszLDAPObjectPath,
  702. SE_DS_OBJECT_ALL,
  703. SecurityInformation,
  704. NULL,
  705. NULL,
  706. &pDacl,
  707. NULL,
  708. &pSD );
  709. if ( dwErr != ERROR_SUCCESS ) {
  710. goto CLEAN_RETURN;
  711. }
  712. //pCAclOld represents existing ACL
  713. pCAclOld = new CAcl();
  714. CHECK_NULL( pCAclOld, CLEAN_RETURN );
  715. dwErr = pCAclOld->Initialize( FALSE, pDacl,0 ,0 );
  716. if( dwErr != ERROR_SUCCESS )
  717. goto CLEAN_RETURN;
  718. if( !FLAG_ON( Options, MSG_TAG_CP ) )
  719. {
  720. dwErr = GetProtection( pSD, &Protection );
  721. if( dwErr != ERROR_SUCCESS )
  722. goto CLEAN_RETURN;
  723. }
  724. }
  725. pCAclNew = new CAcl();
  726. CHECK_NULL( pCAclNew, CLEAN_RETURN );
  727. //
  728. // Grant
  729. //
  730. if ( dwErr == ERROR_SUCCESS && FLAG_ON( Options, MSG_TAG_CG ) ) {
  731. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
  732. if ( DsAclsArgs[ j ].Flag == MSG_TAG_CG ) {
  733. dwErr = ProcessCmdlineUsers( wargv,
  734. &DsAclsArgs[ j ],
  735. GRANT,
  736. Inheritance,
  737. sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ),
  738. DsAclsRights,
  739. pCAclNew );
  740. if ( dwErr != ERROR_SUCCESS ) {
  741. goto CLEAN_RETURN;
  742. }
  743. break;
  744. }
  745. }
  746. }
  747. if ( dwErr == ERROR_SUCCESS && FLAG_ON( Options, MSG_TAG_CD ) ) {
  748. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
  749. if ( DsAclsArgs[ j ].Flag == MSG_TAG_CD ) {
  750. dwErr = ProcessCmdlineUsers( wargv,
  751. &DsAclsArgs[ j ],
  752. DENY,
  753. Inheritance,
  754. sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ),
  755. DsAclsRights,
  756. pCAclNew );
  757. if ( dwErr != ERROR_SUCCESS ) {
  758. goto CLEAN_RETURN;
  759. }
  760. break;
  761. }
  762. }
  763. }
  764. if ( dwErr == ERROR_SUCCESS && FLAG_ON( Options, MSG_TAG_CR ) ) {
  765. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
  766. if ( DsAclsArgs[ j ].Flag == MSG_TAG_CR ) {
  767. dwErr = ProcessCmdlineUsers( wargv,
  768. &DsAclsArgs[ j ],
  769. REVOKE,
  770. Inheritance,
  771. sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ),
  772. DsAclsRights,
  773. pCAclNew );
  774. if ( dwErr != ERROR_SUCCESS ) {
  775. goto CLEAN_RETURN;
  776. }
  777. break;
  778. }
  779. }
  780. }
  781. //Build Cache
  782. g_Cache->BuildCache();
  783. //Verify that we have been able to convert all ObjectType and InheritedObjectType
  784. // names to GUIDs
  785. pCAclNew->GetInfoFromCache();
  786. if( !pCAclNew->VerifyAllNames() )
  787. {
  788. dwErr = ERROR_INVALID_PARAMETER;
  789. goto CLEAN_RETURN;
  790. }
  791. if( pCAclOld )
  792. pCAclOld->GetInfoFromCache();
  793. if( pCAclOld )
  794. {
  795. pCAclOld->MergeAcl( pCAclNew );
  796. if(( dwErr = pCAclOld->BuildAcl( &pNewDacl ) ) != ERROR_SUCCESS )
  797. goto CLEAN_RETURN;
  798. }
  799. else
  800. {
  801. if( ( dwErr = pCAclNew->BuildAcl( &pNewDacl ) ) != ERROR_SUCCESS )
  802. goto CLEAN_RETURN;
  803. }
  804. SecurityInformation = DACL_SECURITY_INFORMATION | Protection;
  805. dwErr = SetNamedSecurityInfo ( pszLDAPObjectPath,
  806. SE_DS_OBJECT_ALL,
  807. SecurityInformation,
  808. NULL,
  809. NULL,
  810. pNewDacl,
  811. NULL );
  812. if( dwErr != ERROR_SUCCESS )
  813. goto CLEAN_RETURN;
  814. }
  815. //
  816. // Now, see if we have to restore any security to the defaults
  817. //
  818. if ( FLAG_ON( Options, MSG_TAG_CS ) ) {
  819. dwErr = SetDefaultSecurityOnObjectTree( pszObjectPath,
  820. ( BOOLEAN )( FLAG_ON( Options, MSG_TAG_CT ) ?
  821. TRUE : FALSE ),Protection );
  822. if( dwErr != ERROR_SUCCESS )
  823. goto CLEAN_RETURN;
  824. }
  825. //Display the security
  826. if( pSD )
  827. {
  828. LocalFree( pSD );
  829. pSD = NULL;
  830. }
  831. SecurityInformation = DACL_SECURITY_INFORMATION;
  832. if ( FLAG_ON( Options, MSG_TAG_CA ) )
  833. {
  834. SecurityInformation |= SACL_SECURITY_INFORMATION |
  835. GROUP_SECURITY_INFORMATION |
  836. OWNER_SECURITY_INFORMATION;
  837. }
  838. dwErr = GetNamedSecurityInfo( pszLDAPObjectPath,
  839. SE_DS_OBJECT_ALL,
  840. SecurityInformation,
  841. NULL,
  842. NULL,
  843. NULL,
  844. NULL,
  845. &pSD );
  846. if( dwErr != ERROR_SUCCESS )
  847. {
  848. if( dwErr == ERROR_FILE_NOT_FOUND )
  849. {
  850. DisplayMessageEx( 0, MSG_INVALID_OBJECT_PATH );
  851. bErrorShown = TRUE;
  852. }
  853. goto CLEAN_RETURN;
  854. }
  855. dwErr = DumpAccess( pSD,
  856. FLAG_ON( Options, MSG_TAG_CA )
  857. );
  858. CLEAN_RETURN:
  859. if ( dwErr == ERROR_SUCCESS )
  860. {
  861. DisplayMessageEx( 0, MSG_DSACLS_SUCCESS );
  862. } else {
  863. if(!bErrorShown)
  864. DisplayErrorMessage( dwErr );
  865. DisplayMessageEx( 0, MSG_DSACLS_FAILURE );
  866. }
  867. //Free Unicode Command Line Arguments
  868. if( wargv )
  869. {
  870. //delete wargv and stuff
  871. for( j = 0; j < argc; ++ j )
  872. {
  873. if( wargv[j] )
  874. LocalFree(wargv[j] );
  875. }
  876. LocalFree( wargv );
  877. }
  878. if( pszObjectPath )
  879. LocalFree( pszObjectPath );
  880. if( pSD )
  881. LocalFree( pSD );
  882. if( pNewDacl )
  883. LocalFree( pNewDacl );
  884. //Free the Global Stuff
  885. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG ) ); j++ ) {
  886. if( DsAclsArgs[ j ].String )
  887. LocalFree( DsAclsArgs[ j ].String );
  888. }
  889. for ( j = 0; j < ( sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ) ); j++ ) {
  890. if( DsAclsInherit[ j ].String )
  891. LocalFree( DsAclsInherit[ j ].String );
  892. }
  893. for ( j = 0; j < ( sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ) ); j++ ) {
  894. if( DsAclsRights[ j ].String )
  895. LocalFree( DsAclsRights[ j ].String );
  896. if( DsAclsRights[ j ].StringEx )
  897. LocalFree( DsAclsRights[ j ].StringEx );
  898. }
  899. if( pCAclOld )
  900. delete pCAclOld ;
  901. if( pCAclNew )
  902. delete pCAclNew;
  903. if( g_szSchemaNamingContext )
  904. LocalFree( g_szSchemaNamingContext );
  905. if( g_szConfigurationNamingContext )
  906. LocalFree( g_szConfigurationNamingContext );
  907. if( g_szServerName )
  908. LocalFree( g_szServerName );
  909. if( g_Cache )
  910. delete g_Cache;
  911. return( dwErr );
  912. }
  913. DWORD
  914. InitializeGlobalArrays()
  915. {
  916. HMODULE hCurrentModule;
  917. WCHAR LoadBuffer[ 1024 ];
  918. int j = 0;
  919. hCurrentModule = GetModuleHandle( NULL );
  920. for ( j = 0; j < ( sizeof( DsAclsArgs ) / sizeof( DSACLS_ARG )); j++ )
  921. {
  922. long Length = LoadString( hCurrentModule,
  923. DsAclsArgs[ j ].ResourceId,
  924. LoadBuffer,
  925. sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
  926. if ( Length == 0 )
  927. {
  928. return GetLastError();
  929. } else {
  930. DsAclsArgs[ j ].String = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
  931. ( Length + 1 )*sizeof(WCHAR) );
  932. if ( !DsAclsArgs[ j ].String )
  933. {
  934. return ERROR_NOT_ENOUGH_MEMORY;
  935. }
  936. DsAclsArgs[ j ].Length = Length;
  937. wcsncpy( DsAclsArgs[ j ].String, LoadBuffer, Length + 1 );
  938. }
  939. }
  940. //
  941. // Load the inherit strings
  942. //
  943. for ( j = 0; j < ( sizeof( DsAclsInherit ) / sizeof( DSACLS_INHERIT ) ); j++ )
  944. {
  945. long Length = LoadString( hCurrentModule,
  946. DsAclsInherit[ j ].ResourceId,
  947. LoadBuffer,
  948. sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
  949. if ( Length == 0 ) {
  950. return GetLastError();
  951. } else
  952. {
  953. DsAclsInherit[ j ].String = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
  954. ( Length + 1 ) * sizeof( WCHAR ) );
  955. if ( !DsAclsInherit[ j ].String )
  956. return ERROR_NOT_ENOUGH_MEMORY;
  957. wcsncpy( DsAclsInherit[ j ].String, LoadBuffer, Length + 1 );
  958. DsAclsInherit[ j ].Length = Length;
  959. }
  960. }
  961. //
  962. //Load The protect flags
  963. //
  964. for( j = 0; j < ( sizeof( DsAclsProtect ) / sizeof( DSACLS_PROTECT ) ); j++ )
  965. {
  966. long Length = LoadString( hCurrentModule,
  967. DsAclsProtect[ j ].ResourceId,
  968. LoadBuffer,
  969. sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
  970. if ( Length == 0 ) {
  971. return GetLastError();
  972. } else
  973. {
  974. DsAclsProtect[ j ].String = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
  975. ( Length + 1 ) * sizeof( WCHAR ) );
  976. if ( !DsAclsProtect[ j ].String )
  977. return ERROR_NOT_ENOUGH_MEMORY;
  978. wcsncpy( DsAclsProtect[ j ].String, LoadBuffer, Length + 1 );
  979. DsAclsProtect[ j ].Length = Length;
  980. }
  981. }
  982. //
  983. // Load the access rights
  984. //
  985. for ( j = 0; j < ( sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ) ); j++ )
  986. {
  987. long Length = LoadString( hCurrentModule,
  988. DsAclsRights[ j ].ResourceId,
  989. LoadBuffer,
  990. sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
  991. if ( Length == 0 ) {
  992. return GetLastError();
  993. } else
  994. {
  995. DsAclsRights[ j ].String = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
  996. ( Length + 1 ) * sizeof( WCHAR ) );
  997. if ( !DsAclsRights[ j ].String ) {
  998. return ERROR_NOT_ENOUGH_MEMORY;
  999. }
  1000. wcsncpy( DsAclsRights[ j ].String, LoadBuffer, Length + 1 );
  1001. DsAclsRights[ j ].Length = Length;
  1002. }
  1003. //Load Ex . Ex String are used for displaying the access rights
  1004. if( DsAclsRights[ j ].ResourceIdEx != -1 )
  1005. {
  1006. Length = LoadString( hCurrentModule,
  1007. DsAclsRights[ j ].ResourceIdEx,
  1008. LoadBuffer,
  1009. sizeof( LoadBuffer ) / sizeof ( WCHAR ) - 1 );
  1010. if ( Length == 0 ) {
  1011. return GetLastError();
  1012. } else
  1013. {
  1014. DsAclsRights[ j ].StringEx = (LPWSTR)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
  1015. ( Length + 1 ) * sizeof( WCHAR ) );
  1016. if ( !DsAclsRights[ j ].StringEx ) {
  1017. return ERROR_NOT_ENOUGH_MEMORY;
  1018. }
  1019. wcsncpy( DsAclsRights[ j ].StringEx, LoadBuffer, Length + 1 );
  1020. }
  1021. }
  1022. }
  1023. return ERROR_SUCCESS;
  1024. }
  1025. /*******************************************************************
  1026. NAME: ConvertArgvToUnicode
  1027. SYNOPSIS: Converts Command Line Arguments to UNICODE
  1028. RETURNS: ERROR_SUCCESS if success
  1029. ERROR_NOT_ENOUGH_MEMORY
  1030. ********************************************************************/
  1031. DWORD
  1032. ConvertArgvToUnicode( LPWSTR * wargv, char ** argv, int argc )
  1033. {
  1034. DWORD dwErr = ERROR_SUCCESS;
  1035. int i = 0;
  1036. for ( i = 0; i < argc ; ++i )
  1037. if( ( dwErr = ConvertStringAToStringW( argv[i], wargv + i ) ) != ERROR_SUCCESS )
  1038. return dwErr;
  1039. return ERROR_SUCCESS;
  1040. }
  1041. /*
  1042. Sets Security Descriptor for pszObject
  1043. */
  1044. DWORD
  1045. WriteObjectSecurity( IN LPWSTR pszObject,
  1046. IN SECURITY_INFORMATION si,
  1047. IN PSECURITY_DESCRIPTOR pSD )
  1048. {
  1049. DWORD dwErr;
  1050. SECURITY_DESCRIPTOR_CONTROL wSDControl = 0;
  1051. DWORD dwRevision;
  1052. PSID psidOwner = NULL;
  1053. PSID psidGroup = NULL;
  1054. PACL pDacl = NULL;
  1055. PACL pSacl = NULL;
  1056. BOOL bDefaulted;
  1057. BOOL bPresent;
  1058. LPWSTR pszLDAPObjectPath = NULL;
  1059. if( ( dwErr = BuildLdapPath( &pszLDAPObjectPath,
  1060. g_szServerName,
  1061. pszObject ) ) != ERROR_SUCCESS )
  1062. return dwErr;
  1063. //
  1064. // Get pointers to various security descriptor parts for
  1065. // calling SetNamedSecurityInfo
  1066. //
  1067. ;
  1068. if( !GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision) )
  1069. {
  1070. return GetLastError();
  1071. }
  1072. if( !GetSecurityDescriptorOwner(pSD, &psidOwner, &bDefaulted) )
  1073. {
  1074. return GetLastError();
  1075. }
  1076. if( !GetSecurityDescriptorGroup(pSD, &psidGroup, &bDefaulted) )
  1077. {
  1078. return GetLastError();
  1079. }
  1080. if( !GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefaulted) )
  1081. {
  1082. return GetLastError();
  1083. }
  1084. if( !GetSecurityDescriptorSacl(pSD, &bPresent, &pSacl, &bDefaulted) )
  1085. {
  1086. return GetLastError();
  1087. }
  1088. if ((si & DACL_SECURITY_INFORMATION) && (wSDControl & SE_DACL_PROTECTED))
  1089. si |= PROTECTED_DACL_SECURITY_INFORMATION;
  1090. if ((si & SACL_SECURITY_INFORMATION) && (wSDControl & SE_SACL_PROTECTED))
  1091. si |= PROTECTED_SACL_SECURITY_INFORMATION;
  1092. return SetNamedSecurityInfo( (LPWSTR)pszLDAPObjectPath,
  1093. SE_DS_OBJECT_ALL,
  1094. si,
  1095. psidOwner,
  1096. psidGroup,
  1097. pDacl,
  1098. pSacl);
  1099. }
  1100. /*******************************************************************
  1101. NAME: DisplayAccessRights
  1102. SYNOPSIS: Displays Access Rights in Acess Mask
  1103. RETURNS: NONE
  1104. ********************************************************************/
  1105. void DisplayAccessRights( UINT nSpace, ACCESS_MASK m_Mask )
  1106. {
  1107. for ( int j = 0; j < ( sizeof( DsAclsRights ) / sizeof( DSACLS_RIGHTS ) ); j++ )
  1108. {
  1109. if( FlagOn( m_Mask,DsAclsRights[j].Right ) )
  1110. {
  1111. DisplayStringWithNewLine( nSpace,DsAclsRights[j].StringEx );
  1112. }
  1113. }
  1114. }
  1115. /*******************************************************************
  1116. NAME: ConvertAccessMaskToGenericString
  1117. SYNOPSIS: Map access mask to FULL CONTROL or SPECIAL
  1118. RETURNS: NONE
  1119. ********************************************************************/
  1120. void ConvertAccessMaskToGenericString( ACCESS_MASK m_Mask, LPWSTR szLoadBuffer, UINT nBuffer )
  1121. {
  1122. szLoadBuffer[0] = 0;
  1123. WCHAR szTemp[1024];
  1124. if( GENERIC_ALL_MAPPING == ( m_Mask & GENERIC_ALL_MAPPING ) )
  1125. {
  1126. LoadString( g_hInstance, MSG_TAG_GA_EX, szLoadBuffer, nBuffer );
  1127. }
  1128. else
  1129. {
  1130. LoadString( g_hInstance, MSG_DSACLS_SPECIAL, szLoadBuffer, nBuffer );
  1131. }
  1132. }
  1133. /*******************************************************************
  1134. NAME: MapGeneric
  1135. ********************************************************************/
  1136. void MapGeneric( ACCESS_MASK * pMask )
  1137. {
  1138. GENERIC_MAPPING m = DS_GENERIC_MAPPING;
  1139. MapGenericMask( pMask, &m );
  1140. }
  1141. /*******************************************************************
  1142. NAME: BuildExplicitAccess
  1143. SYNOPSIS: Builds Explicit Access
  1144. RETURNS: ERROR_SUCCESS if success
  1145. ERROR_NOT_ENOUGH_MEMORY
  1146. ********************************************************************/
  1147. DWORD BuildExplicitAccess( IN PSID pSid,
  1148. IN GUID* pGuidObject,
  1149. IN GUID* pGuidInherit,
  1150. IN ACCESS_MODE AccessMode,
  1151. IN ULONG Access,
  1152. IN ULONG Inheritance,
  1153. OUT PEXPLICIT_ACCESS pExplicitAccess )
  1154. {
  1155. DWORD dwErr = ERROR_SUCCESS;
  1156. PSID pSidLocal = NULL;
  1157. DWORD cbSid = 0;
  1158. POBJECTS_AND_SID pOAS = NULL;
  1159. cbSid = GetLengthSid( pSid );
  1160. pSidLocal = (PSID) LocalAlloc( LMEM_FIXED, cbSid );
  1161. CHECK_NULL( pSidLocal,FAILURE_RETURN );
  1162. CopySid( cbSid,pSidLocal, pSid );
  1163. if( pGuidObject || pGuidInherit )
  1164. {
  1165. pOAS = (POBJECTS_AND_SID)LocalAlloc( LMEM_FIXED, sizeof( OBJECTS_AND_SID ) );
  1166. CHECK_NULL( pOAS, FAILURE_RETURN );
  1167. BuildTrusteeWithObjectsAndSid( &pExplicitAccess->Trustee,
  1168. pOAS,
  1169. pGuidObject,
  1170. pGuidInherit,
  1171. pSidLocal );
  1172. }
  1173. else
  1174. BuildTrusteeWithSid( &pExplicitAccess->Trustee,
  1175. pSidLocal );
  1176. MapGeneric( &Access );
  1177. pExplicitAccess->grfAccessMode = AccessMode;
  1178. pExplicitAccess->grfAccessPermissions =Access;
  1179. pExplicitAccess->grfInheritance = Inheritance;
  1180. goto SUCCESS_RETURN;
  1181. FAILURE_RETURN:
  1182. if(pSidLocal)
  1183. LocalFree(pSidLocal);
  1184. if( pOAS )
  1185. LocalFree( pOAS );
  1186. SUCCESS_RETURN:
  1187. return dwErr;
  1188. }
  1189. /*******************************************************************
  1190. NAME: ParseUserAndPermissons
  1191. SYNOPSIS: Parses <GROUP\USER>:Access;[object\property];[inheritid]
  1192. ********************************************************************/
  1193. DWORD ParseUserAndPermissons( IN LPWSTR pszArgument,
  1194. IN DSACLS_OP Op,
  1195. IN ULONG RightsListCount,
  1196. IN PDSACLS_RIGHTS RightsList,
  1197. OUT LPWSTR * ppszTrusteeName,
  1198. OUT PULONG pAccess,
  1199. OUT LPWSTR * ppszObjectId,
  1200. OUT LPWSTR * ppszInheritId )
  1201. {
  1202. LPWSTR pszTempString = NULL;
  1203. LPWSTR pszTempString2 = NULL;
  1204. DWORD dwErr = ERROR_SUCCESS;
  1205. ULONG j = 0;
  1206. *ppszTrusteeName = NULL;
  1207. *pAccess = 0;
  1208. *ppszObjectId = NULL;
  1209. *ppszInheritId = NULL;
  1210. if ( Op != REVOKE )
  1211. {
  1212. pszTempString = wcschr( pszArgument, L':' );
  1213. if ( !pszTempString )
  1214. {
  1215. dwErr = ERROR_INVALID_PARAMETER;
  1216. goto FAILURE_RETURN;
  1217. }
  1218. *pszTempString = L'\0';
  1219. }
  1220. dwErr = CopyUnicodeString( ppszTrusteeName, pszArgument );
  1221. if ( dwErr != ERROR_SUCCESS )
  1222. {
  1223. goto FAILURE_RETURN;
  1224. }
  1225. if ( Op != REVOKE )
  1226. {
  1227. *pszTempString = L':';
  1228. pszTempString++;
  1229. // Now, process all of the user rights
  1230. *pAccess = 0;
  1231. while ( pszTempString && !( *pszTempString == L';' || *pszTempString == L'\0' ) )
  1232. {
  1233. for ( j = 0; j < RightsListCount; j++ )
  1234. {
  1235. if ( !_wcsnicmp( pszTempString,
  1236. RightsList[ j ].String,
  1237. RightsList[ j ].Length ) )
  1238. {
  1239. *pAccess |= RightsList[ j ].Right;
  1240. pszTempString += RightsList[ j ].Length;
  1241. break;
  1242. }
  1243. }
  1244. if ( j == RightsListCount )
  1245. {
  1246. dwErr = ERROR_INVALID_PARAMETER;
  1247. goto FAILURE_RETURN;
  1248. }
  1249. }
  1250. if ( *pAccess == 0 )
  1251. {
  1252. dwErr = ERROR_INVALID_PARAMETER;
  1253. goto FAILURE_RETURN;
  1254. }
  1255. //
  1256. // Object id
  1257. //
  1258. if ( pszTempString && *pszTempString != L'\0' )
  1259. {
  1260. pszTempString++;
  1261. if ( pszTempString && *pszTempString != L';' && *pszTempString != L'\0' )
  1262. {
  1263. pszTempString2 = wcschr( pszTempString, L';' );
  1264. if ( pszTempString2 )
  1265. {
  1266. *pszTempString2 = L'\0';
  1267. }
  1268. dwErr = CopyUnicodeString( ppszObjectId,pszTempString );
  1269. if ( dwErr != ERROR_SUCCESS )
  1270. {
  1271. goto FAILURE_RETURN;
  1272. }
  1273. if ( pszTempString2 )
  1274. {
  1275. *pszTempString2 = L';';
  1276. }
  1277. pszTempString = pszTempString2;
  1278. }
  1279. }
  1280. else
  1281. *ppszObjectId = NULL;
  1282. //
  1283. // Inherit id
  1284. //
  1285. if ( pszTempString && *pszTempString != L'\0' )
  1286. {
  1287. pszTempString++;
  1288. if ( pszTempString && *pszTempString != L'\0' )
  1289. {
  1290. dwErr = CopyUnicodeString( ppszInheritId,
  1291. pszTempString );
  1292. if ( dwErr != ERROR_SUCCESS )
  1293. {
  1294. goto FAILURE_RETURN;
  1295. }
  1296. }
  1297. } else
  1298. *ppszInheritId = NULL;
  1299. }
  1300. FAILURE_RETURN:
  1301. if( dwErr != ERROR_SUCCESS )
  1302. {
  1303. if( *ppszTrusteeName )
  1304. {
  1305. LocalFree( *ppszTrusteeName );
  1306. *ppszTrusteeName = NULL;
  1307. }
  1308. if( *ppszObjectId )
  1309. {
  1310. LocalFree( *ppszObjectId );
  1311. *ppszObjectId = NULL;
  1312. }
  1313. if( *ppszInheritId )
  1314. {
  1315. LocalFree( *ppszInheritId );
  1316. *ppszInheritId = NULL;
  1317. }
  1318. *pAccess = 0;
  1319. }
  1320. return dwErr;
  1321. }