]> andersk Git - moira.git/blobdiff - clients/moira/user.c
Diane Delgado's changes for a fixed table-locking order
[moira.git] / clients / moira / user.c
index d6f81bf959de81a62409fd2c3e05eb3ff37bac3a..e116804a2e1c43a58f1b26dc03337c391baf9a33 100644 (file)
  */
 
 #include <stdio.h>
-#include <strings.h>
+#include <string.h>
 #include <moira.h>
 #include <moira_site.h>
 #include <menu.h>
 #include <ctype.h>
-
+#include <sys/time.h>
+#ifdef GDSS
+#include <des.h>
+#include <krb.h>
+#include <gdss.h>
+#endif
 #include "mit-copyright.h"
 #include "defs.h"
 #include "f_defs.h"
 #define UID   1
 #define BY_NAME  2
 #define CLASS 3
+#define ID 4
 
+#ifdef ATHENA
+#define DEFAULT_SHELL "/bin/athena/tcsh"
+#else
 #define DEFAULT_SHELL "/bin/csh"
+#endif
 #define DEFAULT_CLASS "?"
 
 
@@ -96,6 +106,10 @@ PrintUserInfo(info)
 char ** info;
 {
     char name[BUFSIZ], buf[BUFSIZ];
+    int status;
+#ifdef GDSS
+    SigInfo si;
+#endif
 
     sprintf(name, "%s, %s %s", info[U_LAST], info[U_FIRST], info[U_MIDDLE]);
     sprintf(buf, "Login name: %-20s Full name: %s", info[U_NAME], name);
@@ -103,8 +117,30 @@ char ** info;
     sprintf(buf, "User id: %-23s Login shell %-10s Class: %s", 
            info[U_UID], info[U_SHELL], info[U_CLASS]);
     Put_message(buf);
-    sprintf(buf, "Account is: %-20s Encrypted MIT ID number: %s",
-           UserState(atoi(info[U_STATE])), info[U_MITID]);
+
+#ifdef GDSS
+    sprintf(buf, "%s:%s", info[U_NAME], info[U_MITID]);
+    si.rawsig = NULL;
+    status = GDSS_Verify(buf, strlen(buf), info[U_SIGNATURE], &si);
+#ifdef DEBUG
+    hex_dump(info[U_SIGNATURE]);
+    sprintf(buf, "GDSS_Verify => %d", status);
+    Put_message(buf);
+#endif /* DEBUG */
+#else /* GDSS */
+    status = 0;
+#endif /* GDSS */
+
+    sprintf(buf, "Account is: %-20s MIT ID number: %s Signed: %s",
+           UserState(atoi(info[U_STATE])), info[U_MITID],
+           *info[U_SIGNATURE] ? (status ? "Bad" : "Yes") : "No");
+    Put_message(buf);
+    if (atoi(info[U_SECURE]))
+      sprintf(buf, "Secure password set on %s.", atot(info[U_SECURE]));
+    else
+      sprintf(buf, "No secure password set.");
+    Put_message(buf);
+    sprintf(buf, "Comments: %s", info[U_COMMENT]);
     Put_message(buf);
     sprintf(buf, MOD_FORMAT, info[U_MODBY], info[U_MODTIME],info[U_MODWITH]);
     Put_message(buf);
@@ -129,6 +165,9 @@ char ** info;
     info[U_STATE] = Strsave(DEFAULT_NO);
     info[U_MITID] = Strsave(DEFAULT_NONE);
     info[U_CLASS] = Strsave(DEFAULT_CLASS);
+    info[U_COMMENT] = Strsave("");
+    info[U_SIGNATURE] = Strsave("");
+    info[U_SECURE] = Strsave("0");
     info[U_MODTIME] = info[U_MODBY] = info[U_MODWITH] = info[U_END] = NULL;
     return(info);
 }
