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