2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
18 #include <WINNT/afsevent.h>
19 #include <WINNT/afsreg.h>
22 #include <afs/cellconfig.h>
23 #include <afs/afsutil.h>
24 #include <afs/com_err.h>
32 #include "ptprototypes.h"
41 extern struct ubik_client *pruclient;
44 struct sourcestack *s_next;
51 char cell[MAXCELLCHARS];
54 static int CleanUp(struct cmd_syndesc *as, void *arock);
57 pts_Interactive(struct cmd_syndesc *as, void *arock)
65 pts_Quit(struct cmd_syndesc *as, void *arock)
72 pts_Source(struct cmd_syndesc *as, void *arock)
75 struct sourcestack *sp;
78 if (!as->parms[0].items) {
79 /* can this happen? */
82 fd = fopen(as->parms[0].items->data, "r");
84 perror(as->parms[0].items->data);
87 sp = malloc(sizeof *sp);
89 return errno ? errno : ENOMEM;
100 pts_Sleep(struct cmd_syndesc *as, void *arock)
103 if (!as->parms[0].items) {
104 /* can this happen? */
107 delay = atoi(as->parms[0].items->data);
108 #ifdef AFS_PTHREAD_ENV
119 struct sourcestack *sp;
133 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
134 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
135 * anyway. It's gonna give somebody fits to debug, I know, I know.
142 win32_enableCrypt(void)
149 /* Look up configuration parameters in Registry */
150 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
151 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
152 if (code != ERROR_SUCCESS) {
153 dummyLen = sizeof(cryptall);
154 RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL,
155 (BYTE *) &cryptall, &dummyLen);
157 RegCloseKey (parmKey);
161 #endif /* AFS_NT40_ENV */
164 GetGlobals(struct cmd_syndesc *as, void *arock)
166 struct authstate *state = (struct authstate *) arock;
175 if (!strcmp(as->name, "help"))
183 if (state->confdir == NULL) {
187 if (as->parms[16].items) {
189 cell = as->parms[16].items->data;
191 if (as->parms[17].items) { /* -noauth */
195 if (as->parms[20].items) { /* -localauth */
199 if (as->parms[21].items) { /* -auth */
203 if (as->parms[22].items /* -encrypt */
205 || win32_enableCrypt()
206 #endif /* AFS_NT40_ENV */
211 if (as->parms[18].items || as->parms[20].items) { /* -test, -localauth */
213 confdir = AFSDIR_SERVER_ETC_DIRPATH;
216 confdir = AFSDIR_SERVER_ETC_DIRPATH;
218 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
221 if (as->parms[23].items) { /* -config */
223 confdir = as->parms[23].items->data;
228 code = pr_Initialize(sec, confdir, cell);
233 afs_com_err(whoami, code, "while initializing");
237 state->confdir = confdir;
238 if (cell && cell != state->cell)
239 strncpy(state->cell, cell, MAXCELLCHARS-1);
242 if (as->parms[19].items)
249 CleanUp(struct cmd_syndesc *as, void *arock)
251 if (as && !strcmp(as->name, "help"))
254 /* Need to shutdown the ubik_client & other connections */
262 CreateGroup(struct cmd_syndesc *as, void *arock)
267 struct cmd_item *namei;
268 struct cmd_item *idi;
270 namei = as->parms[0].items;
271 idi = as->parms[2].items;
272 if (as->parms[1].items)
273 owner = as->parms[1].items->data;
279 code = util_GetInt32(idi->data, &id);
281 afs_com_err(whoami, code, "because group id was: '%s'",
286 printf("0 isn't a valid group id; aborting\n");
291 afs_com_err(whoami, code, "because group id %d was not negative",
300 code = pr_CreateGroup(namei->data, owner, &id);
303 afs_com_err(whoami, code,
304 "; unable to create group %s with id %d%s%s%s%s",
305 namei->data, id, owner ? " owned by '" : "",
306 owner ? owner : "", owner ? "'" : "",
307 (force ? " (ignored)" : ""));
309 afs_com_err(whoami, code, "; unable to create group %s %s",
310 namei->data, (force ? "(ignored)" : ""));
314 printf("group %s has id %d\n", namei->data, id);
321 CreateUser(struct cmd_syndesc *as, void *arock)
325 struct cmd_item *namei;
326 struct cmd_item *idi;
328 namei = as->parms[0].items;
329 idi = as->parms[1].items;
333 code = util_GetInt32(idi->data, &id);
335 afs_com_err(whoami, code, "because id was: '%s'", idi->data);
339 printf("0 isn't a valid user id; aborting\n");
344 afs_com_err(whoami, code, "because user id %d was not positive",
352 code = pr_CreateUser(namei->data, &id);
355 afs_com_err(whoami, code,
356 "; unable to create user %s with id %d %s",
357 namei->data, id, (force ? "(ignored)" : ""));
359 afs_com_err(whoami, code, "; unable to create user %s %s",
360 namei->data, (force ? "(ignored)" : ""));
364 printf("User %s has id %d\n", namei->data, id);
373 GetNameOrId(struct cmd_syndesc *as, struct idlist *lids, struct namelist *lnames)
380 if (!(as->parms[0].items || as->parms[1].items)) {
381 afs_com_err(whoami, 0, "must specify either a name or an id.");
384 if (as->parms[0].items && as->parms[1].items) {
385 afs_com_err(whoami, 0, "can't specify both a name and id.");
390 lids->idlist_len = 0;
391 lids->idlist_val = 0;
393 if (as->parms[0].items) { /* name */
394 struct namelist names; /* local copy, if not ret. names */
397 names.namelist_val = 0; /* so it gets freed later if needed */
403 n = 0; /* count names */
404 for (i = as->parms[0].items; i; i = i->next)
406 nl->namelist_val = malloc(n * PR_MAXNAMELEN);
407 nl->namelist_len = n;
409 for (i = as->parms[0].items; i; i = i->next)
410 strncpy(nl->namelist_val[n++], i->data, PR_MAXNAMELEN);
412 code = pr_NameToId(nl, lids);
414 afs_com_err(whoami, code, "so couldn't look up names");
416 for (n = 0; n < lids->idlist_len; n++) {
417 if ((lids->idlist_val[n] == ANONYMOUSID)) {
418 afs_com_err(whoami, PRNOENT, "so couldn't look up id for %s",
419 nl->namelist_val[n]);
423 /* treat things as working if any of the lookups worked */
428 if (names.namelist_val)
429 free(names.namelist_val);
430 } else if (as->parms[1].items) { /* id */
432 for (i = as->parms[1].items; i; i = i->next)
434 lids->idlist_val = malloc(n * sizeof(afs_int32));
435 lids->idlist_len = n;
437 for (i = as->parms[1].items; i; i = i->next) {
438 code = util_GetInt32(i->data, &lids->idlist_val[n]);
440 afs_com_err(whoami, code =
441 PRNOENT, "because a bogus id '%s' was specified",
445 if (!code && lnames) {
446 lnames->namelist_val = 0;
447 lnames->namelist_len = 0;
448 code = pr_IdToName(lids, lnames);
450 afs_com_err(whoami, code, "translating ids");
454 if (lids->idlist_val)
455 free(lids->idlist_val);
464 GetNameOrId(struct cmd_syndesc *as, struct idlist *lids,
465 struct namelist *lnames)
468 int n = 0, nd = 0, nm = 0, id, x;
470 struct namelist names, tnames; /* local copy, if not ret. names */
471 struct idlist ids, tids; /* local copy, if not ret. ids */
474 /* Initialise our outputs */
475 memset(lids, 0, sizeof(struct idlist));
477 memset(lnames, 0, sizeof(struct namelist));
479 for (i = as->parms[0].items; i; i = i->next)
482 /* Nothing to do, so bail */
486 lids->idlist_val = malloc(n * sizeof(afs_int32));
487 lids->idlist_len = n;
488 ids.idlist_val = malloc(n * sizeof(afs_int32));
490 names.namelist_val = malloc(n * PR_MAXNAMELEN);
491 names.namelist_len = n;
493 lnames->namelist_val = malloc(n * PR_MAXNAMELEN);
494 lnames->namelist_len = 0;
496 for (i = as->parms[0].items; i; i = i->next) {
497 tnames.namelist_val = malloc(PR_MAXNAMELEN);
498 strncpy(tnames.namelist_val[0], i->data, PR_MAXNAMELEN);
499 tnames.namelist_len = 1;
502 code = pr_NameToId(&tnames, &tids);
503 if ((!code && (tids.idlist_val[0] != 32766))
504 || (code = util_GetInt32(i->data, &id))) {
505 /* Assume it's a name instead */
506 strncpy(names.namelist_val[nm++], i->data, PR_MAXNAMELEN);
508 ids.idlist_val[nd++] = id;
510 free(tnames.namelist_val);
512 names.namelist_len = nm;
514 tids.idlist_len = nd = nm = 0;
516 code = pr_NameToId(&names, &tids);
518 afs_com_err(whoami, code, "so couldn't look up names");
520 for (n = 0; n < tids.idlist_len; n++) {
521 if (tids.idlist_val[n] == ANONYMOUSID) {
522 afs_com_err(whoami, PRNOENT, "so couldn't look up id for %s",
523 names.namelist_val[n]);
526 lids->idlist_val[nd] = tids.idlist_val[n];
528 strcpy(lnames->namelist_val[nd], names.namelist_val[n]);
532 for (x = 0; x < ids.idlist_len; x++) {
533 lids->idlist_val[nd + x] = ids.idlist_val[x];
535 lids->idlist_len = nd + x;
536 if (!code && lnames) {
537 tnames.namelist_val = 0;
538 tnames.namelist_len = 0;
539 code = pr_IdToName(&ids, &tnames);
541 afs_com_err(whoami, code, "translating ids");
545 for (x = 0; x < ids.idlist_len; x++)
546 strcpy(lnames->namelist_val[nd + x], tnames.namelist_val[x]);
547 lnames->namelist_len = nd + x;
551 /* treat things as working if any of the lookups worked */
555 if (lids->idlist_val)
556 free(lids->idlist_val);
564 AddToGroup(struct cmd_syndesc *as, void *arock)
567 struct cmd_item *u, *g;
569 for (u = as->parms[0].items; u; u = u->next) {
570 for (g = as->parms[1].items; g; g = g->next) {
571 code = pr_AddToGroup(u->data, g->data);
573 afs_com_err(whoami, code,
574 "; unable to add user %s to group %s %s", u->data,
575 g->data, (force ? "(ignored)" : ""));
585 RemoveFromGroup(struct cmd_syndesc *as, void *arock)
588 struct cmd_item *u, *g;
590 for (u = as->parms[0].items; u; u = u->next) {
591 for (g = as->parms[1].items; g; g = g->next) {
592 code = pr_RemoveUserFromGroup(u->data, g->data);
594 afs_com_err(whoami, code,
595 "; unable to remove user %s from group %s %s",
596 u->data, g->data, (force ? "(ignored)" : ""));
606 ListMembership(struct cmd_syndesc *as, void *arock)
615 if (GetNameOrId(as, &ids, &names))
618 for (i = 0; i < ids.idlist_len; i++) {
619 afs_int32 id = ids.idlist_val[i];
620 char *name = names.namelist_val[i];
622 if (id == ANONYMOUSID)
623 continue; /* bad entry */
625 list.namelist_val = 0;
626 list.namelist_len = 0;
627 if (as->parms[2].items) { /* -expandgroups */
628 code = pr_IDListExpandedMembers(id, &list);
632 code = pr_IDListMembers(id, &list);
635 afs_com_err(whoami, code, "; unable to get membership of %s (id: %d)",
640 printf("Members of %s (id: %d) are:\n", name, id);
642 printf("Groups %s (id: %d) is a member of:\n", name, id);
644 for (j = 0; j < list.namelist_len; j++)
645 printf(" %s\n", list.namelist_val[j]);
646 if (list.namelist_val)
647 free(list.namelist_val);
648 if (as->parms[1].items && id < 0) { /* -supergroups */
649 list.namelist_val = 0;
650 list.namelist_len = 0;
651 code = pr_ListSuperGroups(ids.idlist_val[i], &list);
652 if (code == RXGEN_OPCODE) {
653 continue; /* server does not support supergroups */
654 } else if (code != 0) {
655 afs_com_err(whoami, code,
656 "; unable to get supergroups of %s (id: %d)",
660 printf("Groups %s (id: %d) is a member of:\n", name, id);
661 for (j = 0; j < list.namelist_len; j++)
662 printf(" %s\n", list.namelist_val[j]);
663 if (list.namelist_val)
664 free(list.namelist_val);
668 free(ids.idlist_val);
669 if (names.namelist_val)
670 free(names.namelist_val);
675 Delete(struct cmd_syndesc *as, void *arock)
682 if (GetNameOrId(as, &ids, &names))
685 for (i = 0; i < ids.idlist_len; i++) {
686 afs_int32 id = ids.idlist_val[i];
687 char *name = names.namelist_val[i];
689 if (id == ANONYMOUSID)
692 code = pr_DeleteByID(id);
694 afs_com_err(whoami, code, "deleting %s (id: %d) %s", name, id,
695 (force ? "(ignored)" : ""));
701 free(ids.idlist_val);
702 if (names.namelist_val)
703 free(names.namelist_val);
707 /* access bit translation info */
709 char *flags_upcase = "SOMA "; /* legal all access values */
710 char *flags_dncase = "s mar"; /* legal member acces values */
711 int flags_shift[5] = { 2, 1, 2, 2, 1 }; /* bits for each */
714 CheckEntry(struct cmd_syndesc *as, void *arock)
718 int i, flag = 0, admin = 0;
719 namelist lnames, names;
722 struct prcheckentry aentry;
724 if (GetNameOrId(as, &ids, &names))
728 lids.idlist_val = malloc(sizeof(afs_int32) * 2);
729 lnames.namelist_len = 0;
730 lnames.namelist_val = 0;
732 for (i = 0; i < ids.idlist_len; i++) {
733 afs_int32 id = ids.idlist_val[i];
735 if (id == ANONYMOUSID)
739 code = pr_ListEntry(id, &aentry);
742 afs_com_err(whoami, code, "; unable to find entry for (id: %d)", id);
746 lids.idlist_val[0] = aentry.owner;
747 lids.idlist_val[1] = aentry.creator;
748 code = pr_IdToName(&lids, &lnames);
751 afs_com_err(whoami, code,
752 "translating owner (%d) and creator (%d) ids",
753 aentry.owner, aentry.creator);
756 printf("Name: %s, id: %d, owner: %s, creator: %s,\n", aentry.name,
757 aentry.id, lnames.namelist_val[0], lnames.namelist_val[1]);
758 printf(" membership: %d", aentry.count);
761 afs_int32 flags = aentry.flags;
764 access[5] = 0; /* null-terminate the string */
765 for (j = 4; j >= 0; j--) {
784 printf(", flags: %s", access);
786 if (aentry.id == SYSADMINID)
788 else if (!pr_IsAMemberOf(aentry.name, "system:administrators", &flag)) {
793 printf(", group quota: unlimited");
795 printf(", group quota: %d", aentry.ngroups);
797 printf(", foreign user quota=%d", aentry.nusers);
802 if (lnames.namelist_val)
803 free(lnames.namelist_val);
805 free(lids.idlist_val);
807 free(ids.idlist_val);
813 ListEntries(struct cmd_syndesc *as, void *arock)
816 afs_int32 flag, startindex, nentries, nextstartindex;
817 struct prlistentries *entriesp = 0, *e;
821 if (as->parms[1].items)
823 if (as->parms[0].items)
826 printf("Name ID Owner Creator\n");
827 for (startindex = 0; startindex != -1; startindex = nextstartindex) {
829 pr_ListEntries(flag, startindex, &nentries, &entriesp,
832 afs_com_err(whoami, code, "; unable to list entries");
838 /* Now display each of the entries we read */
839 for (i = 0, e = entriesp; i < nentries; i++, e++) {
840 printf("%-25s %6d %6d %7d \n", e->name, e->id, e->owner,
850 ChownGroup(struct cmd_syndesc *as, void *arock)
856 name = as->parms[0].items->data;
857 owner = as->parms[1].items->data;
858 code = pr_ChangeEntry(name, "", 0, owner);
860 afs_com_err(whoami, code, "; unable to change owner of %s to %s", name,
866 ChangeName(struct cmd_syndesc *as, void *arock)
872 oldname = as->parms[0].items->data;
873 newname = as->parms[1].items->data;
874 code = pr_ChangeEntry(oldname, newname, 0, "");
876 afs_com_err(whoami, code, "; unable to change name of %s to %s", oldname,
882 ListMax(struct cmd_syndesc *as, void *arock)
885 afs_int32 maxUser, maxGroup;
887 code = pr_ListMaxUserId(&maxUser);
889 afs_com_err(whoami, code, "getting maximum user id");
891 code = pr_ListMaxGroupId(&maxGroup);
893 afs_com_err(whoami, code, "getting maximum group id");
895 printf("Max user id is %d and max group id is %d.\n", maxUser,
903 SetMaxCommand(struct cmd_syndesc *as, void *arock)
909 if (as->parms[1].items) {
911 code = util_GetInt32(as->parms[1].items->data, &maxid);
913 afs_com_err(whoami, code, "because id was: '%s'",
914 as->parms[1].items->data);
916 code = pr_SetMaxUserId(maxid);
918 afs_com_err(whoami, code, "so couldn't set Max User Id to %d",
922 if (as->parms[0].items) {
924 code = util_GetInt32(as->parms[0].items->data, &maxid);
926 afs_com_err(whoami, code, "because id was: '%s'",
927 as->parms[0].items->data);
929 code = pr_SetMaxGroupId(maxid);
931 afs_com_err(whoami, code, "so couldn't set Max Group Id to %d",
935 if (!as->parms[0].items && !as->parms[1].items) {
937 printf("Must specify at least one of group or user.\n");
943 SetFields(struct cmd_syndesc *as, void *arock)
949 afs_int32 mask, flags=0, ngroups, nusers;
951 if (GetNameOrId(as, &ids, &names))
958 if (as->parms[1].items) { /* privacy bits */
959 char *access = as->parms[1].items->data;
962 if (strpbrk(access, "76543210") != 0) { /* all octal digits */
963 sscanf(access, "%lo", (long unsigned int *) &flags);
964 } else { /* interpret flag bit names */
965 if (strlen(access) != 5) {
967 printf("Access bits must be of the form 'somar', not %s\n",
971 if (strpbrk(access, "somar-") == 0)
974 for (i = 0; i < 5; i++) {
975 if (access[i] == flags_upcase[i])
977 else if (access[i] == flags_dncase[i])
979 else if (access[i] == '-')
983 ("Access bits out of order or illegal:\n must be a combination of letters from '%s' or '%s' or hyphen, not %s\n",
984 flags_upcase, flags_dncase, access);
987 flags <<= flags_shift[i];
988 if (flags_shift[i] == 1) {
995 mask |= PR_SF_ALLBITS;
997 if (as->parms[2].items) { /* limitgroups */
998 code = util_GetInt32(as->parms[2].items->data, &ngroups);
1000 afs_com_err(whoami, code, "because ngroups was: '%s'",
1001 as->parms[2].items->data);
1004 mask |= PR_SF_NGROUPS;
1007 if (as->parms[3].items) { /* limitgroups */
1008 code = util_GetInt32(as->parms[3].items->data, &nusers);
1010 afs_com_err(whoami, code, "because nusers was: '%s'",
1011 as->parms[3].items->data);
1014 mask |= PR_SF_NUSERS;
1018 for (i = 0; i < ids.idlist_len; i++) {
1019 afs_int32 id = ids.idlist_val[i];
1020 char *name = names.namelist_val[i];
1021 if (id == ANONYMOUSID)
1023 code = pr_SetFieldsEntry(id, mask, flags, ngroups, nusers);
1025 afs_com_err(whoami, code, "; unable to set fields for %s (id: %d)",
1031 free(ids.idlist_val);
1032 if (names.namelist_val)
1033 free(names.namelist_val);
1038 ListOwned(struct cmd_syndesc *as, void *arock)
1047 if (GetNameOrId(as, &ids, &names))
1050 for (i = 0; i < ids.idlist_len; i++) {
1051 afs_int32 oid = ids.idlist_val[i];
1052 char *name = names.namelist_val[i];
1054 if (oid == ANONYMOUSID)
1058 printf("Groups owned by %s (id: %d) are:\n", name, oid);
1060 printf("Orphaned groups are:\n");
1063 list.namelist_val = 0;
1064 list.namelist_len = 0;
1065 code = pr_ListOwned(oid, &list, &more);
1067 afs_com_err(whoami, code,
1068 "; unable to get owner list for %s (id: %d)", name,
1073 for (j = 0; j < list.namelist_len; j++)
1074 printf(" %s\n", list.namelist_val[j]);
1075 if (list.namelist_val)
1076 free(list.namelist_val);
1081 free(ids.idlist_val);
1082 if (names.namelist_val)
1083 free(names.namelist_val);
1088 add_std_args(struct cmd_syndesc *ts)
1090 char test_help[AFSDIR_PATH_MAX];
1092 sprintf(test_help, "use config file in %s", AFSDIR_SERVER_ETC_DIRPATH);
1095 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
1096 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "run unauthenticated");
1097 cmd_AddParm(ts, "-test", CMD_FLAG, CMD_OPTIONAL | CMD_HIDE, test_help);
1098 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
1099 "Continue oper despite reasonable errors");
1100 cmd_AddParm(ts, "-localauth", CMD_FLAG, CMD_OPTIONAL,
1101 "use local authentication");
1102 cmd_AddParm(ts, "-auth", CMD_FLAG, CMD_OPTIONAL,
1103 "use user's authentication (default)");
1104 cmd_AddParm(ts, "-encrypt", CMD_FLAG, CMD_OPTIONAL,
1105 "encrypt commands");
1106 cmd_AddParm(ts, "-config", CMD_SINGLE, CMD_OPTIONAL, "config location");
1110 static void add_NameOrId_args (ts)
1111 struct cmd_syndesc *ts;
1113 cmd_AddParm(ts,"-name",CMD_LIST,CMD_OPTIONAL,"user or group name");
1114 cmd_AddParm(ts,"-id",CMD_LIST,CMD_OPTIONAL,"user or group id");
1118 #include "AFS_component_version_number.c"
1121 main(int argc, char **argv)
1124 struct cmd_syndesc *ts;
1129 char *parsev[CMD_MAXPARMS];
1131 struct authstate state;
1138 WSAStartup(0x0101, &WSAjunk);
1141 #ifdef AFS_AIX32_ENV
1143 * The following signal action for AIX is necessary so that in case of a
1144 * crash (i.e. core is generated) we can include the user's data section
1145 * in the core dump. Unfortunately, by default, only a partial core is
1146 * generated which, in many cases, isn't too useful.
1148 struct sigaction nsa;
1150 sigemptyset(&nsa.sa_mask);
1151 nsa.sa_handler = SIG_DFL;
1152 nsa.sa_flags = SA_FULLDUMP;
1153 sigaction(SIGSEGV, &nsa, NULL);
1156 memset(&state, 0, sizeof(state));
1157 state.sec = 1; /* default is auth */
1159 ts = cmd_CreateSyntax("creategroup", CreateGroup, NULL, 0,
1160 "create a new group");
1161 cmd_AddParm(ts, "-name", CMD_LIST, 0, "group name");
1162 cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_OPTIONAL, "owner of the group");
1163 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL,
1164 "id (negated) for the group");
1166 cmd_CreateAlias(ts, "cg");
1168 ts = cmd_CreateSyntax("createuser", CreateUser, NULL, 0, "create a new user");
1169 cmd_AddParm(ts, "-name", CMD_LIST, 0, "user name");
1170 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "user id");
1172 cmd_CreateAlias(ts, "cu");
1174 ts = cmd_CreateSyntax("adduser", AddToGroup, NULL, 0, "add a user to a group");
1175 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1176 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1179 ts = cmd_CreateSyntax("removeuser", RemoveFromGroup, NULL, 0,
1180 "remove a user from a group");
1181 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1182 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1185 ts = cmd_CreateSyntax("membership", ListMembership, NULL, 0,
1186 "list membership of a user or group");
1187 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1188 cmd_AddParm(ts, "-supergroups", CMD_FLAG, CMD_OPTIONAL, "show supergroups");
1189 cmd_AddParm(ts, "-expandgroups", CMD_FLAG, CMD_OPTIONAL, "expand super and sub group membership");
1191 cmd_CreateAlias(ts, "groups");
1193 ts = cmd_CreateSyntax("delete", Delete, NULL, 0,
1194 "delete a user or group from database");
1195 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1198 ts = cmd_CreateSyntax("examine", CheckEntry, NULL, 0, "examine an entry");
1199 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1201 cmd_CreateAlias(ts, "check");
1203 ts = cmd_CreateSyntax("chown", ChownGroup, NULL, 0,
1204 "change ownership of a group");
1205 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "group name");
1206 cmd_AddParm(ts, "-owner", CMD_SINGLE, 0, "new owner");
1209 ts = cmd_CreateSyntax("rename", ChangeName, NULL, 0, "rename user or group");
1210 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old name");
1211 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new name");
1213 cmd_CreateAlias(ts, "chname");
1215 ts = cmd_CreateSyntax("listmax", ListMax, NULL, 0, "list max id");
1218 ts = cmd_CreateSyntax("setmax", SetMaxCommand, NULL, 0, "set max id");
1219 cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_OPTIONAL, "group max");
1220 cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_OPTIONAL, "user max");
1223 ts = cmd_CreateSyntax("setfields", SetFields, NULL, 0,
1224 "set fields for an entry");
1225 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1226 cmd_AddParm(ts, "-access", CMD_SINGLE, CMD_OPTIONAL, "set privacy flags");
1227 cmd_AddParm(ts, "-groupquota", CMD_SINGLE, CMD_OPTIONAL,
1228 "set limit on group creation");
1230 cmd_AddParm(ts, "-userquota", CMD_SINGLE, CMD_OPTIONAL,
1231 "set limit on foreign user creation");
1235 ts = cmd_CreateSyntax("listowned", ListOwned, NULL, 0,
1236 "list groups owned by an entry or zero id gets orphaned groups");
1237 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1240 ts = cmd_CreateSyntax("listentries", ListEntries, NULL, 0,
1241 "list users/groups in the protection database");
1242 cmd_AddParm(ts, "-users", CMD_FLAG, CMD_OPTIONAL, "list user entries");
1243 cmd_AddParm(ts, "-groups", CMD_FLAG, CMD_OPTIONAL, "list group entries");
1246 ts = cmd_CreateSyntax("interactive", pts_Interactive, NULL, 0,
1247 "enter interactive mode");
1249 cmd_CreateAlias(ts, "in");
1251 ts = cmd_CreateSyntax("quit", pts_Quit, NULL, 0, "exit program");
1254 ts = cmd_CreateSyntax("source", pts_Source, NULL, 0, "read commands from file");
1255 cmd_AddParm(ts, "-file", CMD_SINGLE, 0, "filename");
1258 ts = cmd_CreateSyntax("sleep", pts_Sleep, NULL, 0, "pause for a bit");
1259 cmd_AddParm(ts, "-delay", CMD_SINGLE, 0, "seconds");
1262 cmd_SetBeforeProc(GetGlobals, &state);
1266 if (cmd_Dispatch(argc, argv)) {
1267 CleanUp(NULL, NULL);
1270 while (source && !finished) {
1271 if (isatty(fileno(source)))
1272 fprintf(stderr, "pts> ");
1273 if (!fgets(line, sizeof line, source)) {
1279 for (cp = line; *cp; ++cp)
1289 cmd_ParseLine(line, parsev, &parsec,
1290 sizeof(parsev) / sizeof(*parsev));
1292 afs_com_err(whoami, code, "parsing line: <%s>", line);
1296 parsev[0] = argv[0];
1297 cmd_Dispatch(parsec, parsev);
1299 cmd_FreeArgv(parsev);
1301 CleanUp(NULL, NULL);