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.

1412 lines
39 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. task.cxx
  5. Abstract:
  6. Routines implementing the Task object
  7. Author:
  8. Cliff Van Dyke (cliffv) 11-Apr-2001
  9. --*/
  10. #include "pch.hxx"
  11. //
  12. // Define the default values for all scalar attributes
  13. //
  14. BOOL AzGlDefIsRoleDefinition = FALSE;
  15. AZP_DEFAULT_VALUE AzGlTaskDefaultValues[] = {
  16. { AZ_PROP_TASK_BIZRULE, AZ_DIRTY_TASK_BIZRULE, NULL },
  17. { AZ_PROP_TASK_BIZRULE_LANGUAGE, AZ_DIRTY_TASK_BIZRULE_LANGUAGE, NULL },
  18. { AZ_PROP_TASK_BIZRULE_IMPORTED_PATH, AZ_DIRTY_TASK_BIZRULE_IMPORTED_PATH, NULL },
  19. { AZ_PROP_TASK_IS_ROLE_DEFINITION, AZ_DIRTY_TASK_IS_ROLE_DEFINITION, &AzGlDefIsRoleDefinition },
  20. { 0, 0, NULL }
  21. };
  22. DWORD
  23. AzpTaskInit(
  24. IN PGENERIC_OBJECT ParentGenericObject,
  25. IN PGENERIC_OBJECT ChildGenericObject
  26. )
  27. /*++
  28. Routine Description:
  29. This routine is a worker routine for AzTaskCreate. It does any object specific
  30. initialization that needs to be done.
  31. On entry, AzGlResource must be locked exclusively.
  32. Arguments:
  33. ParentGenericObject - Specifies the parent object to add the child object onto.
  34. The reference count has been incremented on this object.
  35. ChildGenericObject - Specifies the newly allocated child object.
  36. The reference count has been incremented on this object.
  37. Return Value:
  38. NO_ERROR - The operation was successful
  39. ERROR_NOT_ENOUGH_MEMORY - not enough memory
  40. Other exception status codes
  41. --*/
  42. {
  43. DWORD WinStatus;
  44. NTSTATUS Status;
  45. PAZP_TASK Task = (PAZP_TASK) ChildGenericObject;
  46. PAZP_APPLICATION Application = NULL;
  47. PAZP_SCOPE Scope = NULL;
  48. //
  49. // Initialization
  50. //
  51. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  52. //
  53. // Behave differently depending on the object type of the parent object
  54. //
  55. if ( ParentGenericObject->ObjectType == OBJECT_TYPE_APPLICATION ) {
  56. Application = (PAZP_APPLICATION) ParentGenericObject;
  57. } else if ( ParentGenericObject->ObjectType == OBJECT_TYPE_SCOPE ) {
  58. Application = (PAZP_APPLICATION) ParentOfChild( ParentGenericObject );
  59. Scope = (PAZP_SCOPE) ParentGenericObject;
  60. } else {
  61. ASSERT( FALSE );
  62. }
  63. //
  64. // Tasks reference 'Operations' that are children of the same 'Application' as the Task object
  65. // Tasks reference 'Tasks' that are children of the same 'Application' as the Task object
  66. // Let the generic object manager know all of the lists we support
  67. //
  68. ChildGenericObject->GenericObjectLists = &Task->Operations,
  69. // Link to Operations
  70. ObInitObjectList( &Task->Operations,
  71. &Task->Tasks,
  72. FALSE, // Forward link
  73. 0, // No link pair id
  74. AZ_DIRTY_TASK_OPERATIONS,
  75. &Application->Operations,
  76. NULL,
  77. NULL );
  78. // Link to Tasks
  79. ObInitObjectList( &Task->Tasks,
  80. &Task->backRoles,
  81. FALSE, // Forward link
  82. 0, // No link pair id
  83. AZ_DIRTY_TASK_TASKS,
  84. &Application->Tasks,
  85. Scope == NULL ? NULL : &Scope->Tasks,
  86. NULL );
  87. // Back link to roles
  88. ObInitObjectList( &Task->backRoles,
  89. &Task->backTasks,
  90. TRUE, // Backward link
  91. 0, // No link pair id
  92. 0, // No dirty bit on back link
  93. NULL,
  94. NULL,
  95. NULL );
  96. // Back link to tasks
  97. ObInitObjectList( &Task->backTasks,
  98. NULL,
  99. TRUE, // Backward link
  100. 0, // No link pair id
  101. 0, // No dirty bit on back link
  102. NULL,
  103. NULL,
  104. NULL );
  105. //
  106. // Initialize the list of free script engines
  107. //
  108. InitializeListHead( &Task->FreeScriptHead );
  109. //
  110. // Initialize the list of Running script engines
  111. //
  112. Status = SafeInitializeCriticalSection( &Task->RunningScriptCritSect, SAFE_RUNNING_SCRIPT_LIST );
  113. if ( !NT_SUCCESS( Status )) {
  114. WinStatus = RtlNtStatusToDosError( Status );
  115. goto Cleanup;
  116. }
  117. Task->RunningScriptCritSectInitialized = TRUE;
  118. InitializeListHead( &Task->RunningScriptHead );
  119. WinStatus = NO_ERROR;
  120. Cleanup:
  121. if ( WinStatus != NO_ERROR ) {
  122. AzpTaskFree( ChildGenericObject );
  123. }
  124. return WinStatus;
  125. }
  126. VOID
  127. AzpTaskFree(
  128. IN PGENERIC_OBJECT GenericObject
  129. )
  130. /*++
  131. Routine Description:
  132. This routine is a worker routine for Task 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_TASK Task = (PAZP_TASK) GenericObject;
  142. //
  143. // Initialization
  144. //
  145. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  146. //
  147. // Free any local strings
  148. //
  149. AzpFreeString( &Task->BizRule );
  150. AzpFreeString( &Task->BizRuleLanguage );
  151. AzpFreeString( &Task->BizRuleImportedPath );
  152. //
  153. // Free the running script list
  154. //
  155. if ( Task->RunningScriptCritSectInitialized ) {
  156. //
  157. // Free the Free Script List itself
  158. //
  159. AzpFlushBizRule( Task );
  160. //
  161. // The task object is referenced as long as the script is running
  162. // So we shouldn't be here unless the running script list is empty.
  163. ASSERT( IsListEmpty( &Task->RunningScriptHead ));
  164. // Free the crit sect protecting the list
  165. SafeDeleteCriticalSection( &Task->RunningScriptCritSect );
  166. Task->RunningScriptCritSectInitialized = FALSE;
  167. }
  168. }
  169. DWORD
  170. AzpTaskNameConflict(
  171. IN PGENERIC_OBJECT ParentGenericObject,
  172. IN PAZP_STRING ChildObjectNameString
  173. )
  174. /*++
  175. Routine Description:
  176. This routine is a worker routine to determine if the specified ChildObjectNameString
  177. conflicts with the names of other objects that share a namespace with Tasks.
  178. On entry, AzGlResource must be locked exclusively.
  179. Arguments:
  180. ParentGenericObject - Specifies the parent object to add the child object onto.
  181. The reference count has been incremented on this object.
  182. ChildObjectNameString - Specifies the name of the child object.
  183. Return Value:
  184. NO_ERROR - The operation was successful
  185. ERROR_ALREADY_EXISTS - An object by that name already exists
  186. --*/
  187. {
  188. ULONG WinStatus;
  189. PAZP_APPLICATION Application = NULL;
  190. PGENERIC_OBJECT ConflictGenericObject;
  191. //
  192. // Initialization
  193. //
  194. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  195. //
  196. // Behave differently depending on the object type of the parent object
  197. //
  198. //
  199. // A task that is a child of an application
  200. // cannot have the same name as any tasks that are children of any of the child scopes.
  201. //
  202. if ( ParentGenericObject->ObjectType == OBJECT_TYPE_APPLICATION ) {
  203. Application = (PAZP_APPLICATION) ParentGenericObject;
  204. //
  205. // Check tasks that are children of child scopes.
  206. //
  207. WinStatus = ObCheckNameConflict( &Application->Scopes,
  208. ChildObjectNameString,
  209. offsetof(_AZP_SCOPE, Tasks),
  210. 0,
  211. 0 );
  212. //
  213. // A task that is a child of a scope,
  214. // cannot have the same name as tasks that are children of the application.
  215. //
  216. } else if ( ParentGenericObject->ObjectType == OBJECT_TYPE_SCOPE ) {
  217. Application = (PAZP_APPLICATION) ParentOfChild( ParentGenericObject );
  218. //
  219. // Check tasks that are children of the application.
  220. //
  221. WinStatus = ObReferenceObjectByName( &Application->Tasks,
  222. ChildObjectNameString,
  223. 0, // No special flags
  224. &ConflictGenericObject );
  225. if ( WinStatus == NO_ERROR ) {
  226. ObDereferenceObject( ConflictGenericObject );
  227. WinStatus = ERROR_ALREADY_EXISTS;
  228. } else {
  229. WinStatus = NO_ERROR;
  230. }
  231. } else {
  232. WinStatus = ERROR_INTERNAL_ERROR;
  233. ASSERT( FALSE );
  234. }
  235. //
  236. // Tasks and operations share a namespace so ensure there isn't an operation by this name.
  237. //
  238. if ( WinStatus == NO_ERROR ) {
  239. WinStatus = ObReferenceObjectByName( &Application->Operations,
  240. ChildObjectNameString,
  241. 0, // No special flags
  242. &ConflictGenericObject );
  243. if ( WinStatus == NO_ERROR ) {
  244. ObDereferenceObject( ConflictGenericObject );
  245. WinStatus = ERROR_ALREADY_EXISTS;
  246. } else {
  247. WinStatus = NO_ERROR;
  248. }
  249. }
  250. return WinStatus;
  251. }
  252. DWORD
  253. AzpTaskGetProperty(
  254. IN PGENERIC_OBJECT GenericObject,
  255. IN ULONG Flags,
  256. IN ULONG PropertyId,
  257. OUT PVOID *PropertyValue
  258. )
  259. /*++
  260. Routine Description:
  261. This routine is the Task specific worker routine for AzGetProperty.
  262. It does any object specific property gets.
  263. On entry, AzGlResource must be locked shared.
  264. Arguments:
  265. GenericObject - Specifies a pointer to the object to be queried
  266. Flags - Specifies internal flags
  267. AZP_FLAGS_BY_GUID - name lists should be returned as GUID lists
  268. PropertyId - Specifies which property to return.
  269. PropertyValue - Specifies a pointer to return the property in.
  270. The returned pointer must be freed using AzFreeMemory.
  271. The returned value and type depends in PropertyId. The valid values are:
  272. AZ_PROP_TASK_BIZRULE LPWSTR - Biz rule for the task
  273. AZ_PROP_TASK_BIZRULE_LANGUAGE LPWSTR - Biz language rule for the task
  274. AZ_PROP_TASK_BIZRULE_IMPORTED_PATH LPWSTR - Path Bizrule was imported from
  275. AZ_PROP_TASK_OPERATIONS AZ_STRING_ARRAY - Operations granted by this task
  276. AZ_PROP_TASK_TASKS AZ_STRING_ARRAY - tasks granted by this task
  277. AZ_PROP_TASK_IS_ROLE_DEFINITION PULONG - TRUE if this task is a role template
  278. Return Value:
  279. Status of the operation
  280. --*/
  281. {
  282. DWORD WinStatus = NO_ERROR;
  283. PAZP_TASK Task = (PAZP_TASK) GenericObject;
  284. //
  285. // Initialization
  286. //
  287. ASSERT( AzpIsLockedShared( &AzGlResource ) );
  288. //
  289. // Return any object specific attribute
  290. //
  291. switch ( PropertyId ) {
  292. //
  293. // Return BizRule to the caller
  294. //
  295. case AZ_PROP_TASK_BIZRULE:
  296. //
  297. // check if bizrule should be returned
  298. //
  299. if ( Task->BizRule.String != NULL &&
  300. (ParentOfChild(GenericObject))->ObjectType == OBJECT_TYPE_SCOPE &&
  301. (ParentOfChild(GenericObject))->PolicyAdmins.GenericObjects.UsedCount != 0 ) {
  302. //
  303. // the parent scope object is delegated, do not allow bizrule
  304. //
  305. AzPrint(( AZD_INVPARM, "AzTaskGetProperty: scope is delegated - bizrule not allowed %ld\n", PropertyId ));
  306. WinStatus = ERROR_NOT_SUPPORTED;
  307. } else {
  308. *PropertyValue = AzpGetStringProperty( &Task->BizRule );
  309. if ( *PropertyValue == NULL ) {
  310. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  311. }
  312. }
  313. break;
  314. //
  315. // Return BizRule language to the caller
  316. //
  317. case AZ_PROP_TASK_BIZRULE_LANGUAGE:
  318. //
  319. // check if bizrule should be returned
  320. //
  321. if ( Task->BizRuleLanguage.String != NULL &&
  322. (ParentOfChild(GenericObject))->ObjectType == OBJECT_TYPE_SCOPE &&
  323. (ParentOfChild(GenericObject))->PolicyAdmins.GenericObjects.UsedCount != 0 ) {
  324. //
  325. // the parent scope object is delegated, do not allow bizrule
  326. //
  327. AzPrint(( AZD_INVPARM, "AzTaskGetProperty: scope is delegated - bizrule not allowed %ld\n", PropertyId ));
  328. WinStatus = ERROR_NOT_SUPPORTED;
  329. } else {
  330. *PropertyValue = AzpGetStringProperty( &Task->BizRuleLanguage );
  331. if ( *PropertyValue == NULL ) {
  332. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  333. }
  334. }
  335. break;
  336. //
  337. // Return BizRule imported path to the caller
  338. //
  339. case AZ_PROP_TASK_BIZRULE_IMPORTED_PATH:
  340. //
  341. // check if bizrule should be returned
  342. //
  343. if ( Task->BizRuleImportedPath.String != NULL &&
  344. (ParentOfChild(GenericObject))->ObjectType == OBJECT_TYPE_SCOPE &&
  345. (ParentOfChild(GenericObject))->PolicyAdmins.GenericObjects.UsedCount != 0 ) {
  346. //
  347. // the parent scope object is delegated, do not allow bizrule
  348. //
  349. AzPrint(( AZD_INVPARM, "AzTaskGetProperty: scope is delegated - bizrule not allowed %ld\n", PropertyId ));
  350. WinStatus = ERROR_NOT_SUPPORTED;
  351. } else {
  352. *PropertyValue = AzpGetStringProperty( &Task->BizRuleImportedPath );
  353. if ( *PropertyValue == NULL ) {
  354. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  355. }
  356. }
  357. break;
  358. //
  359. // Return the set of operations to the caller
  360. //
  361. case AZ_PROP_TASK_OPERATIONS:
  362. if ( Flags & AZP_FLAGS_BY_GUID )
  363. {
  364. *PropertyValue = ObGetPropertyItemGuids( &Task->Operations);
  365. }
  366. else
  367. {
  368. *PropertyValue = ObGetPropertyItems( &Task->Operations);
  369. }
  370. if ( *PropertyValue == NULL ) {
  371. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  372. }
  373. break;
  374. //
  375. // Return the set of tasks to the caller
  376. //
  377. case AZ_PROP_TASK_TASKS:
  378. if ( Flags & AZP_FLAGS_BY_GUID )
  379. {
  380. *PropertyValue = ObGetPropertyItemGuids( &Task->Tasks);
  381. }
  382. else
  383. {
  384. *PropertyValue = ObGetPropertyItems( &Task->Tasks);
  385. }
  386. if ( *PropertyValue == NULL ) {
  387. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  388. }
  389. break;
  390. case AZ_PROP_TASK_IS_ROLE_DEFINITION:
  391. *PropertyValue = AzpGetUlongProperty( (Task->IsRoleDefinition) ? 1 : 0 );
  392. if ( *PropertyValue == NULL ) {
  393. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  394. }
  395. break;
  396. default:
  397. AzPrint(( AZD_INVPARM, "AzTaskGetProperty: invalid prop id %ld\n", PropertyId ));
  398. WinStatus = ERROR_INVALID_PARAMETER;
  399. break;
  400. }
  401. return WinStatus;
  402. }
  403. DWORD
  404. AzpTaskSetProperty(
  405. IN PGENERIC_OBJECT GenericObject,
  406. IN ULONG Flags,
  407. IN ULONG PropertyId,
  408. IN PVOID PropertyValue
  409. )
  410. /*++
  411. Routine Description:
  412. This routine is the Task object specific worker routine for AzSetProperty.
  413. It does any object specific property sets.
  414. On entry, AzGlResource must be locked exclusive.
  415. Arguments:
  416. GenericObject - Specifies a pointer to the object to be modified
  417. Flags - Specifies flags controlling to operation of the routine
  418. AZP_FLAGS_SETTING_TO_DEFAULT - Property is being set to default value
  419. PropertyId - Specifies which property to set.
  420. PropertyValue - Specifies a pointer to the property.
  421. The specified value and type depends in PropertyId. The valid values are:
  422. AZ_PROP_TASK_BIZRULE LPWSTR - Biz rule for the task
  423. AZ_PROP_TASK_BIZRULE_LANGUAGE LPWSTR - Biz language rule for the task
  424. AZ_PROP_TASK_BIZRULE_IMPORTED_PATH LPWSTR - Path Bizrule was imported from
  425. AZ_PROP_TASK_IS_ROLE_DEFINITION PULONG - TRUE if this task is a role template
  426. Return Value:
  427. Status of the operation
  428. --*/
  429. {
  430. DWORD WinStatus = NO_ERROR;
  431. PAZP_TASK Task = (PAZP_TASK) GenericObject;
  432. AZP_STRING CapturedString;
  433. AZP_STRING ValidValue1;
  434. AZP_STRING ValidValue2;
  435. BOOL bHasChanged = TRUE;
  436. //
  437. // Initialization
  438. //
  439. UNREFERENCED_PARAMETER( Flags );
  440. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  441. AzpInitString( &CapturedString, NULL );
  442. //
  443. // Set any object specific attribute
  444. //
  445. switch ( PropertyId ) {
  446. //
  447. // Set BizRule on the object
  448. //
  449. case AZ_PROP_TASK_BIZRULE:
  450. BEGIN_SETPROP( &WinStatus, Task, Flags, AZ_DIRTY_TASK_BIZRULE ) {
  451. //
  452. // Capture the input string
  453. //
  454. WinStatus = AzpCaptureString( &CapturedString,
  455. (LPWSTR) PropertyValue,
  456. CHECK_STRING_LENGTH( Flags, AZ_MAX_TASK_BIZRULE_LENGTH),
  457. TRUE ); // NULL is OK
  458. if ( WinStatus != NO_ERROR ) {
  459. goto Cleanup;
  460. }
  461. if (IsNormalFlags(Flags) && CapturedString.String != NULL)
  462. {
  463. //
  464. // This SetProperty comes from the client. We will check against
  465. // space only biz rules
  466. //
  467. BOOL bSpaceOnly = TRUE;
  468. for (UINT i = 0; i < CapturedString.StringSize / sizeof(WCHAR) - 1; i++)
  469. {
  470. if (!iswspace(CapturedString.String[i]))
  471. {
  472. bSpaceOnly = FALSE;
  473. break;
  474. }
  475. }
  476. if (bSpaceOnly)
  477. {
  478. WinStatus = ERROR_INVALID_DATA;
  479. goto Cleanup;
  480. }
  481. }
  482. //
  483. // Do parameter validity checking
  484. //
  485. BEGIN_VALIDITY_CHECKING( Flags ) {
  486. //
  487. // check if bizrule attribute is allowed
  488. //
  489. if ( CapturedString.String != NULL &&
  490. (ParentOfChild(GenericObject))->ObjectType == OBJECT_TYPE_SCOPE &&
  491. (ParentOfChild(GenericObject))->PolicyAdmins.GenericObjects.UsedCount != 0 ) {
  492. //
  493. // the parent scope object is delegated, do not allow bizrule
  494. //
  495. AzPrint(( AZD_INVPARM, "AzTaskGetProperty: scope is delegated - bizrule not allowed %ld\n", PropertyId ));
  496. WinStatus = ERROR_NOT_SUPPORTED;
  497. goto Cleanup;
  498. }
  499. //
  500. // Ensure the language is set
  501. //
  502. if ( CapturedString.String != NULL &&
  503. Task->BizRuleLanguage.String == NULL ) {
  504. AzPrint(( AZD_INVPARM, "AzpTaskSetProperty: Must set language before bizrule\n" ));
  505. WinStatus = ERROR_INVALID_PARAMETER;
  506. goto Cleanup;
  507. }
  508. } END_VALIDITY_CHECKING;
  509. //
  510. // Only process the change if the strings have changed
  511. //
  512. bHasChanged = !AzpEqualStrings( &CapturedString, &Task->BizRule );
  513. if ( bHasChanged ) {
  514. //
  515. // Swap the old/new names
  516. //
  517. SafeEnterCriticalSection( &Task->RunningScriptCritSect );
  518. AzpSwapStrings( &CapturedString, &Task->BizRule );
  519. Task->BizRuleSerialNumber ++;
  520. SafeLeaveCriticalSection( &Task->RunningScriptCritSect );
  521. //
  522. // Tell the script engine cache that the script has changed
  523. //
  524. AzpFlushBizRule( Task );
  525. //
  526. // Do parameter validity checking
  527. //
  528. BEGIN_VALIDITY_CHECKING( Flags ) {
  529. //
  530. // Ensure the script is syntactically valid
  531. //
  532. if ( Task->BizRule.String != NULL &&
  533. Task->BizRuleLanguage.String != NULL ) {
  534. WinStatus = AzpParseBizRule( Task );
  535. if ( WinStatus != NO_ERROR ) {
  536. // Put the script back
  537. SafeEnterCriticalSection( &Task->RunningScriptCritSect );
  538. AzpSwapStrings( &CapturedString, &Task->BizRule );
  539. Task->BizRuleSerialNumber ++;
  540. SafeLeaveCriticalSection( &Task->RunningScriptCritSect );
  541. }
  542. }
  543. } END_VALIDITY_CHECKING;
  544. }
  545. } END_SETPROP (bHasChanged);
  546. break;
  547. //
  548. // Set BizRule language on the object
  549. //
  550. case AZ_PROP_TASK_BIZRULE_LANGUAGE:
  551. BEGIN_SETPROP( &WinStatus, Task, Flags, AZ_DIRTY_TASK_BIZRULE_LANGUAGE ) {
  552. //
  553. // Capture the input string
  554. //
  555. WinStatus = AzpCaptureString( &CapturedString,
  556. (LPWSTR) PropertyValue,
  557. CHECK_STRING_LENGTH( Flags, AZ_MAX_TASK_BIZRULE_LANGUAGE_LENGTH),
  558. TRUE ); // NULL is OK
  559. if ( WinStatus != NO_ERROR ) {
  560. goto Cleanup;
  561. }
  562. //
  563. // Ensure it is one of the valid values
  564. //
  565. //
  566. // Do parameter validity checking
  567. //
  568. BEGIN_VALIDITY_CHECKING( Flags ) {
  569. //
  570. // check if bizrule attribute is allowed
  571. //
  572. if ( CapturedString.String != NULL &&
  573. (ParentOfChild(GenericObject))->ObjectType == OBJECT_TYPE_SCOPE &&
  574. (ParentOfChild(GenericObject))->PolicyAdmins.GenericObjects.UsedCount != 0 ) {
  575. //
  576. // the parent scope object is delegated, do not allow bizrule
  577. //
  578. AzPrint(( AZD_INVPARM, "AzTaskGetProperty: scope is delegated - bizrule not allowed %ld\n", PropertyId ));
  579. WinStatus = ERROR_NOT_SUPPORTED;
  580. goto Cleanup;
  581. }
  582. if ( CapturedString.String != NULL ) {
  583. AzpInitString( &ValidValue1, L"VBScript" );
  584. AzpInitString( &ValidValue2, L"JScript" );
  585. if ( !AzpEqualStrings( &CapturedString, &ValidValue1) &&
  586. !AzpEqualStrings( &CapturedString, &ValidValue2) ) {
  587. AzPrint(( AZD_INVPARM, "AzpTaskSetProperty: invalid language %ws\n", CapturedString.String ));
  588. WinStatus = ERROR_INVALID_PARAMETER;
  589. goto Cleanup;
  590. }
  591. }
  592. } END_VALIDITY_CHECKING;
  593. //
  594. // Only process the change if the strings have changed
  595. //
  596. bHasChanged = !AzpEqualStrings( &CapturedString, &Task->BizRuleLanguage );
  597. if ( bHasChanged ) {
  598. //
  599. // Swap the old/new names
  600. //
  601. SafeEnterCriticalSection( &Task->RunningScriptCritSect );
  602. AzpSwapStrings( &CapturedString, &Task->BizRuleLanguage );
  603. RtlZeroMemory( &Task->BizRuleLanguageClsid, sizeof(Task->BizRuleLanguageClsid) );
  604. Task->BizRuleSerialNumber ++;
  605. SafeLeaveCriticalSection( &Task->RunningScriptCritSect );
  606. //
  607. // Tell the script engine cache that the script has changed
  608. //
  609. AzpFlushBizRule( Task );
  610. //
  611. // Do parameter validity checking
  612. //
  613. BEGIN_VALIDITY_CHECKING( Flags ) {
  614. //
  615. // Ensure the script is syntactically valid
  616. //
  617. if ( Task->BizRule.String != NULL &&
  618. Task->BizRuleLanguage.String != NULL ) {
  619. WinStatus = AzpParseBizRule( Task );
  620. if ( WinStatus != NO_ERROR ) {
  621. // Put the script back
  622. SafeEnterCriticalSection( &Task->RunningScriptCritSect );
  623. AzpSwapStrings( &CapturedString, &Task->BizRuleLanguage );
  624. Task->BizRuleSerialNumber ++;
  625. RtlZeroMemory( &Task->BizRuleLanguageClsid, sizeof(Task->BizRuleLanguageClsid) );
  626. SafeLeaveCriticalSection( &Task->RunningScriptCritSect );
  627. }
  628. }
  629. } END_VALIDITY_CHECKING;
  630. }
  631. } END_SETPROP (bHasChanged);
  632. break;
  633. //
  634. // Set BizRule imported path on the object
  635. //
  636. case AZ_PROP_TASK_BIZRULE_IMPORTED_PATH:
  637. BEGIN_SETPROP( &WinStatus, Task, Flags, AZ_DIRTY_TASK_BIZRULE_IMPORTED_PATH ) {
  638. //
  639. // Capture the input string
  640. //
  641. WinStatus = AzpCaptureString( &CapturedString,
  642. (LPWSTR) PropertyValue,
  643. CHECK_STRING_LENGTH( Flags, AZ_MAX_TASK_BIZRULE_IMPORTED_PATH_LENGTH),
  644. TRUE ); // NULL is OK
  645. if ( WinStatus != NO_ERROR ) {
  646. goto Cleanup;
  647. }
  648. //
  649. // Ensure it is one of the valid values
  650. //
  651. //
  652. // Do parameter validity checking
  653. //
  654. BEGIN_VALIDITY_CHECKING( Flags ) {
  655. //
  656. // check if bizrule attribute is allowed
  657. //
  658. if ( CapturedString.String != NULL &&
  659. (ParentOfChild(GenericObject))->ObjectType == OBJECT_TYPE_SCOPE &&
  660. (ParentOfChild(GenericObject))->PolicyAdmins.GenericObjects.UsedCount != 0 ) {
  661. //
  662. // the parent scope object is delegated, do not allow bizrule
  663. //
  664. AzPrint(( AZD_INVPARM, "AzTaskGetProperty: scope is delegated - bizrule not allowed %ld\n", PropertyId ));
  665. WinStatus = ERROR_NOT_SUPPORTED;
  666. goto Cleanup;
  667. }
  668. } END_VALIDITY_CHECKING;
  669. //
  670. // Swap the old/new names
  671. //
  672. AzpSwapStrings( &CapturedString, &Task->BizRuleImportedPath );
  673. } END_SETPROP(bHasChanged);
  674. break;
  675. case AZ_PROP_TASK_IS_ROLE_DEFINITION:
  676. BEGIN_SETPROP( &WinStatus, Task, Flags, AZ_DIRTY_TASK_IS_ROLE_DEFINITION ) {
  677. WinStatus = AzpCaptureLong( PropertyValue, &Task->IsRoleDefinition );
  678. } END_SETPROP(bHasChanged);
  679. break;
  680. default:
  681. AzPrint(( AZD_INVPARM, "AzpTaskSetProperty: invalid prop id %ld\n", PropertyId ));
  682. WinStatus = ERROR_INVALID_PARAMETER;
  683. goto Cleanup;
  684. }
  685. //
  686. // Free any local resources
  687. //
  688. Cleanup:
  689. AzpFreeString( &CapturedString );
  690. return WinStatus;
  691. }
  692. DWORD
  693. AzpTaskCheckRefLoop(
  694. IN PAZP_TASK ParentTask,
  695. IN PAZP_TASK CurrentTask,
  696. IN ULONG GenericObjectListOffset
  697. )
  698. /*++
  699. Routine Description:
  700. This routine determines whether the task members of "CurrentTask"
  701. reference "ParentTask". This is done to detect loops where the
  702. task references itself directly or indirectly.
  703. On entry, AzGlResource must be locked shared.
  704. Arguments:
  705. ParentTask - Task that contains the original membership.
  706. CurrentTask - Task that is currently being inspected to see if it
  707. loops back to ParentTask
  708. GenericObjectListOffset - Offset to the particular GenericObjectList being
  709. checked.
  710. Return Value:
  711. Status of the operation
  712. ERROR_DS_LOOP_DETECT - A loop has been detected.
  713. --*/
  714. {
  715. ULONG WinStatus;
  716. PGENERIC_OBJECT_LIST GenericObjectList;
  717. ULONG i;
  718. PAZP_TASK NextTask;
  719. //
  720. // Check for a reference to ourself
  721. //
  722. ASSERT( AzpIsLockedShared( &AzGlResource ) );
  723. if ( ParentTask == CurrentTask ) {
  724. return ERROR_DS_LOOP_DETECT;
  725. }
  726. //
  727. // Compute a pointer to the membership list to check
  728. //
  729. GenericObjectList = (PGENERIC_OBJECT_LIST)
  730. (((LPBYTE)CurrentTask)+GenericObjectListOffset);
  731. //
  732. // Check all tasks that are members of the current task
  733. //
  734. for ( i=0; i<GenericObjectList->GenericObjects.UsedCount; i++ ) {
  735. NextTask = (PAZP_TASK) (GenericObjectList->GenericObjects.Array[i]);
  736. //
  737. // Recursively check this task
  738. //
  739. WinStatus = AzpTaskCheckRefLoop( ParentTask, NextTask, GenericObjectListOffset );
  740. if ( WinStatus != NO_ERROR ) {
  741. return WinStatus;
  742. }
  743. }
  744. return NO_ERROR;
  745. }
  746. DWORD
  747. AzpTaskAddPropertyItem(
  748. IN PGENERIC_OBJECT GenericObject,
  749. IN PGENERIC_OBJECT_LIST GenericObjectList,
  750. IN PGENERIC_OBJECT LinkedToObject
  751. )
  752. /*++
  753. Routine Description:
  754. This routine is the task object specific worker routine for AzAddPropertyItem.
  755. It does any object specific property adds
  756. On entry, AzGlResource must be locked exclusive.
  757. Arguments:
  758. GenericObject - Specifies a pointer to the object to be modified
  759. GenericObjectList - Specifies the object list the object is to be added to
  760. LinkedToObject - Specifies the object that is being linked to
  761. Return Value:
  762. Status of the operation
  763. --*/
  764. {
  765. DWORD WinStatus;
  766. PAZP_TASK Task = (PAZP_TASK) GenericObject;
  767. //
  768. // Initialization
  769. //
  770. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  771. //
  772. // If we're linking to a task,
  773. // Ensure this newly added membership doesn't cause a task membership loop
  774. //
  775. if ( LinkedToObject->ObjectType == OBJECT_TYPE_TASK ) {
  776. WinStatus = AzpTaskCheckRefLoop( Task,
  777. (PAZP_TASK)LinkedToObject,
  778. (ULONG)(((LPBYTE)GenericObjectList)-((LPBYTE)Task)) );
  779. } else {
  780. WinStatus = NO_ERROR;
  781. }
  782. //
  783. // Free any local resources
  784. //
  785. return WinStatus;
  786. }
  787. DWORD
  788. AzpTaskGetGenericChildHead(
  789. IN AZ_HANDLE ParentHandle,
  790. OUT PULONG ObjectType,
  791. OUT PGENERIC_OBJECT_HEAD *GenericChildHead
  792. )
  793. /*++
  794. Routine Description:
  795. This routine determines whether ParentHandle supports Task objects as
  796. children.
  797. Arguments:
  798. ParentHandle - Specifies a handle to the object that is the parent of the role.
  799. This may be an Application Handle or a Scope handle.
  800. ObjectType - Returns the object type of the ParentHandle.
  801. GenericChildHead - Returns a pointer to the head of the list of roles objects
  802. that are children of the object specified by ParentHandle. This in an unverified
  803. pointer. The pointer is only valid after ParentHandle has been validated.
  804. Return Value:
  805. Status of the operation.
  806. --*/
  807. {
  808. DWORD WinStatus;
  809. //
  810. // Determine the type of the parent handle
  811. //
  812. WinStatus = ObGetHandleType( (PGENERIC_OBJECT)ParentHandle,
  813. FALSE, // ignore deleted objects
  814. ObjectType );
  815. if ( WinStatus != NO_ERROR ) {
  816. return WinStatus;
  817. }
  818. //
  819. // Verify that the specified handle support children roles.
  820. //
  821. switch ( *ObjectType ) {
  822. case OBJECT_TYPE_APPLICATION:
  823. *GenericChildHead = &(((PAZP_APPLICATION)ParentHandle)->Tasks);
  824. break;
  825. case OBJECT_TYPE_SCOPE:
  826. *GenericChildHead = &(((PAZP_SCOPE)ParentHandle)->Tasks);
  827. break;
  828. default:
  829. return ERROR_INVALID_HANDLE;
  830. }
  831. return NO_ERROR;
  832. }
  833. DWORD
  834. WINAPI
  835. AzTaskCreate(
  836. IN AZ_HANDLE ParentHandle,
  837. IN LPCWSTR TaskName,
  838. IN DWORD Reserved,
  839. OUT PAZ_HANDLE TaskHandle
  840. )
  841. /*++
  842. Routine Description:
  843. This routine adds a task into the scope of the specified parent object
  844. Arguments:
  845. ParentHandle - Specifies a handle to the object that is the parent of the task.
  846. This may be an Application Handle or a Scope handle.
  847. TaskName - Specifies the name of the task to add.
  848. Reserved - Reserved. Must by zero.
  849. TaskHandle - Return a handle to the task.
  850. The caller must close this handle by calling AzCloseHandle.
  851. Return Value:
  852. NO_ERROR - The operation was successful
  853. ERROR_ALREADY_EXISTS - An object by that name already exists
  854. --*/
  855. {
  856. DWORD WinStatus;
  857. DWORD ObjectType;
  858. PGENERIC_OBJECT_HEAD GenericChildHead;
  859. //
  860. // Determine that the parent handle supports tasks as children
  861. //
  862. WinStatus = AzpTaskGetGenericChildHead( ParentHandle,
  863. &ObjectType,
  864. &GenericChildHead );
  865. if ( WinStatus != NO_ERROR ) {
  866. return WinStatus;
  867. }
  868. //
  869. // Call the common routine to do most of the work
  870. //
  871. return ObCommonCreateObject(
  872. (PGENERIC_OBJECT) ParentHandle,
  873. ObjectType,
  874. GenericChildHead,
  875. OBJECT_TYPE_TASK,
  876. TaskName,
  877. Reserved,
  878. (PGENERIC_OBJECT *) TaskHandle );
  879. }
  880. DWORD
  881. WINAPI
  882. AzTaskOpen(
  883. IN AZ_HANDLE ParentHandle,
  884. IN LPCWSTR TaskName,
  885. IN DWORD Reserved,
  886. OUT PAZ_HANDLE TaskHandle
  887. )
  888. /*++
  889. Routine Description:
  890. This routine opens a task into the scope of the specified parent object.
  891. Arguments:
  892. ParentHandle - Specifies a handle to the object that is the parent of the task.
  893. This may be an Application Handle or a Scope handle.
  894. TaskName - Specifies the name of the task to open
  895. Reserved - Reserved. Must by zero.
  896. TaskHandle - Return a handle to the task.
  897. The caller must close this handle by calling AzCloseHandle.
  898. Return Value:
  899. NO_ERROR - The operation was successful
  900. ERROR_NOT_FOUND - There is no task by that name
  901. --*/
  902. {
  903. DWORD WinStatus;
  904. DWORD ObjectType;
  905. PGENERIC_OBJECT_HEAD GenericChildHead;
  906. //
  907. // Determine that the parent handle supports tasks as children
  908. //
  909. WinStatus = AzpTaskGetGenericChildHead( ParentHandle,
  910. &ObjectType,
  911. &GenericChildHead );
  912. if ( WinStatus != NO_ERROR ) {
  913. return WinStatus;
  914. }
  915. //
  916. // Call the common routine to do most of the work
  917. //
  918. return ObCommonOpenObject(
  919. (PGENERIC_OBJECT) ParentHandle,
  920. ObjectType,
  921. GenericChildHead,
  922. OBJECT_TYPE_TASK,
  923. TaskName,
  924. Reserved,
  925. (PGENERIC_OBJECT *) TaskHandle );
  926. }
  927. DWORD
  928. WINAPI
  929. AzTaskEnum(
  930. IN AZ_HANDLE ParentHandle,
  931. IN DWORD Reserved,
  932. IN OUT PULONG EnumerationContext,
  933. OUT PAZ_HANDLE TaskHandle
  934. )
  935. /*++
  936. Routine Description:
  937. Enumerates all of the tasks for the specified parent object.
  938. Arguments:
  939. ParentHandle - Specifies a handle to the object that is the parent of the task.
  940. This may be an Application Handle or a Scope handle.
  941. Reserved - Reserved. Must by zero.
  942. EnumerationContext - Specifies a context indicating the next task to return
  943. On input for the first call, should point to zero.
  944. On input for subsequent calls, should point to the value returned on the previous call.
  945. On output, returns a value to be passed on the next call.
  946. TaskHandle - Returns a handle to the next task object.
  947. The caller must close this handle by calling AzCloseHandle.
  948. Return Value:
  949. NO_ERROR - The operation was successful (a handle was returned)
  950. ERROR_NO_MORE_ITEMS - No more items were available for enumeration
  951. --*/
  952. {
  953. DWORD WinStatus;
  954. DWORD ObjectType;
  955. PGENERIC_OBJECT_HEAD GenericChildHead;
  956. //
  957. // Determine that the parent handle supports tasks as children
  958. //
  959. WinStatus = AzpTaskGetGenericChildHead( ParentHandle,
  960. &ObjectType,
  961. &GenericChildHead );
  962. if ( WinStatus != NO_ERROR ) {
  963. return WinStatus;
  964. }
  965. //
  966. // Call the common routine to do most of the work
  967. //
  968. return ObCommonEnumObjects(
  969. (PGENERIC_OBJECT) ParentHandle,
  970. ObjectType,
  971. GenericChildHead,
  972. EnumerationContext,
  973. Reserved,
  974. (PGENERIC_OBJECT *) TaskHandle );
  975. }
  976. DWORD
  977. WINAPI
  978. AzTaskDelete(
  979. IN AZ_HANDLE ParentHandle,
  980. IN LPCWSTR TaskName,
  981. IN DWORD Reserved
  982. )
  983. /*++
  984. Routine Description:
  985. This routine deletes a task from the scope of the specified parent object.
  986. Also deletes any child objects of TaskName.
  987. Arguments:
  988. ParentHandle - Specifies a handle to the object that is the parent of the task.
  989. This may be an Application Handle or a Scope handle.
  990. TaskName - Specifies the name of the task to delete.
  991. Reserved - Reserved. Must by zero.
  992. Return Value:
  993. NO_ERROR - The operation was successful
  994. ERROR_NOT_FOUND - An object by that name cannot be found
  995. --*/
  996. {
  997. DWORD WinStatus;
  998. DWORD ObjectType;
  999. PGENERIC_OBJECT_HEAD GenericChildHead;
  1000. //
  1001. // Determine that the parent handle supports tasks as children
  1002. //
  1003. WinStatus = AzpTaskGetGenericChildHead( ParentHandle,
  1004. &ObjectType,
  1005. &GenericChildHead );
  1006. if ( WinStatus != NO_ERROR ) {
  1007. return WinStatus;
  1008. }
  1009. //
  1010. // Call the common routine to do most of the work
  1011. //
  1012. return ObCommonDeleteObject(
  1013. (PGENERIC_OBJECT) ParentHandle,
  1014. ObjectType,
  1015. GenericChildHead,
  1016. OBJECT_TYPE_TASK,
  1017. TaskName,
  1018. Reserved );
  1019. }