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