/* Set v_seen if necessary */
if (vbuf->v_seen[0] == 0) {
- sprintf(vbuf->v_seen, "*:%ld", vbuf->v_lastseen);
+ snprintf(vbuf->v_seen, sizeof vbuf->v_seen, "*:%ld", vbuf->v_lastseen);
}
}
-void MailboxName(char *buf, struct usersupp *who, char *prefix)
+void MailboxName(char *buf, size_t n, const struct usersupp *who, const char *prefix)
{
- sprintf(buf, "%010ld.%s", who->usernum, prefix);
+ snprintf(buf, n, "%010ld.%s", who->usernum, prefix);
}
void logged_in_response(void)
{
cprintf("%d %s|%d|%ld|%ld|%u|%ld|%ld\n",
- OK, CC->usersupp.fullname, CC->usersupp.axlevel,
+ CIT_OK, CC->usersupp.fullname, CC->usersupp.axlevel,
CC->usersupp.timescalled, CC->usersupp.posted,
CC->usersupp.flags, CC->usersupp.usernum,
CC->usersupp.lastcall);
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... */
- become_session(who);
PerformSessionHooks(EVT_LOGOUT);
- become_session(NULL);
}
#ifdef ENABLE_CHKPWD
if (pipe(pipev)) {
lprintf(1, "pipe failed (%s): denying autologin access for "
- "uid %u\n", strerror(errno), uid);
+ "uid %ld\n", strerror(errno), (long)uid);
return 0;
}
switch (pid = fork()) {
case -1:
lprintf(1, "fork failed (%s): denying autologin access for "
- "uid %u\n", strerror(errno), uid);
+ "uid %ld\n", strerror(errno), (long)uid);
close(pipev[0]);
close(pipev[1]);
return 0;
}
close(pipev[0]);
- write(pipev[1], buf, sprintf(buf, "%lu\n", (unsigned long) uid));
+ write(pipev[1], buf,
+ snprintf(buf, sizeof buf, "%lu\n", (unsigned long) uid));
write(pipev[1], pass, strlen(pass));
write(pipev[1], "\n", 1);
close(pipev[1]);
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR) {
lprintf(1, "waitpid failed (%s): denying autologin "
- "access for uid %u\n",
- strerror(errno), uid);
+ "access for uid %ld\n",
+ strerror(errno), (long)uid);
return 0;
}
if (WIFEXITED(status) && !WEXITSTATUS(status))
cdb_delete(CDB_USERSUPP, lowercase_name, strlen(lowercase_name));
/* remove the user's bio file */
- sprintf(filename, "./bio/%ld", usbuf.usernum);
+ snprintf(filename, sizeof filename, "./bio/%ld", usbuf.usernum);
unlink(filename);
/* remove the user's picture */
- sprintf(filename, "./userpics/%ld.gif", usbuf.usernum);
+ snprintf(filename, sizeof filename, "./userpics/%ld.gif", usbuf.usernum);
unlink(filename);
return (0);
/*
* create_user() - back end processing to create a new user
+ *
+ * Set 'newusername' to the desired account name.
+ * Set 'become_user' to nonzero if this is self-service account creation and we want
+ * to actually log in as the user we just created, otherwise set it to 0.
*/
-int create_user(char *newusername)
+int create_user(char *newusername, int become_user)
{
struct usersupp usbuf;
- int a;
struct passwd *p = NULL;
- char username[64];
+ char username[SIZ];
+ char mailboxname[ROOMNAMELEN];
+ uid_t uid;
strcpy(username, newusername);
strproc(username);
p = (struct passwd *) getpwnam(username);
#endif
if (p != NULL) {
- strcpy(username, p->pw_gecos);
- for (a = 0; a < strlen(username); ++a) {
- if (username[a] == ',')
- username[a] = 0;
- }
- CC->usersupp.uid = p->pw_uid;
+ extract_token(username, p->pw_gecos, 0, ',');
+ uid = p->pw_uid;
} else {
- CC->usersupp.uid = BBSUID;
+ uid = BBSUID;
}
if (!getuser(&usbuf, username)) {
return (ERROR + ALREADY_EXISTS);
}
- strcpy(CC->curr_user, username);
- strcpy(CC->usersupp.fullname, username);
- strcpy(CC->usersupp.password, "");
- (CC->logged_in) = 1;
+
+ /* Go ahead and initialize a new user record */
+ memset(&usbuf, 0, sizeof(struct usersupp));
+ strcpy(usbuf.fullname, username);
+ strcpy(usbuf.password, "");
+ usbuf.uid = uid;
/* These are the default flags on new accounts */
- CC->usersupp.flags = US_LASTOLD | US_DISAPPEAR | US_PAGINATOR | US_FLOORS;
+ usbuf.flags = US_LASTOLD | US_DISAPPEAR | US_PAGINATOR | US_FLOORS;
- CC->usersupp.timescalled = 0;
- CC->usersupp.posted = 0;
- CC->usersupp.axlevel = config.c_initax;
- CC->usersupp.USscreenwidth = 80;
- CC->usersupp.USscreenheight = 24;
- time(&CC->usersupp.lastcall);
- CC->usersupp.moderation_filter = config.c_default_filter;
+ usbuf.timescalled = 0;
+ usbuf.posted = 0;
+ usbuf.axlevel = config.c_initax;
+ usbuf.USscreenwidth = 80;
+ usbuf.USscreenheight = 24;
+ usbuf.lastcall = time(NULL);
+ usbuf.moderation_filter = config.c_default_filter;
/* fetch a new user number */
- CC->usersupp.usernum = get_new_user_number();
+ usbuf.usernum = get_new_user_number();
- if (CC->usersupp.usernum == 1L) {
- CC->usersupp.axlevel = 6;
+ /* The very first user created on the system will always be an Aide */
+ if (usbuf.usernum == 1L) {
+ usbuf.axlevel = 6;
}
+
/* add user to userlog */
- putuser(&CC->usersupp);
- if (getuser(&CC->usersupp, CC->curr_user)) {
- return (ERROR + INTERNAL_ERROR);
- }
+ putuser(&usbuf);
+
/* give the user a private mailbox */
- create_room(MAILROOM, 4, "", 0, 1);
+ MailboxName(mailboxname, sizeof mailboxname, &usbuf, MAILROOM);
+ create_room(mailboxname, 5, "", 0, 1);
+
+ /*** Everything below this line can be bypassed if we are administratively
+ creating a user, instead of doing self-service account creation
+ ***/
+
+ if (become_user) {
+ /* Now become the user we just created */
+ memcpy(&CC->usersupp, &usbuf, sizeof(struct usersupp));
+ strcpy(CC->curr_user, username);
+ CC->logged_in = 1;
+
+ /* Check to make sure we're still who we think we are */
+ if (getuser(&CC->usersupp, CC->curr_user)) {
+ return (ERROR + INTERNAL_ERROR);
+ }
+
+ rec_log(CL_NEWUSER, CC->curr_user);
+ }
- rec_log(CL_NEWUSER, CC->curr_user);
return (0);
}
/*
- * cmd_newu() - create a new user account
+ * cmd_newu() - create a new user account and log in as that user
*/
void cmd_newu(char *cmdbuf)
{
int a;
char username[SIZ];
- if ((CC->logged_in)) {
+ if (config.c_disable_newu) {
+ cprintf("%d Self-service user account creation "
+ "is disabled on this system.\n", ERROR);
+ return;
+ }
+
+ if (CC->logged_in) {
cprintf("%d Already logged in.\n", ERROR);
return;
}
- if ((CC->nologin)) {
+ if (CC->nologin) {
cprintf("%d %s: Too many users are already online (maximum is %d)\n",
ERROR + MAX_SESSIONS_EXCEEDED,
config.c_nodename, config.c_maxsessions);
cprintf("%d You must supply a user name.\n", ERROR);
return;
}
- a = create_user(username);
+
if ((!strcasecmp(username, "bbs")) ||
(!strcasecmp(username, "new")) ||
(!strcasecmp(username, "."))) {
cprintf("%d '%s' is an invalid login name.\n", ERROR, username);
return;
}
- if (a == ERROR + ALREADY_EXISTS) {
+
+ a = create_user(username, 1);
+
+ if (a == 0) {
+ session_startup();
+ logged_in_response();
+ } else if (a == ERROR + ALREADY_EXISTS) {
cprintf("%d '%s' already exists.\n",
ERROR + ALREADY_EXISTS, username);
return;
cprintf("%d Internal error - user record disappeared?\n",
ERROR + INTERNAL_ERROR);
return;
- } else if (a == 0) {
- session_startup();
- logged_in_response();
} else {
cprintf("%d unknown error\n", ERROR);
}
*/
void cmd_setp(char *new_pw)
{
- if (CtdlAccessCheck(ac_logged_in))
+ if (CtdlAccessCheck(ac_logged_in)) {
return;
+ }
if (CC->usersupp.uid != BBSUID) {
cprintf("%d Not allowed. Use the 'passwd' command.\n", ERROR);
}
strproc(new_pw);
if (strlen(new_pw) == 0) {
- cprintf("%d Password unchanged.\n", OK);
+ cprintf("%d Password unchanged.\n", CIT_OK);
return;
}
lgetuser(&CC->usersupp, CC->curr_user);
strcpy(CC->usersupp.password, new_pw);
lputuser(&CC->usersupp);
- cprintf("%d Password changed.\n", OK);
+ cprintf("%d Password changed.\n", CIT_OK);
rec_log(CL_PWCHANGE, CC->curr_user);
PerformSessionHooks(EVT_SETPASS);
}
+
+/*
+ * cmd_creu() - administratively create a new user account (do not log in to it)
+ */
+void cmd_creu(char *cmdbuf)
+{
+ int a;
+ char username[SIZ];
+
+ if (CtdlAccessCheck(ac_aide)) {
+ return;
+ }
+
+ extract(username, cmdbuf, 0);
+ username[25] = 0;
+ strproc(username);
+
+ if (strlen(username) == 0) {
+ cprintf("%d You must supply a user name.\n", ERROR);
+ return;
+ }
+
+ a = create_user(username, 0);
+
+ if (a == 0) {
+ cprintf("%d ok\n", CIT_OK);
+ return;
+ } else if (a == ERROR + ALREADY_EXISTS) {
+ cprintf("%d '%s' already exists.\n",
+ ERROR + ALREADY_EXISTS, username);
+ return;
+ } else {
+ cprintf("%d An error occured creating the user account.\n", ERROR);
+ }
+ rec_log(CL_NEWUSER, username);
+}
+
+
+
/*
* get user parameters
*/
getuser(&CC->usersupp, CC->curr_user);
cprintf("%d %d|%d|%d|%d\n",
- OK,
+ CIT_OK,
CC->usersupp.USscreenwidth,
CC->usersupp.USscreenheight,
(CC->usersupp.flags & US_USER_SET),
lprintf(9, "new_mod processed to %d\n", new_mod);
}
lputuser(&CC->usersupp);
- cprintf("%d Ok\n", OK);
+ cprintf("%d Ok\n", CIT_OK);
}
/*
CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
vbuf.v_lastseen = newlr;
- sprintf(vbuf.v_seen, "*:%ld", newlr);
+ snprintf(vbuf.v_seen, sizeof vbuf.v_seen, "*:%ld", newlr);
CtdlSetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
lputuser(&CC->usersupp);
- cprintf("%d %ld\n", OK, newlr);
+ cprintf("%d %ld\n", CIT_OK, newlr);
}
target_setting = extract_int(argbuf, 1);
CtdlSetSeen(target_msgnum, target_setting);
- cprintf("%d OK\n", OK);
+ cprintf("%d OK\n", CIT_OK);
}
char bbb[SIZ];
struct visit vbuf;
- if (CtdlAccessCheck(ac_room_aide))
- return;
+ /*
+ * These commands are only allowed by aides, room aides,
+ * and room namespace owners
+ */
+ if (is_room_aide()
+ || (atol(CC->quickroom.QRname) == CC->usersupp.usernum) ) {
+ /* access granted */
+ }
+ else {
+ /* access denied */
+ cprintf("%d Higher access or room ownership required.\n",
+ ERROR + HIGHER_ACCESS_REQUIRED);
+ return;
+ }
if (lgetuser(&USscratch, iuser) != 0) {
cprintf("%d No such user.\n", ERROR);
lputuser(&USscratch);
/* post a message in Aide> saying what we just did */
- sprintf(bbb, "%s %s %s> by %s\n",
+ snprintf(bbb, sizeof bbb, "%s %s %s> by %s\n",
iuser,
((op == 1) ? "invited to" : "kicked out of"),
CC->quickroom.QRname,
aide_message(bbb);
cprintf("%d %s %s %s.\n",
- OK, iuser,
+ CIT_OK, iuser,
((op == 1) ? "invited to" : "kicked out of"),
CC->quickroom.QRname);
return;
struct visit vbuf;
/* On some systems, Aides are not allowed to forget rooms */
- if (is_aide() && (config.c_aide_zap == 0)) {
+ if (is_aide() && (config.c_aide_zap == 0)
+ && ((CC->quickroom.QRflags & QR_MAILBOX) == 0) ) {
return(1);
}
}
if (CtdlForgetThisRoom() == 0) {
- cprintf("%d Ok\n", OK);
+ cprintf("%d Ok\n", CIT_OK);
}
else {
cprintf("%d You may not forget this room.\n", ERROR);
}
if ((CitControl.MMflags & MM_VALID) == 0) {
- cprintf("%d There are no unvalidated users.\n", OK);
+ cprintf("%d There are no unvalidated users.\n", CIT_OK);
return;
}
CitControl.MMflags = CitControl.MMflags & (~MM_VALID);
put_control();
end_critical_section(S_CONTROL);
- cprintf("%d *** End of registration.\n", OK);
+ cprintf("%d *** End of registration.\n", CIT_OK);
}
/* If the access level was set to zero, delete the user */
if (newax == 0) {
if (purge_user(user) == 0) {
- cprintf("%d %s Deleted.\n", OK, userbuf.fullname);
+ cprintf("%d %s Deleted.\n", CIT_OK, userbuf.fullname);
return;
}
}
- cprintf("%d User '%s' validated.\n", OK, userbuf.fullname);
+ cprintf("%d User '%s' validated.\n", CIT_OK, userbuf.fullname);
}
/* check for mail */
mail = NewMailCount();
- cprintf("%d %d|%d|%d\n", OK, mail, regis, vali);
+ cprintf("%d %d|%d|%d\n", CIT_OK, mail, regis, vali);
}
struct usersupp usbuf;
if (getuser(&usbuf, who) == 0) {
- cprintf("%d %s\n", OK, usbuf.fullname);
+ cprintf("%d %s\n", CIT_OK, usbuf.fullname);
} else {
cprintf("%d No such user.\n", ERROR + NO_SUCH_USER);
}
return;
}
cprintf("%d %s|%s|%u|%ld|%ld|%d|%ld|%ld|%d\n",
- OK,
+ CIT_OK,
usbuf.fullname,
usbuf.password,
usbuf.flags,
deleted = 1;
}
}
- cprintf("%d Ok", OK);
+ cprintf("%d Ok", CIT_OK);
if (deleted)
cprintf(" (%s deleted)", requested_user);
cprintf("\n");
long *msglist = NULL;
int num_msgs = 0;
- MailboxName(mailboxname, &CC->usersupp, MAILROOM);
+ MailboxName(mailboxname, sizeof mailboxname, &CC->usersupp, MAILROOM);
if (getroom(&mailbox, mailboxname) != 0)
return (0);
CtdlGetRelationship(&vbuf, &CC->usersupp, &mailbox);