6 #include "TaAfsUsrMgr.h"
14 * DEFINITIONS ________________________________________________________________
19 #define iswhite(_ch) ( ((_ch) == TEXT(' ')) || ((_ch) == TEXT('\t')) )
23 * PROTOTYPES _________________________________________________________________
27 DWORD WINAPI Task_ThreadProc (PVOID lp);
29 void Task_Perform (LPTASKPACKET ptp);
31 void Task_OpenCell (LPTASKPACKET ptp);
32 void Task_UpdCreds (LPTASKPACKET ptp);
33 void Task_UpdUsers (LPTASKPACKET ptp);
34 void Task_UpdGroups (LPTASKPACKET ptp);
35 void Task_UpdMachines (LPTASKPACKET ptp);
36 void Task_Refresh (LPTASKPACKET ptp);
37 void Task_RefreshMult (LPTASKPACKET ptp);
38 void Task_Get_Actions (LPTASKPACKET ptp);
39 void Task_Get_Random_Key (LPTASKPACKET ptp);
40 void Task_User_Change (LPTASKPACKET ptp);
41 void Task_User_Find (LPTASKPACKET ptp);
42 void Task_User_Enum (LPTASKPACKET ptp);
43 void Task_User_GroupList_Set (LPTASKPACKET ptp);
44 BOOL Task_User_GroupList_Set_Do (LPUSER_GROUPLIST_SET_PARAMS lpp, ULONG *pStatus);
45 void Task_User_CPW (LPTASKPACKET ptp);
46 void Task_User_Unlock (LPTASKPACKET ptp);
47 void Task_User_Create (LPTASKPACKET ptp);
48 void Task_User_Delete (LPTASKPACKET ptp);
49 void Task_Group_Change (LPTASKPACKET ptp);
50 void Task_Group_Search (LPTASKPACKET ptp);
51 void Task_Group_Members_Get (LPTASKPACKET ptp);
52 void Task_Group_Members_Set (LPTASKPACKET ptp);
53 BOOL Task_Group_Members_Set_Do (LPGROUP_MEMBERS_SET_PARAMS lpp, ULONG *pStatus);
54 void Task_Group_Enum (LPTASKPACKET ptp);
55 void Task_Group_Rename (LPTASKPACKET ptp);
56 void Task_Group_Owned_Get (LPTASKPACKET ptp);
57 void Task_Group_Owned_Set (LPTASKPACKET ptp);
58 BOOL Task_Group_Owned_Set_Do (LPGROUP_OWNED_SET_PARAMS lpp, ULONG *pStatus);
59 void Task_Group_Create (LPTASKPACKET ptp);
60 void Task_Group_Delete (LPTASKPACKET ptp);
61 void Task_Cell_Change (LPTASKPACKET ptp);
62 void Task_List_Translate (LPTASKPACKET ptp);
63 void Task_Object_Listen (LPTASKPACKET ptp);
64 void Task_Object_Get (LPTASKPACKET ptp);
65 void Task_Set_Refresh (LPTASKPACKET ptp);
66 void Task_Expired_Creds (LPTASKPACKET ptp);
68 void WeedAsidList (LPASIDLIST *ppList, BOOL fWantMachines);
69 void TranslateRegExp (LPTSTR pszTarget, LPCTSTR pszSource);
70 BOOL PerformRefresh (LPTASKPACKET ptp, ASID idScope, ULONG *pStatus);
74 * ROUTINES ___________________________________________________________________
78 LPTASKPACKET CreateTaskPacket (int idTask, HWND hReply, PVOID lpUser)
82 if ((ptp = New (TASKPACKET)) != NULL)
84 memset (ptp, 0x00, sizeof(TASKPACKET));
92 if ((ptp->pReturn = New (TASKPACKETDATA)) != NULL)
94 memset (ptp->pReturn, 0x00, sizeof(TASKPACKETDATA));
102 void FreeTaskPacket (LPTASKPACKET ptp)
108 if (TASKDATA(ptp)->pAsidList)
109 asc_AsidListFree (&TASKDATA(ptp)->pAsidList);
110 if (TASKDATA(ptp)->pActionList)
111 asc_ActionListFree (&TASKDATA(ptp)->pActionList);
112 Delete (ptp->pReturn);
119 void PerformTask (LPTASKPACKET ptp)
136 Task_UpdGroups (ptp);
139 case taskUPD_MACHINES:
140 Task_UpdMachines (ptp);
147 case taskREFRESHMULT:
148 Task_RefreshMult (ptp);
151 case taskGET_ACTIONS:
152 Task_Get_Actions (ptp);
155 case taskGET_RANDOM_KEY:
156 Task_Get_Random_Key (ptp);
159 case taskUSER_CHANGE:
160 Task_User_Change (ptp);
164 Task_User_Find (ptp);
168 Task_User_Enum (ptp);
171 case taskUSER_GROUPLIST_SET:
172 Task_User_GroupList_Set (ptp);
179 case taskUSER_UNLOCK:
180 Task_User_Unlock (ptp);
183 case taskUSER_CREATE:
184 Task_User_Create (ptp);
187 case taskUSER_DELETE:
188 Task_User_Delete (ptp);
191 case taskGROUP_CHANGE:
192 Task_Group_Change (ptp);
195 case taskGROUP_SEARCH:
196 Task_Group_Search (ptp);
199 case taskGROUP_MEMBERS_GET:
200 Task_Group_Members_Get (ptp);
203 case taskGROUP_MEMBERS_SET:
204 Task_Group_Members_Set (ptp);
208 Task_Group_Enum (ptp);
211 case taskGROUP_RENAME:
212 Task_Group_Rename (ptp);
215 case taskGROUP_OWNED_GET:
216 Task_Group_Owned_Get (ptp);
219 case taskGROUP_OWNED_SET:
220 Task_Group_Owned_Set (ptp);
223 case taskGROUP_CREATE:
224 Task_Group_Create (ptp);
227 case taskGROUP_DELETE:
228 Task_Group_Delete (ptp);
231 case taskCELL_CHANGE:
232 Task_Cell_Change (ptp);
235 case taskLIST_TRANSLATE:
236 Task_List_Translate (ptp);
239 case taskOBJECT_LISTEN:
240 Task_Object_Listen (ptp);
244 Task_Object_Get (ptp);
247 case taskSET_REFRESH:
248 Task_Set_Refresh (ptp);
251 case taskEXPIRED_CREDS:
252 Task_Expired_Creds (ptp);
257 ptp->status = ERROR_INVALID_FUNCTION;
264 * KEYS _______________________________________________________________________
268 HASHVALUE CALLBACK Key_Asid_HashData (LPHASHLISTKEY pKey, PVOID pData)
270 return *(ASID*)pData;
273 HASHVALUE CALLBACK Key_Asid_HashObject (LPHASHLISTKEY pKey, PVOID pObject)
275 return Key_Asid_HashData (pKey, (ASID*)pObject);
278 BOOL CALLBACK Key_Asid_Compare (LPHASHLISTKEY pKey, PVOID pObject, PVOID pData)
280 return ((*(ASID*)pObject) == (*(ASID*)pData));
285 * TASKS ______________________________________________________________________
289 void Task_OpenCell (LPTASKPACKET ptp)
291 LPOPENCELL_PARAMS lpp = (LPOPENCELL_PARAMS)( ptp->lpUser );
293 Display_StartWorking();
295 // Try to open the cell for administration
297 ptp->rc = asc_CellOpen (g.idClient, lpp->hCreds, lpp->szCell, AFSADMSVR_SCOPE_USERS, &TASKDATA(ptp)->idCell, &ptp->status);
301 PostMessage (g.hMain, WM_SHOW_YOURSELF, 0, 1);
303 else if ((!ptp->rc) && (!IsWindow(ptp->hReply)))
305 if (lpp->fCloseAppOnFail)
306 FatalErrorDialog (ptp->status, IDS_ERROR_CANT_OPEN_CELL, TEXT("%s"), lpp->szCell);
308 ErrorDialog (ptp->status, IDS_ERROR_CANT_OPEN_CELL, TEXT("%s"), lpp->szCell);
311 // If we previously had another cell open, close it.
320 (void)asc_CellClose (g.idClient, g.idCell, &status);
322 g.idCell = TASKDATA(ptp)->idCell;
327 // Update the "Selected Cell:" text on the main window
329 TCHAR szCell[ cchNAME ];
331 GetString (szCell, IDS_CELL_NONE);
332 else if (!asc_CellNameGet_Fast (g.idClient, g.idCell, szCell))
333 GetString (szCell, IDS_CELL_NONE);
334 SetDlgItemText (g.hMain, IDC_CELL, szCell);
335 ShowCurrentCredentials();
337 // Oh--also, set the refresh rate for the newly-opened cell
340 asc_CellRefreshRateSet (g.idClient, g.idCell, gr.cminRefreshRate, &dummy);
342 // Start re-populating the Users or Groups tab (whichever is showing)
344 Display_PopulateList();
346 Display_StopWorking();
348 // When we've opened a new cell, it's time to open the Actions window.
351 PostMessage (g.hMain, WM_SHOW_ACTIONS, 0, 0);
354 ptp->lpUser = 0; // we freed this; don't let the caller use it again
358 void Task_UpdCreds (LPTASKPACKET ptp)
360 // Update the display to report our new credentials
362 ShowCurrentCredentials();
364 // Tell the admin server to use our new credentials, and refresh everything
366 if (!asc_CredentialsPush (g.idClient, g.hCreds, g.idCell, &ptp->status))
369 ptp->rc = PerformRefresh (ptp, g.idCell, &ptp->status);
373 void Task_UpdUsers (LPTASKPACKET ptp)
375 // First we'll query the admin server to find a list of all users which
376 // match our search pattern.
378 lstrcpy (TASKDATA(ptp)->szPattern, g.szPatternUsers);
380 TCHAR szRegExp[ cchNAME ];
381 TranslateRegExp (szRegExp, TASKDATA(ptp)->szPattern);
382 if (!asc_ObjectFindMultiple (g.idClient, g.idCell, TYPE_USER, szRegExp, &gr.SearchUsers, &TASKDATA(ptp)->pAsidList, &ptp->status))
385 // If we got a result back, weed out any entries that look like machines.
389 WeedAsidList (&TASKDATA(ptp)->pAsidList, FALSE);
392 // Wow, that was easy. Okay, next step: ensure that we have properties
393 // for all these guys in the local cache--to do that, we'll query their
394 // properties, then free the result.
398 LPASOBJPROPLIST pPropList = NULL;
399 if (!asc_ObjectPropertiesGetMultiple (g.idClient, GET_ALL_DATA, g.idCell, TASKDATA(ptp)->pAsidList, &pPropList, &ptp->status))
402 asc_ObjPropListFree (&pPropList);
407 void Task_UpdGroups (LPTASKPACKET ptp)
409 // First we'll query the admin server to find a list of all groups which
410 // match our search pattern.
412 lstrcpy (TASKDATA(ptp)->szPattern, g.szPatternGroups);
414 TCHAR szRegExp[ cchNAME ];
415 TranslateRegExp (szRegExp, TASKDATA(ptp)->szPattern);
416 if (!asc_ObjectFindMultiple (g.idClient, g.idCell, TYPE_GROUP, szRegExp, NULL, &TASKDATA(ptp)->pAsidList, &ptp->status))
419 // Wow, that was easy. Okay, next step: ensure that we have properties
420 // for all these guys in the local cache--to do that, we'll query their
421 // properties, then free the result.
425 LPASOBJPROPLIST pPropList = NULL;
426 if (!asc_ObjectPropertiesGetMultiple (g.idClient, GET_ALL_DATA, g.idCell, TASKDATA(ptp)->pAsidList, &pPropList, &ptp->status))
429 asc_ObjPropListFree (&pPropList);
434 void Task_UpdMachines (LPTASKPACKET ptp)
436 // First we'll query the admin server to find a list of all users which
437 // match our search pattern.
439 TCHAR szRegExp[ cchNAME ];
440 if (g.szPatternMachines[0])
441 TranslateRegExp (szRegExp, g.szPatternMachines);
443 lstrcpy (szRegExp, TEXT("^[0-9.]*$"));
445 if (!asc_ObjectFindMultiple (g.idClient, g.idCell, TYPE_USER, szRegExp, NULL, &TASKDATA(ptp)->pAsidList, &ptp->status))
448 lstrcpy (TASKDATA(ptp)->szPattern, g.szPatternMachines);
450 // If we got a result back, weed out any entries that don't look
455 WeedAsidList (&TASKDATA(ptp)->pAsidList, TRUE);
458 // Wow, that was easy. Okay, next step: ensure that we have properties
459 // for all these guys in the local cache--to do that, we'll query their
460 // properties, then free the result.
464 LPASOBJPROPLIST pPropList = NULL;
465 if (!asc_ObjectPropertiesGetMultiple (g.idClient, GET_ALL_DATA, g.idCell, TASKDATA(ptp)->pAsidList, &pPropList, &ptp->status))
468 asc_ObjPropListFree (&pPropList);
474 void Task_Refresh (LPTASKPACKET ptp)
476 ASID idScope = (ASID)( ptp->lpUser );
478 ptp->rc = PerformRefresh (ptp, idScope, &ptp->status);
482 void Task_RefreshMult (LPTASKPACKET ptp)
484 LPASIDLIST pAsidList = (LPASIDLIST)( ptp->lpUser );
486 // Invalidate the admin server's cached information about the specified
487 // object. Remember that this is recursive hierarchically: if you pass
488 // in a cell's ID, for instance, information about all users, groups,
489 // servers, services, partitions and volumes anywhere in that cell will
492 ptp->rc = asc_ObjectRefreshMultiple (g.idClient, g.idCell, pAsidList, &ptp->status);
494 // The Refresh call above just made us invalidate the status for one or
495 // more objects; to get the display to reflect the changes, we'll have to
496 // query the server for the latest properties for those objects. Once that's
497 // done, we'll just redraw the main window and it will pick up the changes.
502 LPASOBJPROPLIST pPropList = NULL;
503 if (asc_ObjectPropertiesGetMultiple (g.idClient, GET_ALL_DATA, g.idCell, pAsidList, &pPropList, &status))
505 // That call returned properties for the objects; we don't need
506 // the properties here--we just wanted to get them in the cache.
507 // Now that they're in the cache, redrawing the main window will
508 // cause the latest data to be displayed.
511 asc_ObjPropListFree (&pPropList);
512 Display_RefreshView_Fast();
516 asc_AsidListFree (&pAsidList);
517 ptp->lpUser = 0; // we freed this; don't let the caller use it again
521 void Task_Get_Actions (LPTASKPACKET ptp)
523 // Query the admin server to get a current list of operations-in-progress.
524 // We'll limit our search to operations being performed on this cell.
526 ptp->rc = asc_ActionGetMultiple (g.idClient, 0, g.idCell, &TASKDATA(ptp)->pActionList, &ptp->status);
530 void Task_Get_Random_Key (LPTASKPACKET ptp)
532 ptp->rc = asc_RandomKeyGet (g.idClient, g.idCell, TASKDATA(ptp)->key, &ptp->status);
534 if (!ptp->rc && !IsWindow(ptp->hReply))
536 ErrorDialog (ptp->status, IDS_ERROR_CANT_GET_RANDOM_KEY);
541 void Task_User_Change (LPTASKPACKET ptp)
543 LPUSER_CHANGE_PARAMS lpp = (LPUSER_CHANGE_PARAMS)( ptp->lpUser );
545 if ((ptp->rc = asc_UserChange (g.idClient, g.idCell, lpp->idUser, &lpp->NewProperties, &ptp->status)) == TRUE)
547 Display_RefreshView_Fast();
550 if (!ptp->rc && !IsWindow (ptp->hReply))
552 TCHAR szUser[ cchNAME ];
553 User_GetDisplayName (szUser, lpp->idUser);
554 ErrorDialog (ptp->status, IDS_ERROR_CANT_CHANGE_USER, TEXT("%s"), szUser);
558 ptp->lpUser = 0; // we freed this; don't let the caller use it again
562 void Task_User_Find (LPTASKPACKET ptp)
564 LPTSTR pszName = (LPTSTR)( ptp->lpUser );
566 if ((ptp->rc = asc_ObjectFind (g.idClient, g.idCell, TYPE_USER, pszName, &TASKDATA(ptp)->idObject, &ptp->status)) == TRUE)
568 ptp->rc = asc_ObjectPropertiesGet (g.idClient, GET_ALL_DATA, g.idCell, TASKDATA(ptp)->idObject, &TASKDATA(ptp)->Properties, &ptp->status);
571 FreeString (pszName);
572 ptp->lpUser = 0; // we freed this; don't let the caller use it again
576 void Task_User_Enum (LPTASKPACKET ptp)
578 LPCTSTR pszPattern = (LPCTSTR)( ptp->lpUser );
580 TCHAR szRegExp[ cchNAME ];
581 TranslateRegExp (szRegExp, pszPattern);
582 if ((ptp->rc = asc_ObjectFindMultiple (g.idClient, g.idCell, TYPE_USER, szRegExp, NULL, &TASKDATA(ptp)->pAsidList, &ptp->status)) == TRUE)
584 LPASOBJPROPLIST pPropList = NULL;
586 ptp->rc = asc_ObjectPropertiesGetMultiple (g.idClient, GET_RUDIMENTARY_DATA, g.idCell, TASKDATA(ptp)->pAsidList, &pPropList, &ptp->status);
589 asc_ObjPropListFree (&pPropList);
592 FreeString (pszPattern);
593 ptp->lpUser = 0; // we freed this; don't let the caller use it again
597 void Task_User_GroupList_Set (LPTASKPACKET ptp)
599 LPUSER_GROUPLIST_SET_PARAMS lpp = (LPUSER_GROUPLIST_SET_PARAMS)( ptp->lpUser );
601 ptp->rc = Task_User_GroupList_Set_Do (lpp, &ptp->status);
603 asc_AsidListFree (&lpp->pUsers);
604 asc_AsidListFree (&lpp->pGroups);
606 ptp->lpUser = 0; // we freed this; don't let the caller use it again
610 BOOL Task_User_GroupList_Set_Do (LPUSER_GROUPLIST_SET_PARAMS lpp, ULONG *pStatus)
614 // Maintain a structure describing any errors we encounter, so we can give
615 // a reasonable error dialog if need be.
617 LPERRORDATA ped = ED_Create (IDS_ERROR_CANT_SET_GROUPS, IDS_ERROR_CANT_SET_GROUPS_MULTIPLE);
619 // We'll need the supplied group-list in a hashlist, so we can quickly
620 // test it for inclusion of a particular group.
622 LPHASHLIST pGroupsAllow = New (HASHLIST);
623 for (size_t iGroup = 0; iGroup < lpp->pGroups->cEntries; ++iGroup)
624 pGroupsAllow->AddUnique ((PVOID)(lpp->pGroups->aEntries[ iGroup ].idObject));
626 // We'll have to do this next bit for each user in the supplied user-list
628 for (size_t iUser = 0; iUser < lpp->pUsers->cEntries; ++iUser)
632 // Obtain the appropriate current list of groups for this user
634 LPASIDLIST pGroupsOld = NULL;
635 if (lpp->fMembership)
637 if (!asc_GroupMembershipGet (g.idClient, g.idCell, lpp->pUsers->aEntries[ iUser ].idObject, &pGroupsOld, &status))
639 ED_RegisterStatus (ped, lpp->pUsers->aEntries[ iUser ].idObject, FALSE, status);
643 else // (!lpp->fMembership)
645 if (!asc_GroupOwnershipGet (g.idClient, g.idCell, lpp->pUsers->aEntries[ iUser ].idObject, &pGroupsOld, &status))
647 ED_RegisterStatus (ped, lpp->pUsers->aEntries[ iUser ].idObject, FALSE, status);
654 // Test each group in that current list to see if it's also on our
655 // pGroupsAllow list. If not, remove it.
657 for (iGroup = 0; iGroup < pGroupsOld->cEntries; ++iGroup)
659 if (pGroupsAllow->fIsInList ((PVOID)(pGroupsOld->aEntries[iGroup].idObject)))
662 if (lpp->fMembership)
664 if (!asc_GroupMemberRemove (g.idClient, g.idCell, pGroupsOld->aEntries[iGroup].idObject, lpp->pUsers->aEntries[iUser].idObject, &status))
665 ED_RegisterStatus (ped, lpp->pUsers->aEntries[ iUser ].idObject, FALSE, status);
667 else // (!lpp->fMembership)
669 ASOBJPROP Properties;
670 if (asc_ObjectPropertiesGet (g.idClient, GET_ALL_DATA, g.idCell, pGroupsOld->aEntries[iGroup].idObject, &Properties, &status))
672 AFSADMSVR_CHANGEGROUP_PARAMS pp;
673 memset (&pp, 0x00, sizeof(pp));
674 lstrcpy (pp.szOwner, Properties.szName); // make group self-owned
675 pp.aaListStatus = Properties.u.GroupProperties.aaListStatus;
676 pp.aaListGroupsOwned = Properties.u.GroupProperties.aaListGroupsOwned;
677 pp.aaListMembers = Properties.u.GroupProperties.aaListMembers;
678 pp.aaAddMember = Properties.u.GroupProperties.aaAddMember;
679 pp.aaDeleteMember = Properties.u.GroupProperties.aaDeleteMember;
680 if (!asc_GroupChange (g.idClient, g.idCell, pGroupsOld->aEntries[iGroup].idObject, &pp, &status))
681 ED_RegisterStatus (ped, lpp->pUsers->aEntries[ iUser ].idObject, FALSE, status);
686 // Now the more complex part: see if there are any groups in the
687 // supplied group-list which are marked as mandatory, but which
688 // aren't in our pGroupsOld list. We'll need to put the latter in a
689 // hashlist for this...
691 LPHASHLIST pGroupsOldList = New (HASHLIST);
692 for (iGroup = 0; iGroup < pGroupsOld->cEntries; ++iGroup)
693 pGroupsOldList->AddUnique ((PVOID)(pGroupsOld->aEntries[ iGroup ].idObject));
695 for (iGroup = 0; iGroup < lpp->pGroups->cEntries; ++iGroup)
697 if (!lpp->pGroups->aEntries[ iGroup ].lParam)
698 continue; // group not mandatory
699 if (pGroupsOldList->fIsInList ((PVOID)(lpp->pGroups->aEntries[ iGroup ].idObject)))
700 continue; // already a member
702 if (lpp->fMembership)
704 if (!asc_GroupMemberAdd (g.idClient, g.idCell, lpp->pGroups->aEntries[iGroup].idObject, lpp->pUsers->aEntries[iUser].idObject, &status))
705 ED_RegisterStatus (ped, lpp->pUsers->aEntries[ iUser ].idObject, FALSE, status);
707 else // (!lpp->fMembership)
709 ASOBJPROP Properties;
710 if (asc_ObjectPropertiesGet (g.idClient, GET_ALL_DATA, g.idCell, lpp->pGroups->aEntries[iGroup].idObject, &Properties, &status))
712 AFSADMSVR_CHANGEGROUP_PARAMS pp;
713 memset (&pp, 0x00, sizeof(pp));
714 pp.aaListStatus = Properties.u.GroupProperties.aaListStatus;
715 pp.aaListGroupsOwned = Properties.u.GroupProperties.aaListGroupsOwned;
716 pp.aaListMembers = Properties.u.GroupProperties.aaListMembers;
717 pp.aaAddMember = Properties.u.GroupProperties.aaAddMember;
718 pp.aaDeleteMember = Properties.u.GroupProperties.aaDeleteMember;
720 if (asc_ObjectNameGet_Fast (g.idClient, g.idCell, lpp->pUsers->aEntries[iUser].idObject, pp.szOwner, &status))
722 if (!asc_GroupChange (g.idClient, g.idCell, lpp->pGroups->aEntries[iGroup].idObject, &pp, &status))
723 ED_RegisterStatus (ped, lpp->pUsers->aEntries[ iUser ].idObject, FALSE, status);
729 Delete (pGroupsOldList);
730 asc_AsidListFree (&pGroupsOld);
733 // If there were any errors, report them.
735 if ((*pStatus = ED_GetFinalStatus(ped)) != 0)
738 ED_ShowErrorDialog(ped);
744 Delete (pGroupsAllow);
749 void Task_User_CPW (LPTASKPACKET ptp)
751 LPUSER_CPW_PARAMS lpp = (LPUSER_CPW_PARAMS)( ptp->lpUser );
753 ptp->rc = asc_UserPasswordSet (g.idClient, g.idCell, lpp->idUser, lpp->keyVersion, lpp->keyString, lpp->keyData, &ptp->status);
755 if ((!ptp->rc) && (!IsWindow(ptp->hReply)))
757 TCHAR szName[ cchNAME ];
758 User_GetDisplayName (szName, lpp->idUser);
759 ErrorDialog (ptp->status, IDS_ERROR_CANT_CHANGE_PASSWORD, TEXT("%s"), szName);
763 ptp->lpUser = 0; // we freed this; don't let the caller use it again
767 void Task_User_Unlock (LPTASKPACKET ptp)
769 LPASIDLIST pUserList = (LPASIDLIST)( ptp->lpUser );
771 // Maintain a structure describing any errors we encounter, so we can give
772 // a reasonable error dialog if need be.
774 LPERRORDATA ped = ED_Create (IDS_ERROR_CANT_UNLOCK, IDS_ERROR_CANT_UNLOCK_MULTIPLE);
776 // Try to unlock the users' accounts...
778 for (size_t iUser = 0; iUser < pUserList->cEntries; ++iUser)
780 if (!asc_UserUnlock (g.idClient, g.idCell, pUserList->aEntries[ iUser ].idObject, &ptp->status))
781 ED_RegisterStatus (ped, pUserList->aEntries[ iUser ].idObject, FALSE, ptp->status);
784 // If there were any errors, report them.
786 if (ED_GetFinalStatus(ped) && !IsWindow(ptp->hReply))
787 ED_ShowErrorDialog(ped);
790 asc_AsidListFree (&pUserList);
791 ptp->lpUser = 0; // we freed this; don't let the caller use it again
795 void Task_User_Create (LPTASKPACKET ptp)
797 LPUSER_CREATE_PARAMS lpp = (LPUSER_CREATE_PARAMS)(ptp->lpUser);
799 // We may actually have been asked to create more than one user here;
800 // the {lpp->mszNames} parameter is a multi-string. So everything we
801 // do, we'll do for each new user-name...
803 for (LPTSTR pszName = lpp->mszNames; pszName && *pszName; pszName += 1+lstrlen(pszName))
805 // First create this new user account
809 AFSADMSVR_CREATEUSER_PARAMS pp;
810 memset (&pp, 0x00, sizeof(AFSADMSVR_CREATEUSER_PARAMS));
811 User_SplitDisplayName (pszName, pp.szName, pp.szInstance);
812 lstrcpy (pp.szPassword, lpp->szPassword);
813 pp.idUser = lpp->idUser;
814 pp.fCreateKAS = lpp->fCreateKAS;
815 pp.fCreatePTS = lpp->fCreatePTS;
816 if ((ptp->rc = asc_UserCreate (g.idClient, g.idCell, &pp, &idUser, &ptp->status)) == FALSE)
818 if (!IsWindow (ptp->hReply))
819 ErrorDialog (ptp->status, IDS_ERROR_CANT_CREATE_USER, TEXT("%s"), pszName);
823 // Then change its properties to be what we want
825 if ((ptp->rc = asc_UserChange (g.idClient, g.idCell, idUser, &lpp->Properties, &ptp->status)) == FALSE)
827 if (!IsWindow (ptp->hReply))
828 ErrorDialog (ptp->status, IDS_ERROR_CANT_CHANGE_USER, TEXT("%s"), pszName);
833 // Finally update its lists of groups
835 if (lpp->pGroupsMember)
837 USER_GROUPLIST_SET_PARAMS pp;
838 memset (&pp, 0x00, sizeof(USER_GROUPLIST_SET_PARAMS));
839 asc_AsidListCreate (&pp.pUsers);
840 asc_AsidListAddEntry (&pp.pUsers, idUser, 0);
841 asc_AsidListCopy (&pp.pGroups, &lpp->pGroupsMember);
842 pp.fMembership = TRUE;
843 ptp->rc = Task_User_GroupList_Set_Do (&pp, &ptp->status);
844 asc_AsidListFree (&pp.pUsers);
845 asc_AsidListFree (&pp.pGroups);
847 if (lpp->pGroupsOwner)
849 USER_GROUPLIST_SET_PARAMS pp;
850 memset (&pp, 0x00, sizeof(USER_GROUPLIST_SET_PARAMS));
851 asc_AsidListCreate (&pp.pUsers);
852 asc_AsidListAddEntry (&pp.pUsers, idUser, 0);
853 asc_AsidListCopy (&pp.pGroups, &lpp->pGroupsOwner);
854 pp.fMembership = FALSE;
855 ptp->rc = Task_User_GroupList_Set_Do (&pp, &ptp->status);
856 asc_AsidListFree (&pp.pUsers);
857 asc_AsidListFree (&pp.pGroups);
863 Display_PopulateList();
865 if (lpp->pGroupsOwner)
866 asc_AsidListFree (&lpp->pGroupsOwner);
867 if (lpp->pGroupsMember)
868 asc_AsidListFree (&lpp->pGroupsMember);
870 FreeString (lpp->mszNames);
872 ptp->lpUser = 0; // we freed this; don't let the caller use it again
876 void Task_User_Delete (LPTASKPACKET ptp)
878 LPUSER_DELETE_PARAMS lpp = (LPUSER_DELETE_PARAMS)(ptp->lpUser);
880 // Maintain a structure describing any errors we encounter, so we can give
881 // a reasonable error dialog if need be.
883 LPERRORDATA ped = ED_Create (IDS_ERROR_CANT_DELETE_USER, IDS_ERROR_CANT_DELETE_USER_MULTIPLE);
885 // Go through and delete these users
887 for (size_t iUser = 0; iUser < lpp->pUserList->cEntries; ++iUser)
889 AFSADMSVR_DELETEUSER_PARAMS pp;
890 memset (&pp, 0x00, sizeof(pp));
891 pp.fDeleteKAS = lpp->fDeleteKAS;
892 pp.fDeletePTS = lpp->fDeletePTS;
895 if (!asc_UserDelete (g.idClient, g.idCell, lpp->pUserList->aEntries[iUser].idObject, &pp, &status))
896 ED_RegisterStatus (ped, lpp->pUserList->aEntries[iUser].idObject, FALSE, status);
899 // If there were any errors, report them.
901 if (ED_GetFinalStatus(ped) && !IsWindow(ptp->hReply))
902 ED_ShowErrorDialog(ped);
907 Display_PopulateList();
910 asc_AsidListFree (&lpp->pUserList);
912 ptp->lpUser = 0; // we freed this; don't let the caller use it again
916 void Task_Group_Change (LPTASKPACKET ptp)
918 LPGROUP_CHANGE_PARAMS lpp = (LPGROUP_CHANGE_PARAMS)( ptp->lpUser );
920 if ((ptp->rc = asc_GroupChange (g.idClient, g.idCell, lpp->idGroup, &lpp->NewProperties, &ptp->status)) == TRUE)
922 Display_RefreshView_Fast();
925 if (!ptp->rc && !IsWindow (ptp->hReply))
927 TCHAR szGroup[ cchNAME ];
928 asc_ObjectNameGet_Fast (g.idClient, g.idCell, lpp->idGroup, szGroup);
929 ErrorDialog (ptp->status, IDS_ERROR_CANT_CHANGE_GROUP, TEXT("%s"), szGroup);
933 ptp->lpUser = 0; // we freed this; don't let the caller use it again
937 void Task_Group_Search (LPTASKPACKET ptp)
939 LPGROUP_SEARCH_PARAMS lpp = (LPGROUP_SEARCH_PARAMS)( ptp->lpUser );
941 // Prepare an intermediate place for us to put the results of our search.
942 // We'll be doing lots of work in this intermediate list, so it'll be
943 // implemented as a hashlist with a key over the objects' ASIDs.
949 } GROUP_SEARCH_FOUND, *LPGROUP_SEARCH_FOUND;
951 LPHASHLIST pListGroups = New (HASHLIST);
952 LPHASHLISTKEY pListKeyAsid = pListGroups->CreateKey ("ASID", Key_Asid_Compare, Key_Asid_HashObject, Key_Asid_HashData);
954 // Search through the appropriate groups for each user in the list
956 for (size_t iUser = 0; iUser < lpp->pUserList->cEntries; ++iUser)
958 LPASIDLIST pGroups = NULL;
961 if (lpp->fMembership)
963 if (!asc_GroupMembershipGet (g.idClient, g.idCell, lpp->pUserList->aEntries[ iUser ].idObject, &pGroups, &status))
966 else // (!lpp->fMembership)
968 if (!asc_GroupOwnershipGet (g.idClient, g.idCell, lpp->pUserList->aEntries[ iUser ].idObject, &pGroups, &status))
974 // For each group we found, make sure the group is in the big
975 // list we'll be returning. Use the {lParam} field of the
976 // list's entry as a counter, to remember how many users have
979 for (size_t iGroup = 0; iGroup < pGroups->cEntries; ++iGroup)
981 // Is it in the list already? If not, add it.
983 LPGROUP_SEARCH_FOUND pFind;
984 if ((pFind = (LPGROUP_SEARCH_FOUND)pListKeyAsid->GetFirstObject (&pGroups->aEntries[ iGroup ].idObject)) != NULL)
990 pFind = New (GROUP_SEARCH_FOUND);
991 pFind->idGroup = pGroups->aEntries[ iGroup ].idObject;
993 pListGroups->Add (pFind);
997 asc_AsidListFree (&pGroups);
1001 // Now that we have a list of groups that match our search criteria,
1002 // stick it in an ASID list. The lParam field for each ASID will be set
1003 // to 1 if all users have that group, or 0 if only some have it.
1005 if (!asc_AsidListCreate (&TASKDATA(ptp)->pAsidList))
1008 ptp->status = ERROR_NOT_ENOUGH_MEMORY;
1013 for (LPENUM pEnum = pListGroups->FindFirst(); pEnum; pEnum = pEnum->FindNext())
1015 LPGROUP_SEARCH_FOUND pFind = (LPGROUP_SEARCH_FOUND)( pEnum->GetObject() );
1017 asc_AsidListAddEntry (&TASKDATA(ptp)->pAsidList, pFind->idGroup, (LPARAM)( (pFind->cUsers == lpp->pUserList->cEntries) ? 1 : 0 ));
1019 pListGroups->Remove (pFind);
1023 TASKDATA(ptp)->fMembership = lpp->fMembership;
1026 // Now that we have an ASID list full of groups to return, make sure we
1027 // have rudimentary properties for all those groups.
1032 asc_AsidListCopy (&pList, &TASKDATA(ptp)->pAsidList);
1034 LPASOBJPROPLIST pPropList = NULL;
1035 if (!asc_ObjectPropertiesGetMultiple (g.idClient, GET_RUDIMENTARY_DATA, g.idCell, pList, &pPropList, &ptp->status))
1038 asc_ObjPropListFree (&pPropList);
1040 asc_AsidListFree (&pList);
1044 Delete (pListGroups);
1045 asc_AsidListFree (&lpp->pUserList);
1047 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1051 void Task_Group_Members_Get (LPTASKPACKET ptp)
1053 LPASIDLIST pGroups = (LPASIDLIST)( ptp->lpUser );
1055 // Prepare an intermediate place for us to put the results of our search.
1056 // We'll be doing lots of work in this intermediate list, so it'll be
1057 // implemented as a hashlist with a key over the objects' ASIDs.
1063 } GROUP_MEMBER_FOUND, *LPGROUP_MEMBER_FOUND;
1065 LPHASHLIST pListUsers = New (HASHLIST);
1066 LPHASHLISTKEY pListKeyAsid = pListUsers->CreateKey ("ASID", Key_Asid_Compare, Key_Asid_HashObject, Key_Asid_HashData);
1068 // For each group in the list, find all of that group's members
1070 for (size_t iGroup = 0; iGroup < pGroups->cEntries; ++iGroup)
1072 LPASIDLIST pMembers = NULL;
1075 if (!asc_GroupMembersGet (g.idClient, g.idCell, pGroups->aEntries[ iGroup ].idObject, &pMembers, &status))
1080 // For each member we found, make sure the member is in the big
1081 // list we'll be returning. Use the {lParam} field of the
1082 // list's entry as a counter, to remember how many groups have
1085 for (size_t iMember = 0; iMember < pMembers->cEntries; ++iMember)
1087 // Is it in the list already? If not, add it.
1089 LPGROUP_MEMBER_FOUND pFind;
1090 if ((pFind = (LPGROUP_MEMBER_FOUND)pListKeyAsid->GetFirstObject (&pMembers->aEntries[ iMember ].idObject)) != NULL)
1096 pFind = New (GROUP_MEMBER_FOUND);
1097 pFind->idUser = pMembers->aEntries[ iMember ].idObject;
1099 pListUsers->Add (pFind);
1103 asc_AsidListFree (&pMembers);
1107 // Now that we have a list of users that match our search criteria,
1108 // stick it in an ASID list. The lParam field for each ASID will be set
1109 // to 1 if all groups have that member, or 0 if only some have it.
1111 if (!asc_AsidListCreate (&TASKDATA(ptp)->pAsidList))
1114 ptp->status = ERROR_NOT_ENOUGH_MEMORY;
1119 for (LPENUM pEnum = pListUsers->FindFirst(); pEnum; pEnum = pEnum->FindNext())
1121 LPGROUP_MEMBER_FOUND pFind = (LPGROUP_MEMBER_FOUND)( pEnum->GetObject() );
1123 asc_AsidListAddEntry (&TASKDATA(ptp)->pAsidList, pFind->idUser, (LPARAM)( (pFind->cGroups == pGroups->cEntries) ? 1 : 0 ));
1125 pListUsers->Remove (pFind);
1130 // Now that we have an ASID list full of users to return, make sure we
1131 // have rudimentary properties for all those users.
1136 asc_AsidListCopy (&pList, &TASKDATA(ptp)->pAsidList);
1138 LPASOBJPROPLIST pPropList = NULL;
1139 if (!asc_ObjectPropertiesGetMultiple (g.idClient, GET_RUDIMENTARY_DATA, g.idCell, pList, &pPropList, &ptp->status))
1142 asc_ObjPropListFree (&pPropList);
1144 asc_AsidListFree (&pList);
1148 Delete (pListUsers);
1149 asc_AsidListFree (&pGroups);
1150 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1154 void Task_Group_Members_Set (LPTASKPACKET ptp)
1156 LPGROUP_MEMBERS_SET_PARAMS lpp = (LPGROUP_MEMBERS_SET_PARAMS)( ptp->lpUser );
1158 ptp->rc = Task_Group_Members_Set_Do (lpp, &ptp->status);
1160 asc_AsidListFree (&lpp->pGroups);
1161 asc_AsidListFree (&lpp->pMembers);
1163 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1167 BOOL Task_Group_Members_Set_Do (LPGROUP_MEMBERS_SET_PARAMS lpp, ULONG *pStatus)
1171 // Maintain a structure describing any errors we encounter, so we can give
1172 // a reasonable error dialog if need be.
1174 LPERRORDATA ped = ED_Create (IDS_ERROR_CANT_SET_MEMBERS, IDS_ERROR_CANT_SET_MEMBERS_MULTIPLE);
1176 // We'll need the supplied member-list in a hashlist, so we can quickly
1177 // test it to see if a particular member should remain in a group.
1179 LPHASHLIST pMembersAllow = New (HASHLIST);
1180 for (size_t iMember = 0; iMember < lpp->pMembers->cEntries; ++iMember)
1181 pMembersAllow->AddUnique ((PVOID)(lpp->pMembers->aEntries[ iMember ].idObject));
1183 // We'll have to do this next bit for each group in the supplied group-list
1185 for (size_t iGroup = 0; iGroup < lpp->pGroups->cEntries; ++iGroup)
1189 // Obtain the current list of members for this group
1191 LPASIDLIST pMembersOld = NULL;
1192 if (!asc_GroupMembersGet (g.idClient, g.idCell, lpp->pGroups->aEntries[ iGroup ].idObject, &pMembersOld, &status))
1194 ED_RegisterStatus (ped, lpp->pGroups->aEntries[ iGroup ].idObject, FALSE, status);
1200 // Test each member in that current list to see if it's also on our
1201 // pMembersAllow list. If not, remove it.
1203 for (iMember = 0; iMember < pMembersOld->cEntries; ++iMember)
1205 if (pMembersAllow->fIsInList ((PVOID)(pMembersOld->aEntries[iMember].idObject)))
1208 if (!asc_GroupMemberRemove (g.idClient, g.idCell, lpp->pGroups->aEntries[iGroup].idObject, pMembersOld->aEntries[iMember].idObject, &status))
1209 ED_RegisterStatus (ped, lpp->pGroups->aEntries[ iGroup ].idObject, FALSE, status);
1212 // Now the more complex part: see if there are any members in the
1213 // supplied member-list which are marked as mandatory, but which
1214 // aren't in our pMembersOld list. We'll need to put the latter in a
1215 // hashlist for this...
1217 LPHASHLIST pMembersOldList = New (HASHLIST);
1218 for (iMember = 0; iMember < pMembersOld->cEntries; ++iMember)
1219 pMembersOldList->AddUnique ((PVOID)(pMembersOld->aEntries[ iMember ].idObject));
1221 for (iMember = 0; iMember < lpp->pMembers->cEntries; ++iMember)
1223 if (!lpp->pMembers->aEntries[ iMember ].lParam)
1224 continue; // member not mandatory
1225 if (pMembersOldList->fIsInList ((PVOID)(lpp->pMembers->aEntries[ iMember ].idObject)))
1226 continue; // already a member
1228 if (!asc_GroupMemberAdd (g.idClient, g.idCell, lpp->pGroups->aEntries[iGroup].idObject, lpp->pMembers->aEntries[iMember].idObject, &status))
1229 ED_RegisterStatus (ped, lpp->pGroups->aEntries[ iGroup ].idObject, FALSE, status);
1232 Delete (pMembersOldList);
1234 asc_AsidListFree (&pMembersOld);
1237 // If there were any errors, report them.
1239 if ((*pStatus = ED_GetFinalStatus(ped)) != 0)
1242 ED_ShowErrorDialog(ped);
1248 Delete (pMembersAllow);
1253 void Task_Group_Enum (LPTASKPACKET ptp)
1255 LPCTSTR pszPattern = (LPCTSTR)( ptp->lpUser );
1257 TCHAR szRegExp[ cchNAME ];
1258 TranslateRegExp (szRegExp, pszPattern);
1259 if ((ptp->rc = asc_ObjectFindMultiple (g.idClient, g.idCell, TYPE_GROUP, szRegExp, NULL, &TASKDATA(ptp)->pAsidList, &ptp->status)) == TRUE)
1261 LPASOBJPROPLIST pPropList = NULL;
1263 ptp->rc = asc_ObjectPropertiesGetMultiple (g.idClient, GET_RUDIMENTARY_DATA, g.idCell, TASKDATA(ptp)->pAsidList, &pPropList, &ptp->status);
1266 asc_ObjPropListFree (&pPropList);
1269 FreeString (pszPattern);
1270 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1274 void Task_Group_Rename (LPTASKPACKET ptp)
1276 LPGROUP_RENAME_PARAMS lpp = (LPGROUP_RENAME_PARAMS)( ptp->lpUser );
1278 if ((ptp->rc = asc_GroupRename (g.idClient, g.idCell, lpp->idGroup, lpp->szNewName, &ptp->status)) != FALSE)
1280 Display_RefreshView_Fast();
1283 if (!ptp->rc && !IsWindow (ptp->hReply))
1285 TCHAR szOldName[ cchNAME ];
1286 asc_ObjectNameGet_Fast (g.idClient, g.idCell, lpp->idGroup, szOldName);
1287 ErrorDialog (ptp->status, IDS_ERROR_CANT_RENAME_GROUP, TEXT("%s%s"), szOldName, lpp->szNewName);
1291 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1295 void Task_Group_Owned_Get (LPTASKPACKET ptp)
1297 ASID idGroup = (ASID)( ptp->lpUser );
1299 ptp->rc = asc_GroupOwnershipGet (g.idClient, g.idCell, idGroup, &TASKDATA(ptp)->pAsidList, &ptp->status);
1301 // Modify the ASID list to have lParams of 1. (This indicates that all
1302 // our supplied groups own this thing; silly but consistent with the
1303 // other such interfaces.)
1305 if (TASKDATA(ptp)->pAsidList)
1307 for (size_t ii = 0; ii < TASKDATA(ptp)->pAsidList->cEntries; ++ii)
1308 TASKDATA(ptp)->pAsidList->aEntries[ ii ].lParam = 1;
1311 // Now that we have an ASID list full of groups to return, make sure we
1312 // have rudimentary properties for all those groups.
1317 asc_AsidListCopy (&pList, &TASKDATA(ptp)->pAsidList);
1319 LPASOBJPROPLIST pPropList = NULL;
1320 if (!asc_ObjectPropertiesGetMultiple (g.idClient, GET_RUDIMENTARY_DATA, g.idCell, pList, &pPropList, &ptp->status))
1323 asc_ObjPropListFree (&pPropList);
1325 asc_AsidListFree (&pList);
1330 void Task_Group_Owned_Set (LPTASKPACKET ptp)
1332 LPGROUP_OWNED_SET_PARAMS lpp = (LPGROUP_OWNED_SET_PARAMS)( ptp->lpUser );
1334 ptp->rc = Task_Group_Owned_Set_Do (lpp, &ptp->status);
1336 asc_AsidListFree (&lpp->pOwnedGroups);
1338 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1342 BOOL Task_Group_Owned_Set_Do (LPGROUP_OWNED_SET_PARAMS lpp, ULONG *pStatus)
1346 // Maintain a structure describing any errors we encounter, so we can give
1347 // a reasonable error dialog if need be.
1349 LPERRORDATA ped = ED_Create (IDS_ERROR_CANT_CHANGE_OWNER, IDS_ERROR_CANT_CHANGE_OWNER_MULTIPLE);
1351 // We'll need the supplied groups-to-own list in a hashlist, so we can
1352 // quickly test it for inclusion of a particular group.
1354 LPHASHLIST pGroupsAllow = New (HASHLIST);
1355 for (size_t iGroup = 0; iGroup < lpp->pOwnedGroups->cEntries; ++iGroup)
1356 pGroupsAllow->AddUnique ((PVOID)(lpp->pOwnedGroups->aEntries[ iGroup ].idObject));
1358 // Obtain the current list-of-groups-owned for this group
1360 LPASIDLIST pGroupsOld = NULL;
1361 if ((rc = asc_GroupOwnershipGet (g.idClient, g.idCell, lpp->idGroup, &pGroupsOld, pStatus)) == FALSE)
1366 for (size_t ii = 0; ii < lpp->pOwnedGroups->cEntries; ++ii)
1367 ED_RegisterStatus (ped, lpp->pOwnedGroups->aEntries[ii].idObject, FALSE, *pStatus);
1371 // Test each group in that current list to see if it's also on our
1372 // pGroupsAllow list. If not, remove it.
1374 for (iGroup = 0; iGroup < pGroupsOld->cEntries; ++iGroup)
1376 if (pGroupsAllow->fIsInList ((PVOID)(pGroupsOld->aEntries[iGroup].idObject)))
1380 ASOBJPROP Properties;
1381 if (!asc_ObjectPropertiesGet (g.idClient, GET_ALL_DATA, g.idCell, pGroupsOld->aEntries[iGroup].idObject, &Properties, &status))
1382 ED_RegisterStatus (ped, pGroupsOld->aEntries[iGroup].idObject, FALSE, status);
1385 AFSADMSVR_CHANGEGROUP_PARAMS pp;
1386 memset (&pp, 0x00, sizeof(pp));
1387 lstrcpy (pp.szOwner, Properties.szName); // make group self-owned
1388 pp.aaListStatus = Properties.u.GroupProperties.aaListStatus;
1389 pp.aaListGroupsOwned = Properties.u.GroupProperties.aaListGroupsOwned;
1390 pp.aaListMembers = Properties.u.GroupProperties.aaListMembers;
1391 pp.aaAddMember = Properties.u.GroupProperties.aaAddMember;
1392 pp.aaDeleteMember = Properties.u.GroupProperties.aaDeleteMember;
1394 if (!asc_GroupChange (g.idClient, g.idCell, pGroupsOld->aEntries[iGroup].idObject, &pp, &status))
1395 ED_RegisterStatus (ped, pGroupsOld->aEntries[iGroup].idObject, FALSE, status);
1399 // Now the more complex part: see if there are any groups in the
1400 // supplied group-list which are marked as mandatory, but which
1401 // aren't in our pGroupsOld list. We'll need to put the latter in a
1402 // hashlist for this...
1404 LPHASHLIST pGroupsOldList = New (HASHLIST);
1405 for (iGroup = 0; iGroup < pGroupsOld->cEntries; ++iGroup)
1406 pGroupsOldList->AddUnique ((PVOID)(pGroupsOld->aEntries[ iGroup ].idObject));
1408 for (iGroup = 0; iGroup < lpp->pOwnedGroups->cEntries; ++iGroup)
1410 if (!lpp->pOwnedGroups->aEntries[ iGroup ].lParam)
1411 continue; // group not mandatory
1412 if (pGroupsOldList->fIsInList ((PVOID)(lpp->pOwnedGroups->aEntries[ iGroup ].idObject)))
1413 continue; // already a member
1416 ASOBJPROP Properties;
1417 if (!asc_ObjectPropertiesGet (g.idClient, GET_ALL_DATA, g.idCell, lpp->pOwnedGroups->aEntries[iGroup].idObject, &Properties, &status))
1418 ED_RegisterStatus (ped, lpp->pOwnedGroups->aEntries[iGroup].idObject, FALSE, status);
1421 AFSADMSVR_CHANGEGROUP_PARAMS pp;
1422 memset (&pp, 0x00, sizeof(pp));
1423 pp.aaListStatus = Properties.u.GroupProperties.aaListStatus;
1424 pp.aaListGroupsOwned = Properties.u.GroupProperties.aaListGroupsOwned;
1425 pp.aaListMembers = Properties.u.GroupProperties.aaListMembers;
1426 pp.aaAddMember = Properties.u.GroupProperties.aaAddMember;
1427 pp.aaDeleteMember = Properties.u.GroupProperties.aaDeleteMember;
1429 if (asc_ObjectNameGet_Fast (g.idClient, g.idCell, lpp->idGroup, pp.szOwner, &status))
1431 if (!asc_GroupChange (g.idClient, g.idCell, lpp->pOwnedGroups->aEntries[iGroup].idObject, &pp, &status))
1432 ED_RegisterStatus (ped, lpp->pOwnedGroups->aEntries[iGroup].idObject, FALSE, status);
1437 Delete (pGroupsOldList);
1438 asc_AsidListFree (&pGroupsOld);
1441 // If there were any errors, report them.
1443 if ((*pStatus = ED_GetFinalStatus(ped)) != 0)
1446 ED_ShowErrorDialog(ped);
1452 Delete (pGroupsAllow);
1457 void Task_Group_Create (LPTASKPACKET ptp)
1459 LPGROUP_CREATE_PARAMS lpp = (LPGROUP_CREATE_PARAMS)(ptp->lpUser);
1461 // If no owner was specified, use our current credentials' ID. If
1462 // we can't get that, we'll make each group self-owned.
1464 if (!lpp->szOwner[0])
1466 TCHAR szCell[ cchNAME ];
1467 if (!AfsAppLib_CrackCredentials (g.hCreds, szCell, lpp->szOwner))
1468 lpp->szOwner[0] = TEXT('\0');
1471 // We may actually have been asked to create more than one group here;
1472 // the {lpp->mszNames} parameter is a multi-string. So everything we
1473 // do, we'll do for each new group-name...
1475 for (LPTSTR pszName = lpp->mszNames; pszName && *pszName; pszName += 1+lstrlen(pszName))
1477 // First create this new group account
1481 AFSADMSVR_CREATEGROUP_PARAMS pp;
1482 memset (&pp, 0x00, sizeof(AFSADMSVR_CREATEGROUP_PARAMS));
1483 pp.idGroup = lpp->idGroup;
1484 lstrcpy (pp.szName, pszName);
1485 lstrcpy (pp.szOwner, lpp->szOwner);
1487 lstrcpy (pp.szOwner, pszName);
1489 if ((ptp->rc = asc_GroupCreate (g.idClient, g.idCell, &pp, &idGroup, &ptp->status)) == FALSE)
1491 if (!IsWindow (ptp->hReply))
1492 ErrorDialog (ptp->status, IDS_ERROR_CANT_CREATE_GROUP, TEXT("%s"), pszName);
1496 // Then change its properties to be what we want
1498 if ((ptp->rc = asc_GroupChange (g.idClient, g.idCell, idGroup, &lpp->Properties, &ptp->status)) == FALSE)
1500 if (!IsWindow (ptp->hReply))
1501 ErrorDialog (ptp->status, IDS_ERROR_CANT_CHANGE_GROUP, TEXT("%s"), pszName);
1506 // Finally update its lists of groups
1510 GROUP_MEMBERS_SET_PARAMS pp;
1511 memset (&pp, 0x00, sizeof(GROUP_MEMBERS_SET_PARAMS));
1512 asc_AsidListCreate (&pp.pGroups);
1513 asc_AsidListAddEntry (&pp.pGroups, idGroup, 0);
1514 asc_AsidListCopy (&pp.pMembers, &lpp->pMembers);
1515 ptp->rc = Task_Group_Members_Set_Do (&pp, &ptp->status);
1516 asc_AsidListFree (&pp.pGroups);
1517 asc_AsidListFree (&pp.pMembers);
1519 if (lpp->pGroupsOwner)
1521 GROUP_OWNED_SET_PARAMS pp;
1522 memset (&pp, 0x00, sizeof(GROUP_OWNED_SET_PARAMS));
1523 pp.idGroup = idGroup;
1524 asc_AsidListCopy (&pp.pOwnedGroups, &lpp->pGroupsOwner);
1525 ptp->rc = Task_Group_Owned_Set_Do (&pp, &ptp->status);
1526 asc_AsidListFree (&pp.pOwnedGroups);
1532 Display_PopulateList();
1534 if (lpp->pGroupsOwner)
1535 asc_AsidListFree (&lpp->pGroupsOwner);
1537 asc_AsidListFree (&lpp->pMembers);
1539 FreeString (lpp->mszNames);
1541 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1545 void Task_Group_Delete (LPTASKPACKET ptp)
1547 LPASIDLIST pGroupList = (LPASIDLIST)(ptp->lpUser);
1549 // Maintain a structure describing any errors we encounter, so we can give
1550 // a reasonable error dialog if need be.
1552 LPERRORDATA ped = ED_Create (IDS_ERROR_CANT_DELETE_GROUP, IDS_ERROR_CANT_DELETE_GROUP_MULTIPLE);
1554 // Go through and delete these users
1556 for (size_t iGroup = 0; iGroup < pGroupList->cEntries; ++iGroup)
1559 if (!asc_GroupDelete (g.idClient, g.idCell, pGroupList->aEntries[iGroup].idObject, &status))
1560 ED_RegisterStatus (ped, pGroupList->aEntries[iGroup].idObject, FALSE, status);
1563 // If there were any errors, report them.
1565 if (ED_GetFinalStatus(ped) && !IsWindow(ptp->hReply))
1566 ED_ShowErrorDialog(ped);
1571 Display_PopulateList();
1574 asc_AsidListFree (&pGroupList);
1575 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1579 void Task_Cell_Change (LPTASKPACKET ptp)
1581 LPCELL_CHANGE_PARAMS lpp = (LPCELL_CHANGE_PARAMS)(ptp->lpUser);
1583 AFSADMSVR_CHANGECELL_PARAMS Change;
1584 memset (&Change, 0x00, sizeof(Change));
1585 Change.idUserMax = (DWORD)(lpp->idUserMax);
1586 Change.idGroupMax = (DWORD)(lpp->idGroupMax);
1587 ptp->rc = asc_CellChange (g.idClient, lpp->idCell, &Change, &ptp->status);
1589 if (!ptp->rc && !IsWindow (ptp->hReply))
1591 TCHAR szCell[ cchNAME ];
1592 asc_CellNameGet_Fast (g.idClient, lpp->idCell, szCell);
1593 ErrorDialog (ptp->status, IDS_ERROR_CANT_CHANGE_CELL, TEXT("%s"), szCell);
1597 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1601 void Task_List_Translate (LPTASKPACKET ptp)
1603 LPLIST_TRANSLATE_PARAMS lpp = (LPLIST_TRANSLATE_PARAMS)( ptp->lpUser );
1604 TASKDATA(ptp)->Type = lpp->Type;
1606 // We'll need a hashlist into which to dump our results as we build
1607 // them (we use a hashlist so we can quickly detect and ignore duplicates).
1609 LPHASHLIST pList = New (HASHLIST);
1611 // Now split the input string up into a series of names. To do that,
1612 // we'll valid separator characters are; since names can't have whitespace,
1613 // we'll include that.
1615 TCHAR szSeparators[ cchRESOURCE ];
1616 if (!GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SLIST, szSeparators, cchRESOURCE))
1617 szSeparators[0] = TEXT(',');
1618 GetString (&szSeparators[1], IDS_SEPARATORS);
1622 LPCTSTR pszStart = lpp->pszNames;
1623 while (iswhite(*pszStart) || lstrchr (szSeparators, *pszStart))
1628 // Find the first non-name character
1630 LPCTSTR pszEnd = pszStart;
1631 while (*pszEnd && !iswhite(*pszEnd) && !lstrchr(szSeparators, *pszEnd))
1634 // Copy off this particular name
1636 TCHAR szName[ cchNAME ];
1637 lstrcpy (szName, pszStart);
1638 szName[ pszEnd - pszStart ] = TEXT('\0');
1640 // Find the next valid-name character
1643 while (iswhite(*pszStart) || lstrchr(szSeparators, *pszStart))
1646 // Translate this particular name. We'll also handle wildcards
1647 // here: if we don't get any wildcard characters, treat it as
1648 // a direct lookup; if we do, treat it as a regexp match.
1650 if (lstrchr (szName, TEXT('*')) || lstrchr (szName, TEXT('?')) ||
1651 lstrchr (szName, TEXT('^')) || lstrchr (szName, TEXT('!')))
1653 TCHAR szRegExp[ cchNAME ];
1654 TranslateRegExp (szRegExp, szName);
1656 LPASIDLIST pAsidList;
1657 if (asc_ObjectFindMultiple (g.idClient, g.idCell, lpp->Type, szRegExp, NULL, &pAsidList, &ptp->status))
1661 for (size_t ii = 0; ii < pAsidList->cEntries; ++ii)
1662 pList->AddUnique ((PVOID)(pAsidList->aEntries[ii].idObject));
1663 asc_AsidListFree (&pAsidList);
1667 else // No wildcards; just look up the name directly
1670 if (asc_ObjectFind (g.idClient, g.idCell, lpp->Type, szName, &idObject, &ptp->status))
1671 pList->AddUnique ((PVOID)idObject);
1676 // Finally, build an ASIDLIST from our hashlist's contents.
1678 if (!asc_AsidListCreate (&TASKDATA(ptp)->pAsidList))
1681 ptp->status = ERROR_NOT_ENOUGH_MEMORY;
1685 for (LPENUM pEnum = pList->FindFirst(); pEnum; pEnum = pEnum->FindNext())
1687 ASID idObject = (ASID)(pEnum->GetObject());
1688 asc_AsidListAddEntry (&TASKDATA(ptp)->pAsidList, idObject, 0);
1695 FreeString (lpp->pszNames);
1697 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1701 void Task_Object_Listen (LPTASKPACKET ptp)
1703 LPOBJECT_LISTEN_PARAMS lpp = (LPOBJECT_LISTEN_PARAMS)( ptp->lpUser );
1705 if (IsWindow(lpp->hNotify) && (lpp->pAsidList))
1706 ptp->rc = asc_ObjectListenMultiple (g.idClient, g.idCell, lpp->pAsidList, lpp->hNotify, &ptp->status);
1708 ptp->rc = asc_ObjectListenClear (g.idClient, lpp->hNotify, &ptp->status);
1711 asc_AsidListFree (&lpp->pAsidList);
1713 ptp->lpUser = 0; // we freed this; don't let the caller use it again
1717 void Task_Object_Get (LPTASKPACKET ptp)
1719 ASID idObject = (ASID)(ptp->lpUser);
1720 ptp->rc = asc_ObjectPropertiesGet (g.idClient, GET_ALL_DATA, g.idCell, idObject, &TASKDATA(ptp)->Properties, &ptp->status);
1724 void Task_Set_Refresh (LPTASKPACKET ptp)
1728 ptp->rc = asc_CellRefreshRateSet (g.idClient, g.idCell, gr.cminRefreshRate, &ptp->status);
1733 void Task_Expired_Creds (LPTASKPACKET ptp)
1737 CheckForExpiredCredentials();
1742 void WeedAsidList (LPASIDLIST *ppList, BOOL fWantMachines)
1746 // First off, we can't do anything unless we have these guys' names.
1748 if (ppList && (*ppList) && (*ppList)->cEntries)
1750 LPASOBJPROPLIST pPropList = NULL;
1751 asc_ObjectPropertiesGetMultiple (g.idClient, GET_RUDIMENTARY_DATA, g.idCell, *ppList, &pPropList, &status);
1753 asc_ObjPropListFree (&pPropList);
1756 for (size_t ii = 0; ppList && (*ppList) && (ii < (*ppList)->cEntries); )
1758 TCHAR szName[ cchRESOURCE ];
1759 if (!asc_ObjectNameGet_Fast (g.idClient, g.idCell, (*ppList)->aEntries[ ii ].idObject, szName, &status))
1765 if (fIsMachineAccount(szName) == fWantMachines)
1768 asc_AsidListRemoveEntryByIndex (ppList, ii);
1773 void TranslateRegExp (LPTSTR pszTarget, LPCTSTR pszSource)
1777 if (!gr.fWindowsRegexp)
1779 lstrcpy (pszTarget, pszSource);
1783 for ( ; *pszSource; pszSource++)
1790 *pszTarget++ = TEXT('\\');
1791 *pszTarget++ = *pszSource;
1795 *pszTarget++ = TEXT('.');
1799 *pszTarget++ = TEXT('.');
1800 *pszTarget++ = TEXT('*');
1804 *pszTarget++ = *pszSource;
1811 *pszTarget++ = TEXT('\0');
1815 BOOL PerformRefresh (LPTASKPACKET ptp, ASID idScope, ULONG *pStatus)
1817 // Invalidate the admin server's cached information about the specified
1818 // object. Remember that this is recursive hierarchically: if you pass
1819 // in a cell's ID, for instance, information about all users, groups,
1820 // servers, services, partitions and volumes anywhere in that cell will
1826 if (!asc_ObjectRefresh (g.idClient, g.idCell, idScope, pStatus))
1829 // The Refresh call above is a misnomer; it's really an Invalidate request,
1830 // in that it only causes the admin server to dump its cached information
1831 // over the specified scope. At this point we need to do something to
1832 // trigger the server to re-query that information, so that it will send
1833 // an ACTION_REFRESH notification (indicating it's doing that requery),
1834 // which we'll pick up on and use as a trigger to refresh our display.
1835 // A convenient way to get the server to do that re-query is to ask it
1836 // to perform some simple search among the users in the cell--we'll ask
1837 // it to find, oh, say, "JoeBobUser", and in order to do that, it will
1838 // have to re-fill its cache.
1840 LPASIDLIST pListDummy;
1842 (void)asc_ObjectFindMultiple (g.idClient, g.idCell, TYPE_USER, TEXT("JoeBobUser"), NULL, &pListDummy, &statusDummy);
1843 if (pListDummy != NULL)
1844 asc_AsidListFree (&pListDummy);