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