libroken: Build on windows
[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     typedef enum { USER, GROUP } DoPtsGroupMemberAdd_parm_t;
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     typedef enum { OWNER, GROUP } DoPtsGroupOwnerChange_parm_t;
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     typedef enum { OWNER, GROUP } DoPtsGroupCreate_parm_t;
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;
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     typedef enum { GROUP } DoPtsGroupGet_parm_t;
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     typedef enum { GROUP } DoPtsGroupDelete_parm_t;
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     typedef enum { MAX } DoPtsGroupMaxSet_parm_t;
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     typedef enum { GROUP } DoPtsGroupMemberList_parm_t;
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     typedef enum { USER, GROUP } DoPtsGroupMemberRemove_parm_t;
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     typedef enum { GROUP, NEWNAME } DoPtsGroupRename_parm_t;
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     typedef enum { GROUP, LISTSTATUS, LISTGROUPSOWNED, LISTMEMBERSHIP,
295         LISTADD, LISTDELTE
296     } DoPtsGroupModify_parm_t;
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     typedef enum { USER } DoPtsUserCreate_parm_t;
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     typedef enum { USER } DoPtsUserDelete_parm_t;
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     typedef enum { USER } DoPtsUserGet_parm_t;
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     typedef enum { USER, NEWNAME } DoPtsUserRename_parm_t;
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     typedef enum { USER, GROUPQUOTA, LISTSTATUS, LISTGROUPSOWNED,
420         LISTMEMBERSHIP
421     } DoPtsUserModify_parm_t;
422     afs_status_t st = 0;
423     const char *user = as->parms[USER].items->data;
424     pts_UserUpdateEntry_t entry;
425     int have_quota = 0;
426     int have_list_status_perm = 0;
427     int have_list_groups_owned_perm = 0;
428     int have_list_membership_perm = 0;
429
430     entry.flag = 0;
431
432     if (as->parms[GROUPQUOTA].items) {
433         entry.groupCreationQuota =
434             GetIntFromString(as->parms[GROUPQUOTA].items->data, "bad quota");
435         entry.flag = PTS_USER_UPDATE_GROUP_CREATE_QUOTA;
436         have_quota = 1;
437     }
438
439     if (as->parms[LISTSTATUS].items) {
440         entry.listStatus =
441             GetUserAccessFromString(as->parms[LISTSTATUS].items->data,
442                                     "invalid permission specifier");
443         entry.flag |= PTS_USER_UPDATE_PERMISSIONS;
444         have_list_status_perm = 1;
445     }
446
447     if (as->parms[LISTGROUPSOWNED].items) {
448         entry.listGroupsOwned =
449             GetUserAccessFromString(as->parms[LISTGROUPSOWNED].items->data,
450                                     "invalid permission specifier");
451         entry.flag |= PTS_USER_UPDATE_PERMISSIONS;
452         have_list_groups_owned_perm = 1;
453     }
454
455     if (as->parms[LISTMEMBERSHIP].items) {
456         entry.listMembership =
457             GetUserAccessFromString(as->parms[LISTMEMBERSHIP].items->data,
458                                     "invalid permission specifier");
459         entry.flag |= PTS_USER_UPDATE_PERMISSIONS;
460         have_list_membership_perm = 1;
461     }
462
463     if (entry.flag == 0) {
464         ERR_EXT("you must specify either quota or permissions to modify");
465     } else {
466         if (entry.flag & PTS_USER_UPDATE_PERMISSIONS) {
467             if ((have_list_status_perm + have_list_groups_owned_perm +
468                  have_list_membership_perm) != 3) {
469                 ERR_EXT("you must completely specify all permissions "
470                         "when modifying a user");
471             }
472         }
473     }
474
475     if (!pts_UserModify(cellHandle, user, &entry, &st)) {
476         ERR_ST_EXT("pts_UserModify", st);
477     }
478
479     return 0;
480 }
481
482 int
483 DoPtsUserMaxGet(struct cmd_syndesc *as, void *arock)
484 {
485     afs_status_t st = 0;
486     int max_user_id;
487
488     if (!pts_UserMaxGet(cellHandle, &max_user_id, &st)) {
489         ERR_ST_EXT("pts_UserMaxGet", st);
490     }
491
492     return 0;
493 }
494
495 int
496 DoPtsUserMaxSet(struct cmd_syndesc *as, void *arock)
497 {
498     typedef enum { MAX } DoPtsUserMaxSet_parm_t;
499     afs_status_t st = 0;
500     const char *max = as->parms[MAX].items->data;
501     int max_user_id;
502
503     max_user_id = GetIntFromString(max, "bad user id");
504
505     if (!pts_UserMaxSet(cellHandle, max_user_id, &st)) {
506         ERR_ST_EXT("pts_UserMaxSet", st);
507     }
508
509     return 0;
510 }
511
512 int
513 DoPtsUserMemberList(struct cmd_syndesc *as, void *arock)
514 {
515     typedef enum { USER } DoPtsUserMemberList_parm_t;
516     afs_status_t st = 0;
517     const char *user = as->parms[USER].items->data;
518     void *iter;
519     char group[PTS_MAX_NAME_LEN];
520
521     if (!pts_UserMemberListBegin(cellHandle, user, &iter, &st)) {
522         ERR_ST_EXT("pts_UserMemberListBegin", st);
523     }
524
525     printf("Listing group membership for %s\n", user);
526
527     while (pts_UserMemberListNext(iter, group, &st)) {
528         printf("\t%s\n", group);
529     }
530
531     if (st != ADMITERATORDONE) {
532         ERR_ST_EXT("pts_UserMemberListNext", st);
533     }
534
535     if (!pts_UserMemberListDone(iter, &st)) {
536         ERR_ST_EXT("pts_UserMemberListDone", st);
537     }
538
539     return 0;
540 }
541
542 int
543 DoPtsOwnedGroupList(struct cmd_syndesc *as, void *arock)
544 {
545     typedef enum { USER } DoPtsOwnedGroupList_parm_t;
546     afs_status_t st = 0;
547     const char *user = as->parms[USER].items->data;
548     void *iter;
549     char group[PTS_MAX_NAME_LEN];
550
551     if (!pts_OwnedGroupListBegin(cellHandle, user, &iter, &st)) {
552         ERR_ST_EXT("pts_OwnedGroupListBegin", st);
553     }
554
555     printf("Listing groups owned by %s\n", user);
556
557     while (pts_OwnedGroupListNext(iter, group, &st)) {
558         printf("\t%s\n", group);
559     }
560
561     if (st != ADMITERATORDONE) {
562         ERR_ST_EXT("pts_OwnedGroupListNext", st);
563     }
564
565     if (!pts_OwnedGroupListDone(iter, &st)) {
566         ERR_ST_EXT("pts_OwnedGroupListDone", st);
567     }
568
569     return 0;
570 }
571
572 void
573 SetupPtsAdminCmd(void)
574 {
575     struct cmd_syndesc *ts;
576
577     ts = cmd_CreateSyntax("PtsGroupMemberAdd", DoPtsGroupMemberAdd, NULL,
578                           "add a user to a group");
579     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to add");
580     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
581     SetupCommonCmdArgs(ts);
582
583     ts = cmd_CreateSyntax("PtsGroupOwnerChange", DoPtsGroupOwnerChange, NULL,
584                           "change the owner of a group");
585     cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_REQUIRED, "new owner");
586     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
587     SetupCommonCmdArgs(ts);
588
589     ts = cmd_CreateSyntax("PtsGroupCreate", DoPtsGroupCreate, NULL,
590                           "create a new group");
591     cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_REQUIRED, "owner of group");
592     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to create");
593     SetupCommonCmdArgs(ts);
594
595     ts = cmd_CreateSyntax("PtsGroupGet", DoPtsGroupGet, NULL,
596                           "get information about a group");
597     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to query");
598     SetupCommonCmdArgs(ts);
599
600     ts = cmd_CreateSyntax("PtsGroupDelete", DoPtsGroupDelete, NULL,
601                           "delete a group");
602     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to delete");
603     SetupCommonCmdArgs(ts);
604
605     ts = cmd_CreateSyntax("PtsGroupMaxGet", DoPtsGroupMaxGet, NULL,
606                           "get the maximum group id");
607     SetupCommonCmdArgs(ts);
608
609     ts = cmd_CreateSyntax("PtsGroupMaxSet", DoPtsGroupMaxSet, NULL,
610                           "set the maximum group id");
611     cmd_AddParm(ts, "-max", CMD_SINGLE, CMD_REQUIRED, "new max group id");
612     SetupCommonCmdArgs(ts);
613
614     ts = cmd_CreateSyntax("PtsGroupMemberList", DoPtsGroupMemberList, NULL,
615                           "list members of a group");
616     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to query");
617     SetupCommonCmdArgs(ts);
618
619     ts = cmd_CreateSyntax("PtsGroupMemberRemove", DoPtsGroupMemberRemove, NULL,
620                           "remove a member from a group");
621     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to remove");
622     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
623     SetupCommonCmdArgs(ts);
624
625     ts = cmd_CreateSyntax("PtsGroupRename", DoPtsGroupRename, NULL,
626                           "rename a group");
627     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
628     cmd_AddParm(ts, "-newname", CMD_SINGLE, CMD_REQUIRED, "new group name");
629     SetupCommonCmdArgs(ts);
630
631     ts = cmd_CreateSyntax("PtsGroupModify", DoPtsGroupModify, NULL,
632                           "modify a group");
633     cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_REQUIRED, "group to modify");
634     cmd_AddParm(ts, "-liststatus", CMD_SINGLE, CMD_REQUIRED,
635                 "list status permission <owner | group | any>");
636     cmd_AddParm(ts, "-listgroupsowned", CMD_SINGLE, CMD_REQUIRED,
637                 "list groups owned permission <owner | any>");
638     cmd_AddParm(ts, "-listmembership", CMD_SINGLE, CMD_REQUIRED,
639                 "list membership permission <owner | group | any>");
640     cmd_AddParm(ts, "-listadd", CMD_SINGLE, CMD_REQUIRED,
641                 "list add permission <owner | group | any>");
642     cmd_AddParm(ts, "-listdelete", CMD_SINGLE, CMD_REQUIRED,
643                 "list delete permission <owner | group>");
644     SetupCommonCmdArgs(ts);
645
646     ts = cmd_CreateSyntax("PtsUserCreate", DoPtsUserCreate, NULL,
647                           "create a new user");
648     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to create");
649     SetupCommonCmdArgs(ts);
650
651     ts = cmd_CreateSyntax("PtsUserDelete", DoPtsUserDelete, NULL,
652                           "delete a user");
653     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to delete");
654     SetupCommonCmdArgs(ts);
655
656     ts = cmd_CreateSyntax("PtsUserGet", DoPtsUserGet, NULL,
657                           "get information about a user");
658     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to query");
659     SetupCommonCmdArgs(ts);
660
661     ts = cmd_CreateSyntax("PtsUserRename", DoPtsUserRename, NULL,
662                           "rename a user");
663     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to modify");
664     cmd_AddParm(ts, "-newname", CMD_SINGLE, CMD_REQUIRED, "new user name");
665     SetupCommonCmdArgs(ts);
666
667     ts = cmd_CreateSyntax("PtsUserModify", DoPtsUserModify, NULL,
668                           "change a user");
669     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to modify");
670     cmd_AddParm(ts, "-groupquota", CMD_SINGLE, CMD_OPTIONAL,
671                 "group creation quota");
672     cmd_AddParm(ts, "-liststatus", CMD_SINGLE, CMD_OPTIONAL,
673                 "list status permission <owner | any>");
674     cmd_AddParm(ts, "-listgroupsowned", CMD_SINGLE, CMD_OPTIONAL,
675                 "list groups owned permission <owner | any>");
676     cmd_AddParm(ts, "-listmembership", CMD_SINGLE, CMD_OPTIONAL,
677                 "list membership permission <owner | any>");
678     SetupCommonCmdArgs(ts);
679
680     ts = cmd_CreateSyntax("PtsUserMaxGet", DoPtsUserMaxGet, NULL,
681                           "get the max user id");
682     SetupCommonCmdArgs(ts);
683
684     ts = cmd_CreateSyntax("PtsUserMaxSet", DoPtsUserMaxSet, NULL,
685                           "set the max user id");
686     cmd_AddParm(ts, "-max", CMD_SINGLE, CMD_REQUIRED, "max user id");
687     SetupCommonCmdArgs(ts);
688
689     ts = cmd_CreateSyntax("PtsUserMemberList", DoPtsUserMemberList, NULL,
690                           "list group membership for a user");
691     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to query");
692     SetupCommonCmdArgs(ts);
693
694     ts = cmd_CreateSyntax("PtsOwnedGroupList", DoPtsOwnedGroupList, NULL,
695                           "list groups owned by a user");
696     cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_REQUIRED, "user to query");
697     SetupCommonCmdArgs(ts);
698 }