diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/bbs/Makefile | 2 | ||||
-rw-r--r-- | common/bbs/passwd.c | 268 |
2 files changed, 269 insertions, 1 deletions
diff --git a/common/bbs/Makefile b/common/bbs/Makefile index 6db6f465..5e051079 100644 --- a/common/bbs/Makefile +++ b/common/bbs/Makefile @@ -3,7 +3,7 @@ SRCROOT:= ../.. .include "$(SRCROOT)/pttbbs.mk" -SRCS:= log.c money.c names.c path.c time.c string.c fhdr_stamp.c cache.c +SRCS:= log.c money.c names.c path.c time.c string.c fhdr_stamp.c cache.c passwd.c LIB:= cmbbs install: diff --git a/common/bbs/passwd.c b/common/bbs/passwd.c new file mode 100644 index 00000000..3c41793d --- /dev/null +++ b/common/bbs/passwd.c @@ -0,0 +1,268 @@ +/* $Id$ */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include "cmbbs.h" + +#if 0 + +static int semid = -1; + +#ifndef SEM_R +#define SEM_R 0400 +#endif + +#ifndef SEM_A +#define SEM_A 0200 +#endif + +#ifndef __FreeBSD__ +#include <sys/sem.h> +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + unsigned short *array; /* array for GETALL & SETALL */ + struct seminfo *__buf; /* buffer for IPC_INFO */ +}; +#endif + +int +passwd_init(void) +{ + semid = semget(PASSWDSEM_KEY, 1, SEM_R | SEM_A | IPC_CREAT | IPC_EXCL); + if (semid == -1) { + if (errno == EEXIST) { + semid = semget(PASSWDSEM_KEY, 1, SEM_R | SEM_A); + if (semid == -1) { + perror("semget"); + exit(1); + } + } else { + perror("semget"); + exit(1); + } + } else { + union semun s; + + s.val = 1; + if (semctl(semid, 0, SETVAL, s) == -1) { + perror("semctl"); + exit(1); + } + } + + return 0; +} + +int +passwd_update_money(int num) +/* update money only + Ptt: don't call it directly, call deumoney() */ +{ + int pwdfd; + int money=moneyof(num); + userec_t u; + if (num < 1 || num > MAX_USERS) + return -1; + + if ((pwdfd = open(fn_passwd, O_WRONLY)) < 0) + exit(1); + lseek(pwdfd, sizeof(userec_t) * (num - 1) + + ((char *)&u.money - (char *)&u), SEEK_SET); + write(pwdfd, &money, sizeof(int)); + close(pwdfd); + return 0; +} + +void +passwd_force_update(int flag) +{ + if(!currutmp || (currutmp->alerts & ALERT_PWD) == 0) + return; + currutmp->alerts &= ~flag; +} + +int +passwd_update(int num, userec_t * buf) +{ + int pwdfd; + if (num < 1 || num > MAX_USERS) + return -1; + buf->money = moneyof(num); + if(usernum == num && currutmp && ((pwdfd = currutmp->alerts) & ALERT_PWD)) + { + userec_t u; + passwd_query(num, &u); + if(pwdfd & ALERT_PWD_BADPOST) + cuser.badpost = buf->badpost = u.badpost; + if(pwdfd & ALERT_PWD_GOODPOST) + cuser.goodpost = buf->goodpost = u.goodpost; + if(pwdfd & ALERT_PWD_PERM) + cuser.userlevel = buf->userlevel = u.userlevel; + if(pwdfd & ALERT_PWD_JUSTIFY) + { + memcpy(buf->justify, u.justify, sizeof(u.justify)); + memcpy(cuser.justify, u.justify, sizeof(u.justify)); + memcpy(buf->email, u.email, sizeof(u.email)); + memcpy(cuser.email, u.email, sizeof(u.email)); + } + cuser.numposts += u.numposts - latest_numposts; + currutmp->alerts &= ~ALERT_PWD; + + // ALERT_PWD_RELOAD: reload all! No need to write. + if (pwdfd & ALERT_PWD_RELOAD) + { + memcpy(&cuser, &u, sizeof(u)); + return 0; + } + } + if ((pwdfd = open(fn_passwd, O_WRONLY)) < 0) + exit(1); + lseek(pwdfd, sizeof(userec_t) * (num - 1), SEEK_SET); + write(pwdfd, buf, sizeof(userec_t)); + close(pwdfd); + +#ifndef _BBS_UTIL_C_ + if (latest_numposts != cuser.numposts) { + sendalert_uid(usernum, ALERT_PWD_POSTS); + latest_numposts = cuser.numposts; + } +#endif + return 0; +} + +int +passwd_query(int num, userec_t * buf) +{ + int pwdfd; + if (num < 1 || num > MAX_USERS) + return -1; + if ((pwdfd = open(fn_passwd, O_RDONLY)) < 0) + exit(1); + lseek(pwdfd, sizeof(userec_t) * (num - 1), SEEK_SET); + read(pwdfd, buf, sizeof(userec_t)); + close(pwdfd); + + if (buf == &cuser) + latest_numposts = cuser.numposts; + + return 0; +} + +int initcuser(const char *userid) +{ + // Ptt: setup cuser and usernum here + if(userid[0]=='\0' || + !(usernum = searchuser(userid, NULL)) || usernum > MAX_USERS) + return -1; + passwd_query(usernum, &cuser); + return usernum; +} + +int +passwd_apply(void *ctx, int (*fptr) (void *ctx, int, userec_t *)) +{ + int i; + userec_t user; + for (i = 0; i < MAX_USERS; i++) { + passwd_query(i + 1, &user); + if ((*fptr) (ctx, i, &user) < 0) + return -1; + } + return 0; +} + +void +passwd_lock(void) +{ + struct sembuf buf = {0, -1, SEM_UNDO}; + + if (semop(semid, &buf, 1)) { + perror("semop"); + exit(1); + } +} + +void +passwd_unlock(void) +{ + struct sembuf buf = {0, 1, SEM_UNDO}; + + if (semop(semid, &buf, 1)) { + perror("semop"); + exit(1); + } +} + +// XXX NOTE: string in plain will be destroyed. +int +checkpasswd(const char *passwd, char *plain) +{ + int ok; + char *pw; + + ok = 0; + pw = fcrypt(plain, passwd); + if(pw && strcmp(pw, passwd)==0) + ok = 1; + memset(plain, 0, strlen(plain)); + + return ok; +} + +char * +genpasswd(char *pw) +{ + if (pw[0]) { + char saltc[2], c; + int i; + + i = 9 * getpid(); + saltc[0] = i & 077; + saltc[1] = (i >> 6) & 077; + + for (i = 0; i < 2; i++) { + c = saltc[i] + '.'; + if (c > '9') + c += 7; + if (c > 'Z') + c += 6; + saltc[i] = c; + } + return fcrypt(pw, saltc); + } + return ""; +} + + +void +logattempt(const char *uid, char type, time4_t now, const char *loghost) +{ + char fname[PATHLEN]; + int fd, len; + char genbuf[200]; + + snprintf(genbuf, sizeof(genbuf), "%c%-12s[%s] ?@%s\n", type, uid, + Cdate(&now), loghost); + len = strlen(genbuf); + // log to public (BBSHOME) + if ((fd = open(FN_BADLOGIN, O_WRONLY | O_CREAT | O_APPEND, 0644)) > 0) { + write(fd, genbuf, len); + close(fd); + } + // log to user private log + if (type == '-') { + snprintf(genbuf, sizeof(genbuf), + "[%s] %s\n", Cdate(&now), loghost); + len = strlen(genbuf); + sethomefile(fname, uid, FN_BADLOGIN); + if ((fd = open(fname, O_WRONLY | O_CREAT | O_APPEND, 0644)) > 0) { + write(fd, genbuf, len); + close(fd); + } + } +} + +#endif |