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