/* $Id$ */ #define _UTIL_C_ #include "bbs.h" time4_t now; #undef MAX_GUEST_LIFE #undef MAX_LIFE // override max life #define MAX_GUEST_LIFE (365L * 24 * 60 * 60) #define MAX_LIFE (365L *10 * 24 * 60 * 60) static int free_accs = 0; int check_free(void *data, int n, userec_t *u) { if (u->userid[0] == 0) free_accs++; return 0; } int check(void *data, int n, userec_t *u) { time4_t d; char buf[256]; (void)data; if (u->userid[0] == 0 && u->userid[1]) { // expired user, clean record! syslog(LOG_ERR, "reset record (%d)", n+1); memset(u, 0, sizeof(userec_t)); passwd_update(n+1, u); return 0; } if(u->userid[0] != '\0') { if(!is_validuserid(u->userid)) { syslog(LOG_ERR, "bad userid(%d): %s", n, u->userid); u->userid[0] = '\0'; } else { // test PASSWD synchronization /* int unum = searchuser(u->userid, u->userid); if (unum == 0) { strcpy(buf, ctime4(&u->lastlogin)); syslog(LOG_NOTICE, "invalid user record (%d): %s (%s) %s", n+1, u->userid, (u->userlevel & PERM_LOGINOK) ? "regok" : "unreg", buf ); u->userid[0] = '\0'; passwd_update(n+1, u); } return 0; */ d = now - u->lastlogin; // ignore regged accounts now. if (u->userlevel & PERM_LOGINOK) return 0; if (u->userlevel & PERM_SYSOP) return 0; if (u->userlevel & PERM_XEMPT) return 0; // if((d > MAX_GUEST_LIFE && (u->userlevel & PERM_LOGINOK) == 0) // || (d > MAX_LIFE && (u->userlevel & PERM_XEMPT) == 0)) { if(d > MAX_GUEST_LIFE) { /* expired */ int unum; unum = searchuser(u->userid, u->userid); strcpy(buf, ctime4(&u->lastlogin)); if (unum != n+1) { syslog(LOG_NOTICE, "out-of-sync user(%d/%d): %s %s", unum, n, u->userid, buf); } else if (unum != 0) { syslog(LOG_NOTICE, "kill user(%d): %s %s", unum, // (u->userlevel & PERM_LOGINOK) ? "regok" : "guest", u->userid, buf); log_filef(FN_USIES, LOG_CREAT, "%s %s %-12s %s", Cdate(&now), "CLEAN(EXPIRE)", u->userid, buf); sprintf(buf, "mv home/%c/%s tmp/", u->userid[0], u->userid); if(system(buf)) syslog(LOG_ERR, "can't move user home: %s", u->userid); u->userid[0] = '\0'; setuserid(unum, u->userid); // flush into passwd memset(u, 0, sizeof(userec_t)); passwd_update(unum, u); } else { /* static int changed = 0; if (changed ++ > 10) exit(0); */ syslog(LOG_NOTICE, "clean user(%d): %s %s", n+1, u->userid, buf); log_filef(FN_USIES, LOG_CREAT, "%s %s %-12s %s", Cdate(&now), "CLEAN(CLEAR)", u->userid, buf); u->userid[0] = '\0'; memset(u, 0, sizeof(userec_t)); passwd_update(n+1, u); } } } } return 0; } int check_last_login(void *data, int n, userec_t *u) { char buf[256]; if (u->userid[0] == 0) return 0; // ignore all XEMPTY users if (u->userlevel & PERM_XEMPT) return 0; strcpy(buf, Cdate(&u->firstlogin)); if (u->lastlogin > now + 86400 || u->lastlogin < 0) // should not be newer than now plus one day. { // invalid record printf("使用者 %-*s (登入%3d 次, %s%s, %s [%04X])\n 最後登入日期異常 [%04X]: %s", IDLEN, u->userid, u->numlogins, (u->userlevel & PERM_LOGINOK) ? "已過認證" : "未過認證", (u->userlevel & PERM_SYSOP) ? "[SYSOP]" : "", buf, (unsigned)u->firstlogin, (unsigned)u->lastlogin, ctime4(&u->lastlogin)); // fix it u->lastlogin = u->firstlogin; if (u->lastlogin > now) { printf(" (首次登入日期也異常)"); u->lastlogin = u->firstlogin = 0x362CFC7E; } printf(" 已修正登入日期為: %s\n", ctime4(&u->lastlogin)); // flush passwd_update(n+1, u); } return 0; } int main(int argc, char **argv) { now = time(NULL); openlog("reaper", LOG_PID | LOG_PERROR, SYSLOG_FACILITY); chdir(BBSHOME); attach_SHM(); if(passwd_init()) exit(1); passwd_apply(NULL, check); // passwd_apply(NULL, check_free); // printf("free accounts=%d\n", free_accs); return 0; }