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