source: trunk/third/moira/clients/moira/user.c @ 23882

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