env_unix.c
来自「广泛使用的邮件服务器!同时」· C语言 代码 · 共 1,848 行 · 第 1/5 页
C
1,848 行
case SET_FTPPROTECTION: ftp_protection = (long) value; case GET_FTPPROTECTION: ret = (void *) ftp_protection; break; case SET_PUBLICPROTECTION: public_protection = (long) value; case GET_PUBLICPROTECTION: ret = (void *) public_protection; break; case SET_SHAREDPROTECTION: shared_protection = (long) value; case GET_SHAREDPROTECTION: ret = (void *) shared_protection; break; case SET_FTPDIRPROTECTION: ftp_dir_protection = (long) value; case GET_FTPDIRPROTECTION: ret = (void *) ftp_dir_protection; break; case SET_PUBLICDIRPROTECTION: public_dir_protection = (long) value; case GET_PUBLICDIRPROTECTION: ret = (void *) public_dir_protection; break; case SET_SHAREDDIRPROTECTION: shared_dir_protection = (long) value; case GET_SHAREDDIRPROTECTION: ret = (void *) shared_dir_protection; break; case SET_LOCKTIMEOUT: locktimeout = (long) value; case GET_LOCKTIMEOUT: ret = (void *) locktimeout; break; case SET_DISABLEFCNTLLOCK: fcntlhangbug = value ? T : NIL; case GET_DISABLEFCNTLLOCK: ret = (void *) (fcntlhangbug ? VOIDT : NIL); break; case SET_LOCKEACCESERROR: disableLockWarning = value ? NIL : T; case GET_LOCKEACCESERROR: ret = (void *) (disableLockWarning ? NIL : VOIDT); break; case SET_HIDEDOTFILES: hideDotFiles = value ? T : NIL; case GET_HIDEDOTFILES: ret = (void *) (hideDotFiles ? VOIDT : NIL); break; case SET_DISABLEPLAINTEXT: disablePlaintext = (long) value; case GET_DISABLEPLAINTEXT: ret = (void *) disablePlaintext; break; case SET_CHROOTSERVER: closedBox = value ? T : NIL; case GET_CHROOTSERVER: ret = (void *) (closedBox ? VOIDT : NIL); break; case SET_ADVERTISETHEWORLD: advertisetheworld = value ? T : NIL; case GET_ADVERTISETHEWORLD: ret = (void *) (advertisetheworld ? VOIDT : NIL); break; case SET_LIMITEDADVERTISE: limitedadvertise = value ? T : NIL; case GET_LIMITEDADVERTISE: ret = (void *) (limitedadvertise ? VOIDT : NIL); break; case SET_DISABLEAUTOSHAREDNS: noautomaticsharedns = value ? T : NIL; case GET_DISABLEAUTOSHAREDNS: ret = (void *) (noautomaticsharedns ? VOIDT : NIL); break; case SET_DISABLE822TZTEXT: no822tztext = value ? T : NIL; case GET_DISABLE822TZTEXT: ret = (void *) (no822tztext ? VOIDT : NIL); break; case SET_USERHASNOLIFE: has_no_life = value ? T : NIL; case GET_USERHASNOLIFE: ret = (void *) (has_no_life ? VOIDT : NIL); break; case SET_KERBEROS_CP_SVR_NAME: kerb_cp_svr_name = value ? T : NIL; case GET_KERBEROS_CP_SVR_NAME: ret = (void *) (kerb_cp_svr_name ? VOIDT : NIL); break; case SET_NETFSSTATBUG: netfsstatbug = value ? T : NIL; case GET_NETFSSTATBUG: ret = (void *) (netfsstatbug ? VOIDT : NIL); break; case SET_BLOCKENVINIT: block_env_init = value ? T : NIL; case GET_BLOCKENVINIT: ret = (void *) (block_env_init ? VOIDT : NIL); break; case SET_BLOCKNOTIFY: mailblocknotify = (blocknotify_t) value; case GET_BLOCKNOTIFY: ret = (void *) mailblocknotify; break; case SET_LOGOUTHOOK: maillogouthook = (logouthook_t) value; case GET_LOGOUTHOOK: ret = maillogouthook; break; case SET_LOGOUTDATA: maillogoutdata = (void *) value; case GET_LOGOUTDATA: ret = maillogoutdata; } return ret;}/* Write current time * Accepts: destination string * optional format of day-of-week prefix * format of date and time * flag whether to append symbolic timezone */static void do_date (char *date,char *prefix,char *fmt,int suffix){ time_t tn = time (0); struct tm *t = gmtime (&tn); int zone = t->tm_hour * 60 + t->tm_min; int julian = t->tm_yday; t = localtime (&tn); /* get local time now */ /* minus UTC minutes since midnight */ zone = t->tm_hour * 60 + t->tm_min - zone; /* julian can be one of: * 36x local time is December 31, UTC is January 1, offset -24 hours * 1 local time is 1 day ahead of UTC, offset +24 hours * 0 local time is same day as UTC, no offset * -1 local time is 1 day behind UTC, offset -24 hours * -36x local time is January 1, UTC is December 31, offset +24 hours */ if (julian = t->tm_yday -julian) zone += ((julian < 0) == (abs (julian) == 1)) ? -24*60 : 24*60; if (prefix) { /* want day of week? */ sprintf (date,prefix,days[t->tm_wday]); date += strlen (date); /* make next sprintf append */ } /* output the date */ sprintf (date,fmt,t->tm_mday,months[t->tm_mon],t->tm_year+1900, t->tm_hour,t->tm_min,t->tm_sec,zone/60,abs (zone) % 60); /* append timezone suffix if desired */ if (suffix) rfc822_timezone (date,(void *) t);}/* Write current time in RFC 822 format * Accepts: destination string */void rfc822_date (char *date){ do_date (date,"%s, ","%d %s %d %02d:%02d:%02d %+03d%02d", no822tztext ? NIL : T);}/* Write current time in fixed-width RFC 822 format * Accepts: destination string */void rfc822_fixed_date (char *date){ do_date (date,NIL,"%02d %s %4d %02d:%02d:%02d %+03d%02d",NIL);}/* Write current time in internal format * Accepts: destination string */void internal_date (char *date){ do_date (date,NIL,"%02d-%s-%d %02d:%02d:%02d %+03d%02d",NIL);}/* Initialize server * Accepts: server name for syslog or NIL * /etc/services service name or NIL * alternate /etc/services service name or NIL * clock interrupt handler * kiss-of-death interrupt handler * hangup interrupt handler * termination interrupt handler */void server_init (char *server,char *service,char *sslservice, void *clkint,void *kodint,void *hupint,void *trmint, void *staint){ int onceonly = server && service && sslservice; if (onceonly) { /* set server name in syslog */ int mask; openlog (myServerName = cpystr (server),LOG_PID,syslog_facility); fclose (stderr); /* possibly save a process ID */ dorc (NIL,NIL); /* do systemwide configuration */ switch (mask = umask (022)){/* check old umask */ case 0: /* definitely unreasonable */ case 022: /* don't need to change it */ break; default: /* already was a reasonable value */ umask (mask); /* so change it back */ } } arm_signal (SIGALRM,clkint); /* prepare for clock interrupt */ arm_signal (SIGUSR2,kodint); /* prepare for Kiss Of Death */ arm_signal (SIGHUP,hupint); /* prepare for hangup */ arm_signal (SIGPIPE,hupint); /* alternative hangup */ arm_signal (SIGTERM,trmint); /* prepare for termination */ /* status dump */ if (staint) arm_signal (SIGUSR1,staint); if (onceonly) { /* set up network and maybe SSL */ long port; struct servent *sv; /* Use SSL if SSL service, or if server starts with "s" and not service */ if (((port = tcp_serverport ()) >= 0)) { if ((sv = getservbyname (service,"tcp")) && (port == ntohs (sv->s_port))) syslog (LOG_DEBUG,"%s service init from %s",service,tcp_clientaddr ()); else if ((sv = getservbyname (sslservice,"tcp")) && (port == ntohs (sv->s_port))) { syslog (LOG_DEBUG,"%s SSL service init from %s",sslservice, tcp_clientaddr ()); ssl_server_init (server); } else { /* not service or SSL service port */ syslog (LOG_DEBUG,"port %ld service init from %s",port, tcp_clientaddr ()); if (*server == 's') ssl_server_init (server); } } }}/* Wait for stdin input * Accepts: timeout in seconds * Returns: T if have input on stdin, else NIL */long server_input_wait (long seconds){ fd_set rfd,efd; struct timeval tmo; FD_ZERO (&rfd); FD_ZERO (&efd); FD_SET (0,&rfd); FD_SET (0,&efd); tmo.tv_sec = seconds; tmo.tv_usec = 0; return select (1,&rfd,0,&efd,&tmo) ? LONGT : NIL;}/* Return UNIX password entry for user name * Accepts: user name string * Returns: password entry * * Tries all-lowercase form of user name if given user name fails */static struct passwd *pwuser (unsigned char *user){ unsigned char *s; struct passwd *pw = getpwnam (user); if (!pw) { /* failed, see if any uppercase characters */ for (s = user; *s && ((*s < 'A') || (*s > 'Z')); s++); if (*s) { /* yes, try all lowercase form */ pw = getpwnam (s = lcase (cpystr (user))); fs_give ((void **) &s); } } return pw;}/* Validate password for user name * Accepts: user name string * password string * argument count * argument vector * Returns: password entry if validated * * Tries password+1 if password fails and starts with space */static struct passwd *valpwd (char *user,char *pwd,int argc,char *argv[]){ char *s; struct passwd *pw; struct passwd *ret = NIL; if (auth_md5.server) { /* using CRAM-MD5 authentication? */ if (s = auth_md5_pwd (user)) { if (!strcmp (s,pwd) || ((*pwd == ' ') && pwd[1] && !strcmp (s,pwd+1))) ret = pwuser (user); /* validated, get passwd entry for user */ memset (s,0,strlen (s)); /* erase sensitive information */ fs_give ((void **) &s); } } else if (pw = pwuser (user)) {/* can get user? */ s = cpystr (pw->pw_name); /* copy returned name in case we need it */ if (*pwd && !(ret = checkpw (pw,pwd,argc,argv)) && (*pwd == ' ') && pwd[1] && (ret = pwuser (s))) ret = checkpw (pw,pwd+1,argc,argv); fs_give ((void **) &s); /* don't need copy of name any more */ } return ret;}/* Server log in * Accepts: user name string * password string * authenticating user name string * argument count * argument vector * Returns: T if password validated, NIL otherwise */long server_login (char *user,char *pwd,char *authuser,int argc,char *argv[]){ struct passwd *pw = NIL; int level = LOG_NOTICE; char *err = "failed"; /* cretins still haven't given up */ if ((strlen (user) >= NETMAXUSER) || (authuser && (strlen (authuser) >= NETMAXUSER))) { level = LOG_ALERT; /* escalate this alert */ err = "SYSTEM BREAK-IN ATTEMPT"; logtry = 0; /* render this session useless */ } else if (logtry-- <= 0) err = "excessive login failures"; else if (disablePlaintext) err = "disabled"; else if (!(authuser && *authuser)) pw = valpwd (user,pwd,argc,argv); else if (valpwd (authuser,pwd,argc,argv)) pw = pwuser (user); if (pw && pw_login (pw,authuser,pw->pw_name,NIL,argc,argv)) return T; syslog (level|LOG_AUTH,"Login %s user=%.64s auth=%.64s host=%.80s",err, user,(authuser && *authuser) ? authuser : user,tcp_clienthost ()); sleep (3); /* slow down possible cracker */ return NIL;}/* Authenticated server log in * Accepts: user name string * authenticating user name string * argument count * argument vector * Returns: T if password validated, NIL otherwise */long authserver_login (char *user,char *authuser,int argc,char *argv[]){ return pw_login (pwuser (user),authuser,user,NIL,argc,argv);}/* Log in as anonymous daemon * Accepts: argument count * argument vector * Returns: T if successful, NIL if error */long anonymous_login (int argc,char *argv[]){ /* log in Mr. A. N. Onymous */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?