📄 env_unix.c
字号:
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 ()); } else if (closedBox) { /* paranoid site, lock out other directories */ if (chdir (home) || chroot (home)) syslog (LOG_NOTICE|LOG_AUTH, "Login %s failed: unable to set chroot=%.80s host=%.80s", pw->pw_name,home,tcp_clienthost ()); else if (loginpw (pw,argc,argv)) ret = env_init (user,NIL); else fatal ("Login failed after chroot"); } /* 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); } endpwent (); /* in case shadow passwords in pw data */ 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]; /* don't init if blocked */ if (block_env_init) return LONGT; if (myUserName) fatal ("env_init called twice!"); /* initially nothing in namespace list */ nslist[0] = nslist[1] = nslist[2] = NIL; /* myUserName must be set before dorc() call */ myUserName = cpystr (user ? user : ANONYMOUSUSER); /* force default prototypes to be set */ if (!createProto) createProto = &CREATEPROTO; if (!appendProto) appendProto = &EMPTYPROTO; dorc (NIL,NIL); /* do systemwide configuration */ if (!home) { /* 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 */ } myHomeDir = cpystr (""); /* home directory is root */ sysInbox = cpystr ("INBOX");/* make system INBOX */ } else { /* open or black box */ closedBox = NIL; /* definitely not a closed box */ if (user) { /* remember user name and home directory */ if (blackBoxDir) { /* build black box directory name */ sprintf (tmp,"%s/%s",blackBoxDir,myUserName); /* must exist */ if (!((!stat (home = tmp,&sbuf) && (sbuf.st_mode & S_IFDIR)) || (blackBoxDefaultHome && !stat (home = blackBoxDefaultHome,&sbuf) && (sbuf.st_mode & S_IFDIR)))) fatal ("no home"); 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"); } nslist[0] = &nshome; /* home namespace */ /* limited advertise namespaces */ if (limitedadvertise) nslist[2] = &nslimited; else if (blackBox) { /* black box namespaces */ nslist[1] = &nsblackother; nslist[2] = &nsshared; } else { /* open box namespaces */ nslist[1] = &nsunixother; nslist[2] = advertisetheworld ? &nsworld : &nsshared; } } else { nslist[2] = &nsftp; /* anonymous user */ 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 (allowuserconfig) { /* allow user config files */ dorc (strcat (strcpy (tmp,myHomeDir),"/.mminit"),T); dorc (strcat (strcpy (tmp,myHomeDir),"/.imaprc"),NIL); } if (!closedBox && !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); /* 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){ struct passwd *pw; struct stat sbuf; char *s; unsigned long euid; char *ret = UNLOGGEDUSER; /* no user name yet and not root? */ if (!myUserName && (euid = geteuid ())) { /* yes, look up getlogin() user name or EUID */ if (((s = (char *) getlogin ()) && *s && (strlen (s) < NETMAXUSER) && (pw = getpwnam (s)) && (pw->pw_uid == euid)) || (pw = getpwuid (euid))) { if (block_env_init) { /* don't env_init if blocked */ if (flags) *flags = MU_LOGGEDIN; return pw->pw_name; } 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 fatal ("Unable to look up user name"); } 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 (){ if (!myLocalHost) { char *s,tmp[MAILTMPLEN]; char *t = "unknown"; tmp[0] = tmp[MAILTMPLEN-1] = '\0'; if (!gethostname (tmp,MAILTMPLEN-1) && tmp[0]) { /* sanity check of name */ for (s = tmp; (*s > 0x20) && (*s < 0x7f); ++s); if (!*s) t = tcp_canonical (tmp); } myLocalHost = cpystr (t); } 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 (); /* initialize if first time */ if (!myMailboxDir && myHomeDir) { 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 || blackBox || 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+8,"INBOX") ? name+8 : "INBOX"); else dst = NIL; /* unknown namespace */ break; case '/': /* root access */ if (anonymous) dst = NIL; /* anonymous forbidden to do this */ else if (blackBox) { /* other user access if blackbox */ if (restrictBox & RESTRICTOTHERUSER) dst = NIL; /* see if other user INBOX */ else if ((s = strchr (name+1,'/')) && !compare_cstring (s+1,"INBOX")) { *s = '\0'; /* temporarily tie off string */ sprintf (dst,"%s/%s/INBOX",blackBoxDir,name+1); *s = '/'; /* in case caller cares */ } else sprintf (dst,"%s/%s",blackBoxDir,name+1); } 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 closed/restricted */ else if (closedBox || (restrictBox & RESTRICTOTHERUSER)) dst = NIL; else if (blackBox) { /* black box form of other user */ /* see if other user INBOX */ if ((s = strchr (name,'/')) && compare_cstring (s+1,"INBOX")) { *s = '\0'; /* temporarily tie off string */ sprintf (dst,"%s/%s/INBOX",blackBoxDir,name); *s = '/'; /* in case caller cares */ } else sprintf (dst,"%s/%s",blackBoxDir,name); } 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -