📄 env_ami.c
字号:
* 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) syslog (LOG_NOTICE|LOG_AUTH, "Login attempt after lockout user=%.80s host=%.80s", user,tcp_clienthost ());#ifndef PLAINTEXT_DISABLED else if (logpw) { /* have logpw, validate authentication ID */ if (pw_login (pw,ausr,pw->pw_name,pw->pw_dir,argc,argv)) return T; }#endif else syslog (LOG_NOTICE|LOG_AUTH,"%s user=%.80s host=%.80s", (logtry-- > 0) ? "Login failure" : "Excessive login attempts", 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[]){ 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,ANONYMOUSHOME,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 *s,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 */ anonymousHome = ""; /* make sure user rc files don't try these */ 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 */ nslist[0] = &nshome; /* home directory */ /* other users */ nslist[1] = &nsamigaother;#ifdef ADVERTISE_THE_WORLD nslist[2] = &nsworld; /* you probably don't want to do this! */#else nslist[2] = &nsshared; /* what, me paranoid? */#endif } 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 */ } } myHomeDir = cpystr (home); /* use real home directory */ 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; 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 (){ if (!myHomeDir) myusername ();/* initialize if first time */ return myHomeDir ? myHomeDir : "";}/* Return my home mailbox name * Returns: my home directory name */static char *mymailboxdir (){ /* initialize if first time */#ifdef MAILSUBDIR if (!myMailboxDir) { char tmp[MAILTMPLEN]; sprintf (tmp,"%s/%s",myhomedir (),MAILSUBDIR); myHomeDir = cpystr (tmp); /* use pre-defined subdirectory of home */ }#else if (!myMailboxDir && myHomeDir) myMailboxDir = cpystr (myhomedir ());#endif return myMailboxDir ? myMailboxDir : "";}/* Return system standard INBOX * Accepts: buffer string */char *sysinbox (){ char tmp[MAILTMPLEN]; if (!sysInbox) { /* initialize if first time */ sprintf (tmp,"%s/%s",MAILSPOOL,myusername ()); sysInbox = cpystr (tmp); /* system inbox is from mail spool */ } return sysInbox;}/* Return mailbox directory name * Accepts: destination buffer * directory prefix * name in directory * Returns: file name or NIL if error */char *mailboxdir (char *dst,char *dir,char *name){ char tmp[MAILTMPLEN]; if (dir || name) { /* if either argument provided */ if (dir) { if (strlen (dir) > NETMAXMBX) return NIL; strcpy (tmp,dir); /* write directory prefix */ } else tmp[0] = '\0'; /* otherwise null string */ if (name) { if (strlen (name) > NETMAXMBX) return NIL; strcat (tmp,name); /* write name in directory */ } /* validate name, return its name */ if (!mailboxfile (dst,tmp)) return NIL; } /* no arguments, wants mailbox directory */ else strcpy (dst,mymailboxdir ()); return dst; /* return the name */}/* Return mailbox file name * Accepts: destination buffer * mailbox name * Returns: file name or empty string for driver-selected INBOX or NIL if error */char *mailboxfile (char *dst,char *name){ struct passwd *pw; char *dir = mymailboxdir (); *dst = '\0'; /* default to empty string */ /* check invalid name */ if (!name || !*name || (*name == '{') || (strlen (name) > NETMAXMBX)) return NIL; /* check for INBOX */ if (((name[0] == 'I') || (name[0] == 'i')) && ((name[1] == 'N') || (name[1] == 'n')) && ((name[2] == 'B') || (name[2] == 'b')) && ((name[3] == 'O') || (name[3] == 'o')) && ((name[4] == 'X') || (name[4] == 'x')) && !name[5]) { /* if restricted, canonicalize name of INBOX */ if (anonymous || closedBox) name = "INBOX"; else return dst; /* else driver selects the INBOX name */ } /* restricted name? */ else if ((*name == '#') || anonymous) { if (strstr (name,"..") || strstr (name,"//") || strstr (name,"/~")) return NIL; /* none of these allowed when restricted */ switch (*name) { /* what kind of restricted name? */ case '#': /* namespace name */ if (((name[1] == 'f') || (name[1] == 'F')) && ((name[2] == 't') || (name[2] == 'T')) && ((name[3] == 'p') || (name[3] == 'P')) && (name[4] == '/') && (dir = ftpHome)) name += 5; else if (((name[1] == 'p') || (name[1] == 'P')) && ((name[2] == 'u') || (name[2] == 'U')) && ((name[3] == 'b') || (name[3] == 'B')) && ((name[4] == 'l') || (name[4] == 'L')) && ((name[5] == 'i') || (name[5] == 'I')) && ((name[6] == 'c') || (name[6] == 'C')) && (name[7] == '/') && (dir = publicHome)) name += 8; else if (!anonymous && ((name[1] == 's') || (name[1] == 'S')) && ((name[2] == 'h') || (name[2] == 'H')) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -