]> code.citadel.org Git - citadel.git/blobdiff - citadel/user_ops.c
* Renamed "dynloader" to "serv_extensions" globally. We don't want people
[citadel.git] / citadel / user_ops.c
index 0f05ceb6fd902c44a7c73419c3381bdc5bdbc5bd..5e8acacd082a6f5280318ae75bee55877fe73de1 100644 (file)
@@ -17,6 +17,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <pwd.h>
+#include <ctype.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 
@@ -41,7 +42,7 @@
 #include "server.h"
 #include "database.h"
 #include "user_ops.h"
-#include "dynloader.h"
+#include "serv_extensions.h"
 #include "sysdep_decls.h"
 #include "support.h"
 #include "room_ops.h"
@@ -61,7 +62,7 @@
 int getuser(struct usersupp *usbuf, char name[])
 {
 
-       char lowercase_name[32];
+       char lowercase_name[USERNAME_SIZE];
        int a;
        struct cdbdata *cdbus;
 
@@ -81,9 +82,6 @@ int getuser(struct usersupp *usbuf, char name[])
                sizeof(struct usersupp) : cdbus->len));
        cdb_free(cdbus);
 
-       if (usbuf->version < 573) {
-               CC->usersupp.moderation_filter = config.c_default_filter;
-       }
        return (0);
 }
 
@@ -108,7 +106,7 @@ int lgetuser(struct usersupp *usbuf, char *name)
  */
 void putuser(struct usersupp *usbuf)
 {
-       char lowercase_name[32];
+       char lowercase_name[USERNAME_SIZE];
        int a;
 
        for (a = 0; a <= strlen(usbuf->fullname); ++a) {
@@ -229,6 +227,12 @@ void CtdlGetRelationship(struct visit *vbuf,
                        sizeof(struct visit) : cdbvisit->len));
                cdb_free(cdbvisit);
        }
+       else {
+               /* If this is the first time the user has seen this room,
+                * set the view to be the default for the room.
+                */
+               vbuf->v_view = rel_room->QRdefaultview;
+       }
 
        /* Set v_seen if necessary */
        if (vbuf->v_seen[0] == 0) {
@@ -385,6 +389,8 @@ void cmd_user(char *cmdbuf)
  */
 void session_startup(void)
 {
+       int i;
+
        syslog(LOG_NOTICE, "session %d: user <%s> logged in",
               CC->cs_pid, CC->curr_user);
 
@@ -400,14 +406,30 @@ void session_startup(void)
        }
        lputuser(&CC->usersupp);
 
+       /*
+        * Populate CC->cs_inet_email with a default address.  This will be
+        * overwritten with the user's directory address, if one exists, when
+        * the vCard module's login hook runs.
+        */
+       snprintf(CC->cs_inet_email, sizeof CC->cs_inet_email, "%s@%s",
+               CC->usersupp.fullname, config.c_fqdn);
+       for (i=0; i<strlen(CC->cs_inet_email); ++i) {
+               if (isspace(CC->cs_inet_email[i])) {
+                       CC->cs_inet_email[i] = '_';
+               }
+       }
+
+       /* Create any personal rooms required by the system.
+        * (Technically, MAILROOM should be there already, but just in case...)
+        */
+       create_room(MAILROOM, 4, "", 0, 1, 0);
+       create_room(SENTITEMS, 4, "", 0, 1, 0);
+
        /* Run any startup routines registered by loadable modules */
        PerformSessionHooks(EVT_LOGIN);
 
-       /* Create any personal rooms required by the system */
-       create_room(SENTITEMS, 4, "", 0, 1);
-
        /* Enter the lobby */
-       usergoto(BASEROOM, 0, NULL, NULL);
+       usergoto(config.c_baseroom, 0, 0, NULL, NULL);
 
        /* Record this login in the Citadel log */
        rec_log(CL_LOGIN, CC->curr_user);
@@ -454,14 +476,6 @@ void logout(struct CitContext *who)
                network_talking_to(who->net_node, NTT_REMOVE);
        }
 
-       /*
-        * Yes, we really need to free EVERY LAST BYTE we allocated.
-        */
-       if (who->cs_inet_email != NULL) {
-               phree(who->cs_inet_email);
-               who->cs_inet_email = NULL;
-       }
-
        /* Do modular stuff... */
        PerformSessionHooks(EVT_LOGOUT);
 }
