libadmin: Don't pass garbage to pts_GroupCreate
[openafs.git] / src / libadmin / test / pts.c
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 /*
11  * This file implements the pts related funtions for afscp
12  */
13
14 #include <afsconfig.h>
15 #include <afs/param.h>
16
17 #include <roken.h>
18
19 #include "pts.h"
20
21 /*
22  * Utility functions
23  */
24
25 /*
26  * Generic fuction for converting input string to an integer.  Pass
27  * the error_msg you want displayed if there is an error converting
28  * the string.
29  */
30
31 static int
32 GetIntFromString(const char *int_str, const char *error_msg)
33 {
34     int i;
35     char *bad_char = NULL;
36
37     i = strtoul(int_str, &bad_char, 10);
38     if ((bad_char == NULL) || (*bad_char == 0)) {
39         return i;
40     }
41
42     ERR_EXT(error_msg);
43 }
44
45 /*
46  * Generic fuction for converting input string to an pts_groupAccess_t.  Pass
47  * the error_msg you want displayed if there is an error converting
48  * the string.
49  */
50
51 static pts_groupAccess_t
52 GetGroupAccessFromString(const char *in_str, const char *error_msg)
53 {
54     pts_groupAccess_t access;
55
56     if (!strcasecmp("owner", in_str)) {
57         access = PTS_GROUP_OWNER_ACCESS;
58     } else if (!strcasecmp("group", in_str)) {
59         access = PTS_GROUP_ACCESS;
60     } else if (!strcasecmp("any", in_str)) {
61         access = PTS_GROUP_ANYUSER_ACCESS;
62     } else {
63         ERR_EXT(error_msg);
64     }
65
66     return access;
67 }
68
69 /*
70  * Generic fuction for converting input string to an pts_userAccess_t.  Pass
71  * the error_msg you want displayed if there is an error converting
72  * the string.
73  */
74
75 static pts_userAccess_t
76 GetUserAccessFromString(const char *in_str, const char *error_msg)
77 {
78     pts_userAccess_t access;
79
80     if (!strcasecmp("owner", in_str)) {
81         access = PTS_USER_OWNER_ACCESS;
82     } else if (!strcasecmp("any", in_str)) {
83         access = PTS_USER_ANYUSER_ACCESS;
84     } else {
85         ERR_EXT(error_msg);
86     }
87
88     return access;
89 }
90
91 int
92 DoPtsGroupMemberAdd(struct cmd_syndesc *as, void *arock)
93 {
94     enum { USER, GROUP };
95     afs_status_t st = 0;
96     const char *user = as->parms[USER].items->data;
97     const char *group = as->parms[GROUP].items->data;
98
99     if (!pts_GroupMemberAdd(cellHandle, user, group, &st)) {
100         ERR_ST_EXT("pts_GroupMemberAdd", st);
101     }
102
103     return 0;
104 }
105
106 int
107 DoPtsGroupOwnerChange(struct cmd_syndesc *as, void *arock)
108 {
109     enum { OWNER, GROUP };
110     afs_status_t st = 0;
111     const char *owner = as->parms[OWNER].items->data;
112     const char *group = as->parms[GROUP].items->data;
113
114     if (!pts_GroupOwnerChange(cellHandle, group, owner, &st)) {
115         ERR_ST_EXT("pts_GroupOwnerChange", st);
116     }
117
118     return 0;
119 }
120
121 int
122 DoPtsGroupCreate(struct cmd_syndesc *as, void *arock)
123 {
124     enum { OWNER, GROUP };
125     afs_status_t st = 0;
126     char *owner = as->parms[OWNER].items->data;
127     char *group = as->parms[GROUP].items->data;
128     int new_group_id = 0;
129
130     if (!pts_GroupCreate(cellHandle, group, owner, &new_group_id, &st)) {
131         ERR_ST_EXT("pts_GroupMemberAdd", st);
132     }
133
134     printf("Group id %d\n", new_group_id);
135
136     return 0;
137 }
138
139 static void
140 Print_pts_groupAccess_p(pts_groupAccess_p access, const char *prefix)
141 {
142     if (*access == PTS_GROUP_OWNER_ACCESS) {
143         printf("%sPTS_GROUP_OWNER_ACCESS\n", prefix);
144     } else if (*access == PTS_GROUP_ACCESS) {
145         printf("%sPTS_GROUP_ACCESS\n", prefix);
146     } else if (*access == PTS_GROUP_ANYUSER_ACCESS) {
147         printf("%sPTS_GROUP_ANYUSER_ACCESS\n", prefix);
148     }
149 }
150
151 static void
152 Print_pts_GroupEntry_p(pts_GroupEntry_p entry, const char *prefix)
153 {
154     printf("%sName %s Uid %d\n", prefix, entry->name, entry->nameUid);
155     printf("%sOwner %s Uid %d\n", prefix, entry->owner, entry->ownerUid);
156     printf("%sCreator %s Uid %d\n", prefix, entry->creator,
157            entry->creatorUid);
158     printf("%sMembership count %d\n", prefix, entry->membershipCount);
159     printf("%sList status permission:\n", prefix);
160     Print_pts_groupAccess_p(&entry->listStatus, "    ");
161     printf("%sList groups owned permission:\n", prefix);
162     Print_pts_groupAccess_p(&entry->listGroupsOwned, "    ");
163     printf("%sList membership permission:\n", prefix);
164     Print_pts_groupAccess_p(&entry->listMembership, "    ");
165     printf("%sList add permission:\n", prefix);
166     Print_pts_groupAccess_p(&entry->listAdd, "    ");
167     printf("%sList delete permission:\n", prefix);
168     Print_pts_groupAccess_p(&entry->listDelete, "    ");
169 }
170
171 int
172 DoPtsGroupGet(struct cmd_syndesc *as, void *arock)
173 {
174     enum { GROUP };
175     afs_status_t st = 0;
176     const char *group = as->parms[GROUP].items->data;
177     pts_GroupEntry_t entry;
178
179     if (!pts_GroupGet(cellHandle, group, &entry, &st)) {
180         ERR_ST_EXT("pts_GroupGet", st);
181     }
182
183     Print_pts_GroupEntry_p(&entry, "");
184
185     return 0;
186 }
187
188 int
189 DoPtsGroupDelete(struct cmd_syndesc *as, void *arock)
190 {
191     enum { GROUP };
192     afs_status_t st = 0;
193     const char *group = as->parms[GROUP].items->data;
194
195     if (!pts_GroupDelete(cellHandle, group, &st)) {
196         ERR_ST_EXT("pts_GroupDelete", st);
197     }
198
199     return 0;
200 }
201
202 int
203 DoPtsGroupMaxGet(struct cmd_syndesc *as, void *arock)
204 {
205     afs_status_t st = 0;
206     int max_group_id;
207
208     if (!pts_GroupMaxGet(cellHandle, &max_group_id, &st)) {
209         ERR_ST_EXT("pts_GroupMaxGet", st);
210     }
211
212     return 0;
213 }
214
215 int
216 DoPtsGroupMaxSet(struct cmd_syndesc *as, void *arock)
217 {
218     enum { MAX };
219     afs_status_t st = 0;
220     const char *max = as->parms[MAX].items->data;
221     int max_group_id;
222
223     max_group_id = GetIntFromString(max, "bad group id");
224
225     if (!pts_GroupMaxSet(cellHandle, max_group_id, &st)) {
226         ERR_ST_EXT("pts_GroupMaxSet", st);
227     }
228
229     return 0;
230 }
231
232 int
233 DoPtsGroupMemberList(struct cmd_syndesc *as, void *arock)
234 {
235     enum { GROUP };
236     afs_status_t st = 0;
237     const char *group = as->parms[GROUP].items->data;
238     void *iter;
239     char member[PTS_MAX_NAME_LEN];
240
241     if (!pts_GroupMemberListBegin(cellHandle, group, &iter, &st)) {
242         ERR_ST_EXT("pts_GroupMemberListBegin", st);
243     }
244
245     printf("Listing members of group %s\n", group);
246     while (pts_GroupMemberListNext(iter, member, &st)) {
247         printf("\t%s\n", member);
248     }
249
250     if (st != ADMITERATORDONE) {
251         ERR_ST_EXT("pts_GroupMemberListNext", st);
252     }
253
254     if (!pts_GroupMemberListDone(iter, &st)) {
255         ERR_ST_EXT("pts_GroupMemberListDone", st);
256     }
257
258     return 0;
259 }
260
261 int
262 DoPtsGroupMemberRemove(struct cmd_syndesc *as, void *arock)
263 {
264     enum { USER, GROUP };
265     afs_status_t st = 0;
266     const char *user = as->parms[USER].items->data;
267     const char *group = as->parms[GROUP].items->data;
268
269     if (!pts_GroupMemberRemove(cellHandle, user, group, &st)) {
270         ERR_ST_EXT("pts_GroupMemberRemove", st);
271     }
272
273     return 0;
274 }
275
276 int
277 DoPtsGroupRename(struct cmd_syndesc *as, void *arock)
278 {
279     enum { GROUP, NEWNAME };
280     afs_status_t st = 0;
281     const char *group = as->parms[GROUP].items->data;
282     char *new_name = as->parms[NEWNAME].items->data;
283
284     if (!pts_GroupRename(cellHandle, group, new_name, &st)) {
285         ERR_ST_EXT("pts_GroupRename", st);
286     }
287
288     return 0;
289 }
290
291 int
292 DoPtsGroupModify(struct cmd_syndesc *as, void *arock)
293 {
294     enum { GROUP, LISTSTATUS, LISTGROUPSOWNED, LISTMEMBERSHIP,
295         LISTADD, LISTDELTE
296     };
297     afs_status_t st = 0;
298     const char *group = as->parms[GROUP].items->data;
299     pts_GroupUpdateEntry_t entry;
300
301     entry.listStatus =
302         GetGroupAccessFromString(as->parms[LISTSTATUS].items->data,
303                                  "invalid permission specifier");
304     entry.listGroupsOwned =
305         GetGroupAccessFromString(as->parms[LISTGROUPSOWNED].items->data,
306                                  "invalid permission specifier");
307     entry.listMembership =
308         GetGroupAccessFromString(as->parms[LISTMEMBERSHIP].items->data,
309                                  "invalid permission specifier");
310     entry.listAdd =
311         GetGroupAccessFromString(as->parms[LISTADD].items->data,
312                                  "invalid permission specifier");
313     entry.listDelete =
314         GetGroupAccessFromString(as->parms[LISTDELTE].items->data,
315                                  "invalid permission specifier");
316
317     if (!pts_GroupModify(cellHandle, group, &entry, &st)) {
318         ERR_ST_EXT("pts_GroupModify", st);
319     }
320
321     return 0;
322 }
323
324 int
325 DoPtsUserCreate(struct cmd_syndesc *as, void *arock)
326 {
327     enum { USER };
328     afs_status_t st = 0;
329     char *user = as->parms[USER].items->data;
330     int new_user_id;
331
332     if (!pts_UserCreate(cellHandle, user, &new_user_id, &st)) {
333         ERR_ST_EXT("pts_UserCreate", st);
334     }
335
336     printf("Created user id %d\n", new_user_id);
337
338     return 0;
339 }
340
341 int
342 DoPtsUserDelete(struct cmd_syndesc *as, void *arock)
343 {
344     enum { USER };
345     afs_status_t st = 0;
346     const char *user = as->parms[USER].items->data;
347
348     if (!pts_UserDelete(cellHandle, user, &st)) {
349         ERR_ST_EXT("pts_UserDelete", st);
350     }
351
352     return 0;
353 }
354
355 static void
356 Print_pts_userAccess_p(pts_userAccess_p access, const char *prefix)
357 {
358     if (*access == PTS_USER_OWNER_ACCESS) {
359         printf("%sPTS_USER_OWNER_ACCESS\n", prefix);
360     } else if (*access == PTS_USER_ANYUSER_ACCESS) {
361         printf("%sPTS_USER_ANYUSER_ACCESS\n", prefix);
362     }
363 }
364
365 static void
366 Print_pts_UserEntry_p(pts_UserEntry_p entry, const char *prefix)
367 {
368     printf("%sName %s Uid %d\n", prefix, entry->name, entry->nameUid);
369     printf("%sOwner %s Uid %d\n", prefix, entry->owner, entry->ownerUid);
370     printf("%sCreator %s Uid %d\n", prefix, entry->creator,
371            entry->creatorUid);
372     printf("%sGroup creation quota %d\n", prefix, entry->groupCreationQuota);
373     printf("%sGroup membership count %d\n", prefix,
374            entry->groupMembershipCount);
375     printf("%sList status permission\n", prefix);
376     Print_pts_userAccess_p(&entry->listStatus, "    ");
377     printf("%sList groups owned permission\n", prefix);
378     Print_pts_userAccess_p(&entry->listGroupsOwned, "    ");
379     printf("%sList membership permission\n", prefix);
380     Print_pts_userAccess_p(&entry->listMembership, "    ");
381     printf("%s\n", prefix);
382 }
383
384 int
385 DoPtsUserGet(struct cmd_syndesc *as, void *arock)
386 {
387     enum { USER };
388     afs_status_t st = 0;
389     const char *user = as->parms[USER].items->data;
390     pts_UserEntry_t entry;
391
392     if (!pts_UserGet(cellHandle, user, &entry, &st)) {
393         ERR_ST_EXT("pts_UserGet", st);
394     }
395
396     Print_pts_UserEntry_p(&entry, "");
397
398     return 0;
399 }
400
401 int
402 DoPtsUserRename(struct cmd_syndesc *as, void *arock)
403 {
404     enum { USER, NEWNAME };
405     afs_status_t st = 0;
406     const char *user = as->parms[USER].items->data;
407     char *new_name = as->parms[NEWNAME].items->data;
408
409     if (!pts_UserRename(cellHandle, user, new_name, &st)) {
410         ERR_ST_EXT("pts_UserRename", st);
411     }
412
413     return 0;
414 }
415
416 int
417 DoPtsUserModify(struct cmd_syndesc *as, void *arock)
418 {
419     enum { USER, GROUPQUOTA, LISTSTATUS, LISTGROUPSOWNED,
420         LISTMEMBERSHIP
421     };
422     afs_status_t st = 0;
423     const char *user = as->parms[USER].items->data;
424     pts_UserUpdateEntry_t entry;
425     int have_list_status_perm = 0;
426     int have_list_groups_owned_perm = 0;
427     int have_list_membership_perm = 0;
428
429     entry.flag = 0;
430
431     if (as->parms[GROUPQUOTA].items) {
432         entry.groupCreationQuota =
433             GetIntFromString(as->parms[GROUPQUOTA].items->data, "bad quota");
434         entry.flag = PTS_USER_UPDATE_GROUP_CREATE_QUOTA;
435     }
436
437     if (as->parms[LISTSTATUS].items) {
438         entry.listStatus =
439             GetUserAccessFromString(as->parms[LISTSTATUS].items->data,
440                                     "invalid permission specifier");
441         entry.flag |= PTS_USER_UPDATE_PERMISSIONS;
442         have_list_status_perm = 1;
443     }
444
445     if (as->parms[LISTGROUPSOWNED].items) {
446         entry.listGroupsOwned =
447             GetUserAccessFromString(as->parms[LISTGROUPSOWNED].items->data,
448                                     "invalid permission specifier");
449         entry.flag |= PTS_USER_UPDATE_PERMISSIONS;
450         have_list_groups_owned_perm = 1;
451     }
452
453     if (as->parms[LISTMEMBERSHIP].items) {
454         entry.listMembership =
455             GetUserAccessFromString(as->parms[LISTMEMBERSHIP].items->data,
456                                     "invalid permission specifier");
457         entry.flag |= PTS_USER_UPDATE_PERMISSIONS;
458         have_list_membership_perm = 1;
459     }
460
461     if (entry.flag == 0) {
462         ERR_EXT("you must specify either quota or permissions to modify");
463     } else {
464         if (entry.flag & PTS_USER_UPDATE_PERMISSIONS) {
465             if ((have_list_status_perm + have_list_groups_owned_perm +
466                  have_list_membership_perm) != 3) {
467                 ERR_EXT("you must completely specify all permissions "
468                         "when modifying a user");
469             }
470         }
471     }
472
473     if (!pts_UserModify(cellHandle, user, &entry, &st)) {
474         ERR_ST_EXT("pts_UserModify", st);
475     }
476
477     return 0;
478 }
479
480 int
481 DoPtsUserMaxGet(struct cmd_syndesc *as, void *arock)
482 {
483     afs_status_t st = 0;
484     int max_user_id;
485
486     if (!pts_UserMaxGet(cellHandle, &max_user_id, &st)) {
487         ERR_ST_EXT("pts_UserMaxGet", st);
488     }
489
490     return 0;
491 }
492
493 int
494 DoPtsUserMaxSet(struct cmd_syndesc *as, void *arock)
495 {
496     enum { MAX };
497     afs_status_t st = 0;
498     const char *max = as->parms[MAX].items->data;
499     int max_user_id;
500
501     max_user_id = GetIntFromString(max, "bad user id");
502
503     if (!pts_UserMaxSet(cellHandle, max_user_id, &st)) {
504         ERR_ST_EXT("pts_UserMaxSet", st);
505     }
506
507     return 0;
508 }
509
510 int
511 DoPtsUserMemberList(struct cmd_syndesc *as, void *arock)
512 {
513     enum { USER };
514     afs_status_t st = 0;
515     const char *user = as->parms[USER].items->data;
516     void *iter;
517     char group[PTS_MAX_NAME_LEN];
518
519     if (!pts_UserMemberListBegin(cellHandle, user, &iter, &st)) {
520         ERR_ST_EXT("pts_UserMemberListBegin", st);
521     }
522
523     printf("Listing group membership for %s\n", user);
524
525     while (pts_UserMemberListNext(iter, group, &st)) {
526         printf("\t%s\n", group);
527     }
528
529     if (st != ADMITERATORDONE) {
530         ERR_ST_EXT("pts_UserMemberListNext", st);
531     }
532
533     if (!pts_UserMemberListDone(iter, &st)) {
534         ERR_ST_EXT("pts_UserMemberListDone", st);
535     }
536
537     return 0;
538 }
539
540 int
541 DoPtsOwnedGroupList(struct cmd_syndesc *as, void *arock)
542 {
543     enum { USER };
544     afs_status_t st = 0;
545     const char *user = as->parms[USER].items->data;
546     void *iter;
547     char group[PTS_MAX_NAME_LEN];
548
549     if (!pts_OwnedGroupListBegin(cellHandle, user, &iter, &st)) {
550         ERR_ST_EXT("pts_OwnedGroupListBegin", st);
551     }
552
553     printf("Listing groups owned by %s\n", user);
554
555     while (pts_OwnedGroupListNext(iter, group, &st)) {
556         printf("\t%s\n", group);
557     }
558
559     if (st != ADMITERATORDONE) {
560         ERR_ST_EXT("pts_OwnedGroupListNext", st);
561     }
562
563     if (!pts_OwnedGroupListDone(iter, &st)) {
564         ERR_ST_EXT("pts_OwnedGroupListDone", st);
565     }
566
567     return 0;
568 }
569
570 void
571 SetupPtsAdminCmd(void)
572 {
573     struct cmd_syndesc *ts;
574
575     ts = cmd_CreateSyntax("PtsGroupMemberAdd", DoPtsGroupMemberAdd, NULL,
576                           "add a user to a group");
577     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to add");
578     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
579     SetupCommonCmdArgs(ts);
580
581     ts = cmd_CreateSyntax("PtsGroupOwnerChange", DoPtsGroupOwnerChange, NULL,
582                           "change the owner of a group");
583     cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_REQUIRED, "new owner");
584     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
585     SetupCommonCmdArgs(ts);
586
587     ts = cmd_CreateSyntax("PtsGroupCreate", DoPtsGroupCreate, NULL,
588                           "create a new group");
589     cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_REQUIRED, "owner of group");
590     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to create");
591     SetupCommonCmdArgs(ts);
592
593     ts = cmd_CreateSyntax("PtsGroupGet", DoPtsGroupGet, NULL,
594                           "get information about a group");
595     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to query");
596     SetupCommonCmdArgs(ts);
597
598     ts = cmd_CreateSyntax("PtsGroupDelete", DoPtsGroupDelete, NULL,
599                           "delete a group");
600     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to delete");
601     SetupCommonCmdArgs(ts);
602
603     ts = cmd_CreateSyntax("PtsGroupMaxGet", DoPtsGroupMaxGet, NULL,
604                           "get the maximum group id");
605     SetupCommonCmdArgs(ts);
606
607     ts = cmd_CreateSyntax("PtsGroupMaxSet", DoPtsGroupMaxSet, NULL,
608                           "set the maximum group id");
609     cmd_AddParm(ts, "-max", CMD_SINGLE, CMD_REQUIRED, "new max group id");
610     SetupCommonCmdArgs(ts);
611
612     ts = cmd_CreateSyntax("PtsGroupMemberList", DoPtsGroupMemberList, NULL,
613                           "list members of a group");
614     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to query");
615     SetupCommonCmdArgs(ts);
616
617     ts = cmd_CreateSyntax("PtsGroupMemberRemove", DoPtsGroupMemberRemove, NULL,
618                           "remove a member from a group");
619     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to remove");
620     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
621     SetupCommonCmdArgs(ts);
622
623     ts = cmd_CreateSyntax("PtsGroupRename", DoPtsGroupRename, NULL,
624                           "rename a group");
625     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
626     cmd_AddParm(ts, "-newname", CMD_SINGLE, CMD_REQUIRED, "new group name");
627     SetupCommonCmdArgs(ts);
628
629     ts = cmd_CreateSyntax("PtsGroupModify", DoPtsGroupModify, NULL,
630                           "modify a group");
631     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
632     cmd_AddParm(ts, "-liststatus", CMD_SINGLE, CMD_REQUIRED,
633                 "list status permission <owner | group | any>");
634     cmd_AddParm(ts, "-listgroupsowned", CMD_SINGLE, CMD_REQUIRED,
635                 "list groups owned permission <owner | any>");
636     cmd_AddParm(ts, "-listmembership", CMD_SINGLE, CMD_REQUIRED,
637                 "list membership permission <owner | group | any>");
638     cmd_AddParm(ts, "-listadd", CMD_SINGLE, CMD_REQUIRED,
639                 "list add permission <owner | group | any>");
640     cmd_AddParm(ts, "-listdelete", CMD_SINGLE, CMD_REQUIRED,
641                 "list delete permission <owner | group>");
642     SetupCommonCmdArgs(ts);
643
644     ts = cmd_CreateSyntax("PtsUserCreate", DoPtsUserCreate, NULL,
645                           "create a new user");
646     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to create");
647     SetupCommonCmdArgs(ts);
648
649     ts = cmd_CreateSyntax("PtsUserDelete", DoPtsUserDelete, NULL,
650                           "delete a user");
651     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to delete");
652     SetupCommonCmdArgs(ts);
653
654     ts = cmd_CreateSyntax("PtsUserGet", DoPtsUserGet, NULL,
655                           "get information about a user");
656     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to query");
657     SetupCommonCmdArgs(ts);
658
659     ts = cmd_CreateSyntax("PtsUserRename", DoPtsUserRename, NULL,
660                           "rename a user");
661     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to modify");
662     cmd_AddParm(ts, "-newname", CMD_SINGLE, CMD_REQUIRED, "new user name");
663     SetupCommonCmdArgs(ts);
664
665     ts = cmd_CreateSyntax("PtsUserModify", DoPtsUserModify, NULL,
666                           "change a user");
667     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to modify");
668     cmd_AddParm(ts, "-groupquota", CMD_SINGLE, CMD_OPTIONAL,
669                 "group creation quota");
670     cmd_AddParm(ts, "-liststatus", CMD_SINGLE, CMD_OPTIONAL,
671                 "list status permission <owner | any>");
672     cmd_AddParm(ts, "-listgroupsowned", CMD_SINGLE, CMD_OPTIONAL,
673                 "list groups owned permission <owner | any>");
674     cmd_AddParm(ts, "-listmembership", CMD_SINGLE, CMD_OPTIONAL,
675                 "list membership permission <owner | any>");
676     SetupCommonCmdArgs(ts);
677
678     ts = cmd_CreateSyntax("PtsUserMaxGet", DoPtsUserMaxGet, NULL,
679                           "get the max user id");
680     SetupCommonCmdArgs(ts);
681
682     ts = cmd_CreateSyntax("PtsUserMaxSet", DoPtsUserMaxSet, NULL,
683                           "set the max user id");
684     cmd_AddParm(ts, "-max", CMD_SINGLE, CMD_REQUIRED, "max user id");
685     SetupCommonCmdArgs(ts);
686
687     ts = cmd_CreateSyntax("PtsUserMemberList", DoPtsUserMemberList, NULL,
688                           "list group membership for a user");
689     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to query");
690     SetupCommonCmdArgs(ts);
691
692     ts = cmd_CreateSyntax("PtsOwnedGroupList", DoPtsOwnedGroupList, NULL,
693                           "list groups owned by a user");
694     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to query");
695     SetupCommonCmdArgs(ts);
696 }