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.

1218 lines
30 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. group.cxx
  5. Abstract:
  6. Routines implementing the Group object
  7. Author:
  8. Cliff Van Dyke (cliffv) 11-Apr-2001
  9. --*/
  10. #include "pch.hxx"
  11. DWORD
  12. AzpGroupInit(
  13. IN PGENERIC_OBJECT ParentGenericObject,
  14. IN PGENERIC_OBJECT ChildGenericObject
  15. )
  16. /*++
  17. Routine Description:
  18. This routine is a worker routine for AzGroupCreate. It does any object specific
  19. initialization that needs to be done.
  20. On entry, AzGlResource must be locked exclusively.
  21. Arguments:
  22. ParentGenericObject - Specifies the parent object to add the child object onto.
  23. The reference count has been incremented on this object.
  24. ChildGenericObject - Specifies the newly allocated child object.
  25. The reference count has been incremented on this object.
  26. Return Value:
  27. NO_ERROR - The operation was successful
  28. ERROR_NOT_ENOUGH_MEMORY - not enough memory
  29. Other exception status codes
  30. --*/
  31. {
  32. PAZP_GROUP Group = (PAZP_GROUP) ChildGenericObject;
  33. PAZP_ADMIN_MANAGER AdminManager = NULL;
  34. PAZP_APPLICATION Application = NULL;
  35. PAZP_SCOPE Scope = NULL;
  36. PGENERIC_OBJECT_HEAD ParentSids = NULL;
  37. //
  38. // Initialization
  39. //
  40. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  41. //
  42. // Behave differently depending on the object type of the parent object
  43. //
  44. // A group references SID objects that are siblings of itself.
  45. // That way, the back links on the SID object references just the groups
  46. // that are siblings of the SID object.
  47. //
  48. if ( ParentGenericObject->ObjectType == OBJECT_TYPE_ADMIN_MANAGER ) {
  49. AdminManager = (PAZP_ADMIN_MANAGER) ParentGenericObject;
  50. ParentSids = &AdminManager->AzpSids;
  51. } else if ( ParentGenericObject->ObjectType == OBJECT_TYPE_APPLICATION ) {
  52. AdminManager = ParentGenericObject->AdminManagerObject;
  53. Application = (PAZP_APPLICATION) ParentGenericObject;
  54. ParentSids = &Application->AzpSids;
  55. } else if ( ParentGenericObject->ObjectType == OBJECT_TYPE_SCOPE ) {
  56. AdminManager = ParentGenericObject->AdminManagerObject;
  57. Application = (PAZP_APPLICATION) ParentGenericObject->ParentGenericObjectHead->ParentGenericObject;
  58. Scope = (PAZP_SCOPE) ParentGenericObject;
  59. ParentSids = &Scope->AzpSids;
  60. } else {
  61. ASSERT( FALSE );
  62. }
  63. //
  64. // Groups reference other groups.
  65. // These other groups can be siblings of this group or siblings of our parents.
  66. //
  67. // Let the generic object manager know all of the lists we support
  68. //
  69. ChildGenericObject->GenericObjectLists = &Group->AppMembers,
  70. ObInitObjectList( &Group->AppMembers,
  71. &Group->AppNonMembers,
  72. FALSE, // Forward link
  73. AZP_LINKPAIR_MEMBERS,
  74. &AdminManager->Groups,
  75. Application == NULL ? NULL : &Application->Groups,
  76. Scope == NULL ? NULL : &Scope->Groups );
  77. // Same for non members
  78. ObInitObjectList( &Group->AppNonMembers,
  79. &Group->backAppMembers,
  80. FALSE, // Forward link
  81. AZP_LINKPAIR_NON_MEMBERS,
  82. &AdminManager->Groups,
  83. Application == NULL ? NULL : &Application->Groups,
  84. Scope == NULL ? NULL : &Scope->Groups );
  85. // back links for the above
  86. ObInitObjectList( &Group->backAppMembers,
  87. &Group->backAppNonMembers,
  88. TRUE, // backward link
  89. AZP_LINKPAIR_MEMBERS,
  90. NULL,
  91. NULL,
  92. NULL );
  93. ObInitObjectList( &Group->backAppNonMembers,
  94. &Group->backRoles,
  95. TRUE, // backward link
  96. AZP_LINKPAIR_NON_MEMBERS,
  97. NULL,
  98. NULL,
  99. NULL );
  100. // Groups are referenced by "Roles"
  101. ObInitObjectList( &Group->backRoles,
  102. &Group->SidMembers,
  103. TRUE, // Backward link
  104. 0, // No link pair id
  105. NULL,
  106. NULL,
  107. NULL );
  108. // Groups reference SID objects
  109. ObInitObjectList( &Group->SidMembers,
  110. &Group->SidNonMembers,
  111. FALSE, // Forward link
  112. AZP_LINKPAIR_SID_MEMBERS,
  113. ParentSids,
  114. NULL,
  115. NULL );
  116. // Same for non members
  117. ObInitObjectList( &Group->SidNonMembers,
  118. NULL,
  119. FALSE, // Forward link
  120. AZP_LINKPAIR_SID_NON_MEMBERS,
  121. ParentSids,
  122. NULL,
  123. NULL );
  124. return NO_ERROR;
  125. }
  126. VOID
  127. AzpGroupFree(
  128. IN PGENERIC_OBJECT GenericObject
  129. )
  130. /*++
  131. Routine Description:
  132. This routine is a worker routine for Group object free. It does any object specific
  133. cleanup that needs to be done.
  134. On entry, AzGlResource must be locked exclusively.
  135. Arguments:
  136. GenericObject - Specifies a pointer to the object to be deleted.
  137. Return Value:
  138. None
  139. --*/
  140. {
  141. PAZP_GROUP Group = (PAZP_GROUP) GenericObject;
  142. //
  143. // Initialization
  144. //
  145. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  146. //
  147. // Free any local strings
  148. //
  149. AzpFreeString( &Group->LdapQuery );
  150. }
  151. DWORD
  152. AzpGroupGetProperty(
  153. IN PGENERIC_OBJECT GenericObject,
  154. IN ULONG PropertyId,
  155. OUT PVOID *PropertyValue
  156. )
  157. /*++
  158. Routine Description:
  159. This routine is a worker routine for AzGroupGetProperty. It does any object specific
  160. property gets.
  161. On entry, AzGlResource must be locked shared.
  162. Arguments:
  163. GenericObject - Specifies a pointer to the object to be queried
  164. PropertyId - Specifies which property to return.
  165. PropertyValue - Specifies a pointer to return the property in.
  166. The returned pointer must be freed using AzFreeMemory.
  167. The returned value and type depends in PropertyId. The valid values are:
  168. AZ_PROP_GROUP_TYPE PULONG - Group type of the group
  169. AZ_PROP_GROUP_APP_MEMBERS AZ_STRING_ARRAY - Application groups that are members of this group
  170. AZ_PROP_GROUP_APP_NON_MEMBERS AZ_STRING_ARRAY - Application groups that are non-members of this group
  171. AZ_PROP_GROUP_LDAP_QUERY LPWSTR - Ldap query string of the group
  172. AZ_PROP_GROUP_MEMBERS AZ_SID_ARRAY - NT sids that are members of this group
  173. AZ_PROP_GROUP_NON_MEMBERS AZ_SID_ARRAY - NT sids that are non-members of this group
  174. Return Value:
  175. Status of the operation
  176. --*/
  177. {
  178. DWORD WinStatus = NO_ERROR;
  179. PAZP_GROUP Group = (PAZP_GROUP) GenericObject;
  180. //
  181. // Initialization
  182. //
  183. ASSERT( AzpIsLockedShared( &AzGlResource ) );
  184. //
  185. // Return any object specific attribute
  186. //
  187. //
  188. switch ( PropertyId ) {
  189. case AZ_PROP_GROUP_TYPE:
  190. *PropertyValue = AzpGetUlongProperty( Group->GroupType );
  191. if ( *PropertyValue == NULL ) {
  192. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  193. }
  194. break;
  195. // Return the set of app members to the caller
  196. case AZ_PROP_GROUP_APP_MEMBERS:
  197. *PropertyValue = ObGetPropertyItems( &Group->AppMembers );
  198. if ( *PropertyValue == NULL ) {
  199. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  200. }
  201. break;
  202. case AZ_PROP_GROUP_APP_NON_MEMBERS:
  203. *PropertyValue = ObGetPropertyItems( &Group->AppNonMembers );
  204. if ( *PropertyValue == NULL ) {
  205. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  206. }
  207. break;
  208. // Return the set of sid members to the caller
  209. case AZ_PROP_GROUP_MEMBERS:
  210. *PropertyValue = ObGetPropertyItems( &Group->SidMembers );
  211. if ( *PropertyValue == NULL ) {
  212. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  213. }
  214. break;
  215. case AZ_PROP_GROUP_NON_MEMBERS:
  216. *PropertyValue = ObGetPropertyItems( &Group->SidNonMembers );
  217. if ( *PropertyValue == NULL ) {
  218. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  219. }
  220. break;
  221. //
  222. // Return ldap query string to the caller
  223. //
  224. case AZ_PROP_GROUP_LDAP_QUERY:
  225. *PropertyValue = AzpGetStringProperty( &Group->LdapQuery );
  226. if ( *PropertyValue == NULL ) {
  227. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  228. }
  229. break;
  230. default:
  231. AzPrint(( AZD_INVPARM, "AzpGroupGetProperty: invalid opcode\n", PropertyId ));
  232. WinStatus = ERROR_INVALID_PARAMETER;
  233. break;
  234. }
  235. return WinStatus;
  236. }
  237. DWORD
  238. AzpGroupSetProperty(
  239. IN PGENERIC_OBJECT GenericObject,
  240. IN ULONG PropertyId,
  241. IN PVOID PropertyValue
  242. )
  243. /*++
  244. Routine Description:
  245. This routine is a worker routine for AzGroupSetProperty. It does any object specific
  246. property sets.
  247. On entry, AzGlResource must be locked exclusive.
  248. Arguments:
  249. GenericObject - Specifies a pointer to the object to be modified
  250. PropertyId - Specifies which property to set.
  251. PropertyValue - Specifies a pointer to the property.
  252. The specified value and type depends in PropertyId. The valid values are:
  253. AZ_PROP_GROUP_TYPE PULONG - Group type of the group
  254. AZ_PROP_GROUP_LDAP_QUERY LPWSTR - Ldap query string of the group
  255. Return Value:
  256. Status of the operation
  257. --*/
  258. {
  259. DWORD WinStatus = NO_ERROR;
  260. PAZP_GROUP Group = (PAZP_GROUP) GenericObject;
  261. AZP_STRING CapturedString;
  262. ULONG LocalGroupType;
  263. //
  264. // Initialization
  265. //
  266. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  267. AzpInitString( &CapturedString, NULL );
  268. //
  269. // Set the group type
  270. //
  271. switch ( PropertyId ) {
  272. case AZ_PROP_GROUP_TYPE:
  273. WinStatus = AzpCaptureUlong( PropertyValue, &LocalGroupType );
  274. if ( WinStatus != NO_ERROR ) {
  275. goto Cleanup;
  276. }
  277. if ( LocalGroupType != AZ_GROUPTYPE_LDAP_QUERY &&
  278. LocalGroupType != AZ_GROUPTYPE_MEMBERSHIP ) {
  279. AzPrint(( AZD_INVPARM, "AzpGroupGetProperty: invalid grouptype %ld\n", LocalGroupType ));
  280. WinStatus = ERROR_INVALID_PARAMETER;
  281. goto Cleanup;
  282. }
  283. Group->GroupType = LocalGroupType;
  284. break;
  285. //
  286. // Set LDAP Query string on the object
  287. //
  288. case AZ_PROP_GROUP_LDAP_QUERY:
  289. //
  290. // Capture the input string
  291. //
  292. WinStatus = AzpCaptureString( &CapturedString,
  293. (LPWSTR) PropertyValue,
  294. AZ_MAX_GROUP_LDAP_QUERY_LENGTH,
  295. TRUE ); // NULL is OK
  296. if ( WinStatus != NO_ERROR ) {
  297. goto Cleanup;
  298. }
  299. //
  300. // Only allow this propery if the group type is right
  301. // (But let them clear it out)
  302. //
  303. if ( Group->GroupType != AZ_GROUPTYPE_LDAP_QUERY &&
  304. CapturedString.StringSize != 0 ) {
  305. AzPrint(( AZD_INVPARM, "AzpGroupSetProperty: can't set ldap query before group type\n" ));
  306. WinStatus = ERROR_INVALID_PARAMETER;
  307. goto Cleanup;
  308. }
  309. //
  310. // Swap the old/new names
  311. //
  312. AzpSwapStrings( &CapturedString, &Group->LdapQuery );
  313. break;
  314. default:
  315. AzPrint(( AZD_INVPARM, "AzpGroupSetProperty: invalid propid %ld\n", PropertyId ));
  316. WinStatus = ERROR_INVALID_PARAMETER;
  317. goto Cleanup;
  318. }
  319. //
  320. // Free any local resources
  321. //
  322. Cleanup:
  323. AzpFreeString( &CapturedString );
  324. return WinStatus;
  325. }
  326. DWORD
  327. AzpGroupCheckRefLoop(
  328. IN PAZP_GROUP ParentGroup,
  329. IN PAZP_GROUP CurrentGroup,
  330. IN ULONG GenericObjectListOffset
  331. )
  332. /*++
  333. Routine Description:
  334. This routine determines whether the group members of "CurrentGroup"
  335. reference "ParentGroup". This is done to detect loops where the
  336. group references itself directly or indirectly.
  337. On entry, AzGlResource must be locked shared.
  338. Arguments:
  339. ParentGroup - Group that contains the original membership.
  340. CurrentGroup - Group that is currently being inspected to see if it
  341. loops back to ParentGroup
  342. GenericObjectListOffset - Offset to the particular GenericObjectList being
  343. checked.
  344. Return Value:
  345. Status of the operation
  346. ERROR_DS_LOOP_DETECT - A loop has been detected.
  347. --*/
  348. {
  349. ULONG WinStatus;
  350. PGENERIC_OBJECT_LIST GenericObjectList;
  351. ULONG i;
  352. PAZP_GROUP NextGroup;
  353. //
  354. // Check for a reference to ourself
  355. //
  356. ASSERT( AzpIsLockedShared( &AzGlResource ) );
  357. if ( ParentGroup == CurrentGroup ) {
  358. return ERROR_DS_LOOP_DETECT;
  359. }
  360. //
  361. // Compute a pointer to the membership list to check
  362. //
  363. GenericObjectList = (PGENERIC_OBJECT_LIST)
  364. (((LPBYTE)CurrentGroup)+GenericObjectListOffset);
  365. //
  366. // Check all groups that are members of the current group
  367. //
  368. for ( i=0; i<GenericObjectList->GenericObjects.UsedCount; i++ ) {
  369. NextGroup = (PAZP_GROUP) (GenericObjectList->GenericObjects.Array[i]);
  370. //
  371. // Recursively check this group
  372. //
  373. WinStatus = AzpGroupCheckRefLoop( ParentGroup, NextGroup, GenericObjectListOffset );
  374. if ( WinStatus != NO_ERROR ) {
  375. return WinStatus;
  376. }
  377. }
  378. return NO_ERROR;
  379. }
  380. DWORD
  381. AzpGroupAddPropertyItem(
  382. IN PGENERIC_OBJECT GenericObject,
  383. IN PGENERIC_OBJECT_LIST GenericObjectList,
  384. IN PGENERIC_OBJECT LinkedToObject
  385. )
  386. /*++
  387. Routine Description:
  388. This routine is a worker routine for AzGroupAddPropertyItem. It does any object specific
  389. property adds
  390. On entry, AzGlResource must be locked exclusive.
  391. Arguments:
  392. GenericObject - Specifies a pointer to the object to be modified
  393. GenericObjectList - Specifies the object list the object is to be added to
  394. LinkedToObject - Specifies the object that is being linked to
  395. Return Value:
  396. Status of the operation
  397. --*/
  398. {
  399. DWORD WinStatus = NO_ERROR;
  400. PAZP_GROUP Group = (PAZP_GROUP) GenericObject;
  401. //
  402. // Initialization
  403. //
  404. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  405. //
  406. // All item adds are membership additions.
  407. // Ensure the group has the right group type.
  408. //
  409. if ( Group->GroupType != AZ_GROUPTYPE_MEMBERSHIP ) {
  410. AzPrint(( AZD_INVPARM, "AzpGroupAddPropertyItem: invalid group type %ld\n", Group->GroupType ));
  411. WinStatus = ERROR_INVALID_PARAMETER;
  412. goto Cleanup;
  413. }
  414. //
  415. // Ensure this newly added membership doesn't cause a group membership loop
  416. //
  417. if ( !AzpIsSidList( GenericObjectList ) ) {
  418. WinStatus = AzpGroupCheckRefLoop( Group,
  419. (PAZP_GROUP)LinkedToObject,
  420. (ULONG)(((LPBYTE)GenericObjectList)-((LPBYTE)Group)) );
  421. }
  422. //
  423. // Free any local resources
  424. //
  425. Cleanup:
  426. return WinStatus;
  427. }
  428. DWORD
  429. AzpGroupGetGenericChildHead(
  430. IN AZ_HANDLE ParentHandle,
  431. OUT PULONG ObjectType,
  432. OUT PGENERIC_OBJECT_HEAD *GenericChildHead
  433. )
  434. /*++
  435. Routine Description:
  436. This routine determines whether ParentHandle supports Group objects as
  437. children.
  438. Arguments:
  439. ParentHandle - Specifies a handle to the object that is the parent of the group.
  440. This may be an Admin Manager handle, an Application Handle, or a
  441. Scope handle.
  442. ObjectType - Returns the object type of the ParentHandle.
  443. GenericChildHead - Returns a pointer to the head of the list of groups objects
  444. that are children of the object specified by ParentHandle. This in an unverified
  445. pointer. The pointer is only valid after ParentHandle has been validated.
  446. Return Value:
  447. Status of the operation.
  448. --*/
  449. {
  450. DWORD WinStatus;
  451. //
  452. // Determine the type of the parent handle
  453. //
  454. WinStatus = ObGetHandleType( (PGENERIC_OBJECT)ParentHandle,
  455. FALSE, // ignore deleted objects
  456. ObjectType );
  457. if ( WinStatus != NO_ERROR ) {
  458. return WinStatus;
  459. }
  460. //
  461. // Verify that the specified handle support children groups.
  462. //
  463. switch ( *ObjectType ) {
  464. case OBJECT_TYPE_ADMIN_MANAGER:
  465. *GenericChildHead = &(((PAZP_ADMIN_MANAGER)ParentHandle)->Groups);
  466. break;
  467. case OBJECT_TYPE_APPLICATION:
  468. *GenericChildHead = &(((PAZP_APPLICATION)ParentHandle)->Groups);
  469. break;
  470. case OBJECT_TYPE_SCOPE:
  471. *GenericChildHead = &(((PAZP_SCOPE)ParentHandle)->Groups);
  472. break;
  473. default:
  474. return ERROR_INVALID_HANDLE;
  475. }
  476. return NO_ERROR;
  477. }
  478. DWORD
  479. WINAPI
  480. AzGroupCreate(
  481. IN AZ_HANDLE ParentHandle,
  482. IN LPCWSTR GroupName,
  483. IN DWORD Reserved,
  484. OUT PAZ_HANDLE GroupHandle
  485. )
  486. /*++
  487. Routine Description:
  488. This routine adds a group into the scope of the specified parent object.
  489. Arguments:
  490. ParentHandle - Specifies a handle to the object that is the parent of the group.
  491. This may be an Admin Manager handle, an Application Handle, or a
  492. Scope handle.
  493. GroupName - Specifies the name of the group to add.
  494. Reserved - Reserved. Must by zero.
  495. GroupHandle - Return a handle to the group.
  496. The caller must close this handle by calling AzCloseHandle.
  497. Return Value:
  498. NO_ERROR - The operation was successful
  499. ERROR_ALREADY_EXISTS - An object by that name already exists
  500. --*/
  501. {
  502. DWORD WinStatus;
  503. DWORD ObjectType;
  504. PGENERIC_OBJECT_HEAD GenericChildHead;
  505. //
  506. // Determine that the parent handle supports groups as children
  507. //
  508. WinStatus = AzpGroupGetGenericChildHead( ParentHandle,
  509. &ObjectType,
  510. &GenericChildHead );
  511. if ( WinStatus != NO_ERROR ) {
  512. return WinStatus;
  513. }
  514. //
  515. // Call the common routine to do most of the work
  516. //
  517. return ObCommonCreateObject(
  518. (PGENERIC_OBJECT) ParentHandle,
  519. ObjectType,
  520. GenericChildHead,
  521. OBJECT_TYPE_GROUP,
  522. GroupName,
  523. Reserved,
  524. (PGENERIC_OBJECT *) GroupHandle );
  525. }
  526. DWORD
  527. WINAPI
  528. AzGroupOpen(
  529. IN AZ_HANDLE ParentHandle,
  530. IN LPCWSTR GroupName,
  531. IN DWORD Reserved,
  532. OUT PAZ_HANDLE GroupHandle
  533. )
  534. /*++
  535. Routine Description:
  536. This routine opens a group into the scope of the specified parent object.
  537. Arguments:
  538. ParentHandle - Specifies a handle to the object that is the parent of the group.
  539. This may be an Admin Manager handle, an Application Handle, or a
  540. Scope handle.
  541. GroupName - Specifies the name of the group to open
  542. Reserved - Reserved. Must by zero.
  543. GroupHandle - Return a handle to the group.
  544. The caller must close this handle by calling AzCloseHandle.
  545. Return Value:
  546. NO_ERROR - The operation was successful
  547. ERROR_NOT_FOUND - There is no group by that name
  548. --*/
  549. {
  550. DWORD WinStatus;
  551. DWORD ObjectType;
  552. PGENERIC_OBJECT_HEAD GenericChildHead;
  553. //
  554. // Determine that the parent handle supports groups as children
  555. //
  556. WinStatus = AzpGroupGetGenericChildHead( ParentHandle,
  557. &ObjectType,
  558. &GenericChildHead );
  559. if ( WinStatus != NO_ERROR ) {
  560. return WinStatus;
  561. }
  562. //
  563. // Call the common routine to do most of the work
  564. //
  565. return ObCommonOpenObject(
  566. (PGENERIC_OBJECT) ParentHandle,
  567. ObjectType,
  568. GenericChildHead,
  569. OBJECT_TYPE_GROUP,
  570. GroupName,
  571. Reserved,
  572. (PGENERIC_OBJECT *) GroupHandle );
  573. }
  574. DWORD
  575. WINAPI
  576. AzGroupEnum(
  577. IN AZ_HANDLE ParentHandle,
  578. IN DWORD Reserved,
  579. IN OUT PULONG EnumerationContext,
  580. OUT PAZ_HANDLE GroupHandle
  581. )
  582. /*++
  583. Routine Description:
  584. Enumerates all of the groups for the specified parent object.
  585. Arguments:
  586. ParentHandle - Specifies a handle to the object that is the parent of the group.
  587. This may be an Admin Manager handle, an Application Handle, or a
  588. Scope handle.
  589. Reserved - Reserved. Must by zero.
  590. EnumerationContext - Specifies a context indicating the next group to return
  591. On input for the first call, should point to zero.
  592. On input for subsequent calls, should point to the value returned on the previous call.
  593. On output, returns a value to be passed on the next call.
  594. GroupHandle - Returns a handle to the next group object.
  595. The caller must close this handle by calling AzCloseHandle.
  596. Return Value:
  597. NO_ERROR - The operation was successful (a handle was returned)
  598. ERROR_NO_MORE_ITEMS - No more items were available for enumeration
  599. --*/
  600. {
  601. DWORD WinStatus;
  602. DWORD ObjectType;
  603. PGENERIC_OBJECT_HEAD GenericChildHead;
  604. //
  605. // Determine that the parent handle supports groups as children
  606. //
  607. WinStatus = AzpGroupGetGenericChildHead( ParentHandle,
  608. &ObjectType,
  609. &GenericChildHead );
  610. if ( WinStatus != NO_ERROR ) {
  611. return WinStatus;
  612. }
  613. //
  614. // Call the common routine to do most of the work
  615. //
  616. return ObCommonEnumObjects(
  617. (PGENERIC_OBJECT) ParentHandle,
  618. ObjectType,
  619. GenericChildHead,
  620. EnumerationContext,
  621. Reserved,
  622. (PGENERIC_OBJECT *) GroupHandle );
  623. }
  624. DWORD
  625. WINAPI
  626. AzGroupGetProperty(
  627. IN AZ_HANDLE GroupHandle,
  628. IN ULONG PropertyId,
  629. IN DWORD Reserved,
  630. OUT PVOID *PropertyValue
  631. )
  632. /*++
  633. Routine Description:
  634. Returns the specified property for a group.
  635. Arguments:
  636. GroupHandle - Specifies a handle to the group
  637. PropertyId - Specifies which property to return.
  638. Reserved - Reserved. Must by zero.
  639. PropertyValue - Specifies a pointer to return the property in.
  640. The returned pointer must be freed using AzFreeMemory.
  641. The returned value and type depends in PropertyId. The valid values are:
  642. AZ_PROP_NAME LPWSTR - Object name of the object
  643. AZ_PROP_DESCRIPTION LPWSTR - Description of the object
  644. AZ_PROP_GROUP_TYPE PULONG - Group type of the group
  645. AZ_PROP_GROUP_APP_MEMBERS AZ_STRING_ARRAY - Application groups that are members of this group
  646. AZ_PROP_GROUP_APP_NON_MEMBERS AZ_STRING_ARRAY - Application groups that are non-members of this group
  647. AZ_PROP_GROUP_LDAP_QUERY LPWSTR - Ldap query string of the group
  648. AZ_PROP_GROUP_MEMBERS AZ_SID_ARRAY - NT sids that are members of this group
  649. AZ_PROP_GROUP_NON_MEMBERS AZ_SID_ARRAY - NT sids that are non-members of this group
  650. Return Value:
  651. NO_ERROR - The operation was successful
  652. ERROR_INVALID_PARAMETER - PropertyId isn't valid
  653. --*/
  654. {
  655. //
  656. // Call the common routine to do most of the work
  657. //
  658. return ObCommonGetProperty(
  659. (PGENERIC_OBJECT) GroupHandle,
  660. OBJECT_TYPE_GROUP,
  661. PropertyId,
  662. Reserved,
  663. PropertyValue );
  664. }
  665. DWORD
  666. WINAPI
  667. AzGroupSetProperty(
  668. IN AZ_HANDLE GroupHandle,
  669. IN ULONG PropertyId,
  670. IN DWORD Reserved,
  671. IN PVOID PropertyValue
  672. )
  673. /*++
  674. Routine Description:
  675. Sets the specified property for a group.
  676. Arguments:
  677. GroupHandle - Specifies a handle to the group
  678. PropertyId - Specifies which property to set
  679. Reserved - Reserved. Must by zero.
  680. PropertyValue - Specifies a pointer to the property.
  681. The specified value and type depends in PropertyId. The valid values are:
  682. AZ_PROP_NAME LPWSTR - Object name of the object
  683. AZ_PROP_DESCRIPTION LPWSTR - Description of the object
  684. AZ_PROP_GROUP_TYPE PULONG - Group type of the group
  685. Return Value:
  686. NO_ERROR - The operation was successful
  687. ERROR_INVALID_PARAMETER - PropertyId isn't valid
  688. --*/
  689. {
  690. //
  691. // Call the common routine to do most of the work
  692. //
  693. return ObCommonSetProperty(
  694. (PGENERIC_OBJECT) GroupHandle,
  695. OBJECT_TYPE_GROUP,
  696. PropertyId,
  697. Reserved,
  698. PropertyValue );
  699. }
  700. DWORD
  701. WINAPI
  702. AzGroupAddPropertyItem(
  703. IN AZ_HANDLE GroupHandle,
  704. IN ULONG PropertyId,
  705. IN DWORD Reserved,
  706. IN PVOID PropertyValue
  707. )
  708. /*++
  709. Routine Description:
  710. Adds an item to the list of items specified by PropertyId.
  711. Arguments:
  712. GroupHandle - Specifies a handle to the task
  713. PropertyId - Specifies which property to modify
  714. Reserved - Reserved. Must by zero.
  715. PropertyValue - Specifies a pointer to item to add.
  716. The specified value and type depends on PropertyId. The valid values are:
  717. AZ_PROP_GROUP_APP_MEMBERS LPWSTR - Application groups that are members of this group
  718. AZ_PROP_GROUP_APP_NON_MEMBERS LPWSTR - Application groups that are non-members of this group
  719. AZ_PROP_GROUP_MEMBERS PSID - NT sids that are members of this group
  720. AZ_PROP_GROUP_NON_MEMBERS PSID - NT sids that are non-members of this group
  721. Return Value:
  722. NO_ERROR - The operation was successful
  723. ERROR_INVALID_PARAMETER - PropertyId isn't valid
  724. ERROR_NOT_FOUND - There is no object by that name
  725. ERROR_ALREADY_EXISTS - An item by that name already exists in the list
  726. --*/
  727. {
  728. PGENERIC_OBJECT_LIST GenericObjectList;
  729. //
  730. // Validate the Property ID
  731. //
  732. switch ( PropertyId ) {
  733. case AZ_PROP_GROUP_APP_MEMBERS:
  734. GenericObjectList = &((PAZP_GROUP)GroupHandle)->AppMembers;
  735. break;
  736. case AZ_PROP_GROUP_APP_NON_MEMBERS:
  737. GenericObjectList = &((PAZP_GROUP)GroupHandle)->AppNonMembers;
  738. break;
  739. case AZ_PROP_GROUP_MEMBERS:
  740. GenericObjectList = &((PAZP_GROUP)GroupHandle)->SidMembers;
  741. break;
  742. case AZ_PROP_GROUP_NON_MEMBERS:
  743. GenericObjectList = &((PAZP_GROUP)GroupHandle)->SidNonMembers;
  744. break;
  745. default:
  746. AzPrint(( AZD_INVPARM, "AzGroupAddPropertyItem: invalid prop id %ld\n", PropertyId ));
  747. return ERROR_INVALID_PARAMETER;
  748. }
  749. //
  750. // Call the common routine to do most of the work
  751. //
  752. return ObCommonAddPropertyItem(
  753. (PGENERIC_OBJECT) GroupHandle,
  754. OBJECT_TYPE_GROUP,
  755. GenericObjectList,
  756. Reserved,
  757. (LPWSTR) PropertyValue );
  758. }
  759. DWORD
  760. WINAPI
  761. AzGroupRemovePropertyItem(
  762. IN AZ_HANDLE GroupHandle,
  763. IN ULONG PropertyId,
  764. IN DWORD Reserved,
  765. IN PVOID PropertyValue
  766. )
  767. /*++
  768. Routine Description:
  769. Remove an item from the list of items specified by PropertyId.
  770. Arguments:
  771. GroupHandle - Specifies a handle to the task
  772. PropertyId - Specifies which property to modify
  773. Reserved - Reserved. Must by zero.
  774. PropertyValue - Specifies a pointer to item to remove.
  775. The specified value and type depends on PropertyId. The valid values are:
  776. AZ_PROP_GROUP_APP_MEMBERS LPWSTR - Application groups that are members of this group
  777. AZ_PROP_GROUP_APP_NON_MEMBERS LPWSTR - Application groups that are non-members of this group
  778. AZ_PROP_GROUP_MEMBERS PSID - NT sids that are members of this group
  779. AZ_PROP_GROUP_NON_MEMBERS PSID - NT sids that are non-members of this group
  780. Return Value:
  781. NO_ERROR - The operation was successful
  782. ERROR_INVALID_PARAMETER - PropertyId isn't valid
  783. ERROR_NOT_FOUND - There is no item by that name in the list
  784. --*/
  785. {
  786. PGENERIC_OBJECT_LIST GenericObjectList;
  787. //
  788. // Validate the Property ID
  789. //
  790. switch ( PropertyId ) {
  791. case AZ_PROP_GROUP_APP_MEMBERS:
  792. GenericObjectList = &((PAZP_GROUP)GroupHandle)->AppMembers;
  793. break;
  794. case AZ_PROP_GROUP_APP_NON_MEMBERS:
  795. GenericObjectList = &((PAZP_GROUP)GroupHandle)->AppNonMembers;
  796. break;
  797. case AZ_PROP_GROUP_MEMBERS:
  798. GenericObjectList = &((PAZP_GROUP)GroupHandle)->SidMembers;
  799. break;
  800. case AZ_PROP_GROUP_NON_MEMBERS:
  801. GenericObjectList = &((PAZP_GROUP)GroupHandle)->SidNonMembers;
  802. break;
  803. default:
  804. AzPrint(( AZD_INVPARM, "AzGroupRemovePropertyItem: invalid prop id %ld\n", PropertyId ));
  805. return ERROR_INVALID_PARAMETER;
  806. }
  807. //
  808. // Call the common routine to do most of the work
  809. //
  810. return ObCommonRemovePropertyItem (
  811. (PGENERIC_OBJECT) GroupHandle,
  812. OBJECT_TYPE_GROUP,
  813. GenericObjectList,
  814. Reserved,
  815. (LPWSTR) PropertyValue );
  816. }
  817. DWORD
  818. WINAPI
  819. AzGroupDelete(
  820. IN AZ_HANDLE ParentHandle,
  821. IN LPCWSTR GroupName,
  822. IN DWORD Reserved
  823. )
  824. /*++
  825. Routine Description:
  826. This routine deletes a group from the scope of the specified parent object.
  827. Also deletes any child objects of GroupName.
  828. Arguments:
  829. ParentHandle - Specifies a handle to the object that is the parent of the group.
  830. This may be an Admin Manager handle, an Application Handle, or a
  831. Scope handle.
  832. GroupName - Specifies the name of the group to delete.
  833. Reserved - Reserved. Must by zero.
  834. Return Value:
  835. NO_ERROR - The operation was successful
  836. ERROR_NOT_FOUND - An object by that name cannot be found
  837. --*/
  838. {
  839. DWORD WinStatus;
  840. DWORD ObjectType;
  841. PGENERIC_OBJECT_HEAD GenericChildHead;
  842. //
  843. // Determine that the parent handle supports groups as children
  844. //
  845. WinStatus = AzpGroupGetGenericChildHead( ParentHandle,
  846. &ObjectType,
  847. &GenericChildHead );
  848. if ( WinStatus != NO_ERROR ) {
  849. return WinStatus;
  850. }
  851. //
  852. // Call the common routine to do most of the work
  853. //
  854. return ObCommonDeleteObject(
  855. (PGENERIC_OBJECT) ParentHandle,
  856. ObjectType,
  857. GenericChildHead,
  858. OBJECT_TYPE_GROUP,
  859. GroupName,
  860. Reserved );
  861. }