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