bt455s10@uhccux.uhcc.hawaii.edu (Carl "Art" McIntosh) (01/17/90)
The commands chsh and chfn in /usr/ucb under OS 2.01.00 seem broken, at least they don't behave as expected :^)). The problem appears to be that if you are root, and execute chsh, the program exits with the following error message: # chsh Changing login shell for root Old shell: /bin/sh New shell: /bin/sh <=== I type this Sorry, password file changedsize: 1347, expected 1378 Warn your system administrator, please. # Upon examination of the /etc/ptmp.bad file which chsh creates, I see that the shell for *every* account with UID 0 has been changed to /bin/sh. This of course includes sa, startup and shutdown. The chsh NCR is using seems to behave awfully similar to the one posted to the net a while back, I remember installing the program on my ISC unix system at home and fixing the *very same* problem in it. BTW, NCR seems to include PD utilities along with their OS and not acknowlege such, for instance the /etc/zoneinfo junk looks alot like the tz package posted to the net by ado@ncifcrf.gov .... Below is the chsh/chfn package from the net I mentioned above, already fixed to check the user's *name* instead of the UID, so the program behaves as expected. chfn is really just a link to chsh so it suffers from the same malady as chsh. ----------------------- cut here ------------------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: Makefile READ_ME chfn.1 chsh.1 chsh.c # Wrapped by root@pilikia on Tue Jan 16 18:46:38 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(451 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' XCFLAGS=-O XDEST=/usr/local/bin XDOC_DEST=/usr/catman/u_man/man9 X Xchfn chsh: chsh.o X cc $(CFLAGS) chsh.o -o chsh X -rm chfn X ln chsh chfn X Xclean: X rm -f chsh chfn *.o core X Xinstall: chsh chfn X @echo Warning: you must be superuser to do this. X -rm $(DEST)/chsh $(DEST)/chfn X cp chsh $(DEST)/chsh X ln $(DEST)/chsh $(DEST)/chfn X chown root $(DEST)/chsh X chmod 4711 $(DEST)/chsh X nroff -man chsh.1 > $(DOC_DEST)/chsh.1 X nroff -man chfn.1 > $(DOC_DEST)/chfn.1 END_OF_FILE if test 451 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'READ_ME' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'READ_ME'\" else echo shar: Extracting \"'READ_ME'\" \(1567 characters\) sed "s/^X//" >'READ_ME' <<'END_OF_FILE' XThis program was originally written by K. Richard Magill, Xand posted to mod.sources. Since it contained a few XSYS5 dependencies, a *serious* security bug, and no sanity Xchecks at all, I decided to hack it up a bit. X XIt now checks a given shell for existence and executability (only Xby looking at the mode, sorry), and it honors the standard X(as far as I know) algorithm for locking password files. X XThe serious security bug was the following: Imagine a user called Xhacky doing the following: Xchsh hacky '/bin/sh Xdummy::0:0::/:' X XSo, if you've installed it already, better remove it *fast*. X XAlso, some cosmetic changes were made: If no username is given, the Xcurrent user is assumed, and if no shell/realname is given, the Xold one is printed, and a new one asked. X XINSTALLATION: X XFirst, look at the defines at the top in chsh.c. If your system has Xputpwent(), remove the #define NOPUTPWENT. X XSecond, if you don't mind people playing with other people's Xshells and names, remove the #define SECURE. X XThird, KEEP YOUR HANDS OFF the #define DEBUG. X XI tried this on a mucho hacked up 11/34 running V7, so it is not Xmore than sensible that you test it before letting it anywhere near Xthe password file. X XNow, compile it, run it a few times (not as super-user), and, Xwhen you're satisfied, remove the #define DEBUG. X XNow you can type make install, to re-compile and install it. X(Don't forget to look at the Makefile to make sure all Xpaths are as you would like them). X X-- X Jack Jansen, jack@htsa.UUCP (or jack@mcvax.UUCP) X ...!mcvax!vu44!htsa!jack X The shell is my oyster. END_OF_FILE if test 1567 -ne `wc -c <'READ_ME'`; then echo shar: \"'READ_ME'\" unpacked with wrong size! fi # end of 'READ_ME' fi if test -f 'chfn.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'chfn.1'\" else echo shar: Extracting \"'chfn.1'\" \(829 characters\) sed "s/^X//" >'chfn.1' <<'END_OF_FILE' X.TH CHFN 1 Local X.SH NAME Xchfn \- change user's real name X.SH SYNOPSIS X.B chfn X[ user [ realname ] ] X.SH DESCRIPTION X.I chfn Xallows the user to change her real name, as printed by X.I finger(1) Xand X.I who(1). XIf no X.B user Xargument is given, the real name is changed for the person Xcurrently logged in. X.PP XIf no X.B realname Xis given, the current name is printed, and a new one is asked. X.PP XDepending on choices made by the system administrator, it might Xor might not be possible to modify someone else's name. The program Xwill then ask for the correct password first. X.SH SEE ALSO Xchsh(1), finger(1), who(1) X.SH DIAGNOSTICS XAll kinds of problems with the password file, and locking it, Xare reported, and the program exits. X.SH AUTHOR XK. Richard Magill, rich@rexaco1.UUCP X.br XExtensively modified by Jack Jansen, jack@htsa.UUCP. END_OF_FILE if test 829 -ne `wc -c <'chfn.1'`; then echo shar: \"'chfn.1'\" unpacked with wrong size! fi # end of 'chfn.1' fi if test -f 'chsh.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'chsh.1'\" else echo shar: Extracting \"'chsh.1'\" \(982 characters\) sed "s/^X//" >'chsh.1' <<'END_OF_FILE' X.TH CHSH 1 Local X.SH NAME Xchsh \- change login shell X.SH SYNOPSIS X.B chsh X[ user [ shell ] ] X.SH DESCRIPTION X.I chsh Xallows the user to change her login shell. XIf no X.B user Xargument is given, the login shell is changed for the person Xcurrently logged in. X.PP XIf no X.B shell Xis given, the current shell is printed, and a new one is asked. X.PP XDepending on choices made by the system administrator, it might Xor might not be possible to modify someone else's shell. The program Xwill then ask for the correct password first. X.SH SEE ALSO Xchfn(1), login(1) X.SH DIAGNOSTICS XThe X.B shell Xgiven is checked for existence, and executability. X.br XAlso, all kinds of problems with the password file, and locking it, Xare reported, and the program exits. X.SH BUGS XThe executability check only looks at the mode, so it doesn't Xguarantee that you will be able to log in with the given shell. X.SH AUTHOR XK. Richard Magill, rich@rexaco1.UUCP X.br XExtensively modified by Jack Jansen, jack@htsa.UUCP. END_OF_FILE if test 982 -ne `wc -c <'chsh.1'`; then echo shar: \"'chsh.1'\" unpacked with wrong size! fi # end of 'chsh.1' fi if test -f 'chsh.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'chsh.c'\" else echo shar: Extracting \"'chsh.c'\" \(6000 characters\) sed "s/^X//" >'chsh.c' <<'END_OF_FILE' X/* X * This program was originally written by K. Richard Magill, X * and posted to mod.sources. It has been extensively X * modified by Jack Jansen. See below for details. X * X * K. Richard Magill, 26-jan-86. X * Last Mod 26-jan-86, rich. X * Modified by Jack Jansen, 30-jan-86: X * - It now runs under V7. X * - It now uses (what I believe to be) standard X * password file locking and backups. X * - Check the size of the new passwd file, abort if X * it looks funny. X * - Check that there are no :colons: or \nnewlines\n in the X * given string. X * - Use name from getlogin() if not given, and ask for X * parameters if not given. X * - if SECURE is defined, don't let other people X * muck finger/shell info. X */ X/* #define NOPUTPWENT /* Define this if you don't have putpwent */ X#define SECURE /* Only owner/root can change stuff */ X/* #define DEBUG /* ALWAYS DEFINE THIS AT FIRST */ X/*#define void int /* If your compiler doesn't know void */ X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <pwd.h> X X#define WATCH(s,x) if(x){perror(s);return(-1);} X Xchar *PASSWD = "/etc/passwd"; X#ifndef DEBUG Xchar *BACKUP = "/etc/passwd.bak"; Xchar *LOCK = "/etc/vipw.lock"; Xchar *TEMP = "/etc/ptmp"; Xchar *BAD_TEMP = "/etc/ptmp.bad"; X#else Xchar *LOCK = "vipw.lock"; Xchar *TEMP = "ptmp"; Xchar *BAD_TEMP = "ptmp.bad"; X#endif /* DEBUG */ Xchar ArgBuf[128]; Xchar *Arg = ArgBuf; X Xvoid endpwent(), perror(); Xchar *crypt(), *getpass(), *getlogin(), *mktemp(); Xstruct passwd *getpwent(), *getpwnam(), *fgetpwent(); Xchar *strchr(); X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X register int i; X register struct passwd *p; X FILE *fout; X int target_id; /* Who are we changing? */ X struct stat stat_buf; X long OldLen, NewLen; /* Old/New length of passwd */ X long LenDiff; /* Expected length dif. */ X int ShellMode; /* True if chsh */ X char *UserName; /* Who are we working for */ X X if( strcmp(argv[0], "chsh") == 0 ) ShellMode = 1; else X if( strcmp(argv[0], "chfn") != 0 ) { X fprintf(stderr,"Sorry, program name should be 'chsh' or 'chfn'.\n"); X exit(1); X } X X if( argc >= 2 ) { /* Login name given */ X UserName = argv[1]; X } else { X UserName = getlogin(); X printf("Changing %s for %s\n", ShellMode ? "login shell": X "real name", UserName); X } X X /* is this person real? */ X X if ((p = getpwnam(UserName)) == NULL) { X (void) fprintf(stderr, "%s: don't know %s\n", X argv[0], UserName); X return(-1); X } /* if person isn't real */ X X /* do we have permission to do this? */ X target_id = p->pw_uid; X X if ((i = getuid()) != 0 && i != target_id) { X#ifdef SECURE X fprintf(stderr,"Sorry, you don't have permission to do that.\n"); X exit(1); X#else X char salt[3]; X X salt[0] = p->pw_passwd[0]; X salt[1] = p->pw_passwd[1]; X salt[3] = '\0'; X X if (*p->pw_passwd != '\0' X && strncmp(crypt(getpass("Password: "), salt), X p->pw_passwd, 8)) { X (void) fprintf(stderr, "Sorry.\n"); X return(-1); X } /* passwd didn't match */ X#endif /* SECURE */ X } /* check for permission */ X X /* If in verbose mode, print old info */ X if( argc <= 2 ) { X if( ShellMode ) { X printf("Old shell: %s\n", p->pw_shell?p->pw_shell:""); X printf("New shell: "); X gets(Arg); X } else { X printf("Old name: %s\n", p->pw_gecos?p->pw_gecos:""); X printf("New name: "); X gets(Arg); X } X } else { X Arg = argv[2]; X } X X /* Check for dirty characters */ X if( strchr(Arg, '\n') || strchr(Arg, ':') ) { X fprintf(stderr,"%s: Dirty characters in argument.\n",argv[0]); X exit(1); X } X X /* Check that the shell sounds reasonable */ X if( ShellMode ) { X if( *Arg != '/' ) { X fprintf(stderr,"%s: shell name should be full path.\n",Arg); X exit(1); X } X WATCH(Arg,stat(Arg,&stat_buf)); X if( (stat_buf.st_mode & 0111) == 0 ) { X fprintf(stderr,"%s is not an executable.\n"); X exit(1); X } X } X X /* set up files */ X X endpwent(); /* close passwd file */ X X setpwent(); X X /* Now, lock the password file */ X creat(LOCK,0600); /* This might fail. No problem */ X if( link(LOCK,TEMP) < 0 ) { X fprintf(stderr,"Sorry, password file busy.\n"); X exit(1); X } X WATCH(TEMP,(fout = fopen(TEMP, "w")) == NULL); X X while ((p = getpwent()) != NULL) { X /*if (p->pw_uid == target_id) {*/ X if (strcmp(p->pw_name, UserName) == 0) { X if (!ShellMode ) { X LenDiff = strlen(Arg)-strlen(p->pw_gecos); X p->pw_gecos = Arg; X } else { X LenDiff = (-strlen(p->pw_shell)); X p->pw_shell = Arg == NULL ? "/bin/sh" X : Arg; X LenDiff += strlen(p->pw_shell); X } X } /* if this is entry to be changed */ X X WATCH("putpwent",putpwent(p, fout)); X } /* while not eof (we couldn't recognize an error) */ X X /* close files */ X endpwent(); X fclose(fout); X X /* Check that sizes are as expected */ X WATCH(TEMP, stat(TEMP, &stat_buf) ); X NewLen = stat_buf.st_size; X WATCH(PASSWD, stat(PASSWD, &stat_buf) ); X OldLen = stat_buf.st_size; X if( OldLen + LenDiff != NewLen ) { X fprintf(stderr,"Sorry, password file changed size: %ld, expected %ld.\n", NewLen, OldLen+LenDiff); X fprintf(stderr,"Warn your system administrator, please.\n"); X WATCH(TEMP, link(TEMP,BAD_TEMP)); X WATCH(TEMP,unlink(TEMP)); X WATCH(LOCK,unlink(LOCK)); X exit(1); X } X X#ifndef DEBUG X /* remove old backup if it exists */ X WATCH(BACKUP,!stat(BACKUP, &stat_buf) && unlink(BACKUP)); X X /* make current passwd file backup */ X WATCH("linking passwd to passwd.bak",link(PASSWD, BACKUP) || unlink(PASSWD)); X X /* make new file passwd */ X WATCH("linking temp to passwd",link(TEMP, PASSWD) || unlink(TEMP)); X WATCH("chmod passwd", chmod(PASSWD, 0644)); X#endif /* DEBUG */ X X /* Remove lock */ X WATCH(LOCK,unlink(LOCK)); X X#ifdef DEBUG X printf("Now, check that %s looks reasonable.\n", TEMP); X#endif /* DEBUG */ X /* must have succeeded */ X return(0); X} /* main */ X X#ifdef NOPUTPWENT Xputpwent(ent, fp) X FILE *fp; X struct passwd *ent; X { X X fprintf(fp,"%s:%s:%d:%d:%s:%s:%s\n", ent->pw_name, ent->pw_passwd, X ent->pw_uid, ent->pw_gid, ent->pw_gecos, ent->pw_dir, X ent->pw_shell); X return(0); X} X#endif /* NOPUTPWENT */ END_OF_FILE if test 6000 -ne `wc -c <'chsh.c'`; then echo shar: \"'chsh.c'\" unpacked with wrong size! fi # end of 'chsh.c' fi echo shar: End of shell archive. exit 0 ----------------------- cut here ------------------------- -- Art Neilson | ARPA: manapua!pilikia!root@trout.nosc.mil Bank of Hawaii Tech Support | UUCP: uunet!ucsd!nosc!manapua!pilikia!root
wescott@Columbia.NCR.COM (Mike Wescott) (01/19/90)
In article <6186@uhccux.uhcc.hawaii.edu> bt455s10@uhccux.uhcc.hawaii.edu (Carl "Art" McIntosh) writes: > The commands chsh and chfn in /usr/ucb under OS 2.01.00 seem broken, Yep. It is.. > The chsh NCR is using seems to behave awfully > similar to the one posted to the net a while back It's the same one. > the /etc/zoneinfo junk looks alot like > the tz package posted to the net by ado@ncifcrf.gov .... Again, we used ado's software. However, we have not deliberately slighted anyone. It is difficult to introduce PD software into the product and to make sure that proper credit appears in the documentation. We could do a better job there. > Below is the chsh/chfn package from the net I mentioned above, > already fixed to check the user's *name* instead of the UID, Thanks, I'll see that your fix gets implemented. -- -Mike Wescott mike.wescott@ncrcae.Columbia.NCR.COM
wescott@Columbia.NCR.COM (Mike Wescott) (01/19/90)
In article <1904@sauron.Columbia.NCR.COM> wescott@micky.Columbia.NCR.COM (Mike Wescott) writes: > In article <6186@uhccux.uhcc.hawaii.edu> bt455s10@uhccux.uhcc.hawaii.edu (Carl "Art" McIntosh) writes: > > The commands chsh and chfn in /usr/ucb under OS 2.01.00 seem broken, > > Yep. It is.. I spoke too quickly. Yes it is broken in OS 2.01.00 but fixed in a later release. -- -Mike Wescott mike.wescott@ncrcae.Columbia.NCR.COM