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