Windows: permit aklog to build with krb4 support and roken
[openafs.git] / src / WINNT / afsadmsvr / TaAfsAdmSvrSearch.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 #include <winsock2.h>
11 #include <ws2tcpip.h>
12
13 extern "C" {
14 #include <afsconfig.h>
15 #include <afs/param.h>
16 #include <afs/stds.h>
17 #include <roken.h>
18 }
19
20 #include "TaAfsAdmSvrInternal.h"
21
22 #define c100ns1SECOND   ((LONGLONG)10000000)
23
24
25 /*
26  * ROUTINES ___________________________________________________________________
27  *
28  */
29
30 BOOL IsValidTime (LPSYSTEMTIME pst)
31 {
32    return (pst->wYear > 1970) ? TRUE : FALSE;
33 }
34
35
36 BOOL AfsAdmSvr_Search_Compare (LPTSTR pszName, LPTSTR pszPattern)
37 {
38    // An empty pattern matches everyone
39    //
40    if (!pszPattern || !*pszPattern)
41       return TRUE;
42
43    // Cache the expression so we only have to compile it when it changes.
44    // We also add a little convenience measure: you can prepend "!" to any
45    // regexp to negate the entire sense of the regexp--for instance, "!ri"
46    // matches every word which doesn't have "ri" in it.
47    //
48    static LPREGEXP pLastExpr = NULL;
49    static TCHAR szLastExpression[ 1024 ] = TEXT("");
50    static BOOL fLastInclusive = TRUE;
51
52    if (lstrcmp (pszPattern, szLastExpression))
53       {
54       if (pLastExpr)
55          Delete (pLastExpr);
56       lstrcpy (szLastExpression, pszPattern);
57       if ((fLastInclusive = (*pszPattern != TEXT('!'))) == FALSE)
58          ++pszPattern;
59       pLastExpr = New2 (REGEXP,(pszPattern));
60       }
61
62    if (!pLastExpr) // this shouldn't happen, but be safe anyway
63       return TRUE;
64
65    return ((pLastExpr->Matches (pszName)) == fLastInclusive);
66 }
67
68
69 BOOL AfsAdmSvr_Search_Compare (LPIDENT lpi, LPTSTR pszPattern)
70 {
71    if (lpi->GetRefCount() == 0)
72       return FALSE;
73
74    TCHAR szName[ cchSTRING ];
75    switch (lpi->GetType())
76       {
77       case itCELL:
78          lpi->GetCellName (szName);
79          break;
80       case itSERVER:
81          lpi->GetLongServerName (szName);
82          break;
83       case itSERVICE:
84          lpi->GetServiceName (szName);
85          break;
86       case itAGGREGATE:
87          lpi->GetAggregateName (szName);
88          break;
89       case itFILESET:
90          lpi->GetFilesetName (szName);
91          break;
92       case itUSER:
93          lpi->GetUserName (szName);
94          break;
95       case itGROUP:
96          lpi->GetGroupName (szName);
97          break;
98       default:
99          return FALSE;
100       }
101
102    return AfsAdmSvr_Search_Compare (szName, pszPattern);
103 }
104
105
106 BOOL AfsAdmSvr_SearchRefresh (ASID idSearchScope, ASOBJTYPE ObjectType, AFSADMSVR_SEARCH_REFRESH SearchRefresh, ULONG *pStatus)
107 {
108    BOOL rc = TRUE;
109    ULONG status = 0;
110
111    if (SearchRefresh == SEARCH_ALL_OBJECTS)
112       {
113       if (GetAsidType (idSearchScope) == itCELL)
114          {
115          LPCELL lpCell;
116          if ((lpCell = ((LPIDENT)idSearchScope)->OpenCell (&status)) == NULL)
117             rc = FALSE;
118          else
119             {
120             lpCell->RefreshAll();
121             lpCell->Close();
122             }
123          }
124       else // (GetAsidType (idSearchScope) != itCELL)
125          {
126          LPSERVER lpServer;
127          if ((lpServer = ((LPIDENT)idSearchScope)->OpenServer (&status)) == NULL)
128             rc = FALSE;
129          else
130             {
131             // What do we need to refresh on this server?
132             switch (ObjectType)
133                {
134                case TYPE_SERVICE:
135                   lpServer->RefreshStatus();
136                   lpServer->RefreshServices();
137                   break;
138
139                case TYPE_PARTITION:
140                case TYPE_VOLUME:
141                   lpServer->RefreshStatus();
142                   lpServer->RefreshAggregates();
143                   break;
144
145                default:
146                   lpServer->RefreshAll();
147                   break;
148                }
149             lpServer->Close();
150             }
151          }
152       }
153
154    if (!rc && pStatus)
155       *pStatus = status;
156    return rc;
157 }
158
159
160 BOOL AfsAdmSvr_Search_AllInCell (LPASIDLIST *ppList, ASID idCell, LPTSTR pszPattern, ULONG *pStatus)
161 {
162    BOOL rc = TRUE;
163    ULONG status = 0;
164
165    HENUM hEnum;
166    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
167       {
168       if (lpiFind->GetCell() != (LPIDENT)idCell)
169          continue;
170       if (!AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
171          continue;
172       AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
173       }
174    IDENT::FindClose (&hEnum);
175
176    if (!rc && pStatus)
177       *pStatus = status;
178    return rc;
179 }
180
181
182 BOOL AfsAdmSvr_Search_ServersInCell (LPASIDLIST *ppList, ASID idCell, LPTSTR pszPattern, ULONG *pStatus)
183 {
184    BOOL rc = TRUE;
185    ULONG status = 0;
186
187    LPCELL lpCell;
188    if ((lpCell = ((LPIDENT)idCell)->OpenCell (&status)) == NULL)
189       rc = FALSE;
190    else
191       {
192       HENUM hEnum;
193       for (LPSERVER lpServer = lpCell->ServerFindFirst (&hEnum, TRUE, &status); lpServer; lpServer = lpCell->ServerFindNext (&hEnum))
194          {
195          LPIDENT lpiFind = lpServer->GetIdentifier();
196          if (AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
197             AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
198          lpServer->Close();
199          }
200       lpCell->ServerFindClose (&hEnum);
201       if (status && (status != ADMITERATORDONE))
202          rc = FALSE;
203       lpCell->Close();
204       }
205
206    if (!rc && pStatus)
207       *pStatus = status;
208    return rc;
209 }
210
211
212 BOOL AfsAdmSvr_Search_ServicesInCell (LPASIDLIST *ppList, ASID idCell, LPTSTR pszPattern, ULONG *pStatus)
213 {
214    BOOL rc = TRUE;
215    ULONG status = 0;
216
217    HENUM hEnum;
218    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
219       {
220       if (lpiFind->GetType() != itSERVICE)
221          continue;
222       if (lpiFind->GetCell() != (LPIDENT)idCell)
223          continue;
224       if (!AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
225          continue;
226       AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
227       }
228    IDENT::FindClose (&hEnum);
229
230    if (!rc && pStatus)
231       *pStatus = status;
232    return rc;
233 }
234
235
236 BOOL AfsAdmSvr_Search_PartitionsInCell (LPASIDLIST *ppList, ASID idCell, LPTSTR pszPattern, ULONG *pStatus)
237 {
238    BOOL rc = TRUE;
239    ULONG status = 0;
240
241    HENUM hEnum;
242    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
243       {
244       if (lpiFind->GetType() != itAGGREGATE)
245          continue;
246       if (lpiFind->GetCell() != (LPIDENT)idCell)
247          continue;
248       if (!AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
249          continue;
250       AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
251       }
252    IDENT::FindClose (&hEnum);
253
254    if (!rc && pStatus)
255       *pStatus = status;
256    return rc;
257 }
258
259
260 BOOL AfsAdmSvr_Search_VolumesInCell (LPASIDLIST *ppList, ASID idCell, LPTSTR pszPattern, ULONG *pStatus)
261 {
262    BOOL rc = TRUE;
263    ULONG status = 0;
264
265    HENUM hEnum;
266    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
267       {
268       if (lpiFind->GetType() != itFILESET)
269          continue;
270       if (lpiFind->GetCell() != (LPIDENT)idCell)
271          continue;
272       if (!AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
273          continue;
274       AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
275       }
276    IDENT::FindClose (&hEnum);
277
278    if (!rc && pStatus)
279       *pStatus = status;
280    return rc;
281 }
282
283
284 BOOL AfsAdmSvr_Search_UsersInCell (LPASIDLIST *ppList, ASID idCell, LPTSTR pszPattern, ULONG *pStatus)
285 {
286    BOOL rc = TRUE;
287    ULONG status = 0;
288
289    LPCELL lpCell;
290    if ((lpCell = ((LPIDENT)idCell)->OpenCell (&status)) == NULL)
291       rc = FALSE;
292    else
293       {
294       HENUM hEnum;
295       for (LPUSER lpUser = lpCell->UserFindFirst (&hEnum, TRUE, &status); lpUser; lpUser = lpCell->UserFindNext (&hEnum))
296          {
297          LPIDENT lpiFind = lpUser->GetIdentifier();
298          if (AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
299             AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
300          lpUser->Close();
301          }
302       lpCell->UserFindClose (&hEnum);
303       if (status && (status != ADMITERATORDONE))
304          rc = FALSE;
305       lpCell->Close();
306       }
307
308    if (!rc && pStatus)
309       *pStatus = status;
310    return rc;
311 }
312
313
314 BOOL AfsAdmSvr_Search_GroupsInCell (LPASIDLIST *ppList, ASID idCell, LPTSTR pszPattern, ULONG *pStatus)
315 {
316    BOOL rc = TRUE;
317    ULONG status = 0;
318
319    LPCELL lpCell;
320    if ((lpCell = ((LPIDENT)idCell)->OpenCell (&status)) == NULL)
321       rc = FALSE;
322    else
323       {
324       HENUM hEnum;
325       for (LPPTSGROUP lpGroup = lpCell->GroupFindFirst (&hEnum, TRUE, &status); lpGroup; lpGroup = lpCell->GroupFindNext (&hEnum))
326          {
327          LPIDENT lpiFind = lpGroup->GetIdentifier();
328          if (AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
329             AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
330          lpGroup->Close();
331          }
332       lpCell->GroupFindClose (&hEnum);
333       if (status && (status != ADMITERATORDONE))
334          rc = FALSE;
335       lpCell->Close();
336       }
337
338    if (!rc && pStatus)
339       *pStatus = status;
340    return rc;
341 }
342
343
344 BOOL AfsAdmSvr_Search_AllInServer (LPASIDLIST *ppList, ASID idServer, LPTSTR pszPattern, ULONG *pStatus)
345 {
346    BOOL rc = TRUE;
347    ULONG status = 0;
348
349    LPSERVER lpServer;
350    if ((lpServer = ((LPIDENT)idServer)->OpenServer (&status)) == NULL)
351       rc = FALSE;
352    else
353       {
354       HENUM hEnum;
355       for (LPAGGREGATE lpAggregate = lpServer->AggregateFindFirst (&hEnum, TRUE, &status); lpAggregate; lpAggregate = lpServer->AggregateFindNext (&hEnum))
356          {
357          LPIDENT lpiFind = lpAggregate->GetIdentifier();
358          if (AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
359             AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
360          lpAggregate->Close();
361          }
362       lpServer->AggregateFindClose (&hEnum);
363       if (status && (status != ADMITERATORDONE))
364          rc = FALSE;
365       else
366          {
367          for (LPSERVICE lpService = lpServer->ServiceFindFirst (&hEnum, TRUE, &status); lpService; lpService = lpServer->ServiceFindNext (&hEnum))
368             {
369             LPIDENT lpiFind = lpService->GetIdentifier();
370             if (AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
371                AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
372             lpService->Close();
373             }
374          lpServer->ServiceFindClose (&hEnum);
375          if (status && (status != ADMITERATORDONE))
376             rc = FALSE;
377          }
378       lpServer->Close();
379       }
380
381    if (!rc && pStatus)
382       *pStatus = status;
383    return rc;
384 }
385
386
387 BOOL AfsAdmSvr_Search_ServicesInServer (LPASIDLIST *ppList, ASID idServer, LPTSTR pszPattern, ULONG *pStatus)
388 {
389    BOOL rc = TRUE;
390    ULONG status = 0;
391
392    LPSERVER lpServer;
393    if ((lpServer = ((LPIDENT)idServer)->OpenServer (&status)) == NULL)
394       rc = FALSE;
395    else
396       {
397       HENUM hEnum;
398       for (LPSERVICE lpService = lpServer->ServiceFindFirst (&hEnum, TRUE, &status); lpService; lpService = lpServer->ServiceFindNext (&hEnum))
399          {
400          LPIDENT lpiFind = lpService->GetIdentifier();
401          if (AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
402             AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
403          lpService->Close();
404          }
405       lpServer->ServiceFindClose (&hEnum);
406       if (status && (status != ADMITERATORDONE))
407          rc = FALSE;
408       lpServer->Close();
409       }
410
411    if (!rc && pStatus)
412       *pStatus = status;
413    return rc;
414 }
415
416
417 BOOL AfsAdmSvr_Search_PartitionsInServer (LPASIDLIST *ppList, ASID idServer, LPTSTR pszPattern, ULONG *pStatus)
418 {
419    BOOL rc = TRUE;
420    ULONG status = 0;
421
422    LPSERVER lpServer;
423    if ((lpServer = ((LPIDENT)idServer)->OpenServer (&status)) == NULL)
424       rc = FALSE;
425    else
426       {
427       HENUM hEnum;
428       for (LPAGGREGATE lpAggregate = lpServer->AggregateFindFirst (&hEnum, TRUE, &status); lpAggregate; lpAggregate = lpServer->AggregateFindNext (&hEnum))
429          {
430          LPIDENT lpiFind = lpAggregate->GetIdentifier();
431          if (AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
432             AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
433          lpAggregate->Close();
434          }
435       lpServer->AggregateFindClose (&hEnum);
436       if (status && (status != ADMITERATORDONE))
437          rc = FALSE;
438       lpServer->Close();
439       }
440
441    if (!rc && pStatus)
442       *pStatus = status;
443    return rc;
444 }
445
446
447 BOOL AfsAdmSvr_Search_VolumesInServer (LPASIDLIST *ppList, ASID idServer, LPTSTR pszPattern, ULONG *pStatus)
448 {
449    BOOL rc = TRUE;
450    ULONG status = 0;
451
452    HENUM hEnum;
453    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
454       {
455       if (lpiFind->GetType() != itFILESET)
456          continue;
457       if (lpiFind->GetServer() != (LPIDENT)idServer)
458          continue;
459       if (!AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
460          continue;
461       AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
462       }
463    IDENT::FindClose (&hEnum);
464
465    if (!rc && pStatus)
466       *pStatus = status;
467    return rc;
468 }
469
470
471 BOOL AfsAdmSvr_Search_VolumesInPartition (LPASIDLIST *ppList, ASID idPartition, LPTSTR pszPattern, ULONG *pStatus)
472 {
473    BOOL rc = TRUE;
474    ULONG status = 0;
475
476    LPAGGREGATE lpAggregate;
477    if ((lpAggregate = ((LPIDENT)idPartition)->OpenAggregate (&status)) == NULL)
478       rc = FALSE;
479    else
480       {
481       HENUM hEnum;
482       for (LPFILESET lpFileset = lpAggregate->FilesetFindFirst (&hEnum, TRUE, &status); lpFileset; lpFileset = lpAggregate->FilesetFindNext (&hEnum))
483          {
484          LPIDENT lpiFind = lpFileset->GetIdentifier();
485          if (AfsAdmSvr_Search_Compare (lpiFind, pszPattern))
486             AfsAdmSvr_AddToAsidList (ppList, (ASID)lpiFind, 0);
487          lpFileset->Close();
488          }
489       lpAggregate->FilesetFindClose (&hEnum);
490       if (status && (status != ADMITERATORDONE))
491          rc = FALSE;
492       lpAggregate->Close();
493       }
494
495    if (!rc && pStatus)
496       *pStatus = status;
497    return rc;
498 }
499
500
501 BOOL AfsAdmSvr_Search_ServerInCell (ASID *pidObject, ASID idCell, LPTSTR pszName, ULONG *pStatus)
502 {
503    BOOL rc = TRUE;
504    ULONG status = 0;
505
506    LPCELL lpCell;
507    if ((lpCell = ((LPIDENT)idCell)->OpenCell (&status)) == NULL)
508       rc = FALSE;
509    else
510       {
511       LPSERVER lpServer;
512       if ((lpServer = lpCell->OpenServer (pszName, &status)) == NULL)
513          rc = FALSE;
514       else
515          {
516          *pidObject = (ASID)(lpServer->GetIdentifier());
517          lpServer->Close();
518          }
519       lpCell->Close();
520       }
521
522    if (!rc && pStatus)
523       *pStatus = status;
524    return rc;
525 }
526
527
528 BOOL AfsAdmSvr_Search_ServiceInCell (ASID *pidObject, ASID idCell, LPTSTR pszName, ULONG *pStatus)
529 {
530    BOOL rc = FALSE;
531    ULONG status = ERROR_INVALID_PARAMETER;
532
533    HENUM hEnum;
534    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
535       {
536       if (lpiFind->GetType() != itSERVICE)
537          continue;
538       if (lpiFind->GetCell() != (LPIDENT)idCell)
539          continue;
540       if (lpiFind->GetRefCount() == 0)
541          return FALSE;
542
543       TCHAR szService[ cchNAME ];
544       lpiFind->GetServiceName (szService);
545       if (!lstrcmpi (pszName, szService))
546          {
547          *pidObject = (ASID)lpiFind;
548          rc = TRUE;
549          break;
550          }
551       }
552    IDENT::FindClose (&hEnum);
553
554    if (!rc && pStatus)
555       *pStatus = status;
556    return rc;
557 }
558
559
560 BOOL AfsAdmSvr_Search_PartitionInCell (ASID *pidObject, ASID idCell, LPTSTR pszName, ULONG *pStatus)
561 {
562    BOOL rc = FALSE;
563    ULONG status = ERROR_INVALID_PARAMETER;
564
565    HENUM hEnum;
566    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
567       {
568       if (lpiFind->GetType() != itAGGREGATE)
569          continue;
570       if (lpiFind->GetCell() != (LPIDENT)idCell)
571          continue;
572       if (lpiFind->GetRefCount() == 0)
573          return FALSE;
574
575       TCHAR szAggregate[ cchNAME ];
576       lpiFind->GetAggregateName (szAggregate);
577       if (!lstrcmpi (pszName, szAggregate))
578          {
579          *pidObject = (ASID)lpiFind;
580          rc = TRUE;
581          break;
582          }
583       }
584    IDENT::FindClose (&hEnum);
585
586    if (!rc && pStatus)
587       *pStatus = status;
588    return rc;
589 }
590
591
592 BOOL AfsAdmSvr_Search_VolumeInCell (ASID *pidObject, ASID idCell, LPTSTR pszName, ULONG *pStatus)
593 {
594    BOOL rc = FALSE;
595    ULONG status = ERROR_INVALID_PARAMETER;
596
597    HENUM hEnum;
598    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
599       {
600       if (lpiFind->GetType() != itFILESET)
601          continue;
602       if (lpiFind->GetCell() != (LPIDENT)idCell)
603          continue;
604       if (lpiFind->GetRefCount() == 0)
605          return FALSE;
606
607       TCHAR szFileset[ cchNAME ];
608       lpiFind->GetFilesetName (szFileset);
609       if (!lstrcmpi (szFileset, pszName))
610          {
611          *pidObject = (ASID)lpiFind;
612          rc = TRUE;
613          break;
614          }
615       }
616    IDENT::FindClose (&hEnum);
617
618    if (!rc && pStatus)
619       *pStatus = status;
620    return rc;
621 }
622
623
624 BOOL AfsAdmSvr_Search_UserInCell (ASID *pidObject, ASID idCell, LPTSTR pszName, ULONG *pStatus)
625 {
626    BOOL rc = TRUE;
627    ULONG status = 0;
628
629    LPCELL lpCell;
630    if ((lpCell = ((LPIDENT)idCell)->OpenCell (&status)) == NULL)
631       rc = FALSE;
632    else
633       {
634       LPUSER lpUser;
635       if ((lpUser = lpCell->OpenUser (pszName, NULL, &status)) == NULL)
636          rc = FALSE;
637       else
638          {
639          *pidObject = (ASID)(lpUser->GetIdentifier());
640          lpUser->Close();
641          }
642       lpCell->Close();
643       }
644
645    if (!rc && pStatus)
646       *pStatus = status;
647    return rc;
648 }
649
650
651 BOOL AfsAdmSvr_Search_GroupInCell (ASID *pidObject, ASID idCell, LPTSTR pszName, ULONG *pStatus)
652 {
653    BOOL rc = TRUE;
654    ULONG status = 0;
655
656    LPCELL lpCell;
657    if ((lpCell = ((LPIDENT)idCell)->OpenCell (&status)) == NULL)
658       rc = FALSE;
659    else
660       {
661       LPPTSGROUP lpGroup;
662       if ((lpGroup = lpCell->OpenGroup (pszName, &status)) == NULL)
663          rc = FALSE;
664       else
665          {
666          *pidObject = (ASID)(lpGroup->GetIdentifier());
667          lpGroup->Close();
668          }
669       lpCell->Close();
670       }
671
672    if (!rc && pStatus)
673       *pStatus = status;
674    return rc;
675 }
676
677
678 BOOL AfsAdmSvr_Search_ServiceInServer (ASID *pidObject, ASID idServer, LPTSTR pszName, ULONG *pStatus)
679 {
680    BOOL rc = TRUE;
681    ULONG status = 0;
682
683    LPSERVER lpServer;
684    if ((lpServer = ((LPIDENT)idServer)->OpenServer (&status)) == NULL)
685       rc = FALSE;
686    else
687       {
688       LPSERVICE lpService;
689       if ((lpService = lpServer->OpenService (pszName, &status)) == NULL)
690          rc = FALSE;
691       else
692          {
693          *pidObject = (ASID)(lpService->GetIdentifier());
694          lpService->Close();
695          }
696       lpServer->Close();
697       }
698
699    if (!rc && pStatus)
700       *pStatus = status;
701    return rc;
702 }
703
704
705 BOOL AfsAdmSvr_Search_PartitionInServer (ASID *pidObject, ASID idServer, LPTSTR pszName, ULONG *pStatus)
706 {
707    BOOL rc = TRUE;
708    ULONG status = 0;
709
710    LPSERVER lpServer;
711    if ((lpServer = ((LPIDENT)idServer)->OpenServer (&status)) == NULL)
712       rc = FALSE;
713    else
714       {
715       LPAGGREGATE lpAggregate;
716       if ((lpAggregate = lpServer->OpenAggregate (pszName, &status)) == NULL)
717          rc = FALSE;
718       else
719          {
720          *pidObject = (ASID)(lpAggregate->GetIdentifier());
721          lpAggregate->Close();
722          }
723       lpServer->Close();
724       }
725
726    if (!rc && pStatus)
727       *pStatus = status;
728    return rc;
729 }
730
731
732 BOOL AfsAdmSvr_Search_VolumeInServer (ASID *pidObject, ASID idServer, LPTSTR pszName, ULONG *pStatus)
733 {
734    BOOL rc = FALSE;
735    ULONG status = ERROR_INVALID_PARAMETER;
736
737    HENUM hEnum;
738    for (LPIDENT lpiFind = IDENT::FindFirst (&hEnum); lpiFind; lpiFind = IDENT::FindNext (&hEnum))
739       {
740       if (lpiFind->GetType() != itFILESET)
741          continue;
742       if (lpiFind->GetServer() != (LPIDENT)idServer)
743          continue;
744       if (lpiFind->GetRefCount() == 0)
745          return FALSE;
746
747       TCHAR szFileset[ cchNAME ];
748       lpiFind->GetFilesetName (szFileset);
749       if (!lstrcmpi (pszName, szFileset))
750          {
751          *pidObject = (ASID)lpiFind;
752          rc = TRUE;
753          break;
754          }
755       }
756    IDENT::FindClose (&hEnum);
757
758    if (!rc && pStatus)
759       *pStatus = status;
760    return rc;
761 }
762
763
764 BOOL AfsAdmSvr_Search_VolumeInPartition (ASID *pidObject, ASID idPartition, LPTSTR pszName, ULONG *pStatus)
765 {
766    BOOL rc = TRUE;
767    ULONG status = 0;
768
769    LPAGGREGATE lpAggregate;
770    if ((lpAggregate = ((LPIDENT)idPartition)->OpenAggregate (&status)) == NULL)
771       rc = FALSE;
772    else
773       {
774       LPFILESET lpFileset;
775       if ((lpFileset = lpAggregate->OpenFileset (pszName, &status)) == NULL)
776          rc = FALSE;
777       else
778          {
779          *pidObject = (ASID)(lpFileset->GetIdentifier());
780          lpFileset->Close();
781          }
782       lpAggregate->Close();
783       }
784
785    if (!rc && pStatus)
786       *pStatus = status;
787    return rc;
788 }
789
790
791 BOOL AfsAdmSvr_Search_OneUser (ASID *pidObject, ASID idScope, LPTSTR pszName, ULONG *pStatus)
792 {
793    BOOL rc = TRUE;
794    ULONG status = 0;
795
796    LPCELL lpCell;
797    if ((lpCell = ((LPIDENT)idScope)->OpenCell (&status)) == NULL)
798       rc = FALSE;
799    else
800       {
801       LPUSER lpUser;
802       if ((lpUser = lpCell->OpenUser (pszName, TEXT(""), &status)) == NULL)
803          rc = FALSE;
804       else
805          {
806          *pidObject = (ASID)(lpUser->GetIdentifier());
807          lpUser->Close();
808          }
809
810       lpCell->Close();
811       }
812
813    if (!rc && pStatus)
814       *pStatus = status;
815    return rc;
816 }
817
818 BOOL AfsAdmSvr_Search_OneGroup (ASID *pidObject, ASID idScope, LPTSTR pszName, ULONG *pStatus)
819 {
820    BOOL rc = TRUE;
821    ULONG status = 0;
822
823    LPCELL lpCell;
824    if ((lpCell = ((LPIDENT)idScope)->OpenCell (&status)) == NULL)
825       rc = FALSE;
826    else
827       {
828       LPPTSGROUP lpGroup;
829       if ((lpGroup = lpCell->OpenGroup (pszName, &status)) == NULL)
830          rc = FALSE;
831       else
832          {
833          *pidObject = (ASID)(lpGroup->GetIdentifier());
834          lpGroup->Close();
835          }
836
837       lpCell->Close();
838       }
839
840    if (!rc && pStatus)
841       *pStatus = status;
842    return rc;
843 }
844
845
846 void AfsAdmSvr_Search_Advanced (LPASIDLIST *ppList, LPAFSADMSVR_SEARCH_PARAMS pSearchParams)
847 {
848    ULONG status;
849
850    if (ppList && (*ppList) && pSearchParams && (pSearchParams->SearchType != SEARCH_NO_LIMITATIONS))
851       {
852       for (size_t iEntry = 0; iEntry < (*ppList)->cEntries; )
853          {
854          BOOL fDelete = TRUE;
855
856          // Try to grab the properties for this object. If we succeed,
857          // we can determine if the object matches the necessary criteria
858          // to indicate we should keep it in the list.
859          //
860          ASID idObject = (*ppList)->aEntries[ iEntry ].idObject;
861
862          LPASOBJPROP pProperties;
863          if ((pProperties = AfsAdmSvr_GetCurrentProperties (idObject, &status)) != NULL)
864             {
865             if ( (pProperties->verProperties >= verPROP_FIRST_SCAN) ||
866                  (AfsAdmSvr_ObtainFullProperties (pProperties, &status)) )
867                {
868                // We managed to get the full properties for this object.
869                // Now check its properties against our search criteria--
870                // only if it has exactly the necessary criteria will we
871                // clear {fDelete}.
872                //
873                switch (pSearchParams->SearchType)
874                   {
875                   case SEARCH_EXPIRES_BEFORE:
876                      if ((pProperties->Type == TYPE_USER) && (pProperties->u.UserProperties.fHaveKasInfo))
877                         {
878                         if (IsValidTime (&pProperties->u.UserProperties.KASINFO.timeExpires))
879                            {
880                            FILETIME ftExpires;
881                            SystemTimeToFileTime (&pProperties->u.UserProperties.KASINFO.timeExpires, &ftExpires);
882
883                            FILETIME ftThreshhold;
884                            SystemTimeToFileTime (&pSearchParams->SearchTime, &ftThreshhold);
885
886                            if (CompareFileTime (&ftExpires, &ftThreshhold) <= 0)
887                               fDelete = FALSE;
888                            }
889                         }
890                      break;
891
892                   case SEARCH_PASSWORD_EXPIRES_BEFORE:
893                      if ((pProperties->Type == TYPE_USER) && (pProperties->u.UserProperties.fHaveKasInfo))
894                         {
895                         if (pProperties->u.UserProperties.KASINFO.cdayPwExpire)
896                            {
897                            FILETIME ftPwExpires;
898                            SystemTimeToFileTime (&pProperties->u.UserProperties.KASINFO.timeLastPwChange, &ftPwExpires);
899
900                            // A FILETIME is a count-of-100ns-intervals since 1601.
901                            // We need to increase the {ftPwExpires} time by the
902                            // number of days in KASINFO.cdayPwExpires, so we'll
903                            // be adding a big number to our FILETIME structure.
904                            //
905                            LARGE_INTEGER ldw;
906                            ldw.HighPart = ftPwExpires.dwHighDateTime;
907                            ldw.LowPart = ftPwExpires.dwLowDateTime;
908                            ldw.QuadPart += c100ns1SECOND * (LONGLONG)csec1DAY * (LONGLONG)pProperties->u.UserProperties.KASINFO.cdayPwExpire;
909                            ftPwExpires.dwHighDateTime = (DWORD)ldw.HighPart;
910                            ftPwExpires.dwLowDateTime = (DWORD)ldw.LowPart;
911
912                            FILETIME ftThreshhold;
913                            SystemTimeToFileTime (&pSearchParams->SearchTime, &ftThreshhold);
914
915                            if (CompareFileTime (&ftPwExpires, &ftThreshhold) <= 0)
916                               fDelete = FALSE;
917                            }
918                         }
919                      break;
920                   }
921                }
922             }
923
924          // Okay, we've made our choice--remove it, or not.
925          //
926          if (fDelete)
927             AfsAdmSvr_RemoveFromAsidListByIndex (ppList, iEntry);
928          else
929             ++iEntry;
930          }
931       }
932 }
933