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 + -
显示快捷键?