]> andersk Git - moira.git/blob - clients/moira/user.c
fixed some defaults and messages
[moira.git] / clients / moira / user.c
1 #if (!defined(lint) && !defined(SABER))
2   static char rcsid_module_c[] = "$Header$";
3 #endif lint
4
5 /*      This is the file user.c for the SMS Client, which allows a nieve
6  *      user to quickly and easily maintain most parts of the SMS database.
7  *      It Contains: Functions for manipulating user information.
8  *      
9  *      Created:        5/9/88
10  *      By:             Chris D. Peterson
11  *
12  *      $Source$
13  *      $Author$
14  *      $Header$
15  *      
16  *      Copyright 1988 by the Massachusetts Institute of Technology.
17  *
18  *      For further information on copyright and distribution 
19  *      see the file mit-copyright.h
20  */
21
22 #include <stdio.h>
23 #include <strings.h>
24 #include <sms.h>
25 #include <menu.h>
26
27 #include "mit-copyright.h"
28 #include "defs.h"
29 #include "f_defs.h"
30 #include "globals.h"
31 #include "infodefs.h"
32
33 #define LOGIN 0
34 #define UID   1
35 #define BY_NAME  2
36 #define CLASS 3
37
38 #define DEFAULT_SHELL "/bin/csh"
39 #define DEFAULT_CLASS "?"
40
41
42 /*      Function Name: UserState
43  *      Description: Convert a numeric state into a descriptive string.
44  *      Arguments: state value
45  *      Returns: pointer to statically allocated string.
46  */
47
48 static char *states[] = { "Not registered",
49                           "Active",
50                           "Half registered",
51                           "Marked for deletion",
52                           "Not registerable" };
53
54 static char *UserState(state)
55 int state;
56 {
57     if (state < 0 || state > 4)
58         return("Unknown");
59     return(states[state]);
60 }
61
62
63 /*      Function Name: PrintUserName
64  *      Description: Print name of a user.
65  *      Arguments: info - the information about a user.
66  *      Returns: none.
67  */
68
69 static void
70 PrintUserName(info)
71 char ** info;
72 {
73     char buf[BUFSIZ], print_buf[BUFSIZ];
74     sprintf(buf, "%s, %s %s", info[U_LAST], info[U_FIRST], info[U_MIDDLE]);
75     sprintf(print_buf, "%-40s User Name: %s", buf, info[U_NAME]);
76     Put_message(print_buf);
77 }
78
79 /*      Function Name: PrintUserInfo
80  *      Description: Prints Information about a user.
81  *      Arguments: info - an argument list with the user information
82  *                          in it.
83  *      Returns: none
84  */
85
86 static void
87 PrintUserInfo(info)
88 char ** info;
89 {
90     char name[BUFSIZ], buf[BUFSIZ];
91
92     sprintf(name, "%s, %s %s", info[U_LAST], info[U_FIRST], info[U_MIDDLE]);
93     sprintf(buf, "Login name: %-10s Full name: %s", info[U_NAME], name);
94     Put_message(buf);
95     sprintf(buf, "User id: %-13s Login shell %-15s Class: %s", 
96             info[U_UID], info[U_SHELL], info[U_CLASS]);
97     Put_message(buf);
98     sprintf(buf, "Account is: %-10s Encrypted MIT ID number: %s",
99             UserState(atoi(info[U_STATE])), info[U_MITID]);
100     Put_message(buf);
101     sprintf(buf, MOD_FORMAT, info[U_MODBY], info[U_MODTIME],info[U_MODWITH]);
102     Put_message(buf);
103 }
104
105 /*      Function Name: SetUserDefaults
106  *      Description: Sets the default values for add user.
107  *      Arguments: info - a blank user info array of char *'s.
108  *      Returns: args - the filled info structure.
109  */
110
111 static char **
112 SetUserDefaults(info)
113 char ** info;
114 {
115     info[U_NAME] = Strsave(UNIQUE_LOGIN);
116     info[U_UID] = Strsave(UNIQUE_UID);
117     info[U_SHELL] = Strsave(DEFAULT_SHELL);
118     info[U_LAST] = Strsave(DEFAULT_NONE);
119     info[U_FIRST] = Strsave(DEFAULT_NONE);
120     info[U_MIDDLE] = Strsave(DEFAULT_NONE);
121     info[U_STATE] = Strsave(DEFAULT_NO);
122     info[U_MITID] = Strsave(DEFAULT_NONE);
123     info[U_CLASS] = Strsave(DEFAULT_CLASS);
124     info[U_MODTIME] = info[U_MODBY] = info[U_MODWITH] = info[U_END] = NULL;
125     return(info);
126 }
127
128 /*      Function Name: AskUserInfo.
129  *      Description: This function askes the user for information about a 
130  *                   machine and saves it into a structure.
131  *      Arguments: info - a pointer the the structure to put the info into.
132  *                 flags - Flags asking us which info we want.
133  *      Returns: the args to pass to the query.
134  *      NOTES: the return args are not necessarily in the correct order to
135  *             use the #defined names (e.g args[UID] is not the uid anymore).
136  */
137
138 char **
139 AskUserInfo(info, name)
140 char ** info;
141 Bool name;
142 {
143     char temp_buf[BUFSIZ], *newname, *temp_ptr;
144
145     if (name) {
146         sprintf(temp_buf,"\nChanging Attributes of user %s.\n",info[U_NAME]);
147         Put_message(temp_buf);
148     }
149     if (name) {
150         newname = Strsave(info[U_NAME]);
151         GetValueFromUser("The new login name for this user", &newname);
152     }
153     else
154         GetValueFromUser("Login name for this user", &info[U_NAME]);
155
156     GetValueFromUser("User's UID", &info[U_UID]);
157     GetValueFromUser("User's shell", &info[U_SHELL]);
158     GetValueFromUser("User's last name", &info[U_LAST]);
159     GetValueFromUser("User's first name", &info[U_FIRST]);
160     GetValueFromUser("User's middle name", &info[U_MIDDLE]);
161     GetValueFromUser("User's status", &info[U_STATE]);
162     temp_ptr = Strsave(info[U_MITID]);
163     Put_message("User's MIT ID number (type a new unencrypted number, or keep same encryption)");
164     GetValueFromUser("", &temp_ptr);
165     if ( strcmp( temp_ptr, info[U_MITID] ) != 0) {
166         EncryptID(temp_buf, temp_ptr, info[U_FIRST], info[U_LAST]);
167         free(info[U_MITID]);
168         info[U_MITID] = Strsave(temp_buf);
169     }
170     free(temp_ptr);
171     GetTypeFromUser("User's MIT Year (class)", "class", &info[U_CLASS]);
172     
173     FreeAndClear(&info[U_MODTIME], TRUE);
174     FreeAndClear(&info[U_MODBY], TRUE);
175     FreeAndClear(&info[U_MODWITH], TRUE);
176
177 /* 
178  * Slide the newname into the #2 slot, this screws up all future references 
179  * to this list, since we slip the pointer into a info list it gets freed 
180  * when the rest of the list gets freed.
181  */
182     if (name)                   
183         SlipInNewName(info, newname);
184
185     return(info);
186 }
187
188 /*      Function Name: GetUserInfo
189  *      Description: Stores the user information in a queue.
190  *      Arguments: type - type of field given to get info, one of:
191  *                        LOGIN, UID, BY_NAME, CLASS.
192  *                 name1 - name of thing specified by type (wildcards okay)
193  *                 name2 - other name, only used in get user by first and last.
194  *                         (wildcards okay).
195  *      Returns: the first element of the queue containing the user info.
196  */
197
198 struct qelem *
199 GetUserInfo(type, name1, name2)
200 int type;
201 char *name1, *name2;
202 {
203     char * args[2];
204     register int status;
205     struct qelem * elem = NULL;
206
207     switch(type) {
208     case LOGIN:
209         args[0] = name1;
210         if ( (status = sms_query("get_user_by_login", 1, args,
211                                StoreInfo, (char *) &elem)) != 0) {
212             com_err(program_name, status, 
213                     " when attempting to get_user_by_login.");
214             return (NULL);               
215         }
216         break;
217     case UID:
218         args[0] = name1;
219         if ( (status = sms_query("get_user_by_uid", 1, args,
220                                StoreInfo, (char *) &elem)) != 0) {
221             com_err(program_name, status, 
222                     " when attempting to get_user_by_uid.");
223             return (NULL);      
224         }
225         break;
226     case BY_NAME:
227         args[0] = name1;
228         args[1] = name2;    
229         if ( (status = sms_query("get_user_by_name", 2, args,
230                                StoreInfo, (char *) &elem)) != 0) {
231             com_err(program_name, status, 
232                     " when attempting to get_user_by_name.");
233             return (NULL);      
234         }
235         break;
236     case CLASS:
237         args[0] = name1;
238         if ( (status = sms_query("get_user_by_class", 1, args,
239                                StoreInfo, (char *) &elem)) != 0) {
240             com_err(program_name, status, 
241                     " when attempting to get_user_by_class.");
242             return (NULL);      
243         }
244         break;
245     }
246     return( QueueTop(elem) );
247 }
248
249 /*      Function Name: AddNewUser
250  *      Description: Adds a new user to the database.
251  *      Arguments: none.
252  *      Returns: DM_NORMAL.
253  */
254
255 /* ARGSUSED */
256 int
257 AddNewUser()
258 {
259     register int status;
260     char ** args, *info[MAX_ARGS_SIZE];
261
262     args = AskUserInfo(SetUserDefaults(info), FALSE);
263     if ( (status = sms_query("add_user", CountArgs(args), 
264                              args, Scream, (char *) NULL)) != SMS_SUCCESS)
265         com_err(program_name, status, " in add_user");
266     else
267         Put_message("New user added to database.");
268     FreeInfo(args);
269     return(DM_NORMAL);
270 }
271
272
273 /*      Function Name: GetLoginName
274  *      Description: Asks the user for a login name and reserves
275  *                   it with kerberous.
276  *      Arguments: none.
277  *      Returns: a malloced login name for the user.
278  */
279
280 static char *
281 GetLoginName()
282 {
283     char name[BUFSIZ];
284
285     Prompt_input("Login name for this user? ", name, BUFSIZ);
286     
287     Put_message(
288               "KERBEROS code not added, did not reserve name with kerberos.");
289
290     return(Strsave(name));
291 }
292
293
294 /*      Function Name: ChooseUser
295  *      Description: Choose a user from a list and return the uid.
296  *      Arguments: top - a queue of user information.
297  *      Returns: uid - the malloced uid of the user that was chosen.
298  */
299
300 static char *
301 ChooseUser(elem)
302 struct qelem * elem;
303 {
304     while (elem != NULL) {
305         char ** info = (char **)  elem->q_data;
306         PrintUserInfo(info);
307         switch(YesNoQuitQuestion("Is this the user you want (y/n/q)", FALSE)) {
308         case TRUE:
309             return(Strsave(info[U_UID]));
310         case FALSE:
311             break;
312         default:                /* quit or ^C. */
313             return(NULL);
314         }
315         elem = elem->q_forw;
316     }
317     return(NULL);
318 }
319
320 /*      Function Name: GetUidNumberFromName
321  *      Description: Gets the users uid number, from the name.
322  *      Arguments: none.
323  *      Returns: uid - a malloced string containing the uid.
324  */
325
326 static char *
327 GetUidNumberFromName()
328 {
329     char *args[5], *uid, first[BUFSIZ], last[BUFSIZ];
330     register int status;
331     struct qelem * top = NULL;
332     
333     Prompt_input("First Name: ", first, BUFSIZ);
334     Prompt_input("Last  Name: ", last, BUFSIZ);
335
336     args[0] = first;
337     args[1] = last;
338     
339     switch (status = sms_query("get_user_by_name", 2, args,
340                                StoreInfo, (char *) &top)) {
341     case SMS_SUCCESS:
342         break;
343     case SMS_NO_MATCH:
344         Put_message("There is no user in the database with that name.");
345         return(NULL);
346     default:
347         com_err(program_name, status, " in get_user_by_name.");
348         return(NULL);
349     }
350     
351     top = QueueTop(top);
352     if (QueueCount(top) == 1) /* This is a unique name. */ {
353         char ** info = (char **) top->q_data;
354         Put_message("User ID Number retrieved for the user: ");
355         Put_message("");
356         PrintUserName(info);
357         uid = Strsave(info[U_UID]);
358         FreeQueue(top);
359         return(Strsave(uid));
360     }
361
362     Put_message("That name is not unique, choose the user that you want.");
363     uid = ChooseUser(top);
364     FreeQueue(top);
365     return(uid);
366 }
367
368 /*      Function Name: SetUserPassword
369  *      Description: Set the new kerberos password for this user.
370  *      Arguments: name - kerberos principle name for this user, (login name).
371  *      Returns: none.
372  */
373
374 static void
375 SetUserPassword(name)
376 char * name;
377 {
378     name = name;                        /* make saber happy. */
379     Put_message("Kerberos password not changed, code non-existant.");
380     /* clever message to call account_admin, if this fails. */
381 }
382
383 /*      Function Name:  GiveBackLogin
384  *      Description: Gives back previously reserved kerberous principle.
385  *      Arguments: name - principle to give back.
386  *      Returns: void.
387  */
388
389 static void
390 GiveBackLogin(name)
391 char * name;
392 {
393     name = name;                        /* make saber happy. */
394     Put_message("kerberos code not implimented, name not given back.");
395     /* send mail to db maintainer if this fails. */
396 }
397
398 /*      Function Name: RegisterUser
399  *      Description: This function registers a user.
400  *      Arguments: none.
401  *      Returns: DM_NORMAL.
402  */
403
404 int
405 RegisterUser()
406 {
407     char * args[MAX_ARGS_SIZE];
408     char *login, *fstype = NULL;
409     char temp_buf[BUFSIZ];
410     register int status;
411     
412     Put_message("This function has NO kerberos support, so stange things");
413     Put_message("may happen if you use it to register a user.");
414
415     switch (YesNoQuestion("Do you know the users UID Number (y/n)", FALSE)) {
416     case TRUE:
417         Prompt_input("What is the UID number of the user? ", temp_buf, BUFSIZ);
418         args[0] = Strsave(temp_buf);
419         break;
420     case FALSE:
421         if ( (args[0] = GetUidNumberFromName()) == NULL)
422             return(DM_NORMAL);
423         break;
424     default:
425         return(DM_NORMAL);
426     }
427
428     if ( ((login = args[1] = GetLoginName()) == NULL) ||
429         ( GetFSTypes(&fstype) == SUB_ERROR ) ) {
430         FreeInfo(args);    /* This work because the NULL temination is ok. */
431         return(DM_NORMAL);
432     }
433     args[2] = fstype;
434     args[3] = NULL;
435     
436     switch (status = sms_query("register_user", CountArgs(args),
437                                args, Scream, (char *) NULL)) {
438     case SMS_SUCCESS:
439         sprintf(temp_buf, "User %s successfully registered.", login);
440         Put_message(temp_buf);
441         SetUserPassword(login);
442         break;
443     case SMS_IN_USE:
444         GiveBackLogin(login);
445         sprintf(temp_buf, "The username %s is already in use.", login);
446         Put_message(temp_buf);
447         break;
448     default:
449         com_err(program_name, status, " in register_user");
450         break;
451     }
452     FreeInfo(args);
453     return(DM_NORMAL);
454 }
455
456 /*      Function Name: RealUpdateUser
457  *      Description: actuall updates the user information.
458  *      Arguments: info - all current information for the user fields.
459  *                 junk - an UNUSED boolean.
460  *      Returns: none.
461  */
462
463 /* ARGSUSED */
464 static void
465 RealUpdateUser(info, junk)
466 char ** info;
467 Bool junk;
468 {
469     register int status;
470     char error_buf[BUFSIZ];
471     char ** args = AskUserInfo(info, TRUE);
472     
473     if ( (status = sms_query("update_user", CountArgs(args), 
474                              args, Scream, (char *) NULL)) != SMS_SUCCESS) {
475         com_err(program_name, status, " in ModifyFields");
476         sprintf(error_buf, "User %s not updated due to errors.", info[NAME]);
477         Put_message(error_buf);
478     }
479 }
480
481 /*      Function Name: UpdateUser
482  *      Description: Modify some of the information about a user.
483  *      Arguments: argc, argv - login name of the user in argv[1].
484  *      Returns: DM_NORMAL.
485  */
486
487 /* ARGSUSED */
488 int
489 UpdateUser(argc, argv)
490 int argc;
491 char **argv;
492 {
493     struct qelem * elem;
494
495     elem = GetUserInfo(LOGIN, argv[1], (char *) NULL);
496     QueryLoop(elem, NullPrint, RealUpdateUser, "Update the user");
497     
498     FreeQueue(elem);
499     return(DM_NORMAL);
500 }
501
502 /*      Function Name: RealDeactivateUser
503  *      Description: sets the user's status to 3.
504  *      Arguments: info - all current information for the user fields
505  *                 one_item - indicates the user hasn't been queried yet
506  *      Returns: none.
507  */
508
509 static void
510 RealDeactivateUser(info, one_item)
511 char ** info;
512 Bool one_item;
513 {
514     register int status;
515     char txt_buf[BUFSIZ];
516     char * qargs[2];
517
518     if (one_item) {
519         sprintf(txt_buf, "Deactivate user %s (y/n)", info[NAME]);
520         if (!YesNoQuestion(txt_buf, 2))
521             return;
522     }
523
524     qargs[0] = info[NAME];
525     qargs[1] = "3";
526     if ((status = sms_query("update_user_status", 2, qargs, Scream,
527                             (char *) NULL)) != SMS_SUCCESS) {
528         com_err(program_name, status, " in update_user_status");
529         sprintf(txt_buf, "User %s not deactivated due to errors.", info[NAME]);
530         Put_message(txt_buf);
531     }
532 }
533
534
535 /*      Function Name: DeactivateUser
536  *      Description: sets the user's status to 3.
537  *      Arguments: argc, argv - login name of the user in argv[1].
538  *      Returns: DM_NORMAL.
539  */
540
541 /* ARGSUSED */
542 int
543 DeactivateUser(argc, argv)
544 int argc;
545 char **argv;
546 {
547     struct qelem * elem;
548
549     elem = GetUserInfo(LOGIN, argv[1], (char *) NULL);
550     QueryLoop(elem, NullPrint, RealDeactivateUser, "Deactivate user");
551     
552     FreeQueue(elem);
553     return(DM_NORMAL);
554 }
555
556
557 /* ------------------------- Top Menu ------------------------- */
558
559 /* DeleteUser() in delete.c */
560
561 /*      Function Name: DeleteUserByUid
562  *      Description: Deletes the user given a uid number.
563  *      Arguments: argc, argv - uid if user in argv[1].
564  *      Returns: DM_NORMAL.
565  *      NOTES: This just gets the username from the sms server 
566  *             and performs a DeleteUser().
567  */
568
569 int
570 DeleteUserByUid(argc, argv)
571 int argc;
572 char **argv;
573 {
574     int status;
575     struct qelem *elem = NULL;
576     char ** info;
577
578     if(!ValidName(argv[1]))
579         return(DM_NORMAL);
580     
581     if ( (status = sms_query("get_user_by_uid", 1, argv+1, StoreInfo,
582                              (char * ) &elem)) != SMS_SUCCESS)
583         com_err(program_name, status, " in get_user_by_uid");
584     
585     info = (char **) elem->q_data;
586     argv[1] = info[U_NAME];
587
588     (void) DeleteUser(argc, argv);
589     return(DM_NORMAL);
590
591
592 /* ------------------------- Show User Information ------------------------- */
593
594 /*      Function Name: ShowUserByLogin
595  *      Description: Shows user information given a login name.
596  *      Arguments: argc, argv - login name in argv[1].
597  *      Returns: DM_NORMAL
598  */
599
600 /* ARGSUSED */
601 int
602 ShowUserByLogin(argc, argv)
603 int argc;
604 char *argv[];
605 {
606     struct qelem *top, *elem;
607
608     elem = top = GetUserInfo(LOGIN, argv[1], (char *) NULL);
609     Loop(elem, PrintUserInfo);
610
611     FreeQueue(top);
612     return (DM_NORMAL);
613 }
614
615 /*      Function Name: RetrieveUserByName
616  *      Description: Show information on a user give fist and/or last name.
617  *      Arguments: argc, argv - argv[1] - first name.
618  *                              argv[2] - last name.
619  *      Returns: DM_NORMAL.
620  */
621
622 /* ARGSUSED */
623 int
624 ShowUserByName(argc, argv)
625 int argc;
626 char *argv[];
627 {
628     struct qelem *top;
629     char buf[BUFSIZ];
630
631     top = GetUserInfo(BY_NAME, argv[1], argv[2]);
632
633     if (top == NULL)            /* if there was an error then return. */
634         return(DM_NORMAL);
635
636     if (!PromptWithDefault("Print full information, or just the names (f/n)?",
637                            buf, 2, "f"))
638         return(DM_NORMAL);
639
640     switch(buf[0]) {
641     case 'F':
642     case 'f':
643         Loop(top, PrintUserInfo);
644         break;
645     case 'N':
646     case 'n':
647         Loop(top, PrintUserName);
648         break;
649     }
650     
651     FreeQueue(top);
652     return (DM_NORMAL);
653 }
654
655 /*      Function Name: ShowUserByClass
656  *      Description: Shows real and login names of all users in class.
657  *      Arguments: argc, argv - argv[1] contains the class.
658  *      Returns: none.
659  */
660
661 /* ARGSUSED */
662 int
663 ShowUserByClass(argc, argv)
664 int argc;
665 char **argv;
666 {
667     struct qelem *top;
668
669     top = GetUserInfo(CLASS, argv[1], (char *) NULL);
670     Loop(top, PrintUserName);
671
672     FreeQueue(top);
673     return (DM_NORMAL);
674 }
675
676 /*
677  * Local Variables:
678  * mode: c
679  * c-indent-level: 4
680  * c-continued-statement-offset: 4
681  * c-brace-offset: -4
682  * c-argdecl-indent: 4
683  * c-label-offset: -4
684  * End:
685  */
This page took 0.223445 seconds and 5 git commands to generate.