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