gww@aphasia.UUCP (George Williams) (09/17/85)
We are running bsd4.2 on a vax 750. Every now and then after I have been logged in for a while I will try to su, have su ask the password, and then it sits for a bit and exits. It does not generate any error messages, the exit status is 0. After this has happened it will keep happening until I log out, I have always been able to su immediately after logging in. Anyone else had this? Anyone know why? George Williams decvax!frog!aphasia!gww One day I shall burst my bud Of calm, and blossom into hysteria.
dave@uwvax.UUCP (Dave Cohrs) (09/21/85)
> Every now and then after I have been logged in for a while I will try to > su, have su ask the password, and then it sits for a bit and exits. It > does not generate any error messages, the exit status is 0. After this > has happened it will keep happening until I log out, I have always been > able to su immediately after logging in. You didn't say to whom you were su'ing. However, if you were becoming root, this behaviour doesn't make sense. If you were becoming another normal user, this probably means the current directory was inaccesable to the new user. In this case, su gives up quietly. I think this is a case there things could be a bit more verbose. -- Dave Cohrs (608) 262-1204 ...!{harvard,ihnp4,seismo,topaz}!uwvax!dave dave@wisc-romano.arpa
pdg@ihdev.UUCP (P. D. Guthrie) (09/21/85)
In article <314@aphasia.UUCP> gww@aphasia.UUCP (George Williams) writes: >We are running bsd4.2 on a vax 750. > >Every now and then after I have been logged in for a while I will try to >su, have su ask the password, and then it sits for a bit and exits. It >does not generate any error messages, the exit status is 0. After this >has happened it will keep happening until I log out, I have always been >able to su immediately after logging in. > >Anyone else had this? Anyone know why? > > George Williams > decvax!frog!aphasia!gww I had this happen almost all the time on a 4.1 system. However it only happened when I su'd to a non-root user. Curiouser and curiouser.... I never did try to track it down, but I would be interested to know what it was. Anyone? Paul Guthrie ihnp4!ihdev!pdg
root@bu-cs.UUCP (Barry Shein) (09/22/85)
>From: gww@aphasia.UUCP (George Williams) >We are running bsd4.2 on a vax 750. > >Every now and then after I have been logged in for a while I will try to >su, have su ask the password, and then it sits for a bit and exits. It >does not generate any error messages, the exit status is 0. After this >has happened it will keep happening until I log out, I have always been >able to su immediately after logging in. > >Anyone else had this? Anyone know why? YES, I thought *I* was crazy. If anyone has the fix please post, meanwhile I'll take a look myself. I wondered why no one else ever had mentioned this. -Barry Shein, Boston University
chris@umcp-cs.UUCP (Chris Torek) (09/22/85)
> You didn't say to whom you were su'ing. ... If you were becoming > another normal user, this probably means the current directory was > inaccesable to the new user. In this case, su gives up quietly. 'Tis not su, 'tis csh, the vile wretched beast. One of the first things it does is figure out its current directory; if it cannot, it exits. Gosling Emacs also used to have this cretinous behaviour. I changed it to attempt a getwd, and if that failed, to try first a chdir($HOME) and finally a chdir(/), warning you along the way that it was unable to figure out where you were and so (rather than quit or come up confused) put you elsewhere. This is perhaps not much better, but *some* solution was necessary. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
root@bu-cs.UUCP (Barry Shein) (09/22/85)
From: dave@uwvax.UUCP (Dave Cohrs) >> Every now and then after I have been logged in for a while I will try to >> su, have su ask the password, and then it sits for a bit and exits. It >> does not generate any error messages, the exit status is 0. After this >> has happened it will keep happening until I log out, I have always been >> able to su immediately after logging in. > >You didn't say to whom you were su'ing. However, if you were becoming >root, this behaviour doesn't make sense. If you were becoming another >normal user, this probably means the current directory was inaccesable >to the new user. In this case, su gives up quietly. I think this is >a case there things could be a bit more verbose. You better explain which version of UNIX you believe this happens (su exits silently if '.' is not accessible.) I just tried it under 4.2bsd (vax), SYSVR2 (3b5) and SYSVR(1?) (PC7300) and all let me su to a non-priv'd user while in a directory they had no access to, of course: % ls . not found % was the amusing side effect, but that is not what you said (and that is a non-fatal and correct side-effect and has nothing to do with su.) -Barry Shein, Boston University
gamiddleton@thunder.UUCP (Guy Middleton) (09/23/85)
In article <664@bu-cs.UUCP> root@bu-cs.UUCP (Barry Shein) writes: >>From: gww@aphasia.UUCP (George Williams) > >>We are running bsd4.2 on a vax 750. >> >>Every now and then after I have been logged in for a while I will try to >>su, have su ask the password, and then it sits for a bit and exits. It >>does not generate any error messages, the exit status is 0. After this >>has happened it will keep happening until I log out, I have always been >>able to su immediately after logging in. >> >>Anyone else had this? Anyone know why? > >YES, I thought *I* was crazy. If anyone has the fix please post, meanwhile >I'll take a look myself. I wondered why no one else ever had mentioned this. > > -Barry Shein, Boston University Well, if you're using csh, then that may be your problem. If csh can't stat the parent of the directory it starts up in, it dies quietly. Or at least it used to; we have a different version here. -- Guy Middleton, Lakehead University, Thunder Bay, Ont. ..{allegra,clyde,decvax,utcsrgv}!watmath!thunder!gamiddleton ..ihnp4!mmm!thunder!gamiddleton
friesen@psivax.UUCP (Stanley Friesen) (09/23/85)
In article <314@aphasia.UUCP> gww@aphasia.UUCP (George Williams) writes: >We are running bsd4.2 on a vax 750. > >Every now and then after I have been logged in for a while I will try to >su, have su ask the password, and then it sits for a bit and exits. It >does not generate any error messages, the exit status is 0. After this >has happened it will keep happening until I log out, I have always been >able to su immediately after logging in. > Well, since at least two people have asked, I will make this a Followup instead of a Reply. I too have had this problem, and it seems to occur when the user specified to 'su' does not have r and x permissions to all directories between / and the current working directory. All you need to do to get around it is to cd to a directory with general r & x permissions with the same permissions for all parent directories. (Apparently the problem is that the *shell* will exit if it cannot access the current directory, & since su thinks it has executed the shell correctly it gives no error message.) P.S this also explains why this never happens when you su to root, since root has universal access. -- Sarima (Stanley Friesen) UUCP: {ttidca|ihnp4|sdcrdcf|quad1|nrcvax|bellcore|logico}!psivax!friesen ARPA: ttidca!psivax!friesen@rand-unix.arpa
mcooper@oberon.UUCP (Michael Cooper) (09/24/85)
In article <319@ihdev.UUCP> pdg@ihdev.UUCP (55224-P. D. Guthrie) writes: >In article <314@aphasia.UUCP> gww@aphasia.UUCP (George Williams) writes: >>We are running bsd4.2 on a vax 750. >> >>Every now and then after I have been logged in for a while I will try to >>su, have su ask the password, and then it sits for a bit and exits. It >>does not generate any error messages, the exit status is 0. After this >>has happened it will keep happening until I log out, I have always been >>able to su immediately after logging in. >> >>Anyone else had this? Anyone know why? >> >> George Williams >> decvax!frog!aphasia!gww > >I had this happen almost all the time on a 4.1 system. However it only >happened when I su'd to a non-root user. Curiouser and curiouser.... >I never did try to track it down, but I would be interested to know >what it was. Anyone? > > Paul Guthrie > ihnp4!ihdev!pdg If you are in a directory that is inaccessable to the user you are su'ing into, then the shell exits. -- Michael Cooper +----------------------------------------------------------------------------+ |University of Southern California - University Computing Services | |============================================================================| | Usenet: ...!{uscvax, sdcrdcf, engvax, scgvaxd, smeagol, | | cit-vax, brand, dworkin, tyger, omnilax}!oberon!mcooper | | Bitnet: mcooper@jaxom | | ARPA: mcooper@usc-oberon.arpa OR mcooper%usc-oberon@usc-ecld.arpa | +----------------------------------------------------------------------------+
msc@saber.UUCP (Mark Callow) (09/24/85)
> > Every now and then after I have been logged in for a while I will try to > > su, have su ask the password, and then it sits for a bit and exits. It > > You didn't say to whom you were su'ing. However, if you were becoming > root, this behaviour doesn't make sense. If you were becoming another > normal user, this probably means the current directory was inaccesable > to the new user. In this case, su gives up quietly. I think this is > a case there things could be a bit more verbose. It's not su that gives up it's the C shell. Here's the story from the Mt Xinu bug list as reported by Ralph Campbell. _______________________________________________________________________________ csh--bin ralph (Ralph Campbell) 25 May 83 The C shell quits silently if the parent directory (or anything back to the root) isn't readable when it starts up (and if it isn't a login shell). This can happen when you su to someone who can't read your working directory; the su fails silently. Here's why: The Cshell's dinit() calls getwd() (defined in /usr/src/libc/libjobs/getwd.c), which notices the problem, writes an error message to file descriptor 2, and exits. However, file descriptor 2 is closed by initdesc() before getwd() acts. The whole thing is a mess because you're trying to be compatible with version 5 on up with respect to file descriptors, so I daren't suggest a fix. _______________________________________________________________________________ -- From the TARDIS of Mark Callow msc@saber.UUCP, sun!saber!msc@decwrl.ARPA ...{decwrl,ucbvax}!sun!saber!msc, ...{amdcad,ihnp4}!saber!msc
friesen@psivax.UUCP (Stanley Friesen) (09/25/85)
In article <667@bu-cs.UUCP> root@bu-cs.UUCP (Barry Shein) writes: >> If you were becoming another >>normal user, this probably means the current directory was inaccesable >>to the new user. In this case, su gives up quietly. I think this is >>a case there things could be a bit more verbose. >>>(Actually it is the shell which gives up) > >You better explain which version of UNIX you believe this happens >(su exits silently if '.' is not accessible.) > >I just tried it under 4.2bsd (vax), SYSVR2 (3b5) and SYSVR(1?) (PC7300) >and all let me su to a non-priv'd user while in a directory they had >no access to, of course: > Hmm, curiouser and curiouser. I have had it happen on both 4.1 and 4.2 BSD. And I know it is the directory access since doing a cd to a different directory always fixes it. Which *shell* were you using, I was using 'csh'. -- Sarima (Stanley Friesen) UUCP: {ttidca|ihnp4|sdcrdcf|quad1|nrcvax|bellcore|logico}!psivax!friesen ARPA: ttidca!psivax!friesen@rand-unix.arpa
prb@cray.UUCP (Paul Borman) (09/28/85)
No one is crazy. This is a bug. It can be fixed (without chdiring to / (which wont work on a system which has / as 711)). Solution: change sh.dir.c so that if you are not superuser it will call /bin/pwd to find your current working directory. make /bin/pwd suid to root. This is NOT a security problem. Enhancement: put your current working dir into a environ var called CWD and your inode/device into CWDINO. Then, when the csh starts up, it stats . and sees if CWDINO is right, if so, then just use CWD, else call pwd. Hell, I'll just put the sources in here.... The #ifdef SYSV is the stuff you have to add to make it work. I ported 4.2 csh to System V and fixed the bug (again) while I was doing it. The 3rd file is just along for the ride. -Paul R Borman Cray Research, Inc. ihnp4!cray!prb ----sh.dir.c---- static char *sccsid = "@(#)sh.dir.c 4.2 2/3/83"; #include "sh.h" #include "sh.dir.h" /* * C Shell - directory management */ struct directory *dfind(); char *dfollow(); struct directory dhead; /* "head" of loop */ int printd; /* force name to be printed */ static char *fakev[] = { "dirs", NOSTR }; /* * dinit - initialize current working directory */ dinit(hp) char *hp; { register char *cp; register struct directory *dp; char path[BUFSIZ]; if (loginsh && hp) cp = hp; else { #ifdef SYSV cp = getwd_up(path); #else cp = getwd(path); #endif if (cp == NULL) { write(2, path, strlen(path)); exit(1); } } dp = (struct directory *)calloc(sizeof (struct directory), 1); dp->di_name = savestr(cp); dp->di_count = 0; dhead.di_next = dhead.di_prev = dp; dp->di_next = dp->di_prev = &dhead; printd = 0; dnewcwd(dp); } /* * dodirs - list all directories in directory loop */ dodirs(v) char **v; { register struct directory *dp; bool lflag; char *hp = value("home"); if (*hp == '\0') hp = NOSTR; if (*++v != NOSTR) if (eq(*v, "-l") && *++v == NOSTR) lflag = 1; else error("Usage: dirs [ -l ]"); else lflag = 0; dp = dcwd; do { if (dp == &dhead) continue; if (!lflag && hp != NOSTR) { dtildepr(hp, dp->di_name); } else printf("%s", dp->di_name); printf(" "); } while ((dp = dp->di_prev) != dcwd); printf("\n"); } dtildepr(home, dir) register char *home, *dir; { if (!eq(home, "/") && prefix(home, dir)) printf("~%s", dir + strlen(home)); else printf("%s", dir); } /* * dochngd - implement chdir command. */ dochngd(v) char **v; { register char *cp; register struct directory *dp; printd = 0; if (*++v == NOSTR) { if ((cp = value("home")) == NOSTR || *cp == 0) bferr("No home directory"); if (chdir(cp) < 0) bferr("Can't change to home directory"); cp = savestr(cp); } else if ((dp = dfind(*v)) != 0) { printd = 1; if (chdir(dp->di_name) < 0) Perror(dp->di_name); dcwd->di_prev->di_next = dcwd->di_next; dcwd->di_next->di_prev = dcwd->di_prev; goto flushcwd; } else cp = dfollow(*v); dp = (struct directory *)calloc(sizeof (struct directory), 1); dp->di_name = cp; dp->di_count = 0; dp->di_next = dcwd->di_next; dp->di_prev = dcwd->di_prev; dp->di_prev->di_next = dp; dp->di_next->di_prev = dp; flushcwd: dfree(dcwd); dnewcwd(dp); } /* * dfollow - change to arg directory; fall back on cdpath if not valid */ char * dfollow(cp) register char *cp; { register char **cdp; struct varent *c; cp = globone(cp); if (chdir(cp) == 0) goto gotcha; if (cp[0] != '/' && !prefix("./", cp) && !prefix("../", cp) && (c = adrof("cdpath"))) { for (cdp = c->vec; *cdp; cdp++) { char buf[BUFSIZ]; strcpy(buf, *cdp); strcat(buf, "/"); strcat(buf, cp); if (chdir(buf) >= 0) { printd = 1; xfree(cp); cp = savestr(buf); goto gotcha; } } } if (adrof(cp)) { char *dp = value(cp); if (dp[0] == '/' || dp[0] == '.') if (chdir(dp) >= 0) { xfree(cp); cp = savestr(dp); printd = 1; goto gotcha; } } xfree(cp); Perror(cp); gotcha: if (*cp != '/') { char *dp = calloc(strlen(cp) + strlen(dcwd->di_name) + 2, 1); strcpy(dp, dcwd->di_name); strcat(dp, "/"); strcat(dp, cp); xfree(cp); cp = dp; } dcanon(cp); return (cp); } /* * dopushd - push new directory onto directory stack. * with no arguments exchange top and second. * with numeric argument (+n) bring it to top. */ dopushd(v) char **v; { register struct directory *dp; printd = 1; if (*++v == NOSTR) { if ((dp = dcwd->di_prev) == &dhead) dp = dhead.di_prev; if (dp == dcwd) bferr("No other directory"); if (chdir(dp->di_name) < 0) Perror(dp->di_name); dp->di_prev->di_next = dp->di_next; dp->di_next->di_prev = dp->di_prev; dp->di_next = dcwd->di_next; dp->di_prev = dcwd; dcwd->di_next->di_prev = dp; dcwd->di_next = dp; } else if (dp = dfind(*v)) { if (chdir(dp->di_name) < 0) Perror(dp->di_name); } else { register char *cp; cp = dfollow(*v); dp = (struct directory *)calloc(sizeof (struct directory), 1); dp->di_name = cp; dp->di_count = 0; dp->di_prev = dcwd; dp->di_next = dcwd->di_next; dcwd->di_next = dp; dp->di_next->di_prev = dp; } dnewcwd(dp); } /* * dfind - find a directory if specified by numeric (+n) argument */ struct directory * dfind(cp) register char *cp; { register struct directory *dp; register int i; register char *ep; if (*cp++ != '+') return (0); for (ep = cp; digit(*ep); ep++) continue; if (*ep) return (0); i = getn(cp); if (i <= 0) return (0); for (dp = dcwd; i != 0; i--) { if ((dp = dp->di_prev) == &dhead) dp = dp->di_prev; if (dp == dcwd) bferr("Directory stack not that deep"); } return (dp); } /* * dopopd - pop a directory out of the directory stack * with a numeric argument just discard it. */ dopopd(v) char **v; { register struct directory *dp, *p; printd = 1; if (*++v == NOSTR) dp = dcwd; else if ((dp = dfind(*v)) == 0) bferr("Bad directory"); if (dp->di_prev == &dhead && dp->di_next == &dhead) bferr("Directory stack empty"); if (dp == dcwd) { if ((p = dp->di_prev) == &dhead) p = dhead.di_prev; if (chdir(p->di_name) < 0) Perror(p->di_name); } dp->di_prev->di_next = dp->di_next; dp->di_next->di_prev = dp->di_prev; if (dp == dcwd) dnewcwd(p); else dodirs(fakev); dfree(dp); } /* * dfree - free the directory (or keep it if it still has ref count) */ dfree(dp) register struct directory *dp; { if (dp->di_count != 0) dp->di_next = dp->di_prev = 0; else xfree(dp->di_name), xfree((char *)dp); } /* * dcanon - canonicalize the pathname, removing excess ./ and ../ etc. * we are of course assuming that the file system is standardly * constructed (always have ..'s, directories have links) */ dcanon(cp) char *cp; { register char *p, *sp; register bool slash; if (*cp != '/') abort(); for (p = cp; *p; ) { /* for each component */ sp = p; /* save slash address */ while(*++p == '/') /* flush extra slashes */ ; if (p != ++sp) strcpy(sp, p); p = sp; /* save start of component */ slash = 0; while(*++p) /* find next slash or end of path */ if (*p == '/') { slash = 1; *p = 0; break; } if (*sp == '\0') /* if component is null */ if (--sp == cp) /* if path is one char (i.e. /) */ break; else *sp = '\0'; else if (eq(".", sp)) { if (slash) { strcpy(sp, ++p); p = --sp; } else if (--sp != cp) *sp = '\0'; } else if (eq("..", sp)) { if (--sp != cp) while (*--sp != '/') ; if (slash) { strcpy(++sp, ++p); p = --sp; } else if (cp == sp) *++sp = '\0'; else *sp = '\0'; } else if (slash) *p = '/'; } } /* * dnewcwd - make a new directory in the loop the current one */ dnewcwd(dp) register struct directory *dp; { dcwd = dp; set("cwd", savestr(dcwd->di_name)); if (printd) dodirs(fakev); #ifdef SYSV dnewCWD(); #endif } ----sh.getwd_up.c---- #ifdef SYSV #include "sh.h" #define NULL 0 #define STREQ(a,b) (!strcmp(a,b)) /* * returns the current working directory ala pwd(1) * exits if it can't find it. the actual getwd(3J) * spits out a error message on stderr, but since csh(1) * doesn't have filedes 2 open, it makes no sense. * * up => unprivilaged */ char * getwd_up(s) char *s; { int p[2]; int ppid = getpid(); int cpid; int status; int r; char *s1; if (checkCWD(s)) return(s); if (pipe(p) < 0) exit(1); switch(cpid = fork()) { case -1: exit(1); case 0: close(p[0]); /* * This is actually the case in the csh(1). * csh(1) doesn't have 0 or 1 open, so when you do * a pipe, you end up with p[0] == 0 && p[1] == 1. */ if (p[1] != 1) { if (dup2(p[1], 1) < 0) exit(1); close(p[1]); } execl("/bin/pwd", "pwd", 0); exit(1); default: close(p[1]); /* * make sure we get the right kid */ while ((r = wait(&status)) != -1 && r != cpid) ; if ( r == -1) exit(1); break; } /* * we exit if the kid exited un-nornal like */ if (status & 0377) exit(1); if ((r = read(p[0], s, BUFSIZ)) <= 0) exit(1); close(p[0]); s[r] = '\0'; s1 = s; /* * Also, we only want up to and not including the first newline */ while (*s1) if (*s1++ == '\n') { *--s1 = '\0'; break; } return(s); } dnewCWD() { struct stat st; if (stat(".", &st) < 0) return; setenv("CWD", savestr(value("cwd"))); setenv("CWDINO", savestr(ltoo(((long)st.st_dev << 16) | ((long)st.st_ino)))); } char * checkCWD(s) char *s; { char *CWD; char *CWDINO; struct stat st; if (((CWD = getenv("CWD")) == NULL) || ((CWDINO = getenv("CWDINO")) == NULL) || (stat(".", &st) < 0)) return(NULL); if (STREQ(ltoo(((long)st.st_dev << 16) | (long)st.st_ino),CWDINO)) return(strcpy(s, CWD)); return(NULL); } char * ltoo(v) long v; { static char rbuf[16]; char *p = rbuf; while (v > 0) { *p++ = (v & 07) + '0'; v = v >> 3; } return(reverse(rbuf)); } char * reverse(s) char *s; { char *os = s; char *p = s; char c; while (*p) ++p; --p; while (s < p) { c = *s; *s++ = *p; *p-- = c; } return(os); } #endif ----sh.which.c--- #ifdef MOD_WHICH #include "sh.h" dowhich(v) char **v; { struct varent *vp; struct biltins *bp; int found; while (*++v) { found = 0; for (vp = aliases.link; vp; vp = vp->link) { if (!strcmp(vp->name, *v)) { palias(vp); ++found; } } #ifdef MOD_ASSIGN for (vp = assigns.link; vp; vp = vp->link) { if (!strcmp(vp->name, *v)) { passign(vp); ++found; } } #endif MOD_ASSIGN if (!found ) for (bp = bfunc; bp->bname; ++bp) { if (!strcmp(bp->bname, *v)) { printf("%s: is built into the csh\n", *v); ++found; } } if (!found) which(*v); } } palias(vp) struct varent *vp; { printf(vp->name); printf(": aliased to "); blkpr(vp->vec); printf("\n"); } #ifdef MOD_ASSIGN passign(vp) struct varent *vp; { printf(vp->name); printf(": assigned to "); blkpr(vp->vec); printf("\n"); } #endif MOD_ASSIGN which(file) char *file; { char tmp[100]; char *t = tmp; struct varent *vp; char **p; if (vp = adrof("path")) { p = vp->vec; for (p = vp->vec ; *p; ++p) { strcpy(tmp, *p); strcat(tmp, "/"); strcat(tmp, file); if (access(tmp, 1) == 0) { printf("%s\n",tmp); return; } } } printf("no %s in ", file); blkpr(adrof("path")->vec); printf("\n"); } #endif -- -Paul R Borman Cray Research, Inc. ...ihnp4!cray!prb
mikel@codas.UUCP (Mikel Manitius) (10/02/85)
> In article <667@bu-cs.UUCP> root@bu-cs.UUCP (Barry Shein) writes: > >> If you were becoming another > >>normal user, this probably means the current directory was inaccesable > >>to the new user. In this case, su gives up quietly. I think this is > >>a case there things could be a bit more verbose. > >>>(Actually it is the shell which gives up) > > > >You better explain which version of UNIX you believe this happens > >(su exits silently if '.' is not accessible.) > > > >I just tried it under 4.2bsd (vax), SYSVR2 (3b5) and SYSVR(1?) (PC7300) > >and all let me su to a non-priv'd user while in a directory they had > >no access to, of course: > > > Hmm, curiouser and curiouser. I have had it happen on both > 4.1 and 4.2 BSD. And I know it is the directory access since doing a > cd to a different directory always fixes it. Which *shell* were you > using, I was using 'csh'. > -- > > Sarima (Stanley Friesen) > > UUCP: {ttidca|ihnp4|sdcrdcf|quad1|nrcvax|bellcore|logico}!psivax!friesen > ARPA: ttidca!psivax!friesen@rand-unix.arpa I have had the problem happen to me on 4.1bsd, you su to a user, who does not have access to any of the dirrectories leading to your current dirrectory, then you simply get your old shell back and su dies (or the new shell), at the time I was using csh(1). Mikel Manitius AT&T Information Systems {ihnp4!}codas!mikel 151 Wymore Rd. Rm: 420 (305) 869-2462 Altamonte Springs, FL AT&T-IS ETN: 755 32714