win95-initial-port-20010430
[openafs.git] / src / WINNT / afsadmsvr / TaAfsAdmSvrProperties.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include "TaAfsAdmSvrInternal.h"
16
17
18 /*
19  * VARIABLES __________________________________________________________________
20  *
21  */
22
23 typedef struct
24    {
25    ASID idCell;
26    DWORD timeLastRefresh;
27    DWORD cminRefreshRate;
28    HANDLE hThread;
29    } REFRESHTHREAD, *LPREFRESHTHREAD;
30
31 static struct
32    {
33    REFRESHTHREAD *aRefreshThreads;
34    size_t cRefreshThreads;
35    CRITICAL_SECTION *pcsRefreshThreads;
36    } l;
37
38
39 /*
40  * AUTO-REFRESH _______________________________________________________________
41  *
42  */
43
44 DWORD WINAPI AfsAdmSvr_AutoRefreshThread (PVOID lp)
45 {
46    ASID idCell = (ASID)lp;
47    for (;;)
48       {
49       EnterCriticalSection (l.pcsRefreshThreads);
50
51       BOOL fFound = FALSE;
52       DWORD cminRefreshRate;
53       DWORD timeLastRefresh;
54       for (size_t iThread = 0; (!fFound) && (iThread < l.cRefreshThreads); ++iThread)
55          {
56          LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
57          if (pThread->idCell == idCell)
58             {
59             fFound = TRUE;
60             cminRefreshRate = pThread->cminRefreshRate;
61             timeLastRefresh = pThread->timeLastRefresh;
62             }
63          }
64
65       LeaveCriticalSection (l.pcsRefreshThreads);
66
67       if (!fFound)
68          break;
69
70       DWORD timeNextRefresh = timeLastRefresh + cminRefreshRate;
71       if ((cminRefreshRate) && ((!timeLastRefresh) || (AfsAdmSvr_GetCurrentTime() >= timeNextRefresh)))
72          {
73          Print (dlDETAIL, TEXT("Auto-refresh: %lu minutes elapsed; refreshing cell 0x%08lX"), cminRefreshRate, idCell);
74
75          LPCELL lpCell;
76          if ((lpCell = ((LPIDENT)idCell)->OpenCell()) != NULL)
77             {
78             lpCell->Invalidate();
79
80             ULONG status;
81             if (!lpCell->RefreshAll (&status))
82                Print (dlERROR, TEXT("Auto-refresh: RefreshCell failed; error 0x%08lX"), status);
83             else
84                Print (dlSTANDARD, TEXT("Auto-refresh of cell 0x%08lX successful"), idCell);
85             lpCell->Close();
86             }
87          }
88
89       Sleep (60L * 1000L); // sleep for one minute
90       }
91
92    return 0;
93 }
94
95
96 void AfsAdmSvr_PrepCellRefresh (void)
97 {
98    if (!l.pcsRefreshThreads)
99       {
100       l.pcsRefreshThreads = New (CRITICAL_SECTION);
101       InitializeCriticalSection (l.pcsRefreshThreads);
102       }
103 }
104
105
106 void AfsAdmSvr_SetCellRefreshRate (ASID idCell, ULONG cminRefreshRate)
107 {
108    AfsAdmSvr_PrepCellRefresh();
109    EnterCriticalSection (l.pcsRefreshThreads);
110
111    for (size_t iThread = 0; iThread < l.cRefreshThreads; ++iThread)
112       {
113       LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
114       if (pThread->idCell == idCell)
115          {
116          pThread->cminRefreshRate = cminRefreshRate;
117          break;
118          }
119       }
120    if (iThread == l.cRefreshThreads)
121       {
122       for (size_t iThread = 0; iThread < l.cRefreshThreads; ++iThread)
123          {
124          LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
125          if (pThread->idCell == 0)
126             break;
127          }
128       if (REALLOC (l.aRefreshThreads, l.cRefreshThreads, 1+iThread, 1))
129          {
130          DWORD idThread;
131
132          LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
133          pThread->idCell = idCell;
134          pThread->timeLastRefresh = AfsAdmSvr_GetCurrentTime();
135          pThread->cminRefreshRate = cminRefreshRate;
136          pThread->hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)AfsAdmSvr_AutoRefreshThread, (LPVOID)idCell, 0, &idThread);
137          }
138       }
139
140    LeaveCriticalSection (l.pcsRefreshThreads);
141 }
142
143
144 void AfsAdmSvr_StopCellRefreshThread (ASID idCell)
145 {
146    AfsAdmSvr_PrepCellRefresh();
147    EnterCriticalSection (l.pcsRefreshThreads);
148
149    for (size_t iThread = 0; iThread < l.cRefreshThreads; ++iThread)
150       {
151       LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
152       if (pThread->idCell == idCell)
153          pThread->idCell = 0;
154       }
155
156    LeaveCriticalSection (l.pcsRefreshThreads);
157 }
158
159
160 void AfsAdmSvr_MarkRefreshThread (ASID idCell)
161 {
162    AfsAdmSvr_PrepCellRefresh();
163    EnterCriticalSection (l.pcsRefreshThreads);
164
165    for (size_t iThread = 0; iThread < l.cRefreshThreads; ++iThread)
166       {
167       LPREFRESHTHREAD pThread = &l.aRefreshThreads[ iThread ];
168       if (pThread->idCell == idCell)
169          pThread->timeLastRefresh = AfsAdmSvr_GetCurrentTime();
170       }
171
172    LeaveCriticalSection (l.pcsRefreshThreads);
173 }
174
175
176 /*
177  * OBJECT PROPERTIES __________________________________________________________
178  *
179  */
180
181 void AfsAdmSvr_ObtainRudimentaryProperties (LPASOBJPROP pProperties)
182 {
183    LPIDENT lpi = (LPIDENT)(pProperties->idObject);
184
185    switch (GetAsidType (pProperties->idObject))
186       {
187       case itCELL:
188          pProperties->Type = TYPE_CELL;
189          lpi->GetCellName (pProperties->szName);
190          break;
191
192       case itSERVER:
193          pProperties->Type = TYPE_SERVER;
194          pProperties->idParentCell = (ASID)( lpi->GetCell() );
195          lpi->GetServerName (pProperties->szName);
196          break;
197
198       case itSERVICE:
199          pProperties->Type = TYPE_SERVICE;
200          pProperties->idParentCell = (ASID)( lpi->GetCell() );
201          pProperties->idParentServer = (ASID)( lpi->GetServer() );
202          lpi->GetServiceName (pProperties->szName);
203          break;
204
205       case itAGGREGATE:
206          pProperties->Type = TYPE_PARTITION;
207          pProperties->idParentCell = (ASID)( lpi->GetCell() );
208          pProperties->idParentServer = (ASID)( lpi->GetServer() );
209          lpi->GetAggregateName (pProperties->szName);
210          break;
211
212       case itFILESET:
213          pProperties->Type = TYPE_VOLUME;
214          pProperties->idParentCell = (ASID)( lpi->GetCell() );
215          pProperties->idParentServer = (ASID)( lpi->GetServer() );
216          pProperties->idParentPartition = (ASID)( lpi->GetAggregate() );
217          lpi->GetFilesetName (pProperties->szName);
218          break;
219
220       case itUSER:
221          pProperties->Type = TYPE_USER;
222          pProperties->idParentCell = (ASID)( lpi->GetCell() );
223          lpi->GetUserName (pProperties->szName);
224          break;
225
226       case itGROUP:
227          pProperties->Type = TYPE_GROUP;
228          pProperties->idParentCell = (ASID)( lpi->GetCell() );
229          lpi->GetGroupName (pProperties->szName);
230          break;
231
232       default:
233          pProperties->verProperties = verPROP_NO_OBJECT;
234          return;
235       }
236
237    if (pProperties->verProperties == verPROP_NO_OBJECT)
238       pProperties->verProperties = verPROP_RUDIMENTARY;
239 }
240
241
242 BOOL AfsAdmSvr_ObtainFullProperties (LPASOBJPROP pProperties, ULONG *pStatus)
243 {
244    BOOL rc = TRUE;
245    ULONG status = 0;
246
247    AfsAdmSvr_ObtainRudimentaryProperties (pProperties);
248
249    if (pProperties->verProperties != verPROP_NO_OBJECT)
250       {
251       LPIDENT lpi = (LPIDENT)(pProperties->idObject);
252
253       switch (GetAsidType (pProperties->idObject))
254          {
255          case itCELL:
256             PTSPROPERTIES PtsProperties;
257             if ((rc = AfsClass_GetPtsProperties (lpi, &PtsProperties, &status)) == TRUE)
258                {
259                pProperties->u.CellProperties.idUserMax = (DWORD)PtsProperties.idUserMax;
260                pProperties->u.CellProperties.idGroupMax = (DWORD)PtsProperties.idGroupMax;
261                }
262             break;
263
264          case itSERVER:
265             LPSERVER lpServer;
266             if ((lpServer = lpi->OpenServer (&status)) == NULL)
267                rc = FALSE;
268             else
269                {
270                SERVERSTATUS ss;
271                if (!lpServer->GetStatus (&ss, TRUE, &status))
272                   rc = FALSE;
273                else
274                   {
275                   pProperties->u.ServerProperties.nAddresses = 0;
276                   for (size_t ii = 0; ii < ss.nAddresses; ++ii)
277                      {
278                      if (!ss.aAddresses[ii].sin_addr.s_addr)
279                         continue;
280                      if (pProperties->u.ServerProperties.nAddresses < ASOBJPROP_SERVER_MAXADDRESS)
281                         {
282                         pProperties->u.ServerProperties.aAddresses[ pProperties->u.ServerProperties.nAddresses ] = ntohl(ss.aAddresses[ii].sin_addr.s_addr);
283                         pProperties->u.ServerProperties.nAddresses ++;
284                         }
285                      }
286                   }
287                lpServer->Close();
288                }
289             break;
290
291          case itSERVICE:
292             LPSERVICE lpService;
293             if ((lpService = lpi->OpenService (&status)) == NULL)
294                rc = FALSE;
295             else
296                {
297                SERVICESTATUS ss;
298                if (!lpService->GetStatus (&ss, TRUE, &status))
299                   rc = FALSE;
300                else
301                   {
302                   pProperties->u.ServiceProperties.ServiceType = ss.type;
303                   pProperties->u.ServiceProperties.ServiceState = ss.state;
304                   lstrcpy (pProperties->u.ServiceProperties.szAuxStatus, ss.szAuxStatus);
305                   lstrcpy (pProperties->u.ServiceProperties.szParams, ss.szParams);
306                   lstrcpy (pProperties->u.ServiceProperties.szNotifier, ss.szNotifier);
307                   memcpy (&pProperties->u.ServiceProperties.timeLastStart, &ss.timeLastStart, sizeof(SYSTEMTIME));
308                   memcpy (&pProperties->u.ServiceProperties.timeLastStop, &ss.timeLastStop, sizeof(SYSTEMTIME));
309                   memcpy (&pProperties->u.ServiceProperties.timeLastFail, &ss.timeLastFail, sizeof(SYSTEMTIME));
310                   pProperties->u.ServiceProperties.nStarts = ss.nStarts;
311                   pProperties->u.ServiceProperties.dwErrLast = ss.dwErrLast;
312                   pProperties->u.ServiceProperties.dwSigLast = ss.dwSigLast;
313                   }
314                lpService->Close();
315                }
316             break;
317
318          case itAGGREGATE:
319             LPAGGREGATE lpAggregate;
320             if ((lpAggregate = lpi->OpenAggregate(&status)) == NULL)
321                rc = FALSE;
322             else
323                {
324                AGGREGATESTATUS as;
325                if (!lpAggregate->GetStatus (&as, TRUE, &status))
326                   rc = FALSE;
327                else
328                   {
329                   pProperties->u.PartitionProperties.dwID = as.dwID;
330                   pProperties->u.PartitionProperties.ckStorageTotal = as.ckStorageTotal;
331                   pProperties->u.PartitionProperties.ckStorageFree = as.ckStorageFree;
332                   pProperties->u.PartitionProperties.ckStorageAllocated = as.ckStorageAllocated;
333                   }
334                lpAggregate->Close();
335                }
336             break;
337
338          case itFILESET:
339             LPFILESET lpFileset;
340             if ((lpFileset = lpi->OpenFileset(&status)) == NULL)
341                rc = FALSE;
342             else
343                {
344                FILESETSTATUS fs;
345                if (!lpFileset->GetStatus (&fs, TRUE, &status))
346                   rc = FALSE;
347                else
348                   {
349                   pProperties->u.VolumeProperties.id = fs.id;
350                   pProperties->u.VolumeProperties.idReadWrite = fs.idReadWrite;
351                   pProperties->u.VolumeProperties.idReplica = fs.idReplica;
352                   pProperties->u.VolumeProperties.idClone = fs.idClone;
353                   memcpy (&pProperties->u.VolumeProperties.timeCreation, &fs.timeCreation, sizeof(SYSTEMTIME));
354                   memcpy (&pProperties->u.VolumeProperties.timeLastUpdate, &fs.timeLastUpdate, sizeof(SYSTEMTIME));
355                   memcpy (&pProperties->u.VolumeProperties.timeLastAccess, &fs.timeLastAccess, sizeof(SYSTEMTIME));
356                   memcpy (&pProperties->u.VolumeProperties.timeLastBackup, &fs.timeLastBackup, sizeof(SYSTEMTIME));
357                   memcpy (&pProperties->u.VolumeProperties.timeCopyCreation, &fs.timeCopyCreation, sizeof(SYSTEMTIME));
358                   pProperties->u.VolumeProperties.nFiles = fs.nFiles;
359                   pProperties->u.VolumeProperties.ckQuota = fs.ckQuota;
360                   pProperties->u.VolumeProperties.ckUsed = fs.ckUsed;
361                   pProperties->u.VolumeProperties.FilesetType = fs.Type;
362                   pProperties->u.VolumeProperties.FilesetState = fs.State;
363                   }
364                lpFileset->Close();
365                }
366             break;
367
368          case itUSER:
369             LPUSER lpUser;
370             if ((lpUser = lpi->OpenUser (&status)) == NULL)
371                rc = FALSE;
372             else
373                {
374                USERSTATUS us;
375                if (!lpUser->GetStatus (&us, TRUE, &status))
376                   rc = FALSE;
377                else
378                   {
379                   lpUser->GetName (NULL, pProperties->u.UserProperties.szInstance);
380
381                   if ((pProperties->u.UserProperties.fHaveKasInfo = us.fHaveKasInfo) == TRUE)
382                      {
383                      pProperties->u.UserProperties.KASINFO.fIsAdmin = us.KASINFO.fIsAdmin;
384                      pProperties->u.UserProperties.KASINFO.fCanGetTickets = us.KASINFO.fCanGetTickets;
385                      pProperties->u.UserProperties.KASINFO.fEncrypt = us.KASINFO.fEncrypt;
386                      pProperties->u.UserProperties.KASINFO.fCanChangePassword = us.KASINFO.fCanChangePassword;
387                      pProperties->u.UserProperties.KASINFO.fCanReusePasswords = us.KASINFO.fCanReusePasswords;
388                      memcpy (&pProperties->u.UserProperties.KASINFO.timeExpires, &us.KASINFO.timeExpires, sizeof(SYSTEMTIME));
389                      memcpy (&pProperties->u.UserProperties.KASINFO.timeLastPwChange, &us.KASINFO.timeLastPwChange, sizeof(SYSTEMTIME));
390                      memcpy (&pProperties->u.UserProperties.KASINFO.timeLastMod, &us.KASINFO.timeLastMod, sizeof(SYSTEMTIME));
391                      pProperties->u.UserProperties.KASINFO.szUserLastMod[0] = TEXT('\0');
392                      pProperties->u.UserProperties.KASINFO.csecTicketLifetime = us.KASINFO.csecTicketLifetime;
393                      pProperties->u.UserProperties.KASINFO.keyVersion = us.KASINFO.keyVersion;
394                      memcpy (&pProperties->u.UserProperties.KASINFO.keyData, us.KASINFO.key.key, ENCRYPTIONKEYLENGTH);
395                      pProperties->u.UserProperties.KASINFO.dwKeyChecksum = us.KASINFO.dwKeyChecksum;
396                      pProperties->u.UserProperties.KASINFO.cdayPwExpire = us.KASINFO.cdayPwExpire;
397                      pProperties->u.UserProperties.KASINFO.cFailLogin = us.KASINFO.cFailLogin;
398                      pProperties->u.UserProperties.KASINFO.csecFailLoginLock = us.KASINFO.csecFailLoginLock;
399                      if (us.KASINFO.lpiLastMod)
400                         us.KASINFO.lpiLastMod->GetUserName (pProperties->u.UserProperties.KASINFO.szUserLastMod);
401                      }
402                   if ((pProperties->u.UserProperties.fHavePtsInfo = us.fHavePtsInfo) == TRUE)
403                      {
404                      pProperties->u.UserProperties.PTSINFO.cgroupCreationQuota = us.PTSINFO.cgroupCreationQuota;
405                      pProperties->u.UserProperties.PTSINFO.cgroupMember = us.PTSINFO.cgroupMember;
406                      pProperties->u.UserProperties.PTSINFO.uidName = us.PTSINFO.uidName;
407                      pProperties->u.UserProperties.PTSINFO.uidOwner = us.PTSINFO.uidOwner;
408                      pProperties->u.UserProperties.PTSINFO.uidCreator = us.PTSINFO.uidCreator;
409                      lstrcpy (pProperties->u.UserProperties.PTSINFO.szOwner, us.PTSINFO.szOwner);
410                      lstrcpy (pProperties->u.UserProperties.PTSINFO.szCreator, us.PTSINFO.szCreator);
411                      pProperties->u.UserProperties.PTSINFO.aaListStatus = us.PTSINFO.aaListStatus;
412                      pProperties->u.UserProperties.PTSINFO.aaGroupsOwned = us.PTSINFO.aaGroupsOwned;
413                      pProperties->u.UserProperties.PTSINFO.aaMembership = us.PTSINFO.aaMembership;
414                      }
415                   }
416                lpUser->Close();
417                }
418             break;
419
420          case itGROUP:
421             lpi->GetGroupName (pProperties->szName);
422
423             LPPTSGROUP lpGroup;
424             if ((lpGroup = lpi->OpenGroup (&status)) == NULL)
425                rc = FALSE;
426             else
427                {
428                PTSGROUPSTATUS gs;
429                if (!lpGroup->GetStatus (&gs, TRUE, &status))
430                   rc = FALSE;
431                else
432                   {
433                   pProperties->u.GroupProperties.nMembers = gs.nMembers;
434                   pProperties->u.GroupProperties.uidName = gs.uidName;
435                   pProperties->u.GroupProperties.uidOwner = gs.uidOwner;
436                   pProperties->u.GroupProperties.uidCreator = gs.uidCreator;
437                   pProperties->u.GroupProperties.aaListStatus = gs.aaListStatus;
438                   pProperties->u.GroupProperties.aaListGroupsOwned = gs.aaListGroupsOwned;
439                   pProperties->u.GroupProperties.aaListMembers = gs.aaListMembers;
440                   pProperties->u.GroupProperties.aaAddMember = gs.aaAddMember;
441                   pProperties->u.GroupProperties.aaDeleteMember = gs.aaDeleteMember;
442                   lstrcpy (pProperties->u.GroupProperties.szOwner, gs.szOwner);
443                   lstrcpy (pProperties->u.GroupProperties.szCreator, gs.szCreator);
444                   }
445                lpGroup->Close();
446                }
447             break;
448          }
449       }
450
451    if (rc && (pProperties->verProperties < verPROP_FIRST_SCAN))
452       pProperties->verProperties = verPROP_FIRST_SCAN;
453
454    if (!rc)
455       pProperties->verProperties = verPROP_NO_OBJECT;
456
457    if (!rc && pStatus)
458       *pStatus = status;
459    return rc;
460 }
461
462
463 BOOL AfsAdmSvr_PropertiesDiffer (LPASOBJPROP pProp1, LPASOBJPROP pProp2)
464 {
465    if (pProp1->idObject != pProp2->idObject)
466       return TRUE;
467    if (pProp1->Type != pProp2->Type)
468       return TRUE;
469    if (pProp1->idParentCell != pProp2->idParentCell)
470       return TRUE;
471    if (pProp1->idParentServer != pProp2->idParentServer)
472       return TRUE;
473    if (pProp1->idParentPartition != pProp2->idParentPartition)
474       return TRUE;
475    if (lstrcmp (pProp1->szName, pProp2->szName))
476       return TRUE;
477    if (memcmp (&pProp1->u, &pProp2->u, sizeof(pProp1->u)))
478       return TRUE;
479
480    return FALSE;
481 }
482
483
484 void AfsAdmSvr_TestProperties (ASID idObject)
485 {
486    LPASOBJPROP pProperties;
487    if ((pProperties = (LPASOBJPROP)((LPIDENT)idObject)->GetUserParam()) == NULL)
488       return;
489
490    if (pProperties->verProperties >= verPROP_FIRST_SCAN)
491       {
492       ASOBJPROP NewProperties;
493       memcpy (&NewProperties, pProperties, sizeof(ASOBJPROP));
494       memset (&NewProperties.u, 0x00, sizeof(NewProperties.u));
495
496       if (AfsAdmSvr_ObtainFullProperties (&NewProperties))
497          {
498          if (AfsAdmSvr_PropertiesDiffer (&NewProperties, pProperties))
499             {
500             LPIDENT lpi = (LPIDENT)(pProperties->idObject);
501
502             LPASOBJPROP pStoredProp;
503             if ((pStoredProp = (LPASOBJPROP)(lpi->GetUserParam())) != NULL)
504                {
505                pStoredProp->idParentCell = NewProperties.idParentCell;
506                pStoredProp->idParentServer = NewProperties.idParentServer;
507                pStoredProp->idParentPartition = NewProperties.idParentPartition;
508                lstrcpy (pStoredProp->szName, NewProperties.szName);
509                memcpy (&pStoredProp->u, &NewProperties.u, sizeof(NewProperties.u));
510                pStoredProp->verProperties ++;
511                }
512             }
513          }
514       }
515 }
516
517
518 BOOL CALLBACK AfsAdmSvr_NotifyCallback (NOTIFYEVENT evt, PNOTIFYPARAMS pParams)
519 {
520    switch (evt)
521       {
522       case evtCreate:
523          LPIDENT lpiCreate;
524          if ((lpiCreate = pParams->lpi1) != NULL)
525             {
526             if ((lpiCreate->GetUserParam()) == NULL)
527                {
528                LPASOBJPROP pProperties = New (ASOBJPROP);
529                memset (pProperties, 0x00, sizeof(ASOBJPROP));
530                pProperties->idObject = (ASID)lpiCreate;
531                AfsAdmSvr_ObtainRudimentaryProperties (pProperties);
532                lpiCreate->SetUserParam(pProperties);
533                }
534
535             AfsAdmSvr_TestProperties ((ASID)lpiCreate);
536             }
537          break;
538
539       case evtDestroy:
540          if (GetAsidType ((ASID)pParams->lpi1) == itCELL)
541             AfsAdmSvr_StopCellRefreshThread ((ASID)(pParams->lpi1));
542          break;
543
544       case evtRefreshAllBegin:
545          AfsAdmSvr_Action_StartRefresh ((ASID)(pParams->lpi1));
546          break;
547
548       case evtRefreshAllEnd:
549          AfsAdmSvr_Action_StopRefresh ((ASID)(pParams->lpi1));
550          break;
551
552       case evtRefreshStatusEnd:
553          AfsAdmSvr_TestProperties ((ASID)(pParams->lpi1));
554          break;
555       }
556
557    return TRUE;
558 }
559
560
561 LPASOBJPROP AfsAdmSvr_GetCurrentProperties (ASID idObject, ULONG *pStatus)
562 {
563    switch (GetAsidType (idObject))
564       {
565       case itCELL:
566          LPCELL lpCell;
567          if ((lpCell = ((LPIDENT)idObject)->OpenCell (pStatus)) == NULL)
568             return NULL;
569          lpCell->Close();
570          break;
571
572       case itSERVER:
573          LPSERVER lpServer;
574          if ((lpServer = ((LPIDENT)idObject)->OpenServer (pStatus)) == NULL)
575             return NULL;
576          lpServer->Close();
577          break;
578
579       case itSERVICE:
580          LPSERVICE lpService;
581          if ((lpService = ((LPIDENT)idObject)->OpenService (pStatus)) == NULL)
582             return NULL;
583          lpService->Close();
584          break;
585
586       case itAGGREGATE:
587          LPAGGREGATE lpAggregate;
588          if ((lpAggregate = ((LPIDENT)idObject)->OpenAggregate (pStatus)) == NULL)
589             return NULL;
590          lpAggregate->Close();
591          break;
592
593       case itFILESET:
594          LPFILESET lpFileset;
595          if ((lpFileset = ((LPIDENT)idObject)->OpenFileset (pStatus)) == NULL)
596             return NULL;
597          lpFileset->Close();
598          break;
599
600       case itUSER:
601          LPUSER lpUser;
602          if ((lpUser = ((LPIDENT)idObject)->OpenUser (pStatus)) == NULL)
603             return NULL;
604          lpUser->Close();
605          break;
606
607       case itGROUP:
608          LPPTSGROUP lpGroup;
609          if ((lpGroup = ((LPIDENT)idObject)->OpenGroup (pStatus)) == NULL)
610             return NULL;
611          lpGroup->Close();
612          break;
613
614       default:
615          return (LPASOBJPROP)FALSE_(ERROR_INVALID_PARAMETER,pStatus);
616       }
617
618    LPASOBJPROP pCurrentProperties;
619    if ((pCurrentProperties = (LPASOBJPROP)((LPIDENT)idObject)->GetUserParam()) == NULL)
620       {
621       return (LPASOBJPROP)FALSE_(ERROR_NOT_ENOUGH_MEMORY,pStatus);
622       }
623
624    return pCurrentProperties;
625 }
626
627
628 BOOL AfsAdmSvr_InvalidateObjectProperties (ASID idObject, ULONG *pStatus)
629 {
630    switch (GetAsidType (idObject))
631       {
632       case itCELL:
633          LPCELL lpCell;
634          if ((lpCell = ((LPIDENT)idObject)->OpenCell (pStatus)) == NULL)
635             return FALSE;
636          lpCell->Invalidate();
637          lpCell->Close();
638          break;
639
640       case itSERVER:
641          LPSERVER lpServer;
642          if ((lpServer = ((LPIDENT)idObject)->OpenServer (pStatus)) == NULL)
643             return FALSE;
644          lpServer->Invalidate();
645          lpServer->Close();
646          break;
647
648       case itSERVICE:
649          LPSERVICE lpService;
650          if ((lpService = ((LPIDENT)idObject)->OpenService (pStatus)) == NULL)
651             return FALSE;
652          lpService->Invalidate();
653          lpService->Close();
654          break;
655
656       case itAGGREGATE:
657          LPAGGREGATE lpAggregate;
658          if ((lpAggregate = ((LPIDENT)idObject)->OpenAggregate (pStatus)) == NULL)
659             return FALSE;
660          lpAggregate->Invalidate();
661          lpAggregate->Close();
662          break;
663
664       case itFILESET:
665          LPFILESET lpFileset;
666          if ((lpFileset = ((LPIDENT)idObject)->OpenFileset (pStatus)) == NULL)
667             return FALSE;
668          lpFileset->Invalidate();
669          lpFileset->Close();
670          break;
671
672       case itUSER:
673          LPUSER lpUser;
674          if ((lpUser = ((LPIDENT)idObject)->OpenUser (pStatus)) == NULL)
675             return FALSE;
676          lpUser->Invalidate();
677          lpUser->Close();
678          break;
679
680       case itGROUP:
681          LPPTSGROUP lpGroup;
682          if ((lpGroup = ((LPIDENT)idObject)->OpenGroup (pStatus)) == NULL)
683             return FALSE;
684          lpGroup->Invalidate();
685          lpGroup->Close();
686          break;
687
688       default:
689          return FALSE_(ERROR_INVALID_PARAMETER,pStatus);
690       }
691
692    return TRUE;
693 }
694