|
|
1.1 ! root 1: #include <ctype.h> ! 2: #include <stddef.h> ! 3: #include <stdlib.h> ! 4: #include <stdio.h> ! 5: #include <string.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: #include <fcntl.h> ! 9: #include <unistd.h> ! 10: #include "../pkg/ar.h" ! 11: #include "dist.h" ! 12: ! 13: /* determine if we can create the given pathname. not a generally useful ! 14: function since it destroys the pathname in the process... */ ! 15: static int ! 16: cancreate(char *path, int recurse) ! 17: { ! 18: char *slash; ! 19: ! 20: for (;;) { ! 21: slash = strrchr(path, '/'); ! 22: if (! slash) ! 23: return 0; /* supposed to be absolute */ ! 24: *slash = '\0'; ! 25: if (!*path) ! 26: break; ! 27: if (access(path, W_OK) == 0) ! 28: return 1; ! 29: if (!recurse) /* for remove we check only one directory */ ! 30: return 0; ! 31: if (access(path, F_OK) == 0) ! 32: return 0; ! 33: } ! 34: return access("/", W_OK) == 0; ! 35: } ! 36: ! 37: /* ! 38: * try the instructions of the package on the given fd against the ! 39: * permissions currently in the file system. return 1 if we think we ! 40: * ought to go ahead and try inspkg. ! 41: */ ! 42: int ! 43: tryperm(int fd) ! 44: { ! 45: char armag[SARMAG]; ! 46: struct ar_hdr arhdr; ! 47: long size; ! 48: char temp[L_tmpnam]; ! 49: int tfd; ! 50: FILE *tfp; ! 51: int cmd, c, nf, retval; ! 52: char *path; ! 53: ! 54: /* return 1 so inspkg will be called and barf for us */ ! 55: if (read(fd, armag, sizeof armag) != SARMAG || strncmp(armag, ARMAG, SARMAG)) ! 56: return 1; ! 57: if (read(fd, (char *) &arhdr, sizeof arhdr) != sizeof arhdr) ! 58: return 1; ! 59: size = strtol(arhdr.ar_size, 0, 10); ! 60: tmpnam(temp); ! 61: close(creat(temp, 0600)); /* ape deficiency */ ! 62: tfd = open(temp, O_RDWR); ! 63: if (tfd < 0) { ! 64: eprintf("can't create temp file %s for tryperm", temp); ! 65: remove(temp); /* just in case something's *real* weird */ ! 66: exit(1); ! 67: } ! 68: if (fdcopy(tfd, fd, size, 0) != size) { ! 69: close(tfd); ! 70: remove(temp); ! 71: eprintf("can't extract Instructions in tryperm"); ! 72: return 1; /* inspkg will (presumably) barf for us */ ! 73: } ! 74: lseek(tfd, 0L, 0); ! 75: tfp = fdopen(tfd, "r"); ! 76: ! 77: /* now that we have the instructions file, do the real meat. */ ! 78: retval = 1; ! 79: while ((cmd = getc(tfp)) != EOF) { ! 80: switch (cmd) { ! 81: case 'b': /* b <mode> <dmaj> <dmin> <uid> <gid> <path> */ ! 82: case 'c': /* c <mode> <dmaj> <dmin> <uid> <gid> <path> */ ! 83: nf = 6; ! 84: break; ! 85: case 'd': /* d <mode> <uid> <gid> <path> */ ! 86: case 'f': /* f <component> <uid> <gid> <path> */ ! 87: nf = 4; ! 88: break; ! 89: case 'l': /* l <path1> <path2> */ ! 90: case 's': /* s <path1> <path2> */ ! 91: nf = 2; ! 92: break; ! 93: case 'r': /* r <path> */ ! 94: case 'x': /* x <command> */ ! 95: case 'X': /* X <path> */ ! 96: nf = 1; ! 97: break; ! 98: default: ! 99: goto reterr; ! 100: } ! 101: ! 102: /* get the last field of the line */ ! 103: while (nf--) { ! 104: while ((c = getc(tfp)) != EOF) ! 105: if (!isspace(c)) ! 106: break; ! 107: if (c == EOF) ! 108: goto reterr; ! 109: ungetc(c, tfp); ! 110: path = getpath(tfp); ! 111: } ! 112: ! 113: /* eat the newline */ ! 114: if (getc(tfp) != '\n') ! 115: goto reterr; ! 116: ! 117: switch (cmd) { ! 118: case 'X': ! 119: case 'x': ! 120: break; ! 121: ! 122: case 'r': ! 123: if (access(path, F_OK) != 0) ! 124: break; ! 125: if (cancreate(path, 0)) ! 126: break; ! 127: retval = 0; ! 128: goto out; ! 129: ! 130: default: ! 131: if (cancreate(path, 1)) ! 132: break; ! 133: retval = 0; ! 134: goto out; ! 135: } ! 136: } ! 137: ! 138: out: ! 139: fclose(tfp); ! 140: remove(temp); ! 141: return retval; ! 142: ! 143: reterr: ! 144: /* there was some kind of bug in the format of the package. return 1 ! 145: and later on inspkg will generate an appropriate error message to ! 146: be returned to the remote system */ ! 147: fclose(tfp); ! 148: remove(temp); ! 149: return 1; ! 150: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.