2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afs/param.h>
13 #include "TaAfsAdmSvrInternal.h"
17 * ROUTINES ___________________________________________________________________
22 // ...obtains a cookie to represent the calling process. The cookie should
23 // be freed with AfsAdmSvr_Disconnect when the process disconnects.
25 int AfsAdmSvr_Connect (STRING szClientAddress, DWORD *pidClient, ULONG *pStatus)
27 // Make sure AfsClass initialized properly. If it's already init'd,
28 // this won't hurt at all.
31 if (!AfsClass_Initialize (&status))
33 Print (TEXT("Denying client %s due to AfsClass initialization failure"), szClientAddress);
34 return FALSE_(status, pStatus);
37 // Find a free CLIENTINFO structure for this caller
39 if (!AfsAdmSvr_AttachClient (szClientAddress, pidClient, pStatus))
42 Print (TEXT("Connected to client %s (ID 0x%08lX)"), AfsAdmSvr_GetClientName (*pidClient), *pidClient);
49 // ...reminds the admin server that the specified client is still around.
50 // this call should be made at least every csecAFSADMSVR_CLIENT_PING
51 // seconds, lest the admin server think you've disconnected. (The
52 // client library TaAfsAdmSvrClient.lib automatically handles this.)
54 int AfsAdmSvr_Ping (DWORD idClient, ULONG *pStatus)
58 if (!AfsAdmSvr_fIsValidClient (idClient))
59 return Leave_FALSE_(ERROR_INVALID_PARAMETER, pStatus);
61 AfsAdmSvr_PingClient (idClient);
67 // AfsAdmSvr_Disconnect
68 // ...releases and invalidates the cookie representing the calling process.
70 int AfsAdmSvr_Disconnect (DWORD idClient, ULONG *pStatus)
74 // Make sure this is a valid client, and free its l.aClients[] entry if so.
76 if (!AfsAdmSvr_fIsValidClient (idClient))
77 return Leave_FALSE_(ERROR_INVALID_PARAMETER, pStatus);
79 Print (TEXT("Disconnected from client %s (ID 0x%08lX)"), AfsAdmSvr_GetClientName (idClient), idClient);
81 AfsAdmSvr_DetachClient (idClient);
87 // AfsAdmSvr_CrackCredentials
88 // ...queries the specified AFS credentials token for its cell, user
89 // and expiration date.
91 int AfsAdmSvr_CrackCredentials (DWORD idClient, DWORD hCreds, STRING pszCell, STRING pszUser, SYSTEMTIME *pstExpiration, ULONG *pStatus)
94 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
96 if (!AfsAdmSvr_fIsValidClient (idClient))
97 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
99 Print (dlDETAIL, TEXT("Client 0x%08lX: CrackCredentials (0x%08lX)"), idClient, hCreds);
101 unsigned long dateExpirationQuery;
102 int fHasKasTokenQuery;
103 char szUser[ cchSTRING ];
104 char szUser2[ cchSTRING ];
105 char szCell[ cchSTRING ];
106 char *pszCellQuery = (pszCell) ? (char *)pszCell : szCell;
107 char *pszUserQuery = (pszUser) ? (char *)pszUser : szUser;
108 if (!afsclient_TokenQuery ((PVOID)hCreds, &dateExpirationQuery, pszUserQuery, szUser2, pszCellQuery, &fHasKasTokenQuery, (afs_status_p)&status))
109 return FALSE_(status, pStatus, iOp);
112 AfsAppLib_UnixTimeToSystemTime (pstExpiration, dateExpirationQuery);
114 AfsAdmSvr_EndOperation (iOp);
119 // AfsAdmSvr_GetCredentials
120 // ...queries the user's current AFS credentials for the specified cell
121 // if the user already has credentials in the cell, returns a nonzero
122 // token {hCreds}, suitable for use in AfsAdmSvr_OpenCell().
124 DWORD AfsAdmSvr_GetCredentials (DWORD idClient, STRING pszCell, ULONG *pStatus)
127 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
129 if (!AfsAdmSvr_fIsValidClient (idClient))
130 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
132 Print (dlDETAIL, TEXT("Client 0x%08lX: GetCredentials (%s)"), idClient, pszCell);
134 const char *pszCellTest = (pszCell && *pszCell) ? (const char *)pszCell : NULL;
137 if (!afsclient_TokenGetExisting (pszCellTest, &hCreds, (afs_status_p)&status))
138 return FALSE_(status, pStatus, iOp);
140 AfsAdmSvr_EndOperation (iOp);
141 return (DWORD)hCreds;
145 // AfsAdmSvr_SetCredentials
146 // ...obtains new AFS credentials within the administrative server process
147 // on behalf of the specified user. if successful, returns a nonzero
148 // token {hCreds}, suitable for use in AfsAdmSvr_OpenCell().
150 DWORD AfsAdmSvr_SetCredentials (DWORD idClient, STRING pszCell, STRING pszUser, STRING pszPassword, ULONG *pStatus)
153 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
155 Print (dlDETAIL, TEXT("Client 0x%08lX: SetCredentials (%s,%s)"), idClient, pszCell, pszUser);
157 if (!AfsAdmSvr_fIsValidClient (idClient))
158 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
160 const char *pszCellSet = (pszCell && *pszCell) ? (const char *)pszCell : NULL;
163 if (!afsclient_TokenGetNew (pszCellSet, (const char *)pszUser, (const char *)pszPassword, &hCreds, (afs_status_p)&status))
164 return FALSE_(status,pStatus,iOp);
166 AfsAdmSvr_EndOperation (iOp);
167 return (DWORD)hCreds;
171 // AfsAdmSvr_PushCredentials
172 // ...requests that the specified AFS credentials be used hereafter
173 // when manipulating the specified cell. You should follow this
174 // call with a Refresh request if necessary.
176 int AfsAdmSvr_PushCredentials (DWORD idClient, DWORD hCreds, ASID idCell, ULONG *pStatus)
179 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
181 Print (dlDETAIL, TEXT("Client 0x%08lX: PushCredentials (hCreds=0x%08lX, idCell=0x%08lX)"), idClient, hCreds, idCell);
183 if (!AfsAdmSvr_fIsValidClient (idClient))
184 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
186 if (GetAsidType (idCell) != itCELL)
187 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
190 if ((lpCell = ((LPIDENT)idCell)->OpenCell (&status)) == NULL)
191 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
193 lpCell->SetCurrentCredentials ((PVOID)hCreds);
196 AfsAdmSvr_EndOperation (iOp);
201 // AfsAdmSvr_GetLocalCell
202 // ...obtains the name of the primary cell used by the admin server
204 int AfsAdmSvr_GetLocalCell (DWORD idClient, STRING pszCellName, ULONG *pStatus)
206 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
208 Print (dlDETAIL, TEXT("Client 0x%08lX: GetLocalCell"), idClient);
210 if (!AfsAdmSvr_fIsValidClient (idClient))
211 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
213 if (!CELL::GetDefaultCell (pszCellName, pStatus))
215 AfsAdmSvr_EndOperation (iOp);
219 AfsAdmSvr_EndOperation (iOp);
224 // AfsAdmSvr_ErrorCodeTranslate
225 // ...translates an error code into an English string
227 int AfsAdmSvr_ErrorCodeTranslate (DWORD idClient, ULONG code, LANGID idLanguage, STRING pszErrorText, ULONG *pStatus)
229 if (!AfsAppLib_TranslateError (pszErrorText, code, idLanguage))
230 return FALSE_(ERROR_INVALID_PARAMETER,pStatus);
233 if ((pch = (LPTSTR)lstrrchr (pszErrorText, TEXT('('))) != NULL)
235 while (lstrlen(pszErrorText) && pszErrorText[ lstrlen(pszErrorText)-1 ] == TEXT(' '))
236 pszErrorText[ lstrlen(pszErrorText)-1 ] = TEXT('\0');
241 // AfsAdmSvr_GetAction
242 // ...returns information about a particular operation in progress.
244 int AfsAdmSvr_GetAction (DWORD idClient, DWORD idAction, LPASACTION pAction, ULONG *pStatus)
246 Print (dlDETAIL, TEXT("Client 0x%08lX: GetAction (idAction=0x%08lX)"), idClient, idAction);
248 if (!AfsAdmSvr_fIsValidClient (idClient))
249 return FALSE_(ERROR_INVALID_PARAMETER,pStatus);
251 if (!AfsAdmSvr_GetOperation (idAction, pAction))
252 return FALSE_(ERROR_INVALID_PARAMETER,pStatus);
254 Print (dlERROR, TEXT("Client 0x%08lX: GetAction succeeded"));
259 // AfsAdmSvr_GetActions
260 // ...returns a list of operations in progress. The list returned can
261 // be constrained to only including those operations initiated by
262 // a particular client and/or performed in a particular cell.
264 int AfsAdmSvr_GetActions (DWORD idClient, DWORD idClientSearch, ASID idCellSearch, LPASACTIONLIST *ppList, ULONG *pStatus)
266 Print (dlDETAIL, TEXT("Client 0x%08lX: GetActions (idClientSearch=0x%08lX, idCellSearch=0x%08lX)"), idClient, idClientSearch, idCellSearch);
268 if (!AfsAdmSvr_fIsValidClient (idClient))
269 return FALSE_(ERROR_INVALID_PARAMETER,pStatus);
271 if ((*ppList = AfsAdmSvr_GetOperations (idClientSearch, idCellSearch)) == NULL)
273 Print (dlERROR, TEXT("Client 0x%08lX: GetActions failed"), idClient);
274 return FALSE_(ERROR_NOT_ENOUGH_MEMORY,pStatus);
277 Print (dlERROR, TEXT("Client 0x%08lX: GetActions succeeded; %ld actions"), idClient, (*ppList) ? (*ppList)->cEntries : 0);
282 // AfsAdmSvr_OpenCell
283 // ...opens a cell for administration.
285 int AfsAdmSvr_OpenCell (DWORD idClient, DWORD hCreds, STRING pszCellName, DWORD dwScopeFlags, ASID *pidCell, ULONG *pStatus)
287 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
289 if (!AfsAdmSvr_fIsValidClient (idClient))
290 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
292 Print (dlDETAIL, TEXT("Client 0x%08lX: OpenCell"), idClient);
294 AfsAdmSvr_AddToMinScope (dwScopeFlags);
297 if ((lpiCell = CELL::OpenCell ((LPTSTR)pszCellName, (PVOID)hCreds, pStatus)) == NULL)
299 AfsAdmSvr_EndOperation (iOp);
303 Print (dlDETAIL, TEXT("Client 0x%08lX: OpenCell succeeded (idCell=0x%08lX)"), idClient, (DWORD)lpiCell);
305 *pidCell = (ASID)lpiCell;
306 AfsAdmSvr_EndOperation (iOp);
311 // AfsAdmSvr_CloseCell
312 // ...used by client to open a cell for administration.
314 int AfsAdmSvr_CloseCell (DWORD idClient, ASID idCell, ULONG *pStatus)
316 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
318 Print (dlDETAIL, TEXT("Client 0x%08lX: CloseCell (idCell=0x%08lX)"), idClient, idCell);
320 if (!AfsAdmSvr_fIsValidClient (idClient))
321 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
323 if (GetAsidType (idCell) != itCELL)
324 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
326 CELL::CloseCell ((LPIDENT)idCell);
328 AfsAdmSvr_EndOperation (iOp);
333 // AfsAdmSvr_FindObject
334 // AfsAdmSvr_FindObjects
335 // ...used to search through all objects in the cell, obtaining a list
336 // of those which match the specified criteria. For FindObjects, the
337 // {*ppList} parameter will be filled in with an allocated list of
338 // ASIDs, and should be freed using the AfsAdmSvr_FreeAsidList()
339 // routine (clients using the TaAfsAdmSvrClient.lib library should
340 // call asc_AsidListFree(), which is a wrapper for that routine).
341 // The _FindObject routine can be used to find exactly one object--
342 // for instance, finding the ASID for a particular user or volume--
343 // while the _FindObjects routine returns a list of all objects
344 // which match the specified criteria--all volumes on a partition,
345 // or all users named "b*" within a cell.
347 int AfsAdmSvr_FindObject (DWORD idClient, ASID idSearchScope, ASOBJTYPE ObjectType, AFSADMSVR_SEARCH_REFRESH SearchRefresh, STRING szName, ASID *pidObject, ULONG *pStatus)
352 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
354 Print (dlDETAIL, TEXT("Client 0x%08lX: FindObject (scope=0x%08lX, type=%lu, name='%s')"), idClient, idSearchScope, ObjectType, szName);
356 if (!AfsAdmSvr_fIsValidClient (idClient))
357 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
359 if (GetAsidType (idSearchScope) == itUNUSED)
360 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
362 // We've got a special case here: if possible, we don't want to have to
363 // refresh the contents of the entire cell. So if the client is looking
364 // for a user or group, we can just try to grab that object by its name;
365 // afsclass supports an interface for just this case.
370 rc = AfsAdmSvr_Search_OneUser (pidObject, idSearchScope, szName, &status);
374 rc = AfsAdmSvr_Search_OneGroup (pidObject, idSearchScope, szName, &status);
378 // We'll have to do the search the hard way. First
379 // see if we need to refresh this cell/server.
381 if (!AfsAdmSvr_SearchRefresh (idSearchScope, ObjectType, SearchRefresh, &status))
382 return FALSE_(status,pStatus,iOp);
384 // Look for the specified object.
386 switch (GetAsidType (idSearchScope))
389 if (ObjectType == TYPE_SERVER)
390 rc = AfsAdmSvr_Search_ServerInCell (pidObject, idSearchScope, szName, &status);
391 else if (ObjectType == TYPE_SERVICE)
392 rc = AfsAdmSvr_Search_ServiceInCell (pidObject, idSearchScope, szName, &status);
393 else if (ObjectType == TYPE_PARTITION)
394 rc = AfsAdmSvr_Search_PartitionInCell (pidObject, idSearchScope, szName, &status);
395 else if (ObjectType == TYPE_VOLUME)
396 rc = AfsAdmSvr_Search_VolumeInCell (pidObject, idSearchScope, szName, &status);
397 else if (ObjectType == TYPE_USER)
398 rc = AfsAdmSvr_Search_UserInCell (pidObject, idSearchScope, szName, &status);
399 else if (ObjectType == TYPE_GROUP)
400 rc = AfsAdmSvr_Search_GroupInCell (pidObject, idSearchScope, szName, &status);
404 status = ERROR_INVALID_PARAMETER;
409 if (ObjectType == TYPE_SERVICE)
410 rc = AfsAdmSvr_Search_ServiceInServer (pidObject, idSearchScope, szName, &status);
411 else if (ObjectType == TYPE_PARTITION)
412 rc = AfsAdmSvr_Search_PartitionInServer (pidObject, idSearchScope, szName, &status);
413 else if (ObjectType == TYPE_VOLUME)
414 rc = AfsAdmSvr_Search_VolumeInServer (pidObject, idSearchScope, szName, &status);
418 status = ERROR_INVALID_PARAMETER;
423 if (ObjectType == TYPE_VOLUME)
424 rc = AfsAdmSvr_Search_VolumeInPartition (pidObject, idSearchScope, szName, &status);
428 status = ERROR_INVALID_PARAMETER;
439 Print (dlERROR, TEXT("Client 0x%08lX: FindObject failed (status=0x%08lX)"), idClient, status);
441 Print (dlDETAIL, TEXT("Client 0x%08lX: FindObject succeeded; returning idObject=0x%08lX"), idClient, *pidObject);
443 AfsAdmSvr_EndOperation (iOp);
448 int AfsAdmSvr_FindObjects (DWORD idClient, ASID idSearchScope, ASOBJTYPE ObjectType, AFSADMSVR_SEARCH_REFRESH SearchRefresh, STRING szPattern, LPAFSADMSVR_SEARCH_PARAMS pSearchParams, LPASIDLIST *ppList, ULONG *pStatus)
453 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
455 Print (dlDETAIL, TEXT("Client 0x%08lX: FindObjects (scope=0x%08lX, type=%lu, pat='%s')"), idClient, idSearchScope, ObjectType, szPattern);
457 if (!AfsAdmSvr_fIsValidClient (idClient))
458 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
460 if (GetAsidType (idSearchScope) == itUNUSED)
461 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
463 // First see if we need to refresh this cell/server
465 if (!AfsAdmSvr_SearchRefresh (idSearchScope, ObjectType, SearchRefresh, &status))
466 return FALSE_(status,pStatus,iOp);
468 // Prepare an ASIDLIST, and call whatever subroutine is necessary to
469 // perform the actual search.
471 if ((*ppList = AfsAdmSvr_CreateAsidList()) == NULL)
472 return FALSE_(ERROR_NOT_ENOUGH_MEMORY,pStatus,iOp);
474 LPTSTR pszPattern = (szPattern && szPattern[0]) ? (LPTSTR)szPattern : NULL;
476 switch (GetAsidType (idSearchScope))
479 if (ObjectType == TYPE_ANY)
480 rc = AfsAdmSvr_Search_AllInCell (ppList, idSearchScope, pszPattern, &status);
481 else if (ObjectType == TYPE_SERVER)
482 rc = AfsAdmSvr_Search_ServersInCell (ppList, idSearchScope, pszPattern, &status);
483 else if (ObjectType == TYPE_SERVICE)
484 rc = AfsAdmSvr_Search_ServicesInCell (ppList, idSearchScope, pszPattern, &status);
485 else if (ObjectType == TYPE_PARTITION)
486 rc = AfsAdmSvr_Search_PartitionsInCell (ppList, idSearchScope, pszPattern, &status);
487 else if (ObjectType == TYPE_VOLUME)
488 rc = AfsAdmSvr_Search_VolumesInCell (ppList, idSearchScope, pszPattern, &status);
489 else if (ObjectType == TYPE_USER)
490 rc = AfsAdmSvr_Search_UsersInCell (ppList, idSearchScope, pszPattern, &status);
491 else if (ObjectType == TYPE_GROUP)
492 rc = AfsAdmSvr_Search_GroupsInCell (ppList, idSearchScope, pszPattern, &status);
496 status = ERROR_INVALID_PARAMETER;
501 if (ObjectType == TYPE_ANY)
502 rc = AfsAdmSvr_Search_AllInServer (ppList, idSearchScope, pszPattern, &status);
503 else if (ObjectType == TYPE_SERVICE)
504 rc = AfsAdmSvr_Search_ServicesInServer (ppList, idSearchScope, pszPattern, &status);
505 else if (ObjectType == TYPE_PARTITION)
506 rc = AfsAdmSvr_Search_PartitionsInServer (ppList, idSearchScope, pszPattern, &status);
507 else if (ObjectType == TYPE_VOLUME)
508 rc = AfsAdmSvr_Search_VolumesInServer (ppList, idSearchScope, pszPattern, &status);
512 status = ERROR_INVALID_PARAMETER;
517 if (ObjectType == TYPE_ANY)
518 rc = AfsAdmSvr_Search_VolumesInPartition (ppList, idSearchScope, pszPattern, &status);
519 else if (ObjectType == TYPE_VOLUME)
520 rc = AfsAdmSvr_Search_VolumesInPartition (ppList, idSearchScope, pszPattern, &status);
524 status = ERROR_INVALID_PARAMETER;
529 if (rc && (*ppList) && (pSearchParams))
530 AfsAdmSvr_Search_Advanced (ppList, pSearchParams);
532 if (!rc && (*ppList))
533 AfsAdmSvr_FreeAsidList (ppList);
538 Print (dlERROR, TEXT("Client 0x%08lX: FindObjects failed (status=0x%08lX)"), idClient, status);
540 Print (dlDETAIL, TEXT("Client 0x%08lX: FindObjects succeeded; returning %lu item(s)"), idClient, (*ppList)->cEntries);
542 AfsAdmSvr_EndOperation (iOp);
547 // AfsAdmSvr_GetObject
548 // AfsAdmSvr_GetObjects
549 // ...returns server-cached information about the specified object (or
552 int AfsAdmSvr_GetObject (DWORD idClient, AFSADMSVR_GET_TYPE GetType, AFSADMSVR_GET_LEVEL GetLevel, ASID idObject, DWORD verProperties, LPASOBJPROP pProperties, ULONG *pStatus)
554 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
556 Print (dlDETAIL2, TEXT("Client 0x%08lX: GetObject (Type=%lu, Level=%lu, idObject=0x%08lX, ver=%ld)"), idClient, (LONG)GetType, (LONG)GetLevel, idObject, verProperties);
558 memset (pProperties, 0x00, sizeof(ASOBJPROP));
560 if (!AfsAdmSvr_fIsValidClient (idClient))
561 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
563 LPASOBJPROP pCurrentProperties;
564 if ((pCurrentProperties = AfsAdmSvr_GetCurrentProperties (idObject, pStatus)) == NULL)
566 Print (dlERROR, TEXT("Client 0x%08lX: GetObject failed; no properties"), idClient, idObject);
567 AfsAdmSvr_EndOperation (iOp);
571 // At this point pCurrentProperties may just be rudimentary properties.
572 // If the user has requested GET_ALL_DATA, we'll have to get full properties.
574 if ( (GetLevel == GET_ALL_DATA) && (pCurrentProperties->verProperties < verPROP_FIRST_SCAN) )
576 if (!AfsAdmSvr_ObtainFullProperties (pCurrentProperties, pStatus))
578 Print (dlERROR, TEXT("Client 0x%08lX: GetObject failed; no full properties"), idClient, idObject);
579 AfsAdmSvr_EndOperation (iOp);
584 // Now determine if we need to return anything at all; if the user specified
585 // RETURN_IF_OUT_OF_DATE, it's possible that there's no need to do so.
587 if ((pCurrentProperties->verProperties > verProperties) || (GetType == RETURN_DATA_ALWAYS))
589 memcpy (pProperties, pCurrentProperties, sizeof(ASOBJPROP));
592 Print (dlDETAIL2, TEXT("Client 0x%08lX: GetObject succeeded (idObject=0x%08lX)"), idClient, idObject);
593 AfsAdmSvr_EndOperation (iOp);
598 int AfsAdmSvr_GetObjects (DWORD idClient, AFSADMSVR_GET_TYPE GetType, AFSADMSVR_GET_LEVEL GetLevel, LPASIDLIST pListObjects, LPASOBJPROPLIST *ppListObjectProperties, ULONG *pStatus)
600 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
602 Print (dlDETAIL, TEXT("Client 0x%08lX: GetObjects (Type=%lu, Level=%lu, nObjects=%lu)"), idClient, (LONG)GetType, (LONG)GetLevel, (pListObjects) ? (pListObjects->cEntries) : 0);
604 if (!AfsAdmSvr_fIsValidClient (idClient))
605 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
607 *ppListObjectProperties = NULL;
608 for (size_t iObject = 0; iObject < pListObjects->cEntries; ++iObject)
610 ASOBJPROP ObjectProperties;
613 if (AfsAdmSvr_GetObject (idClient, GetType, GetLevel, pListObjects->aEntries[ iObject ].idObject, pListObjects->aEntries[ iObject ].lParam, &ObjectProperties, &status))
615 if (ObjectProperties.idObject == pListObjects->aEntries[ iObject ].idObject)
617 if (!*ppListObjectProperties)
618 *ppListObjectProperties = AfsAdmSvr_CreateObjPropList();
620 if (*ppListObjectProperties)
621 AfsAdmSvr_AddToObjPropList (ppListObjectProperties, &ObjectProperties, 0);
626 Print (dlDETAIL, TEXT("Client 0x%08lX: GetObjects succeeded; returning %lu properties"), idClient, (*ppListObjectProperties) ? ((*ppListObjectProperties)->cEntries) : 0);
627 AfsAdmSvr_EndOperation (iOp);
632 // AfsAdmSvr_RefreshObject
633 // AfsAdmSvr_RefreshObjects
634 // ...invalidates the server's cache of information about the specified
635 // object or objects.
637 int AfsAdmSvr_RefreshObject (DWORD idClient, ASID idObject, ULONG *pStatus)
639 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
641 Print (dlDETAIL, TEXT("Client 0x%08lX: RefreshObject (idObject=0x%08lX)"), idClient, idObject);
643 if (!AfsAdmSvr_fIsValidClient (idClient))
644 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
646 if (!AfsAdmSvr_InvalidateObjectProperties (idObject, pStatus))
648 AfsAdmSvr_EndOperation (iOp);
652 AfsAdmSvr_EndOperation (iOp);
657 int AfsAdmSvr_RefreshObjects (DWORD idClient, LPASIDLIST pListObjects, ULONG *pStatus)
659 size_t iOp = AfsAdmSvr_BeginOperation (idClient);
661 Print (dlDETAIL, TEXT("Client 0x%08lX: RefreshObjects (nObjects=%lu)"), idClient, (pListObjects) ? (pListObjects->cEntries) : 0);
663 if (!AfsAdmSvr_fIsValidClient (idClient))
664 return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
666 for (size_t iObject = 0; iObject < pListObjects->cEntries; ++iObject)
669 AfsAdmSvr_RefreshObject (idClient, pListObjects->aEntries[ iObject ].idObject, &status);
672 AfsAdmSvr_EndOperation (iOp);
677 // AfsAdmSvr_CallbackHost
678 // ...provides a context in which the server can issue callback functions
679 // via the AfsAdmSvrCallBack_* routines, which the client must implement.
680 // This routine will only return if the server is shut down. It should
681 // be called on a dedicated thread by the client. (TaAfsAdmSvrClient.lib
682 // automatically handles this.)
684 void AfsAdmSvr_CallbackHost (void)
686 AfsAdmSvr_CallbackManager();
691 // AfsAdmSvr_GetRandomKey
692 // ...returns a randomly-generated 8-byte encryption key
694 int AfsAdmSvr_GetRandomKey (DWORD idClient, ASID idCell, BYTE keyData[ ENCRYPTIONKEYLENGTH ], ULONG *pStatus)
696 if (!AfsAdmSvr_fIsValidClient (idClient))
697 return FALSE_(ERROR_INVALID_PARAMETER,pStatus);
699 return AfsClass_GetRandomKey ((LPIDENT)idCell, (LPENCRYPTIONKEY)keyData, pStatus);