@@ -615,7 +629,7 @@ int purge_user(char pname[])
 {
        char filename[64];
        struct usersupp usbuf;
-       char lowercase_name[32];
+       char lowercase_name[USERNAME_SIZE];
        int a;
        struct CitContext *ccptr;
        int user_is_logged_in = 0;
@@ -679,6 +693,7 @@ int purge_user(char pname[])
 int create_user(char *newusername, int become_user)
 {
        struct usersupp usbuf;
+       struct quickroom qrbuf;
        struct passwd *p = NULL;
        char username[SIZ];
        char mailboxname[ROOMNAMELEN];
@@ -716,7 +731,6 @@ int create_user(char *newusername, int become_user)
        usbuf.USscreenwidth = 80;
        usbuf.USscreenheight = 24;
        usbuf.lastcall = time(NULL);
-       usbuf.moderation_filter = config.c_default_filter;
 
        /* fetch a new user number */
        usbuf.usernum = get_new_user_number();
@@ -729,13 +743,23 @@ int create_user(char *newusername, int become_user)
        /* add user to userlog */
        putuser(&usbuf);
 
-       /* give the user a private mailbox */
+       /*
+        * Give the user a private mailbox and a configuration room.
+        * Make the latter an invisible system room.
+        */
        MailboxName(mailboxname, sizeof mailboxname, &usbuf, MAILROOM);
-       create_room(mailboxname, 5, "", 0, 1);
+       create_room(mailboxname, 5, "", 0, 1, 1);
 
-       /*** Everything below this line can be bypassed if we are administratively
-            creating a user, instead of doing self-service account creation
-        ***/
+       MailboxName(mailboxname, sizeof mailboxname, &usbuf, USERCONFIGROOM);
+       create_room(mailboxname, 5, "", 0, 1, 1);
+        if (lgetroom(&qrbuf, USERCONFIGROOM) == 0) {
+                qrbuf.QRflags2 |= QR2_SYSTEM;
+                lputroom(&qrbuf);
+        }
+
+       /* Everything below this line can be bypassed if administratively
+          creating a user, instead of doing self-service account creation
+        */
 
        if (become_user) {
                /* Now become the user we just created */
@@ -892,12 +916,11 @@ void cmd_getu(void)
                return;
 
        getuser(&CC->usersupp, CC->curr_user);
-       cprintf("%d %d|%d|%d|%d\n",
+       cprintf("%d %d|%d|%d|\n",
                CIT_OK,
                CC->usersupp.USscreenwidth,
                CC->usersupp.USscreenheight,
-               (CC->usersupp.flags & US_USER_SET),
-               CC->usersupp.moderation_filter
+               (CC->usersupp.flags & US_USER_SET)
            );
 }
 
@@ -906,8 +929,6 @@ void cmd_getu(void)
  */
 void cmd_setu(char *new_parms)
 {
-       int new_mod;
-
        if (CtdlAccessCheck(ac_logged_in))
                return;
 
@@ -922,25 +943,6 @@ void cmd_setu(char *new_parms)
        CC->usersupp.flags = CC->usersupp.flags |
            (extract_int(new_parms, 2) & US_USER_SET);
 
-       if (num_parms(new_parms) >= 4) {
-               new_mod = extract_int(new_parms, 3);
-               lprintf(9, "new_mod extracted to %d\n", new_mod);
-
-               /* Aides cannot set the filter level lower than -100 */
-               if (new_mod < (-100))
-                       new_mod = -100;
-
-               /* Normal users cannot set the filter level lower than -63 */
-               if ((new_mod < (-63)) && (CC->usersupp.axlevel < 6))
-                       new_mod = -63;
-
-               /* Nobody can set the filter level higher than +63 */
-               if (new_mod > 63)
-                       new_mod = 63;
-
-               CC->usersupp.moderation_filter = new_mod;
-               lprintf(9, "new_mod processed to %d\n", new_mod);
-       }
        lputuser(&CC->usersupp);
        cprintf("%d Ok\n", CIT_OK);
 }
@@ -996,6 +998,19 @@ void cmd_seen(char *argbuf) {
 }
 
 
+void cmd_gtsn(char *argbuf) {
+       char buf[SIZ];
+
+       if (CtdlAccessCheck(ac_logged_in)) {
+               return;
+       }
+
+       CtdlGetSeen(buf);
+       cprintf("%d %s\n", CIT_OK, buf);
+}
+
+
+
 /*
  * INVT and KICK commands
  */
@@ -1013,14 +1028,20 @@ void cmd_invt_kick(char *iuser, int op)
        if (is_room_aide()
           || (atol(CC->quickroom.QRname) == CC->usersupp.usernum) ) {
                /* access granted */
-       }
-       else {
+       } else {
                /* access denied */
                 cprintf("%d Higher access or room ownership required.\n",
                         ERROR + HIGHER_ACCESS_REQUIRED);
                 return;
         }
 
+       if (!strncasecmp(CC->quickroom.QRname, config.c_baseroom,
+                        ROOMNAMELEN)) {
+               cprintf("%d Can't add/remove users from this room.\n",
+                       ERROR + NOT_HERE);
+               return;
+       }
+
        if (lgetuser(&USscratch, iuser) != 0) {
                cprintf("%d No such user.\n", ERROR);
                return;
@@ -1078,7 +1099,7 @@ int CtdlForgetThisRoom(void) {
        lputuser(&CC->usersupp);
 
        /* Return to the Lobby, so we don't end up in an undefined room */
-       usergoto(BASEROOM, 0, NULL, NULL);
+       usergoto(config.c_baseroom, 0, 0, NULL, NULL);
        return(0);
 
 }
@@ -1272,9 +1293,9 @@ void cmd_chek(void)
        }
 
        /* check for mail */
-       mail = NewMailCount();
+       mail = InitialMailCheck();
 
-       cprintf("%d %d|%d|%d\n", CIT_OK, mail, regis, vali);
+       cprintf("%d %d|%d|%d|%s|\n", CIT_OK, mail, regis, vali, CC->cs_inet_email);
 }
 
 
@@ -1332,6 +1353,7 @@ void cmd_asup(char *cmdbuf)
 {
        struct usersupp usbuf;
        char requested_user[SIZ];
+       char notify[SIZ];
        int np;
        int newax;
        int deleted = 0;
@@ -1371,6 +1393,13 @@ void cmd_asup(char *cmdbuf)
                        deleted = 1;
                }
        }
+
+       if (deleted) {
+               sprintf(notify, "User <%s> deleted by %s\n",
+                       usbuf.fullname, CC->usersupp.fullname);
+               aide_message(notify);
+       }
+
        cprintf("%d Ok", CIT_OK);
        if (deleted)
                cprintf(" (%s deleted)", requested_user);
@@ -1378,43 +1407,100 @@ void cmd_asup(char *cmdbuf)
 }
 
 
