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