Code shuffling fixes warning with inline function... weirdo.
[citadel.git] / citadel / user_ops.c
index 2f23c3875cc6e710acd8c0ae4247f68bd5961a2b..2b66fdbe24029a51e77fd6896008977b5ebc31c1 100644 (file)
@@ -1,5 +1,21 @@
 /* 
  * Server functions which perform operations on user objects.
+ *
+ * Copyright (c) 1987-2011 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include "sysdep.h"
@@ -13,6 +29,7 @@
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <syslog.h>
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
 #include "threads.h"
 #include "citadel_ldap.h"
 #include "context.h"
-
 #include "ctdl_module.h"
-
-////#define CTDL_INLINE_USR INLINE
 #include "user_ops.h"
 
 /* These pipes are used to talk to the chkpwd daemon, which is forked during startup */
@@ -216,10 +230,10 @@ int rename_user(char *oldname, char *newname) {
                else {          /* Sanity checks succeeded.  Now rename the user. */
                        if (usbuf.usernum == 0)
                        {
-                               CtdlLogPrintf (CTDL_DEBUG, "Can not rename user \"Citadel\".\n");
+                               syslog(LOG_DEBUG, "Can not rename user \"Citadel\".\n");
                                retcode = RENAMEUSER_NOT_FOUND;
                        } else {
-                               CtdlLogPrintf(CTDL_DEBUG, "Renaming <%s> to <%s>\n", oldname, newname);
+                               syslog(LOG_DEBUG, "Renaming <%s> to <%s>\n", oldname, newname);
                                cdb_delete(CDB_USERS, oldnamekey, strlen(oldnamekey));
                                safestrncpy(usbuf.fullname, newname, sizeof usbuf.fullname);
                                CtdlPutUser(&usbuf);
@@ -403,11 +417,11 @@ int CtdlGetUserByNumber(struct ctdluser *usbuf, long number)
 
        cdbun = cdb_fetch(CDB_USERSBYNUMBER, &number, sizeof(long));
        if (cdbun == NULL) {
-               CtdlLogPrintf(CTDL_INFO, "User %ld not found\n", number);
+               syslog(LOG_INFO, "User %ld not found\n", number);
                return(-1);
        }
 
-       CtdlLogPrintf(CTDL_INFO, "User %ld maps to %s\n", number, cdbun->ptr);
+       syslog(LOG_INFO, "User %ld maps to %s\n", number, cdbun->ptr);
        r = CtdlGetUser(usbuf, cdbun->ptr);
        cdb_free(cdbun);
        return(r);
@@ -456,7 +470,7 @@ void rebuild_ubn_for_user(struct ctdluser *usbuf, void *data) {
        }
 
        while (u != NULL) {
-               CtdlLogPrintf(CTDL_DEBUG, "Rebuilding usersbynumber index %10ld : %s\n",
+               syslog(LOG_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);
 
@@ -517,7 +531,7 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
        int found_user;
        long len;
 
-       CtdlLogPrintf(9, "CtdlLoginExistingUser(%s, %s)\n", authname, trythisname);
+       syslog(LOG_DEBUG, "CtdlLoginExistingUser(%s, %s)\n", authname, trythisname);
 
        if ((CC->logged_in)) {
                return login_already_logged_in;
@@ -527,7 +541,7 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
        
        if (!strncasecmp(trythisname, "SYS_", 4))
        {
-               CtdlLogPrintf(CTDL_DEBUG, "System user \"%s\" is not allowed to log in.\n", trythisname);
+               syslog(LOG_DEBUG, "System user \"%s\" is not allowed to log in.\n", trythisname);
                return login_not_found;
        }
 
@@ -556,21 +570,21 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
                struct passwd *tempPwdPtr;
                char pwdbuffer[256];
        
-               CtdlLogPrintf(CTDL_DEBUG, "asking host about <%s>\n", username);
+               syslog(LOG_DEBUG, "asking host about <%s>\n", username);
 #ifdef HAVE_GETPWNAM_R
 #ifdef SOLARIS_GETPWUID
-               CtdlLogPrintf(CTDL_DEBUG, "Calling getpwnam_r()\n");
+               syslog(LOG_DEBUG, "Calling getpwnam_r()\n");
                tempPwdPtr = getpwnam_r(username, &pd, pwdbuffer, sizeof pwdbuffer);
 #else // SOLARIS_GETPWUID
-               CtdlLogPrintf(CTDL_DEBUG, "Calling getpwnam_r()\n");
+               syslog(LOG_DEBUG, "Calling getpwnam_r()\n");
                getpwnam_r(username, &pd, pwdbuffer, sizeof pwdbuffer, &tempPwdPtr);
 #endif // SOLARIS_GETPWUID
 #else // HAVE_GETPWNAM_R
-               CtdlLogPrintf(CTDL_DEBUG, "SHOULD NEVER GET HERE!!!\n");
+               syslog(LOG_DEBUG, "SHOULD NEVER GET HERE!!!\n");
                tempPwdPtr = NULL;
 #endif // HAVE_GETPWNAM_R
                if (tempPwdPtr == NULL) {
-                       CtdlLogPrintf(CTDL_DEBUG, "no such user <%s>\n", username);
+                       syslog(LOG_DEBUG, "no such user <%s>\n", username);
                        return login_not_found;
                }
        
@@ -578,7 +592,7 @@ int CtdlLoginExistingUser(char *authname, const char *trythisname)
                 * If not found, make one attempt to create it.
                 */
                found_user = getuserbyuid(&CC->user, pd.pw_uid);
-               CtdlLogPrintf(CTDL_DEBUG, "found it: uid=%ld, gecos=%s here: %d\n",
+               syslog(LOG_DEBUG, "found it: uid=%ld, gecos=%s here: %d\n",
                        (long)pd.pw_uid, pd.pw_gecos, found_user);
                if (found_user != 0) {
                        len = cutuserkey(username);
@@ -661,11 +675,11 @@ void cmd_user(char *cmdbuf)
        char username[256];
        int a;
 
-       CtdlLogPrintf(CTDL_DEBUG, "cmd_user(%s)\n", cmdbuf);
+       syslog(LOG_DEBUG, "cmd_user(%s)\n", cmdbuf);
        extract_token(username, cmdbuf, 0, '|', sizeof username);
-       CtdlLogPrintf(CTDL_DEBUG, "username: %s\n", username);
+       syslog(LOG_DEBUG, "username: %s\n", username);
        striplt(username);
-       CtdlLogPrintf(CTDL_DEBUG, "username: %s\n", username);
+       syslog(LOG_DEBUG, "username: %s\n", username);
 
        a = CtdlLoginExistingUser(NULL, username);
        switch (a) {
@@ -699,7 +713,7 @@ void cmd_user(char *cmdbuf)
 void do_login(void)
 {
        CC->logged_in = 1;
-       CtdlLogPrintf(CTDL_NOTICE, "<%s> logged in\n", CC->curr_user);
+       syslog(LOG_NOTICE, "<%s> logged in\n", CC->curr_user);
 
        CtdlGetUserLock(&CC->user, CC->curr_user);
        ++(CC->user.timescalled);
@@ -739,7 +753,7 @@ void do_login(void)
        CtdlCreateRoom(MAILROOM, 4, "", 0, 1, 0, VIEW_MAILBOX);
        CtdlCreateRoom(SENTITEMS, 4, "", 0, 1, 0, VIEW_MAILBOX);
        CtdlCreateRoom(USERTRASHROOM, 4, "", 0, 1, 0, VIEW_MAILBOX);
-       /* CtdlCreateRoom(USERDRAFTROOM, 4, "", 0, 1, 0, VIEW_MAILBOX); temporarily disabled for 7.60 */
+       CtdlCreateRoom(USERDRAFTROOM, 4, "", 0, 1, 0, VIEW_MAILBOX);
 
        /* Run any startup routines registered by loadable modules */
        PerformSessionHooks(EVT_LOGIN);
@@ -760,18 +774,14 @@ void logged_in_response(void)
 
 
 
-/* 
- * misc things to be taken care of when a user is logged out
- */
-void logout(void)
-{
-       CtdlUserLogout();
-}
-
-
 void CtdlUserLogout(void)
 {
        CitContext *CCC = MyContext();
+
+       syslog(LOG_DEBUG, "CtdlUserLogout() logging out <%s> from session %d",
+               CCC->curr_user, CCC->cs_pid
+       );
+
        /*
         * If there is a download in progress, abort it.
         */
@@ -812,10 +822,23 @@ void CtdlUserLogout(void)
        if ((CCC->user.axlevel == AxDeleted) && (CCC->user.usernum))
                purge_user(CCC->user.fullname);
 
+       /* Clear out the user record in memory so we don't behave like a ghost */
+       memset(&CCC->user, 0, sizeof(struct ctdluser));
+       CCC->curr_user[0] = 0;
+       CCC->is_master = 0;
+       CCC->cs_inet_email[0] = 0;
+       CCC->cs_inet_other_emails[0] = 0;
+       CCC->cs_inet_fn[0] = 0;
+       CCC->fake_username[0] = 0;
+       CCC->fake_hostname[0] = 0;
+       CCC->fake_roomname[0] = 0;
+       
+
        /* Free any output buffers */
        unbuffer_output();
 }
 
+
 /*
  * Validate a password on the host unix system by talking to the chkpwd daemon
  */
@@ -825,24 +848,39 @@ static int validpw(uid_t uid, const char *pass)
        int rv = 0;
 
        if (IsEmptyStr(pass)) {
-               CtdlLogPrintf(CTDL_DEBUG, "refusing to check empty password for uid=%d using chkpwd...\n", uid);
+               syslog(LOG_DEBUG, "Refusing to chkpwd for uid=%d with empty password.\n", uid);
                return 0;
        }
 
-       CtdlLogPrintf(CTDL_DEBUG, "Validating password for uid=%d using chkpwd...\n", uid);
+       syslog(LOG_DEBUG, "Validating password for uid=%d using chkpwd...\n", uid);
 
        begin_critical_section(S_CHKPWD);
        rv = write(chkpwd_write_pipe[1], &uid, sizeof(uid_t));
+       if (rv == -1) {
+               syslog(LOG_EMERG, "Communicatino with chkpwd broken: %s\n", strerror(errno));
+               end_critical_section(S_CHKPWD);
+               return 0;
+       }
        rv = write(chkpwd_write_pipe[1], pass, 256);
+       if (rv == -1) {
+               syslog(LOG_EMERG, "Communicatino with chkpwd broken: %s\n", strerror(errno));
+               end_critical_section(S_CHKPWD);
+               return 0;
+       }
        rv = read(chkpwd_read_pipe[0], buf, 4);
+       if (rv == -1) {
+               syslog(LOG_EMERG, "Communicatino with chkpwd broken: %s\n", strerror(errno));
+               end_critical_section(S_CHKPWD);
+               return 0;
+       }
        end_critical_section(S_CHKPWD);
 
        if (!strncmp(buf, "PASS", 4)) {
-               CtdlLogPrintf(CTDL_DEBUG, "...pass\n");
+               syslog(LOG_DEBUG, "...pass\n");
                return(1);
        }
 
-       CtdlLogPrintf(CTDL_DEBUG, "...fail\n");
+       syslog(LOG_DEBUG, "...fail\n");
        return 0;
 }
 
@@ -854,7 +892,7 @@ void start_chkpwd_daemon(void) {
        struct stat filestats;
        int i;
 
-       CtdlLogPrintf(CTDL_DEBUG, "Starting chkpwd daemon for host authentication mode\n");
+       syslog(LOG_DEBUG, "Starting chkpwd daemon for host authentication mode\n");
 
        if ((stat(file_chkpwd, &filestats)==-1) ||
            (filestats.st_size==0)){
@@ -862,29 +900,29 @@ void start_chkpwd_daemon(void) {
                abort();
        }
        if (pipe(chkpwd_write_pipe) != 0) {
-               CtdlLogPrintf(CTDL_EMERG, "Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
+               syslog(LOG_EMERG, "Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
                abort();
        }
        if (pipe(chkpwd_read_pipe) != 0) {
-               CtdlLogPrintf(CTDL_EMERG, "Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
+               syslog(LOG_EMERG, "Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
                abort();
        }
 
        chkpwd_pid = fork();
        if (chkpwd_pid < 0) {
-               CtdlLogPrintf(CTDL_EMERG, "Unable to fork chkpwd daemon: %s\n", strerror(errno));
+               syslog(LOG_EMERG, "Unable to fork chkpwd daemon: %s\n", strerror(errno));
                abort();
        }
        if (chkpwd_pid == 0) {
-               CtdlLogPrintf(CTDL_DEBUG, "Now calling dup2() write\n");
+               syslog(LOG_DEBUG, "Now calling dup2() write\n");
                dup2(chkpwd_write_pipe[0], 0);
-               CtdlLogPrintf(CTDL_DEBUG, "Now calling dup2() write\n");
+               syslog(LOG_DEBUG, "Now calling dup2() write\n");
                dup2(chkpwd_read_pipe[1], 1);
-               CtdlLogPrintf(CTDL_DEBUG, "Now closing stuff\n");
+               syslog(LOG_DEBUG, "Now closing stuff\n");
                for (i=2; i<256; ++i) close(i);
-               CtdlLogPrintf(CTDL_DEBUG, "Now calling execl(%s)\n", file_chkpwd);
+               syslog(LOG_DEBUG, "Now calling execl(%s)\n", file_chkpwd);
                execl(file_chkpwd, file_chkpwd, NULL);
-               CtdlLogPrintf(CTDL_EMERG, "Unable to exec chkpwd daemon: %s\n", strerror(errno));
+               syslog(LOG_EMERG, "Unable to exec chkpwd daemon: %s\n", strerror(errno));
                abort();
                exit(errno);
        }
@@ -896,19 +934,19 @@ int CtdlTryPassword(const char *password, long len)
        int code;
 
        if ((CC->logged_in)) {
-               CtdlLogPrintf(CTDL_WARNING, "CtdlTryPassword: already logged in\n");
+               syslog(LOG_WARNING, "CtdlTryPassword: already logged in\n");
                return pass_already_logged_in;
        }
        if (!strcmp(CC->curr_user, NLI)) {
-               CtdlLogPrintf(CTDL_WARNING, "CtdlTryPassword: no user selected\n");
+               syslog(LOG_WARNING, "CtdlTryPassword: no user selected\n");
                return pass_no_user;
        }
        if (CtdlGetUser(&CC->user, CC->curr_user)) {
-               CtdlLogPrintf(CTDL_ERR, "CtdlTryPassword: internal error\n");
+               syslog(LOG_ERR, "CtdlTryPassword: internal error\n");
                return pass_internal_error;
        }
        if (password == NULL) {
-               CtdlLogPrintf(CTDL_INFO, "CtdlTryPassword: NULL password string supplied\n");
+               syslog(LOG_INFO, "CtdlTryPassword: NULL password string supplied\n");
                return pass_wrong_password;
        }
        code = (-1);
@@ -980,7 +1018,7 @@ int CtdlTryPassword(const char *password, long len)
                do_login();
                return pass_ok;
        } else {
-               CtdlLogPrintf(CTDL_WARNING, "Bad password specified for <%s>\n", CC->curr_user);
+               syslog(LOG_WARNING, "Bad password specified for <%s>\n", CC->curr_user);
                return pass_wrong_password;
        }
 }
@@ -1031,7 +1069,7 @@ int purge_user(char pname[])
                return (ERROR + NO_SUCH_USER);
 
        if (CtdlGetUser(&usbuf, pname) != 0) {
-               CtdlLogPrintf(CTDL_ERR, "Cannot purge user <%s> - not found\n", pname);
+               syslog(LOG_ERR, "Cannot purge user <%s> - not found\n", pname);
                return (ERROR + NO_SUCH_USER);
        }
        /* Don't delete a user who is currently logged in.  Instead, just
@@ -1039,12 +1077,12 @@ int purge_user(char pname[])
         * during the next purge.
         */
        if (CtdlIsUserLoggedInByNum(usbuf.usernum)) {
-               CtdlLogPrintf(CTDL_WARNING, "User <%s> is logged in; not deleting.\n", pname);
+               syslog(LOG_WARNING, "User <%s> is logged in; not deleting.\n", pname);
                usbuf.axlevel = AxDeleted;
                CtdlPutUser(&usbuf);
                return (1);
        }
-       CtdlLogPrintf(CTDL_NOTICE, "Deleting user <%s>\n", pname);
+       syslog(LOG_NOTICE, "Deleting user <%s>\n", pname);
 
 /*
  * FIXME:
@@ -1224,7 +1262,7 @@ int create_user(const char *newusername, long len, int become_user)
                CC->cs_addr
        );
        CtdlAideMessage(buf, "User Creation Notice");
-       CtdlLogPrintf(CTDL_NOTICE, "New user <%s> created\n", username);
+       syslog(LOG_NOTICE, "New user <%s> created\n", username);
        return (0);
 }
 
@@ -1237,7 +1275,7 @@ void cmd_newu(char *cmdbuf)
 {
        int a;
        long len;
-       char username[26];
+       char username[SIZ];
 
        if (config.c_auth_mode != AUTHMODE_NATIVE) {
                cprintf("%d This system does not use native mode authentication.\n",
@@ -1302,7 +1340,7 @@ void CtdlSetPassword(char *new_pw)
        CtdlGetUserLock(&CC->user, CC->curr_user);
        safestrncpy(CC->user.password, new_pw, sizeof(CC->user.password));
        CtdlPutUserLock(&CC->user);
-       CtdlLogPrintf(CTDL_INFO, "Password changed for user <%s>\n", CC->curr_user);
+       syslog(LOG_INFO, "Password changed for user <%s>\n", CC->curr_user);
        PerformSessionHooks(EVT_SETPASS);
 }
 
@@ -1312,8 +1350,6 @@ void CtdlSetPassword(char *new_pw)
  */
 void cmd_setp(char *new_pw)
 {
-       int generate_random_password = 0;
-
        if (CtdlAccessCheck(ac_logged_in)) {
                return;
        }
@@ -1329,7 +1365,6 @@ void cmd_setp(char *new_pw)
 
        if (!strcasecmp(new_pw, "GENERATE_RANDOM_PASSWORD")) {
                char random_password[17];
-               generate_random_password = 1;
                snprintf(random_password, sizeof random_password, "%08lx%08lx", random(), random());
                CtdlSetPassword(random_password);
                cprintf("%d %s\n", CIT_OK, random_password);
@@ -1362,17 +1397,16 @@ void cmd_creu(char *cmdbuf)
        }
 
        extract_token(username, cmdbuf, 0, '|', sizeof username);
-       extract_token(password, cmdbuf, 1, '|', sizeof password);
-       ////username[25] = 0;
-       //password[31] = 0;
        strproc(username);
        strproc(password);
-       len = cutuserkey(username);
-
        if (IsEmptyStr(username)) {
                cprintf("%d You must supply a user name.\n", ERROR + USERNAME_REQUIRED);
                return;
        }
+       len = cutuserkey(username);
+
+
+       extract_token(password, cmdbuf, 1, '|', sizeof password);
 
        a = create_user(username, len, 0);
 
@@ -1557,8 +1591,9 @@ void cmd_invt_kick(char *iuser, int op) {
         * These commands are only allowed by aides, room aides,
         * and room namespace owners
         */
-       if (is_room_aide()
-          || (atol(CC->room.QRname) == CC->user.usernum) ) {
+       if (is_room_aide()) {
+               /* access granted */
+       } else if ( ((atol(CC->room.QRname) == CC->user.usernum) ) && (CC->user.usernum != 0) ) {
                /* access granted */
        } else {
                /* access denied */
@@ -2055,19 +2090,19 @@ void cmd_renu(char *cmdbuf)
 CTDL_MODULE_INIT(user_ops)
 {
        if (!threading) {
-               CtdlRegisterProtoHook(cmd_user, "USER", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_pass, "PASS", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_creu, "CREU", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_setp, "SETP", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_getu, "GETU", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_setu, "SETU", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_slrp, "SLRP", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_invt, "INVT", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_kick, "KICK", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_forg, "FORG", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_user, "USER", "Submit username for login");
+               CtdlRegisterProtoHook(cmd_pass, "PASS", "Complete login by submitting a password");
+               CtdlRegisterProtoHook(cmd_creu, "CREU", "Create User");
+               CtdlRegisterProtoHook(cmd_setp, "SETP", "Set the password for an account");
+               CtdlRegisterProtoHook(cmd_getu, "GETU", "Get User parameters");
+               CtdlRegisterProtoHook(cmd_setu, "SETU", "Set User parameters");
+               CtdlRegisterProtoHook(cmd_slrp, "SLRP", "Set Last Read Pointer");
+               CtdlRegisterProtoHook(cmd_invt, "INVT", "Invite a user to a room");
+               CtdlRegisterProtoHook(cmd_kick, "KICK", "Kick a user out of a room");
+               CtdlRegisterProtoHook(cmd_forg, "FORG", "Forget a room");
                CtdlRegisterProtoHook(cmd_gnur, "GNUR", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_vali, "VALI", "Autoconverted. TODO: document me.");
-               CtdlRegisterProtoHook(cmd_list, "LIST", "Autoconverted. TODO: document me.");
+               CtdlRegisterProtoHook(cmd_vali, "VALI", "Validate new users");
+               CtdlRegisterProtoHook(cmd_list, "LIST", "List users");
                CtdlRegisterProtoHook(cmd_chek, "CHEK", "Autoconverted. TODO: document me.");
                CtdlRegisterProtoHook(cmd_qusr, "QUSR", "Autoconverted. TODO: document me.");
                CtdlRegisterProtoHook(cmd_agup, "AGUP", "Autoconverted. TODO: document me.");