From: Dave West Date: Wed, 28 May 2008 00:40:47 +0000 (+0000) Subject: Now we name all the private contexts. X-Git-Tag: v7.86~2202 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=e739cb7572012e2a0a9b820757f4e2adf7b37a63 Now we name all the private contexts. Auto purger will complain if a user 0 has no name or does not have a SYS_* type name as this is considered a bug. upgrade module will try to fix up names of user 0 and will delete any user 0 that does not fit the criteria without warning. User name Citadel is no longer reserved but all usernames starting SYS_* are. --- diff --git a/citadel/include/ctdl_module.h b/citadel/include/ctdl_module.h index d17a9861b..97fdf7eb3 100644 --- a/citadel/include/ctdl_module.h +++ b/citadel/include/ctdl_module.h @@ -147,6 +147,7 @@ void CtdlThreadAllocTSD(void); * You must free the returned pointer when done. */ struct CitContext *CtdlGetContextArray (int *count); +void CtdlFillPrivateContext(struct CitContext *context, char *name); diff --git a/citadel/modules/checkpoint/serv_checkpoint.c b/citadel/modules/checkpoint/serv_checkpoint.c index 8c7176f0b..49d361194 100644 --- a/citadel/modules/checkpoint/serv_checkpoint.c +++ b/citadel/modules/checkpoint/serv_checkpoint.c @@ -49,10 +49,8 @@ void *checkpoint_thread(void *arg) { CtdlLogPrintf(CTDL_DEBUG, "checkpoint_thread() initializing\n"); - memset(&checkpointCC, 0, sizeof(struct CitContext)); - checkpointCC.internal_pgm = 1; - checkpointCC.cs_pid = 0; - pthread_setspecific(MyConKey, (void *)&checkpointCC ); + CtdlFillPrivateContext(&checkpointCC, "checkpoint"); + citthread_setspecific(MyConKey, (void *)&checkpointCC ); while (!CtdlThreadCheckStop()) { cdb_checkpoint(); diff --git a/citadel/modules/expire/serv_expire.c b/citadel/modules/expire/serv_expire.c index ac5debf2c..ea852dd49 100644 --- a/citadel/modules/expire/serv_expire.c +++ b/citadel/modules/expire/serv_expire.c @@ -115,6 +115,7 @@ struct ValidUser *ValidUserList = NULL; int messages_purged; int users_not_purged; char *users_corrupt_msg = NULL; +char *users_zero_msg = NULL; struct ctdlroomref *rr = NULL; @@ -462,6 +463,12 @@ void do_user_purge(struct ctdluser *us, void *data) { { users_corrupt_msg = malloc(SIZ); strcpy(users_corrupt_msg, "The auto-purger found the following user numbers with no name.\n" + "If the user number is 0 you should report this to the Citadel development\n" + "team either by a bugzilla report at http://bugzilla.citadel.org or\n" + "posting a message in the Citadel Support room on Uncensored at\n" + "https://uncensored.citadel.org You should make it clear that you have seen a\n" + "user 0 messages in the Aide room which means a module has not named its\n" + "private context.\n" "Unfortunately the auto-purger is not yet able to fix this problem.\n" "This problem is not considered serious since a user with no name can\n" "not log in.\n"); @@ -470,6 +477,26 @@ void do_user_purge(struct ctdluser *us, void *data) { users_corrupt_msg=realloc(users_corrupt_msg, strlen(users_corrupt_msg)+SIZ); snprintf(&users_corrupt_msg[strlen(users_corrupt_msg)], SIZ, " %ld\n", us->usernum); } + else if (us->usernum == 0L) + { + purge=0; + if (users_zero_msg == NULL) + { + users_zero_msg = malloc(SIZ); + strcpy(users_zero_msg, "The auto-purger found a user with a user number of 0 but no name.\n" + "This is the result of a bug where a private contaxt has been created but\n" + "not named.\n\n" + "Please report this to the Citadel development team either by a bugzilla\n" + "report at http://bugzilla.citadel.org or by posting a message in the\n" + "Citadel Support room on Uncensored at https://uncensored.citadel.org\n" + "You should make it clear that you have seen a user 0 messages in the\n" + "Aide room which means a module has not named its private context.\n\n" + "This problem is not considered serious since it does not constitute a\n" + "security risk and should not impare system operation.\n" + ); + } + } + } @@ -546,6 +573,12 @@ int PurgeUsers(void) { users_corrupt_msg = NULL; } + if(users_zero_msg) + { + aide_message(users_zero_msg, "User Zero Message"); + free (users_zero_msg); + users_zero_msg = NULL; + } CtdlLogPrintf(CTDL_DEBUG, "Purged %d users.\n", num_users_purged); return(num_users_purged); @@ -767,10 +800,8 @@ void *purge_databases(void *args) CtdlLogPrintf(CTDL_DEBUG, "Auto-purger_thread() initializing\n"); - memset(&purgerCC, 0, sizeof(struct CitContext)); - purgerCC.internal_pgm = 1; - purgerCC.cs_pid = 0; - pthread_setspecific(MyConKey, (void *)&purgerCC ); + CtdlFillPrivateContext(&purgerCC, "purger"); + citthread_setspecific(MyConKey, (void *)&purgerCC ); while (!CtdlThreadCheckStop()) { /* Do the auto-purge if the current hour equals the purge hour, diff --git a/citadel/modules/fulltext/serv_fulltext.c b/citadel/modules/fulltext/serv_fulltext.c index 5147bad19..280c6ca1f 100644 --- a/citadel/modules/fulltext/serv_fulltext.c +++ b/citadel/modules/fulltext/serv_fulltext.c @@ -348,10 +348,8 @@ void *indexer_thread(void *arg) { CtdlLogPrintf(CTDL_DEBUG, "indexer_thread() initializing\n"); - memset(&indexerCC, 0, sizeof(struct CitContext)); - indexerCC.internal_pgm = 1; - indexerCC.cs_pid = 0; - pthread_setspecific(MyConKey, (void *)&indexerCC ); + CtdlFillPrivateContext(&indexerCC, "indexer"); + citthread_setspecific(MyConKey, (void *)&indexerCC ); while (!CtdlThreadCheckStop()) { do_fulltext_indexing(); diff --git a/citadel/modules/network/serv_network.c b/citadel/modules/network/serv_network.c index 969cefed2..2e963c825 100644 --- a/citadel/modules/network/serv_network.c +++ b/citadel/modules/network/serv_network.c @@ -2085,10 +2085,8 @@ void *network_do_queue(void *args) { struct CitContext networkerCC; /* Give the networker its own private CitContext */ - memset(&networkerCC, 0, sizeof(struct CitContext)); - networkerCC.internal_pgm = 1; - networkerCC.cs_pid = 0; - pthread_setspecific(MyConKey, (void *)&networkerCC ); + CtdlFillPrivateContext(&networkerCC, "network"); + citthread_setspecific(MyConKey, (void *)&networkerCC ); /* * Run the full set of processing tasks no more frequently diff --git a/citadel/modules/rssclient/serv_rssclient.c b/citadel/modules/rssclient/serv_rssclient.c index 851b9cbb4..16ca6ea83 100644 --- a/citadel/modules/rssclient/serv_rssclient.c +++ b/citadel/modules/rssclient/serv_rssclient.c @@ -519,10 +519,8 @@ void *rssclient_scan(void *args) { struct CitContext rssclientCC; /* Give this thread its own private CitContext */ - memset(&rssclientCC, 0, sizeof(struct CitContext)); - rssclientCC.internal_pgm = 1; - rssclientCC.cs_pid = 0; - pthread_setspecific(MyConKey, (void *)&rssclientCC ); + CtdlFillPrivateContext(&rssclientCC, "rssclient"); + citthread_setspecific(MyConKey, (void *)&rssclientCC ); CtdlThreadAllocTSD(); diff --git a/citadel/modules/upgrade/serv_upgrade.c b/citadel/modules/upgrade/serv_upgrade.c index dfdad1b72..ce147b9b9 100644 --- a/citadel/modules/upgrade/serv_upgrade.c +++ b/citadel/modules/upgrade/serv_upgrade.c @@ -47,6 +47,50 @@ #include "ctdl_module.h" + +/* + * Fix up the name for Citadel user 0 and try to remove any extra users with number 0 + */ +void fix_sys_user_name(void) +{ + struct ctdluser usbuf; + char usernamekey[USERNAME_SIZE]; + + /** If we have a user called Citadel rename them to SYS_Citadel */ + if (getuser(&usbuf, "Citadel") == 0) + { + rename_user("Citadel", "SYS_Citadel"); + } + + while (getuserbynumber(&usbuf, 0) == 0) + { + /* delete user with number 0 and no name */ + if (IsEmptyStr(usbuf.fullname)) + cdb_delete(CDB_USERS, "", 0); + else + { /* temporarily set this user to -1 */ + usbuf.usernum = -1; + putuser(&usbuf); + } + } + + /** Make sure user SYS_* is user 0 */ + while (getuserbynumber(&usbuf, -1) == 0) + { + if (strncmp(usbuf.fullname, "SYS_", 4)) + { /** Delete any user 0 that doesn't start with SYS_ */ + makeuserkey(usernamekey, usbuf.fullname); + cdb_delete(CDB_USERS, usernamekey, strlen(usernamekey)); + } + else + { + usbuf.usernum = 0; + putuser(&usbuf); + } + } +} + + /* * Back end processing function for cmd_bmbx */ @@ -225,7 +269,9 @@ void check_server_upgrades(void) { if ((CitControl.version > 000) && (CitControl.version < 659)) { rebuild_euid_index(); } - + if (CitControl.version > 734) { + fix_sys_user_name(); + } CitControl.version = REV_LEVEL; put_control(); } diff --git a/citadel/server_main.c b/citadel/server_main.c index cfb7ce64f..ea03a202c 100644 --- a/citadel/server_main.c +++ b/citadel/server_main.c @@ -249,18 +249,21 @@ int main(int argc, char **argv) */ master_startup(); + /* + * Run any upgrade entry points + */ + CtdlLogPrintf(CTDL_INFO, "Upgrading modules.\n"); + upgrade_modules(); -/* - * Initialise the user 0 to have a name. It would be nice to do it in InitializeMasterCC - * since it is contained within the MasterCC but we can't because the DB isn't available - * at that time so we do it seperate. +/** + * Load the user for the masterCC or create them if they don't exist */ - /** Give user 0 a name and create them if necessary */ - if (getuser(&masterCC.user, "Citadel")) + if (getuser(&masterCC.user, "SYS_Citadel")) { - getuserbynumber(&masterCC.user, 0); - strcpy (masterCC.user.fullname, "Citadel"); + /** User doesn't exist. We can't use create user here as the user number needs to be 0 */ + strcpy (masterCC.user.fullname, "SYS_Citadel") ; putuser(&masterCC.user); + getuser(&masterCC.user, "SYS_Citadel"); /** Just to be safe */ } /* @@ -284,11 +287,6 @@ int main(int argc, char **argv) CitadelServiceTCP); - /* - * Run any upgrade entry points - */ - CtdlLogPrintf(CTDL_INFO, "Upgrading modules.\n"); - upgrade_modules(); /* diff --git a/citadel/sysdep.c b/citadel/sysdep.c index 265f879e7..14e9e3e9d 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -71,6 +71,8 @@ #include "ctdl_module.h" #include "threads.h" +#include "user_ops.h" + #ifdef DEBUG_MEMORY_LEAKS struct igheap { @@ -463,6 +465,27 @@ struct CitContext *CtdlGetContextArray(int *count) return nptr; } + + +/** + * This function returns a private context with the user filled in correctly + */ +void CtdlFillPrivateContext(struct CitContext *context, char *name) +{ + char sysname[USERNAME_SIZE]; + + memset(context, 0, sizeof(struct CitContext)); + context->internal_pgm = 1; + context->cs_pid = 0; + strcpy (sysname, "SYS_"); + strcat (sysname, name); + if (getuser(&(context->user), sysname)) + { + strcpy(context->user.fullname, sysname); + putuser(&(context->user)); + } +} + /* * The following functions implement output buffering. If the kernel supplies * native TCP buffering (Linux & *BSD), use that; otherwise, emulate it with diff --git a/citadel/user_ops.c b/citadel/user_ops.c index e376c9d32..e75bebccf 100644 --- a/citadel/user_ops.c +++ b/citadel/user_ops.c @@ -59,7 +59,7 @@ int chkpwd_read_pipe[2]; * makeuserkey() - convert a username into the format used as a database key * (it's just the username converted into lower case) */ -static INLINE void makeuserkey(char *key, char *username) { +INLINE void makeuserkey(char *key, char *username) { int i, len; len = strlen(username); @@ -427,9 +427,9 @@ int CtdlLoginExistingUser(char *authname, char *trythisname) if (trythisname == NULL) return login_not_found; - if (!strcasecmp(trythisname, "Citadel")) + if (!strncasecmp(trythisname, "SYS_", 4)) { - CtdlLogPrintf(CTDL_DEBUG, "System user \"Citadel\" is not allowed to log in.\n"); + CtdlLogPrintf(CTDL_DEBUG, "System user \"%s\" is not allowed to log in.\n", trythisname); return login_not_found; } diff --git a/citadel/user_ops.h b/citadel/user_ops.h index 9aad99642..bf1be2cfb 100644 --- a/citadel/user_ops.h +++ b/citadel/user_ops.h @@ -93,3 +93,4 @@ void start_chkpwd_daemon(void); #define RENAMEUSER_ALREADY_EXISTS 3 /* An account with the desired new name already exists */ int rename_user(char *oldname, char *newname); +INLINE void makeuserkey(char *key, char *username);