]> andersk Git - moira.git/blobdiff - reg_svr/reg_svr.pc
Build without krb4 if it's unavailable.
[moira.git] / reg_svr / reg_svr.pc
index acb65068ff6e7bc165cb693278c42a2fd7c46fcc..1016e18649431f7594cfcf918e4271890f1183f6 100644 (file)
@@ -33,7 +33,9 @@
 #include <unistd.h>
 
 #include <com_err.h>
+#ifdef HAVE_KRB4
 #include <krb.h>
+#endif
 
 EXEC SQL INCLUDE sqlca;
 
@@ -42,6 +44,7 @@ RCSID("$Header$");
 char *whoami, *hostname, *shorthostname;
 
 char *find_usernames(char *first, char *middle, char *last);
+int check_username_available(char *username);
 void fixname(char *name);
 int register_user(int uid, char *username);
 void mr_com_err(const char *whoami, long code, const char *fmt, va_list pvar);
@@ -358,6 +361,9 @@ void RIFO(reg_client *rc, int argc, char **argv)
        continue;
       if (strlen(first) > 3 && strlen(ufirst) < 3)
        continue;
+      if (!*ufirst && !*ulast)
+       continue;
+
       /* Ignore the middle name since Moira doesn't have those reliably */
       break;
     }
@@ -531,6 +537,80 @@ void SPIN(reg_client *rc, int argc, char **argv)
     }
 }
 
+void CLGN(reg_client *rc, int argc, char **argv)
+{
+  int i;
+  char *login;
+  long status;
+
+  if (!rc->uid || rc->id || rc->username || argc != 1)
+    {
+      reply(rc, PROTOCOL_ERROR, "INIT", "c", NULL);
+      return;
+    }
+
+  login = argv[0];
+  
+  /* make sure someone's not trying to overrun reply */
+  if (strlen(login) > 100)
+    {
+      com_err(whoami, 0, "Buffer overrun attempted? Closing connection");
+      rc->lastmod = 0;
+      return;
+    }
+
+  if ((strlen(login) < 3) || (strlen(login) > USERS_LOGIN_SIZE - 1) ||
+      (login[0] == '_') || isdigit(login[0]))
+    {
+      reply(rc, BAD_USERNAME, "GETL", "c", rc->suggestions, login,
+            3, USERS_LOGIN_SIZE - 1);
+      return;
+    }
+
+  for (i = 0; i < strlen(login); i++)
+    {
+      if (!islower(login[i]) && !isdigit(login[i]) && (login[i] != '_'))
+        {
+          reply(rc, BAD_USERNAME, "GETL", "c", rc->suggestions, login,
+                3, USERS_LOGIN_SIZE - 1);
+          return;
+        }
+    }
+
+  status = check_kerberos(login);
+  if (status == MR_SUCCESS)
+    {
+      status = check_username_available(login);
+      if (status == MR_SUCCESS)
+       {
+         reply(rc, USERNAME_AVAILABLE, "LOGC", "c", login, login);
+         return;
+       }
+    }
+
+  if (status == MR_IN_USE)
+    {
+      if (rc->reserved_username)
+        {
+          reply(rc, RESERVED_USERNAME_UNAVAILABLE, "INIT", "c", NULL,
+                rc->username);
+          return;
+        }
+      reply(rc, USERNAME_UNAVAILABLE, "GETL", "c", rc->suggestions);
+      return;
+    }
+  else if (status == MR_DOWN)
+    {
+      reply(rc, DATABASE_CLOSED, "INIT", "c", NULL);
+      return;
+    }
+  else if (status != MR_SUCCESS)
+    {
+      reply(rc, INTERNAL_ERROR, "INIT", "c", NULL, error_message(status));
+      return;
+    }
+}
+
 void LOGN(reg_client *rc, int argc, char **argv)
 {
   int i;
@@ -710,6 +790,9 @@ void QUIT(reg_client *rc, int argc, char **argv)
 /* Register a user in Moira */
 int register_user(int uid, char *username)
 {
+  EXEC SQL BEGIN DECLARE SECTION;
+  char class[USERS_TYPE_SIZE];
+  EXEC SQL END DECLARE SECTION;
   char uidbuf[10], *qargv[3], *motd = NULL;
   long status;
 
@@ -724,13 +807,7 @@ int register_user(int uid, char *username)
       return MR_DOWN;
     }
 
-  status = krb_get_svc_in_tkt(REG_SVR_PRINCIPAL, REG_SVR_INSTANCE,
-                             krb_realmofhost(hostname), MOIRA_SNAME,
-                             shorthostname, 1, KEYFILE);
-  if (status)
-    status += ERROR_TABLE_BASE_krb;
-  else
-    status = mr_auth("reg_svr");
+  status = mr_krb5_auth("reg_svr");
   if (status)
     {
       com_err(whoami, status, "authenticating to moira");
@@ -738,10 +815,28 @@ int register_user(int uid, char *username)
       return MR_INTERNAL;
     }
 
+  EXEC SQL SELECT type INTO :class FROM users WHERE unix_uid = :uid;
+
   sprintf(uidbuf, "%d", uid);
   qargv[0] = uidbuf;
   qargv[1] = username;
-  qargv[2] = "IMAP";
+
+  /* Incoming students should be given Exchange poboxes.
+   * Doesn't work for undergrads in the class of 2100 or higher.
+   */ 
+  if (!strcmp(strtrim(class), "G") || !strncmp(class, "FALL", 4) ||
+      !strncmp(class, "SPRING", 5) || !strncmp(class, "SUMMER", 6) ||
+      !strncmp(class, "20", 2))
+    {
+      com_err(whoami, 0, "assigning EXCHANGE pobox to user %s, class %s", username, class);
+      qargv[2] = "EXCHANGE";
+    }
+  else 
+    {
+      com_err(whoami, 0, "assigning IMAP pobox to user %s, class %s", username, class);
+      qargv[2] = "IMAP";
+    }
+
   status = mr_query("register_user", 3, qargv, NULL, NULL);
   mr_disconnect();
   return status;
@@ -879,6 +974,44 @@ char *find_usernames(char *first, char *middle, char *last)
   return unames;
 }
 
+/* This does the database-side checks to make sure a username is
+ * available.
+ */
+int check_username_available(char *username)
+{
+  int count;
+
+  EXEC SQL SELECT COUNT(login) INTO :count FROM users
+    WHERE login = :username;
+  if (sqlca.sqlcode)
+    return MR_DBMS_ERR;
+  if (count != 0)
+    return MR_IN_USE;
+
+  EXEC SQL SELECT COUNT(name) INTO :count FROM list
+    WHERE name = :username;
+  if (sqlca.sqlcode)
+    return MR_DBMS_ERR;
+  if (count != 0)
+    return MR_IN_USE;
+
+  EXEC SQL SELECT COUNT(label) INTO :count FROM filesys
+    WHERE label = :username;
+  if (sqlca.sqlcode)
+    return MR_DBMS_ERR;
+  if (count != 0)
+    return MR_IN_USE;
+
+  EXEC SQL SELECT COUNT(login) INTO :count FROM userhistory
+    WHERE login = :username;
+  if (sqlca.sqlcode)
+    return MR_DBMS_ERR;
+  if (count != 0)
+    return MR_IN_USE;
+
+  return MR_SUCCESS;
+}
+
 void fixname(char *name)
 {
   char *s, *d;
This page took 0.054541 seconds and 4 git commands to generate.