Annotation of 42BSD/ucb/chsh.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *sccsid = "@(#)chsh.c      4.7 (Berkeley) 7/10/83";
                      3: #endif
                      4: 
                      5: /*
                      6:  * chsh
                      7:  */
                      8: #include <stdio.h>
                      9: #include <signal.h>
                     10: #include <pwd.h>
                     11: #include <sys/file.h>
                     12: #include <sys/time.h>
                     13: #include <sys/resource.h>
                     14: 
                     15: char   passwd[] = "/etc/passwd";
                     16: char   temp[]   = "/etc/ptmp";
                     17: struct passwd *pwd;
                     18: struct passwd *getpwent();
                     19: int    endpwent();
                     20: char   *crypt();
                     21: char   *getpass();
                     22: char   *strcat();
                     23: char   buf[BUFSIZ];
                     24: 
                     25: main(argc, argv)
                     26: register char *argv[];
                     27: {
                     28:        register int u, fd;
                     29:        register FILE *tf;
                     30: 
                     31:        if (argc < 2 || argc > 3) {
                     32:                printf("Usage: chsh user [ /bin/csh ]\n");
                     33:                exit(1);
                     34:        }
                     35:        if (argc == 2)
                     36:                argv[2] = "";
                     37:        else {
                     38:                if (argv[2][0] != '/')
                     39:                        argv[2] = strcat(
                     40:                            "/bin/\0 12345678901234567890123456789", argv[2]);
                     41:                if (strcmp(argv[2], "/bin/csh") &&
                     42:                    strcmp(argv[2], "/bin/oldcsh") &&
                     43:                    strcmp(argv[2], "/bin/newcsh") &&
                     44:                    strcmp(argv[2], "/usr/new/csh") &&
                     45:                        /* and, for cretins who can't read the manual */
                     46:                    strcmp(argv[2], "/bin/sh") &&
                     47:                    getuid()) {
                     48:                        printf(
                     49:                            "Only /bin/csh may be specified\n"
                     50:                        );
                     51:                        exit(1);
                     52:                }
                     53:                if (access(argv[2], 1) < 0) {
                     54:                        printf("%s is not available\n", argv[2]);
                     55:                        exit(1);
                     56:                }
                     57:        }
                     58:        unlimit(RLIMIT_CPU);
                     59:        unlimit(RLIMIT_FSIZE);
                     60:        while ((pwd=getpwent()) != NULL) {
                     61:                if (strcmp(pwd->pw_name, argv[1]) == 0) {
                     62:                        u = getuid();
                     63:                        if (u!=0 && u != pwd->pw_uid) {
                     64:                                printf("Permission denied.\n");
                     65:                                exit(1);
                     66:                        }
                     67:                        break;
                     68:                }
                     69:        }
                     70:        endpwent();
                     71: 
                     72:        signal(SIGHUP, SIG_IGN);
                     73:        signal(SIGINT, SIG_IGN);
                     74:        signal(SIGQUIT, SIG_IGN);
                     75:        signal(SIGTSTP, SIG_IGN);
                     76:        (void) umask(0);
                     77:        if ((fd = open(temp, O_CREAT|O_EXCL|O_RDWR, 0644)) < 0) {
                     78:                printf("Temporary file busy -- try again\n");
                     79:                exit(1);
                     80:        }
                     81:        if ((tf=fdopen(fd, "w")) == NULL) {
                     82:                printf("Absurd fdopen failure - seek help\n");
                     83:                goto out;
                     84:        }
                     85:        /*
                     86:         * Copy passwd to temp, replacing matching lines
                     87:         * with new shell.
                     88:         */
                     89:        while ((pwd=getpwent()) != NULL) {
                     90:                if (strcmp(pwd->pw_name, argv[1]) == 0) {
                     91:                        u = getuid();
                     92:                        if (u != 0 && u != pwd->pw_uid) {
                     93:                                printf("Permission denied.\n");
                     94:                                goto out;
                     95:                        }
                     96:                        pwd->pw_shell = argv[2];
                     97:                }
                     98:                if (strcmp(pwd->pw_shell, "/bin/sh") == 0)
                     99:                        pwd->pw_shell = "";
                    100:                fprintf(tf, "%s:%s:%d:%d:%s:%s:%s\n"
                    101:                        , pwd->pw_name
                    102:                        , pwd->pw_passwd
                    103:                        , pwd->pw_uid
                    104:                        , pwd->pw_gid
                    105:                        , pwd->pw_gecos
                    106:                        , pwd->pw_dir
                    107:                        , pwd->pw_shell
                    108:                );
                    109:        }
                    110:        endpwent();
                    111:        if (rename(temp, passwd) < 0) {
                    112:                fprintf(stderr, "chsh: "); perror("rename");
                    113:   out:
                    114:                unlink(temp);
                    115:                exit(1);
                    116:        }
                    117:        fclose(tf);
                    118:        exit(0);
                    119: }
                    120: 
                    121: unlimit(lim)
                    122: {
                    123:        struct rlimit rlim;
                    124: 
                    125:        rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
                    126:        setrlimit(lim, &rlim);
                    127: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.