📄 env_unix.c
字号:
long port; struct servent *sv; struct sockaddr_in sin; int i = sizeof (struct sockaddr_in); /* Don't use tcp_clienthost() since reverse DNS problems may slow down the * greeting message and cause the client to time out. */ char *client = getpeername (0,(struct sockaddr *) &sin,(void *) &i) ? "UNKNOWN" : inet_ntoa (sin.sin_addr); switch (i = 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 (i); /* so change it back */ } /* set server name in syslog */ if (server) openlog (server,LOG_PID,LOG_MAIL); if (service && altservice && ((port = tcp_serverport ()) >= 0)) { if ((sv = getservbyname (service,"tcp")) && (port == ntohs (sv->s_port))) syslog (LOG_DEBUG,"%s service init from %s",service,client); else if ((sv = getservbyname (altservice,"tcp")) && (port == ntohs (sv->s_port))) syslog (LOG_DEBUG,"%s alternative service init from %s", altservice,client); else syslog (LOG_DEBUG,"port %ld service init from %s",port,client); } /* set SASL name */ if (sasl) mail_parameters (NIL,SET_SERVICENAME,(void *) sasl); 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 (SIGTERM,trmint); /* prepare for termination */}/* 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;}/* 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[]){ char *s,usr[MAILTMPLEN],ausr[MAILTMPLEN]; struct passwd *pw; struct passwd *logpw = NIL; /* cretins still haven't given up */ if ((strlen (user) >= MAILTMPLEN) || (authuser && (strlen (authuser) >= MAILTMPLEN))) { syslog (LOG_ALERT|LOG_AUTH,"SYSTEM BREAK-IN ATTEMPT, host=%.80s", tcp_clienthost ()); logtry = 0; /* render this session useless */ } else { strcpy (usr,user); /* make writeable copy of user */ if (auth_md5.server) { /* using CRAM-MD5 authentication? */ /* make sure user exists */ if ((pw = getpwnam (usr)) || (pw = getpwnam (lcase (usr)))) { /* default authentication identity */ if (!(authuser && *authuser)) s = auth_md5_pwd (strcpy (ausr,pw->pw_name)); /* otherwise use given authentication id */ else if (!(s = auth_md5_pwd (strcpy (ausr,authuser)))) s = auth_md5_pwd (lcase (ausr)); if (s) { /* have a CRAM-MD5 password? */ if (!strcmp (s,pwd) && strcmp (s,pwd+1)) logpw = pw; /* erase sensitive information */ memset (s,0,strlen (s)); fs_give ((void **) &s); } else syslog (LOG_NOTICE|LOG_AUTH, "Login %s failed: %s has no CRAM-MD5 password host=%.80s", usr,ausr,tcp_clienthost ()); } } /* ordinary password authentication */ else if ((authuser && *authuser) ? (((pw = getpwnam (strcpy (ausr,authuser))) || (pw = getpwnam (lcase (ausr)))) && (checkpw (pw,pwd,argc,argv) || ((*pwd == ' ') && checkpw (getpwnam (ausr),pwd+1,argc,argv))) && ((pw = getpwnam (strcpy (usr,user))) || (pw = getpwnam (lcase (usr))))) : (((pw = getpwnam (strcpy (ausr,user))) || (pw = getpwnam (lcase (ausr)))) && ((pw = checkpw (pw,pwd,argc,argv)) || ((*pwd == ' ') && (pw = checkpw (getpwnam(ausr),pwd+1,argc,argv)))))) logpw = pw; if (logtry <= 0) /* excessive login failures */ syslog (LOG_NOTICE|LOG_AUTH, "Login attempt after lockout user=%.80s host=%.80s", user,tcp_clienthost ()); else if (!logpw) /* login failed */ syslog (LOG_NOTICE|LOG_AUTH,"%s user=%.80s host=%.80s", (logtry-- > 0) ? "Login failure" : "Excessive login attempts", user,tcp_clienthost ());#ifndef PLAINTEXT_DISABLED /* validate with authentication ID */ else if (pw_login (pw,ausr,pw->pw_name,pw->pw_dir,argc,argv)) return T;#endif } 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[]){ struct passwd *pw = getpwnam (user); return pw ? pw_login (pw,authuser,pw->pw_name,pw->pw_dir,argc,argv) : NIL;}/* Log in as anonymous daemon * Accepts: argument count * argument vector * Returns: T if successful, NIL if error */long anonymous_login (int argc,char *argv[]){ struct passwd *pw = getpwnam ((char *) anonymous_user); /* log in Mr. A. N. Onymous */ return pw ? pw_login (pw,NIL,NIL,NIL,argc,argv) : NIL;}/* Finish log in and environment initialization * Accepts: passwd struct for loginpw() * authentication user name * user name (NIL for anonymous) * home directory (NIL for anonymous) * argument count * argument vector * Returns: T if successful, NIL if error */long pw_login (struct passwd *pw,char *authuser,char *user,char *home,int argc, char *argv[]){ long ret = NIL; /* OK if matches authorization ID */ if (authuser && strcmp (authuser,pw->pw_name)) { struct group *gr = getgrnam ((char *) admin_grp); char **t; /* scan list of mail administrators */ for (t = gr ? gr->gr_mem : NIL; t; t++) if (!strcmp (authuser,*t)) { syslog (LOG_NOTICE|LOG_AUTH,"Admin %s override of user=%s host=%.80s", authuser,pw->pw_name,tcp_clienthost ()); return pw_login (pw,NIL,user,home,argc,argv); } syslog (LOG_NOTICE|LOG_AUTH, "Login %s failed: invalid authentication ID %s host=%.80s", pw->pw_name,authuser,tcp_clienthost ()); } else if (!pw->pw_uid); /* disallow UID 0 */ /* if same as EUID, treat as application */ else if (pw->pw_uid == geteuid ()) ret = env_init (user,home); else { /* in case loginpw() smashes these */ char *u = user ? cpystr (user) : NIL; char *h = home ? cpystr (home) : NIL;#ifdef CHROOT_SERVER /* paranoid site, lock out other directories */ if (chdir (home ? home : ANONYMOUSHOME) || chroot (home ? home : ANONYMOUSHOME)) return NIL; home = "/"; /* home directory now root */ closedBox = T; /* flag that this is a closed box */#endif /* log the user in */ if (loginpw (pw,argc,argv)) ret = env_init (u,h); if (h) fs_give ((void **) &h); if (u) fs_give ((void **) &u); } if (ret) chdir (myhomedir ());/* make sure at home directory */ return ret; /* return status */}/* Initialize environment * Accepts: user name * home directory name * Returns: T, always */long env_init (char *user,char *home){ extern MAILSTREAM CREATEPROTO; extern MAILSTREAM EMPTYPROTO; struct passwd *pw; struct stat sbuf; char tmp[MAILTMPLEN]; if (myUserName) fatal ("env_init called twice!"); /* myUserName must be set before dorc() call */ myUserName = cpystr (user ? user : (char *) anonymous_user); if (closedBox) { /* closed box server */ /* standard user can only reference home */ if (user) nslist[0] = &nshome; else { /* anonymous user */ nslist[0] = &nsblackother; /* set root */ anonymous = T; /* flag as anonymous */ } nslist[1] = nslist[2] = NIL;/* can't reference anything else */ /* make sure user rc files don't try these */ blackBoxDir = blackBoxDefaultHome = anonymousHome = ""; sysInbox = cpystr ("INBOX");/* make system INBOX */ } else { /* open or black box */ /* do systemwide configuration */ dorc ("/etc/c-client.cf",NIL); if (!anonymousHome) anonymousHome = cpystr (ANONYMOUSHOME); if (user) { /* remember user name and home directory */ if (blackBoxDir) { /* build black box directory name */ sprintf (tmp,"%s/%s",blackBoxDir,myUserName); /* if black box if exists and directory */ if (home = (!stat (tmp,&sbuf) && (sbuf.st_mode & S_IFDIR)) ? tmp : blackBoxDefaultHome) { sysInbox = (char *) fs_get (strlen (home) + 7); /* set system INBOX */ sprintf (sysInbox,"%s/INBOX",home); blackBox = T; /* mark that it's a black box */ /* mbox meaningless if black box */ mail_parameters (NIL,DISABLE_DRIVER,(void *) "mbox"); } } if (blackBox) /* black box? */ nslist[0] = &nshome,nslist[1] = &nsblackother,nslist[2] = &nsshared; else { /* not a black box */ nslist[0] = &nshome; /* home directory */ /* other users */ nslist[1] = &nsunixother;#ifdef ADVERTISE_THE_WORLD nslist[2] = &nsworld; /* you probably don't want to do this! */#else nslist[2] = &nsshared; /* what, me paranoid? */#endif /* make sure user rc files don't try this */ blackBoxDir = blackBoxDefaultHome = ""; } } else { /* anonymous user */ nslist[0] = nslist[1] = NIL,nslist[2] = &nsftp; sprintf (tmp,"%s/INBOX",home = anonymousHome); sysInbox = cpystr (tmp); /* make system INBOX */ anonymous = T; /* flag as anonymous */ /* make sure an error message happens */ if (!blackBoxDir) blackBoxDir = blackBoxDefaultHome = anonymousHome; } } /* use real home directory */ myHomeDir = cpystr (home ? home : ANONYMOUSHOME); dorc (strcat (strcpy (tmp,myHomeDir),"/.mminit"),T); dorc (strcat (strcpy (tmp,myHomeDir),"/.imaprc"),NIL); if (!closedBox) { /* can't do this on closed server */ /* #ftp namespace */ if (!ftpHome && (pw = getpwnam ("ftp"))) ftpHome = cpystr (pw->pw_dir); /* #public namespace */ if (!publicHome && (pw = getpwnam ("imappublic"))) publicHome = cpystr (pw->pw_dir); /* #shared namespace */ if (!anonymous && !sharedHome && (pw = getpwnam ("imapshared"))) sharedHome = cpystr (pw->pw_dir); } if (!myLocalHost) mylocalhost (); if (!myNewsrc) myNewsrc = cpystr(strcat (strcpy (tmp,myHomeDir),"/.newsrc")); if (!newsActive) newsActive = cpystr (ACTIVEFILE); if (!newsSpool) newsSpool = cpystr (NEWSSPOOL); /* force default prototype to be set */ if (!createProto) createProto = &CREATEPROTO; if (!appendProto) appendProto = &EMPTYPROTO; /* re-do open action to get flags */ (*createProto->dtb->open) (NIL); endpwent (); /* close pw database */ return T;} /* Return my user name * Accepts: pointer to optional flags * Returns: my user name */char *myusername_full (unsigned long *flags){ char *ret = (char *) unlogged_user; if (!myUserName) { /* get user name if don't have it yet */ struct passwd *pw; struct stat sbuf; unsigned long euid = geteuid (); char *s = (char *) (euid ? getlogin () : NIL); /* look up getlogin() user name or EUID */ if (!((s && *s && (strlen (s) < NETMAXUSER) && (pw = getpwnam (s)) && (pw->pw_uid == euid)) || (pw = getpwuid (euid)))) fatal ("Unable to look up user name"); /* init environment if not root */ if (euid) env_init (pw->pw_name,((s = getenv ("HOME")) && *s && (strlen (s) < NETMAXMBX) && !stat (s,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFDIR)) ? s : pw->pw_dir); else ret = pw->pw_name; /* in case UID 0 user is other than root */ } if (myUserName) { /* logged in? */ if (flags) *flags = anonymous ? MU_ANONYMOUS : MU_LOGGEDIN; ret = myUserName; /* return user name */ } else if (flags) *flags = MU_NOTLOGGEDIN; return ret;}/* Return my local host name * Returns: my local host name */char *mylocalhost (){ char tmp[MAILTMPLEN]; struct hostent *host_name; if (!myLocalHost) { gethostname(tmp,MAILTMPLEN);/* get local host name */ myLocalHost = cpystr ((host_name = gethostbyname (tmp)) ? host_name->h_name : tmp); } return myLocalHost;}/* Return my home directory name * Returns: my home directory name */char *myhomedir ()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -