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