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>
28 #include <rx/rxgk_int.h>
33 #include "ptprototypes.h"
40 extern struct ubik_client *pruclient;
43 struct sourcestack *s_next;
50 char cell[MAXCELLCHARS];
54 * Constants for add_std_args() global parameters. Start at offset 16, to try
55 * to avoid conflicting with any subcommand-specific parameters. If any
56 * subcommand uses more than 16 params, these constants will probably need to
71 static int CleanUp(struct cmd_syndesc *as, void *arock);
74 pts_Interactive(struct cmd_syndesc *as, void *arock)
82 pts_Quit(struct cmd_syndesc *as, void *arock)
89 pts_Source(struct cmd_syndesc *as, void *arock)
92 struct sourcestack *sp;
95 if (!as->parms[0].items) {
96 /* can this happen? */
99 fd = fopen(as->parms[0].items->data, "r");
101 perror(as->parms[0].items->data);
104 sp = malloc(sizeof *sp);
106 return errno ? errno : ENOMEM;
117 pts_Sleep(struct cmd_syndesc *as, void *arock)
120 if (!as->parms[0].items) {
121 /* can this happen? */
124 delay = atoi(as->parms[0].items->data);
125 #ifdef AFS_PTHREAD_ENV
136 struct sourcestack *sp;
150 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
151 * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
152 * anyway. It's gonna give somebody fits to debug, I know, I know.
159 win32_enableCrypt(void)
166 /* Look up configuration parameters in Registry */
167 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
168 0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
169 if (code != ERROR_SUCCESS) {
170 dummyLen = sizeof(cryptall);
171 RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL,
172 (BYTE *) &cryptall, &dummyLen);
174 RegCloseKey (parmKey);
178 #endif /* AFS_NT40_ENV */
181 GetGlobals(struct cmd_syndesc *as, void *arock)
183 struct authstate *state = (struct authstate *) arock;
189 const char* retry_confdir;
190 RXGK_Level rxgk_level = RXGK_LEVEL_BOGUS;
194 if (!strcmp(as->name, "help"))
202 if (state->initialized == 0) {
206 if (as->parms[OPT_cell].items) {
208 cell = as->parms[OPT_cell].items->data;
210 if (as->parms[OPT_noauth].items) {
214 if (as->parms[OPT_localauth].items) {
218 if (as->parms[OPT_auth].items) {
222 if (as->parms[OPT_encrypt].items
224 || win32_enableCrypt()
225 #endif /* AFS_NT40_ENV */
230 if (as->parms[OPT_test].items || as->parms[OPT_localauth].items) {
232 confdir = AFSDIR_SERVER_ETC_DIRPATH;
233 retry_confdir = NULL;
236 confdir = AFSDIR_SERVER_ETC_DIRPATH;
237 retry_confdir = NULL;
239 confdir = AFSDIR_CLIENT_ETC_DIRPATH;
240 retry_confdir = AFSDIR_SERVER_ETC_DIRPATH;
244 if (as->parms[OPT_config].items) { /* -config */
246 confdir = as->parms[OPT_config].items->data;
247 retry_confdir = NULL;
250 if (as->parms[OPT_rxgk].items) {
251 char *rxgk_seclevel_str = as->parms[OPT_rxgk].items->data;
254 if (strcmp(rxgk_seclevel_str, "clear") == 0)
255 rxgk_level = RXGK_LEVEL_CLEAR;
256 else if (strcmp(rxgk_seclevel_str, "auth") == 0)
257 rxgk_level = RXGK_LEVEL_AUTH;
258 else if (strcmp(rxgk_seclevel_str, "crypt") == 0)
259 rxgk_level = RXGK_LEVEL_CRYPT;
261 fprintf(stderr, "Invalid argument to -rxgk: %s\n", rxgk_seclevel_str);
269 code = pr_Initialize2(sec, confdir, cell, rxgk_level);
270 if (code != 0 && retry_confdir != NULL) {
271 fprintf(stderr, "pts: Retrying initialization with directory %s\n",
273 code = pr_Initialize2(sec, retry_confdir, cell, rxgk_level);
279 afs_com_err(whoami, code, "while initializing");
283 state->initialized = 1;
284 if (cell && cell != state->cell)
285 strncpy(state->cell, cell, MAXCELLCHARS-1);
288 if (as->parms[OPT_force].items)
295 CleanUp(struct cmd_syndesc *as, void *arock)
297 if (as && !strcmp(as->name, "help"))
300 /* Need to shutdown the ubik_client & other connections */
308 CreateGroup(struct cmd_syndesc *as, void *arock)
313 struct cmd_item *namei;
314 struct cmd_item *idi;
316 namei = as->parms[0].items;
317 idi = as->parms[2].items;
318 if (as->parms[1].items)
319 owner = as->parms[1].items->data;
325 code = util_GetInt32(idi->data, &id);
327 afs_com_err(whoami, code, "because group id was: '%s'",
332 fprintf(stderr, "0 isn't a valid group id; aborting\n");
337 afs_com_err(whoami, code, "because group id %d was not negative",
346 code = pr_CreateGroup(namei->data, owner, &id);
349 afs_com_err(whoami, code,
350 "; unable to create group %s with id %d%s%s%s%s",
351 namei->data, id, owner ? " owned by '" : "",
352 owner ? owner : "", owner ? "'" : "",
353 (force ? " (ignored)" : ""));
355 afs_com_err(whoami, code, "; unable to create group %s %s",
356 namei->data, (force ? "(ignored)" : ""));
360 printf("group %s has id %d\n", namei->data, id);
367 CreateUser(struct cmd_syndesc *as, void *arock)
371 struct cmd_item *namei;
372 struct cmd_item *idi;
374 namei = as->parms[0].items;
375 idi = as->parms[1].items;
379 code = util_GetInt32(idi->data, &id);
381 afs_com_err(whoami, code, "because id was: '%s'", idi->data);
385 fprintf(stderr, "0 isn't a valid user id; aborting\n");
390 afs_com_err(whoami, code, "because user id %d was not positive",
398 code = pr_CreateUser(namei->data, &id);
401 afs_com_err(whoami, code,
402 "; unable to create user %s with id %d %s",
403 namei->data, id, (force ? "(ignored)" : ""));
405 afs_com_err(whoami, code, "; unable to create user %s %s",
406 namei->data, (force ? "(ignored)" : ""));
410 printf("User %s has id %d\n", namei->data, id);
418 GetNameOrId(struct cmd_syndesc *as, struct idlist *lids,
419 struct namelist *lnames)
422 int n = 0, nd = 0, nm = 0, id, x;
424 struct namelist names, tnames; /* local copy, if not ret. names */
425 struct idlist ids, tids; /* local copy, if not ret. ids */
428 /* Initialise our outputs */
429 memset(lids, 0, sizeof(struct idlist));
431 memset(lnames, 0, sizeof(struct namelist));
433 for (i = as->parms[0].items; i; i = i->next)
436 /* Nothing to do, so bail */
440 lids->idlist_val = malloc(n * sizeof(afs_int32));
441 lids->idlist_len = n;
442 ids.idlist_val = malloc(n * sizeof(afs_int32));
444 names.namelist_val = malloc(n * PR_MAXNAMELEN);
445 names.namelist_len = n;
447 lnames->namelist_val = malloc(n * PR_MAXNAMELEN);
448 lnames->namelist_len = 0;
450 for (i = as->parms[0].items; i; i = i->next) {
451 tnames.namelist_val = malloc(PR_MAXNAMELEN);
452 strncpy(tnames.namelist_val[0], i->data, PR_MAXNAMELEN);
453 tnames.namelist_len = 1;
456 code = pr_NameToId(&tnames, &tids);
457 if ((!code && (tids.idlist_val[0] != 32766))
458 || (code = util_GetInt32(i->data, &id))) {
459 /* Assume it's a name instead */
460 strncpy(names.namelist_val[nm++], i->data, PR_MAXNAMELEN);
462 ids.idlist_val[nd++] = id;
464 free(tnames.namelist_val);
466 names.namelist_len = nm;
468 tids.idlist_len = nd = nm = 0;
470 code = pr_NameToId(&names, &tids);
472 afs_com_err(whoami, code, "so couldn't look up names");
474 for (n = 0; n < tids.idlist_len; n++) {
475 if (tids.idlist_val[n] == ANONYMOUSID) {
476 afs_com_err(whoami, PRNOENT, "so couldn't look up id for %s",
477 names.namelist_val[n]);
480 lids->idlist_val[nd] = tids.idlist_val[n];
482 strcpy(lnames->namelist_val[nd], names.namelist_val[n]);
486 for (x = 0; x < ids.idlist_len; x++) {
487 lids->idlist_val[nd + x] = ids.idlist_val[x];
489 lids->idlist_len = nd + x;
490 if (!code && lnames) {
491 tnames.namelist_val = 0;
492 tnames.namelist_len = 0;
493 code = pr_IdToName(&ids, &tnames);
495 afs_com_err(whoami, code, "translating ids");
499 for (x = 0; x < ids.idlist_len; x++)
500 strcpy(lnames->namelist_val[nd + x], tnames.namelist_val[x]);
501 lnames->namelist_len = nd + x;
505 /* treat things as working if any of the lookups worked */
509 if (lids->idlist_val)
510 free(lids->idlist_val);
518 AddToGroup(struct cmd_syndesc *as, void *arock)
521 struct cmd_item *u, *g;
523 for (u = as->parms[0].items; u; u = u->next) {
524 for (g = as->parms[1].items; g; g = g->next) {
525 code = pr_AddToGroup(u->data, g->data);
527 afs_com_err(whoami, code,
528 "; unable to add user %s to group %s %s", u->data,
529 g->data, (force ? "(ignored)" : ""));
539 RemoveFromGroup(struct cmd_syndesc *as, void *arock)
542 struct cmd_item *u, *g;
544 for (u = as->parms[0].items; u; u = u->next) {
545 for (g = as->parms[1].items; g; g = g->next) {
546 code = pr_RemoveUserFromGroup(u->data, g->data);
548 afs_com_err(whoami, code,
549 "; unable to remove user %s from group %s %s",
550 u->data, g->data, (force ? "(ignored)" : ""));
560 ListMembership(struct cmd_syndesc *as, void *arock)
569 if (GetNameOrId(as, &ids, &names))
572 for (i = 0; i < ids.idlist_len; i++) {
573 afs_int32 id = ids.idlist_val[i];
574 char *name = names.namelist_val[i];
576 if (id == ANONYMOUSID)
577 continue; /* bad entry */
579 list.namelist_val = 0;
580 list.namelist_len = 0;
581 if (as->parms[2].items) { /* -expandgroups */
582 code = pr_IDListExpandedMembers(id, &list);
586 code = pr_IDListMembers(id, &list);
589 afs_com_err(whoami, code, "; unable to get membership of %s (id: %d)",
594 printf("Members of %s (id: %d) are:\n", name, id);
596 printf("Groups %s (id: %d) is a member of:\n", name, id);
598 for (j = 0; j < list.namelist_len; j++)
599 printf(" %s\n", list.namelist_val[j]);
600 if (list.namelist_val)
601 free(list.namelist_val);
602 if (as->parms[1].items && id < 0) { /* -supergroups */
603 list.namelist_val = 0;
604 list.namelist_len = 0;
605 code = pr_ListSuperGroups(ids.idlist_val[i], &list);
606 if (code == RXGEN_OPCODE) {
607 continue; /* server does not support supergroups */
608 } else if (code != 0) {
609 afs_com_err(whoami, code,
610 "; unable to get supergroups of %s (id: %d)",
614 printf("Groups %s (id: %d) is a member of:\n", name, id);
615 for (j = 0; j < list.namelist_len; j++)
616 printf(" %s\n", list.namelist_val[j]);
617 if (list.namelist_val)
618 free(list.namelist_val);
622 free(ids.idlist_val);
623 if (names.namelist_val)
624 free(names.namelist_val);
629 Delete(struct cmd_syndesc *as, void *arock)
636 if (GetNameOrId(as, &ids, &names))
639 for (i = 0; i < ids.idlist_len; i++) {
640 afs_int32 id = ids.idlist_val[i];
641 char *name = names.namelist_val[i];
643 if (id == ANONYMOUSID)
646 code = pr_DeleteByID(id);
648 afs_com_err(whoami, code, "deleting %s (id: %d) %s", name, id,
649 (force ? "(ignored)" : ""));
655 free(ids.idlist_val);
656 if (names.namelist_val)
657 free(names.namelist_val);
661 /* access bit translation info */
663 char *flags_upcase = "SOMA "; /* legal all access values */
664 char *flags_dncase = "s mar"; /* legal member acces values */
665 int flags_shift[5] = { 2, 1, 2, 2, 1 }; /* bits for each */
668 CheckEntry(struct cmd_syndesc *as, void *arock)
672 int i, flag = 0, admin = 0;
673 namelist lnames, names;
676 struct prcheckentry aentry;
677 prname admins = "system:administrators";
679 if (GetNameOrId(as, &ids, &names))
683 lids.idlist_val = malloc(sizeof(afs_int32) * 2);
684 lnames.namelist_len = 0;
685 lnames.namelist_val = 0;
687 for (i = 0; i < ids.idlist_len; i++) {
688 afs_int32 id = ids.idlist_val[i];
690 if (id == ANONYMOUSID)
694 code = pr_ListEntry(id, &aentry);
697 afs_com_err(whoami, code, "; unable to find entry for (id: %d)", id);
701 lids.idlist_val[0] = aentry.owner;
702 lids.idlist_val[1] = aentry.creator;
703 code = pr_IdToName(&lids, &lnames);
706 afs_com_err(whoami, code,
707 "translating owner (%d) and creator (%d) ids",
708 aentry.owner, aentry.creator);
711 printf("Name: %s, id: %d, owner: %s, creator: %s,\n", aentry.name,
712 aentry.id, lnames.namelist_val[0], lnames.namelist_val[1]);
713 printf(" membership: %d", aentry.count);
716 afs_int32 flags = aentry.flags;
719 access[5] = 0; /* null-terminate the string */
720 for (j = 4; j >= 0; j--) {
739 printf(", flags: %s", access);
741 if (aentry.id == SYSADMINID)
743 else if (!pr_IsAMemberOf(aentry.name, admins, &flag)) {
748 printf(", group quota: unlimited");
750 printf(", group quota: %d", aentry.ngroups);
754 if (lnames.namelist_val)
755 free(lnames.namelist_val);
757 free(lids.idlist_val);
759 free(ids.idlist_val);
765 ListEntries(struct cmd_syndesc *as, void *arock)
768 afs_int32 flag, startindex, nentries, nextstartindex;
769 struct prlistentries *entriesp = 0, *e;
773 if (as->parms[1].items)
775 if (as->parms[0].items)
778 printf("Name ID Owner Creator\n");
779 for (startindex = 0; startindex != -1; startindex = nextstartindex) {
781 pr_ListEntries(flag, startindex, &nentries, &entriesp,
784 afs_com_err(whoami, code, "; unable to list entries");
790 /* Now display each of the entries we read */
791 for (i = 0, e = entriesp; i < nentries; i++, e++) {
792 printf("%-25s %6d %6d %7d \n", e->name, e->id, e->owner,
802 ChownGroup(struct cmd_syndesc *as, void *arock)
809 name = as->parms[0].items->data;
810 owner = as->parms[1].items->data;
811 code = pr_ChangeEntry(name, newname, 0, owner);
813 afs_com_err(whoami, code, "; unable to change owner of %s to %s", name,
819 ChangeName(struct cmd_syndesc *as, void *arock)
826 oldname = as->parms[0].items->data;
827 newname = as->parms[1].items->data;
828 code = pr_ChangeEntry(oldname, newname, 0, owner);
830 afs_com_err(whoami, code, "; unable to change name of %s to %s", oldname,
836 ListMax(struct cmd_syndesc *as, void *arock)
839 afs_int32 maxUser, maxGroup;
841 code = pr_ListMaxUserId(&maxUser);
843 afs_com_err(whoami, code, "getting maximum user id");
845 code = pr_ListMaxGroupId(&maxGroup);
847 afs_com_err(whoami, code, "getting maximum group id");
849 printf("Max user id is %d and max group id is %d.\n", maxUser,
857 SetMaxCommand(struct cmd_syndesc *as, void *arock)
863 if (as->parms[1].items) {
865 code = util_GetInt32(as->parms[1].items->data, &maxid);
867 afs_com_err(whoami, code, "because id was: '%s'",
868 as->parms[1].items->data);
870 code = pr_SetMaxUserId(maxid);
872 afs_com_err(whoami, code, "so couldn't set Max User Id to %d",
876 if (as->parms[0].items) {
878 code = util_GetInt32(as->parms[0].items->data, &maxid);
880 afs_com_err(whoami, code, "because id was: '%s'",
881 as->parms[0].items->data);
883 code = pr_SetMaxGroupId(maxid);
885 afs_com_err(whoami, code, "so couldn't set Max Group Id to %d",
889 if (!as->parms[0].items && !as->parms[1].items) {
891 fprintf(stderr, "Must specify at least one of group or user.\n");
897 SetFields(struct cmd_syndesc *as, void *arock)
903 afs_int32 mask, flags=0, ngroups, nusers;
905 if (GetNameOrId(as, &ids, &names))
912 if (as->parms[1].items) { /* privacy bits */
913 char *access = as->parms[1].items->data;
916 if (strpbrk(access, "76543210") != 0) { /* all octal digits */
917 sscanf(access, "%lo", (long unsigned int *) &flags);
918 } else { /* interpret flag bit names */
919 if (strlen(access) != 5) {
921 fprintf(stderr, "Access bits must be of the form 'somar', not %s\n",
925 if (strpbrk(access, "somar-") == 0)
928 for (i = 0; i < 5; i++) {
929 if (access[i] == flags_upcase[i])
931 else if (access[i] == flags_dncase[i])
933 else if (access[i] == '-')
937 "Access bits out of order or illegal:\n must be a combination of letters from '%s' or '%s' or hyphen, not %s\n",
938 flags_upcase, flags_dncase, access);
941 flags <<= flags_shift[i];
942 if (flags_shift[i] == 1) {
949 mask |= PR_SF_ALLBITS;
951 if (as->parms[2].items) { /* limitgroups */
952 code = util_GetInt32(as->parms[2].items->data, &ngroups);
954 afs_com_err(whoami, code, "because ngroups was: '%s'",
955 as->parms[2].items->data);
958 mask |= PR_SF_NGROUPS;
961 for (i = 0; i < ids.idlist_len; i++) {
962 afs_int32 id = ids.idlist_val[i];
963 char *name = names.namelist_val[i];
964 if (id == ANONYMOUSID)
966 code = pr_SetFieldsEntry(id, mask, flags, ngroups, nusers);
968 afs_com_err(whoami, code, "; unable to set fields for %s (id: %d)",
974 free(ids.idlist_val);
975 if (names.namelist_val)
976 free(names.namelist_val);
981 ListOwned(struct cmd_syndesc *as, void *arock)
990 if (GetNameOrId(as, &ids, &names))
993 for (i = 0; i < ids.idlist_len; i++) {
994 afs_int32 oid = ids.idlist_val[i];
995 char *name = names.namelist_val[i];
997 if (oid == ANONYMOUSID)
1001 printf("Groups owned by %s (id: %d) are:\n", name, oid);
1003 printf("Orphaned groups are:\n");
1006 list.namelist_val = 0;
1007 list.namelist_len = 0;
1008 code = pr_ListOwned(oid, &list, &more);
1010 afs_com_err(whoami, code,
1011 "; unable to get owner list for %s (id: %d)", name,
1016 for (j = 0; j < list.namelist_len; j++)
1017 printf(" %s\n", list.namelist_val[j]);
1018 if (list.namelist_val)
1019 free(list.namelist_val);
1024 free(ids.idlist_val);
1025 if (names.namelist_val)
1026 free(names.namelist_val);
1031 add_std_args(struct cmd_syndesc *ts)
1035 if (asprintf(&test_help, "use config file in %s",
1036 AFSDIR_SERVER_ETC_DIRPATH) < 0) {
1037 test_help = strdup("use server config file");
1040 cmd_AddParmAtOffset(ts, OPT_cell, "-cell", CMD_SINGLE, CMD_OPTIONAL,
1042 cmd_AddParmAtOffset(ts, OPT_noauth, "-noauth", CMD_FLAG, CMD_OPTIONAL,
1043 "run unauthenticated");
1044 cmd_AddParmAtOffset(ts, OPT_test, "-test", CMD_FLAG,
1045 CMD_OPTIONAL | CMD_HIDE, test_help);
1046 cmd_AddParmAtOffset(ts, OPT_force, "-force", CMD_FLAG, CMD_OPTIONAL,
1047 "Continue oper despite reasonable errors");
1048 cmd_AddParmAtOffset(ts, OPT_localauth, "-localauth", CMD_FLAG,
1049 CMD_OPTIONAL, "use local authentication");
1050 cmd_AddParmAtOffset(ts, OPT_auth, "-auth", CMD_FLAG, CMD_OPTIONAL,
1051 "use user's authentication (default)");
1052 cmd_AddParmAtOffset(ts, OPT_encrypt, "-encrypt", CMD_FLAG, CMD_OPTIONAL,
1053 "encrypt commands");
1054 cmd_AddParmAtOffset(ts, OPT_config, "-config", CMD_SINGLE, CMD_OPTIONAL,
1056 cmd_AddParmAtOffset(ts, OPT_rxgk, "-rxgk", CMD_SINGLE, CMD_OPTIONAL,
1057 "rxgk security level to use");
1062 static void add_NameOrId_args (ts)
1063 struct cmd_syndesc *ts;
1065 cmd_AddParm(ts,"-name",CMD_LIST,CMD_OPTIONAL,"user or group name");
1066 cmd_AddParm(ts,"-id",CMD_LIST,CMD_OPTIONAL,"user or group id");
1070 #include "AFS_component_version_number.c"
1073 main(int argc, char **argv)
1076 struct cmd_syndesc *ts;
1081 char *parsev[CMD_MAXPARMS];
1083 struct authstate state;
1090 WSAStartup(0x0101, &WSAjunk);
1093 #ifdef AFS_AIX32_ENV
1095 * The following signal action for AIX is necessary so that in case of a
1096 * crash (i.e. core is generated) we can include the user's data section
1097 * in the core dump. Unfortunately, by default, only a partial core is
1098 * generated which, in many cases, isn't too useful.
1100 struct sigaction nsa;
1102 sigemptyset(&nsa.sa_mask);
1103 nsa.sa_handler = SIG_DFL;
1104 nsa.sa_flags = SA_FULLDUMP;
1105 sigaction(SIGSEGV, &nsa, NULL);
1108 memset(&state, 0, sizeof(state));
1109 state.sec = 1; /* default is auth */
1111 ts = cmd_CreateSyntax("creategroup", CreateGroup, NULL, 0,
1112 "create a new group");
1113 cmd_AddParm(ts, "-name", CMD_LIST, 0, "group name");
1114 cmd_AddParm(ts, "-owner", CMD_SINGLE, CMD_OPTIONAL, "owner of the group");
1115 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL,
1116 "id (negated) for the group");
1118 cmd_CreateAlias(ts, "cg");
1120 ts = cmd_CreateSyntax("createuser", CreateUser, NULL, 0, "create a new user");
1121 cmd_AddParm(ts, "-name", CMD_LIST, 0, "user name");
1122 cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "user id");
1124 cmd_CreateAlias(ts, "cu");
1126 ts = cmd_CreateSyntax("adduser", AddToGroup, NULL, 0, "add a user to a group");
1127 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1128 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1131 ts = cmd_CreateSyntax("removeuser", RemoveFromGroup, NULL, 0,
1132 "remove a user from a group");
1133 cmd_AddParm(ts, "-user", CMD_LIST, 0, "user name");
1134 cmd_AddParm(ts, "-group", CMD_LIST, 0, "group name");
1137 ts = cmd_CreateSyntax("membership", ListMembership, NULL, 0,
1138 "list membership of a user or group");
1139 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1140 cmd_AddParm(ts, "-supergroups", CMD_FLAG, CMD_OPTIONAL, "show supergroups");
1141 cmd_AddParm(ts, "-expandgroups", CMD_FLAG, CMD_OPTIONAL, "expand super and sub group membership");
1143 cmd_CreateAlias(ts, "groups");
1145 ts = cmd_CreateSyntax("delete", Delete, NULL, 0,
1146 "delete a user or group from database");
1147 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1150 ts = cmd_CreateSyntax("examine", CheckEntry, NULL, 0, "examine an entry");
1151 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1153 cmd_CreateAlias(ts, "check");
1155 ts = cmd_CreateSyntax("chown", ChownGroup, NULL, 0,
1156 "change ownership of a group");
1157 cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "group name");
1158 cmd_AddParm(ts, "-owner", CMD_SINGLE, 0, "new owner");
1161 ts = cmd_CreateSyntax("rename", ChangeName, NULL, 0, "rename user or group");
1162 cmd_AddParm(ts, "-oldname", CMD_SINGLE, 0, "old name");
1163 cmd_AddParm(ts, "-newname", CMD_SINGLE, 0, "new name");
1165 cmd_CreateAlias(ts, "chname");
1167 ts = cmd_CreateSyntax("listmax", ListMax, NULL, 0, "list max id");
1170 ts = cmd_CreateSyntax("setmax", SetMaxCommand, NULL, 0, "set max id");
1171 cmd_AddParm(ts, "-group", CMD_SINGLE, CMD_OPTIONAL, "group max");
1172 cmd_AddParm(ts, "-user", CMD_SINGLE, CMD_OPTIONAL, "user max");
1175 ts = cmd_CreateSyntax("setfields", SetFields, NULL, 0,
1176 "set fields for an entry");
1177 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1178 cmd_AddParm(ts, "-access", CMD_SINGLE, CMD_OPTIONAL, "set privacy flags");
1179 cmd_AddParm(ts, "-groupquota", CMD_SINGLE, CMD_OPTIONAL,
1180 "set limit on group creation");
1183 ts = cmd_CreateSyntax("listowned", ListOwned, NULL, 0,
1184 "list groups owned by an entry or zero id gets orphaned groups");
1185 cmd_AddParm(ts, "-nameorid", CMD_LIST, 0, "user or group name or id");
1188 ts = cmd_CreateSyntax("listentries", ListEntries, NULL, 0,
1189 "list users/groups in the protection database");
1190 cmd_AddParm(ts, "-users", CMD_FLAG, CMD_OPTIONAL, "list user entries");
1191 cmd_AddParm(ts, "-groups", CMD_FLAG, CMD_OPTIONAL, "list group entries");
1194 ts = cmd_CreateSyntax("interactive", pts_Interactive, NULL, 0,
1195 "enter interactive mode");
1197 cmd_CreateAlias(ts, "in");
1199 ts = cmd_CreateSyntax("quit", pts_Quit, NULL, 0, "exit program");
1202 ts = cmd_CreateSyntax("source", pts_Source, NULL, 0, "read commands from file");
1203 cmd_AddParm(ts, "-file", CMD_SINGLE, 0, "filename");
1206 ts = cmd_CreateSyntax("sleep", pts_Sleep, NULL, 0, "pause for a bit");
1207 cmd_AddParm(ts, "-delay", CMD_SINGLE, 0, "seconds");
1210 cmd_SetBeforeProc(GetGlobals, &state);
1214 if (cmd_Dispatch(argc, argv)) {
1215 CleanUp(NULL, NULL);
1218 while (source && !finished) {
1219 if (isatty(fileno(source)))
1220 fprintf(stderr, "pts> ");
1221 if (!fgets(line, sizeof line, source)) {
1227 for (cp = line; *cp; ++cp)
1237 cmd_ParseLine(line, parsev, &parsec,
1238 sizeof(parsev) / sizeof(*parsev));
1240 afs_com_err(whoami, code, "parsing line: <%s>", line);
1244 parsev[0] = argv[0];
1245 cmd_Dispatch(parsec, parsev);
1247 cmd_FreeArgv(parsev);
1249 CleanUp(NULL, NULL);