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