* usually more strict because you're not really supposed to dump/load and
* upgrade at the same time.
*/
-#define REV_LEVEL 735 /* This version */
+#define REV_LEVEL 736 /* This version */
#define REV_MIN 591 /* Oldest compatible database */
#define EXPORT_REV_MIN 733 /* Oldest compatible export files */
#define LIBCITADEL_MIN 113 /* Minimum required version of libcitadel */
exit
esac
-for x in 00 01 02 03 04 05 06 07 08 09 0a
+for x in 00 01 02 03 04 05 06 07 08 09 0a 0b
do
filename=cdb.$x
echo Dumping $filename
echo Removing old databases
rm -f ./data/*
-for x in 00 01 02 03 04 05 06 07 08 09 0a
+for x in 00 01 02 03 04 05 06 07 08 09 0a 0b
do
filename=cdb.$x
echo Loading $filename
for (i = 0; i < MAXCDB; i++)
if (cursors[i] != NULL) {
CtdlLogPrintf(CTDL_EMERG,
- "cdb_*: cursor still in progress on cdb %d: %s\n",
+ "cdb_*: cursor still in progress on cdb %02x: %s\n",
i, msg);
abort();
}
DB_CREATE | DB_AUTO_COMMIT | DB_THREAD,
0600);
if (ret) {
- CtdlLogPrintf(CTDL_EMERG, "db_open[%d]: %s\n", i,
+ CtdlLogPrintf(CTDL_EMERG, "db_open[%02x]: %s\n", i,
db_strerror(ret));
exit(CTDLEXIT_DB);
}
/* close the tables */
for (a = 0; a < MAXCDB; ++a) {
- CtdlLogPrintf(CTDL_INFO, "Closing database %d\n", a);
+ CtdlLogPrintf(CTDL_INFO, "Closing database %02x\n", a);
ret = dbp[a]->close(dbp[a], 0);
if (ret) {
CtdlLogPrintf(CTDL_EMERG,
};
+
+
+
+/**************************************************************************/
+/* */
+/* Functions in this section handle Citadel internal OpenID mapping stuff */
+/* */
+/**************************************************************************/
+
+
+/*
+ * Attach or detach an OpenID to a Citadel account
+ */
+
+enum {
+ moa_detach,
+ moa_attach
+};
+
+int modify_openid_associations(struct ctdluser *who, char *claimed_id, int operation)
+{
+ if (!who) return(1);
+ if (!claimed_id) return(1);
+ if (IsEmptyStr(claimed_id)) return(1);
+
+ return(2); // error because we are not done yet FIXME
+}
+
+
+/*
+ * When a user is being deleted, we have to delete any OpenID associations
+ */
+void openid_purge(struct ctdluser *usbuf) {
+ /* FIXME finish this */
+}
+
+
+
+
+
+
+
+/**************************************************************************/
+/* */
+/* Functions in this section handle OpenID protocol */
+/* */
+/**************************************************************************/
+
+
/*
* Locate a <link> tag and, given its 'rel=' parameter, return its 'href' parameter
*/
struct CitContext *CCC = CC; /* CachedCitContext - performance boost */
struct ctdl_openid *oiddata;
+ /* commented out because we may be attempting to attach an OpenID to
+ * an existing account that is logged in
+ *
if (CCC->logged_in) {
cprintf("%d Already logged in.\n", ERROR + ALREADY_LOGGED_IN);
return;
}
+ */
if (CCC->openid_data != NULL) {
free(CCC->openid_data);
char k_keyname[128];
char k_o_keyname[128];
char *k_value = NULL;
-
char valbuf[1024];
+
struct fh_data fh = {
valbuf,
0,
curl_formfree(formpost);
valbuf[fh.total_bytes_received] = 0;
+ int success = 0;
+
if (bmstrcasestr(valbuf, "is_valid:true")) {
- CtdlLogPrintf(CTDL_DEBUG, "\e[32mAUTHENTICATION SUCCEEDED\e[0m\n", valbuf);
- }
- else {
- CtdlLogPrintf(CTDL_DEBUG, "\e[31mAUTHENTICATION FAILED\e[0m\n", valbuf);
+ success = 1;
}
- /* FIXME do something with the results */
+ CtdlLogPrintf(CTDL_DEBUG, "Authentication %s.\n", (success ? "succeeded" : "failed") );
/* Respond to the client */
- cprintf("message|FIXME finish this\n");
+
+ if (success) {
+
+ /* If we were already logged in, attach the OpenID to the user's account */
+ if (CC->logged_in) {
+ if (modify_openid_associations(&CC->user, oiddata->claimed_id, moa_attach) == 0) {
+ cprintf("attach\n");
+ }
+ else {
+ cprintf("fail\n");
+ }
+ }
+
+ /* Otherwise, a user is attempting to log in using the validated OpenID */
+ else {
+ cprintf("fail\n"); // FIXME do the login here!!
+ }
+
+ }
+ else {
+ cprintf("fail\n");
+ }
cprintf("000\n");
/* Free the hash list */
// sig = [28] vixxxU4MAqWfxxxxCfrHv3TxxxhEw=
+
+
+/**************************************************************************/
+/* */
+/* Functions in this section handle module initialization and shutdown */
+/* */
+/**************************************************************************/
+
+
/*
* This cleanup function blows away the temporary memory used by this module.
*/
}
-
CTDL_MODULE_INIT(openid_rp)
{
if (!threading)
CtdlRegisterProtoHook(cmd_oids, "OIDS", "Setup OpenID authentication");
CtdlRegisterProtoHook(cmd_oidf, "OIDF", "Finalize OpenID authentication");
CtdlRegisterSessionHook(openid_cleanup_function, EVT_STOP);
+ CtdlRegisterUserHook(openid_purge, EVT_PURGEUSER);
}
/* return our Subversion id for the Log */
if ((CitControl.version > 000) && (CitControl.version < 659)) {
rebuild_euid_index();
}
- if (CitControl.version > 734) {
+ if (CitControl.version < 735) {
fix_sys_user_name();
}
+ if (CitControl.version < 736) {
+ rebuild_usersbynumber();
+ }
CitControl.version = REV_LEVEL;
put_control();
}
CTDL_MODULE_UPGRADE(upgrade)
{
check_server_upgrades();
+ rebuild_usersbynumber(); // FIXME take this out
/* return our Subversion id for the Log */
return "$Id$";
CDB_BIGMSGS, /* larger message bodies */
CDB_FULLTEXT, /* full text search index */
CDB_EUIDINDEX, /* locate msgs by EUID */
+ CDB_USERSBYNUMBER, /* index of users by number */
MAXCDB /* total number of CDB's defined */
};
cdb_delete(CDB_USERS, oldnamekey, strlen(oldnamekey));
safestrncpy(usbuf.fullname, newname, sizeof usbuf.fullname);
putuser(&usbuf);
+ cdb_store(CDB_USERSBYNUMBER, &usbuf.usernum, sizeof(long),
+ usbuf.fullname, strlen(usbuf.fullname)+1 );
+
retcode = RENAMEUSER_OK;
}
}
}
/*
- * getuserbynumber() - get user by number
- * returns 0 if user was found
+ * getuserbynumber() - get user by number
+ * returns 0 if user was found
*
- * WARNING: don't use this function unless you absolutely have to. It does
- * a sequential search and therefore is computationally expensive.
+ * Note: fetching a user this way requires one additional database operation.
*/
-int getuserbynumber(struct ctdluser *usbuf, long int number)
+int getuserbynumber(struct ctdluser *usbuf, long number)
{
- struct cdbdata *cdbus;
+ struct cdbdata *cdbun;
+ int r;
- cdb_rewind(CDB_USERS);
+ cdbun = cdb_fetch(CDB_USERSBYNUMBER, &number, sizeof(long));
+ if (cdbun == NULL) {
+ CtdlLogPrintf(CTDL_INFO, "User %ld not found\n", number);
+ return(-1);
+ }
- while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
- memset(usbuf, 0, sizeof(struct ctdluser));
- memcpy(usbuf, cdbus->ptr,
- ((cdbus->len > sizeof(struct ctdluser)) ?
- sizeof(struct ctdluser) : cdbus->len));
- cdb_free(cdbus);
- if (usbuf->usernum == number) {
- cdb_close_cursor(CDB_USERS);
- return (0);
- }
+ CtdlLogPrintf(CTDL_INFO, "User %ld maps to %s\n", number, cdbun->ptr);
+ r = getuser(usbuf, cdbun->ptr);
+ cdb_free(cdbun);
+ return(r);
+}
+
+
+
+/*
+ * Helper function for rebuild_usersbynumber()
+ */
+void rebuild_ubn_for_user(struct ctdluser *usbuf, void *data) {
+
+ struct ubnlist {
+ struct ubnlist *next;
+ char username[USERNAME_SIZE];
+ long usernum;
+ };
+
+ static struct ubnlist *u = NULL;
+ struct ubnlist *ptr = NULL;
+
+ /* Lazy programming here. Call this function as a ForEachUser backend
+ * in order to queue up the room names, or call it with a null user
+ * to make it do the processing.
+ */
+ if (usbuf != NULL) {
+ ptr = (struct ubnlist *) malloc(sizeof (struct ubnlist));
+ if (ptr == NULL) return;
+
+ ptr->usernum = usbuf->usernum;
+ safestrncpy(ptr->username, usbuf->fullname, sizeof ptr->username);
+ ptr->next = u;
+ u = ptr;
+ return;
}
- return (-1);
+
+ while (u != NULL) {
+ CtdlLogPrintf(CTDL_DEBUG, "Rebuilding usersbynumber index %10ld : %s\n",
+ u->usernum, u->username);
+ cdb_store(CDB_USERSBYNUMBER, &u->usernum, sizeof(long), u->username, strlen(u->username)+1);
+
+ ptr = u;
+ u = u->next;
+ free(ptr);
+ }
+}
+
+
+
+/*
+ * Rebuild the users-by-number index
+ */
+void rebuild_usersbynumber(void) {
+ cdb_trunc(CDB_USERSBYNUMBER); /* delete the old indices */
+ ForEachUser(rebuild_ubn_for_user, NULL); /* enumerate the users */
+ rebuild_ubn_for_user(NULL, NULL); /* and index them */
}
+
/*
* getuserbyuid() - get user by system uid (for PAM mode authentication)
* returns 0 if user was found
/* delete any existing user/room relationships */
cdb_delete(CDB_VISIT, &usbuf.usernum, sizeof(long));
+ /* delete the users-by-number index record */
+ cdb_delete(CDB_USERSBYNUMBER, &usbuf.usernum, sizeof(long));
+
/* delete the userlog entry */
cdb_delete(CDB_USERS, usernamekey, strlen(usernamekey));
usbuf.axlevel = 6;
}
- /* add user to userlog */
+ /* add user to the database */
putuser(&usbuf);
+ cdb_store(CDB_USERSBYNUMBER, &usbuf.usernum, sizeof(long), usbuf.fullname, strlen(usbuf.fullname)+1);
/*
* Give the user a private mailbox and a configuration room.
int is_aide (void);
int is_room_aide (void);
int getuserbynumber (struct ctdluser *usbuf, long int number);
+void rebuild_usersbynumber(void);
void cmd_user (char *cmdbuf);
void session_startup (void);
void logout (void);