]> andersk Git - moira.git/commitdiff
Add CLGN (server) / LOGC (client) protocol option to check if a username
authorzacheiss <zacheiss>
Wed, 29 Jun 2005 06:39:35 +0000 (06:39 +0000)
committerzacheiss <zacheiss>
Wed, 29 Jun 2005 06:39:35 +0000 (06:39 +0000)
is available and give the user a chance to confirm they want to use it.

Also fix missing whitespace in errors file for BAD_PIN error code.

reg_svr/errors
reg_svr/protocol.c
reg_svr/reg_svr.h
reg_svr/reg_svr.pc

index eb60d904de7cdddab2ebb0f43699bda5944ea83e..8ce637758b6262673443cdadff1508628780604b 100644 (file)
@@ -93,8 +93,10 @@ You should be able to log in by tomorrow morning using your Athena
 username (%s) and the password you chose.
 
 Welcome to Athena!
-#21 BAD_PIN
+# 21 BAD_PIN
 The PIN you typed was incorrect. Please make sure you typed it correctly.
 
 If you do not remember your PIN, you will need to contact the Athena
 User Accounts Office in N42-105A, x3-1325.
+# 22 USERNAME_AVAILABLE
+The username "%s" is available for you to use.
index aa82a83f00a5f8bce3e1ee17cdf3dc8dd9373c67..e6e4a84c243a3d682166bfeebc1c44ba9c4afa15 100644 (file)
@@ -44,6 +44,7 @@ struct _handler {
   { "PSWD", PSWD },
   { "QUIT", QUIT },
   { "SPIN", SPIN },
+  { "CLGN", CLGN },
   { NULL, NULL }
 };
 
index 516bae9d1138aca0944c043f8e421bb653cda5d6..c66c018300fb8630cdd0af7894665cd7a1c06a86 100644 (file)
@@ -23,6 +23,7 @@ typedef struct reg_client {
 void RIFO(reg_client *rc, int argc, char **argv);
 void SWRD(reg_client *rc, int argc, char **argv);
 void SPIN(reg_client *rc, int argc, char **argv);
+void CLGN(reg_client *rc, int argc, char **argv);
 void LOGN(reg_client *rc, int argc, char **argv);
 void PSWD(reg_client *rc, int argc, char **argv);
 void QUIT(reg_client *rc, int argc, char **argv);
@@ -40,7 +41,7 @@ enum { NO_MESSAGE, INTERNAL_ERROR, PROTOCOL_ERROR, DATABASE_CLOSED,
        BAD_SIX_WORDS, BAD_USERNAME, USERNAME_UNAVAILABLE, 
        RESERVED_USERNAME_UNAVAILABLE, USERNAME_OK, PASSWORD_SHORT,
        PASSWORD_SIMPLE, PASSWORD_SAMPLE, KADM_ERROR, DONE, BAD_PIN,
-       NUM_REG_ERRORS };
+       USERNAME_AVAILABLE, NUM_REG_ERRORS };
 
 #define TIMEOUT 300 /* 5 minutes */
 
index 43e52e302592d56617046e399f3fffa93ef531a2..4a592f80cfeebb7243ccd9a6d0f2502a2f8f3c45 100644 (file)
@@ -42,6 +42,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);
@@ -534,6 +535,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;
@@ -882,6 +957,37 @@ 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;
+
+  return MR_SUCCESS;
+}
+
 void fixname(char *name)
 {
   char *s, *d;
This page took 0.875073 seconds and 5 git commands to generate.