]> andersk Git - moira.git/blame - clients/moira/user.c
read() in a loop, not all at once, in case packets get split up
[moira.git] / clients / moira / user.c
CommitLineData
7ac48069 1/* $Id $
2 *
3 * This is the file user.c for the Moira Client, which allows users
59ec8dae 4 * to quickly and easily maintain most parts of the Moira database.
0a2c64cb 5 * It Contains: Functions for manipulating user information.
5eaef520 6 *
08345b74 7 * Created: 5/9/88
8 * By: Chris D. Peterson
9 *
7ac48069 10 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
11 * For copying and distribution information, please see the file
12 * <mit-copyright.h>.
08345b74 13 */
14
7ac48069 15#include <mit-copyright.h>
8defc06b 16#include <moira.h>
17#include <moira_site.h>
7ac48069 18#include "defs.h"
19#include "f_defs.h"
20#include "globals.h"
21
600b459e 22#include <sys/time.h>
23
1e80e2f4 24#include <ctype.h>
7ac48069 25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <time.h>
559fe7ab 29#ifdef GDSS
559fe7ab 30#include <gdss.h>
31#endif
7ac48069 32
33RCSID("$Header$");
34
35void CorrectCapitalization(char **name);
36char **AskUserInfo(char **info, Bool name);
600b459e 37struct mqelem *GetUserInfo(int type, char *name1, char *name2);
461c03b6 38
08345b74 39#define LOGIN 0
40#define UID 1
402461ad 41#define BY_NAME 2
075fe5bb 42#define CLASS 3
81701699 43#define ID 4
08345b74 44
d6db948b 45#ifdef ATHENA
46#define DEFAULT_SHELL "/bin/athena/tcsh"
47#else
07b2e652 48#define DEFAULT_SHELL "/bin/csh"
d6db948b 49#endif
07b2e652 50#define DEFAULT_CLASS "?"
51
52
32de30b0 53/* Function Name: UserState
54 * Description: Convert a numeric state into a descriptive string.
55 * Arguments: state value
56 * Returns: pointer to statically allocated string.
57 */
58
5eaef520 59static char *states[] = {
60 "Registerable (0)",
61 "Active (1)",
62 "Half Registered (2)",
63 "Deleted (3)",
64 "Not registerable (4)",
65 "Enrolled/Registerable (5)",
66 "Enrolled/Not Registerable (6)",
67 "Half Enrolled (7)"
68};
69
70static char *UserState(int state)
32de30b0 71{
5eaef520 72 static char buf[BUFSIZ];
78fce9fa 73
5eaef520 74 if (state < 0 || state >= US_END)
75 {
76 sprintf(buf, "Unknown (%d)", state);
77 return buf;
78fce9fa 78 }
5eaef520 79 return states[state];
32de30b0 80}
81
82
075fe5bb 83/* Function Name: PrintUserName
84 * Description: Print name of a user.
85 * Arguments: info - the information about a user.
86 * Returns: none.
87 */
88
5eaef520 89static void PrintUserName(char **info)
075fe5bb 90{
5eaef520 91 char buf[BUFSIZ], print_buf[BUFSIZ];
92 sprintf(buf, "%s, %s %s", info[U_LAST], info[U_FIRST], info[U_MIDDLE]);
93 sprintf(print_buf, "%-40s User Name: %s", buf, info[U_NAME]);
94 Put_message(print_buf);
075fe5bb 95}
96
97/* Function Name: PrintUserInfo
98 * Description: Prints Information about a user.
99 * Arguments: info - an argument list with the user information
100 * in it.
101 * Returns: none
102 */
103
5eaef520 104static void PrintUserInfo(char **info)
075fe5bb 105{
5eaef520 106 char name[BUFSIZ], buf[BUFSIZ];
107 int status;
edd2ce4e 108#ifdef GDSS
5eaef520 109 SigInfo si;
559fe7ab 110#endif
075fe5bb 111
5eaef520 112 sprintf(name, "%s, %s %s", info[U_LAST], info[U_FIRST], info[U_MIDDLE]);
113 sprintf(buf, "Login name: %-20s Full name: %s", info[U_NAME], name);
114 Put_message(buf);
115 sprintf(buf, "User id: %-23s Login shell %-10s Class: %s",
116 info[U_UID], info[U_SHELL], info[U_CLASS]);
117 Put_message(buf);
559fe7ab 118
119#ifdef GDSS
5eaef520 120 sprintf(buf, "%s:%s", info[U_NAME], info[U_MITID]);
121 si.rawsig = NULL;
122 status = GDSS_Verify(buf, strlen(buf), info[U_SIGNATURE], &si);
559fe7ab 123#else /* GDSS */
5eaef520 124 status = 0;
559fe7ab 125#endif /* GDSS */
126
5eaef520 127 sprintf(buf, "Account is: %-20s MIT ID number: %s Signed: %s",
128 UserState(atoi(info[U_STATE])), info[U_MITID],
129 *info[U_SIGNATURE] ? (status ? "Bad" : "Yes") : "No");
130 Put_message(buf);
131 if (atoi(info[U_SECURE]))
132 sprintf(buf, "Secure password set on %s.", atot(info[U_SECURE]));
133 else
134 sprintf(buf, "No secure password set.");
135 Put_message(buf);
136 sprintf(buf, "Comments: %s", info[U_COMMENT]);
137 Put_message(buf);
138 sprintf(buf, MOD_FORMAT, info[U_MODBY], info[U_MODTIME], info[U_MODWITH]);
139 Put_message(buf);
075fe5bb 140}
141
142/* Function Name: SetUserDefaults
143 * Description: Sets the default values for add user.
144 * Arguments: info - a blank user info array of char *'s.
145 * Returns: args - the filled info structure.
146 */
147
5eaef520 148static char **SetUserDefaults(char **info)
075fe5bb 149{
7ac48069 150 info[U_NAME] = strdup(UNIQUE_LOGIN);
151 info[U_UID] = strdup(UNIQUE_UID);
152 info[U_SHELL] = strdup(DEFAULT_SHELL);
153 info[U_LAST] = strdup(DEFAULT_NONE);
154 info[U_FIRST] = strdup(DEFAULT_NONE);
155 info[U_MIDDLE] = strdup(DEFAULT_NONE);
156 info[U_STATE] = strdup(DEFAULT_NO);
157 info[U_MITID] = strdup(DEFAULT_NONE);
158 info[U_CLASS] = strdup(DEFAULT_CLASS);
159 info[U_COMMENT] = strdup("");
160 info[U_SIGNATURE] = strdup("");
161 info[U_SECURE] = strdup("0");
5eaef520 162 info[U_MODTIME] = info[U_MODBY] = info[U_MODWITH] = info[U_END] = NULL;
163 return info;
075fe5bb 164}
461c03b6 165
f0a54771 166
5eaef520 167/* Check that the supplied name follows the capitalization rules, and
f0a54771 168 * offer to correct it if not.
169 */
170
7ac48069 171void CorrectCapitalization(char **name)
f0a54771 172{
5eaef520 173 char temp_buf[BUFSIZ], fixname[BUFSIZ];
174
175 strcpy(fixname, *name);
176 FixCase(fixname);
177 if (strcmp(fixname, *name))
178 {
179 Put_message("You entered a name which does not follow the capitalization conventions.");
180 sprintf(temp_buf, "Correct it to \"%s\"", fixname);
181 if (YesNoQuestion(temp_buf, 1) == TRUE)
182 {
183 free(*name);
7ac48069 184 *name = strdup(fixname);
f0a54771 185 }
186 }
187}
188
189
08345b74 190/* Function Name: AskUserInfo.
5eaef520 191 * Description: This function askes the user for information about a
08345b74 192 * machine and saves it into a structure.
193 * Arguments: info - a pointer the the structure to put the info into.
194 * flags - Flags asking us which info we want.
195 * Returns: the args to pass to the query.
196 * NOTES: the return args are not necessarily in the correct order to
197 * use the #defined names (e.g args[UID] is not the uid anymore).
198 */
199
5eaef520 200char **AskUserInfo(char **info, Bool name)
08345b74 201{
5eaef520 202 int i;
edd2ce4e 203#ifdef GDSS
5eaef520 204 SigInfo si;
edd2ce4e 205#endif
5eaef520 206 char temp_buf[BUFSIZ], *newname;
207
208 if (name)
209 {
210 sprintf(temp_buf, "\nChanging Attributes of user %s.\n", info[U_NAME]);
211 Put_message(temp_buf);
212 }
213 else
214 {
600b459e 215 struct mqelem *elem = NULL;
5eaef520 216 char *argv[3];
217
218 if (GetValueFromUser("User's last name", &info[U_LAST]) == SUB_ERROR)
219 return NULL;
220 CorrectCapitalization(&info[U_LAST]);
221 if (GetValueFromUser("User's first name", &info[U_FIRST]) == SUB_ERROR)
222 return NULL;
223 CorrectCapitalization(&info[U_FIRST]);
224 if (GetValueFromUser("User's middle name", &info[U_MIDDLE]) == SUB_ERROR)
225 return NULL;
226 CorrectCapitalization(&info[U_MIDDLE]);
227 argv[0] = info[U_FIRST];
228 argv[1] = info[U_LAST];
229 if (do_mr_query("get_user_account_by_name", 2, argv,
7ac48069 230 StoreInfo, &elem) == MR_SUCCESS)
5eaef520 231 {
232 Put_message("A user by that name already exists in the database.");
233 Loop(QueueTop(elem), PrintUserInfo);
234 Loop(QueueTop(elem), FreeInfo);
235 FreeQueue(elem);
236 if (YesNoQuestion("Add new user anyway", TRUE) != TRUE)
237 return NULL;
ebd96e37 238 }
075fe5bb 239 }
5eaef520 240 if (name)
241 {
7ac48069 242 newname = strdup(info[U_NAME]);
5eaef520 243 if (GetValueFromUser("The new login name for this user", &newname) ==
244 SUB_ERROR)
245 return NULL;
ebd96e37 246 }
5eaef520 247 else if (GetValueFromUser("Login name for this user", &info[U_NAME]) ==
248 SUB_ERROR)
249 return NULL;
250
251 if (GetValueFromUser("User's UID", &info[U_UID]) == SUB_ERROR)
252 return NULL;
253 if (GetValueFromUser("User's shell", &info[U_SHELL]) == SUB_ERROR)
254 return NULL;
255 if (name)
256 {
257 if (GetValueFromUser("User's last name", &info[U_LAST]) == SUB_ERROR)
258 return NULL;
259 CorrectCapitalization(&info[U_LAST]);
260 if (GetValueFromUser("User's first name", &info[U_FIRST]) == SUB_ERROR)
261 return NULL;
262 CorrectCapitalization(&info[U_FIRST]);
263 if (GetValueFromUser("User's middle name", &info[U_MIDDLE]) == SUB_ERROR)
264 return NULL;
265 CorrectCapitalization(&info[U_MIDDLE]);
266 }
267 while (1)
268 {
269 int i;
270 if (GetValueFromUser("User's status (? for help)", &info[U_STATE]) ==
271 SUB_ERROR)
272 return NULL;
273 if (isdigit(info[U_STATE][0]))
274 break;
275 Put_message("Valid status numbers:");
276 for (i = 0; i < US_END; i++)
277 {
278 sprintf(temp_buf, " %d: %s", i, states[i]);
279 Put_message(temp_buf);
1e80e2f4 280 }
281 }
5eaef520 282 if (GetValueFromUser("User's MIT ID number", &info[U_MITID]) == SUB_ERROR)
283 return NULL;
284 RemoveHyphens(info[U_MITID]);
285 if (GetTypeFromUser("User's MIT Year (class)", "class", &info[U_CLASS]) ==
286 SUB_ERROR)
287 return NULL;
288 if (GetValueFromUser("Comments", &info[U_COMMENT]) == SUB_ERROR)
289 return NULL;
290
291 if (YesNoQuestion("Secure password set",
292 atoi(info[U_SECURE]) ? TRUE : FALSE) == FALSE)
293 {
294 free(info[U_SECURE]);
7ac48069 295 info[U_SECURE] = strdup("0");
5eaef520 296 }
297 else if (!strcmp(info[U_SECURE], "0"))
298 {
299 char buf[16];
300 struct timeval tv;
301
302 gettimeofday(&tv, NULL);
303 sprintf(buf, "%ld", (long) tv.tv_sec);
304 free(info[U_SECURE]);
7ac48069 305 info[U_SECURE] = strdup(buf);
559fe7ab 306 }
307
5eaef520 308 /* Sign record */
b8322cb3 309#ifdef GDSS
5eaef520 310 if (strcmp(info[U_NAME], UNIQUE_LOGIN))
311 {
312 if (name)
313 sprintf(temp_buf, "%s:%s", newname, info[U_MITID]);
314 else
315 sprintf(temp_buf, "%s:%s", info[U_NAME], info[U_MITID]);
316 si.rawsig = NULL;
317 i = GDSS_Verify(temp_buf, strlen(temp_buf), info[U_SIGNATURE], &si);
318 /* If it's already signed OK, don't resign it. */
319 if (i != GDSS_SUCCESS)
320 {
321 free(info[U_SIGNATURE]);
322 info[U_SIGNATURE] = malloc(GDSS_Sig_Size() * 2);
cd42d372 323 sign_again:
5eaef520 324 i = GDSS_Sign(temp_buf, strlen(temp_buf), info[U_SIGNATURE]);
325 if (i != GDSS_SUCCESS)
326 com_err(program_name, gdss2et(i), "Failed to create signature");
327 else
328 {
329 unsigned char buf[256];
330 si.rawsig = buf;
331 i = GDSS_Verify(temp_buf, strlen(temp_buf),
332 info[U_SIGNATURE], &si);
333 if (strlen(buf) > 68)
334 goto sign_again;
cd42d372 335 }
559fe7ab 336 }
337 }
b8322cb3 338#else /* GDSS */
7ac48069 339 info[U_SIGNATURE] = strdup("");
b8322cb3 340#endif /* GDSS */
341
5eaef520 342 FreeAndClear(&info[U_MODTIME], TRUE);
343 FreeAndClear(&info[U_MODBY], TRUE);
344 FreeAndClear(&info[U_MODWITH], TRUE);
08345b74 345
5eaef520 346 /*
347 * Slide the newname into the #2 slot, this screws up all future references
348 * to this list, since we slip the pointer into a info list it gets freed
349 * when the rest of the list gets freed.
350 */
351 if (name)
352 SlipInNewName(info, newname);
08345b74 353
5eaef520 354 return info;
08345b74 355}
356
357/* Function Name: GetUserInfo
358 * Description: Stores the user information in a queue.
359 * Arguments: type - type of field given to get info, one of:
402461ad 360 * LOGIN, UID, BY_NAME, CLASS.
08345b74 361 * name1 - name of thing specified by type (wildcards okay)
362 * name2 - other name, only used in get user by first and last.
363 * (wildcards okay).
364 * Returns: the first element of the queue containing the user info.
dcfa270a 365 *
08345b74 366 */
367
600b459e 368struct mqelem *GetUserInfo(int type, char *name1, char *name2)
08345b74 369{
5eaef520 370 char *args[2];
44d12d58 371 int status;
600b459e 372 struct mqelem *elem = NULL;
08345b74 373
5eaef520 374 switch (type)
375 {
08345b74 376 case LOGIN:
5eaef520 377 args[0] = name1;
378 if ((status = do_mr_query("get_user_account_by_login", 1, args,
7ac48069 379 StoreInfo, &elem)))
5eaef520 380 {
381 com_err(program_name, status,
382 " when attempting to get_user_account_by_login.");
383 return NULL;
08345b74 384 }
5eaef520 385 break;
08345b74 386 case UID:
5eaef520 387 args[0] = name1;
388 if ((status = do_mr_query("get_user_account_by_uid", 1, args,
7ac48069 389 StoreInfo, &elem)))
5eaef520 390 {
391 com_err(program_name, status,
392 " when attempting to get_user_account_by_uid.");
393 return NULL;
08345b74 394 }
5eaef520 395 break;
402461ad 396 case BY_NAME:
5eaef520 397 args[0] = name1;
398 args[1] = name2;
399 if ((status = do_mr_query("get_user_account_by_name", 2, args,
7ac48069 400 StoreInfo, &elem)))
5eaef520 401 {
402 com_err(program_name, status,
403 " when attempting to get_user_account_by_name.");
404 return NULL;
08345b74 405 }
5eaef520 406 break;
08345b74 407 case CLASS:
5eaef520 408 args[0] = name1;
409 if ((status = do_mr_query("get_user_account_by_class", 1, args,
7ac48069 410 StoreInfo, &elem)))
5eaef520 411 {
412 com_err(program_name, status,
413 " when attempting to get_user_account_by_class.");
414 return NULL;
08345b74 415 }
5eaef520 416 break;
81701699 417 case ID:
5eaef520 418 args[0] = name1;
419 if ((status = do_mr_query("get_user_account_by_id", 1, args,
7ac48069 420 StoreInfo, &elem)))
5eaef520 421 {
422 com_err(program_name, status,
423 " when attempting to get_user_account_by_id.");
424 return NULL;
81701699 425 }
5eaef520 426 break;
08345b74 427 }
5eaef520 428 return QueueTop(elem) ;
08345b74 429}
430
075fe5bb 431/* Function Name: AddNewUser
432 * Description: Adds a new user to the database.
433 * Arguments: none.
08345b74 434 * Returns: DM_NORMAL.
435 */
436
7ac48069 437int AddNewUser(int argc, char **argv)
08345b74 438{
44d12d58 439 int status;
5eaef520 440 char **args, *info[MAX_ARGS_SIZE];
075fe5bb 441
5eaef520 442 if (!(args = AskUserInfo(SetUserDefaults(info), FALSE)))
443 {
444 Put_message("Aborted.");
445 return DM_NORMAL;
e4f91beb 446 }
5eaef520 447 if ((status = do_mr_query("add_user_account", CountArgs(args),
7ac48069 448 args, NULL, NULL)))
5eaef520 449 com_err(program_name, status, " in add_user_account");
450 else
451 Put_message("New user added to database.");
452 FreeInfo(args);
453 return DM_NORMAL;
08345b74 454}
455
456
075fe5bb 457/* Function Name: GetLoginName
458 * Description: Asks the user for a login name and reserves
459 * it with kerberous.
460 * Arguments: none.
461 * Returns: a malloced login name for the user.
08345b74 462 */
463
5eaef520 464static char *GetLoginName(void)
08345b74 465{
5eaef520 466 char *name;
075fe5bb 467
7ac48069 468 name = strdup("");
5eaef520 469 if (GetValueFromUser("Login name for this user? ", &name) == SUB_ERROR)
470 return NULL;
471 Put_message("KERBEROS code not added, did not reserve name with kerberos.");
472 return name;
075fe5bb 473}
474
475
476/* Function Name: ChooseUser
477 * Description: Choose a user from a list and return the uid.
478 * Arguments: top - a queue of user information.
479 * Returns: uid - the malloced uid of the user that was chosen.
480 */
08345b74 481
600b459e 482static char *ChooseUser(struct mqelem *elem)
075fe5bb 483{
5eaef520 484 while (elem)
485 {
7ac48069 486 char **info = elem->q_data;
5eaef520 487 PrintUserInfo(info);
488 switch (YesNoQuitQuestion("Is this the user you want (y/n/q)", FALSE))
489 {
075fe5bb 490 case TRUE:
7ac48069 491 return strdup(info[U_UID]);
075fe5bb 492 case FALSE:
5eaef520 493 break;
075fe5bb 494 default: /* quit or ^C. */
5eaef520 495 return NULL;
08345b74 496 }
5eaef520 497 elem = elem->q_forw;
08345b74 498 }
5eaef520 499 return NULL;
08345b74 500}
501
075fe5bb 502/* Function Name: GetUidNumberFromName
503 * Description: Gets the users uid number, from the name.
504 * Arguments: none.
505 * Returns: uid - a malloced string containing the uid.
08345b74 506 */
507
5eaef520 508static char *GetUidNumberFromName(void)
08345b74 509{
5eaef520 510 char *args[5], *uid, first[BUFSIZ], last[BUFSIZ];
44d12d58 511 int status;
600b459e 512 struct mqelem *top = NULL;
5eaef520 513
514 if (!Prompt_input("First Name: ", first, BUFSIZ))
515 return NULL;
516 if (!Prompt_input("Last Name: ", last, BUFSIZ))
517 return NULL;
518 FixCase(first);
519 FixCase(last);
520
521 args[0] = first;
522 args[1] = last;
523
524 switch ((status = do_mr_query("get_user_account_by_name", 2, args,
7ac48069 525 StoreInfo, &top)))
5eaef520 526 {
8defc06b 527 case MR_SUCCESS:
5eaef520 528 break;
8defc06b 529 case MR_NO_MATCH:
5eaef520 530 Put_message("There is no user in the database with that name.");
531 return NULL;
075fe5bb 532 default:
5eaef520 533 com_err(program_name, status, " in get_account_user_by_name.");
534 return NULL;
08345b74 535 }
5eaef520 536
537 top = QueueTop(top);
538 if (QueueCount(top) == 1) /* This is a unique name. */
539 {
7ac48069 540 char **info = top->q_data;
5eaef520 541 Put_message("User ID Number retrieved for the user: ");
542 Put_message("");
543 PrintUserName(info);
7ac48069 544 uid = strdup(info[U_UID]);
5eaef520 545 FreeQueue(top);
7ac48069 546 return strdup(uid);
075fe5bb 547 }
08345b74 548
5eaef520 549 Put_message("That name is not unique, choose the user that you want.");
550 uid = ChooseUser(top);
551 FreeQueue(top);
552 return uid;
08345b74 553}
554
075fe5bb 555/* Function Name: SetUserPassword
556 * Description: Set the new kerberos password for this user.
557 * Arguments: name - kerberos principle name for this user, (login name).
558 * Returns: none.
08345b74 559 */
560
5eaef520 561static void SetUserPassword(char *name)
08345b74 562{
5eaef520 563 name = name; /* make saber happy. */
564 Put_message("Kerberos password not changed, code non-existant.");
565 /* clever message to call account_admin, if this fails. */
075fe5bb 566}
08345b74 567
075fe5bb 568/* Function Name: GiveBackLogin
569 * Description: Gives back previously reserved kerberous principle.
570 * Arguments: name - principle to give back.
571 * Returns: void.
08345b74 572 */
573
5eaef520 574static void GiveBackLogin(char *name)
08345b74 575{
5eaef520 576 name = name; /* make saber happy. */
577 Put_message("kerberos code not implimented, name not given back.");
578 /* send mail to db maintainer if this fails. */
08345b74 579}
580
075fe5bb 581/* Function Name: RegisterUser
582 * Description: This function registers a user.
583 * Arguments: none.
584 * Returns: DM_NORMAL.
08345b74 585 */
586
7ac48069 587int RegisterUser(int argc, char **argv)
08345b74 588{
5eaef520 589 char *args[MAX_ARGS_SIZE];
590 char *login, *fstype = NULL;
591 char temp_buf[BUFSIZ];
44d12d58 592 int status;
5eaef520 593
594 Put_message("This function has NO kerberos support, so strange things");
595 Put_message("may happen if you use it to register a user.");
596
597 switch (YesNoQuestion("Do you know the users UID Number (y/n)", FALSE))
598 {
075fe5bb 599 case TRUE:
5eaef520 600 Prompt_input("What is the UID number of the user? ", temp_buf, BUFSIZ);
7ac48069 601 args[0] = strdup(temp_buf);
5eaef520 602 break;
075fe5bb 603 case FALSE:
5eaef520 604 if (!(args[0] = GetUidNumberFromName()))
605 return DM_NORMAL;
606 break;
075fe5bb 607 default:
5eaef520 608 return DM_NORMAL;
461c03b6 609 }
075fe5bb 610
5eaef520 611 sprintf(temp_buf, "u%s", args[0]);
7ac48069 612 login = strdup(temp_buf);
5eaef520 613 if ((GetValueFromUser("Login name for this user? ", &login) == SUB_ERROR) ||
614 (GetFSTypes(&fstype, FALSE) == SUB_ERROR))
615 {
616 args[1] = login;
617 FreeInfo(args); /* This work because the NULL temination is ok. */
618 return DM_NORMAL;
075fe5bb 619 }
5eaef520 620 Put_message("KERBEROS code not added, did not reserve name with kerberos.");
621 args[1] = login;
622 args[2] = fstype;
623 args[3] = NULL;
624
625 switch ((status = do_mr_query("register_user", CountArgs(args),
7ac48069 626 args, NULL, NULL)))
5eaef520 627 {
8defc06b 628 case MR_SUCCESS:
5eaef520 629 sprintf(temp_buf, "User %s successfully registered.", login);
630 Put_message(temp_buf);
631 SetUserPassword(login);
632 break;
8defc06b 633 case MR_IN_USE:
5eaef520 634 GiveBackLogin(login);
635 sprintf(temp_buf, "The username %s is already in use.", login);
636 Put_message(temp_buf);
637 break;
075fe5bb 638 default:
5eaef520 639 com_err(program_name, status, " in register_user");
640 break;
075fe5bb 641 }
5eaef520 642 FreeInfo(args);
643 return DM_NORMAL;
08345b74 644}
645
075fe5bb 646/* Function Name: RealUpdateUser
647 * Description: actuall updates the user information.
648 * Arguments: info - all current information for the user fields.
649 * junk - an UNUSED boolean.
650 * Returns: none.
08345b74 651 */
652
5eaef520 653static void RealUpdateUser(char **info, Bool junk)
08345b74 654{
44d12d58 655 int status;
5eaef520 656 char error_buf[BUFSIZ];
657 char **args = AskUserInfo(info, TRUE);
658
659 if (!args)
660 {
661 Put_message("Aborted.");
662 return;
e4f91beb 663 }
5eaef520 664 if ((status = do_mr_query("update_user_account", CountArgs(args),
7ac48069 665 args, NULL, NULL)))
5eaef520 666 {
667 com_err(program_name, status, " in ModifyFields");
668 sprintf(error_buf, "User %s not updated due to errors.", info[NAME]);
669 Put_message(error_buf);
08345b74 670 }
08345b74 671}
672
075fe5bb 673/* Function Name: UpdateUser
674 * Description: Modify some of the information about a user.
675 * Arguments: argc, argv - login name of the user in argv[1].
08345b74 676 * Returns: DM_NORMAL.
677 */
678
5eaef520 679int UpdateUser(int argc, char **argv)
08345b74 680{
600b459e 681 struct mqelem *elem;
5eaef520 682
683 elem = GetUserInfo(LOGIN, argv[1], NULL);
684 QueryLoop(elem, NullPrint, RealUpdateUser, "Update the user");
08345b74 685
5eaef520 686 FreeQueue(elem);
687 return DM_NORMAL;
08345b74 688}
689
b3e25186 690/* Function Name: RealDeactivateUser
691 * Description: sets the user's status to 3.
692 * Arguments: info - all current information for the user fields
693 * one_item - indicates the user hasn't been queried yet
694 * Returns: none.
695 */
696
5eaef520 697static void RealDeactivateUser(char **info, Bool one_item)
b3e25186 698{
44d12d58 699 int status;
5eaef520 700 char txt_buf[BUFSIZ];
701 char *qargs[2], **args;
600b459e 702 struct mqelem *elem = NULL;
5eaef520 703
704 if (one_item)
705 {
706 sprintf(txt_buf, "Deactivate user %s (y/n)", info[NAME]);
707 if (YesNoQuestion(txt_buf, FALSE) != TRUE)
708 return;
b3e25186 709 }
710
5eaef520 711 qargs[0] = info[NAME];
712 qargs[1] = "3";
7ac48069 713 if ((status = do_mr_query("update_user_status", 2, qargs, NULL, NULL)))
5eaef520 714 {
715 com_err(program_name, status, " in update_user_status");
716 sprintf(txt_buf, "User %s not deactivated due to errors.", info[NAME]);
717 Put_message(txt_buf);
718 }
719 else if (YesNoQuestion("Also deactivate matching list and filesystem (y/n)",
720 FALSE) == TRUE)
721 {
722 status = do_mr_query("get_list_info", 1, &(info[NAME]), StoreInfo,
7ac48069 723 &elem);
5eaef520 724 if (status == MR_SUCCESS)
725 {
7ac48069 726 args = QueueTop(elem)->q_data;
5eaef520 727 free(args[L_ACTIVE]);
7ac48069 728 args[L_ACTIVE] = strdup("0");
5eaef520 729 FreeAndClear(&args[L_MODTIME], TRUE);
730 FreeAndClear(&args[L_MODBY], TRUE);
731 FreeAndClear(&args[L_MODWITH], TRUE);
732 SlipInNewName(args, args[L_NAME]);
733 if ((status = do_mr_query("update_list", CountArgs(args), args,
7ac48069 734 NULL, NULL)))
5eaef520 735 {
736 com_err(program_name, status, " updating list, "
737 "not deactivating list or filesystem");
738 FreeInfo(args);
739 FreeQueue(elem);
740 return;
28da9b65 741 }
5eaef520 742 FreeInfo(args);
743 FreeQueue(elem);
744 elem = NULL;
745 }
746 else if (status != MR_NO_MATCH)
747 {
748 com_err(program_name, status, " getting list info, "
749 "not deactivating list or filesystem");
750 return;
00d4c0ba 751 }
28da9b65 752
5eaef520 753 if ((status = do_mr_query("get_filesys_by_label", 1, &(info[NAME]),
7ac48069 754 StoreInfo, &elem)))
5eaef520 755 {
756 com_err(program_name, status, " getting filsys info, "
757 "not deactivating filesystem");
758 FreeInfo(args);
759 FreeQueue(elem);
760 return;
00d4c0ba 761 }
7ac48069 762 args = QueueTop(elem)->q_data;
5eaef520 763 free(args[FS_TYPE]);
7ac48069 764 args[FS_TYPE] = strdup("ERR");
5eaef520 765 free(args[FS_COMMENTS]);
7ac48069 766 args[FS_COMMENTS] = strdup("Locker disabled; call 3-1325 for help");
5eaef520 767 FreeAndClear(&args[FS_MODTIME], TRUE);
768 FreeAndClear(&args[FS_MODBY], TRUE);
769 FreeAndClear(&args[FS_MODWITH], TRUE);
770 SlipInNewName(args, args[FS_NAME]);
771 if ((status = do_mr_query("update_filesys", CountArgs(args), args,
7ac48069 772 NULL, NULL)))
5eaef520 773 {
774 com_err(program_name, status, " updating filesystem, "
775 "not deactivating filesystem");
776 FreeInfo(args);
777 FreeQueue(elem);
778 return;
00d4c0ba 779 }
5eaef520 780 FreeInfo(args);
781 FreeQueue(elem);
b3e25186 782 }
783}
784
785
786/* Function Name: DeactivateUser
787 * Description: sets the user's status to 3.
788 * Arguments: argc, argv - login name of the user in argv[1].
789 * Returns: DM_NORMAL.
790 */
791
5eaef520 792int DeactivateUser(int argc, char **argv)
b3e25186 793{
600b459e 794 struct mqelem *elem;
b3e25186 795
5eaef520 796 elem = GetUserInfo(LOGIN, argv[1], NULL);
797 QueryLoop(elem, NullPrint, RealDeactivateUser, "Deactivate user");
798
799 FreeQueue(elem);
800 return DM_NORMAL;
b3e25186 801}
802
803
075fe5bb 804/* ------------------------- Top Menu ------------------------- */
805
806/* DeleteUser() in delete.c */
461c03b6 807
075fe5bb 808/* Function Name: DeleteUserByUid
809 * Description: Deletes the user given a uid number.
810 * Arguments: argc, argv - uid if user in argv[1].
08345b74 811 * Returns: DM_NORMAL.
5eaef520 812 * NOTES: This just gets the username from the mr server
075fe5bb 813 * and performs a DeleteUser().
08345b74 814 */
815
5eaef520 816int DeleteUserByUid(int argc, char **argv)
08345b74 817{
5eaef520 818 int status;
600b459e 819 struct mqelem *elem = NULL;
5eaef520 820 char **info;
821
822 if (!ValidName(argv[1]))
823 return DM_NORMAL;
824
825 if ((status = do_mr_query("get_user_account_by_uid", 1, argv + 1, StoreInfo,
7ac48069 826 &elem)))
5eaef520 827 com_err(program_name, status, " in get_user_account_by_uid");
828
7ac48069 829 info = elem->q_data;
5eaef520 830 argv[1] = info[U_NAME];
831
832 DeleteUser(argc, argv);
833 return DM_NORMAL;
834}
08345b74 835
075fe5bb 836/* ------------------------- Show User Information ------------------------- */
08345b74 837
838/* Function Name: ShowUserByLogin
839 * Description: Shows user information given a login name.
840 * Arguments: argc, argv - login name in argv[1].
841 * Returns: DM_NORMAL
842 */
843
5eaef520 844int ShowUserByLogin(int argc, char *argv[])
08345b74 845{
600b459e 846 struct mqelem *top, *elem;
08345b74 847
5eaef520 848 elem = top = GetUserInfo(LOGIN, argv[1], NULL);
849 Loop(elem, PrintUserInfo);
08345b74 850
5eaef520 851 FreeQueue(top);
852 return DM_NORMAL;
08345b74 853}
854
855/* Function Name: RetrieveUserByName
856 * Description: Show information on a user give fist and/or last name.
857 * Arguments: argc, argv - argv[1] - first name.
858 * argv[2] - last name.
859 * Returns: DM_NORMAL.
860 */
861
5eaef520 862int ShowUserByName(int argc, char *argv[])
08345b74 863{
600b459e 864 struct mqelem *top;
5eaef520 865 char buf[BUFSIZ];
08345b74 866
5eaef520 867 top = GetUserInfo(BY_NAME, argv[1], argv[2]);
08345b74 868
5eaef520 869 if (!top) /* if there was an error then return. */
870 return DM_NORMAL;
08345b74 871
5eaef520 872 if (!PromptWithDefault("Print full information, or just the names (f/n)?",
873 buf, 2, "f"))
874 return DM_NORMAL;
08345b74 875
5eaef520 876 switch (buf[0])
877 {
075fe5bb 878 case 'F':
879 case 'f':
5eaef520 880 Loop(top, PrintUserInfo);
881 break;
075fe5bb 882 case 'N':
883 case 'n':
5eaef520 884 Loop(top, PrintUserName);
885 break;
075fe5bb 886 }
5eaef520 887
888 FreeQueue(top);
889 return DM_NORMAL;
08345b74 890}
891
892/* Function Name: ShowUserByClass
893 * Description: Shows real and login names of all users in class.
894 * Arguments: argc, argv - argv[1] contains the class.
895 * Returns: none.
896 */
897
5eaef520 898int ShowUserByClass(int argc, char **argv)
08345b74 899{
600b459e 900 struct mqelem *top;
08345b74 901
5eaef520 902 if (YesNoQuestion("This will take a long time. Are you sure", 0) == FALSE)
903 return DM_NORMAL;
904 top = GetUserInfo(CLASS, argv[1], NULL);
905 Loop(top, PrintUserName);
08345b74 906
5eaef520 907 FreeQueue(top);
908 return DM_NORMAL;
08345b74 909}
1e80e2f4 910
911
81701699 912/* Function Name: ShowUserById
913 * Description: Shows user information given an ID number.
914 * Arguments: argc, argv - ID number in argv[1].
915 * Returns: DM_NORMAL
916 */
917
5eaef520 918int ShowUserById(int argc, char *argv[])
81701699 919{
600b459e 920 struct mqelem *top, *elem;
81701699 921
5eaef520 922 elem = top = GetUserInfo(ID, argv[1], NULL);
923 Loop(elem, PrintUserInfo);
81701699 924
5eaef520 925 FreeQueue(top);
926 return DM_NORMAL;
81701699 927}
928
929
1e80e2f4 930/* Function Name: GetKrbmap
931 * Description: Shows user <-> Kerberos mappings
932 * Arguments: argc, argv - argv[1] contains the user login name,
933 * argv[2] contains the principal
934 * Returns: none.
935 */
936
5eaef520 937int GetKrbmap(int argc, char **argv)
1e80e2f4 938{
5eaef520 939 int stat;
600b459e 940 struct mqelem *elem = NULL, *top;
5eaef520 941 char buf[BUFSIZ];
942
943 if ((stat = do_mr_query("get_kerberos_user_map", 2, &argv[1],
7ac48069 944 StoreInfo, &elem)))
5eaef520 945 {
946 com_err(program_name, stat, " in GetKrbMap.");
947 return DM_NORMAL;
1e80e2f4 948 }
949
5eaef520 950 top = elem = QueueTop(elem);
951 Put_message("");
952 while (elem)
953 {
7ac48069 954 char **info = elem->q_data;
5eaef520 955 sprintf(buf, "User: %-9s Principal: %s",
956 info[KMAP_USER], info[KMAP_PRINCIPAL]);
957 Put_message(buf);
958 elem = elem->q_forw;
1e80e2f4 959 }
960
5eaef520 961 FreeQueue(QueueTop(top));
962 return DM_NORMAL;
1e80e2f4 963}
964
965
966/* Function Name: AddKrbmap
967 * Description: Add a new user <-> Kerberos mapping
968 * Arguments: argc, argv - argv[1] contains the user login name,
969 * argv[2] contains the principal
970 * Returns: none.
971 */
972
5eaef520 973int AddKrbmap(int argc, char **argv)
1e80e2f4 974{
5eaef520 975 int stat;
1e80e2f4 976
5eaef520 977 if (!strchr(argv[KMAP_PRINCIPAL + 1], '@'))
978 {
979 Put_message("Please specify a realm for the kerberos principal.");
980 return DM_NORMAL;
1e80e2f4 981 }
5eaef520 982 if ((stat = do_mr_query("add_kerberos_user_map", 2, &argv[1],
7ac48069 983 NULL, NULL)))
5eaef520 984 {
985 com_err(program_name, stat, " in AddKrbMap.");
986 if (stat == MR_EXISTS)
987 Put_message("No user or principal may have more than one mapping.");
1e80e2f4 988 }
5eaef520 989 return DM_NORMAL;
1e80e2f4 990}
991
992
993/* Function Name: DeleteKrbmap
994 * Description: Remove a user <-> Kerberos mapping
995 * Arguments: argc, argv - argv[1] contains the user login name,
996 * argv[2] contains the principal
997 * Returns: none.
998 */
999
5eaef520 1000int DeleteKrbmap(int argc, char **argv)
1e80e2f4 1001{
5eaef520 1002 int stat;
1e80e2f4 1003
5eaef520 1004 if ((stat = do_mr_query("delete_kerberos_user_map", 2, &argv[1],
7ac48069 1005 NULL, NULL)))
5eaef520 1006 com_err(program_name, stat, " in DeleteKrbMap.");
1007 return DM_NORMAL;
1e80e2f4 1008}
559fe7ab 1009
1010
10207d4d 1011/* Function Name: GetDirFlags
1012 * Description: Shows MITdir listing preferences
1013 * Arguments: argc, argv - argv[1] contains the user login name
1014 * Returns: none.
1015 */
1016
5eaef520 1017int GetDirFlags(int argc, char **argv)
10207d4d 1018{
5eaef520 1019 int stat, flags;
600b459e 1020 struct mqelem *elem = NULL;
5eaef520 1021 char buf[BUFSIZ], **info;
1022
1023 if (!ValidName(argv[1]))
1024 return DM_NORMAL;
1025
1026 if ((stat = do_mr_query("get_user_directory_flags", 1, &argv[1],
7ac48069 1027 StoreInfo, &elem)))
5eaef520 1028 {
1029 com_err(program_name, stat, " in GetDirFlags.");
1030 return DM_NORMAL;
10207d4d 1031 }
1032
7ac48069 1033 info = QueueTop(elem)->q_data;
5eaef520 1034 flags = atoi(info[0]);
1035 FreeQueue(QueueTop(elem));
1036
1037 Put_message("");
1038 sprintf(buf, "User: %s", argv[1]);
1039 Put_message(buf);
1040 if (flags & DIRFLAGS_SUPPRESS)
1041 Put_message("Does NOT appear in the on-line directory.");
1042 else
1043 {
1044 Put_message("Does appear in the on-line directory.");
1045 if (flags & DIRFLAGS_NONLOCAL)
1046 Put_message("Is listed with non-MIT.EDU email address (if known)");
1047 else
1048 Put_message("Is listed with MIT.EDU email address.");
10207d4d 1049 }
1050
5eaef520 1051 return DM_NORMAL;
10207d4d 1052}
1053
1054/* Function Name: SetDirFlags
1055 * Description: Update online directory preferences
1056 * Arguments: argc, argv - the login name of the user in argv[1].
1057 * Returns: DM_NORMAL.
1058 */
1059
5eaef520 1060int SetDirFlags(int argc, char **argv)
559fe7ab 1061{
5eaef520 1062 int stat, flags;
1063 char **info, buf[BUFSIZ], *args[2];
600b459e 1064 struct mqelem *elem = NULL;
5eaef520 1065
1066 if (!ValidName(argv[1]))
1067 return DM_NORMAL;
1068
1069 /* Fetch current prefs */
1070 if ((stat = do_mr_query("get_user_directory_flags", 1, &argv[1],
7ac48069 1071 StoreInfo, &elem)))
5eaef520 1072 {
1073 com_err(program_name, stat, " in GetDirFlags.");
1074 return DM_NORMAL;
559fe7ab 1075 }
7ac48069 1076 info = QueueTop(elem)->q_data;
5eaef520 1077 flags = atoi(info[0]);
1078 FreeQueue(QueueTop(elem));
1079
1080 sprintf(buf, "List %s in the on-line directory (y/n)", argv[1]);
1081 if (YesNoQuestion(buf, !(flags & DIRFLAGS_SUPPRESS)))
1082 flags &= ~DIRFLAGS_SUPPRESS;
1083 else
1084 flags |= DIRFLAGS_SUPPRESS;
1085
1086 sprintf(buf, "List MIT.EDU email address even when mail is "
1087 "forwarded elsewhere? (y/n)");
1088 if (YesNoQuestion(buf, !(flags & DIRFLAGS_NONLOCAL)))
1089 flags &= ~DIRFLAGS_NONLOCAL;
1090 else
1091 flags |= DIRFLAGS_NONLOCAL;
1092
1093 args[0] = argv[1];
1094 sprintf(buf, "%d", flags);
1095 args[1] = buf;
1096 if ((stat = do_mr_query("update_user_directory_flags", 2,
7ac48069 1097 args, NULL, NULL)))
5eaef520 1098 com_err(program_name, stat, " in SetDirFlags");
1099 else
1100 Put_message("Directory preferences set.");
1101
1102 return DM_NORMAL;
559fe7ab 1103}
This page took 0.27316 seconds and 5 git commands to generate.