#include <fcntl.h>
#include <signal.h>
#include <pwd.h>
+#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#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"
int getuser(struct usersupp *usbuf, char name[])
{
- char lowercase_name[32];
+ char lowercase_name[USERNAME_SIZE];
int a;
struct cdbdata *cdbus;
sizeof(struct usersupp) : cdbus->len));
cdb_free(cdbus);
- if (usbuf->version < 573) {
- CC->usersupp.moderation_filter = config.c_default_filter;
- }
return (0);
}
*/
void putuser(struct usersupp *usbuf)
{
- char lowercase_name[32];
+ char lowercase_name[USERNAME_SIZE];
int a;
for (a = 0; a <= strlen(usbuf->fullname); ++a) {
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) {
*/
void session_startup(void)
{
+ int i;
+
syslog(LOG_NOTICE, "session %d: user <%s> logged in",
CC->cs_pid, CC->curr_user);
}
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);
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);
}
{
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;
int create_user(char *newusername, int become_user)
{
struct usersupp usbuf;
+ struct quickroom qrbuf;
struct passwd *p = NULL;
char username[SIZ];
char mailboxname[ROOMNAMELEN];
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();
/* 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 */
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)
);
}
*/
void cmd_setu(char *new_parms)
{
- int new_mod;
-
if (CtdlAccessCheck(ac_logged_in))
return;
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);
}
}
+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
*/
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;
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);
}
}
/* 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);
}
{
struct usersupp usbuf;
char requested_user[SIZ];
+ char notify[SIZ];
int np;
int newax;
int deleted = 0;
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);
}
+
+/*
+ * 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);
+}