Now we name all the private contexts.
authorDave West <davew@uncensored.citadel.org>
Wed, 28 May 2008 00:40:47 +0000 (00:40 +0000)
committerDave West <davew@uncensored.citadel.org>
Wed, 28 May 2008 00:40:47 +0000 (00:40 +0000)
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.

citadel/include/ctdl_module.h
citadel/modules/checkpoint/serv_checkpoint.c
citadel/modules/expire/serv_expire.c
citadel/modules/fulltext/serv_fulltext.c
citadel/modules/network/serv_network.c
citadel/modules/rssclient/serv_rssclient.c
citadel/modules/upgrade/serv_upgrade.c
citadel/server_main.c
citadel/sysdep.c
citadel/user_ops.c
citadel/user_ops.h

index d17a9861bcc91b5eb37b2034465adb14ec42131c..97fdf7eb36ea1382cba23c183e2f330fe74aae7e 100644 (file)
@@ -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);
 
 
 
index 8c7176f0bf9ef8028c9d7ae9545a06e38ae981ca..49d361194da40e431c50019c9ae9b77c79d4d579 100644 (file)
@@ -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();
index ac5debf2ce388456e7ade160810d915834681ce5..ea852dd49dd135b016e33d98f29020c09bf78a2f 100644 (file)
@@ -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,
index 5147bad198aadbd11915991daaee3960f25fbe02..280c6ca1f1218fbf5ee600557879b6bd8c74f84d 100644 (file)
@@ -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();
index 969cefed2ca85026836a266eccd0db7947d5a9be..2e963c82574389572501db1d55e2123b91159bf1 100644 (file)
@@ -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
index 851b9cbb4a616ef03eb3ee1305f1edd5f3df598c..16ca6ea83260bdef781d1f67c8173d95da0008e1 100644 (file)
@@ -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();
 
index dfdad1b727bf2e0e8fe40642b476ce067d073661..ce147b9b951888300c35bdc4f7745da45ff8cbbd 100644 (file)
 #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();
 }
index cfb7ce64f0a4bbde9b7fc92c2bf6e9d15bf1d033..ea03a202caf2dc8d28383f9cd15cfb8cfd2d1960 100644 (file)
@@ -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();
        
        
        /*
index 265f879e7838eff771687237610a320512a7b961..14e9e3e9d18b454c9e4967d1c549a3691e5a75b4 100644 (file)
@@ -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
index e376c9d32d0ab4de22d6c5daf855ed74d0026926..e75bebccf6c11d02929d01869091375a4bc8b5a1 100644 (file)
@@ -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;
        }
 
index 9aad99642d3f280fcb5f4a41e05913305105e069..bf1be2cfb88329a9c6468ea05d9b93e9a2a034dc 100644 (file)
@@ -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);