]> andersk Git - moira.git/blob - clients/moira/user.c
This version has listmaint, clustermaint, and attachmaint working
[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 <ctype.h>
25 #include <sms.h>
26 #include <menu.h>
27
28 #include "mit-copyright.h"
29 #include "allmaint.h"
30 #include "allmaint_funcs.h"
31 #include "globals.h"
32 #include "infodefs.h"
33
34 #define LOGIN 0
35 #define UID   1
36 #define BY_NAME  2
37 #define QUOTA 3
38 #define CLASS 4
39
40 static void PrintQuota();       /* prints Quota info. */
41 static void PrintUserInfo();    /* prints User info. */
42 static int PrintPOBoxes();      /* prints PO Box information. */
43
44 /*      Function Name: AskUserInfo.
45  *      Description: This function askes the user for information about a 
46  *                   machine and saves it into a structure.
47  *      Arguments: info - a pointer the the structure to put the info into.
48  *                 flags - Flags asking us which info we want.
49  *      Returns: the args to pass to the query.
50  *      NOTES: the return args are not necessarily in the correct order to
51  *             use the #defined names (e.g args[UID] is not the uid anymore).
52  */
53
54 char **
55 AskUserInfo(info, name)
56 char ** info;
57 Bool name;
58 {
59     char temp_buf[BUFSIZ], *newname;
60
61     sprintf(temp_buf,"\nChanging Attributes of user %s.\n",info[U_NAME]);
62     Put_message(temp_buf);
63
64     if (name) {
65         newname = Strsave(info[U_NAME]);
66         GetValueFromUser("The new login name for this user.", &newname);
67     }
68     GetValueFromUser("User's UID:", &info[U_UID]);
69     GetValueFromUser("User's shell:", &info[U_SHELL]);
70     GetValueFromUser("User's last name:", &info[U_LAST]);
71     GetValueFromUser("User's first name:", &info[U_FIRST]);
72     GetValueFromUser("User's middle name:", &info[U_MIDDLE]);
73     GetValueFromUser("User's status:", &info[U_STATE]);
74     GetValueFromUser("User's MIT ID number:", &info[U_MITID]);
75     RemoveHyphens(info[U_MITID]); /* zap'em */
76     GetValueFromUser("User's MIT Year (class):", &info[U_CLASS]);
77     
78     FreeAndClear(&info[U_MODTIME], TRUE);
79     FreeAndClear(&info[U_MODBY], TRUE);
80     FreeAndClear(&info[U_MODWITH], TRUE);
81
82 /* 
83  * Slide the newname into the #2 slot, this screws up all future references 
84  * to this list, since we slip the pointer into a info list it gets freed 
85  * when the rest of the list gets freed.
86  */
87     if (name)                   
88         SlipInNewName(info, newname);
89
90     return(info);
91 }
92
93 /*      Function Name: GetUserInfo
94  *      Description: Stores the user information in a queue.
95  *      Arguments: type - type of field given to get info, one of:
96  *                        LOGIN, UID, BY_NAME, CLASS.
97  *                 name1 - name of thing specified by type (wildcards okay)
98  *                 name2 - other name, only used in get user by first and last.
99  *                         (wildcards okay).
100  *      Returns: the first element of the queue containing the user info.
101  */
102
103 struct qelem *
104 GetUserInfo(type, name1, name2)
105 int type;
106 char *name1, *name2;
107 {
108     char * args[2];
109     register int status;
110     struct qelem * elem = NULL;
111
112     switch(type) {
113     case LOGIN:
114         args[0] = name1;
115         if ( (status = sms_query("get_user_by_login", 1, args,
116                                StoreInfo, (char *) &elem)) != 0) {
117             com_err(program_name, status, 
118                     " when attempting to get_use_by_login.");
119             return (NULL);               
120         }
121         break;
122     case UID:
123         args[0] = name1;
124         if ( (status = sms_query("get_user_by_uid", 1, args,
125                                StoreInfo, (char *) &elem)) != 0) {
126             com_err(program_name, status, 
127                     " when attempting to get_use_by_uid.");
128             return (NULL);      
129         }
130         break;
131     case BY_NAME:
132         args[0] = name1;
133         args[1] = name2;    
134         if ( (status = sms_query("get_user_by_name", 1, args,
135                                StoreInfo, (char *) &elem)) != 0) {
136             com_err(program_name, status, 
137                     " when attempting to get_use_by_name.");
138             return (NULL);      
139         }
140         break;
141     case CLASS:
142         args[0] = name1;
143         if ( (status = sms_query("get_user_by_class", 1, args,
144                                StoreInfo, (char *) &elem)) != 0) {
145             com_err(program_name, status, 
146                     " when attempting to get_use_by_class.");
147             return (NULL);      
148         }
149         break;
150     case QUOTA:
151         args[0] = name1;
152         if ( (status = sms_query("get_nquotas_by_user", 1, args,
153                                StoreInfo, (char *) &elem)) != 0) {
154             com_err(program_name, status, " in get_nfs_quotas_by_user");
155             return (DM_NORMAL);
156         }
157         break;
158     }
159     return( QueueTop(elem) );
160 }
161
162 /* -------------------------- Change Menu -------------------------- */
163
164 /*      Function Name: ModifyUser
165  *      Description: Modify some of the information about a user.
166  *      Arguments: argc, argv - login name of the user in argv[1].
167  *      Returns: DM_NORMAL.
168  */
169
170 /* ARGSUSED */
171 int
172 ModifyUser(argc, argv)
173 int argc;
174 char **argv;
175 {
176     int status;
177     char *temp_buf, error_buf[BUFSIZ];
178     struct qelem * elem, * local;
179
180     local = elem = GetUserInfo(LOGIN, argv[1], (char *) NULL);
181
182     while (local != NULL) {
183         char ** info = (char **) local->q_data;
184         char ** args = AskUserInfo(info, TRUE);
185
186         if ( (status = sms_query("update_user", CountArgs(args), 
187                                  args, Scream, NULL)) != 0) {
188             com_err(program_name, status, " in ModifyFields");
189             if (local->q_forw == NULL)
190                 temp_buf = "";
191             else
192                 temp_buf = ", Continuing to next user";
193             sprintf(error_buf,"User %s not updated due to error%s.",
194                     info[NAME], temp_buf);
195             Put_message(error_buf);
196         }
197         local = local->q_forw;
198     }
199     FreeQueue(elem);
200     return(DM_NORMAL);
201 }
202
203
204 /*      Function Name: POType
205  *      Description: Asks the SMS server if it is of type pop, of
206  *                   of type local. If neither, we assume that it's 
207  *                   of type foreign. 
208  *      Arguments: machine - a canonicalized machine name, 
209  *      Returns: the PO Type, one of: pop, local, foreign.
210  */
211
212 char *
213 POType(machine)
214 char *machine;
215 {
216     int status;
217     char * type;
218     struct qelem *top, *elem = NULL;
219
220     type = "pop";
221     status = sms_query("get_server_locations", 1, &type,
222                        StoreInfo, &elem);
223     if (status && (status != SMS_NO_MATCH)) {
224         com_err(program_name, status, (char *) NULL);
225         return( (char *) NULL);
226     }
227
228     top = elem = QueueTop(elem);
229     while (elem != NULL) {
230         char ** info = (char **) elem->q_data;
231         if (strcmp (info[1], machine) == 0) {
232             FreeQueue(top);
233             return( Strsave("POP") );
234         }
235         elem = elem->q_forw;
236     }
237     FreeQueue(top);
238     return ( Strsave("SMTP") );
239 }
240
241 /*      Function Name: ChangeUserPOBox
242  *      Description: Changes The P.O. Box for a user.
243  *      Arguments: argc, argv - the login name of the user in argv[1].
244  *      Returns: DM_NORMAL.
245  */
246
247 /*ARGSUSED*/
248 int
249 ChangeUserPOBox(argc, argv)
250 int argc;
251 char **argv;
252 {
253     register int status;
254     struct qelem * poqueue, *local;
255     char *type, buf[BUFSIZ], *pohost;
256     static char *po[4];
257     poqueue = NULL;
258
259     sprintf(buf,"Current pobox for user %s: \n", argv[1]); 
260     Put_message(buf);
261     status = sms_query("get_pobox", 1, argv + 1, PrintPOBoxes, NULL);
262     if (status != SMS_NO_MATCH && status != 0) {
263         com_err(program_name, status, "in ChangeUserPOBox.");
264         return(DM_NORMAL);
265     }
266     else if (status == SMS_NO_MATCH) 
267         Put_message("This user has no P.O. Box.");
268     
269     if (YesNoQuestion("Shall we use the least loaded Post Office?", TRUE)) {
270         po[0] = "pop";
271         po[1] = "*";
272         if ( status = sms_query ("get_server_host_info", 2, po,
273                                  StoreInfo, (char *) &poqueue) != 0) {
274             com_err(program_name, status, 
275                     " in ChangeUserPOBox (get_server_host_info).");
276             return(DM_NORMAL);
277         }
278         local = poqueue;
279         while (local != NULL) {
280             char ** args = (char **) local->q_data;
281             int new_space, old_space = -1 ;
282             if ( !isdigit(*args[6]) || !isdigit(*args[7]) )
283                 Put_message(
284                     "non-digit value in server_host_info, this is a bug.");
285             else {
286                 new_space = atoi(argv[7]) - atoi(args[6]);
287                 if ( (new_space < old_space) || (old_space == -1) ) {
288                     old_space = new_space;
289                     strcpy(buf, args[1]);
290                 }
291             }
292             local = local->q_forw;
293         }
294         pohost = Strsave(buf);
295         FreeQueue(poqueue);
296         type = "POP";
297         (void) sprintf(buf, "The Post Office %s was chosen.",
298                        pohost);
299         Put_message(buf);
300     }
301     else if( (Prompt_input("Which Machine for Post Office?", 
302                            buf, BUFSIZ)) ) {
303         if ( (pohost = CanonicalizeHostname(buf)) == NULL) {
304             Put_message("\nNameserver doesn't know that machine, sorry.");
305             return (DM_NORMAL);
306         }
307         type = POType(pohost); 
308     }
309     
310     sprintf(buf, "%s %s's %s %s?", "Are you sure that you want to replace all",
311             argv[1], "P.O. Boxes\n with ** ONE ** on the machine", pohost);
312
313     if(Confirm(buf)) {
314         po[0] = argv[1];
315         po[1] = type;
316         po[2] = pohost;
317         po[3] = po[0];
318         if (status = sms_query("set_pobox", 4, po, Scream, NULL) != 0 )
319             com_err(program_name, status, " in ChangeUserPOBox");
320     } else 
321         Put_message("Operation Aborted.");
322
323     return (DM_NORMAL);
324 }
325
326 /* ------------------------- Top Menu ------------------------- */
327
328 /* delete user in delete.c */
329
330 /*      Function Name: DeleteUserByUid
331  *      Description: Deletes the user given a uid number.
332  *      Arguments: argc, argv - uid if user in argv[1].
333  *      Returns: DM_NORMAL.
334  */
335
336 /*ARGSUSED*/
337 int
338 DeleteUserByUid(argc, argv)
339 int argc;
340 char **argv;
341 {
342     int status;
343
344     if (Confirm("Are you sure you want to remove this user"))
345         if ( (status = sms_query("delete_user_by_uid", 1, argv+1, Scream,
346                                (char * ) NULL)) != 0)
347             com_err(program_name, status, " in DeleteUserByUid");
348
349     return(DM_NORMAL);
350
351
352 /* ------------------------- Show Quota Info ------------------------- */
353
354 /*      Function Name: ShowDefaultQuota
355  *      Description: This prints out a default quota for the system.
356  *      Arguments: none
357  *      Returns: DM_NORMAL.
358  */
359
360 int
361 ShowDefaultQuota()
362 {
363     int status;
364     static char *val[] = {"def_quota"};
365
366     if (status = sms_query("get_value", 1, val, Print, (char *) NULL) != 0)
367         com_err(program_name, status, " in ShowDefaultQuota");
368
369     return (DM_NORMAL);
370 }
371
372 /*      Function Name: ShowUserQuota
373  *      Description: Shows the quota of a user.
374  *      Arguments: argc, argv - users login name is argv[1].
375  *      Returns: DM_NORMAL
376  */
377
378 /*ARGSUSED*/
379 int
380 ShowUserQuota(argc, argv)
381 int argc;
382 char **argv;
383 {
384     struct qelem *elem, *top;
385     top = elem = GetUserInfo(QUOTA, argv[1], (char *) NULL);
386     
387     while (elem != NULL) {
388         char ** info = (char **) elem->q_data;
389         PrintQuota(info);
390         elem = elem->q_forw;
391     }
392     FreeQueue(top);
393     return (DM_NORMAL);
394 }
395
396 /*      Function Name: ChangeDefaultQuota
397  *      Description: Changes the System Wide default quota.
398  *      Arguments: argc, argv - New quota in argv[1].
399  *      Returns: DM_NORMAL.
400  */
401
402 /*ARGSUSED*/
403 int
404 ChangeDefaultQuota(argc, argv)
405 int argc;
406 char *argv[];
407 {
408     char buf[BUFSIZ];
409     int status;
410     static char *newval[] = {
411         "update_value", "def_quota", NULL,
412     };
413
414     sprintf(buf,"%s%s",
415             "Are you sure that you want to change the default quota\n",
416             "for all new users? (y/n) ");
417     if(!Confirm(buf)) {
418         newval[2] = argv[1];
419         if (status = sms_query("update_value", 3, newval, Scream, NULL) != 0)
420             com_err(program_name, status, " in update_value");
421     }
422     else
423         Put_message("Quota not changed.");
424
425     return (DM_NORMAL);
426 }
427
428 /* ---------------------- User Locker Manipultation -------------------- */
429
430 /*      Function Name: AddUserLocker
431  *      Description: Add a new locker for a user.
432  *      Arguments: arc, argv - 
433  *                             argv[1] login name of user.
434  *                             argv[2] server host name.
435  *                             argv[3] Directory on host.
436  *                             argv[4] quota in Kb.
437  *      Returns: DM_NORMAL.
438  */
439
440 /*ARGSUSED*/
441 int
442 AddUserLocker(argc, argv)
443 int argc;
444 char **argv;
445 {
446     int status;
447     char *args[4];
448
449     args[0] = argv[1];
450     args[2] = argv[3];
451     args[3] = argv[4];
452     
453     args[1] = CanonicalizeHostname(argv[2]);
454     if (args[1] == (char *)NULL) {
455         Put_message("Could not canonicalize hostname; continuing..");
456         args[1] = argv[2];
457     }
458     
459     if (status = sms_query("add_locker", 4, args, Scream, NULL) != 0)
460         com_err(program_name, status, " in add_user_locker");
461
462     return(DM_NORMAL);
463 }
464
465 /* needs to be fixed - CDP 6/10/88 */
466
467 /*      Function Name: DeleteUserLocker
468  *      Description: Deletes a locker - BOOM.
469  *      Arguments: arc, argv - the name of the locker in argv[1]/
470  *      Returns: DM_NORMAL.
471  */
472
473 /*ARGSUSED*/
474 int
475 DeleteUserLocker(argc, argv)
476 int argc;
477 char **argv;
478 {
479     int status;
480     if (status = sms_query("delete_locker", 1, argv + 1,
481                            Scream, (char *)NULL) != 0) 
482             com_err(program_name, status, " in delete_locker");
483
484     return(DM_NORMAL);
485 }
486
487 /*      Function Name: ChangeUserQuota
488  *      Description: This function allows all quotas to be updated for a user.
489  *      Arguments: arg, argv - the name of the user in argv[1].
490  *      Returns: DM_NORMAL.
491  */
492
493 /* ARGSUSED */
494 int
495 ChangeUserQuota(argc, argv)
496 int argc;
497 char *argv[];
498 {
499     int status;
500     char error_buf[BUFSIZ];
501     struct qelem *elem, *local;
502     
503     elem = GetUserInfo(QUOTA, argv[1], (char *) NULL);
504
505     local = elem;
506     while (local != NULL) {
507         char **info;
508         info = (char **) local->q_data;
509         PrintQuota(info);
510         GetValueFromUser("New quota (in KB): ", &info[Q_QUOTA]);
511         
512         if (status = sms_query("update_nfs_quota", 3, info,
513                                Scream, (char *) NULL) != 0) {
514             com_err(program_name, status, " in update_nfs_quota");
515             sprintf(error_buf,"Could not perform quota change on %s",
516                     info[Q_FILESYS]); 
517             Put_message(error_buf);
518         }
519         local = local->q_forw;
520     }
521     FreeQueue(elem);
522     return (DM_NORMAL);
523 }
524
525 /*      Function Name: ShowUserByLogin
526  *      Description: Shows user information given a login name.
527  *      Arguments: argc, argv - login name in argv[1].
528  *      Returns: DM_NORMAL
529  */
530
531 /* ARGSUSED */
532 int
533 ShowUserByLogin(argc, argv)
534 int argc;
535 char *argv[];
536 {
537     struct qelem *top, *elem;
538
539     elem = top = GetUserInfo(LOGIN, argv[1], (char *) NULL);
540     while (elem != NULL) {
541         PrintUserInfo( (char **) elem->q_data, FALSE);
542         elem = elem->q_forw;
543     }
544
545     FreeQueue(top);
546     return (DM_NORMAL);
547 }
548
549 /*      Function Name: RetrieveUserByName
550  *      Description: Show information on a user give fist and/or last name.
551  *      Arguments: argc, argv - argv[1] - first name.
552  *                              argv[2] - last name.
553  *      Returns: DM_NORMAL.
554  */
555
556 /* ARGSUSED */
557 int
558 ShowUserByName(argc, argv)
559 int argc;
560 char *argv[];
561 {
562     struct qelem *top, *elem;
563     char buf;
564
565     elem = top = GetUserInfo(BY_NAME, argv[1], argv[2]);
566
567     if (!PromptWithDefault("Print full information, or just the names (F/N)?",
568                            &buf, 1, "F"))
569         return(DM_NORMAL);
570
571     while (elem != NULL) {
572         switch(buf) {
573         case 'F':
574         case 'f':
575             PrintUserInfo( (char **) elem->q_data, FALSE);
576             break;
577         case 'N':
578         case 'n':
579             PrintUserInfo( (char **) elem->q_data, TRUE);
580             break;
581         }
582         elem = elem->q_forw;
583     }
584
585     FreeQueue(top);
586     return (DM_NORMAL);
587 }
588
589 /*      Function Name: ShowUserByClass
590  *      Description: Shows real and login names of all users in class.
591  *      Arguments: argc, argv - argv[1] contains the class.
592  *      Returns: none.
593  */
594
595 /* ARGSUSED */
596 int
597 ShowUserByClass(argc, argv)
598 int argc;
599 char **argv;
600 {
601     struct qelem *top, *elem;
602
603     elem = top = GetUserInfo(CLASS, argv[1], (char *) NULL);
604
605     while (elem != NULL) {
606         PrintUserInfo( (char **) elem->q_data, TRUE);
607         elem = elem->q_forw;
608     }
609
610     FreeQueue(top);
611     return (DM_NORMAL);
612 }
613
614
615 /*      Function Name: PrintQuota
616  *      Description: Prints a users quota information.
617  *      Arguments: info - a pointer to the quota information:
618  *      Returns: none.
619  */
620
621 static void
622 PrintQuota(info)
623 char ** info;
624 {
625     char buf[BUFSIZ];
626
627     sprintf(buf, "Machine: %s\t\tDirectory: %s\t\tQuota: %s",
628                    info[Q_MACHINE], info[Q_DIRECTORY], info[Q_QUOTA]);
629     Put_message(buf);
630 }
631
632 /*      Function Name: PrintPOBoxes
633  *      Description: Yet another specialized print function.
634  *      Arguments: argc, argv - 
635  *                             argv[0] - login name.
636  *                             argv[1] - type.
637  *                             argv[2] - machine.
638  *                             argv[3] - box name.
639  *                 junk.  - NOT USED
640  *      Returns: SMS_CONT
641  */
642
643 /* ARGSUSED */
644 static int
645 PrintPOBoxes(argc, argv, junk)
646 int argc;
647 char **argv;
648 char * junk;
649 {
650     char buf[BUFSIZ];
651     /* no newline 'cause Put_message adds one */
652
653     (void) sprintf(buf, "Address: %s@%s\t\tType: %s", argv[PO_BOX],
654                    argv[PO_MACHINE], argv[PO_TYPE]);
655     (void) Put_message(buf);
656
657     return (SMS_CONT);
658 }
659
660 /*      Function Name: PrintUserInfo
661  *      Description: Prints Information about a user.
662  *      Arguments: info - an argument list with the user information
663  *                          in it.
664  *                 name_only - if TRUE then print only the users name.
665  *      Returns: none
666  */
667
668 static void
669 PrintUserInfo(info, name_only)
670 char ** info;
671 Bool name_only;
672 {
673     char buf[BUFSIZ];
674
675     if (name_only) {
676         sprintf(buf, "%s, %s %s", info[U_LAST],
677                 info[U_FIRST], info[U_MIDDLE]);
678         sprintf(buf, "%-40s/tUser Name: %s", buf, info[U_NAME]);
679         Put_message(buf);
680     }
681     else {
682         (void) sprintf(buf, 
683                        "Login name: %-10s/tUser id: %-10s\tLogin shell %s",
684                        info[U_NAME], info[U_UID], info[U_SHELL]);
685         (void) Put_message(buf);
686         (void) sprintf(buf, "Full name: %s %s %s\tClass: %s", 
687                        info[U_FIRST], info[U_MIDDLE], 
688                        info[U_LAST], info[U_CLASS]);
689         (void) Put_message(buf);
690         (void) sprintf(buf,
691                        "Account status: %s\tEncrypted MIT ID number: %s",
692                        atoi(info[U_STATE]) ? "active" : "inactive",
693                        info[U_MITID]);
694         (void) Put_message(buf);
695         (void) sprintf(buf, "Last Modification by %s at %s with %s.",
696                        info[U_MODBY], info[U_MODTIME], info[U_MODWITH]);
697         (void) Put_message(buf);
698     }
699 }
700
701 /*
702  * Local Variables:
703  * mode: c
704  * c-indent-level: 4
705  * c-continued-statement-offset: 4
706  * c-brace-offset: -4
707  * c-argdecl-indent: 4
708  * c-label-offset: -4
709  * End:
710  */
This page took 0.092459 seconds and 5 git commands to generate.