summaryrefslogtreecommitdiffstats
path: root/mbbsd
diff options
context:
space:
mode:
authorvictor <victor@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-08-08 14:49:40 +0800
committervictor <victor@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-08-08 14:49:40 +0800
commit299369f41fae2c8ab2886ef41ad24815241707aa (patch)
tree6e35e4527fe15ae8e7484e492e976394da97a22b /mbbsd
parent0472f505661582dcaccf2d1a024abf14f2c75e5b (diff)
downloadpttbbs-299369f41fae2c8ab2886ef41ad24815241707aa.tar
pttbbs-299369f41fae2c8ab2886ef41ad24815241707aa.tar.gz
pttbbs-299369f41fae2c8ab2886ef41ad24815241707aa.tar.bz2
pttbbs-299369f41fae2c8ab2886ef41ad24815241707aa.tar.lz
pttbbs-299369f41fae2c8ab2886ef41ad24815241707aa.tar.xz
pttbbs-299369f41fae2c8ab2886ef41ad24815241707aa.tar.zst
pttbbs-299369f41fae2c8ab2886ef41ad24815241707aa.zip
fix race condition of user registeration (as well as while restoring a
backed-up account): Procoess A Process B ====================== ===================== uid = searchuser("") uid = searchuser("") setuserid(uid, userid) setuserid(uid, userid) git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3007 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd')
-rw-r--r--mbbsd/admin.c16
-rw-r--r--mbbsd/register.c54
2 files changed, 29 insertions, 41 deletions
diff --git a/mbbsd/admin.c b/mbbsd/admin.c
index cb79582c..eb6b47d1 100644
--- a/mbbsd/admin.c
+++ b/mbbsd/admin.c
@@ -141,21 +141,7 @@ search_key_user(const char *passwdfile, int mode)
outs("目前的PASSWDS檔沒有此id "
"請先new一個這個id的帳號");
} else {
- int allocid = getnewuserid();
-
- if (allocid > MAX_USERS || allocid <= 0) {
- fprintf(stderr, "本站人口已達飽和!\n");
- exit(1);
- }
- if (passwd_update(allocid, &user) == -1) {
- fprintf(stderr, "客滿了,再見!\n");
- exit(1);
- }
- setuserid(allocid, user.userid);
- if (!searchuser(user.userid, NULL)) {
- fprintf(stderr, "無法建立帳號\n");
- exit(1);
- }
+ setupnewuser(&user);
fclose(fp1);
return 0;
}
diff --git a/mbbsd/register.c b/mbbsd/register.c
index 65133010..50959cd0 100644
--- a/mbbsd/register.c
+++ b/mbbsd/register.c
@@ -134,19 +134,19 @@ check_and_expire_account(int uid, const userec_t * urec)
int
-getnewuserid(void)
+setupnewuser(const userec_t *user)
{
char genbuf[50];
char *fn_fresh = ".fresh";
userec_t utmp;
time_t clock;
struct stat st;
- int fd, i;
+ int fd, uid;
clock = now;
/* Lazy method : 先找尋已經清除的過期帳號 */
- if ((i = searchuser("", NULL)) == 0) {
+ if ((uid = searchuser("", NULL)) == 0) {
/* 每 1 個小時,清理 user 帳號一次 */
if ((stat(fn_fresh, &st) == -1) || (st.st_mtime < clock - 3600)) {
if ((fd = open(fn_fresh, O_RDWR | O_CREAT, 0600)) == -1)
@@ -161,25 +161,37 @@ getnewuserid(void)
return -1;
/* 不曉得為什麼要從 2 開始... Ptt:因為SYSOP在1 */
- for (i = 2; i <= MAX_USERS; i++) {
- passwd_query(i, &utmp);
- check_and_expire_account(i, &utmp);
+ for (uid = 2; uid <= MAX_USERS; uid++) {
+ passwd_query(uid, &utmp);
+ check_and_expire_account(uid, &utmp);
}
}
}
+
passwd_lock();
- i = searchuser("", NULL);
- if ((i <= 0) || (i > MAX_USERS)) {
+
+ uid = searchuser("", NULL);
+ if ((uid <= 0) || (uid > MAX_USERS)) {
passwd_unlock();
vmsg("抱歉,使用者帳號已經滿了,無法註冊新的帳號");
exit(1);
}
- snprintf(genbuf, sizeof(genbuf), "uid %d", i);
+
+ setuserid(uid, user->userid);
+ snprintf(genbuf, sizeof(genbuf), "uid %d", uid);
log_usies("APPLY", genbuf);
- kill_user(i);
+ SHM->money[uid - 1] = user->money;
+
+ if (passwd_update(uid, (userec_t *)user) == -1) {
+ passwd_unlock();
+ vmsg("客滿了,再見!");
+ exit(1);
+ }
+
passwd_unlock();
- return i;
+
+ return uid;
}
void
@@ -187,7 +199,7 @@ new_register(void)
{
userec_t newuser;
char passbuf[STRLEN];
- int allocid, try, id, uid;
+ int try, id, uid;
#ifdef HAVE_USERAGREEMENT
more(HAVE_USERAGREEMENT, YEA);
@@ -270,20 +282,10 @@ new_register(void)
newuser.uflag |= DBCSAWARE_FLAG;
#endif
- allocid = getnewuserid();
- if (allocid > MAX_USERS || allocid <= 0) {
- fprintf(stderr, "本站人口已達飽和!\n");
- exit(1);
- }
- if (passwd_update(allocid, &newuser) == -1) {
- fprintf(stderr, "客滿了,再見!\n");
- exit(1);
- }
- setuserid(allocid, newuser.userid);
- if( (uid = initcuser(newuser.userid)) )
- setumoney(uid, 0);
- else{
- fprintf(stderr, "無法建立帳號\n");
+ setupnewuser(&newuser);
+
+ if( (uid = initcuser(newuser.userid)) < 0) {
+ vmsg("無法建立帳號");
exit(1);
}
log_usies("REGISTER", fromhost);