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