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