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