]> andersk Git - moira.git/blob - clients/moira/user.c
Change default winprofiledir and friends to DFS.
[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 <ctype.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27
28 #include <krb.h>
29
30 RCSID("$Header$");
31
32 void CorrectCapitalization(char **name);
33 char **AskUserInfo(char **info, Bool name);
34 struct mqelem *GetUserInfo(int type, char *name1, char *name2);
35
36 #define LOGIN 0
37 #define UID   1
38 #define BY_NAME  2
39 #define CLASS 3
40 #define ID 4
41
42 #ifdef ATHENA
43 #define DEFAULT_SHELL "/bin/athena/tcsh"
44 #else
45 #define DEFAULT_SHELL "/bin/csh"
46 #endif
47 #define DEFAULT_CLASS "?"
48
49 #define DEFAULT_WINCONSOLESHELL "cmd"
50 #define DEFAULT_WINHOMEDIR "[DFS]"
51 #define DEFAULT_WINPROFILEDIR "[DFS]"
52
53 /*      Function Name: UserState
54  *      Description: Convert a numeric state into a descriptive string.
55  *      Arguments: state value
56  *      Returns: pointer to statically allocated string.
57  */
58
59 static char *states[] = {
60   "Registerable (0)",
61   "Active (1)",
62   "Half Registered (2)",
63   "Deleted (3)",
64   "Not registerable (4)",
65   "Enrolled/Registerable (5)",
66   "Enrolled/Not Registerable (6)",
67   "Half Enrolled (7)",
68   "Registerable, Kerberos only (8)",
69   "Active, Kerberos only (9)"
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
111   sprintf(name, "%s, %s %s", info[U_LAST], info[U_FIRST], info[U_MIDDLE]);
112   sprintf(buf, "Login name: %-20s Full name: %s", info[U_NAME], name);
113   Put_message(buf);
114   sprintf(buf, "User id: %-23s Login shell: %-10s",
115           info[U_UID], info[U_SHELL]);
116   Put_message(buf);
117   sprintf(buf, "Class: %-25s Windows Console Shell: %-10s",
118           info[U_CLASS], info[U_WINCONSOLESHELL]);
119   Put_message(buf);
120   sprintf(buf, "Account is: %-20s MIT ID number: %s",
121           UserState(atoi(info[U_STATE])), info[U_MITID]);
122   Put_message(buf);
123   sprintf(buf, "Windows Home Directory: %s", info[U_WINHOMEDIR]);
124   Put_message(buf);
125   sprintf(buf, "Windows Profile Directory: %s", info[U_WINPROFILEDIR]);
126   Put_message(buf);
127   status = atoi(info[U_STATE]);
128   if (status == 0 || status == 2)
129     {
130       sprintf(buf, "User %s secure Account Coupon to register",
131               atoi(info[U_SECURE]) ? "needs" : "does not need");
132       Put_message(buf);
133     }
134   sprintf(buf, "Comments: %s", info[U_COMMENT]);
135   Put_message(buf);
136   sprintf(buf, "Created  by %s on %s.", info[U_CREATOR], info[U_CREATED]);
137   Put_message(buf);
138   sprintf(buf, MOD_FORMAT, info[U_MODBY], info[U_MODTIME], info[U_MODWITH]);
139   Put_message(buf);
140 }
141
142 /*      Function Name: SetUserDefaults
143  *      Description: Sets the default values for add user.
144  *      Arguments: info - a blank user info array of char *'s.
145  *      Returns: args - the filled info structure.
146  */
147
148 static char **SetUserDefaults(char **info)
149 {
150   info[U_NAME] = strdup(UNIQUE_LOGIN);
151   info[U_UID] = strdup(UNIQUE_UID);
152   info[U_SHELL] = strdup(DEFAULT_SHELL);
153   info[U_WINCONSOLESHELL] = strdup(DEFAULT_WINCONSOLESHELL);
154   info[U_LAST] = strdup(DEFAULT_NONE);
155   info[U_FIRST] = strdup(DEFAULT_NONE);
156   info[U_MIDDLE] = strdup(DEFAULT_NONE);
157   info[U_STATE] = strdup(DEFAULT_NO);
158   info[U_MITID] = strdup(DEFAULT_NONE);
159   info[U_CLASS] = strdup(DEFAULT_CLASS);
160   info[U_COMMENT] = strdup("");
161   info[U_SIGNATURE] = strdup("");
162   info[U_SECURE] = strdup("0");
163   info[U_WINHOMEDIR] = strdup(DEFAULT_WINHOMEDIR);
164   info[U_WINPROFILEDIR] = strdup(DEFAULT_WINPROFILEDIR);
165   info[U_MODTIME] = info[U_MODBY] = info[U_MODWITH] = info[U_END] = NULL;
166   info[U_CREATED] = info[U_CREATOR] = 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, 0) == 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 state;
207   char temp_buf[BUFSIZ], *newname;
208
209   if (name)
210     {
211       sprintf(temp_buf, "\nChanging Attributes of user %s.\n", info[U_NAME]);
212       Put_message(temp_buf);
213     }
214   else
215     {
216       struct mqelem *elem = NULL;
217       char *argv[3];
218
219       if (GetValueFromUser("User's last name", &info[U_LAST]) == SUB_ERROR)
220         return NULL;
221       CorrectCapitalization(&info[U_LAST]);
222       if (GetValueFromUser("User's first name", &info[U_FIRST]) == SUB_ERROR)
223         return NULL;
224       CorrectCapitalization(&info[U_FIRST]);
225       if (GetValueFromUser("User's middle name", &info[U_MIDDLE]) == SUB_ERROR)
226         return NULL;
227       CorrectCapitalization(&info[U_MIDDLE]);
228       argv[0] = info[U_FIRST];
229       argv[1] = info[U_LAST];
230       if (do_mr_query("get_user_account_by_name", 2, argv,
231                       StoreInfo, &elem) == MR_SUCCESS)
232         {
233           Put_message("A user by that name already exists in the database.");
234           Loop(QueueTop(elem), PrintUserInfo);
235           Loop(QueueTop(elem), FreeInfo);
236           FreeQueue(elem);
237           if (YesNoQuestion("Add new user anyway", TRUE) != TRUE)
238             return NULL;
239         }
240     }
241   if (name)
242     {
243       newname = strdup(info[U_NAME]);
244       if (GetValueFromUser("The new login name for this user", &newname) ==
245           SUB_ERROR)
246         return NULL;
247     }
248   else if (GetValueFromUser("Login name for this user", &info[U_NAME]) ==
249            SUB_ERROR)
250     return NULL;
251
252   strcpy(temp_buf, info[U_UID]);
253   if (GetValueFromUser("User's UID", &info[U_UID]) == SUB_ERROR)
254     return NULL;
255   if (strcmp(info[U_UID], UNIQUE_UID) && strcmp(info[U_UID], temp_buf))
256     {
257       struct mqelem *elem = NULL;
258       if (do_mr_query("get_user_account_by_uid", 1, &info[U_UID],
259                       StoreInfo, &elem) == MR_SUCCESS)
260         {
261           Put_message("A user with that uid already exists in the database.");
262           Loop(QueueTop(elem), PrintUserInfo);
263           Loop(QueueTop(elem), FreeInfo);
264           FreeQueue(elem);
265           if (YesNoQuestion("Add new user anyway", TRUE) != TRUE)
266             return NULL;
267         }
268     }
269
270   if (GetValueFromUser("User's shell", &info[U_SHELL]) == SUB_ERROR)
271     return NULL;
272   if (GetValueFromUser("Windows console shell", &info[U_WINCONSOLESHELL])
273       == 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 (GetValueFromUser("Windows Home Directory", &info[U_WINHOMEDIR]) ==
312       SUB_ERROR)
313     return NULL;
314
315   if (GetValueFromUser("Windows Profile Directory", &info[U_WINPROFILEDIR]) ==
316       SUB_ERROR)
317     return NULL;
318
319   state = atoi(info[U_STATE]);
320   if (!name || state == 0 || state == 2)
321     {
322       if (YesNoQuestion("User needs secure Account Coupon to register",
323                         atoi(info[U_SECURE]) ? TRUE : FALSE) == FALSE)
324         {
325           free(info[U_SECURE]);
326           info[U_SECURE] = strdup("0");
327         }
328       else
329         {
330           free(info[U_SECURE]);
331           info[U_SECURE] = strdup("1");
332         }
333     }
334
335   info[U_SIGNATURE] = strdup("");
336
337   FreeAndClear(&info[U_MODTIME], TRUE);
338   FreeAndClear(&info[U_MODBY], TRUE);
339   FreeAndClear(&info[U_MODWITH], TRUE);
340
341   /*
342    * Slide the newname into the #2 slot, this screws up all future references
343    * to this list, since we slip the pointer into a info list it gets freed
344    * when the rest of the list gets freed.
345    */
346   if (name)
347     SlipInNewName(info, newname);
348
349   return info;
350 }
351
352 /*      Function Name: GetUserInfo
353  *      Description: Stores the user information in a queue.
354  *      Arguments: type - type of field given to get info, one of:
355  *                        LOGIN, UID, BY_NAME, CLASS.
356  *                 name1 - name of thing specified by type (wildcards okay)
357  *                 name2 - other name, only used in get user by first and last.
358  *                         (wildcards okay).
359  *      Returns: the first element of the queue containing the user info.
360  *
361  */
362
363 struct mqelem *GetUserInfo(int type, char *name1, char *name2)
364 {
365   char *args[2];
366   int status;
367   struct mqelem *elem = NULL;
368
369   switch (type)
370     {
371     case LOGIN:
372       args[0] = name1;
373       if ((status = do_mr_query("get_user_account_by_login", 1, args,
374                                 StoreInfo, &elem)))
375         {
376           com_err(program_name, status,
377                   " when attempting to get_user_account_by_login.");
378           return NULL;
379         }
380       break;
381     case UID:
382       args[0] = name1;
383       if ((status = do_mr_query("get_user_account_by_uid", 1, args,
384                                 StoreInfo, &elem)))
385         {
386           com_err(program_name, status,
387                   " when attempting to get_user_account_by_uid.");
388           return NULL;
389         }
390       break;
391     case BY_NAME:
392       args[0] = name1;
393       args[1] = name2;
394       if ((status = do_mr_query("get_user_account_by_name", 2, args,
395                                 StoreInfo, &elem)))
396         {
397           com_err(program_name, status,
398                   " when attempting to get_user_account_by_name.");
399           return NULL;
400         }
401       break;
402     case CLASS:
403       args[0] = name1;
404       if ((status = do_mr_query("get_user_account_by_class", 1, args,
405                                 StoreInfo, &elem)))
406         {
407           com_err(program_name, status,
408                   " when attempting to get_user_account_by_class.");
409           return NULL;
410         }
411       break;
412     case ID:
413       args[0] = name1;
414       if ((status = do_mr_query("get_user_account_by_id", 1, args,
415                                 StoreInfo, &elem)))
416         {
417           com_err(program_name, status,
418                   " when attempting to get_user_account_by_id.");
419           return NULL;
420         }
421       break;
422     }
423   return QueueTop(elem) ;
424 }
425
426 /*      Function Name: AddNewUser
427  *      Description: Adds a new user to the database.
428  *      Arguments: none.
429  *      Returns: DM_NORMAL.
430  */
431
432 int AddNewUser(int argc, char **argv)
433 {
434   int status;
435   char **args, *info[MAX_ARGS_SIZE];
436
437   if (!(args = AskUserInfo(SetUserDefaults(info), FALSE)))
438     {
439       Put_message("Aborted.");
440       return DM_NORMAL;
441     }
442   if ((status = do_mr_query("add_user_account", CountArgs(args),
443                             args, NULL, NULL)))
444     com_err(program_name, status, " in add_user_account");
445   else
446     Put_message("New user added to database.");
447   FreeInfo(args);
448   return DM_NORMAL;
449 }
450
451
452 /*      Function Name: GetLoginName
453  *      Description: Asks the user for a login name and reserves
454  *                   it with kerberous.
455  *      Arguments: none.
456  *      Returns: a malloced login name for the user.
457  */
458
459 static char *GetLoginName(void)
460 {
461   char *name;
462
463   name = strdup("");
464   if (GetValueFromUser("Login name for this user? ", &name) == SUB_ERROR)
465     return NULL;
466   Put_message("KERBEROS code not added, did not reserve name with kerberos.");
467   return name;
468 }
469
470
471 /*      Function Name: ChooseUser
472  *      Description: Choose a user from a list and return the uid.
473  *      Arguments: top - a queue of user information.
474  *      Returns: uid - the malloced uid of the user that was chosen.
475  */
476
477 static char *ChooseUser(struct mqelem *elem)
478 {
479   while (elem)
480     {
481       char **info = elem->q_data;
482       PrintUserInfo(info);
483       switch (YesNoQuitQuestion("Is this the user you want (y/n/q)", FALSE))
484         {
485         case TRUE:
486           return strdup(info[U_UID]);
487         case FALSE:
488           break;
489         default:                /* quit or ^C. */
490           return NULL;
491         }
492       elem = elem->q_forw;
493     }
494   return NULL;
495 }
496
497 /*      Function Name: GetUidNumberFromName
498  *      Description: Gets the users uid number, from the name.
499  *      Arguments: none.
500  *      Returns: uid - a malloced string containing the uid.
501  */
502
503 static char *GetUidNumberFromName(void)
504 {
505   char *args[5], *uid, first[BUFSIZ], last[BUFSIZ];
506   int status;
507   struct mqelem *top = NULL;
508
509   if (!Prompt_input("First Name: ", first, BUFSIZ))
510     return NULL;
511   if (!Prompt_input("Last  Name: ", last, BUFSIZ))
512     return NULL;
513   FixCase(first);
514   FixCase(last);
515
516   args[0] = first;
517   args[1] = last;
518
519   switch ((status = do_mr_query("get_user_account_by_name", 2, args,
520                                 StoreInfo, &top)))
521     {
522     case MR_SUCCESS:
523       break;
524     case MR_NO_MATCH:
525       Put_message("There is no user in the database with that name.");
526       return NULL;
527     default:
528       com_err(program_name, status, " in get_account_user_by_name.");
529       return NULL;
530     }
531
532   top = QueueTop(top);
533   if (QueueCount(top) == 1) /* This is a unique name. */
534     {
535       char **info = top->q_data;
536       Put_message("User ID Number retrieved for the user: ");
537       Put_message("");
538       PrintUserName(info);
539       uid = strdup(info[U_UID]);
540       FreeQueue(top);
541       return strdup(uid);
542     }
543
544   Put_message("That name is not unique, choose the user that you want.");
545   uid = ChooseUser(top);
546   FreeQueue(top);
547   return uid;
548 }
549
550 /*      Function Name: SetUserPassword
551  *      Description: Set the new kerberos password for this user.
552  *      Arguments: name - kerberos principle name for this user, (login name).
553  *      Returns: none.
554  */
555
556 static void SetUserPassword(char *name)
557 {
558   name = name;                  /* make saber happy. */
559   Put_message("Kerberos password not changed, code non-existant.");
560   /* clever message to call account_admin, if this fails. */
561 }
562
563 /*      Function Name:  GiveBackLogin
564  *      Description: Gives back previously reserved kerberous principle.
565  *      Arguments: name - principle to give back.
566  *      Returns: void.
567  */
568
569 static void GiveBackLogin(char *name)
570 {
571   name = name;                  /* make saber happy. */
572   Put_message("kerberos code not implemented, name not given back.");
573   /* send mail to db maintainer if this fails. */
574 }
575
576 /*      Function Name: RegisterUser
577  *      Description: This function registers a user.
578  *      Arguments: none.
579  *      Returns: DM_NORMAL.
580  */
581
582 int RegisterUser(int argc, char **argv)
583 {
584   char *args[MAX_ARGS_SIZE];
585   char *login, *potype = NULL;
586   char temp_buf[BUFSIZ];
587   int status, i;
588
589   for (i = 0; i < MAX_ARGS_SIZE; i++)
590     args[i] = NULL;
591
592   Put_message("This function has NO kerberos support, so strange things");
593   Put_message("may happen if you use it to register a user.");
594
595   switch (YesNoQuestion("Do you know the users UID Number (y/n)", FALSE))
596     {
597     case TRUE:
598       Prompt_input("What is the UID number of the user? ", temp_buf, BUFSIZ);
599       args[0] = strdup(temp_buf);
600       break;
601     case FALSE:
602       if (!(args[0] = GetUidNumberFromName()))
603         return DM_NORMAL;
604       break;
605     default:
606       return DM_NORMAL;
607     }
608
609   sprintf(temp_buf, "u%s", args[0]);
610   login = strdup(temp_buf);
611   if (GetValueFromUser("Login name for this user? ", &login) == SUB_ERROR)
612     {
613       args[1] = login;
614       FreeInfo(args);      /* This work because the NULL temination is ok. */
615       return DM_NORMAL;
616     }
617   Put_message("KERBEROS code not added, did not reserve name with kerberos.");
618   args[1] = login;
619   
620   sprintf(temp_buf, "IMAP");
621   potype = strdup(temp_buf);
622   if (GetValueFromUser("P.O. Box Type for this user? ", &potype) == SUB_ERROR)
623     {
624       args[2] = potype;
625       FreeInfo(args);
626       return DM_NORMAL;
627     }
628   if (strcmp(potype, "POP") && strcmp(potype, "IMAP"))
629     {
630       sprintf(temp_buf, "Unknown P.O. Box type.");
631       Put_message(temp_buf);
632       FreeInfo(args);
633       return DM_NORMAL;
634     }
635   args[2] = potype;
636   args[3] = NULL;
637
638   switch ((status = do_mr_query("register_user", CountArgs(args),
639                                 args, NULL, NULL)))
640     {
641     case MR_SUCCESS:
642       sprintf(temp_buf, "User %s successfully registered.", login);
643       Put_message(temp_buf);
644       SetUserPassword(login);
645       break;
646     case MR_IN_USE:
647       GiveBackLogin(login);
648       sprintf(temp_buf, "The username %s is already in use.", login);
649       Put_message(temp_buf);
650       break;
651     default:
652       com_err(program_name, status, " in register_user");
653       break;
654     }
655   FreeInfo(args);
656   return DM_NORMAL;
657 }
658
659 /*      Function Name: RealUpdateUser
660  *      Description: actuall updates the user information.
661  *      Arguments: info - all current information for the user fields.
662  *                 junk - an UNUSED boolean.
663  *      Returns: none.
664  */
665
666 static void RealUpdateUser(char **info, Bool junk)
667 {
668   int status;
669   char error_buf[BUFSIZ];
670   char **args = AskUserInfo(info, TRUE);
671
672   if (!args)
673     {
674       Put_message("Aborted.");
675       return;
676     }
677   if ((status = do_mr_query("update_user_account", CountArgs(args),
678                             args, NULL, NULL)))
679     {
680       com_err(program_name, status, " in ModifyFields");
681       sprintf(error_buf, "User %s not updated due to errors.", info[NAME]);
682       Put_message(error_buf);
683     }
684 }
685
686 /*      Function Name: UpdateUser
687  *      Description: Modify some of the information about a user.
688  *      Arguments: argc, argv - login name of the user in argv[1].
689  *      Returns: DM_NORMAL.
690  */
691
692 int UpdateUser(int argc, char **argv)
693 {
694   struct mqelem *elem;
695
696   elem = GetUserInfo(LOGIN, argv[1], NULL);
697   QueryLoop(elem, NullPrint, RealUpdateUser, "Update the user");
698
699   FreeQueue(elem);
700   return DM_NORMAL;
701 }
702
703 /*      Function Name: RealDeactivateUser
704  *      Description: sets the user's status to 3.
705  *      Arguments: info - all current information for the user fields
706  *                 one_item - indicates the user hasn't been queried yet
707  *      Returns: none.
708  */
709
710 static void RealDeactivateUser(char **info, Bool one_item)
711 {
712   int status;
713   char txt_buf[BUFSIZ];
714   char *qargs[2], **args;
715   struct mqelem *elem = NULL;
716
717   if (one_item)
718     {
719       sprintf(txt_buf, "Deactivate user %s (y/n)", info[NAME]);
720       if (YesNoQuestion(txt_buf, FALSE) != TRUE)
721         return;
722     }
723
724   qargs[0] = info[NAME];
725   qargs[1] = "3";
726   if ((status = do_mr_query("update_user_status", 2, qargs, NULL, NULL)))
727     {
728       com_err(program_name, status, " in update_user_status");
729       sprintf(txt_buf, "User %s not deactivated due to errors.", info[NAME]);
730       Put_message(txt_buf);
731     }
732   else if (YesNoQuestion("Also deactivate matching list and filesystem (y/n)",
733                          FALSE) == TRUE)
734     {
735       status = do_mr_query("get_list_info", 1, &(info[NAME]), StoreInfo,
736                            &elem);
737       if (status == MR_SUCCESS)
738         {
739           args = QueueTop(elem)->q_data;
740           free(args[L_ACTIVE]);
741           args[L_ACTIVE] = strdup("0");
742           FreeAndClear(&args[L_MODTIME], TRUE);
743           FreeAndClear(&args[L_MODBY], TRUE);
744           FreeAndClear(&args[L_MODWITH], TRUE);
745           SlipInNewName(args, strdup(args[L_NAME]));
746           if ((status = do_mr_query("update_list", CountArgs(args), args,
747                                     NULL, NULL)))
748             {
749               com_err(program_name, status, " updating list, "
750                       "not deactivating list or filesystem");
751               FreeInfo(args);
752               FreeQueue(elem);
753               return;
754             }
755           FreeInfo(args);
756           FreeQueue(elem);
757           elem = NULL;
758         }
759       else if (status != MR_NO_MATCH)
760         {
761           com_err(program_name, status, " getting list info, "
762                   "not deactivating list or filesystem");
763           return;
764         }
765
766       if ((status = do_mr_query("get_filesys_by_label", 1, &(info[NAME]),
767                                 StoreInfo, &elem)))
768         {
769           com_err(program_name, status, " getting filsys info, "
770                   "not deactivating filesystem");
771           return;
772         }
773       args = QueueTop(elem)->q_data;
774       free(args[FS_TYPE]);
775       args[FS_TYPE] = strdup("ERR");
776       free(args[FS_COMMENTS]);
777       args[FS_COMMENTS] = strdup("Locker disabled; call 3-1325 for help");
778       FreeAndClear(&args[FS_MODTIME], TRUE);
779       FreeAndClear(&args[FS_MODBY], TRUE);
780       FreeAndClear(&args[FS_MODWITH], TRUE);
781       SlipInNewName(args, strdup(args[FS_NAME]));
782       if ((status = do_mr_query("update_filesys", CountArgs(args), args,
783                                 NULL, NULL)))
784         {
785           com_err(program_name, status, " updating filesystem, "
786                   "not deactivating filesystem");
787           FreeInfo(args);
788           FreeQueue(elem);
789           return;
790         }
791       FreeInfo(args);
792       FreeQueue(elem);
793     }
794 }
795
796
797 /*      Function Name: DeactivateUser
798  *      Description: sets the user's status to 3.
799  *      Arguments: argc, argv - login name of the user in argv[1].
800  *      Returns: DM_NORMAL.
801  */
802
803 int DeactivateUser(int argc, char **argv)
804 {
805   struct mqelem *elem;
806
807   elem = GetUserInfo(LOGIN, argv[1], NULL);
808   QueryLoop(elem, NullPrint, RealDeactivateUser, "Deactivate user");
809
810   FreeQueue(elem);
811   return DM_NORMAL;
812 }
813
814
815 /* ------------------------- Top Menu ------------------------- */
816
817 /* DeleteUser() in delete.c */
818
819 /*      Function Name: DeleteUserByUid
820  *      Description: Deletes the user given a uid number.
821  *      Arguments: argc, argv - uid if user in argv[1].
822  *      Returns: DM_NORMAL.
823  *      NOTES: This just gets the username from the mr server
824  *             and performs a DeleteUser().
825  */
826
827 int DeleteUserByUid(int argc, char **argv)
828 {
829   int status;
830   struct mqelem *elem = NULL;
831   char **info;
832
833   if (!ValidName(argv[1]))
834     return DM_NORMAL;
835
836   if ((status = do_mr_query("get_user_account_by_uid", 1, argv + 1, StoreInfo,
837                             &elem)))
838     com_err(program_name, status, " in get_user_account_by_uid");
839
840   info = elem->q_data;
841   argv[1] = info[U_NAME];
842
843   DeleteUser(argc, argv);
844   return DM_NORMAL;
845 }
846
847 /* ------------------------- Show User Information ------------------------- */
848
849 /*      Function Name: ShowUserByLogin
850  *      Description: Shows user information given a login name.
851  *      Arguments: argc, argv - login name in argv[1].
852  *      Returns: DM_NORMAL
853  */
854
855 int ShowUserByLogin(int argc, char *argv[])
856 {
857   struct mqelem *top, *elem;
858
859   elem = top = GetUserInfo(LOGIN, argv[1], NULL);
860   Loop(elem, PrintUserInfo);
861
862   FreeQueue(top);
863   return DM_NORMAL;
864 }
865
866 /*      Function Name: RetrieveUserByName
867  *      Description: Show information on a user give fist and/or last name.
868  *      Arguments: argc, argv - argv[1] - first name.
869  *                              argv[2] - last name.
870  *      Returns: DM_NORMAL.
871  */
872
873 int ShowUserByName(int argc, char *argv[])
874 {
875   struct mqelem *top;
876   char buf[BUFSIZ];
877
878   top = GetUserInfo(BY_NAME, argv[1], argv[2]);
879
880   if (!top)             /* if there was an error then return. */
881     return DM_NORMAL;
882
883   if (!PromptWithDefault("Print full information, or just the names (f/n)?",
884                          buf, 2, "f"))
885     return DM_NORMAL;
886
887   switch (buf[0])
888     {
889     case 'F':
890     case 'f':
891       Loop(top, PrintUserInfo);
892       break;
893     case 'N':
894     case 'n':
895       Loop(top, PrintUserName);
896       break;
897     }
898
899   FreeQueue(top);
900   return DM_NORMAL;
901 }
902
903 /*      Function Name: ShowUserByClass
904  *      Description: Shows real and login names of all users in class.
905  *      Arguments: argc, argv - argv[1] contains the class.
906  *      Returns: none.
907  */
908
909 int ShowUserByClass(int argc, char **argv)
910 {
911   struct mqelem *top;
912
913   if (YesNoQuestion("This will take a long time.  Are you sure", 0) == FALSE)
914     return DM_NORMAL;
915   top = GetUserInfo(CLASS, argv[1], NULL);
916   Loop(top, PrintUserName);
917
918   FreeQueue(top);
919   return DM_NORMAL;
920 }
921
922
923 /*      Function Name: ShowUserById
924  *      Description: Shows user information given an ID number.
925  *      Arguments: argc, argv - ID number in argv[1].
926  *      Returns: DM_NORMAL
927  */
928
929 int ShowUserById(int argc, char *argv[])
930 {
931   struct mqelem *top, *elem;
932
933   elem = top = GetUserInfo(ID, argv[1], NULL);
934   Loop(elem, PrintUserInfo);
935
936   FreeQueue(top);
937   return DM_NORMAL;
938 }
939
940
941 /*      Function Name: GetKrbmap
942  *      Description: Shows user <-> Kerberos mappings
943  *      Arguments: argc, argv - argv[1] contains the user login name,
944  *              argv[2] contains the principal
945  *      Returns: none.
946  */
947
948 int GetKrbmap(int argc, char **argv)
949 {
950   int stat;
951   struct mqelem *elem = NULL, *top;
952   char buf[BUFSIZ];
953
954   if ((stat = do_mr_query("get_kerberos_user_map", 2, &argv[1],
955                           StoreInfo, &elem)))
956     {
957       com_err(program_name, stat, " in GetKrbMap.");
958       return DM_NORMAL;
959     }
960
961   top = elem = QueueTop(elem);
962   Put_message("");
963   while (elem)
964     {
965       char **info = elem->q_data;
966       sprintf(buf, "User: %-9s Principal: %s",
967               info[KMAP_USER], info[KMAP_PRINCIPAL]);
968       Put_message(buf);
969       elem = elem->q_forw;
970     }
971
972   FreeQueue(QueueTop(top));
973   return DM_NORMAL;
974 }
975
976
977 /*      Function Name: AddKrbmap
978  *      Description: Add a new user <-> Kerberos mapping
979  *      Arguments: argc, argv - argv[1] contains the user login name,
980  *              argv[2] contains the principal
981  *      Returns: none.
982  */
983
984 int AddKrbmap(int argc, char **argv)
985 {
986   int stat;
987
988   if (!strchr(argv[KMAP_PRINCIPAL + 1], '@'))
989     {
990       Put_message("Please specify a realm for the kerberos principal.");
991       return DM_NORMAL;
992     }
993   if ((stat = do_mr_query("add_kerberos_user_map", 2, &argv[1],
994                           NULL, NULL)))
995     {
996       com_err(program_name, stat, " in AddKrbMap.");
997       if (stat == MR_EXISTS)
998         Put_message("No user or principal may have more than one mapping.");
999     }
1000   return DM_NORMAL;
1001 }
1002
1003
1004 /*      Function Name: DeleteKrbmap
1005  *      Description: Remove a user <-> Kerberos mapping
1006  *      Arguments: argc, argv - argv[1] contains the user login name,
1007  *              argv[2] contains the principal
1008  *      Returns: none.
1009  */
1010
1011 int DeleteKrbmap(int argc, char **argv)
1012 {
1013   int stat;
1014
1015   if ((stat = do_mr_query("delete_kerberos_user_map", 2, &argv[1],
1016                           NULL, NULL)))
1017     com_err(program_name, stat, " in DeleteKrbMap.");
1018   return DM_NORMAL;
1019 }
1020
1021 int GetUserReservations(int argc, char **argv)
1022 {
1023   int stat;
1024   struct mqelem *elem = NULL, *top;
1025   char buf[BUFSIZ];
1026
1027   if ((stat = do_mr_query("get_user_reservations", 1, &argv[1],
1028                           StoreInfo, &elem)))
1029     {
1030       com_err(program_name, stat, " in GetUserReservations.");
1031       return DM_NORMAL;
1032     }
1033
1034   top = elem = QueueTop(elem);
1035   Put_message("");
1036   if (!elem)
1037     Put_message("No reservations for that user.");
1038   while (elem)
1039     {
1040       char **info = elem->q_data;
1041       sprintf(buf, "Reservation: %s", info[0]);
1042       Put_message(buf);
1043       elem = elem->q_forw;
1044     }
1045
1046   FreeQueue(QueueTop(top));
1047   return DM_NORMAL;  
1048 }
1049
1050 int AddUserReservation(int argc, char **argv)
1051 {
1052   int stat;
1053   char buf[BUFSIZ];
1054   
1055   switch (stat = do_mr_query("add_user_reservation", 2, &argv[1],
1056                              NULL, NULL))
1057     {
1058     case MR_SUCCESS:
1059       break;
1060     case MR_STRING:
1061       sprintf(buf, "The reservation %s is not valid.", argv[2]);
1062       Put_message(buf);
1063       PrintReservationTypes();
1064       break;
1065     default:
1066       com_err(program_name, stat, " in AddUserReservation.");
1067       break;
1068     }
1069   
1070   return DM_NORMAL;
1071 }
1072
1073 int DelUserReservation(int argc, char **argv)
1074 {
1075   int stat;
1076   char buf[BUFSIZ];
1077
1078   switch (stat = do_mr_query("delete_user_reservation", 2, &argv[1],
1079                      NULL, NULL))
1080     {
1081     case MR_SUCCESS:
1082       break;
1083     case MR_STRING:
1084       sprintf(buf, "The reservation %s is not valid.", argv[2]);
1085       Put_message(buf);
1086       PrintReservationTypes();
1087       break;
1088     default:
1089       com_err(program_name, stat, " in DelUserReservation.");
1090       break;
1091     }
1092   
1093   return DM_NORMAL;
1094 }
1095
1096 int GetUserByReservation(int argc, char **argv)
1097 {
1098   int stat;
1099   struct mqelem *elem = NULL, *top;
1100   char buf[BUFSIZ];
1101
1102   switch (stat = do_mr_query("get_user_by_reservation", 1, &argv[1],
1103                      StoreInfo, &elem))
1104     {
1105     case MR_SUCCESS:
1106       break;
1107     case MR_STRING:
1108       sprintf(buf, "The reservation %s is not valid.", argv[1]);
1109       Put_message(buf);
1110       PrintReservationTypes();
1111       return DM_NORMAL;
1112     default:
1113       com_err(program_name, stat, " in GetUserByReservation.");
1114       return DM_NORMAL;
1115     }
1116   
1117   top = elem = QueueTop(elem);
1118   Put_message("");
1119   while (elem)
1120     {
1121       char **info = elem->q_data;
1122       sprintf(buf, "User: %s", info[0]);
1123       Put_message(buf);
1124       elem = elem->q_forw;
1125     }
1126
1127   FreeQueue(QueueTop(top));
1128   return DM_NORMAL;  
1129 }
1130
1131 void PrintReservationTypes(void)
1132 {
1133   int stat;
1134   struct mqelem *elem = NULL, *top;
1135   char buf[BUFSIZ];
1136   char *qargs[2];
1137
1138   Put_message("Valid types of reservations are: ");
1139   Put_message("");
1140   qargs[0] = "*";
1141   qargs[1] = "RESERVE";
1142   qargs[2] = "*";
1143   if ((stat = do_mr_query("get_alias", 3, &qargs[0],
1144                           StoreInfo, &elem)))
1145     {
1146       com_err(program_name, stat, "in PrintReservationTypes.");
1147     }
1148   top = elem = QueueTop(elem);
1149   while (elem)
1150     {
1151       char **info = elem->q_data;
1152       sprintf(buf, "%s", info[2]);
1153       Put_message(buf);
1154       elem = elem->q_forw;
1155     }
1156
1157   FreeQueue(QueueTop(top));  
1158 }
1159
This page took 0.131373 seconds and 5 git commands to generate.