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);
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 */
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);
}
}
+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;
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;