Annotation of 42BSD/usr.bin/uucp/chkpth.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)chkpth.c   5.1 (Berkeley) 7/2/83";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Doug Kingston, 30 July 82 to fix handling of the "userpath" structures.
                      7:  * (brl-bmd) 
                      8:  * rti!trt: the code here is bizarre.  There must be a zillion holes.
                      9:  * chkpth should not be called for implied Spool requests .
                     10:  * But explicit requests (foo!/usr/spoo/uucp/*) should use chkpth.
                     11:  */
                     12: #include "uucp.h"
                     13: #include <sys/types.h>
                     14: #include <sys/stat.h>
                     15: 
                     16: 
                     17: struct userpath {
                     18:        char *us_lname;
                     19:        char *us_mname;
                     20:        char us_callback;
                     21:        char **us_path;
                     22:        struct userpath *unext;
                     23: };
                     24: struct userpath *Uhead = NULL;
                     25: struct userpath *Mchdef = NULL, *Logdef = NULL;
                     26: int Uptfirst = 1;
                     27: 
                     28: 
                     29: /*******
                     30:  *     chkpth(logname, mchname, path)
                     31:  *     char *path, *logname, *mchname;
                     32:  *
                     33:  *     chkpth  -  this routine will check the path table for the
                     34:  *     machine or log name (non-null parameter) to see if the
                     35:  *     input path (path)
                     36:  *     starts with an acceptable prefix.
                     37:  *
                     38:  *     return codes:  0  |  FAIL
                     39:  */
                     40: 
                     41: chkpth(logname, mchname, path)
                     42: char *path, *logname, *mchname;
                     43: {
                     44:        register struct userpath *u;
                     45:        extern char *lastpart();
                     46:        register char **p, *s;
                     47: 
                     48:        /* Allow only rooted pathnames.  Security wish.  rti!trt */
                     49:        if (*path != '/')
                     50:                return(FAIL);
                     51: 
                     52:        if (Uptfirst) {
                     53:                rdpth();
                     54:                ASSERT(Uhead != NULL, "INIT USERFILE, No entrys!", "", 0);
                     55:                Uptfirst = 0;
                     56:        }
                     57:        for (u = Uhead; u != NULL; ) {
                     58:                if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME)
                     59:                        break;
                     60:                if (*mchname != '\0' && strncmp(mchname, u->us_mname, 7) == SAME)
                     61:                        break;
                     62:                u = u->unext;
                     63:        }
                     64:        if (u == NULL) {
                     65:                if (*logname == '\0')
                     66:                        u = Mchdef;
                     67:                else
                     68:                        u = Logdef;
                     69:                if (u == NULL)
                     70:                        return(FAIL);
                     71:        }
                     72:        /* found user name */
                     73:        p = u->us_path;
                     74: 
                     75:        /*  check for /../ in path name  */
                     76:        for (s = path; *s != '\0'; s++) {
                     77:                if (prefix("/../",s))
                     78:                        return(FAIL);
                     79:        }
                     80: 
                     81:        /* Check for access permission */
                     82:        for (p = u->us_path; *p != NULL; p++)
                     83:                if (prefix(*p, path))
                     84:                        return(0);
                     85: 
                     86:        /* path name not valid */
                     87:        return(FAIL);
                     88: }
                     89: 
                     90: 
                     91: /***
                     92:  *     rdpth()
                     93:  *
                     94:  *     rdpth  -  this routine will read the USERFILE and
                     95:  *     construct the userpath structure pointed to by (u);
                     96:  *
                     97:  *     return codes:  0  |  FAIL
                     98:  *
                     99:  * 5/3/81 - changed to enforce the uucp-wide convention that system
                    100:  *         names be 7 chars or less in length
                    101:  */
                    102: 
                    103: rdpth()
                    104: {
                    105:        char buf[100 + 1], *pbuf[50 + 1];
                    106:        register struct userpath *u;
                    107:        register char *pc, **cp;
                    108:        FILE *uf;
                    109: 
                    110:        if ((uf = fopen(USERFILE, "r")) == NULL) {
                    111:                /* can not open file */
                    112:                return;
                    113:        }
                    114: 
                    115:        while (cfgets(buf, sizeof(buf), uf) != NULL) {
                    116:                int nargs, i;
                    117: 
                    118:                if ((u = (struct userpath *)malloc(sizeof (struct userpath))) == NULL) {
                    119:                        DEBUG (1, "*** Userpath malloc failed\n", 0);
                    120:                        fclose (uf);
                    121:                        return;
                    122:                }
                    123:                if ((pc = calloc((unsigned)strlen(buf) + 1, sizeof (char)))
                    124:                        == NULL) {
                    125:                        /* can not allocate space */
                    126:                        DEBUG (1, "Userpath calloc 1 failed\n", 0);
                    127:                        fclose(uf);
                    128:                        return;
                    129:                }
                    130: 
                    131:                strcpy(pc, buf);
                    132:                nargs = getargs(pc, pbuf);
                    133:                u->us_lname = pbuf[0];
                    134:                pc = index(u->us_lname, ',');
                    135:                if (pc != NULL)
                    136:                        *pc++ = '\0';
                    137:                else
                    138:                        pc = u->us_lname + strlen(u->us_lname);
                    139:                u->us_mname = pc;
                    140:                if (strlen(u->us_mname) > 7)
                    141:                        u->us_mname[7] = '\0';
                    142:                if (*u->us_lname == '\0' && Logdef == NULL)
                    143:                        Logdef = u;
                    144:                /* rti!trt: commented following else so
                    145:                 * chkpth("","",file) works okay.
                    146:                 * I don't understand this, though.
                    147:                 */
                    148:                /*else*/ if (*u->us_mname == '\0' && Mchdef == NULL)
                    149:                        Mchdef = u;
                    150:                i = 1;
                    151:                if (strcmp(pbuf[1], "c") == SAME) {
                    152:                        u->us_callback = 1;
                    153:                        i++;
                    154:                }
                    155:                else
                    156:                        u->us_callback = 0;
                    157:                if ((cp = u->us_path =
                    158:                  (char **)calloc((unsigned)(nargs-i+1), sizeof(char *))) == NULL) {
                    159:                        /*  can not allocate space */
                    160:                        DEBUG (1, "Userpath calloc 2 failed!\n", 0);
                    161:                        fclose(uf);
                    162:                        return;
                    163:                }
                    164: 
                    165:                while (i < nargs)
                    166:                        *cp++ = pbuf[i++];
                    167:                *cp = NULL;
                    168:                u->unext = Uhead;
                    169:                Uhead = u;
                    170:        }
                    171: 
                    172:        fclose(uf);
                    173:        return;
                    174: }
                    175: 
                    176: /***
                    177:  *     callback(name)  check for callback
                    178:  *     char *name;
                    179:  *
                    180:  *     return codes:
                    181:  *             0  -  no call back
                    182:  *             1  -  call back
                    183:  */
                    184: 
                    185: callback(name)
                    186: register char *name;
                    187: {
                    188:        register struct userpath *u;
                    189: 
                    190:        if (Uptfirst) {
                    191:                rdpth();
                    192:                ASSERT(Uhead != NULL, "INIT USERFILE, No Users!", "", 0);
                    193:                Uptfirst = 0;
                    194:        }
                    195: 
                    196:        for (u = Uhead; u != NULL; ) {
                    197:                if (strcmp(u->us_lname, name) == SAME)
                    198:                        /* found user name */
                    199:                        return(u->us_callback);
                    200:                u = u->unext;
                    201:        }
                    202: 
                    203:        /* userid not found */
                    204:        return(0);
                    205: }
                    206: 
                    207: 
                    208: /***
                    209:  *     chkperm(file, mopt)     check write permission of file
                    210:  *     char *mopt;             none NULL - create directories
                    211:  *
                    212:  *     if mopt != NULL and permissions are ok,
                    213:  *     a side effect of this routine is to make
                    214:  *     directories up to the last part of the
                    215:  *     filename (if they do not exist).
                    216:  *
                    217:  *     return 0 | FAIL
                    218:  */
                    219: 
                    220: chkperm(file, mopt)
                    221: char *file, *mopt;
                    222: {
                    223:        struct stat s;
                    224:        int ret;
                    225:        char dir[MAXFULLNAME];
                    226:        extern char *lastpart();
                    227: 
                    228:        if (stat(subfile(file), &s) == 0) {
                    229:                /* Forbid scribbling on a not-generally-writable file */
                    230:                /* rti!trt */
                    231:                if ((s.st_mode & ANYWRITE) == 0)
                    232:                        return(FAIL);
                    233:                return(0);
                    234:        }
                    235: 
                    236:        strcpy(dir, file);
                    237:        *lastpart(dir) = '\0';
                    238:        if ((ret = stat(subfile(dir), &s)) == -1
                    239:          && mopt == NULL)
                    240:                return(FAIL);
                    241: 
                    242:        if (ret != -1) {
                    243:                if ((s.st_mode & ANYWRITE) == 0)
                    244:                        return(FAIL);
                    245:                else
                    246:                        return(0);
                    247:        }
                    248: 
                    249:        /*  make directories  */
                    250:        return(mkdirs(file));
                    251: }
                    252: 
                    253: /*
                    254:  * Check for sufficient privilege to request debugging.
                    255:  * Suggested by seismo!stewart, John Stewart.
                    256:  */
                    257: chkdebug(uid)
                    258: int uid;
                    259: {
                    260:        if (uid > PRIV_UIDS) {
                    261:                fprintf(stderr, "Sorry, uid must be <= %d for debugging\n",
                    262:                        PRIV_UIDS);
                    263:                cleanup(1);
                    264:                exit(1);        /* Just in case */
                    265:        }
                    266: }

unix.superglobalmegacorp.com

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