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