Annotation of 43BSDReno/usr.sbin/chown/chown.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted provided
                      6:  * that: (1) source distributions retain this entire copyright notice and
                      7:  * comment, and (2) distributions including binaries display the following
                      8:  * acknowledgement:  ``This product includes software developed by the
                      9:  * University of California, Berkeley and its contributors'' in the
                     10:  * documentation or other materials provided with the distribution and in
                     11:  * all advertising materials mentioning features or use of this software.
                     12:  * Neither the name of the University nor the names of its contributors may
                     13:  * be used to endorse or promote products derived from this software without
                     14:  * specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: char copyright[] =
                     22: "@(#) Copyright (c) 1988 Regents of the University of California.\n\
                     23:  All rights reserved.\n";
                     24: #endif /* not lint */
                     25: 
                     26: #ifndef lint
                     27: static char sccsid[] = "@(#)chown.c    5.15 (Berkeley) 6/1/90";
                     28: #endif /* not lint */
                     29: 
                     30: #include <sys/param.h>
                     31: #include <sys/stat.h>
                     32: #include <sys/errno.h>
                     33: #include <dirent.h>
                     34: #include <pwd.h>
                     35: #include <grp.h>
                     36: #include <stdio.h>
                     37: #include <ctype.h>
                     38: 
                     39: int ischown, uid, gid, fflag, rflag, retval;
                     40: char *gname, *myname;
                     41: 
                     42: main(argc, argv)
                     43:        int argc;
                     44:        char **argv;
                     45: {
                     46:        extern char *optarg;
                     47:        extern int optind;
                     48:        register char *cp;
                     49:        int ch;
                     50:        char curpath[MAXPATHLEN], *reset, *index(), *rindex();
                     51: 
                     52:        myname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
                     53:        ischown = myname[2] == 'o';
                     54: 
                     55:        while ((ch = getopt(argc, argv, "Rf")) != EOF)
                     56:                switch((char)ch) {
                     57:                case 'R':
                     58:                        rflag++;
                     59:                        break;
                     60:                case 'f':
                     61:                        fflag++;
                     62:                        break;
                     63:                case '?':
                     64:                default:
                     65:                        usage();
                     66:                }
                     67:        argv += optind;
                     68:        argc -= optind;
                     69: 
                     70:        if (argc < 2)
                     71:                usage();
                     72: 
                     73:        if (ischown) {
                     74:                if (cp = index(*argv, '.')) {
                     75:                        *cp++ = '\0';
                     76:                        setgid(cp);
                     77:                }
                     78:                else
                     79:                        gid = -1;
                     80:                setuid(*argv);
                     81:        }
                     82:        else {
                     83:                uid = -1;
                     84:                setgid(*argv);
                     85:        }
                     86: 
                     87:        while (*++argv) {
                     88:                if (reset = index(*argv, '/'))
                     89:                        (void)getwd(curpath);
                     90:                change(*argv);
                     91:                if (reset && chdir(curpath)) {
                     92:                        if (fflag)
                     93:                                exit(0);
                     94:                        err(curpath);
                     95:                        exit(-1);
                     96:                }
                     97:        }
                     98:        exit(retval);
                     99: }
                    100: 
                    101: setgid(s)
                    102:        register char *s;
                    103: {
                    104:        struct group *gr, *getgrnam();
                    105: 
                    106:        if (!*s) {
                    107:                gid = -1;                       /* argument was "uid." */
                    108:                return;
                    109:        }
                    110:        for (gname = s; *s && isdigit(*s); ++s);
                    111:        if (!*s)
                    112:                gid = atoi(gname);
                    113:        else {
                    114:                if (!(gr = getgrnam(gname))) {
                    115:                        if (fflag)
                    116:                                exit(0);
                    117:                        (void)fprintf(stderr, "%s: unknown group id: %s\n",
                    118:                            myname, gname);
                    119:                        exit(-1);
                    120:                }
                    121:                gid = gr->gr_gid;
                    122:        }
                    123: }
                    124: 
                    125: setuid(s)
                    126:        register char *s;
                    127: {
                    128:        struct passwd *pwd, *getpwnam();
                    129:        char *beg;
                    130: 
                    131:        if (!*s) {
                    132:                uid = -1;                       /* argument was ".gid" */
                    133:                return;
                    134:        }
                    135:        for (beg = s; *s && isdigit(*s); ++s);
                    136:        if (!*s)
                    137:                uid = atoi(beg);
                    138:        else {
                    139:                if (!(pwd = getpwnam(beg))) {
                    140:                        if (fflag)
                    141:                                exit(0);
                    142:                        (void)fprintf(stderr,
                    143:                            "chown: unknown user id: %s\n", beg);
                    144:                        exit(-1);
                    145:                }
                    146:                uid = pwd->pw_uid;
                    147:        }
                    148: }
                    149: 
                    150: change(file)
                    151:        char *file;
                    152: {
                    153:        register DIR *dirp;
                    154:        register struct dirent *dp;
                    155:        struct stat buf;
                    156: 
                    157:        if (chown(file, uid, gid)) {
                    158:                chownerr(file);
                    159:                return;
                    160:        }
                    161:        if (!rflag)
                    162:                return;
                    163:        if (lstat(file, &buf)) {
                    164:                err(file);
                    165:                return;
                    166:        }
                    167:        if ((buf.st_mode & S_IFMT) == S_IFDIR) {
                    168:                if (chdir(file) < 0 || !(dirp = opendir("."))) {
                    169:                        err(file);
                    170:                        return;
                    171:                }
                    172:                for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
                    173:                        if (dp->d_name[0] == '.' && (!dp->d_name[1] ||
                    174:                            dp->d_name[1] == '.' && !dp->d_name[2]))
                    175:                                continue;
                    176:                        change(dp->d_name);
                    177:                }
                    178:                closedir(dirp);
                    179:                if (chdir("..")) {
                    180:                        err("..");
                    181:                        exit(fflag ? 0 : -1);
                    182:                }
                    183:        }
                    184: }
                    185: 
                    186: chownerr(file)
                    187:        char *file;
                    188: {
                    189:        extern int errno;
                    190:        static int euid = -1, ngroups = -1;
                    191: 
                    192:        /* check for chown without being root */
                    193:        if (errno != EPERM || uid != -1 && euid == -1 && (euid = geteuid())) {
                    194:                if (fflag)
                    195:                        exit(0);
                    196:                err(file);
                    197:                exit(-1);
                    198:        }
                    199:        /* check group membership; kernel just returns EPERM */
                    200:        if (gid != -1 && ngroups == -1) {
                    201:                int groups[NGROUPS];
                    202: 
                    203:                ngroups = getgroups(NGROUPS, groups);
                    204:                while (--ngroups >= 0 && gid != groups[ngroups]);
                    205:                if (ngroups < 0) {
                    206:                        if (fflag)
                    207:                                exit(0);
                    208:                        (void)fprintf(stderr,
                    209:                            "%s: you are not a member of group %s.\n",
                    210:                            myname, gname);
                    211:                        exit(-1);
                    212:                }
                    213:        }
                    214:        err(file);
                    215: }
                    216: 
                    217: err(s)
                    218:        char *s;
                    219: {
                    220:        extern int errno;
                    221:        char *strerror();
                    222: 
                    223:        if (fflag)
                    224:                return;
                    225:        (void)fprintf(stderr, "%s: %s: %s\n", myname, s, strerror(errno));
                    226:        retval = -1;
                    227: }
                    228: 
                    229: usage()
                    230: {
                    231:        (void)fprintf(stderr, "usage: %s [-Rf] %s file ...\n", myname,
                    232:            ischown ? "owner[.group]" : "group");
                    233:        exit(-1);
                    234: }

unix.superglobalmegacorp.com

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