]> andersk Git - moira.git/blob - clients/moira/user.c
fix RCS IDs
[moira.git] / clients / moira / user.c
1 /* $Id$
2  *
3  *      This is the file user.c for the Moira Client, which allows users
4  *      to quickly and easily maintain most parts of the Moira database.
5  *      It Contains: Functions for manipulating user information.
6  *
7  *      Created:        5/9/88
8  *      By:             Chris D. Peterson
9  *
10  * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
11  * For copying and distribution information, please see the file
12  * <mit-copyright.h>.
13  */
14
15 #include <mit-copyright.h>
16 #include <moira.h>
17 #include <moira_site.h>
18 #include "defs.h"
19 #include "f_defs.h"
20 #include "globals.h"
21
22 #include <sys/time.h>
23
24 #include <ctype.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #ifdef GDSS
30 #include <gdss.h>
31 #endif
32
33 RCSID("$Header$");
34
35 void CorrectCapitalization(char **name);
36 char **AskUserInfo(char **info, Bool name);
37 struct mqelem *GetUserInfo(int type, char *name1, char *name2);
38
39 #define LOGIN 0
40 #define UID   1
41 #define BY_NAME  2
42 #define CLASS 3
43 #define ID 4
44
45 #ifdef ATHENA
46 #define DEFAULT_SHELL "/bin/athena/tcsh"
47 #else
48 #define DEFAULT_SHELL "/bin/csh"
49 #endif
50 #define DEFAULT_CLASS "?"
51
52
53 /*      Function Name: UserState
54  *      Description: Convert a numeric state into a descriptive string.
55  *      Arguments: state value
56  *      Returns: pointer to statically allocated string.
57  */
58
59 static char *states[] = {
60   "Registerable (0)",
61   "Active (1)",
62   "Half Registered (2)",
63   "Deleted (3)",
64   "Not registerable (4)",
65   "Enrolled/Registerable (5)",
66   "Enrolled/Not Registerable (6)",
67   "Half Enrolled (7)"
68 };
69
70 static char *UserState(int state)
71 {
72   static char buf[BUFSIZ];
73
74   if (state < 0 || state >= US_END)
75     {
76       sprintf(buf, "Unknown (%d)", state);
77       return buf;
78     }
79   return states[state];
80 }
81
82
83 /*      Function Name: PrintUserName
84  *      Description: Print name of a user.
85  *      Arguments: info - the information about a user.
86  *      Returns: none.
87  */
88
89 static void PrintUserName(char **info)
90 {
91   char buf[BUFSIZ], print_buf[BUFSIZ];
92   sprintf(buf, "%s, %s %s", info[U_LAST], info[U_FIRST], info[U_MIDDLE]);
93   sprintf(print_buf, "%-40s User Name: %s", buf, info[U_NAME]);
94   Put_message(print_buf);
95 }
96
97 /*      Function Name: PrintUserInfo
98  *      Description: Prints Information about a user.
99  *      Arguments: info - an argument list with the user information
100  *                          in it.
101  *      Returns: none
102  */
103
104 static void PrintUserInfo(char **info)
105 {
106   char name[BUFSIZ], buf[BUFSIZ];
107   int status;
108 #ifdef GDSS
109   SigInfo si;
110 #endif
111
112   sprintf(name, "%s, %s %s", info[U_LAST], info[U_FIRST], info[U_MIDDLE]);
113   sprintf(buf, "Login name: %-20s Full name: %s", info[U_NAME], name);
114   Put_message(buf);
115   sprintf(buf, "User id: %-23s Login shell %-10s Class: %s",
116           info[U_UID], info[U_SHELL], info[U_CLASS]);
117   Put_message(buf);
118
119 #ifdef GDSS
120   sprintf(buf, "%s:%s", info[U_NAME], info[U_MITID]);
121   si.rawsig = NULL;
122   status = GDSS_Verify(buf, strlen(buf), info[U_SIGNATURE], &si);
123 #else /* GDSS */
124   status = 0;
125 #endif /* GDSS */
126
127   sprintf(buf, "Account is: %-20s MIT ID number: %s Signed: %s",
128           UserState(atoi(info[U_STATE])), info[U_MITID],
129           *info[U_SIGNATURE] ? (status ? "Bad" : "Yes") : "No");
130   Put_message(buf);
131   if (atoi(info[U_SECURE]))
132     sprintf(buf, "Secure password set on %s.", atot(info[U_SECURE]));
133   else
134     sprintf(buf, "No secure password set.");
135   Put_message(buf);
136   sprintf(buf, "Comments: %s", info[U_COMMENT]);
137   Put_message(buf);
138   sprintf(buf, MOD_FORMAT, info[U_MODBY], info[U_MODTIME], info[U_MODWITH]);
139   Put_message(buf);
140 }
141
142 /*      Function Name: SetUserDefaults
143  *      Description: Sets the default values for add user.
144  *      Arguments: info - a blank user info array of char *'s.
145  *      Returns: args - the filled info structure.
146  */
147
148 static char **SetUserDefaults(char **info)
149 {
150   info[U_NAME] = strdup(UNIQUE_LOGIN);
151   info[U_UID] = strdup(UNIQUE_UID);
152   info[U_SHELL] = strdup(DEFAULT_SHELL);
153   info[U_LAST] = strdup(DEFAULT_NONE);
154   info[U_FIRST] = strdup(DEFAULT_NONE);
155   info[U_MIDDLE] = strdup(DEFAULT_NONE);
156   info[U_STATE] = strdup(DEFAULT_NO);
157   info[U_MITID] = strdup(DEFAULT_NONE);
158   info[U_CLASS] = strdup(DEFAULT_CLASS);
159   info[U_COMMENT] = strdup("");
160   info[U_SIGNATURE] = strdup("");
161   info[U_SECURE] = strdup("0");
162   info[U_MODTIME] = info[U_MODBY] = info[U_MODWITH] = info[U_END] = NULL;
163   return info;
164 }
165
166
167 /* Check that the supplied name follows the capitalization rules, and
168  * offer to correct it if not.
169  */
170
171 void CorrectCapitalization(char **name)
172 {
173   char temp_buf[BUFSIZ], fixname[BUFSIZ];
174
175   strcpy(fixname, *name);
176   FixCase(fixname);
177   if (strcmp(fixname, *name))
178     {
179       Put_message("You entered a name which does not follow the capitalization conventions.");
180       sprintf(temp_buf, "Correct it to \"%s\"", fixname);
181       if (YesNoQuestion(temp_buf, 1) == TRUE)
182         {
183           free(*name);
184           *name = strdup(fixname);
185         }
186     }
187 }
188
189
190 /*      Function Name: AskUserInfo.
191  *      Description: This function askes the user for information about a
192  *                   machine and saves it into a structure.
193  *      Arguments: info - a pointer the the structure to put the info into.
194  *                 flags - Flags asking us which info we want.
195  *      Returns: the args to pass to the query.
196  *      NOTES: the return args are not necessarily in the correct order to
197  *             use the #defined names (e.g args[UID] is not the uid anymore).
198  */
199
200 char **AskUserInfo(char **info, Bool name)
201 {
202   int i;
203 #ifdef GDSS
204   SigInfo si;
205 #endif
206   char temp_buf[BUFSIZ], *newname;
207
208   if (name)
209     {
210       sprintf(temp_buf, "\nChanging Attributes of user %s.\n", info[U_NAME]);
211       Put_message(temp_buf);
212     }
213   else
214     {
215       struct mqelem *elem = NULL;
216       char *argv[3];
217
218       if (GetValueFromUser("User's last name", &info[U_LAST]) == SUB_ERROR)
219         return NULL;
220       CorrectCapitalization(&info[U_LAST]);
221       if (GetValueFromUser("User's first name", &info[U_FIRST]) == SUB_ERROR)
222         return NULL;
223       CorrectCapitalization(&info[U_FIRST]);
224       if (GetValueFromUser("User's middle name", &info[U_MIDDLE]) == SUB_ERROR)
225         return NULL;
226       CorrectCapitalization(&info[U_MIDDLE]);
227       argv[0] = info[U_FIRST];
228       argv[1] = info[U_LAST];
229       if (do_mr_query("get_user_account_by_name", 2, argv,
230                       StoreInfo, &elem) == MR_SUCCESS)
231         {
232           Put_message("A user by that name already exists in the database.");
233           Loop(QueueTop(elem), PrintUserInfo);
234           Loop(QueueTop(elem), FreeInfo);
235           FreeQueue(elem);
236           if (YesNoQuestion("Add new user anyway", TRUE) != TRUE)
237             return NULL;
238         }
239     }
240   if (name)
241     {
242       newname = strdup(info[U_NAME]);
243       if (GetValueFromUser("The new login name for this user", &newname) ==
244           SUB_ERROR)
245         return NULL;
246     }
247   else if (GetValueFromUser("Login name for this user", &info[U_NAME]) ==
248            SUB_ERROR)
249     return NULL;
250
251   if (GetValueFromUser("User's UID", &info[U_UID]) == SUB_ERROR)
252     return NULL;
253   if (GetValueFromUser("User's shell", &info[U_SHELL]) == SUB_ERROR)
254     return NULL;
255   if (name)
256     {
257       if (GetValueFromUser("User's last name", &info[U_LAST]) == SUB_ERROR)
258         return NULL;
259       CorrectCapitalization(&info[U_LAST]);
260       if (GetValueFromUser("User's first name", &info[U_FIRST]) == SUB_ERROR)
261         return NULL;
262       CorrectCapitalization(&info[U_FIRST]);
263       if (GetValueFromUser("User's middle name", &info[U_MIDDLE]) == SUB_ERROR)
264         return NULL;
265       CorrectCapitalization(&info[U_MIDDLE]);
266     }
267   while (1)
268     {
269       int i;
270       if (GetValueFromUser("User's status (? for help)", &info[U_STATE]) ==
271           SUB_ERROR)
272         return NULL;
273       if (isdigit(info[U_STATE][0]))
274         break;
275       Put_message("Valid status numbers:");
276       for (i = 0; i < US_END; i++)
277         {
278           sprintf(temp_buf, "  %d: %s", i, states[i]);
279           Put_message(temp_buf);
280         }
281     }
282   if (GetValueFromUser("User's MIT ID number", &info[U_MITID]) == SUB_ERROR)
283     return NULL;
284   RemoveHyphens(info[U_MITID]);
285   if (GetTypeFromUser("User's MIT Year (class)", "class", &info[U_CLASS]) ==
286       SUB_ERROR)
287     return NULL;
288   if (GetValueFromUser("Comments", &info[U_COMMENT]) == SUB_ERROR)
289     return NULL;
290
291   if (YesNoQuestion("Secure password set",
292                     atoi(info[U_SECURE]) ? TRUE : FALSE) == FALSE)
293     {
294       free(info[U_SECURE]);
295       info[U_SECURE] = strdup("0");
296     }
297   else if (!strcmp(info[U_SECURE], "0"))
298     {
299       char buf[16];
300       struct timeval tv;
301
302       gettimeofday(&tv, NULL);
303       sprintf(buf, "%ld", (long) tv.tv_sec);
304       free(info[U_SECURE]);
305       info[U_SECURE] = strdup(buf);
306     }
307
308   /* Sign record */
309 #ifdef GDSS
310   if (strcmp(info[U_NAME], UNIQUE_LOGIN))
311     {
312       if (name)
313         sprintf(temp_buf, "%s:%s", newname, info[U_MITID]);
314       else
315         sprintf(temp_buf, "%s:%s", info[U_NAME], info[U_MITID]);
316       si.rawsig = NULL;
317       i = GDSS_Verify(temp_buf, strlen(temp_buf), info[U_SIGNATURE], &si);
318       /* If it's already signed OK, don't resign it. */
319       if (i != GDSS_SUCCESS)
320         {
321           free(info[U_SIGNATURE]);
322           info[U_SIGNATURE] = malloc(GDSS_Sig_Size() * 2);
323         sign_again:
324           i = GDSS_Sign(temp_buf, strlen(temp_buf), info[U_SIGNATURE]);
325           if (i != GDSS_SUCCESS)
326             com_err(program_name, gdss2et(i), "Failed to create signature");
327           else
328             {
329               unsigned char buf[256];
330               si.rawsig = buf;
331               i = GDSS_Verify(temp_buf, strlen(temp_buf),
332                               info[U_SIGNATURE], &si);
333               if (strlen(buf) > 68)
334                 goto sign_again;
335             }
336         }
337     }
338 #else /* GDSS */
339   info[U_SIGNATURE] = strdup("");
340 #endif /* GDSS */
341
342   FreeAndClear(&info[U_MODTIME], TRUE);
343   FreeAndClear(&info[U_MODBY], TRUE);
344   FreeAndClear(&info[U_MODWITH], TRUE);
345
346   /*
347    * Slide the newname into the #2 slot, this screws up all future references
348    * to this list, since we slip the pointer into a info list it gets freed
349    * when the rest of the list gets freed.
350    */
351   if (name)
352     SlipInNewName(info, newname);
353
354   return info;
355 }
356
357 /*      Function Name: GetUserInfo
358  *      Description: Stores the user information in a queue.
359  *      Arguments: type - type of field given to get info, one of:
360  *                        LOGIN, UID, BY_NAME, CLASS.
361  *                 name1 - name of thing specified by type (wildcards okay)
362  *                 name2 - other name, only used in get user by first and last.
363  *                         (wildcards okay).
364  *      Returns: the first element of the queue containing the user info.
365  *
366  */
367
368 struct mqelem *GetUserInfo(int type, char *name1, char *name2)
369 {
370   char *args[2];
371   int status;
372   struct mqelem *elem = NULL;
373
374   switch (type)
375     {
376     case LOGIN:
377       args[0] = name1;
378       if ((status = do_mr_query("get_user_account_by_login", 1, args,
379                                 StoreInfo, &elem)))
380         {
381           com_err(program_name, status,
382                   " when attempting to get_user_account_by_login.");
383           return NULL;
384         }
385       break;
386     case UID:
387       args[0] = name1;
388       if ((status = do_mr_query("get_user_account_by_uid", 1, args,
389                                 StoreInfo, &elem)))
390         {
391           com_err(program_name, status,
392                   " when attempting to get_user_account_by_uid.");
393           return NULL;
394         }
395       break;
396     case BY_NAME:
397       args[0] = name1;
398       args[1] = name2;
399       if ((status = do_mr_query("get_user_account_by_name", 2, args,
400                                 StoreInfo, &elem)))
401         {
402           com_err(program_name, status,
403                   " when attempting to get_user_account_by_name.");
404           return NULL;
405         }
406       break;
407     case CLASS:
408       args[0] = name1;
409       if ((status = do_mr_query("get_user_account_by_class", 1, args,
410                                 StoreInfo, &elem)))
411         {
412           com_err(program_name, status,
413                   " when attempting to get_user_account_by_class.");
414           return NULL;
415         }
416       break;
417     case ID:
418       args[0] = name1;
419       if ((status = do_mr_query("get_user_account_by_id", 1, args,
420                                 StoreInfo, &elem)))
421         {
422           com_err(program_name, status,
423                   " when attempting to get_user_account_by_id.");
424           return NULL;
425         }
426       break;
427     }
428   return QueueTop(elem) ;
429 }
430
431 /*      Function Name: AddNewUser
432  *      Description: Adds a new user to the database.
433  *      Arguments: none.
434  *      Returns: DM_NORMAL.
435  */
436
437 int AddNewUser(int argc, char **argv)
438 {
439   int status;
440   char **args, *info[MAX_ARGS_SIZE];
441
442   if (!(args = AskUserInfo(SetUserDefaults(info), FALSE)))
443     {
444       Put_message("Aborted.");
445       return DM_NORMAL;
446     }
447   if ((status = do_mr_query("add_user_account", CountArgs(args),
448                             args, NULL, NULL)))
449     com_err(program_name, status, " in add_user_account");
450   else
451     Put_message("New user added to database.");
452   FreeInfo(args);
453   return DM_NORMAL;
454 }
455
456
457 /*      Function Name: GetLoginName
458  *      Description: Asks the user for a login name and reserves
459  *                   it with kerberous.
460  *      Arguments: none.
461  *      Returns: a malloced login name for the user.
462  */
463
464 static char *GetLoginName(void)
465 {
466   char *name;
467
468   name = strdup("");
469   if (GetValueFromUser("Login name for this user? ", &name) == SUB_ERROR)
470     return NULL;
471   Put_message("KERBEROS code not added, did not reserve name with kerberos.");
472   return name;
473 }
474
475
476 /*      Function Name: ChooseUser
477  *      Description: Choose a user from a list and return the uid.
478  *      Arguments: top - a queue of user information.
479  *      Returns: uid - the malloced uid of the user that was chosen.
480  */
481
482 static char *ChooseUser(struct mqelem *elem)
483 {
484   while (elem)
485     {
486       char **info = elem->q_data;
487       PrintUserInfo(info);
488       switch (YesNoQuitQuestion("Is this the user you want (y/n/q)", FALSE))
489         {
490         case TRUE:
491           return strdup(info[U_UID]);
492         case FALSE:
493           break;
494         default:                /* quit or ^C. */
495           return NULL;
496         }
497       elem = elem->q_forw;
498     }
499   return NULL;
500 }
501
502 /*      Function Name: GetUidNumberFromName
503  *      Description: Gets the users uid number, from the name.
504  *      Arguments: none.
505  *      Returns: uid - a malloced string containing the uid.
506  */
507
508 static char *GetUidNumberFromName(void)
509 {
510   char *args[5], *uid, first[BUFSIZ], last[BUFSIZ];
511   int status;
512   struct mqelem *top = NULL;
513
514   if (!Prompt_input("First Name: ", first, BUFSIZ))
515     return NULL;
516   if (!Prompt_input("Last  Name: ", last, BUFSIZ))
517     return NULL;
518   FixCase(first);
519   FixCase(last);
520
521   args[0] = first;
522   args[1] = last;
523
524   switch ((status = do_mr_query("get_user_account_by_name", 2, args,
525                                 StoreInfo, &top)))
526     {
527     case MR_SUCCESS:
528       break;
529     case MR_NO_MATCH:
530       Put_message("There is no user in the database with that name.");
531       return NULL;
532     default:
533       com_err(program_name, status, " in get_account_user_by_name.");
534       return NULL;
535     }
536
537   top = QueueTop(top);
538   if (QueueCount(top) == 1) /* This is a unique name. */
539     {
540       char **info = top->q_data;
541       Put_message("User ID Number retrieved for the user: ");
542       Put_message("");
543       PrintUserName(info);
544       uid = strdup(info[U_UID]);
545       FreeQueue(top);
546       return strdup(uid);
547     }
548
549   Put_message("That name is not unique, choose the user that you want.");
550   uid = ChooseUser(top);
551   FreeQueue(top);
552   return uid;
553 }
554
555 /*      Function Name: SetUserPassword
556  *      Description: Set the new kerberos password for this user.
557  *      Arguments: name - kerberos principle name for this user, (login name).
558  *      Returns: none.
559  */
560
561 static void SetUserPassword(char *name)
562 {
563   name = name;                  /* make saber happy. */
564   Put_message("Kerberos password not changed, code non-existant.");
565   /* clever message to call account_admin, if this fails. */
566 }
567
568 /*      Function Name:  GiveBackLogin
569  *      Description: Gives back previously reserved kerberous principle.
570  *      Arguments: name - principle to give back.
571  *      Returns: void.
572  */
573
574 static void GiveBackLogin(char *name)
575 {
576   name = name;                  /* make saber happy. */
577   Put_message("kerberos code not implimented, name not given back.");
578   /* send mail to db maintainer if this fails. */
579 }
580
581 /*      Function Name: RegisterUser
582  *      Description: This function registers a user.
583  *      Arguments: none.
584  *      Returns: DM_NORMAL.
585  */
586
587 int RegisterUser(int argc, char **argv)
588 {
589   char *args[MAX_ARGS_SIZE];
590   char *login, *fstype = NULL;
591   char temp_buf[BUFSIZ];
592   int status;
593
594   Put_message("This function has NO kerberos support, so strange things");
595   Put_message("may happen if you use it to register a user.");
596
597   switch (YesNoQuestion("Do you know the users UID Number (y/n)", FALSE))
598     {
599     case TRUE:
600       Prompt_input("What is the UID number of the user? ", temp_buf, BUFSIZ);
601       args[0] = strdup(temp_buf);
602       break;
603     case FALSE:
604       if (!(args[0] = GetUidNumberFromName()))
605         return DM_NORMAL;
606       break;
607     default:
608       return DM_NORMAL;
609     }
610
611   sprintf(temp_buf, "u%s", args[0]);
612   login = strdup(temp_buf);
613   if ((GetValueFromUser("Login name for this user? ", &login) == SUB_ERROR) ||
614       (GetFSTypes(&fstype, FALSE) == SUB_ERROR))
615     {
616       args[1] = login;
617       FreeInfo(args);      /* This work because the NULL temination is ok. */
618       return DM_NORMAL;
619     }
620   Put_message("KERBEROS code not added, did not reserve name with kerberos.");
621   args[1] = login;
622   args[2] = fstype;
623   args[3] = NULL;
624
625   switch ((status = do_mr_query("register_user", CountArgs(args),
626                                 args, NULL, NULL)))
627     {
628     case MR_SUCCESS:
629       sprintf(temp_buf, "User %s successfully registered.", login);
630       Put_message(temp_buf);
631       SetUserPassword(login);
632       break;
633     case MR_IN_USE:
634       GiveBackLogin(login);
635       sprintf(temp_buf, "The username %s is already in use.", login);
636       Put_message(temp_buf);
637       break;
638     default:
639       com_err(program_name, status, " in register_user");
640       break;
641     }
642   FreeInfo(args);
643   return DM_NORMAL;
644 }
645
646 /*      Function Name: RealUpdateUser
647  *      Description: actuall updates the user information.
648  *      Arguments: info - all current information for the user fields.
649  *                 junk - an UNUSED boolean.
650  *      Returns: none.
651  */
652
653 static void RealUpdateUser(char **info, Bool junk)
654 {
655   int status;
656   char error_buf[BUFSIZ];
657   char **args = AskUserInfo(info, TRUE);
658
659   if (!args)
660     {
661       Put_message("Aborted.");
662       return;
663     }
664   if ((status = do_mr_query("update_user_account", CountArgs(args),
665                             args, NULL, NULL)))
666     {
667       com_err(program_name, status, " in ModifyFields");
668       sprintf(error_buf, "User %s not updated due to errors.", info[NAME]);
669       Put_message(error_buf);
670     }
671 }
672
673 /*      Function Name: UpdateUser
674  *      Description: Modify some of the information about a user.
675  *      Arguments: argc, argv - login name of the user in argv[1].
676  *      Returns: DM_NORMAL.
677  */
678
679 int UpdateUser(int argc, char **argv)
680 {
681   struct mqelem *elem;
682
683   elem = GetUserInfo(LOGIN, argv[1], NULL);
684   QueryLoop(elem, NullPrint, RealUpdateUser, "Update the user");
685
686   FreeQueue(elem);
687   return DM_NORMAL;
688 }
689
690 /*      Function Name: RealDeactivateUser
691  *      Description: sets the user's status to 3.
692  *      Arguments: info - all current information for the user fields
693  *                 one_item - indicates the user hasn't been queried yet
694  *      Returns: none.
695  */
696
697 static void RealDeactivateUser(char **info, Bool one_item)
698 {
699   int status;
700   char txt_buf[BUFSIZ];
701   char *qargs[2], **args;
702   struct mqelem *elem = NULL;
703
704   if (one_item)
705     {
706       sprintf(txt_buf, "Deactivate user %s (y/n)", info[NAME]);
707       if (YesNoQuestion(txt_buf, FALSE) != TRUE)
708         return;
709     }
710
711   qargs[0] = info[NAME];
712   qargs[1] = "3";
713   if ((status = do_mr_query("update_user_status", 2, qargs, NULL, NULL)))
714     {
715       com_err(program_name, status, " in update_user_status");
716       sprintf(txt_buf, "User %s not deactivated due to errors.", info[NAME]);
717       Put_message(txt_buf);
718     }
719   else if (YesNoQuestion("Also deactivate matching list and filesystem (y/n)",
720                          FALSE) == TRUE)
721     {
722       status = do_mr_query("get_list_info", 1, &(info[NAME]), StoreInfo,
723                            &elem);
724       if (status == MR_SUCCESS)
725         {
726           args = QueueTop(elem)->q_data;
727           free(args[L_ACTIVE]);
728           args[L_ACTIVE] = strdup("0");
729           FreeAndClear(&args[L_MODTIME], TRUE);
730           FreeAndClear(&args[L_MODBY], TRUE);
731           FreeAndClear(&args[L_MODWITH], TRUE);
732           SlipInNewName(args, args[L_NAME]);
733           if ((status = do_mr_query("update_list", CountArgs(args), args,
734                                     NULL, NULL)))
735             {
736               com_err(program_name, status, " updating list, "
737                       "not deactivating list or filesystem");
738               FreeInfo(args);
739               FreeQueue(elem);
740               return;
741             }
742           FreeInfo(args);
743           FreeQueue(elem);
744           elem = NULL;
745         }
746       else if (status != MR_NO_MATCH)
747         {
748           com_err(program_name, status, " getting list info, "
749                   "not deactivating list or filesystem");
750           return;
751         }
752
753       if ((status = do_mr_query("get_filesys_by_label", 1, &(info[NAME]),
754                                 StoreInfo, &elem)))
755         {
756           com_err(program_name, status, " getting filsys info, "
757                   "not deactivating filesystem");
758           FreeInfo(args);
759           FreeQueue(elem);
760           return;
761         }
762       args = QueueTop(elem)->q_data;
763       free(args[FS_TYPE]);
764       args[FS_TYPE] = strdup("ERR");
765       free(args[FS_COMMENTS]);
766       args[FS_COMMENTS] = strdup("Locker disabled; call 3-1325 for help");
767       FreeAndClear(&args[FS_MODTIME], TRUE);
768       FreeAndClear(&args[FS_MODBY], TRUE);
769       FreeAndClear(&args[FS_MODWITH], TRUE);
770       SlipInNewName(args, args[FS_NAME]);
771       if ((status = do_mr_query("update_filesys", CountArgs(args), args,
772                                 NULL, NULL)))
773         {
774           com_err(program_name, status, " updating filesystem, "
775                   "not deactivating filesystem");
776           FreeInfo(args);
777           FreeQueue(elem);
778           return;
779         }
780       FreeInfo(args);
781       FreeQueue(elem);
782     }
783 }
784
785
786 /*      Function Name: DeactivateUser
787  *      Description: sets the user's status to 3.
788  *      Arguments: argc, argv - login name of the user in argv[1].
789  *      Returns: DM_NORMAL.
790  */
791
792 int DeactivateUser(int argc, char **argv)
793 {
794   struct mqelem *elem;
795
796   elem = GetUserInfo(LOGIN, argv[1], NULL);
797   QueryLoop(elem, NullPrint, RealDeactivateUser, "Deactivate user");
798
799   FreeQueue(elem);
800   return DM_NORMAL;
801 }
802
803
804 /* ------------------------- Top Menu ------------------------- */
805
806 /* DeleteUser() in delete.c */
807
808 /*      Function Name: DeleteUserByUid
809  *      Description: Deletes the user given a uid number.
810  *      Arguments: argc, argv - uid if user in argv[1].
811  *      Returns: DM_NORMAL.
812  *      NOTES: This just gets the username from the mr server
813  *             and performs a DeleteUser().
814  */
815
816 int DeleteUserByUid(int argc, char **argv)
817 {
818   int status;
819   struct mqelem *elem = NULL;
820   char **info;
821
822   if (!ValidName(argv[1]))
823     return DM_NORMAL;
824
825   if ((status = do_mr_query("get_user_account_by_uid", 1, argv + 1, StoreInfo,
826                             &elem)))
827     com_err(program_name, status, " in get_user_account_by_uid");
828
829   info = elem->q_data;
830   argv[1] = info[U_NAME];
831
832   DeleteUser(argc, argv);
833   return DM_NORMAL;
834 }
835
836 /* ------------------------- Show User Information ------------------------- */
837
838 /*      Function Name: ShowUserByLogin
839  *      Description: Shows user information given a login name.
840  *      Arguments: argc, argv - login name in argv[1].
841  *      Returns: DM_NORMAL
842  */
843
844 int ShowUserByLogin(int argc, char *argv[])
845 {
846   struct mqelem *top, *elem;
847
848   elem = top = GetUserInfo(LOGIN, argv[1], NULL);
849   Loop(elem, PrintUserInfo);
850
851   FreeQueue(top);
852   return DM_NORMAL;
853 }
854
855 /*      Function Name: RetrieveUserByName
856  *      Description: Show information on a user give fist and/or last name.
857  *      Arguments: argc, argv - argv[1] - first name.
858  *                              argv[2] - last name.
859  *      Returns: DM_NORMAL.
860  */
861
862 int ShowUserByName(int argc, char *argv[])
863 {
864   struct mqelem *top;
865   char buf[BUFSIZ];
866
867   top = GetUserInfo(BY_NAME, argv[1], argv[2]);
868
869   if (!top)             /* if there was an error then return. */
870     return DM_NORMAL;
871
872   if (!PromptWithDefault("Print full information, or just the names (f/n)?",
873                          buf, 2, "f"))
874     return DM_NORMAL;
875
876   switch (buf[0])
877     {
878     case 'F':
879     case 'f':
880       Loop(top, PrintUserInfo);
881       break;
882     case 'N':
883     case 'n':
884       Loop(top, PrintUserName);
885       break;
886     }
887
888   FreeQueue(top);
889   return DM_NORMAL;
890 }
891
892 /*      Function Name: ShowUserByClass
893  *      Description: Shows real and login names of all users in class.
894  *      Arguments: argc, argv - argv[1] contains the class.
895  *      Returns: none.
896  */
897
898 int ShowUserByClass(int argc, char **argv)
899 {
900   struct mqelem *top;
901
902   if (YesNoQuestion("This will take a long time.  Are you sure", 0) == FALSE)
903     return DM_NORMAL;
904   top = GetUserInfo(CLASS, argv[1], NULL);
905   Loop(top, PrintUserName);
906
907   FreeQueue(top);
908   return DM_NORMAL;
909 }
910
911
912 /*      Function Name: ShowUserById
913  *      Description: Shows user information given an ID number.
914  *      Arguments: argc, argv - ID number in argv[1].
915  *      Returns: DM_NORMAL
916  */
917
918 int ShowUserById(int argc, char *argv[])
919 {
920   struct mqelem *top, *elem;
921
922   elem = top = GetUserInfo(ID, argv[1], NULL);
923   Loop(elem, PrintUserInfo);
924
925   FreeQueue(top);
926   return DM_NORMAL;
927 }
928
929
930 /*      Function Name: GetKrbmap
931  *      Description: Shows user <-> Kerberos mappings
932  *      Arguments: argc, argv - argv[1] contains the user login name,
933  *              argv[2] contains the principal
934  *      Returns: none.
935  */
936
937 int GetKrbmap(int argc, char **argv)
938 {
939   int stat;
940   struct mqelem *elem = NULL, *top;
941   char buf[BUFSIZ];
942
943   if ((stat = do_mr_query("get_kerberos_user_map", 2, &argv[1],
944                           StoreInfo, &elem)))
945     {
946       com_err(program_name, stat, " in GetKrbMap.");
947       return DM_NORMAL;
948     }
949
950   top = elem = QueueTop(elem);
951   Put_message("");
952   while (elem)
953     {
954       char **info = elem->q_data;
955       sprintf(buf, "User: %-9s Principal: %s",
956               info[KMAP_USER], info[KMAP_PRINCIPAL]);
957       Put_message(buf);
958       elem = elem->q_forw;
959     }
960
961   FreeQueue(QueueTop(top));
962   return DM_NORMAL;
963 }
964
965
966 /*      Function Name: AddKrbmap
967  *      Description: Add a new user <-> Kerberos mapping
968  *      Arguments: argc, argv - argv[1] contains the user login name,
969  *              argv[2] contains the principal
970  *      Returns: none.
971  */
972
973 int AddKrbmap(int argc, char **argv)
974 {
975   int stat;
976
977   if (!strchr(argv[KMAP_PRINCIPAL + 1], '@'))
978     {
979       Put_message("Please specify a realm for the kerberos principal.");
980       return DM_NORMAL;
981     }
982   if ((stat = do_mr_query("add_kerberos_user_map", 2, &argv[1],
983                           NULL, NULL)))
984     {
985       com_err(program_name, stat, " in AddKrbMap.");
986       if (stat == MR_EXISTS)
987         Put_message("No user or principal may have more than one mapping.");
988     }
989   return DM_NORMAL;
990 }
991
992
993 /*      Function Name: DeleteKrbmap
994  *      Description: Remove a user <-> Kerberos mapping
995  *      Arguments: argc, argv - argv[1] contains the user login name,
996  *              argv[2] contains the principal
997  *      Returns: none.
998  */
999
1000 int DeleteKrbmap(int argc, char **argv)
1001 {
1002   int stat;
1003
1004   if ((stat = do_mr_query("delete_kerberos_user_map", 2, &argv[1],
1005                           NULL, NULL)))
1006     com_err(program_name, stat, " in DeleteKrbMap.");
1007   return DM_NORMAL;
1008 }
1009
1010
1011 /*      Function Name: GetDirFlags
1012  *      Description: Shows MITdir listing preferences
1013  *      Arguments: argc, argv - argv[1] contains the user login name
1014  *      Returns: none.
1015  */
1016
1017 int GetDirFlags(int argc, char **argv)
1018 {
1019   int stat, flags;
1020   struct mqelem *elem = NULL;
1021   char buf[BUFSIZ], **info;
1022
1023   if (!ValidName(argv[1]))
1024     return DM_NORMAL;
1025
1026   if ((stat = do_mr_query("get_user_directory_flags", 1, &argv[1],
1027                           StoreInfo, &elem)))
1028     {
1029       com_err(program_name, stat, " in GetDirFlags.");
1030       return DM_NORMAL;
1031     }
1032
1033   info = QueueTop(elem)->q_data;
1034   flags = atoi(info[0]);
1035   FreeQueue(QueueTop(elem));
1036
1037   Put_message("");
1038   sprintf(buf, "User: %s", argv[1]);
1039   Put_message(buf);
1040   if (flags & DIRFLAGS_SUPPRESS)
1041       Put_message("Does NOT appear in the on-line directory.");
1042   else
1043     {
1044       Put_message("Does appear in the on-line directory.");
1045       if (flags & DIRFLAGS_NONLOCAL)
1046         Put_message("Is listed with non-MIT.EDU email address (if known)");
1047       else
1048         Put_message("Is listed with MIT.EDU email address.");
1049     }
1050
1051   return DM_NORMAL;
1052 }
1053
1054 /*      Function Name: SetDirFlags
1055  *      Description: Update online directory preferences
1056  *      Arguments: argc, argv - the login name of the user in argv[1].
1057  *      Returns: DM_NORMAL.
1058  */
1059
1060 int SetDirFlags(int argc, char **argv)
1061 {
1062   int stat, flags;
1063   char **info, buf[BUFSIZ], *args[2];
1064   struct mqelem *elem = NULL;
1065
1066   if (!ValidName(argv[1]))
1067     return DM_NORMAL;
1068
1069   /* Fetch current prefs */
1070   if ((stat = do_mr_query("get_user_directory_flags", 1, &argv[1],
1071                           StoreInfo, &elem)))
1072     {
1073       com_err(program_name, stat, " in GetDirFlags.");
1074       return DM_NORMAL;
1075     }
1076   info = QueueTop(elem)->q_data;
1077   flags = atoi(info[0]);
1078   FreeQueue(QueueTop(elem));
1079
1080   sprintf(buf, "List %s in the on-line directory (y/n)", argv[1]);
1081   if (YesNoQuestion(buf, !(flags & DIRFLAGS_SUPPRESS)))
1082     flags &= ~DIRFLAGS_SUPPRESS;
1083   else
1084     flags |= DIRFLAGS_SUPPRESS;
1085
1086   sprintf(buf, "List MIT.EDU email address even when mail is "
1087           "forwarded elsewhere? (y/n)");
1088   if (YesNoQuestion(buf, !(flags & DIRFLAGS_NONLOCAL)))
1089     flags &= ~DIRFLAGS_NONLOCAL;
1090   else
1091     flags |= DIRFLAGS_NONLOCAL;
1092
1093   args[0] = argv[1];
1094   sprintf(buf, "%d", flags);
1095   args[1] = buf;
1096   if ((stat = do_mr_query("update_user_directory_flags", 2,
1097                           args, NULL, NULL)))
1098     com_err(program_name, stat, " in SetDirFlags");
1099   else
1100     Put_message("Directory preferences set.");
1101
1102   return DM_NORMAL;
1103 }
This page took 0.124414 seconds and 5 git commands to generate.