@@ -171,7 +210,11 @@ AskUserInfo(info, name)
 char ** info;
 Bool name;
 {
-    char temp_buf[BUFSIZ], fixname[BUFSIZ], *newname, *temp_ptr;
+    int siglen, i;
+#ifdef GDSS
+    SigInfo si;
+#endif
+    char temp_buf[BUFSIZ], *newname, *temp_ptr, *sig, sig_buf[BUFSIZ];
 
     if (name) {
        sprintf(temp_buf,"\nChanging Attributes of user %s.\n",info[U_NAME]);
@@ -192,7 +235,7 @@ Bool name;
        CorrectCapitalization(&info[U_MIDDLE]);
        argv[0] = info[U_FIRST];
        argv[1] = info[U_LAST];
-       if (do_mr_query("get_user_by_name", 2, argv,
+       if (do_mr_query("get_user_account_by_name", 2, argv,
                         StoreInfo, (char *) &elem) == 0) {
            Put_message("A user by that name already exists in the database.");
            Loop(QueueTop(elem), PrintUserInfo);
@@ -240,27 +283,72 @@ Bool name;
            Put_message(temp_buf);
        }
     }
-    temp_ptr = Strsave(info[U_MITID]);
-    Put_message("User's MIT ID number (unencrypted, or encryption in quotes)");
-    if (GetValueFromUser("", &temp_ptr) == SUB_ERROR)
+    if (GetValueFromUser("User's MIT ID number", &info[U_MITID]) == SUB_ERROR)
       return(NULL);
-    if ( strcmp( temp_ptr, info[U_MITID] ) != 0) {
-       if (temp_ptr[0] == '"' &&
-           temp_ptr[strlen(temp_ptr) - 1] == '"') {
-           free(info[U_MITID]);
-           temp_ptr[strlen(temp_ptr) - 1] = 0;
-           info[U_MITID] = Strsave(++temp_ptr);
-       } else {
-           EncryptID(temp_buf, temp_ptr, info[U_FIRST], info[U_LAST]);
-           free(info[U_MITID]);
-           info[U_MITID] = Strsave(temp_buf);
-       }
-    }
-    free(temp_ptr);
+    RemoveHyphens(info[U_MITID]);
     if (GetTypeFromUser("User's MIT Year (class)", "class", &info[U_CLASS]) ==
        SUB_ERROR)
       return(NULL);
-    
+    if (GetValueFromUser("Comments", &info[U_COMMENT]) == SUB_ERROR)
+      return(NULL);
+
+    if (YesNoQuestion("Secure password set",
+                     atoi(info[U_SECURE]) ? TRUE : FALSE) == FALSE) {
+       free(info[U_SECURE]);
+       info[U_SECURE] = strsave("0");
+    } else if (!strcmp(info[U_SECURE], "0")) {
+       char buf[16];
+       struct timeval tv;
+
+       gettimeofday(&tv, (struct timezone *)NULL);
+       sprintf(buf, "%d", tv.tv_sec);
+       free(info[U_SECURE]);
+       info[U_SECURE] = strsave(buf);
+    }
+
+    /* Sign record */
+#ifdef GDSS
+    if (strcmp(info[U_NAME], UNIQUE_LOGIN)) {
+       if (name)
+         sprintf(temp_buf, "%s:%s", newname, info[U_MITID]);
+       else
+         sprintf(temp_buf, "%s:%s", info[U_NAME], info[U_MITID]);
+       si.rawsig = NULL;
+       i = GDSS_Verify(temp_buf, strlen(temp_buf), info[U_SIGNATURE], &si);
+       /* If it's already signed OK, don't resign it. */
+       if (i != GDSS_SUCCESS) {
+           free(info[U_SIGNATURE]);
+           info[U_SIGNATURE] = malloc(GDSS_Sig_Size() * 2);
+       sign_again:
+           i = GDSS_Sign(temp_buf, strlen(temp_buf), info[U_SIGNATURE]);
+           if (i != GDSS_SUCCESS)
+             com_err(program_name, gdss2et(i), "Failed to create signature");
+           else {
+               unsigned char buf[256];
+               si.rawsig = buf;
+               i = GDSS_Verify(temp_buf, strlen(temp_buf),
+                               info[U_SIGNATURE], &si);
+               if (strlen(buf) > 68) {
+#ifdef DEBUG
+                   Put_message("Signature too long, trying again");
+#endif /* DEBUG */
+                   goto sign_again;
+               }
+           }
+#ifdef DEBUG
+           Put_message("Made signature:");
+       } else {
+           Put_message("Don't need to remake signature");
+#endif /* DEBUG */
+       }
+#ifdef DEBUG
+       hex_dump(info[U_SIGNATURE]);
+#endif /* DEBUG */
+    }
+#else /* GDSS */
+    info[U_SIGNATURE] = strsave("");
+#endif /* GDSS */
+
     FreeAndClear(&info[U_MODTIME], TRUE);
     FreeAndClear(&info[U_MODBY], TRUE);
     FreeAndClear(&info[U_MODWITH], TRUE);
@@ -284,6 +372,14 @@ Bool name;
  *                 name2 - other name, only used in get user by first and last.
  *                         (wildcards okay).
  *     Returns: the first element of the queue containing the user info.
+ *
+ * Note: if we are checking a login name, if the length is greater
+ * than 8 characters, we immediately print a "no such user" error.
+ * This gets around a bug in Ingres, where a non-existent 8 character
+ * username returns a "no such user" error instantaneously, but a 9
+ * character username takes 5-6 minutes.  :-(  We will need to change
+ * this if we ever make a username longer than 8 characters.
+ * Unlikely, but....
  */
 
 struct qelem *
@@ -297,39 +393,53 @@ char *name1, *name2;
 
     switch(type) {
     case LOGIN:
+       if (strlen(name1) > 8) {
+           com_err(program_name, MR_USER,
+                   " when attempting to get_user_acount_by_login.");
+           return (NULL);
+        }
        args[0] = name1;
-       if ( (status = do_mr_query("get_user_by_login", 1, args,
+       if ( (status = do_mr_query("get_user_account_by_login", 1, args,
                                    StoreInfo, (char *) &elem)) != 0) {
            com_err(program_name, status, 
-                   " when attempting to get_user_by_login.");
+                   " when attempting to get_user_account_by_login.");
            return (NULL);               
        }
        break;
     case UID:
        args[0] = name1;
-       if ( (status = do_mr_query("get_user_by_uid", 1, args,
+       if ( (status = do_mr_query("get_user_account_by_uid", 1, args,
                                    StoreInfo, (char *) &elem)) != 0) {
            com_err(program_name, status, 
-                   " when attempting to get_user_by_uid.");
+                   " when attempting to get_user_account_by_uid.");
            return (NULL);      
        }
        break;
     case BY_NAME:
        args[0] = name1;
        args[1] = name2;    
-       if ( (status = do_mr_query("get_user_by_name", 2, args,
+       if ( (status = do_mr_query("get_user_account_by_name", 2, args,
                                    StoreInfo, (char *) &elem)) != 0) {
            com_err(program_name, status, 
-                   " when attempting to get_user_by_name.");
+                   " when attempting to get_user_account_by_name.");
            return (NULL);      
        }
        break;
     case CLASS:
        args[0] = name1;
-       if ( (status = do_mr_query("get_user_by_class", 1, args,
+       if ( (status = do_mr_query("get_user_account_by_class", 1, args,
+                                   StoreInfo, (char *) &elem)) != 0) {
+           com_err(program_name, status, 
+                   " when attempting to get_user_account_by_class.");
+           return (NULL);      
+       }
+       break;
+    case ID:
+       args[0] = name1;
+       if ( (status = do_mr_query("get_user_account_by_id", 1, args,
                                    StoreInfo, (char *) &elem)) != 0) {
            com_err(program_name, status, 
-                   " when attempting to get_user_by_class.");
+                   " when attempting to get_user_account_by_id.");
            return (NULL);      
        }
        break;
@@ -356,9 +466,9 @@ AddNewUser()
     }
     if (args == NULL)
       return(DM_NORMAL);
-    if ( (status = do_mr_query("add_user", CountArgs(args), 
+    if ( (status = do_mr_query("add_user_account", CountArgs(args), 
                                args, Scream, (char *) NULL)) != MR_SUCCESS)
-       com_err(program_name, status, " in add_user");
+       com_err(program_name, status, " in add_user_account");
     else
        Put_message("New user added to database.");
     FreeInfo(args);
@@ -435,7 +545,7 @@ GetUidNumberFromName()
     args[0] = first;
     args[1] = last;
     
-    switch (status = do_mr_query("get_user_by_name", 2, args,
+    switch (status = do_mr_query("get_user_account_by_name", 2, args,
                                  StoreInfo, (char *) &top)) {
     case MR_SUCCESS:
        break;
@@ -443,7 +553,7 @@ GetUidNumberFromName()
        Put_message("There is no user in the database with that name.");
        return(NULL);
     default:
-       com_err(program_name, status, " in get_user_by_name.");
+       com_err(program_name, status, " in get_account_user_by_name.");
        return(NULL);
     }
     
@@ -508,7 +618,7 @@ RegisterUser()
     char temp_buf[BUFSIZ];
     register int status;
     
-    Put_message("This function has NO kerberos support, so stange things");
+    Put_message("This function has NO kerberos support, so strange things");
     Put_message("may happen if you use it to register a user.");
 
     switch (YesNoQuestion("Do you know the users UID Number (y/n)", FALSE)) {
@@ -524,11 +634,16 @@ RegisterUser()
        return(DM_NORMAL);
     }
 
-    if ( ((login = args[1] = GetLoginName()) == NULL) ||
+    sprintf(temp_buf, "u%s", args[0]);
+    login = strsave(temp_buf);
+    if ( (GetValueFromUser("Login name for this user? ", &login) == SUB_ERROR) ||
        ( GetFSTypes(&fstype, FALSE) == SUB_ERROR ) ) {
+        args[1] = login;
        FreeInfo(args);    /* This work because the NULL temination is ok. */
        return(DM_NORMAL);
     }
+    Put_message("KERBEROS code not added, did not reserve name with kerberos.");
+    args[1] = login;
     args[2] = fstype;
     args[3] = NULL;
     
@@ -573,7 +688,7 @@ Bool junk;
        Put_message("Aborted.");
        return;
     }
-    if ( (status = do_mr_query("update_user", CountArgs(args), 
+    if ( (status = do_mr_query("update_user_account", CountArgs(args), 
                                args, Scream, (char *) NULL)) != MR_SUCCESS) {
        com_err(program_name, status, " in ModifyFields");
        sprintf(error_buf, "User %s not updated due to errors.", info[NAME]);
@@ -616,7 +731,8 @@ Bool one_item;
 {
     register int status;
     char txt_buf[BUFSIZ];
-    char * qargs[2];
+    char * qargs[2], **args;
+    struct qelem *elem = NULL;
 
     if (one_item) {
        sprintf(txt_buf, "Deactivate user %s (y/n)", info[NAME]);
@@ -631,6 +747,55 @@ Bool one_item;
        com_err(program_name, status, " in update_user_status");
        sprintf(txt_buf, "User %s not deactivated due to errors.", info[NAME]);
        Put_message(txt_buf);
+    } else if (YesNoQuestion("Also deactivate matching list and filesystem (y/n)",
+                            FALSE) == TRUE) {
+       if (status = do_mr_query("get_list_info", 1, &(info[NAME]),
+                                StoreInfo, (char *) &elem)) {
+           com_err(program_name, status, " getting list info, not deactivating list or filesystem");
+           return;
+       }
+       args =(char **) (QueueTop(elem)->q_data);
+       free(args[L_ACTIVE]);
+       args[L_ACTIVE] = strsave("0");
+       FreeAndClear(&args[L_MODTIME], TRUE);
+       FreeAndClear(&args[L_MODBY], TRUE);
+       FreeAndClear(&args[L_MODWITH], TRUE);
+       SlipInNewName(args, args[L_NAME]);
+       if (status = do_mr_query("update_list", CountArgs(args), args,
+                                Scream, (char *) NULL)) {
+           com_err(program_name, status, " updating list, not deactivating list or filesystem");
+           FreeInfo(args);
+           FreeQueue(elem);
+           return;
+       }
+       FreeInfo(args);
+       FreeQueue(elem);
+       elem = (struct qelem *) NULL;
+       if (status = do_mr_query("get_filesys_by_label", 1, &(info[NAME]),
+                                StoreInfo, (char *) &elem)) {
+           com_err(program_name, status, " getting filsys info, not deactivating filesystem");
+           FreeInfo(args);
+           FreeQueue(elem);
+           return;
+       }
+       args = (char **) (QueueTop(elem)->q_data);
+       free(args[FS_TYPE]);
+       args[FS_TYPE] = strsave("ERR");
+       free(args[FS_COMMENTS]);
+       args[FS_COMMENTS] = strsave("Locker disabled; call 3-1325 for help");
+       FreeAndClear(&args[FS_MODTIME], TRUE);
+       FreeAndClear(&args[FS_MODBY], TRUE);
+       FreeAndClear(&args[FS_MODWITH], TRUE);
+       SlipInNewName(args, args[FS_NAME]);
+       if (status = do_mr_query("update_filesys", CountArgs(args), args,
+                                Scream, (char *) NULL)) {
+           com_err(program_name, status, " updating filesystem, not deactivating filesystem");
+           FreeInfo(args);
+           FreeQueue(elem);
+           return;
+       }
+       FreeInfo(args);
+       FreeQueue(elem);
     }
 }
 
@@ -681,9 +846,9 @@ char **argv;
     if(!ValidName(argv[1]))
        return(DM_NORMAL);
     
-    if ( (status = do_mr_query("get_user_by_uid", 1, argv+1, StoreInfo,
+    if ( (status = do_mr_query("get_user_account_by_uid", 1, argv+1, StoreInfo,
                                (char * ) &elem)) != MR_SUCCESS)
-       com_err(program_name, status, " in get_user_by_uid");
+       com_err(program_name, status, " in get_user_account_by_uid");
     
     info = (char **) elem->q_data;
     argv[1] = info[U_NAME];
@@ -769,6 +934,8 @@ char **argv;
 {
     struct qelem *top;
 
+    if (YesNoQuestion("This will take a long time.  Are you sure", 0) == FALSE)
+      return (DM_NORMAL);
     top = GetUserInfo(CLASS, argv[1], (char *) NULL);
     Loop(top, PrintUserName);
 
@@ -777,6 +944,28 @@ char **argv;
 }
 
 
+/*     Function Name: ShowUserById
+ *     Description: Shows user information given an ID number.
+ *     Arguments: argc, argv - ID number in argv[1].
+ *     Returns: DM_NORMAL
+ */
+
+/* ARGSUSED */
+int
+ShowUserById(argc, argv)
+int argc;
+char *argv[];
+{
+    struct qelem *top, *elem;
+
+    elem = top = GetUserInfo(ID, argv[1], (char *) NULL);
+    Loop(elem, PrintUserInfo);
+
+    FreeQueue(top);
+    return (DM_NORMAL);
+}
+
+
 /*     Function Name: GetKrbmap
  *     Description: Shows user <-> Kerberos mappings
  *     Arguments: argc, argv - argv[1] contains the user login name,
@@ -830,7 +1019,7 @@ char **argv;
 {
     int stat;
 
-    if (!index(argv[KMAP_PRINCIPAL + 1], '@')) {
+    if (!strchr(argv[KMAP_PRINCIPAL + 1], '@')) {
        Put_message("Please specify a realm for the kerberos principal.");
        return(DM_NORMAL);
     }
@@ -865,3 +1054,53 @@ char **argv;
     }
     return(DM_NORMAL);
 }
+
+
+hex_dump(p)
+unsigned  char *p;
+{
+    char buf[BUFSIZ];
+    int i;
+
+    sprintf(buf, "Size: %d", strlen(p));
+    Put_message(buf);
+    while (strlen(p) >= 8) {
+       sprintf(buf, "%02x %02x %02x %02x %02x %02x %02x %02x",
+               p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+       Put_message(buf);
+       p += 8;
+    }
+    switch (strlen(p)) {
+    case 7:
+       sprintf(buf, "%02x %02x %02x %02x %02x %02x %02x",
+               p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
+       break;
+    case 6:
+       sprintf(buf, "%02x %02x %02x %02x %02x %02x",
+               p[0], p[1], p[2], p[3], p[4], p[5]);
+       break;
+    case 5:
+       sprintf(buf, "%02x %02x %02x %02x %02x",
+               p[0], p[1], p[2], p[3], p[4]);
+       break;
+    case 4:
+       sprintf(buf, "%02x %02x %02x %02x",
+               p[0], p[1], p[2], p[3]);
+       break;
+    case 3:
+       sprintf(buf, "%02x %02x %02x",
+               p[0], p[1], p[2]);
+       break;
+    case 2:
+       sprintf(buf, "%02x %02x",
+               p[0], p[1]);
+       break;
+    case 1:
+       sprintf(buf, "%02x",
+               p[0]);
+       break;
+    default:
+       return;
+    }
+    Put_message(buf);
+}
This page took 0.063337 seconds and 4 git commands to generate.