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