Leaked source code of windows server 2003
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.

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