+
+/*
+ * Check to see if the user who we just sent mail to is logged in.  If yes,
+ * bump the 'new mail' counter for their session.  That enables them to
+ * receive a new mail notification without having to hit the database.
+ */
+void BumpNewMailCounter(long which_user) {
+       struct CitContext *ptr;
+
+       begin_critical_section(S_SESSION_TABLE);
+
+       for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
+               if (ptr->usersupp.usernum == which_user) {
+                       ptr->newmail += 1;
+               }
+       }
+
+       end_critical_section(S_SESSION_TABLE);
+}
+
+
 /*
  * Count the number of new mail messages the user has
  */
 int NewMailCount()
 {
        int num_newmsgs = 0;
-       int a;
-       char mailboxname[ROOMNAMELEN];
-       struct quickroom mailbox;
-       struct visit vbuf;
-       struct cdbdata *cdbfr;
-       long *msglist = NULL;
-       int num_msgs = 0;
 
-       MailboxName(mailboxname, sizeof mailboxname, &CC->usersupp, MAILROOM);
-       if (getroom(&mailbox, mailboxname) != 0)
-               return (0);
-       CtdlGetRelationship(&vbuf, &CC->usersupp, &mailbox);
-
-       cdbfr = cdb_fetch(CDB_MSGLISTS, &mailbox.QRnumber, sizeof(long));
-
-       if (cdbfr != NULL) {
-               msglist = mallok(cdbfr->len);
-               memcpy(msglist, cdbfr->ptr, cdbfr->len);
-               num_msgs = cdbfr->len / sizeof(long);
-               cdb_free(cdbfr);
-       }
-       if (num_msgs > 0)
-               for (a = 0; a < num_msgs; ++a) {
-                       if (msglist[a] > 0L) {
-                               if (msglist[a] > vbuf.v_lastseen) {
-                                       ++num_newmsgs;
-                               }
-                       }
-               }
-       if (msglist != NULL)
-               phree(msglist);
+       num_newmsgs = CC->newmail;
+       CC->newmail = 0;
 
        return (num_newmsgs);
 }
+
+
+/*
+ * Count the number of new mail messages the user has
+ */
+int InitialMailCheck()
+{
+        int num_newmsgs = 0;
+        int a;
+        char mailboxname[ROOMNAMELEN];
+        struct quickroom mailbox;
+        struct visit vbuf;
+        struct cdbdata *cdbfr;
+        long *msglist = NULL;
+        int num_msgs = 0;
+
+        MailboxName(mailboxname, sizeof mailboxname, &CC->usersupp, MAILROOM);
+        if (getroom(&mailbox, mailboxname) != 0)
+                return (0);
+        CtdlGetRelationship(&vbuf, &CC->usersupp, &mailbox);
+
+        cdbfr = cdb_fetch(CDB_MSGLISTS, &mailbox.QRnumber, sizeof(long));
+
+        if (cdbfr != NULL) {
+                msglist = mallok(cdbfr->len);
+                memcpy(msglist, cdbfr->ptr, cdbfr->len);
+                num_msgs = cdbfr->len / sizeof(long);
+                cdb_free(cdbfr);
+        }
+        if (num_msgs > 0)
+                for (a = 0; a < num_msgs; ++a) {
+                        if (msglist[a] > 0L) {
+                                if (msglist[a] > vbuf.v_lastseen) {
+                                        ++num_newmsgs;
+                                }
+                        }
+                }
+        if (msglist != NULL)
+                phree(msglist);
+
+        return (num_newmsgs);
+}
+
+
+
+/*
+ * Set the preferred view for the current user/room combination
+ */
+void cmd_view(char *cmdbuf) {
+       int requested_view;
+       struct visit vbuf;
+
+       if (CtdlAccessCheck(ac_logged_in)) {
+               return;
+       }
+
+       requested_view = extract_int(cmdbuf, 0);
+
+       CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
+       vbuf.v_view = requested_view;
+       CtdlSetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
+       
+       cprintf("%d ok\n", CIT_OK);
+}