Updates for new mbsebbs style
This commit is contained in:
parent
e87e7c2ab6
commit
d91305ad80
@ -4273,6 +4273,8 @@ v0.33.19 26-Oct-2001
|
||||
users need to register with the mbnewuser program, mbsebbs is
|
||||
only for registered users. This should fix all kinds of setuid
|
||||
issues with previous versions.
|
||||
QuickScan messages in netmail areas now only shows personal
|
||||
messages.
|
||||
|
||||
mbnewusr:
|
||||
New program, run by user bbs. This is only to register a new
|
||||
|
@ -5,7 +5,7 @@
|
||||
include ../Makefile.global
|
||||
|
||||
SRCS = bank.c commonio.c filesub.c language.c mbfbgen.c mbtoberep.c \
|
||||
msgutil.c oneline.c pwcheck.c sgetpwent.c xmalloc.c bbslist.c \
|
||||
msgutil.c oneline.c sgetpwent.c xmalloc.c bbslist.c \
|
||||
email.c fsedit.c lineedit.c mblang.c mbuser.c myname.c page.c \
|
||||
pwio.c shadowio.c bye.c encrypt.c funcs.c mail.c mbpasswd.c \
|
||||
mbuseradd.c newuser.c pinfo.c rad64.c timecheck.c change.c \
|
||||
@ -15,22 +15,23 @@ SRCS = bank.c commonio.c filesub.c language.c mbfbgen.c mbtoberep.c \
|
||||
door.c dispfile.c
|
||||
HDRS = bank.h commonio.h filesub.h language.h mbsebbs.h misc.h offline.h \
|
||||
putpwent.h salt.h timeout.h bbslist.h email.h fsedit.h lineedit.h \
|
||||
mbstat.h msgutil.h oneline.h pwcheck.h sgetpwent.h user.h bye.h \
|
||||
mbstat.h msgutil.h oneline.h sgetpwent.h user.h bye.h \
|
||||
encrypt.h funcs.h mail.h mbuser.h myname.h page.h pwio.h shadowio.h \
|
||||
xmalloc.h change.h exitinfo.h funcs4.h mball.h mbuseradd.h newuser.h \
|
||||
pinfo.h rad64.h statetbl.h chat.h file.h getdef.h mbpasswd.h menu.h \
|
||||
nextuser.h pop3.h safe.h timecheck.h mbnewusr.h input.h whoson.h \
|
||||
door.h dispfile.h
|
||||
MBSEBBS_OBJS = bank.o bbslist.o chat.o file.o funcs.o funcs4.o mail.o menu.o \
|
||||
misc.o pinfo.o nextuser.o oneline.o page.o pwcheck.o fsedit.o \
|
||||
misc.o pinfo.o nextuser.o oneline.o page.o fsedit.o \
|
||||
bye.o change.o mbsebbs.o safe.o timeout.o user.o timecheck.o \
|
||||
exitinfo.o filesub.o lineedit.o offline.o language.o msgutil.o \
|
||||
pop3.o email.o input.o whoson.o door.o dispfile.o
|
||||
MBSEBBS_LIBS = ../lib/libmemwatch.a ../lib/libclcomm.a ../lib/libcommon.a ../lib/libmsgbase.a \
|
||||
../lib/libdbase.a ../lib/libmbinet.a
|
||||
MBNEWUSR_OBJS = mbnewusr.o newuser.o language.o bye.o timeout.o dispfile.o oneline.o \
|
||||
timecheck.o exitinfo.o input.o misc.o funcs.o funcs4.o pwcheck.o change.o \
|
||||
filesub.o mail.o email.o whoson.o msgutil.o pop3.o lineedit.o fsedit.o
|
||||
MBNEWUSR_OBJS = mbnewusr.o newuser.o language.o timeout.o dispfile.o oneline.o \
|
||||
timecheck.o input.o exitinfo.o mail.o email.o msgutil.o whoson.o \
|
||||
pop3.o funcs.o misc.o lineedit.o fsedit.o funcs4.o change.o \
|
||||
filesub.o
|
||||
MBNEWUSR_LIBS = ../lib/libmemwatch.a ../lib/libclcomm.a ../lib/libcommon.a ../lib/libmsgbase.a \
|
||||
../lib/libdbase.a ../lib/libmbinet.a
|
||||
MBALL_OBJS = mball.o
|
||||
@ -160,7 +161,6 @@ mbfbgen.o: ../lib/libs.h ../lib/structs.h ../lib/records.h ../lib/common.h ../li
|
||||
mbtoberep.o: ../lib/libs.h ../lib/structs.h
|
||||
msgutil.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/msgtext.h ../lib/msg.h oneline.h msgutil.h
|
||||
oneline.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h oneline.h funcs.h input.h language.h
|
||||
pwcheck.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h pwcheck.h funcs4.h timeout.h
|
||||
sgetpwent.o: ../config.h sgetpwent.h
|
||||
xmalloc.o: ../config.h xmalloc.h
|
||||
bbslist.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h bbslist.h funcs.h input.h language.h
|
||||
@ -179,11 +179,11 @@ funcs.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/co
|
||||
mail.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/msgtext.h ../lib/clcomm.h ../lib/msg.h mail.h funcs.h input.h language.h misc.h timeout.h oneline.h exitinfo.h lineedit.h fsedit.h filesub.h msgutil.h pop3.h email.h whoson.h
|
||||
mbpasswd.o: ../config.h encrypt.h rad64.h myname.h xmalloc.h pwio.h shadowio.h mbpasswd.h
|
||||
mbuseradd.o: ../config.h mbuseradd.h
|
||||
newuser.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h funcs4.h input.h pwcheck.h newuser.h language.h timeout.h change.h bye.h dispfile.h
|
||||
newuser.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h funcs4.h input.h newuser.h language.h timeout.h change.h dispfile.h
|
||||
pinfo.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h pinfo.h input.h
|
||||
rad64.o: ../config.h rad64.h
|
||||
timecheck.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h timecheck.h funcs.h funcs4.h misc.h bye.h exitinfo.h language.h
|
||||
change.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h change.h dispfile.h funcs.h funcs4.h input.h language.h misc.h pwcheck.h timeout.h exitinfo.h bye.h
|
||||
change.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h change.h dispfile.h funcs.h funcs4.h input.h language.h misc.h timeout.h exitinfo.h bye.h
|
||||
exitinfo.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h funcs.h input.h language.h oneline.h misc.h bye.h timeout.h timecheck.h exitinfo.h
|
||||
funcs4.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h ../lib/msg.h funcs4.h input.h misc.h timeout.h language.h
|
||||
mball.o: ../lib/libs.h ../lib/structs.h ../lib/mbse.h ../lib/records.h ../lib/common.h ../lib/dbcfg.h ../lib/clcomm.h mball.h
|
||||
@ -202,8 +202,8 @@ misc.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clc
|
||||
offline.o: ../lib/libs.h ../lib/structs.h ../lib/mbse.h ../lib/records.h ../lib/bluewave.h ../lib/common.h ../lib/clcomm.h ../lib/msgtext.h ../lib/msg.h mail.h funcs.h funcs4.h input.h language.h file.h filesub.h exitinfo.h timeout.h msgutil.h pop3.h offline.h whoson.h
|
||||
putpwent.o: ../config.h putpwent.h
|
||||
salt.o: ../config.h rad64.h getdef.h
|
||||
user.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h timeout.h user.h pwcheck.h dispfile.h funcs4.h input.h misc.h bye.h file.h mail.h change.h menu.h exitinfo.h language.h offline.h statetbl.h email.h
|
||||
mbnewusr.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h mbnewusr.h funcs.h funcs4.h input.h language.h misc.h bye.h timeout.h newuser.h
|
||||
user.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h timeout.h user.h dispfile.h funcs4.h input.h misc.h bye.h file.h mail.h change.h menu.h exitinfo.h language.h offline.h statetbl.h email.h
|
||||
mbnewusr.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h mbnewusr.h funcs.h funcs4.h input.h language.h misc.h timeout.h newuser.h
|
||||
input.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h input.h timeout.h language.h
|
||||
whoson.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h input.h language.h exitinfo.h whoson.h
|
||||
door.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h input.h timeout.h exitinfo.h whoson.h door.h
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include "input.h"
|
||||
#include "language.h"
|
||||
#include "misc.h"
|
||||
#include "pwcheck.h"
|
||||
#include "timeout.h"
|
||||
#include "exitinfo.h"
|
||||
#include "bye.h"
|
||||
@ -65,7 +64,7 @@ int Chg_Language(int NewMode)
|
||||
printf("\nFATAL: Can't open language file\n\n");
|
||||
Pause();
|
||||
free(temp);
|
||||
Quick_Bye(0);
|
||||
return 0;
|
||||
}
|
||||
fread(&langhdr, sizeof(langhdr), 1, pLang);
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
/*
|
||||
* Copy usersrecord into ~/tmp/.bbs-exitinfo.tty
|
||||
*/
|
||||
void InitExitinfo()
|
||||
int InitExitinfo()
|
||||
{
|
||||
FILE *pUsrConfig, *pExitinfo;
|
||||
char *temp;
|
||||
@ -63,7 +63,7 @@ void InitExitinfo()
|
||||
if ((pUsrConfig = fopen(temp,"r+b")) == NULL) {
|
||||
WriteError("$Can't open %s for writing", temp);
|
||||
free(temp);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fread(&usrconfighdr, sizeof(usrconfighdr), 1, pUsrConfig);
|
||||
@ -71,7 +71,7 @@ void InitExitinfo()
|
||||
if(fseek(pUsrConfig, offset, 0) != 0) {
|
||||
WriteError("$Can't move pointer in %s", temp);
|
||||
free(temp);
|
||||
Good_Bye(1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fread(&usrconfig, usrconfighdr.recsize, 1, pUsrConfig);
|
||||
@ -81,13 +81,16 @@ void InitExitinfo()
|
||||
|
||||
sprintf(temp, "%s/tmp/.bbs-exitinfo.%s", getenv("MBSE_ROOT"), pTTY);
|
||||
mkdirs(temp);
|
||||
if ((pExitinfo = fopen(temp, "w+b")) == NULL)
|
||||
if ((pExitinfo = fopen(temp, "w+b")) == NULL) {
|
||||
WriteError("$Can't open %s for writing", temp);
|
||||
else {
|
||||
free(temp);
|
||||
return FALSE;
|
||||
} else {
|
||||
fwrite(&exitinfo, sizeof(exitinfo), 1, pExitinfo);
|
||||
fclose(pExitinfo);
|
||||
}
|
||||
free(temp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#ifndef _EXITINFO_H
|
||||
#define _EXITINFO_H
|
||||
|
||||
void InitExitinfo(void); /* Create exitinfo */
|
||||
int InitExitinfo(void); /* Create exitinfo */
|
||||
void ReadExitinfo(void); /* Read Users Config in Memory */
|
||||
void WriteExitinfo(void); /* Write Users config from memory */
|
||||
|
||||
|
@ -476,6 +476,66 @@ void GetnameNE(char *sStr, int iMaxlen)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Open up /dev/tty to get the password from the user
|
||||
* because this is done in raw mode, it makes life a bit
|
||||
* more difficult.
|
||||
* This function gets a password from a user, upto Max_passlen
|
||||
*/
|
||||
void Getpass(char *theword)
|
||||
{
|
||||
unsigned char c = 0;
|
||||
int counter = 0;
|
||||
char password[Max_passlen+1];
|
||||
|
||||
/*
|
||||
* Open the device that we want to read the password from, you can't use
|
||||
* stdin as this might change in a pipe
|
||||
*/
|
||||
if ((ttyfd = open ("/dev/tty", O_RDWR)) < 0) {
|
||||
perror("open 7");
|
||||
ExitClient(1);
|
||||
}
|
||||
|
||||
/* Set Raw mode so that the characters don't echo */
|
||||
Setraw();
|
||||
alarm_on();
|
||||
|
||||
/*
|
||||
* Till the user presses ENTER or reaches the maximum length allowed
|
||||
*/
|
||||
while ((c != 13) && (counter < Max_passlen )) {
|
||||
|
||||
fflush(stdout);
|
||||
c = Readkey(); /* Reads a character from the raw device */
|
||||
|
||||
if (((c == 8) || (c == KEY_DEL) || (c == 127)) && (counter != 0 )) { /* If its a BACKSPACE */
|
||||
counter--;
|
||||
password[counter] = '\0';
|
||||
printf("\x008 \x008");
|
||||
continue;
|
||||
} /* Backtrack to fix the BACKSPACE */
|
||||
|
||||
if (((c == 8) || (c == KEY_DEL) || (c == 127)) && (counter == 0) ) {
|
||||
printf("\x007");
|
||||
continue;
|
||||
} /* Don't Backtrack as we are at the begining of the passwd field */
|
||||
|
||||
if (isalnum(c)) {
|
||||
password[counter] = c;
|
||||
counter++;
|
||||
printf("%c", CFG.iPasswd_Char);
|
||||
}
|
||||
}
|
||||
Unsetraw(); /* Go normal */
|
||||
close(ttyfd);
|
||||
|
||||
password[counter] = '\0'; /* Make sure the string has a NULL at the end*/
|
||||
strcpy(theword,password);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Pause()
|
||||
{
|
||||
int i, x;
|
||||
|
@ -12,6 +12,7 @@ void Getname(char *, int); /* Get name & convert every 1st char to U/C */
|
||||
void GetnameNE(char *, int); /* Get name & convert every 1st char to U/C */
|
||||
void GetDate(char *, int); /* Get users birth date and check */
|
||||
void GetPhone(char *, int); /* Get telephone number */
|
||||
void Getpass(char *); /* Get a password from the user */
|
||||
void Pause(void); /* Puts Pause on Screen and halts screen */
|
||||
|
||||
|
||||
|
@ -471,7 +471,7 @@ void Post_Msg()
|
||||
/*
|
||||
* Localmail and Echomail may be addressed to All
|
||||
*/
|
||||
if ((msgs.Type == LOCALMAIL) || (msgs.Type == ECHOMAIL)) {
|
||||
if ((msgs.Type == LOCALMAIL) || (msgs.Type == ECHOMAIL) || (msgs.Type == LIST)) {
|
||||
if (strcasecmp(Msg.To, "all") == 0)
|
||||
x = TRUE;
|
||||
else {
|
||||
@ -672,7 +672,8 @@ int Save_Msg(int IsReply, faddr *Dest)
|
||||
* Add quick mailscan info
|
||||
*/
|
||||
if (msgs.Type != LOCALMAIL) {
|
||||
sprintf(temp, "%s/tmp/%smail.jam", getenv("MBSE_ROOT"), (msgs.Type == ECHOMAIL)? "echo" : "net");
|
||||
sprintf(temp, "%s/tmp/%smail.jam", getenv("MBSE_ROOT"),
|
||||
((msgs.Type == ECHOMAIL) || (msgs.Type == LIST))? "echo" : "net");
|
||||
if ((fp = fopen(temp, "a")) != NULL) {
|
||||
fprintf(fp, "%s %lu\n", msgs.Base, Msg.Id);
|
||||
fclose(fp);
|
||||
@ -1413,7 +1414,8 @@ void QuickScan_Msgs()
|
||||
|
||||
if (Msg_Open(sMsgAreaBase)) {
|
||||
for (i = MsgBase.Lowest; i <= MsgBase.Highest; i++) {
|
||||
if (Msg_ReadHeader(i)) {
|
||||
if (Msg_ReadHeader(i) && ((msgs.Type != NETMAIL) ||
|
||||
((msgs.Type == NETMAIL) && ((IsMe(Msg.From)) || (IsMe(Msg.To)))))) {
|
||||
|
||||
colour(WHITE, BLACK);
|
||||
printf("%-6lu", Msg.Id);
|
||||
@ -2120,6 +2122,7 @@ void MailStatus()
|
||||
printf(" Net ");
|
||||
break;
|
||||
|
||||
case LIST:
|
||||
case ECHOMAIL:
|
||||
printf(" Echo ");
|
||||
break;
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "input.h"
|
||||
#include "language.h"
|
||||
#include "misc.h"
|
||||
#include "bye.h"
|
||||
#include "timeout.h"
|
||||
#include "newuser.h"
|
||||
|
||||
@ -132,7 +131,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if ((tty = ttyname(0)) == NULL) {
|
||||
WriteError("Not at a tty");
|
||||
Quick_Bye(0);
|
||||
Fast_Bye(0);
|
||||
}
|
||||
|
||||
if (strncmp("/dev/", tty, 5) == 0)
|
||||
@ -168,7 +167,7 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
if (CheckStatus() == FALSE) {
|
||||
Syslog('+', "Kicking user out, the BBS is closed");
|
||||
Quick_Bye(0);
|
||||
Fast_Bye(0);
|
||||
}
|
||||
|
||||
clear();
|
||||
@ -184,14 +183,12 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
sprintf(temp, "%s/etc/ttyinfo.data", getenv("MBSE_ROOT"));
|
||||
|
||||
iNode = 0;
|
||||
if ((pTty = fopen(temp, "r")) == NULL) {
|
||||
WriteError("Can't read %s", temp);
|
||||
} else {
|
||||
fread(&ttyinfohdr, sizeof(ttyinfohdr), 1, pTty);
|
||||
|
||||
while (fread(&ttyinfo, ttyinfohdr.recsize, 1, pTty) == 1) {
|
||||
iNode++;
|
||||
if (strcmp(ttyinfo.tty, pTTY) == 0)
|
||||
break;
|
||||
}
|
||||
@ -200,9 +197,8 @@ int main(int argc, char **argv)
|
||||
if ((strcmp(ttyinfo.tty, pTTY) != 0) || (!ttyinfo.available)) {
|
||||
Syslog('+', "No BBS allowed on port \"%s\"", pTTY);
|
||||
printf("No BBS on this port allowed!\n\n");
|
||||
Quick_Bye(0);
|
||||
Fast_Bye(0);
|
||||
}
|
||||
Syslog('b', "Node number %d", iNode);
|
||||
|
||||
/*
|
||||
* Ask whether to display Connect String
|
||||
@ -220,7 +216,7 @@ int main(int argc, char **argv)
|
||||
Pause();
|
||||
|
||||
newuser();
|
||||
Quick_Bye(0);
|
||||
Fast_Bye(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "timeout.h"
|
||||
|
||||
extern int do_quiet; /* Logging quiet flag */
|
||||
extern char *Passwd;
|
||||
time_t t_start;
|
||||
|
||||
|
||||
@ -211,7 +210,6 @@ int main(int argc, char **argv)
|
||||
|
||||
sprintf(sMailbox, "mailbox");
|
||||
colour(LIGHTGRAY, BLACK);
|
||||
Passwd = calloc(16, sizeof(char));
|
||||
user();
|
||||
return 0;
|
||||
}
|
||||
|
@ -177,6 +177,10 @@ void Add_Headkludges(faddr *dest, int IsReply)
|
||||
|
||||
break;
|
||||
|
||||
case LIST: Msg.Echomail = TRUE;
|
||||
sprintf(Msg.FromAddress, "%s", aka2str(msgs.Aka));
|
||||
break;
|
||||
|
||||
case ECHOMAIL: Msg.Echomail = TRUE;
|
||||
sprintf(Msg.FromAddress, "%s", aka2str(msgs.Aka));
|
||||
break;
|
||||
@ -279,7 +283,7 @@ void Add_Footkludges(int Quote)
|
||||
#endif
|
||||
MsgText_Add2(temp);
|
||||
|
||||
if (msgs.Type == ECHOMAIL) {
|
||||
if ((msgs.Type == ECHOMAIL) || (msgs.Type == LIST)) {
|
||||
/* RANDOM ORIGIN LINES IMPLEMENTEREN */
|
||||
if (msgs.Aka.point)
|
||||
sprintf(aka, "(%d:%d/%d.%d)", msgs.Aka.zone, msgs.Aka.net, msgs.Aka.node, msgs.Aka.point);
|
||||
|
@ -35,15 +35,12 @@
|
||||
#include "../lib/records.h"
|
||||
#include "../lib/clcomm.h"
|
||||
#include "../lib/common.h"
|
||||
//#include "funcs.h"
|
||||
#include "funcs4.h"
|
||||
#include "input.h"
|
||||
#include "pwcheck.h"
|
||||
#include "newuser.h"
|
||||
#include "language.h"
|
||||
#include "timeout.h"
|
||||
#include "change.h"
|
||||
#include "bye.h"
|
||||
#include "dispfile.h"
|
||||
|
||||
|
||||
@ -52,7 +49,8 @@ extern int do_quiet; /* No logging to the screen */
|
||||
extern pid_t mypid; /* Pid of this program */
|
||||
char UnixName[9]; /* Unix Name */
|
||||
extern char *ieHandle; /* Users Handle */
|
||||
|
||||
extern time_t t_start; /* Program starttime */
|
||||
int do_mailout = FALSE; /* Just for linking */
|
||||
|
||||
|
||||
int newuser()
|
||||
@ -71,7 +69,8 @@ int newuser()
|
||||
Syslog('+', "Newuser registration");
|
||||
clear();
|
||||
DisplayFile((char *)"newuser");
|
||||
iLang = Chg_Language(TRUE);
|
||||
if ((iLang = Chg_Language(TRUE)) == 0)
|
||||
Fast_Bye(1);
|
||||
|
||||
Enter(1);
|
||||
/* MBSE BBS - NEW USER REGISTRATION */
|
||||
@ -105,7 +104,7 @@ int newuser()
|
||||
*/
|
||||
if ((strcasecmp(temp, "off")) == 0) {
|
||||
Syslog('+', "Quick \"off\" logout");
|
||||
Quick_Bye(0);
|
||||
Fast_Bye(0);
|
||||
}
|
||||
|
||||
Count++;
|
||||
@ -115,7 +114,7 @@ int newuser()
|
||||
language(CFG.HiliteF, CFG.HiliteB, 2);
|
||||
Enter(2);
|
||||
Syslog('!', "Exceeded maximum login attempts");
|
||||
Quick_Bye(0);
|
||||
Fast_Bye(0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -376,8 +375,6 @@ int newuser()
|
||||
iLang = atoi(temp2) + 1900;
|
||||
sprintf(temp2, "%04d", iLang);
|
||||
|
||||
Syslog('-', "DOB: test %s %s", temp1, temp2);
|
||||
|
||||
if ((strcmp(temp1,temp2)) == 0) {
|
||||
Enter(1);
|
||||
/* Sorry you entered this year by mistake. */
|
||||
@ -445,6 +442,7 @@ int newuser()
|
||||
|
||||
usrconfig.tLastPwdChange = ltime; /* Days Since Last Password Change */
|
||||
usrconfig.iLastFileArea = 1;
|
||||
usrconfig.iLastMsgArea = 1;
|
||||
|
||||
sprintf(usrconfig.sProtocol, "%s", (char *) Language(65));
|
||||
usrconfig.DoNotDisturb = FALSE;
|
||||
@ -536,3 +534,43 @@ int newuser()
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Fast_Bye(int onsig)
|
||||
{
|
||||
char *temp;
|
||||
time_t t_end;
|
||||
|
||||
time(&t_end);
|
||||
Syslog(' ', "MBNEWUSR finished in %s", t_elapsed(t_start, t_end));
|
||||
socket_shutdown(mypid);
|
||||
|
||||
temp = calloc(PATH_MAX, sizeof(char));
|
||||
sprintf(temp, "%s/tmp/mbsebbs%d", getenv("MBSE_ROOT"), getpid());
|
||||
unlink(temp);
|
||||
free(temp);
|
||||
|
||||
colour(7, 0);
|
||||
fflush(stdout);
|
||||
fflush(stdin);
|
||||
sleep(3);
|
||||
|
||||
Free_Language();
|
||||
free(pTTY);
|
||||
#ifdef MEMWATCH
|
||||
mwTerm();
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This function is the same as Fast_Bye(), it's here
|
||||
* to link the other modules properly.
|
||||
*/
|
||||
void Good_Bye(int onsig)
|
||||
{
|
||||
Fast_Bye(onsig);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _NEWUSER_H
|
||||
#define _NEWUSER_H
|
||||
|
||||
|
||||
int newuser(void); /* Newuser function */
|
||||
|
||||
int newuser(void);
|
||||
void Fast_Bye(int);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -573,6 +573,7 @@ void New_Area(long Area)
|
||||
break;
|
||||
case NETMAIL: printf(Language(393)); /* Netmail */
|
||||
break;
|
||||
case LIST:
|
||||
case ECHOMAIL: printf(Language(394)); /* Echomail */
|
||||
break;
|
||||
case NEWS: printf(Language(395)); /* News */
|
||||
@ -1458,6 +1459,7 @@ void OLR_DownBW()
|
||||
case NETMAIL: AreaInf.area_flags |= (INF_ECHO+INF_NETMAIL+INF_HASFILE);
|
||||
break;
|
||||
|
||||
case LIST:
|
||||
case ECHOMAIL: AreaInf.area_flags |= INF_ECHO;
|
||||
break;
|
||||
|
||||
|
@ -1,103 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: bbs/pwcheck.c
|
||||
* Purpose ...............: Password checking routines
|
||||
* Last modification date : 18-Oct-2001
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2001
|
||||
*
|
||||
* Michiel Broek FIDO: 2:280/2802
|
||||
* Beekmansbos 10 Internet: mbroek@users.sourceforge.net
|
||||
* 1971 BV IJmuiden
|
||||
* the Netherlands
|
||||
*
|
||||
* This file is part of MBSE BBS.
|
||||
*
|
||||
* This BBS is free 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 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* MBSE BBS 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 MBSE BBS; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../lib/libs.h"
|
||||
#include "../lib/mbse.h"
|
||||
#include "../lib/structs.h"
|
||||
#include "../lib/records.h"
|
||||
#include "../lib/common.h"
|
||||
#include "../lib/clcomm.h"
|
||||
#include "pwcheck.h"
|
||||
#include "funcs4.h"
|
||||
#include "timeout.h"
|
||||
|
||||
|
||||
/*
|
||||
* Open up /dev/tty to get the password from the user
|
||||
* because this is done in raw mode, it makes life a bit
|
||||
* more difficult.
|
||||
* This function gets a password from a user, upto Max_passlen
|
||||
*/
|
||||
int Getpass(char *theword)
|
||||
{
|
||||
unsigned char c = 0;
|
||||
int counter = 0;
|
||||
char password[Max_passlen+1];
|
||||
|
||||
/*
|
||||
* Open the device that we want to read the password from, you can't use
|
||||
* stdin as this might change in a pipe
|
||||
*/
|
||||
if ((ttyfd = open ("/dev/tty", O_RDWR)) < 0) {
|
||||
perror("open 7");
|
||||
ExitClient(1);
|
||||
}
|
||||
|
||||
/* Set Raw mode so that the characters don't echo */
|
||||
Setraw();
|
||||
alarm_on();
|
||||
|
||||
/*
|
||||
* Till the user presses ENTER or reaches the maximum length allowed
|
||||
*/
|
||||
while ((c != 13) && (counter < Max_passlen )) {
|
||||
|
||||
fflush(stdout);
|
||||
c = Readkey(); /* Reads a character from the raw device */
|
||||
|
||||
if (((c == 8) || (c == KEY_DEL) || (c == 127)) && (counter != 0 )) { /* If its a BACKSPACE */
|
||||
counter--;
|
||||
password[counter] = '\0';
|
||||
printf("\x008 \x008");
|
||||
continue;
|
||||
} /* Backtrack to fix the BACKSPACE */
|
||||
|
||||
if (((c == 8) || (c == KEY_DEL) || (c == 127)) && (counter == 0) ) {
|
||||
printf("\x007");
|
||||
continue;
|
||||
} /* Don't Backtrack as we are at the begining of the passwd field */
|
||||
|
||||
if (isalnum(c)) {
|
||||
password[counter] = c;
|
||||
counter++;
|
||||
printf("%c", CFG.iPasswd_Char);
|
||||
}
|
||||
}
|
||||
Unsetraw(); /* Go normal */
|
||||
close(ttyfd);
|
||||
|
||||
password[counter] = '\0'; /* Make sure the string has a NULL at the end*/
|
||||
strcpy(theword,password);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
#ifndef _PWCHECK_H
|
||||
#define _PWCHECK_H
|
||||
|
||||
|
||||
int Getpass(char *);
|
||||
|
||||
#endif
|
||||
|
204
mbsebbs/user.c
204
mbsebbs/user.c
@ -38,7 +38,6 @@
|
||||
#include "../lib/clcomm.h"
|
||||
#include "timeout.h"
|
||||
#include "user.h"
|
||||
#include "pwcheck.h"
|
||||
#include "dispfile.h"
|
||||
#include "funcs4.h"
|
||||
#include "input.h"
|
||||
@ -67,9 +66,6 @@ char *StartTime;
|
||||
void SwapDate(char *, char *); /* Swap two Date strings around */
|
||||
|
||||
|
||||
char *Passwd = NULL;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function will take two date strings in the following format DD-MM-YYYY and
|
||||
@ -121,60 +117,54 @@ void user()
|
||||
FILE *pUsrConfig, *pLimits;
|
||||
int i, x;
|
||||
int FoundName = FALSE, iFoundLimit = FALSE;
|
||||
register int recno;
|
||||
int lrecno = 0;
|
||||
long l1, l2;
|
||||
unsigned crc = 0;
|
||||
char *token;
|
||||
char temp[PATH_MAX];
|
||||
char temp1[84];
|
||||
char sGetName[84];
|
||||
char *FileName;
|
||||
char *handle;
|
||||
struct passwd *pw;
|
||||
char *sGetPassword;
|
||||
long offset;
|
||||
time_t LastLogin;
|
||||
struct stat st;
|
||||
char UserName[36];
|
||||
char UserName[37];
|
||||
int IsNew = FALSE;
|
||||
|
||||
|
||||
recno=0;
|
||||
|
||||
grecno = 0;
|
||||
Syslog('+', "Unixmode login: %s", sUnixName);
|
||||
if ((pw = getpwnam(sUnixName)))
|
||||
strcpy(sGetName, pw->pw_gecos);
|
||||
|
||||
sprintf(temp, "%s/etc/users.data", getenv("MBSE_ROOT"));
|
||||
if ((pUsrConfig = fopen(temp,"r+b")) == NULL) {
|
||||
/*
|
||||
* If there are more fields in the passwd gecos field
|
||||
* then only get the first field.
|
||||
* This should not happen.
|
||||
*/
|
||||
if (strchr(sGetName, ',') != NULL)
|
||||
strcpy(sGetName, strtok(sGetName, ","));
|
||||
WriteError("$Can't open %s", temp);
|
||||
printf("Can't open userfile, run \"newuser\" first");
|
||||
ExitClient(0);
|
||||
}
|
||||
|
||||
if (!(CheckName(sGetName))) {
|
||||
printf("Unknown username: %s\n", sGetName);
|
||||
fread(&usrconfighdr, sizeof(usrconfighdr), 1, pUsrConfig);
|
||||
while (fread(&usrconfig, usrconfighdr.recsize, 1, pUsrConfig) == 1) {
|
||||
if (strcmp(usrconfig.Name, sUnixName) == 0) {
|
||||
FoundName = TRUE;
|
||||
break;
|
||||
} else
|
||||
grecno++;
|
||||
}
|
||||
|
||||
if (!FoundName) {
|
||||
printf("Unknown username: %s\n", sUnixName);
|
||||
/* FATAL ERROR: You are not in the BBS users file.*/
|
||||
printf("%s\n", (char *) Language(389));
|
||||
/* Please run 'newuser' to create an account */
|
||||
printf("%s\n", (char *) Language(390));
|
||||
Syslog('?', "FATAL: Could not find user in BBS users file.");
|
||||
Syslog('?', " and system is using unix accounts\n");
|
||||
free(Passwd);
|
||||
ExitClient(0);
|
||||
}
|
||||
|
||||
if (CFG.iCapUserName || SYSOP)
|
||||
strcpy(sGetName, tlcap(sGetName));
|
||||
|
||||
/*
|
||||
* Copy username, split first and lastname.
|
||||
*/
|
||||
strcpy(UserName, tlcap(sGetName));
|
||||
|
||||
if ((strchr(sGetName,' ') == NULL && !CFG.iOneName)) {
|
||||
token = strtok(sGetName, " ");
|
||||
strcpy(UserName, usrconfig.sUserName);
|
||||
if ((strchr(UserName,' ') == NULL && !CFG.iOneName)) {
|
||||
token = strtok(UserName, " ");
|
||||
strcpy(FirstName, token);
|
||||
token = strtok(NULL, "\0");
|
||||
i = strlen(token);
|
||||
@ -184,75 +174,16 @@ void user()
|
||||
}
|
||||
strcpy(LastName, token);
|
||||
} else
|
||||
strcpy(FirstName, sGetName);
|
||||
|
||||
strcpy(FirstName, UserName);
|
||||
strcpy(UserName, usrconfig.sUserName);
|
||||
Syslog('+', "%s On-Line at %s", UserName, ttyinfo.comment);
|
||||
IsDoing("Just Logged In");
|
||||
|
||||
/*
|
||||
* Check some essential files, create them if they don't exist.
|
||||
*/
|
||||
ChkFiles();
|
||||
|
||||
sprintf(temp, "%s/etc/users.data", getenv("MBSE_ROOT"));
|
||||
if ((pUsrConfig = fopen(temp,"r+b")) == NULL) {
|
||||
/*
|
||||
* This should only happen once, when you build the BBS
|
||||
*/
|
||||
WriteError("Can't open users file: %s", temp);
|
||||
printf("Can't open userfile, run \"newuser\" first");
|
||||
free(Passwd);
|
||||
ExitClient(0);
|
||||
}
|
||||
|
||||
handle = calloc(40, sizeof(char));
|
||||
fread(&usrconfighdr, sizeof(usrconfighdr), 1, pUsrConfig);
|
||||
strcpy(temp1, UserName);
|
||||
while (fread(&usrconfig, usrconfighdr.recsize, 1, pUsrConfig) == 1) {
|
||||
strcpy(temp, usrconfig.sUserName);
|
||||
strcpy(handle, usrconfig.sHandle);
|
||||
|
||||
if ((strcasecmp(temp, temp1) == 0 || strcasecmp(handle, temp1) == 0)) {
|
||||
FoundName = TRUE;
|
||||
break;
|
||||
} else
|
||||
recno++;
|
||||
}
|
||||
free(handle);
|
||||
|
||||
if (!FoundName) {
|
||||
Syslog('+', "Name not in user file");
|
||||
Enter(1);
|
||||
/* Scanning User File */
|
||||
language(LIGHTGRAY, BLACK, 3);
|
||||
Enter(1);
|
||||
|
||||
usrconfig.GraphMode = FALSE;
|
||||
DisplayFile((char *)"notfound");
|
||||
|
||||
Enter(1);
|
||||
/* Name entered: */
|
||||
language(LIGHTGRAY, BLACK, 5);
|
||||
printf("%s\n\n", UserName);
|
||||
/* Did you spell your name correctly [Y/n] */
|
||||
language(WHITE, BLACK, 4);
|
||||
fflush(stdout);
|
||||
fflush(stdin);
|
||||
i = toupper(Getone());
|
||||
if (i == Keystroke(4, 0) || i == '\r') {
|
||||
/*
|
||||
* Here we run newuser.
|
||||
*/
|
||||
Syslog('+', "Creating user ...");
|
||||
// recno = newuser(UserName);
|
||||
Quick_Bye(0);
|
||||
IsNew = TRUE;
|
||||
} else {
|
||||
Enter(1);
|
||||
Syslog('+', "User spelt his/her name incorrectly");
|
||||
user();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup users favourite language.
|
||||
*/
|
||||
@ -270,10 +201,13 @@ void user()
|
||||
*/
|
||||
strcpy(temp, UserName);
|
||||
strcpy(temp1, CFG.sysop_name);
|
||||
if ((strcasecmp(temp1, temp)) == 0)
|
||||
SYSOP = TRUE; /* If login name is sysop, set SYSOP true */
|
||||
|
||||
grecno = recno;
|
||||
if ((strcasecmp(CFG.sysop_name, UserName)) == 0) {
|
||||
/*
|
||||
* If login name is sysop, set SYSOP true
|
||||
*/
|
||||
SYSOP = TRUE;
|
||||
Syslog('+', "Sysop is online");
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this a new user?
|
||||
@ -281,22 +215,11 @@ void user()
|
||||
if (usrconfig.iTotalCalls == 0)
|
||||
IsNew = TRUE;
|
||||
|
||||
offset = usrconfighdr.hdrsize + (recno * usrconfighdr.recsize);
|
||||
if (fseek(pUsrConfig, offset, 0) != 0) {
|
||||
printf("Can't move pointer there.");
|
||||
getchar();
|
||||
free(Passwd);
|
||||
ExitClient(1);
|
||||
}
|
||||
|
||||
fread(&usrconfig, usrconfighdr.recsize, 1, pUsrConfig);
|
||||
TermInit(usrconfig.GraphMode);
|
||||
sGetPassword = malloc(Max_passlen+1);
|
||||
crc = usrconfig.iPassword;
|
||||
sprintf(Passwd, "%s", usrconfig.Password);
|
||||
|
||||
IsDoing("Just Logged In");
|
||||
|
||||
/*
|
||||
* Pause after logo screen.
|
||||
*/
|
||||
alarm_on();
|
||||
Pause();
|
||||
|
||||
@ -307,10 +230,6 @@ void user()
|
||||
Syslog('+', "Setup default archiver ZIP");
|
||||
}
|
||||
|
||||
recno = 0;
|
||||
free(sGetPassword);
|
||||
|
||||
|
||||
/*
|
||||
* Check users date format. We do it strict as we
|
||||
* need this to be good for several other purposes.
|
||||
@ -351,12 +270,10 @@ void user()
|
||||
/*
|
||||
* Copy limits.data into memory
|
||||
*/
|
||||
FileName = calloc(84, sizeof(char));
|
||||
sprintf(FileName, "%s/etc/limits.data", getenv("MBSE_ROOT"));
|
||||
sprintf(temp, "%s/etc/limits.data", getenv("MBSE_ROOT"));
|
||||
|
||||
if(( pLimits = fopen(FileName,"rb")) == NULL) {
|
||||
perror("");
|
||||
WriteError("Can't open file: %s", FileName);
|
||||
if ((pLimits = fopen(temp,"rb")) == NULL) {
|
||||
WriteError("$Can't open %s", temp);
|
||||
} else {
|
||||
fread(&LIMIThdr, sizeof(LIMIThdr), 1, pLimits);
|
||||
|
||||
@ -364,15 +281,13 @@ void user()
|
||||
if (LIMIT.Security == usrconfig.Security.level) {
|
||||
iFoundLimit = TRUE;
|
||||
break;
|
||||
} else
|
||||
lrecno++;
|
||||
}
|
||||
}
|
||||
fclose(pLimits);
|
||||
}
|
||||
free(FileName);
|
||||
|
||||
if (!iFoundLimit) {
|
||||
Syslog('?', "Unknown Security Level in limits.data");
|
||||
WriteError("Unknown Security Level in limits.data");
|
||||
usrconfig.iTimeLeft = 0; /* Could not find limit, so set to Zero */
|
||||
usrconfig.iTimeUsed = 0; /* Set to Zero as well */
|
||||
} else {
|
||||
@ -416,23 +331,24 @@ void user()
|
||||
LastLogin = usrconfig.tLastLoginDate;
|
||||
usrconfig.tLastLoginDate = ltime; /* Set current login to current date */
|
||||
usrconfig.iTotalCalls++;
|
||||
memset(&usrconfig.Password, 0, sizeof(usrconfig.Password));
|
||||
sprintf(usrconfig.Password, "%s", Passwd);
|
||||
|
||||
/*
|
||||
* Update user record.
|
||||
*/
|
||||
if (fseek(pUsrConfig, offset, 0) != 0)
|
||||
WriteError("Can't move pointer in file: %s", temp);
|
||||
else {
|
||||
if (fseek(pUsrConfig, usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize), 0) != 0) {
|
||||
WriteError("Can't seek in %s/etc/users.data", getenv("MBSE_ROOT"));
|
||||
} else {
|
||||
fwrite(&usrconfig, sizeof(usrconfig), 1, pUsrConfig);
|
||||
fclose(pUsrConfig);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write users structure to tmp file in ~/tmp
|
||||
* Write users structure to tmp file in ~/tmp/.bbs-exitinfo.ttyxx
|
||||
* A copy of the userrecord is also in the variable exitinfo.
|
||||
*/
|
||||
InitExitinfo();
|
||||
if (! InitExitinfo())
|
||||
Good_Bye(1);
|
||||
|
||||
GetLastUser();
|
||||
StartTime = xstrcpy(GetLocalHM());
|
||||
ChangeHomeDir(exitinfo.Name, exitinfo.Email);
|
||||
@ -442,7 +358,7 @@ void user()
|
||||
usrconfig.Security.level, LIMIT.Description, usrconfig.iTimeLeft, pTTY);
|
||||
time(&Time2Go);
|
||||
Time2Go += usrconfig.iTimeLeft * 60;
|
||||
iUserTimeLeft = usrconfig.iTimeLeft;
|
||||
iUserTimeLeft = exitinfo.iTimeLeft;
|
||||
|
||||
DisplayFile((char *)"mainlogo");
|
||||
DisplayFile((char *)"welcome");
|
||||
@ -463,7 +379,7 @@ void user()
|
||||
DisplayFile((char *)"welcome9");
|
||||
|
||||
sprintf(temp, "%s", (char *) GetDateDMY() );
|
||||
if ((strcmp(usrconfig.sDateOfBirth, temp)) == 0)
|
||||
if ((strcmp(exitinfo.sDateOfBirth, temp)) == 0)
|
||||
DisplayFile((char *)"birthday");
|
||||
|
||||
/*
|
||||
@ -478,7 +394,7 @@ void user()
|
||||
/*
|
||||
* Displays users security file if it exists
|
||||
*/
|
||||
sprintf(temp, "sec%d", usrconfig.Security.level);
|
||||
sprintf(temp, "sec%d", exitinfo.Security.level);
|
||||
DisplayFile(temp);
|
||||
|
||||
/*
|
||||
@ -492,7 +408,7 @@ void user()
|
||||
* file, search order is the same as in DisplayFile()
|
||||
*/
|
||||
st.st_mtime = 0;
|
||||
if (usrconfig.GraphMode) {
|
||||
if (exitinfo.GraphMode) {
|
||||
sprintf(temp, "%s/onceonly.ans", lang.TextPath);
|
||||
stat(temp, &st);
|
||||
if (st.st_mtime == 0) {
|
||||
@ -514,21 +430,19 @@ void user()
|
||||
|
||||
OLR_SyncTags();
|
||||
|
||||
if (usrconfig.MailScan)
|
||||
if (exitinfo.MailScan)
|
||||
CheckMail();
|
||||
|
||||
/*
|
||||
* We don't show new files to new users, their lastlogin
|
||||
* date is not yet set so they would see all the files
|
||||
* which can be boring...
|
||||
* We don't show new files to new users.
|
||||
*/
|
||||
if (usrconfig.ieFILE && (!IsNew))
|
||||
if (exitinfo.ieFILE && (!IsNew))
|
||||
NewfileScan(FALSE);
|
||||
|
||||
/*
|
||||
* Copy last file Area in to current Area
|
||||
*/
|
||||
SetFileArea(usrconfig.iLastFileArea);
|
||||
SetFileArea(exitinfo.iLastFileArea);
|
||||
|
||||
/*
|
||||
* Copy Last Message Area in to Current Msg Area
|
||||
@ -543,10 +457,8 @@ void user()
|
||||
UserSilent(usrconfig.DoNotDisturb);
|
||||
|
||||
/*
|
||||
* Start the menu, but first, wipe the password.
|
||||
* Start the menu.
|
||||
*/
|
||||
memset(Passwd, 0, sizeof(Passwd));
|
||||
free(Passwd);
|
||||
menu();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user