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