|
|
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.