home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / sys / sgi / admin / 87 < prev    next >
Encoding:
Text File  |  1992-12-29  |  13.2 KB  |  455 lines

  1. Newsgroups: comp.sys.sgi.admin
  2. Path: sparky!uunet!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!eagle!ZoSo.lerc.nasa.gov!fsfacca
  3. From: fsfacca@ZoSo.lerc.nasa.gov (Tony Facca)
  4. Subject: Re: letting users choose their login shells
  5. Message-ID: <1992Dec29.151509.16858@eagle.lerc.nasa.gov>
  6. Sender: news@eagle.lerc.nasa.gov
  7. Nntp-Posting-Host: zoso.lerc.nasa.gov
  8. Organization: NASA Lewis Research Center [Cleveland, Ohio]
  9. References: <1hkv9vINNba9@tamsun.tamu.edu>
  10. Date: Tue, 29 Dec 1992 15:15:09 GMT
  11. Lines: 442
  12.  
  13. vamsee@abgen.tamu.edu (Vamsee Lakamsani) writes:
  14. >Is there a way to let the users change their shell and finger information
  15. >on the SGIs. I used "/bin/chsh" and "/bin/chfn" on the SUNs. Does anybody
  16. >know if something similar exists for an SGI(4.0.5A) ?
  17. >
  18. >Vamsee
  19.  
  20. Actually, the source for chsh is available:
  21.  
  22.  
  23. #! /bin/sh
  24. # This is a shell archive.  Remove anything before this line, then unpack
  25. # it by saving it into a file and typing "sh file".  To overwrite existing
  26. # files, type "sh file -c".  You can also feed this as standard input via
  27. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  28. # will see the following message at the end:
  29. #        "End of shell archive."
  30. # Contents:  Makefile READ_ME chfn.1 chsh.1 chsh.c
  31. # Wrapped by fsfacca@ZoSo on Tue Dec 29 10:13:13 1992
  32. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  33. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  34.   echo shar: Will not clobber existing file \"'Makefile'\"
  35. else
  36. echo shar: Extracting \"'Makefile'\" \(397 characters\)
  37. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  38. XCFLAGS=-O
  39. XDEST=/usr/local/bin
  40. XDOC_DEST=/usr/catman/local/cat1
  41. X
  42. Xchfn chsh: chsh.o
  43. X    cc $(CFLAGS) chsh.o -o chsh
  44. X    -rm chfn
  45. X    ln chsh chfn
  46. X
  47. Xinstall: chsh chfn
  48. X    @echo Warning: you must be superuser to do this.
  49. X    -rm $(DEST)/chsh $(DEST)/chfn
  50. X    cp chsh $(DEST)/chsh
  51. X    ln $(DEST)/chsh $(DEST)/chfn
  52. X    chown root $(DEST)/chsh
  53. X    chmod 4711 $(DEST)/chsh
  54. X    cp chsh.1 $(DOC_DEST)/chsh.1
  55. X    cp chfn.1 $(DOC_DEST)/chfn.1
  56. END_OF_FILE
  57. if test 397 -ne `wc -c <'Makefile'`; then
  58.     echo shar: \"'Makefile'\" unpacked with wrong size!
  59. fi
  60. # end of 'Makefile'
  61. fi
  62. if test -f 'READ_ME' -a "${1}" != "-c" ; then 
  63.   echo shar: Will not clobber existing file \"'READ_ME'\"
  64. else
  65. echo shar: Extracting \"'READ_ME'\" \(1567 characters\)
  66. sed "s/^X//" >'READ_ME' <<'END_OF_FILE'
  67. XThis program was originally written by K. Richard Magill,
  68. Xand posted to mod.sources. Since it contained a few
  69. XSYS5 dependencies, a *serious* security bug, and no sanity
  70. Xchecks at all, I decided to hack it up a bit.
  71. X
  72. XIt now checks a given shell for existence and executability (only
  73. Xby looking at the mode, sorry), and it honors the standard
  74. X(as far as I know) algorithm for locking password files.
  75. X
  76. XThe serious security bug was the following: Imagine a user called
  77. Xhacky doing the following:
  78. Xchsh hacky '/bin/sh
  79. Xdummy::0:0::/:'
  80. X
  81. XSo, if you've installed it already, better remove it *fast*.
  82. X
  83. XAlso, some cosmetic changes were made: If no username is given, the
  84. Xcurrent user is assumed, and if no shell/realname is given, the
  85. Xold one is printed, and a new one asked.
  86. X
  87. XINSTALLATION:
  88. X
  89. XFirst, look at the defines at the top in chsh.c. If your system has
  90. Xputpwent(), remove the #define NOPUTPWENT.
  91. X
  92. XSecond, if you don't mind people playing with other people's
  93. Xshells and names, remove the #define SECURE.
  94. X
  95. XThird, KEEP YOUR HANDS OFF the #define DEBUG.
  96. X
  97. XI tried this on a mucho hacked up 11/34 running V7, so it is not
  98. Xmore than sensible that you test it before letting it anywhere near
  99. Xthe password file.
  100. X
  101. XNow, compile it, run it a few times (not as super-user), and,
  102. Xwhen you're satisfied, remove the #define DEBUG.
  103. X
  104. XNow you can type make install, to re-compile and install it.
  105. X(Don't forget to look at the Makefile to make sure all
  106. Xpaths are as you would like them).
  107. X
  108. X--
  109. X    Jack Jansen, jack@htsa.UUCP (or jack@mcvax.UUCP)
  110. X    ...!mcvax!vu44!htsa!jack
  111. X    The shell is my oyster.
  112. END_OF_FILE
  113. if test 1567 -ne `wc -c <'READ_ME'`; then
  114.     echo shar: \"'READ_ME'\" unpacked with wrong size!
  115. fi
  116. # end of 'READ_ME'
  117. fi
  118. if test -f 'chfn.1' -a "${1}" != "-c" ; then 
  119.   echo shar: Will not clobber existing file \"'chfn.1'\"
  120. else
  121. echo shar: Extracting \"'chfn.1'\" \(829 characters\)
  122. sed "s/^X//" >'chfn.1' <<'END_OF_FILE'
  123. X.TH CHFN 1 Local
  124. X.SH NAME
  125. Xchfn \- change user's real name
  126. X.SH SYNOPSIS
  127. X.B chfn
  128. X[ user [ realname ] ]
  129. X.SH DESCRIPTION
  130. X.I chfn
  131. Xallows the user to change her real name, as printed by
  132. X.I finger(1)
  133. Xand
  134. X.I who(1).
  135. XIf no
  136. X.B user
  137. Xargument is given, the real name is changed for the person
  138. Xcurrently logged in.
  139. X.PP
  140. XIf no
  141. X.B realname
  142. Xis given, the current name is printed, and a new one is asked.
  143. X.PP
  144. XDepending on choices made by the system administrator, it might
  145. Xor might not be possible to modify someone else's name. The program
  146. Xwill then ask for the correct password first.
  147. X.SH SEE ALSO
  148. Xchsh(1), finger(1), who(1)
  149. X.SH DIAGNOSTICS
  150. XAll kinds of problems with the password file, and locking it,
  151. Xare reported, and the program exits.
  152. X.SH AUTHOR
  153. XK. Richard Magill, rich@rexaco1.UUCP
  154. X.br
  155. XExtensively modified by Jack Jansen, jack@htsa.UUCP.
  156. END_OF_FILE
  157. if test 829 -ne `wc -c <'chfn.1'`; then
  158.     echo shar: \"'chfn.1'\" unpacked with wrong size!
  159. fi
  160. # end of 'chfn.1'
  161. fi
  162. if test -f 'chsh.1' -a "${1}" != "-c" ; then 
  163.   echo shar: Will not clobber existing file \"'chsh.1'\"
  164. else
  165. echo shar: Extracting \"'chsh.1'\" \(982 characters\)
  166. sed "s/^X//" >'chsh.1' <<'END_OF_FILE'
  167. X.TH CHSH 1 Local
  168. X.SH NAME
  169. Xchsh \- change login shell
  170. X.SH SYNOPSIS
  171. X.B chsh
  172. X[ user [ shell ] ]
  173. X.SH DESCRIPTION
  174. X.I chsh
  175. Xallows the user to change her login shell.
  176. XIf no
  177. X.B user
  178. Xargument is given, the login shell is changed for the person
  179. Xcurrently logged in.
  180. X.PP
  181. XIf no
  182. X.B shell
  183. Xis given, the current shell is printed, and a new one is asked.
  184. X.PP
  185. XDepending on choices made by the system administrator, it might
  186. Xor might not be possible to modify someone else's shell. The program
  187. Xwill then ask for the correct password first.
  188. X.SH SEE ALSO
  189. Xchfn(1), login(1)
  190. X.SH DIAGNOSTICS
  191. XThe
  192. X.B shell
  193. Xgiven is checked for existence, and executability.
  194. X.br
  195. XAlso, all kinds of problems with the password file, and locking it,
  196. Xare reported, and the program exits.
  197. X.SH BUGS
  198. XThe executability check only looks at the mode, so it doesn't
  199. Xguarantee that you will be able to log in with the given shell.
  200. X.SH AUTHOR
  201. XK. Richard Magill, rich@rexaco1.UUCP
  202. X.br
  203. XExtensively modified by Jack Jansen, jack@htsa.UUCP.
  204. END_OF_FILE
  205. if test 982 -ne `wc -c <'chsh.1'`; then
  206.     echo shar: \"'chsh.1'\" unpacked with wrong size!
  207. fi
  208. # end of 'chsh.1'
  209. fi
  210. if test -f 'chsh.c' -a "${1}" != "-c" ; then 
  211.   echo shar: Will not clobber existing file \"'chsh.c'\"
  212. else
  213. echo shar: Extracting \"'chsh.c'\" \(5904 characters\)
  214. sed "s/^X//" >'chsh.c' <<'END_OF_FILE'
  215. X/*
  216. X *    This program was originally written by K. Richard Magill,
  217. X *    and posted to mod.sources. It has been extensively
  218. X *    modified by Jack Jansen. See below for details.
  219. X *
  220. X *    K. Richard Magill, 26-jan-86.
  221. X *    Last Mod 26-jan-86, rich.
  222. X *    Modified by Jack Jansen, 30-jan-86:
  223. X *    - It now runs under V7.
  224. X *    - It now uses (what I believe to be) standard
  225. X *      password file locking and backups.
  226. X *    - Check the size of the new passwd file, abort if
  227. X *      it looks funny.
  228. X *    - Check that there are no :colons: or \nnewlines\n in the
  229. X *      given string.
  230. X *    - Use name from getlogin() if not given, and ask for
  231. X *      parameters if not given.
  232. X *    - if SECURE is defined, don't let other people
  233. X *      muck finger/shell info.
  234. X */
  235. X/*#define NOPUTPWENT  1        Define this if you don't have putpwent */
  236. X#define SECURE    1        /* Only owner/root can change stuff */
  237. X#define DEBUG    1        /* ALWAYS DEFINE THIS AT FIRST */
  238. X/*#define void    int         If your compiler doesn't know void */
  239. X
  240. X#include <stdio.h>
  241. X#include <sys/types.h>
  242. X#include <sys/stat.h>
  243. X#include <pwd.h>
  244. X
  245. X#define WATCH(s,x)    if(x){perror(s);return(-1);}
  246. X
  247. Xchar *PASSWD = "/etc/passwd";
  248. X#ifndef DEBUG
  249. Xchar *BACKUP = "/etc/passwd.bak";
  250. Xchar *LOCK = "/etc/vipw.lock";
  251. Xchar *TEMP = "/etc/ptmp";
  252. Xchar *BAD_TEMP = "/etc/ptmp.bad";
  253. X#else
  254. Xchar *LOCK = "vipw.lock";
  255. Xchar *TEMP = "ptmp";
  256. Xchar *BAD_TEMP = "ptmp.bad";
  257. X#endif DEBUG
  258. Xchar ArgBuf[128];
  259. Xchar *Arg = ArgBuf;
  260. X
  261. Xvoid endpwent(), perror();
  262. Xchar *crypt(), *getpass(), *mktemp();
  263. Xstruct passwd *getpwent(), *getpwnam(), *fgetpwent();
  264. Xchar *index();
  265. X
  266. Xmain(argc, argv)
  267. Xint argc;
  268. Xchar **argv;
  269. X{
  270. X    register int i;
  271. X    register struct passwd *p;
  272. X    FILE *fout;
  273. X    int target_id;            /* Who are we changing? */
  274. X    struct stat stat_buf;
  275. X    long  OldLen, NewLen;        /* Old/New length of passwd */
  276. X    long LenDiff;            /* Expected length dif. */
  277. X    int ShellMode;            /* True if chsh */
  278. X    char *UserName;            /* Who are we working for */
  279. X
  280. X    if( strcmp(argv[0], "chsh") == 0 ) ShellMode = 1; else
  281. X    if( strcmp(argv[0], "chfn") != 0 ) {
  282. X        fprintf(stderr,"Sorry, program name should be 'chsh' or 'chfn'.\n");
  283. X        exit(1);
  284. X    }
  285. X
  286. X    if( argc >= 2 ) {    /* Login name given */
  287. X        UserName = argv[1];
  288. X    } else {
  289. X        UserName = getlogin();
  290. X        printf("Changing %s for %s\n", ShellMode ? "login shell":
  291. X            "real name", UserName);
  292. X    }
  293. X
  294. X    /* is this person real? */
  295. X
  296. X    if ((p = getpwnam(UserName)) == NULL) {
  297. X        (void) fprintf(stderr, "%s: don't know %s\n",
  298. X            argv[0], UserName);
  299. X        return(-1);
  300. X    }    /* if person isn't real */
  301. X
  302. X    /* do we have permission to do this? */
  303. X    target_id = p->pw_uid;
  304. X
  305. X    if ((i = getuid()) != 0 && i != target_id) {
  306. X#ifdef SECURE
  307. X        fprintf(stderr,"Sorry, you don't have permission to do that.\n");
  308. X        exit(1);
  309. X#else
  310. X        char salt[3];
  311. X
  312. X        salt[0] = p->pw_passwd[0];
  313. X        salt[1] = p->pw_passwd[1];
  314. X        salt[3] = '\0';
  315. X
  316. X        if (*p->pw_passwd != '\0'
  317. X            && strncmp(crypt(getpass("Password: "), salt),
  318. X            p->pw_passwd, 8)) {
  319. X            (void) fprintf(stderr, "Sorry.\n");
  320. X            return(-1);
  321. X        }    /* passwd didn't match */
  322. X#endif SECURE
  323. X    }    /* check for permission */
  324. X
  325. X    /* If in verbose mode, print old info */
  326. X    if( argc <= 2 ) {
  327. X        if( ShellMode ) {
  328. X        printf("Old shell: %s\n", p->pw_shell?p->pw_shell:"");
  329. X        printf("New shell: ");
  330. X        gets(Arg);
  331. X        } else {
  332. X        printf("Old name: %s\n", p->pw_gecos?p->pw_gecos:"");
  333. X        printf("New name: ");
  334. X        gets(Arg);
  335. X        }
  336. X    } else {
  337. X        Arg = argv[2];
  338. X    }
  339. X
  340. X    /* Check for dirty characters */
  341. X    if( index(Arg, '\n') || index(Arg, ':') ) {
  342. X        fprintf(stderr,"%s: Dirty characters in argument.\n",argv[0]);
  343. X        exit(1);
  344. X    }
  345. X
  346. X    /* Check that the shell sounds reasonable */
  347. X    if( ShellMode ) {
  348. X        if( *Arg != '/' ) {
  349. X        fprintf(stderr,"%s: shell name should be full path.\n",Arg);
  350. X        exit(1);
  351. X        }
  352. X        WATCH(Arg,stat(Arg,&stat_buf));
  353. X        if( (stat_buf.st_mode & 0111) == 0 ) {
  354. X        fprintf(stderr,"%s is not an executable.\n");
  355. X        exit(1);
  356. X        }
  357. X    }
  358. X
  359. X    /* set up files */
  360. X
  361. X    endpwent();    /* close passwd file */
  362. X
  363. X    setpwent();
  364. X
  365. X    /* Now, lock the password file */
  366. X    creat(LOCK,0600);    /* This might fail. No problem */
  367. X    if( link(LOCK,TEMP) < 0 ) {
  368. X        fprintf(stderr,"Sorry, password file busy.\n");
  369. X        exit(1);
  370. X    }
  371. X    WATCH(TEMP,(fout = fopen(TEMP, "w")) == NULL);
  372. X
  373. X    while ((p = getpwent()) != NULL) {
  374. X        if (p->pw_uid == target_id) {
  375. X            if (!ShellMode ) {
  376. X                LenDiff = strlen(Arg)-strlen(p->pw_gecos);
  377. X                p->pw_gecos = Arg;
  378. X            } else {
  379. X                LenDiff = (-strlen(p->pw_shell));
  380. X                p->pw_shell = Arg == NULL ? "/bin/sh"
  381. X                    : Arg;
  382. X                LenDiff += strlen(p->pw_shell);
  383. X            }
  384. X        }    /* if this is entry to be changed */
  385. X
  386. X        WATCH("putpwent",putpwent(p, fout));
  387. X    }    /* while not eof (we couldn't recognize an error) */
  388. X
  389. X    /* close files */
  390. X    endpwent();
  391. X    fclose(fout);
  392. X
  393. X    /* Check that sizes are as expected */
  394. X    WATCH(TEMP, stat(TEMP, &stat_buf) );
  395. X    NewLen = stat_buf.st_size;
  396. X    WATCH(PASSWD, stat(PASSWD, &stat_buf) );
  397. X    OldLen = stat_buf.st_size;
  398. X    if( OldLen + LenDiff != NewLen ) {
  399. X        fprintf(stderr,"Sorry, password file changed size: %ld, expected %ld.\n", NewLen, OldLen+LenDiff);
  400. X        fprintf(stderr,"Warn your system administrator, please.\n");
  401. X        WATCH(TEMP, link(TEMP,BAD_TEMP));
  402. X        WATCH(TEMP,unlink(TEMP));
  403. X        WATCH(LOCK,unlink(LOCK));
  404. X        exit(1);
  405. X    }
  406. X
  407. X#ifndef DEBUG
  408. X    /* remove old backup if it exists */
  409. X    WATCH(BACKUP,!stat(BACKUP, &stat_buf) && unlink(BACKUP));
  410. X
  411. X    /* make current passwd file backup */
  412. X    WATCH("linking passwd to passwd.bak",link(PASSWD, BACKUP) || unlink(PASSWD));
  413. X
  414. X    /* make new file passwd */
  415. X    WATCH("linking temp to passwd",link(TEMP, PASSWD) || unlink(TEMP));
  416. X    WATCH("chmod passwd", chmod(PASSWD, 0644));
  417. X#endif DEBUG
  418. X
  419. X    /* Remove lock */
  420. X    WATCH(LOCK,unlink(LOCK));
  421. X
  422. X#ifdef DEBUG
  423. X    printf("Now, check that %s looks reasonable.\n", TEMP);
  424. X#endif DEBUG
  425. X    /* must have succeeded */
  426. X    return(0);
  427. X}    /* main */
  428. X
  429. X#ifdef NOPUTPWENT
  430. Xputpwent(ent, fp)
  431. X    FILE *fp;
  432. X    struct passwd *ent;
  433. X    {
  434. X
  435. X    fprintf(fp,"%s:%s:%d:%d:%s:%s:%s\n", ent->pw_name, ent->pw_passwd,
  436. X    ent->pw_uid, ent->pw_gid, ent->pw_gecos, ent->pw_dir,
  437. X    ent->pw_shell);
  438. X    return(0);
  439. X}
  440. X#endif NOPUTPWENT
  441. END_OF_FILE
  442. if test 5904 -ne `wc -c <'chsh.c'`; then
  443.     echo shar: \"'chsh.c'\" unpacked with wrong size!
  444. fi
  445. # end of 'chsh.c'
  446. fi
  447. echo shar: End of shell archive.
  448. exit 0
  449. -- 
  450. -------------------------------------------------------------------------------
  451.      Merry Christmas!!  Happy New Year!         | Remember --
  452.                                                 | Christmas Spirit is not
  453.    Tony Facca   [fsfacca@avelon.lerc.nasa.gov]  |           what you drink..
  454. -------------------------------------------------------------------------------
  455.