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);
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;
}
}
}
+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;
/* Register a user in Moira */
int register_user(int uid, char *username)
{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char pin[USERS_PIN_SIZE];
+ EXEC SQL END DECLARE SECTION;
char uidbuf[10], *qargv[3], *motd = NULL;
long status;
status = krb_get_svc_in_tkt(REG_SVR_PRINCIPAL, REG_SVR_INSTANCE,
krb_realmofhost(hostname), MOIRA_SNAME,
- shorthostname, 1, KEYFILE);
+ shorthostname, 3, 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");
return MR_INTERNAL;
}
+ EXEC SQL SELECT pin INTO :pin FROM users WHERE unix_uid = :uid;
+
sprintf(uidbuf, "%d", uid);
qargv[0] = uidbuf;
qargv[1] = username;
- qargv[2] = "IMAP";
+
+ /* HACK: If user has a PIN set, they're from Sloan.
+ * Give them Exchange poboxes.
+ */
+ if (*pin != '\0')
+ qargv[2] = "EXCHANGE";
+ else
+ qargv[2] = "IMAP";
+
status = mr_query("register_user", 3, qargv, NULL, NULL);
mr_disconnect();
return status;
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;