2 * Command line oriented Moira users tool.
4 * zacheiss@mit.edu, September 2001
8 * Copyright (C) 2000, 2001 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, please see the file
13 #include <mit-copyright.h>
15 #include <moira_site.h>
33 struct string_list *next;
42 /* argument parsing macro */
43 #define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
45 /* flags from command line */
46 int info_flag, update_flag, create_flag, deact_flag, reg_flag;
47 int list_res_flag, update_res_flag, unformatted_flag, verbose, noauth;
49 struct owner_type *sponsor;
50 struct string_list *reservation_add_queue, *reservation_remove_queue;
52 char *username, *whoami;
54 char *newlogin, *uid, *shell, *winshell, *last, *first, *middle, *u_status;
55 char *clearid, *class, *comment, *secure, *winhomedir, *winprofiledir;
57 struct owner_type *parse_member(char *s);
59 static char *states[] = {
62 "Half Registered (2)",
64 "Not registerable (4)",
65 "Enrolled/Registerable (5)",
66 "Enrolled/Not Registerable (6)",
68 "Registerable, Kerberos only (8)",
69 "Active, Kerberos only (9)"
72 static char *UserState(int state)
74 static char buf[BUFSIZ];
76 if (state < 0 || state >= US_END)
78 sprintf(buf, "Unknown (%d)", state);
84 void usage(char **argv);
85 int save_query_info(int argc, char **argv, void *hint);
86 int show_reservations(int argc, char **argv, void *hint);
87 void show_user_info(char **argv);
88 void show_user_info_unformatted(char **argv);
89 struct string_list *add_to_string_list(struct string_list *old_list, char *s);
90 int wrap_mr_query(char *handle, int argc, char **argv,
91 int (*callback)(int, char **, void *), void *callarg);
92 void print_query(char *query_name, int argc, char **argv);
94 int main(int argc, char **argv)
100 /* clear all flags & lists */
101 info_flag = update_flag = create_flag = deact_flag = reg_flag = 0;
102 list_res_flag = update_res_flag = unformatted_flag = verbose = noauth = 0;
103 newlogin = uid = shell = winshell = last = first = middle = NULL;
104 u_status = clearid = class = comment = secure = NULL;
105 winhomedir = winprofiledir = NULL;
106 reservation_add_queue = reservation_remove_queue = NULL;
111 while (++arg - argv < argc)
115 if (argis("i", "info"))
117 else if (argis("C", "create"))
119 else if (argis("D", "deact"))
121 else if (argis("r", "register"))
123 else if (argis("R", "rename")) {
124 if (arg - argv < argc - 1) {
131 else if (argis("U", "uid")) {
132 if (arg - argv < argc - 1) {
139 else if (argis("s", "shell")) {
140 if (arg - argv < argc - 1) {
147 else if (argis("w", "winshell")) {
148 if (arg - argv < argc - 1) {
155 else if (argis("L", "last")) {
156 if (arg - argv < argc - 1) {
163 else if (argis("F", "first")) {
164 if (arg - argv < argc - 1) {
171 else if (argis("M", "middle")) {
172 if (arg - argv < argc - 1) {
179 else if (argis("S", "status")) {
180 if (arg - argv < argc - 1) {
187 len = strlen(u_status);
188 for (i = 0; i < len; i++) {
189 if (!isdigit(u_status[i])) {
190 printf("Error: status code %s is not numeric.\n", u_status);
197 else if (argis("I", "mitid")) {
198 if (arg - argv < argc - 1) {
205 else if (argis("cl", "class")) {
206 if (arg - argv < argc - 1) {
213 else if (argis("c", "comment")) {
214 if (arg - argv < argc - 1) {
221 else if (argis("6", "secure")) {
222 if (arg - argv < argc - 1) {
229 else if (argis("wh", "winhomedir")) {
230 if (arg - argv < argc - 1) {
237 else if (argis("wp", "winprofiledir")) {
238 if (arg - argv < argc - 1) {
241 winprofiledir = *arg;
245 else if (argis("sp", "sponsor")) {
246 if (arg - argv < argc - 1) {
249 sponsor = parse_member(*arg);
253 else if (argis("ar", "addreservation")) {
254 if (arg - argv < argc - 1) {
256 reservation_add_queue = add_to_string_list(reservation_add_queue,
262 else if (argis("dr", "deletereservation")) {
263 if (arg - argv < argc - 1) {
265 reservation_remove_queue = add_to_string_list(reservation_remove_queue, *arg);
270 else if (argis("lr", "listreservation"))
272 else if (argis("u", "unformatted"))
274 else if (argis("n", "noauth"))
276 else if (argis("v", "verbose"))
278 else if (argis("db", "database"))
280 if (arg - argv < argc - 1)
291 else if (username == NULL)
296 if (username == NULL && !create_flag)
299 /* default to info_flag if nothing else was specified */
300 if(!(info_flag || update_flag || create_flag || \
301 deact_flag || reg_flag || list_res_flag || \
307 status = mrcl_connect(server, "stanley", 12, !noauth);
308 if (status == MRCL_AUTH_ERROR)
310 com_err(whoami, 0, "Try the -noauth flag if you don't "
311 "need authentication.");
316 /* create if needed */
322 for (cnt = 0; cnt < 14; cnt++) {
327 argv[U_NAME] = username;
329 argv[U_NAME] = UNIQUE_LOGIN;
333 argv[U_UID] = UNIQUE_UID;
335 argv[U_SHELL] = shell;
337 argv[U_SHELL] = "/bin/athena/tcsh";
339 argv[U_WINCONSOLESHELL] = winshell;
341 argv[U_WINCONSOLESHELL] = "cmd";
345 argv[U_FIRST] = first;
347 argv[U_MIDDLE] = middle;
349 argv[U_STATE] = u_status;
353 argv[U_MITID] = clearid;
355 argv[U_CLASS] = class;
357 argv[U_COMMENT] = comment;
358 /* Signature field always is the empty string */
359 argv[U_SIGNATURE] = "";
361 argv[U_SECURE] = secure;
363 argv[U_SECURE] = "0";
365 argv[U_WINHOMEDIR] = winhomedir;
367 argv[U_WINHOMEDIR] = "[DFS]";
369 argv[U_WINPROFILEDIR] = winprofiledir;
371 argv[U_WINPROFILEDIR] = "[DFS]";
374 argv[U_SPONSOR_NAME] = sponsor->name;
375 switch (sponsor->type)
379 argv[U_SPONSOR_TYPE] = "USER";
380 status = wrap_mr_query("add_user_account", 17, argv, NULL, NULL);
381 if (sponsor->type != M_ANY || status != MR_USER)
385 argv[U_SPONSOR_TYPE] = "LIST";
386 status = wrap_mr_query("add_user_account", 17, argv, NULL, NULL);
390 argv[U_SPONSOR_TYPE] = "KERBEROS";
391 status = mrcl_validate_kerberos_member(argv[U_SPONSOR_NAME],
392 &argv[U_SPONSOR_NAME]);
393 if (mrcl_get_message())
394 mrcl_com_err(whoami);
395 if (status == MRCL_REJECT)
397 status = wrap_mr_query("add_user_account", 17, argv, NULL, NULL);
401 argv[U_SPONSOR_TYPE] = "NONE";
402 status = wrap_mr_query("add_user_account", 17, argv, NULL, NULL);
408 argv[U_SPONSOR_TYPE] = "NONE";
409 argv[U_SPONSOR_NAME] = "NONE";
411 status = wrap_mr_query("add_user_account", 17, argv, NULL, NULL);
416 com_err(whoami, status, "while adding user account.");
420 else if (update_flag)
428 status = wrap_mr_query("get_user_account_by_login", 1, args,
429 save_query_info, old_argv);
432 com_err(whoami, status, "while getting user information.");
436 argv[1] = old_argv[0];
437 argv[2] = old_argv[1];
438 argv[3] = old_argv[2];
439 argv[4] = old_argv[3];
440 argv[5] = old_argv[4];
441 argv[6] = old_argv[5];
442 argv[7] = old_argv[6];
443 argv[8] = old_argv[7];
444 argv[9] = old_argv[8];
445 argv[10] = old_argv[9];
446 argv[11] = old_argv[10];
447 argv[12] = old_argv[11];
448 argv[13] = old_argv[12];
449 argv[14] = old_argv[13];
450 argv[15] = old_argv[14];
451 argv[16] = old_argv[15];
452 argv[17] = old_argv[16];
480 argv[14] = winhomedir;
482 argv[15] = winprofiledir;
485 argv[17] = sponsor->name;
486 switch (sponsor->type)
491 status = wrap_mr_query("update_user_account", 18, argv, NULL,
493 if (sponsor->type != M_ANY || status != MR_USER)
498 status = wrap_mr_query("update_user_account", 18, argv, NULL,
503 argv[16] = "KERBEROS";
504 status = mrcl_validate_kerberos_member(argv[17], &argv[17]);
505 if (mrcl_get_message())
506 mrcl_com_err(whoami);
507 if (status == MRCL_REJECT)
509 status = wrap_mr_query("update_user_account", 18, argv, NULL,
515 status = wrap_mr_query("update_user_account", 18, argv, NULL,
521 status = wrap_mr_query("update_user_account", 18, argv, NULL, NULL);
524 com_err(whoami, status, "while updating user.");
529 /* Deactivate a user, and the matching list and filesystem if they exist */
539 status = wrap_mr_query("update_user_status", 2, args, NULL, NULL);
542 com_err(whoami, status, "while deactivating user.");
546 status = wrap_mr_query("get_list_info", 1, args, save_query_info, argv);
547 if (status == MR_SUCCESS)
549 for (i = 15; i > 0; i--)
550 argv[i + 1] = argv[i];
552 argv[L_ACTIVE + 1] = "0";
554 status = wrap_mr_query("update_list", 16, argv, NULL, NULL);
557 com_err(whoami, status, "while updating list, "
558 "not deactivating list or filesystem.");
562 else if (status && status != MR_NO_MATCH)
564 com_err(whoami, status, "while retrieving list information.");
568 status = wrap_mr_query("get_filesys_by_label", 1, args, save_query_info,
570 if (status == MR_SUCCESS)
572 for (i = 11; i > 0; i--)
573 argv[i + 1] = argv[i];
575 argv[FS_TYPE + 1] = "ERR";
576 argv[FS_COMMENTS + 1] = "Locker disabled; call 3-1325 for help";
578 status = wrap_mr_query("update_filesys", 12, argv, NULL, NULL);
581 com_err(whoami, status, "while updating filesystem, "
582 "not deactivating filesystem.");
586 else if (status && status != MR_NO_MATCH)
588 com_err(whoami, status, "while retrieving filesystem information.");
593 /* Display user info */
600 status = wrap_mr_query("get_user_account_by_login", 1, args,
601 save_query_info, argv);
604 com_err(whoami, status, "while getting user information.");
607 if (unformatted_flag)
608 show_user_info_unformatted(argv);
610 show_user_info(argv);
613 /* register a user */
620 status = wrap_mr_query("get_user_account_by_login", 1, args,
621 save_query_info, argv);
624 com_err(whoami, status, "while looking up uid.");
628 args[0] = argv[U_UID];
632 status = wrap_mr_query("register_user", 3, args, NULL, NULL);
635 com_err(whoami, status, "while registering user.");
640 /* list user reservations */
646 status = wrap_mr_query("get_user_reservations", 1, args,
647 show_reservations, NULL);
649 if (status != MR_NO_MATCH) {
650 com_err(whoami, status, "while getting user reservations.");
655 /* add user reservations */
656 if (reservation_add_queue)
658 struct string_list *q = reservation_add_queue;
662 char *reservation = q->string;
666 args[1] = reservation;
667 status = wrap_mr_query("add_user_reservation", 2, args, NULL, NULL);
670 com_err(whoami, status, "while adding user reservation.");
678 /* delete user reservations */
679 if (reservation_remove_queue)
681 struct string_list *q = reservation_remove_queue;
685 char *reservation = q->string;
689 args[1] = reservation;
690 status = wrap_mr_query("delete_user_reservation", 2, args, NULL,
694 com_err(whoami, status, "while deleting user reservation.");
706 int save_query_info(int argc, char **argv, void *hint)
711 for(i = 0; i < argc; i++)
712 nargv[i] = strdup(argv[i]);
717 int show_reservations(int argc, char **argv, void *hint)
719 printf("Reservation: %s\n", argv[0]);
724 struct string_list *add_to_string_list(struct string_list *old_list, char *s) {
725 struct string_list *new_list;
727 new_list = (struct string_list *)malloc(sizeof(struct string_list *));
728 new_list->next = old_list;
729 new_list->string = s;
734 int wrap_mr_query(char *handle, int argc, char **argv,
735 int (*callback)(int, char **, void *), void *callarg) {
737 print_query(handle, argc, argv);
739 return mr_query(handle, argc, argv, callback, callarg);
742 void print_query(char *query_name, int argc, char **argv) {
745 printf("qy %s", query_name);
746 for(cnt = 0; cnt < argc; cnt++)
747 printf(" <%s>", argv[cnt]);
751 void show_user_info(char **argv)
756 sprintf(tbuf, "%s, %s %s", argv[U_LAST], argv[U_FIRST], argv[U_MIDDLE]);
757 printf("Login name: %-20s Full name: %s\n", argv[U_NAME], tbuf);
758 printf("User id: %-23s Login shell: %-10s\n", argv[U_UID], argv[U_SHELL]);
759 printf("Class: %-25s Windows Console Shell: %-10s\n", argv[U_CLASS],
760 argv[U_WINCONSOLESHELL]);
761 sprintf(tbuf, "%s %s", argv[U_SPONSOR_TYPE],
762 strcmp(argv[U_SPONSOR_TYPE], "NONE") ? argv[U_SPONSOR_NAME] : "");
763 printf("Sponsor: %-25s\n", tbuf);
764 printf("Account is: %-20s MIT ID number: %s\n",
765 UserState(atoi(argv[U_STATE])), argv[U_MITID]);
766 printf("Windows Home Directory: %s\n", argv[U_WINHOMEDIR]);
767 printf("Windows Profile Directory: %s\n", argv[U_WINPROFILEDIR]);
768 status = atoi(argv[U_STATE]);
769 if (status == 0 || status == 2)
771 printf("User %s secure Account Coupon to register\n",
772 atoi(argv[U_SECURE]) ? "needs" : "does not need");
774 printf("Comments: %s\n", argv[U_COMMENT]);
775 printf("Created by %s on %s.\n", argv[U_CREATOR], argv[U_CREATED]);
776 printf("Last mod by %s at %s with %s.\n", argv[U_MODBY], argv[U_MODTIME],
780 void show_user_info_unformatted(char **argv)
785 printf("Login name: %s\n", argv[U_NAME]);
786 printf("Full name: %s, %s %s\n", argv[U_LAST], argv[U_FIRST],
788 printf("User id: %s\n", argv[U_UID]);
789 printf("Class: %s\n", argv[U_CLASS]);
790 sprintf(tbuf, "%s %s", argv[U_SPONSOR_TYPE],
791 strcmp(argv[U_SPONSOR_TYPE], "NONE") ? argv[U_SPONSOR_NAME] : "");
792 printf("Sponsor: %s\n", tbuf);
793 printf("Login shell: %s\n", argv[U_SHELL]);
794 printf("Windows Console Shell: %s\n", argv[U_WINCONSOLESHELL]);
795 printf("Account is: %s\n", UserState(atoi(argv[U_STATE])));
796 printf("MIT ID number: %s\n", argv[U_MITID]);
797 printf("Windows Home Directory: %s\n", argv[U_WINHOMEDIR]);
798 printf("Windows Profile Directory: %s\n", argv[U_WINPROFILEDIR]);
799 status = atoi(argv[U_STATE]);
800 if (status == 0 || status == 2)
801 printf("Secure: %s secure Account Coupon to register\n",
802 atoi(argv[U_SECURE]) ? "Needs" : "Does not need");
803 printf("Comments: %s\n", argv[U_COMMENT]);
804 printf("Created by: %s\n", argv[U_CREATOR]);
805 printf("Created on: %s\n", argv[U_CREATED]);
806 printf("Last mod by: %s\n", argv[U_MODBY]);
807 printf("Last mod on: %s\n", argv[U_MODTIME]);
808 printf("Last mod with: %s\n", argv[U_MODWITH]);
811 void usage(char **argv)
813 #define USAGE_OPTIONS_FORMAT " %-39s%s\n"
814 fprintf(stderr, "Usage: %s username [options]\n", argv[0]);
815 fprintf(stderr, "Options are\n");
816 fprintf(stderr, " %-39s\n", "-i | -info");
817 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-C | -create",
819 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-r | -register",
820 "-R | -rename newname");
821 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-U | -uid uid",
822 "-s | -shell shell");
823 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-S | -status status",
824 "-w | -winshell winshell");
825 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-F | -first firstname",
826 "-L | -last lastname");
827 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-M | -middle middlename",
828 "-I | -mitid mitid");
829 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-cl | -class class",
830 "-c | -comment comment");
831 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-6 | -secure 0|1",
832 "-lr | -listreservation");
833 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-ar | -addreservation reservation",
834 "-dr | -deletereservation reservation");
835 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-wh | -winhomedir winhomedir",
836 "-wp | -winprofiledir winprofiledir");
837 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-sp | -sponsor sponsor",
838 "-u | -unformatted");
839 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-n | -noauth",
841 fprintf(stderr, " %-39s\n", "-db | -database host[:port]");
846 /* Parse a line of input, fetching a member. NULL is returned if a member
847 * is not found. ';' is a comment character.
849 struct owner_type *parse_member(char *s)
851 struct owner_type *m;
854 while (*s && isspace(*s))
857 while (*p && *p != '\n' && *p != ';')
859 if (isprint(*p) && !isspace(*p))
866 if (p == s || strlen(s) == 0)
869 if (!(m = malloc(sizeof(struct owner_type))))
872 if ((p = strchr(s, ':')))
876 if (!strcasecmp("user", s))
878 else if (!strcasecmp("list", s))
880 else if (!strcasecmp("kerberos", s))
881 m->type = M_KERBEROS;
882 else if (!strcasecmp("none", s))
890 m->name = strdup(m->name);
895 m->type = strcasecmp(s, "none") ? M_ANY : M_NONE;