]> andersk Git - moira.git/blob - clients/stanley/stanley.c
7cb568117aa031a301d002b89088c8e7fa86a8ea
[moira.git] / clients / stanley / stanley.c
1 /*
2  * Command line oriented Moira users tool.
3  *
4  * zacheiss@mit.edu, September 2001
5  *
6  * Inspired by blanche
7  *
8  * Copyright (C) 2000, 2001 by the Massachusetts Institute of Technology.
9  * For copying and distribution information, please see the file
10  * <mit-copyright.h>.
11  */
12
13 #include <mit-copyright.h>
14 #include <moira.h>
15 #include <moira_site.h>
16 #include <mrclient.h>
17
18 #include <ctype.h>
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 RCSID("$Header$");
25
26 struct string_list {
27   char *string;
28   struct string_list *next;
29 };
30
31 /* argument parsing macro */
32 #define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
33
34 /* flags from command line */
35 int info_flag, update_flag, create_flag, deact_flag, reg_flag;
36 int list_res_flag, update_res_flag, unformatted_flag, verbose, noauth;
37
38 struct string_list *reservation_add_queue, *reservation_remove_queue;
39
40 char *username, *whoami;
41
42 char *newlogin, *uid, *shell, *winshell, *last, *first, *middle, *u_status;
43 char *clearid, *class, *comment, *secure;
44
45 static char *states[] = {
46   "Registerable (0)",
47   "Active (1)",
48   "Half Registered (2)",
49   "Deleted (3)",
50   "Not registerable (4)",
51   "Enrolled/Registerable (5)",
52   "Enrolled/Not Registerable (6)",
53   "Half Enrolled (7)",
54   "Registerable, Kerberos only (8)",
55   "Active, Kerberos only (9)"
56 };
57
58 static char *UserState(int state)
59 {
60   static char buf[BUFSIZ];
61
62   if (state < 0 || state >= US_END)
63     {
64       sprintf(buf, "Unknown (%d)", state);
65       return buf;
66     }
67   return states[state];
68 }
69
70 void usage(char **argv);
71 int save_query_info(int argc, char **argv, void *hint);
72 int show_reservations(int argc, char **argv, void *hint);
73 void show_user_info(char **argv);
74 void show_user_info_unformatted(char **argv);
75 struct string_list *add_to_string_list(struct string_list *old_list, char *s);
76 int wrap_mr_query(char *handle, int argc, char **argv,
77                   int (*callback)(int, char **, void *), void *callarg);
78 void print_query(char *query_name, int argc, char **argv);
79
80 int main(int argc, char **argv)
81 {
82   int status;
83   char **arg = argv;
84   char *server = NULL;
85
86   /* clear all flags & lists */
87   info_flag = update_flag = create_flag = deact_flag = reg_flag = 0;
88   list_res_flag = update_res_flag = unformatted_flag = verbose = noauth = 0;
89   newlogin = uid = shell = winshell = last = first = middle = NULL;
90   u_status = clearid = class = comment = secure = NULL;
91   reservation_add_queue = reservation_remove_queue = NULL;
92   whoami = argv[0];
93
94   /* parse args */
95   while (++arg - argv < argc)
96     {
97       if (**arg == '-')
98         {
99           if (argis("i", "info"))
100             info_flag++;
101           else if (argis("C", "create"))
102             create_flag++;
103           else if (argis("D", "deact"))
104             deact_flag++;
105           else if (argis("r", "register"))
106             reg_flag++;
107           else if (argis("R", "rename")) {
108             if (arg - argv < argc - 1) {
109               arg++;
110               update_flag++;
111               newlogin = *arg;
112             } else
113               usage(argv);
114           }
115           else if (argis("U", "uid")) {
116             if (arg - argv < argc - 1) {
117               arg++;
118               update_flag++;
119               uid = *arg;
120             } else
121               usage(argv);
122           }
123           else if (argis("s", "shell")) {
124             if (arg - argv < argc - 1) {
125               arg++;
126               update_flag++;
127               shell = *arg;
128             } else
129               usage(argv);
130           }
131           else if (argis("w", "winshell")) {
132             if (arg - argv < argc - 1) {
133               arg++;
134               update_flag++;
135               winshell = *arg;
136             } else
137               usage(argv);
138           }
139           else if (argis("L", "last")) {
140             if (arg - argv < argc - 1) {
141               arg++;
142               update_flag++;
143               last = *arg;
144             } else
145               usage(argv);
146           }
147           else if (argis("F", "first")) {
148             if (arg - argv < argc - 1) {
149               arg++;
150               update_flag++;
151               first = *arg;
152             } else
153               usage(argv);
154           }
155           else if (argis("M", "middle")) {
156             if (arg - argv < argc - 1) {
157               arg++;
158               update_flag++;
159               middle = *arg;
160             } else
161               usage(argv);
162           }
163           else if (argis("S", "status")) {
164             if (arg - argv < argc - 1) { 
165               int i;
166               int len;
167
168               arg++;
169               update_flag++;
170               u_status = *arg;
171               len = strlen(u_status);
172               for (i = 0; i < len; i++) {
173                 if (!isdigit(u_status[i])) {
174                   printf("Error:  status code %s is not numeric.\n", u_status);
175                   exit(1);
176                 }
177               }
178             } else
179               usage(argv);
180           }
181           else if (argis("I", "mitid")) {
182             if (arg - argv < argc - 1) {
183               arg++;
184               update_flag++;
185               clearid = *arg;
186             } else
187               usage(argv);
188           }
189           else if (argis("cl", "class")) {
190             if (arg - argv < argc - 1) {
191               arg++;
192               update_flag++;
193               class = *arg;
194             } else
195               usage(argv);
196           }
197           else if (argis("c", "comment")) {
198             if (arg - argv < argc - 1) {
199               arg++;
200               update_flag++;
201               comment = *arg;
202             } else
203               usage(argv);
204           }
205           else if (argis("6", "secure")) {
206             if (arg - argv < argc - 1) {
207               arg++;
208               update_flag++;
209               secure = *arg;
210             } else
211               usage(argv);
212           }
213           else if (argis("ar", "addreservation")) {
214             if (arg - argv < argc - 1) {
215               arg++;
216               reservation_add_queue = add_to_string_list(reservation_add_queue,
217                                                          *arg);
218             } else
219               usage(argv);
220             update_res_flag++;
221           }
222           else if (argis("dr", "deletereservation")) {
223             if (arg - argv < argc - 1) {
224               arg++;
225               reservation_remove_queue = add_to_string_list(reservation_remove_queue, *arg);
226             } else
227               usage(argv);
228             update_res_flag++;
229           }
230           else if (argis("lr", "listreservation"))
231             list_res_flag++;
232           else if (argis("u", "unformatted"))
233             unformatted_flag++;
234           else if (argis("n", "noauth"))
235             noauth++;
236           else if (argis("v", "verbose"))
237             verbose++;
238           else if (argis("db", "database"))
239             {
240               if (arg - argv < argc - 1)
241                 {
242                   ++arg;
243                   server = *arg;
244                 }
245               else
246                 usage(argv);
247             }
248           else
249             usage(argv);
250         }
251       else if (username == NULL)
252         username = *arg;
253       else
254         usage(argv);
255     }
256   if (username == NULL && !create_flag)
257     usage(argv);
258
259   /* default to info_flag if nothing else was specified */
260   if(!(info_flag       || update_flag || create_flag   || \
261        deact_flag      || reg_flag    || list_res_flag || \
262        update_res_flag)) {
263     info_flag++;
264   }
265
266   /* fire up Moira */
267   status = mrcl_connect(server, "stanley", 8, !noauth);
268   if (status == MRCL_AUTH_ERROR)
269     {
270       com_err(whoami, 0, "Try the -noauth flag if you don't "
271               "need authentication.");
272     }
273   if (status)
274     exit(2);
275
276   /* create if needed */
277   if (create_flag)
278     {
279       char *argv[20];
280       int cnt;
281
282       for (cnt = 0; cnt < 14; cnt++) {
283         argv[cnt] = "";
284       }
285
286       if (username)
287         argv[U_NAME] = username;
288       else
289         argv[U_NAME] = UNIQUE_LOGIN;
290       if (uid)
291         argv[U_UID] = uid;
292       else
293         argv[U_UID] = UNIQUE_UID;
294       if (shell)
295         argv[U_SHELL] = shell;
296       else
297         argv[U_SHELL] = "/bin/athena/tcsh";
298       if (winshell)
299         argv[U_WINCONSOLESHELL] = winshell;
300       else
301         argv[U_WINCONSOLESHELL] = "cmd";
302       if (last)
303         argv[U_LAST] = last;
304       if (first)
305         argv[U_FIRST] = first;
306       if (middle)
307         argv[U_MIDDLE] = middle;
308       if (u_status)
309         argv[U_STATE] = u_status;
310       else
311         argv[U_STATE] = "0";
312       if (clearid)
313         argv[U_MITID] = clearid;
314       if (class)
315         argv[U_CLASS] = class;
316       if (comment)
317         argv[U_COMMENT] = comment;
318       /* Signature field always is the empty string */
319       argv[U_SIGNATURE] = "";
320       if (secure)
321         argv[U_SECURE] = secure;
322       else
323         argv[U_SECURE] = "0";
324
325       status = wrap_mr_query("add_user_account", 13, argv, NULL, NULL);
326       if (status)
327         {
328           com_err(whoami, status, "while adding user account.");
329           exit(1);
330         }
331     }
332   else if (update_flag)
333     {
334       char *old_argv[20];
335       char *argv[20];
336       char *args[5];
337
338       args[0] = username;
339       
340       status = wrap_mr_query("get_user_account_by_login", 1, args, 
341                              save_query_info, old_argv);
342       if (status)
343         {
344           com_err(whoami, status, "while getting user information.");
345           exit(1);
346         }
347
348       argv[1] = old_argv[0];
349       argv[2] = old_argv[1];
350       argv[3] = old_argv[2];
351       argv[4] = old_argv[3];
352       argv[5] = old_argv[4];
353       argv[6] = old_argv[5];
354       argv[7] = old_argv[6];
355       argv[8] = old_argv[7];
356       argv[9] = old_argv[8];
357       argv[10] = old_argv[9];
358       argv[11] = old_argv[10];
359       argv[12] = old_argv[11];
360       argv[13] = old_argv[12];
361       
362       argv[0] = username;
363       if (newlogin)
364         argv[1] = newlogin;
365       if (uid)
366         argv[2] = uid;
367       if (shell)
368         argv[3] = shell;
369       if (winshell)
370         argv[4] = winshell;
371       if (last)
372         argv[5] = last;
373       if (first)
374         argv[6] = first;
375       if (middle)
376         argv[7] = middle;
377       if (u_status)
378         argv[8] = u_status;
379       if (clearid)
380         argv[9] = clearid;
381       if (class)
382         argv[10] = class;
383       if (comment)
384         argv[11] = comment;
385       if (secure)
386         argv[13] = secure;
387
388       status = wrap_mr_query("update_user_account", 14, argv, NULL, NULL);
389
390       if (status)
391         com_err(whoami, status, "while updating user.");
392       else if (newlogin)
393         username = newlogin;
394     }
395
396   /* Deactivate a user, and the matching list and filesystem if they exist */
397   if (deact_flag)
398     {
399       char *args[2];
400       char *argv[20];
401       int i;
402
403       args[0] = username;
404       args[1] = "3";
405
406       status = wrap_mr_query("update_user_status", 2, args, NULL, NULL);
407       if (status)
408         {
409           com_err(whoami, status, "while deactivating user.");
410           exit(1);
411         }
412
413       status = wrap_mr_query("get_list_info", 1, args, save_query_info, argv);
414       if (status == MR_SUCCESS)
415         {
416           for (i = 13; i > 0; i--)
417             argv[i + 1] = argv[i];
418           argv[1] = username;
419           argv[L_ACTIVE + 1] = "0";
420           
421           status = wrap_mr_query("update_list", 14, argv, NULL, NULL);
422           if (status)
423             {
424               com_err(whoami, status, "while updating list, "
425                       "not deactivating list or filesystem.");
426               exit(1);
427             }
428         }
429       else if (status && status != MR_NO_MATCH)
430         {
431           com_err(whoami, status, "while retrieving list information.");
432           exit(1);
433         }
434
435       status = wrap_mr_query("get_filesys_by_label", 1, args, save_query_info,
436                              argv);
437       if (status == MR_SUCCESS)
438         {
439           for (i = 11; i > 0; i--)
440             argv[i + 1] = argv[i];
441           argv[1] = username;
442           argv[FS_TYPE + 1] = "ERR";
443           argv[FS_COMMENTS + 1] = "Locker disabled; call 3-1325 for help";
444           
445           status = wrap_mr_query("update_filesys", 12, argv, NULL, NULL);
446           if (status)
447             {
448               com_err(whoami, status, "while updating filesystem, "
449                       "not deactivating filesystem.");
450               exit(1);
451             }
452         }
453       else if (status && status != MR_NO_MATCH)
454         {
455           com_err(whoami, status, "while retrieving filesystem information.");
456           exit(1);
457         }
458     }
459
460   /* Display user info */
461   if (info_flag)
462     {
463       char *args[2];
464       char *argv[20];
465
466       args[0] = username;
467       status = wrap_mr_query("get_user_account_by_login", 1, args,
468                              save_query_info, argv);
469       if (status)
470         {
471           com_err(whoami, status, "while getting user information.");
472           exit(1);
473         }
474       if (unformatted_flag)
475         show_user_info_unformatted(argv);
476       else
477         show_user_info(argv);
478     }
479
480   /* register a user */
481   if (reg_flag)
482     {
483       char *args[3];
484       char *argv[20];
485
486       args[0] = username;
487       status = wrap_mr_query("get_user_account_by_login", 1, args,
488                              save_query_info, argv);
489       if (status)
490         {
491           com_err(whoami, status, "while looking up uid.");
492           exit(1);
493         }
494
495       args[0] = argv[U_UID];
496       args[1] = username;
497       args[2] = "IMAP";
498
499       status = wrap_mr_query("register_user", 3, args, NULL, NULL);
500       if (status)
501         {
502           com_err(whoami, status, "while registering user.");
503           exit(1);
504         }
505     }
506
507   /* list user reservations */
508   if (list_res_flag)
509     {
510       char *args[1];
511
512       args[0] = username;
513       status = wrap_mr_query("get_user_reservations", 1, args, 
514                              show_reservations, NULL);
515       if (status)
516         if (status != MR_NO_MATCH) {
517           com_err(whoami, status, "while getting user reservations.");
518           exit(1);
519         }
520     }
521
522   /* add user reservations */
523   if (reservation_add_queue)
524     {
525       struct string_list *q = reservation_add_queue;
526
527       while (q) 
528         {
529           char *reservation = q->string;
530           char *args[2];
531
532           args[0] = username;
533           args[1] = reservation;
534           status = wrap_mr_query("add_user_reservation", 2, args, NULL, NULL);
535           if (status)
536             {
537               com_err(whoami, status, "while adding user reservation.");
538               exit(1);
539             }
540
541           q = q->next;
542         }
543     }
544
545   /* delete user reservations */
546   if (reservation_remove_queue)
547     {
548       struct string_list *q = reservation_remove_queue;
549
550       while (q)
551         {
552           char *reservation = q->string;
553           char *args[2];
554
555           args[0] = username;
556           args[1] = reservation;
557           status = wrap_mr_query("delete_user_reservation", 2, args, NULL, 
558                                  NULL);
559           if (status)
560             {
561               com_err(whoami, status, "while deleting user reservation.");
562               exit(1);
563             }
564           
565           q = q->next;
566         }
567     }
568   /* We're done! */
569   mr_disconnect();
570   exit(0);
571 }
572
573 int save_query_info(int argc, char **argv, void *hint)
574 {
575   int i;
576   char **nargv = hint;
577
578   for(i = 0; i < argc; i++)
579     nargv[i] = strdup(argv[i]);
580   
581   return MR_CONT;
582 }
583
584 int show_reservations(int argc, char **argv, void *hint)
585 {
586   printf("Reservation: %s\n", argv[0]);
587
588   return MR_CONT;
589 }
590
591 struct string_list *add_to_string_list(struct string_list *old_list, char *s) {
592   struct string_list *new_list;
593
594   new_list = (struct string_list *)malloc(sizeof(struct string_list *));
595   new_list->next = old_list;
596   new_list->string = s;
597
598   return new_list;
599 }
600
601 int wrap_mr_query(char *handle, int argc, char **argv,
602                   int (*callback)(int, char **, void *), void *callarg) {
603   if (verbose)
604     print_query(handle, argc, argv);
605
606   return mr_query(handle, argc, argv, callback, callarg);
607 }
608
609 void print_query(char *query_name, int argc, char **argv) {
610   int cnt;
611
612   printf("qy %s", query_name);
613   for(cnt = 0; cnt < argc; cnt++)
614     printf(" <%s>", argv[cnt]);
615   printf("\n");
616 }
617
618 void show_user_info(char **argv)
619 {
620   char tbuf[BUFSIZ];
621   int status;
622
623   sprintf(tbuf, "%s, %s %s", argv[U_LAST], argv[U_FIRST], argv[U_MIDDLE]);
624   printf("Login name: %-20s Full name: %s\n", argv[U_NAME], tbuf);
625   printf("User id: %-23s Login shell: %-10s\n", argv[U_UID], argv[U_SHELL]);
626   printf("Class: %-25s Windows Console Shell: %-10s\n", argv[U_CLASS],
627          argv[U_WINCONSOLESHELL]);
628   printf("Account is: %-20s MIT ID number: %s\n",
629          UserState(atoi(argv[U_STATE])), argv[U_MITID]);
630   status = atoi(argv[U_STATE]);
631   if (status == 0 || status == 2)
632     {
633       printf("User %s secure Account Coupon to register\n",
634               atoi(argv[U_SECURE]) ? "needs" : "does not need");
635     }
636   printf("Comments: %s\n", argv[U_COMMENT]);
637   printf("Created  by %s on %s.\n", argv[U_CREATOR], argv[U_CREATED]);
638   printf("Last mod by %s at %s with %s.\n", argv[U_MODBY], argv[U_MODTIME],
639          argv[U_MODWITH]);
640 }
641
642 void show_user_info_unformatted(char **argv)
643 {
644   int status;
645
646   printf("Login name:            %s\n", argv[U_NAME]);
647   printf("Full name:             %s, %s %s\n", argv[U_LAST], argv[U_FIRST], 
648          argv[U_MIDDLE]);
649   printf("User id:               %s\n", argv[U_UID]);
650   printf("Class:                 %s\n", argv[U_CLASS]);
651   printf("Login shell:           %s\n", argv[U_SHELL]);
652   printf("Windows Console Shell: %s\n", argv[U_WINCONSOLESHELL]);
653   printf("Account is:            %s\n", UserState(atoi(argv[U_STATE])));
654   printf("MIT ID number:         %s\n", argv[U_MITID]);
655   status = atoi(argv[U_STATE]);
656   if (status == 0 || status == 2)
657     printf("Secure:                %s secure Account Coupon to register\n",
658            atoi(argv[U_SECURE]) ? "Needs" : "Does not need");
659   printf("Comments:              %s\n", argv[U_COMMENT]);
660   printf("Created by:            %s\n", argv[U_CREATOR]);
661   printf("Created on:            %s\n", argv[U_CREATED]);
662   printf("Last mod by:           %s\n", argv[U_MODBY]);
663   printf("Last mod on:           %s\n", argv[U_MODTIME]);
664   printf("Last mod with:         %s\n", argv[U_MODWITH]);
665 }
666
667 void usage(char **argv)
668 {
669 #define USAGE_OPTIONS_FORMAT "  %-39s%s\n"
670   fprintf(stderr, "Usage: %s username [options]\n", argv[0]);
671   fprintf(stderr, "Options are\n");
672   fprintf(stderr, "  %-39s\n", "-i   | -info");
673   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-C   | -create",
674           "-D   | -deact");
675   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-r   | -register",
676           "-R   | -rename newname");
677   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-U   | -uid uid",
678           "-s   | -shell shell");
679   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-S   | -status status",
680           "-w   | -winshell winshell");
681   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-F   | -first firstname",
682           "-L   | -last lastname");
683   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-M   | -middle middlename",
684           "-I   | -mitid mitid");
685   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-cl  | -class class",
686           "-c   | -comment comment");
687   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-6   | -secure 0|1",
688           "-lr  | -listreservation");
689   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-ar  | -addreservation reservation",
690           "-dr  | -deletereservation reservation");
691   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-u   | -unformatted",
692           "-n   | -noauth");
693   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-v   | -verbose",
694           "-db  | -database host[:port]");
695
696   exit(1);
697 }
This page took 0.079175 seconds and 3 git commands to generate.