Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / WINNT / afsadmsvr / TaAfsAdmSvrGroup.cpp
1 extern "C" {
2 #include <afs/param.h>
3 #include <afs/stds.h>
4 }
5
6 #include "TaAfsAdmSvrInternal.h"
7
8
9 /*
10  * ROUTINES ___________________________________________________________________
11  *
12  */
13
14
15       // AfsAdmSvr_ChangeGroup
16       // ...changes a group account's properties.
17       //
18 int AfsAdmSvr_ChangeGroup (DWORD idClient, ASID idCell, ASID idGroup, LPAFSADMSVR_CHANGEGROUP_PARAMS pChange, ULONG *pStatus)
19 {
20    ASACTION Action;
21    Action.Action = ACTION_GROUP_CHANGE;
22    Action.idClient = idClient;
23    Action.idCell = idCell;
24    Action.u.Group_Change.idGroup = idGroup;
25    size_t iOp = AfsAdmSvr_BeginOperation (idClient, &Action);
26
27    Print (dlDETAIL, TEXT("Client 0x%08lX: ChangeGroup (idGroup=0x%08lX)"), idClient, idGroup);
28
29    if (!AfsAdmSvr_fIsValidClient (idClient))
30       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
31
32    // Find this group's current properties
33    //
34    LPASOBJPROP pCurrentProperties;
35    if ((pCurrentProperties = AfsAdmSvr_GetCurrentProperties (idGroup, pStatus)) == NULL)
36       {
37       Print (dlERROR, TEXT("Client 0x%08lX: ChangeGroup failed; no properties"), idClient);
38       AfsAdmSvr_EndOperation (iOp);
39       return FALSE;
40       }
41
42    // Build an AFSCLASS-style GROUPPROPERTIES structure that reflects the
43    // new properties for the user; mark the structure's dwMask bit to indicate
44    // what we're changing.
45    //
46    GROUPPROPERTIES NewProperties;
47    memset (&NewProperties, 0x00, sizeof(NewProperties));
48
49    if (!pChange->szOwner[0])
50       lstrcpy (NewProperties.szOwner, pCurrentProperties->u.GroupProperties.szOwner);
51    else
52       {
53       lstrcpy (NewProperties.szOwner, pChange->szOwner);
54       if (lstrcmpi (NewProperties.szOwner, pCurrentProperties->u.GroupProperties.szOwner))
55          NewProperties.dwMask |= MASK_GROUPPROP_szOwner;
56       }
57
58    if ((NewProperties.aaListStatus = pChange->aaListStatus) != pCurrentProperties->u.GroupProperties.aaListStatus)
59       NewProperties.dwMask |= MASK_GROUPPROP_aaListStatus;
60    if ((NewProperties.aaListGroupsOwned = pChange->aaListGroupsOwned) != pCurrentProperties->u.GroupProperties.aaListGroupsOwned)
61       NewProperties.dwMask |= MASK_GROUPPROP_aaListGroupsOwned;
62    if ((NewProperties.aaListMembers = pChange->aaListMembers) != pCurrentProperties->u.GroupProperties.aaListMembers)
63       NewProperties.dwMask |= MASK_GROUPPROP_aaListMembers;
64    if ((NewProperties.aaAddMember = pChange->aaAddMember) != pCurrentProperties->u.GroupProperties.aaAddMember)
65       NewProperties.dwMask |= MASK_GROUPPROP_aaAddMember;
66    if ((NewProperties.aaDeleteMember = pChange->aaDeleteMember) != pCurrentProperties->u.GroupProperties.aaDeleteMember)
67       NewProperties.dwMask |= MASK_GROUPPROP_aaDeleteMember;
68
69    // If we've decided to change anything, call AfsClass to actually do it
70    //
71    if (NewProperties.dwMask == 0)
72       {
73       Print (dlDETAIL, TEXT("Client 0x%08lX: ChangeGroup succeeded (nothing to do)"), idClient);
74       }
75    else
76       {
77       ULONG status;
78       if (!AfsClass_SetGroupProperties ((LPIDENT)idGroup, &NewProperties, &status))
79          {
80          Print (dlERROR, TEXT("Client 0x%08lX: ChangeGroup failed; error 0x%08lX"), idClient, status);
81          return FALSE_(status,pStatus,iOp);
82          }
83
84       Print (dlDETAIL, TEXT("Client 0x%08lX: ChangeGroup succeeded"), idClient);
85       }
86
87    AfsAdmSvr_EndOperation (iOp);
88    return TRUE;
89 }
90
91
92       // AfsAdmSvr_GetGroupMembers
93       // ...retrieves the list of users which belong to a group
94       //
95 int AfsAdmSvr_GetGroupMembers (DWORD idClient, ASID idCell, ASID idGroup, LPASIDLIST *ppAsidList, ULONG *pStatus)
96 {
97    size_t iOp = AfsAdmSvr_BeginOperation (idClient);
98
99    Print (dlDETAIL, TEXT("Client 0x%08lX: GetGroupMembers (idGroup=0x%08lX)"), idClient, idGroup);
100
101    if (!AfsAdmSvr_fIsValidClient (idClient))
102       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
103
104    // Use AfsClass to get the list of group members
105    //
106    if (GetAsidType (idGroup) != itGROUP)
107       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
108
109    ULONG status;
110    LPPTSGROUP lpGroup;
111    if ((lpGroup = ((LPIDENT)idGroup)->OpenGroup (&status)) == NULL)
112       return FALSE_(status,pStatus,iOp);
113
114    LPTSTR pmszUsers = NULL;
115    lpGroup->GetMembers (&pmszUsers);
116    lpGroup->Close();
117
118    // Then translate those user names into an ASID list
119    //
120    if ((*ppAsidList = AfsAdmSvr_CreateAsidList()) == NULL)
121       {
122       if (pmszUsers)
123          FreeString (pmszUsers);
124       return FALSE_(ERROR_NOT_ENOUGH_MEMORY,pStatus,iOp);
125       }
126
127    if (pmszUsers)
128       {
129       for (LPTSTR psz = pmszUsers; psz && *psz; psz += 1+lstrlen(psz))
130          {
131          LPIDENT lpi;
132          if ((lpi = IDENT::FindGroup ((LPIDENT)idCell, psz)) == NULL)
133             {
134             TCHAR szName[ cchNAME ];
135             TCHAR szInstance[ cchNAME ];
136             USER::SplitUserName (psz, szName, szInstance);
137
138             if ((lpi = IDENT::FindUser ((LPIDENT)idCell, szName, szInstance)) == NULL)
139                {
140                continue;
141                }
142             }
143
144          AfsAdmSvr_AddToAsidList (ppAsidList, (ASID)lpi, 0);
145          }
146       FreeString (pmszUsers);
147       }
148
149    Print (dlDETAIL, TEXT("Client 0x%08lX: GetGroupMembers succeeded"), idClient);
150    AfsAdmSvr_EndOperation (iOp);
151    return TRUE;
152 }
153
154
155       // AfsAdmSvr_GetGroupMembership
156       // ...retrieves the list of groups to which a user or group belongs
157       //
158 int AfsAdmSvr_GetGroupMembership (DWORD idClient, ASID idCell, ASID idMember, LPASIDLIST *ppAsidList, ULONG *pStatus)
159 {
160    size_t iOp = AfsAdmSvr_BeginOperation (idClient);
161
162    Print (dlDETAIL, TEXT("Client 0x%08lX: GetGroupMembership (idMember=0x%08lX)"), idClient, idMember);
163
164    if (!AfsAdmSvr_fIsValidClient (idClient))
165       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
166
167    // Use AfsClass to get the appropriate list of groups
168    //
169    ULONG status;
170    LPTSTR pmszGroups = NULL;
171
172    if (GetAsidType (idMember) == itUSER)
173       {
174       LPUSER lpUser;
175       if ((lpUser = ((LPIDENT)idMember)->OpenUser (&status)) == NULL)
176          return FALSE_(status,pStatus,iOp);
177       lpUser->GetMemberOf (&pmszGroups);
178       lpUser->Close();
179       }
180    else if (GetAsidType (idMember) == itGROUP)
181       {
182       LPPTSGROUP lpGroup;
183       if ((lpGroup = ((LPIDENT)idMember)->OpenGroup (&status)) == NULL)
184          return FALSE_(status,pStatus,iOp);
185       lpGroup->GetMemberOf (&pmszGroups);
186       lpGroup->Close();
187       }
188    else // bogus type
189       {
190       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
191       }
192
193    // Then translate those group names into an ASID list
194    //
195    if ((*ppAsidList = AfsAdmSvr_CreateAsidList()) == NULL)
196       {
197       if (pmszGroups)
198          FreeString (pmszGroups);
199       return FALSE_(ERROR_NOT_ENOUGH_MEMORY,pStatus,iOp);
200       }
201
202    if (pmszGroups)
203       {
204       for (LPTSTR psz = pmszGroups; psz && *psz; psz += 1+lstrlen(psz))
205          {
206          LPIDENT lpi;
207          if ((lpi = IDENT::FindGroup ((LPIDENT)idCell, psz)) == NULL)
208             continue;
209          AfsAdmSvr_AddToAsidList (ppAsidList, (ASID)lpi, 0);
210          }
211       FreeString (pmszGroups);
212       }
213
214    Print (dlDETAIL, TEXT("Client 0x%08lX: GetGroupMembership succeeded"), idClient);
215    AfsAdmSvr_EndOperation (iOp);
216    return TRUE;
217 }
218
219
220       // AfsAdmSvr_GetGroupOwnership
221       // ...retrieves the list of groups which a user owns
222       //
223 int AfsAdmSvr_GetGroupOwnership (DWORD idClient, ASID idCell, ASID idOwner, LPASIDLIST *ppAsidList, ULONG *pStatus)
224 {
225    size_t iOp = AfsAdmSvr_BeginOperation (idClient);
226
227    Print (dlDETAIL, TEXT("Client 0x%08lX: GetGroupOwnership (idOwner=0x%08lX)"), idClient, idOwner);
228
229    if (!AfsAdmSvr_fIsValidClient (idClient))
230       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
231
232    // Use AfsClass to get the appropriate list of groups
233    //
234    ULONG status;
235    LPTSTR pmszGroups = NULL;
236
237    if (GetAsidType (idOwner) == itUSER)
238       {
239       LPUSER lpUser;
240       if ((lpUser = ((LPIDENT)idOwner)->OpenUser (&status)) == NULL)
241          return FALSE_(status,pStatus,iOp);
242       lpUser->GetOwnerOf (&pmszGroups);
243       lpUser->Close();
244       }
245    else if (GetAsidType (idOwner) == itGROUP)
246       {
247       LPPTSGROUP lpGroup;
248       if ((lpGroup = ((LPIDENT)idOwner)->OpenGroup (&status)) == NULL)
249          return FALSE_(status,pStatus,iOp);
250       lpGroup->GetOwnerOf (&pmszGroups);
251       lpGroup->Close();
252       }
253    else // bogus type
254       {
255       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
256       }
257
258    // Then translate those group names into an ASID list
259    //
260    if ((*ppAsidList = AfsAdmSvr_CreateAsidList()) == NULL)
261       {
262       if (pmszGroups)
263          FreeString (pmszGroups);
264       return FALSE_(ERROR_NOT_ENOUGH_MEMORY,pStatus,iOp);
265       }
266
267    if (pmszGroups)
268       {
269       for (LPTSTR psz = pmszGroups; psz && *psz; psz += 1+lstrlen(psz))
270          {
271          LPIDENT lpi;
272          if ((lpi = IDENT::FindGroup ((LPIDENT)idCell, psz)) == NULL)
273             continue;
274          AfsAdmSvr_AddToAsidList (ppAsidList, (ASID)lpi, 0);
275          }
276       FreeString (pmszGroups);
277       }
278
279    Print (dlDETAIL, TEXT("Client 0x%08lX: GetGroupOwnership succeeded"), idClient);
280    AfsAdmSvr_EndOperation (iOp);
281    return TRUE;
282 }
283
284
285       // AfsAdmSvr_AddGroupMember
286       // ...adds a member to the specified group
287       //
288 int AfsAdmSvr_AddGroupMember (DWORD idClient, ASID idCell, ASID idGroup, ASID idMember, ULONG *pStatus)
289 {
290    ASACTION Action;
291    Action.Action = ACTION_GROUP_MEMBER_ADD;
292    Action.idClient = idClient;
293    Action.idCell = idCell;
294    Action.u.Group_Member_Add.idGroup = idGroup;
295    Action.u.Group_Member_Add.idUser = idMember;
296    size_t iOp = AfsAdmSvr_BeginOperation (idClient, &Action);
297
298    Print (dlDETAIL, TEXT("Client 0x%08lX: AddGroupMember (idGroup=0x%08lX, idUser=0x%08lX)"), idClient, idGroup, idMember);
299
300    if (!AfsAdmSvr_fIsValidClient (idClient))
301       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
302
303    // Modify the group as requested
304    //
305    ULONG status;
306    if (!AfsClass_AddUserToGroup ((LPIDENT)idGroup, (LPIDENT)idMember, &status))
307       return FALSE_(status,pStatus,iOp);
308
309    Print (dlDETAIL, TEXT("Client 0x%08lX: AddGroupMember succeeded"), idClient);
310    AfsAdmSvr_EndOperation (iOp);
311    return TRUE;
312 }
313
314
315       // AfsAdmSvr_RemoveGroupMember
316       // ...removes a member from the specified group
317       //
318 int AfsAdmSvr_RemoveGroupMember (DWORD idClient, ASID idCell, ASID idGroup, ASID idMember, ULONG *pStatus)
319 {
320    ASACTION Action;
321    Action.Action = ACTION_GROUP_MEMBER_REMOVE;
322    Action.idClient = idClient;
323    Action.idCell = idCell;
324    Action.u.Group_Member_Remove.idGroup = idGroup;
325    Action.u.Group_Member_Remove.idUser = idMember;
326    size_t iOp = AfsAdmSvr_BeginOperation (idClient, &Action);
327
328    Print (dlDETAIL, TEXT("Client 0x%08lX: RemoveGroupMember (idGroup=0x%08lX, idUser=0x%08lX)"), idClient, idGroup, idMember);
329
330    if (!AfsAdmSvr_fIsValidClient (idClient))
331       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
332
333    // Modify the group as requested
334    //
335    ULONG status;
336    if (!AfsClass_RemoveUserFromGroup ((LPIDENT)idGroup, (LPIDENT)idMember, &status))
337       return FALSE_(status,pStatus,iOp);
338
339    Print (dlDETAIL, TEXT("Client 0x%08lX: RemoveGroupMember succeeded"), idClient);
340    AfsAdmSvr_EndOperation (iOp);
341    return TRUE;
342 }
343
344
345       // AfsAdmSvr_RenameGroup
346       // ...changes a group's name
347       //
348 int AfsAdmSvr_RenameGroup (DWORD idClient, ASID idCell, ASID idGroup, STRING szNewGroupName, ULONG *pStatus)
349 {
350    ASACTION Action;
351    Action.Action = ACTION_GROUP_RENAME;
352    Action.idClient = idClient;
353    Action.idCell = idCell;
354    Action.u.Group_Rename.idGroup = idGroup;
355    lstrcpy (Action.u.Group_Rename.szNewName, szNewGroupName);
356    size_t iOp = AfsAdmSvr_BeginOperation (idClient, &Action);
357
358    Print (dlDETAIL, TEXT("Client 0x%08lX: RenameGroup (idGroup=0x%08lX, szNewName=%s)"), idClient, idGroup, szNewGroupName);
359
360    if (!AfsAdmSvr_fIsValidClient (idClient))
361       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
362
363    // Modify the group as requested
364    //
365    ULONG status;
366    if (!AfsClass_RenameGroup ((LPIDENT)idGroup, szNewGroupName, &status))
367       return FALSE_(status,pStatus,iOp);
368
369    Print (dlDETAIL, TEXT("Client 0x%08lX: RenameGroup succeeded"), idClient);
370    AfsAdmSvr_EndOperation (iOp);
371    return TRUE;
372 }
373
374
375       // AfsAdmSvr_CreateGroup
376       // ...creates a new PTS group
377       //
378 int AfsAdmSvr_CreateGroup (DWORD idClient, ASID idCell, LPAFSADMSVR_CREATEGROUP_PARAMS pCreate, ASID *pidGroup, ULONG *pStatus)
379 {
380    ASACTION Action;
381    Action.Action = ACTION_GROUP_CREATE;
382    Action.idClient = idClient;
383    Action.idCell = idCell;
384    lstrcpy (Action.u.Group_Create.szGroup, pCreate->szName);
385    size_t iOp = AfsAdmSvr_BeginOperation (idClient, &Action);
386
387    Print (dlDETAIL, TEXT("Client 0x%08lX: CreateGroup (szGroup=%s)"), idClient, pCreate->szName);
388
389    if (!AfsAdmSvr_fIsValidClient (idClient))
390       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
391
392    // Find the owner (if we can)
393    //
394    LPIDENT lpiOwner;
395    if ((lpiOwner = IDENT::FindUser ((LPIDENT)idCell, pCreate->szOwner)) == NULL)
396       lpiOwner = IDENT::FindGroup ((LPIDENT)idCell, pCreate->szOwner);
397
398    // Create the group account
399    //
400    ULONG status;
401    LPIDENT lpiGroup;
402    if ((lpiGroup = AfsClass_CreateGroup ((LPIDENT)idCell, pCreate->szName, lpiOwner, pCreate->idGroup, &status)) == NULL)
403       {
404       Print (dlERROR, TEXT("Client 0x%08lX: CreateGroup failed; error 0x%08lX"), idClient, status);
405       return FALSE_(status,pStatus,iOp);
406       }
407
408    if (pidGroup)
409       *pidGroup = (ASID)lpiGroup;
410
411    // Creating a group account may change the max group ID
412    AfsAdmSvr_TestProperties (idCell);
413
414    Print (dlDETAIL, TEXT("Client 0x%08lX: CreateGroup succeeded"), idClient);
415    AfsAdmSvr_EndOperation (iOp);
416    return TRUE;
417 }
418
419
420       // AfsAdmSvr_DeleteGroup
421       // ...deletes a PTS group
422       //
423 int AfsAdmSvr_DeleteGroup (DWORD idClient, ASID idCell, ASID idGroup, ULONG *pStatus)
424 {
425    ASACTION Action;
426    Action.Action = ACTION_GROUP_DELETE;
427    Action.idClient = idClient;
428    Action.idCell = idCell;
429    Action.u.Group_Delete.idGroup = idGroup;
430    size_t iOp = AfsAdmSvr_BeginOperation (idClient, &Action);
431
432    Print (dlDETAIL, TEXT("Client 0x%08lX: DeleteGroup (idGroup=0x%08lX)"), idClient, idGroup);
433
434    if (!AfsAdmSvr_fIsValidClient (idClient))
435       return FALSE_(ERROR_INVALID_PARAMETER,pStatus,iOp);
436
437    // Delete the group
438    //
439    ULONG status;
440    if (!AfsClass_DeleteGroup ((LPIDENT)idGroup, &status))
441       {
442       Print (dlERROR, TEXT("Client 0x%08lX: DeleteGroup failed; error 0x%08lX"), idClient, status);
443       return FALSE_(status,pStatus,iOp);
444       }
445
446    Print (dlDETAIL, TEXT("Client 0x%08lX: DeleteGroup succeeded"), idClient);
447    AfsAdmSvr_EndOperation (iOp);
448    return TRUE;
449 }
450