📄 env_ami.c
字号:
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 Amiga 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 && !isupper (*s); 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 */ return pw_login (getpwnam (ANONYMOUSUSER),NIL,NIL, (char *) mail_parameters (NIL,GET_ANONYMOUSHOME,NIL), argc,argv);}/* Finish log in and environment initialization * Accepts: passwd struct for loginpw() * optional authentication user name * user name (NIL for anonymous) * home directory (NIL to use directory from passwd struct) * argument count * argument vector * Returns: T if successful, NIL if error */long pw_login (struct passwd *pw,char *auser,char *user,char *home,int argc, char *argv[]){ struct group *gr; char **t; long ret = NIL; if (pw && pw->pw_uid) { /* must have passwd struct for non-UID 0 */ /* make safe copies of user and home */ if (user) user = cpystr (pw->pw_name); home = cpystr (home ? home : pw->pw_dir); /* authorization ID .NE. authentication ID? */ if (user && auser && *auser && compare_cstring (auser,user)) { /* scan list of mail administrators */ if ((gr = getgrnam (ADMINGROUP)) && (t = gr->gr_mem)) while (*t && !ret) if (!compare_cstring (auser,*t++)) ret = pw_login (pw,NIL,user,home,argc,argv); syslog (LOG_NOTICE|LOG_AUTH,"%s %.80s override of user=%.80s host=%.80s", ret ? "Admin" : "Failed",auser,user,tcp_clienthost ()); } /* normal login */ else if (((pw->pw_uid == geteuid ()) || loginpw (pw,argc,argv)) && (ret = env_init (user,home))) chdir (myhomedir ()); fs_give ((void **) &home); /* clean up */ if (user) fs_give ((void **) &user); } return ret; /* return status */}/* Initialize environment * Accepts: user name (NIL for anonymous) * 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!"); /* set up user name */ myUserName = cpystr (user ? user : ANONYMOUSUSER); if (user) { /* remember user name and home directory */ nslist[0] = &nshome; /* home namespace */ nslist[1] = &nsamigaother; nslist[2] = advertisetheworld ? &nsworld : &nsshared; } else { /* anonymous user */ nslist[0] = nslist[1] = NIL,nslist[2] = &nsftp; sprintf (tmp,"%s/INBOX", home = (char *) mail_parameters (NIL,GET_ANONYMOUSHOME,NIL)); sysInbox = cpystr (tmp); /* make system INBOX */ anonymous = T; /* flag as anonymous */ } myHomeDir = cpystr (home); /* set home directory */ if (!noautomaticsharedns) { /* #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 = UNLOGGEDUSER; 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 (){ if (!myHomeDir) myusername ();/* initialize if first time */ return myHomeDir ? myHomeDir : "";}/* Return my home mailbox name * Returns: my home directory name */static char *mymailboxdir (){ char *home = myhomedir (); if (!myMailboxDir && home) { /* initialize if first time */ if (mailsubdir) { char tmp[MAILTMPLEN]; sprintf (tmp,"%s/%s",home,mailsubdir); myMailboxDir = cpystr (tmp);/* use pre-defined subdirectory of home */ } else myMailboxDir = cpystr (home); } 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 *s; if (!name || !*name || (*name == '{') || (strlen (name) > NETMAXMBX) || ((anonymous || restrictBox || (*name == '#')) && (strstr (name,"..") || strstr (name,"//") || strstr (name,"/~")))) dst = NIL; /* invalid name */ else switch (*name) { /* determine mailbox type based upon name */ case '#': /* namespace name */ /* #ftp/ namespace */ if (((name[1] == 'f') || (name[1] == 'F')) && ((name[2] == 't') || (name[2] == 'T')) && ((name[3] == 'p') || (name[3] == 'P')) && (name[4] == '/') && ftpHome) sprintf (dst,"%s/%s",ftpHome,name+5); /* #public/ and #shared/ namespaces */ 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] == '/') && (s = publicHome)) || (!anonymous && ((name[1] == 's') || (name[1] == 'S')) && ((name[2] == 'h') || (name[2] == 'H')) && ((name[3] == 'a') || (name[3] == 'A')) && ((name[4] == 'r') || (name[4] == 'R')) && ((name[5] == 'e') || (name[5] == 'E')) && ((name[6] == 'd') || (name[6] == 'D')) && (name[7] == '/') && (s = sharedHome))) sprintf (dst,"%s/%s",s,compare_cstring (name,"INBOX") ? name : "INBOX"); else dst = NIL; /* unknown namespace */ break; case '/': /* root access */ if (anonymous) dst = NIL; /* anonymous forbidden to do this */ else if ((restrictBox & RESTRICTROOT) && strcmp (name,sysinbox ())) dst = NIL; /* restricted and not access to sysinbox */ else strcpy (dst,name); /* unrestricted, copy root name */ break; case '~': /* other user access */ /* bad syntax or anonymous can't win */ if (!*++name || anonymous) dst = NIL; /* ~/ equivalent to ordinary name */ else if (*name == '/') sprintf (dst,"%s/%s",mymailboxdir (),name+1); /* other user forbidden if restricted */ else if (restrictBox & RESTRICTOTHERUSER) dst = NIL; else { /* clear box other user */ /* copy user name */ for (s = dst; *name && (*name != '/'); *s++ = *name++); *s++ = '\0'; /* tie off user name, look up in passwd file */ if ((pw = getpwnam (dst)) && pw->pw_dir) { if (*name) name++; /* skip past the slash */ /* canonicalize case of INBOX */ if (!compare_cstring (name,"INBOX")) name = "INBOX"; /* remove trailing / from directory */ if ((s = strrchr (pw->pw_dir,'/')) && !s[1]) *s = '\0'; /* don't allow ~root/ if restricted root */ if ((restrictBox & RESTRICTROOT) && !*pw->pw_dir) dst = NIL; /* build final name w/ subdir if needed */ else if (mailsubdir) sprintf (dst,"%s/%s/%s",pw->pw_dir,mailsubdir,name); else sprintf (dst,"%s/%s",pw->pw_dir,name); } else dst = NIL; /* no such user */ } break; case 'I': case 'i': /* possible INBOX */ if (!compare_cstring (name+1,"NBOX")) { /* if anonymous, use INBOX in mailbox dir */ if (anonymous) sprintf (dst,"%s/INBOX",mymailboxdir ()); else *dst = '\0'; /* otherwise driver selects the name */ break; } /* drop into to ordinary name case */ default: /* ordinary name is easy */ sprintf (dst,"%s/%s",mymailboxdir (),name); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -