|
|
1.1 root 1: /* chmod_chk.c - check a stat structure based upon chmod style permissions.
2: * part of uucheck.
3: */
4:
5: #include <sys/stat.h>
6: #include "morestat.h" /* The stat definitions that were left out. */
7: #include "checkperms.h"
8: #include "y.tab.h"
9:
10: /* Test whether statptr->st_mode corresponds to a desired permission. */
11:
12: #define TST(mask, flag) (flag && \
13: ( (((statptr->st_mode) & mask)?TRUE:FALSE) != i_want))
14:
15: boolean
16: chmod_chk(path, ugostrwx, statptr, msg_type)
17: unsigned char *path;
18: unsigned char *ugostrwx;
19: struct stat *statptr;
20: int msg_type; /* Error messages or just warning messages? */
21: {
22: unsigned char *s; /* Handy loop variable for walking through stuff. */
23:
24: boolean user_f = FALSE;
25: boolean group_f = FALSE;
26: boolean others_f = FALSE;
27: boolean setid_f = FALSE;
28: boolean sticky_f = FALSE;
29: boolean read_f = FALSE;
30: boolean write_f = FALSE;
31: boolean execute_f = FALSE;
32: boolean i_want; /* Do we want these permissions, or not? */
33: boolean error = FALSE;
34: boolean warning = FALSE;
35:
36: /* fill in statptr if it isn't already */
37: if (statptr == (struct stat *) NULL) {
38: statptr = (struct stat *) malloc(sizeof(struct stat));
39: stat(path, statptr);
40: }
41:
42: /* Pick off user, group, and other. */
43: for(s = ugostrwx; (*s != '+') && (*s != '-') && (*s != (unsigned char) NULL); ++s) {
44: switch(*s) {
45: case 'u': user_f = TRUE; break;
46: case 'g': group_f = TRUE; break;
47: case 'o': others_f = TRUE; break;
48: default:
49: VERBOSE("(POOrly Formed Formula) ugo\n");
50: FATAL("Who POOFF: %s\n", ugostrwx);
51: } /* switch(*s) */
52: #if 0
53: /* DEBUG */ fprintf(stderr, "who: %c\n",*s);
54: #endif /* 0 */
55: } /* for s = ugostrwx to '+' */
56:
57: /* We should not have hit end of string yet! */
58: if (*s == (char) NULL) {
59: VERBOSE("(POOrly Formed Formula)\n");
60: FATAL("No '+' or '-' POOFF: %s\n", ugostrwx);
61: } /* if *s == (char) NULL */
62:
63: /* Do we want these permissions, or do we want them not? */
64: if (*s == '+') {
65: i_want = TRUE;
66: } else {
67: i_want = FALSE;
68: }
69:
70: ++s; /* Skip past the '+' or '-'. */
71:
72: /* Pick off setid, sticky, read, write, and execute. */
73: for(; (*s != '+') && (*s != (char) NULL); ++s) {
74: switch(*s) {
75: case 's': setid_f = TRUE; break;
76: case 't': sticky_f = TRUE; break;
77: case 'r': read_f = TRUE; break;
78: case 'w': write_f = TRUE; break;
79: case 'x': execute_f = TRUE; break;
80: default:
81: VERBOSE("(POOrly Formed Formula) strwx\n");
82: FATAL("What POOFF: %s\n", ugostrwx);
83: } /* switch(*s) */
84: #if 0
85: /* DEBUG */ fprintf(stderr, "what: %c\n",*s);
86: #endif /* 0 */
87: } /* for s = ugostrwx to '+' */
88:
89: /* CHECKPOINT - Now all flags are set according to the characters
90: * in the chmod permissions string.
91: */
92:
93: /* I don't see a good way to do the following without making this
94: * table flavored code. Perhaps this code should be automaticly
95: * generated from some table.
96: */
97: if (user_f){
98: if (TST(S_ISVTX, sticky_f)) {
99: sprintf(bigbuf, "%s is %ssticky.",
100: path, i_want?"not ":"");
101: notice(msg_type, bigbuf, NULL);
102: SETFAIL;
103: sprintf(command, "chmod %ct %s",
104: i_want?'+':'-', path);
105: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
106: VERBOSE(bigbuf);
107: FIX(system(command););
108: } /* if setid_f */
109: if (TST(S_IREAD, read_f)) {
110: sprintf(bigbuf, "%s is %sowner readable.",
111: path, i_want?"not ":"");
112: notice(msg_type, bigbuf, NULL);
113: SETFAIL;
114: sprintf(command, "chmod u%cr %s",
115: i_want?'+':'-', path);
116: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
117: VERBOSE(bigbuf);
118: FIX(system(command););
119: } /* if read_f */
120: if (TST(S_IWRITE, write_f)) {
121: sprintf(bigbuf, "%s is %sowner writable.",
122: path, i_want?"not ":"");
123: notice(msg_type, bigbuf, NULL);
124: SETFAIL;
125: sprintf(command, "chmod u%cw %s",
126: i_want?'+':'-', path);
127: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
128: VERBOSE(bigbuf);
129: FIX(system(command););
130: } /* if write_f */
131: if (TST(S_IEXEC, execute_f)) {
132: sprintf(bigbuf, "%s is %sowner executable.",
133: path, i_want?"not ":"");
134: notice(msg_type, bigbuf, NULL);
135: SETFAIL;
136: sprintf(command, "chmod u%cx %s",
137: i_want?'+':'-', path);
138: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
139: VERBOSE(bigbuf);
140: FIX(system(command););
141: } /* if execute_f */
142: /* Setuid must come last, or it will be lost. */
143: if (TST(S_ISUID, setid_f)) {
144: sprintf(bigbuf, "%s is %ssetuid.",
145: path, i_want?"not ":"");
146: notice(msg_type, bigbuf, NULL);
147: SETFAIL;
148: sprintf(command, "chmod u%cs %s",
149: i_want?'+':'-', path);
150: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
151: VERBOSE(bigbuf);
152: FIX(system(command););
153: } /* if setid_f */
154: } /* if user_f */
155:
156: if (group_f){
157: if (TST(S_ISVTX, sticky_f)) {
158: sprintf(bigbuf, "%s is %ssticky.",
159: path, i_want?"not ":"");
160: notice(msg_type, bigbuf, NULL);
161: SETFAIL;
162: sprintf(command, "chmod %ct %s",
163: i_want?'+':'-', path);
164: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
165: VERBOSE(bigbuf);
166: FIX(system(command););
167: } /* if setid_f */
168: if (TST(S_IGREAD, read_f)) {
169: sprintf(bigbuf, "%s is %sgroup readable.",
170: path, i_want?"not ":"");
171: notice(msg_type, bigbuf, NULL);
172: SETFAIL;
173: sprintf(command, "chmod g%cr %s",
174: i_want?'+':'-', path);
175: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
176: VERBOSE(bigbuf);
177: FIX(system(command););
178: } /* if read_f */
179: if (TST(S_IGWRITE, write_f)) {
180: sprintf(bigbuf, "%s is %sgroup writable.",
181: path, i_want?"not ":"");
182: notice(msg_type, bigbuf, NULL);
183: SETFAIL;
184: sprintf(command, "chmod g%cw %s",
185: i_want?'+':'-', path);
186: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
187: VERBOSE(bigbuf);
188: FIX(system(command););
189: } /* if write_f */
190: if (TST(S_IGEXEC, execute_f)) {
191: sprintf(bigbuf, "%s is %sgroup executable.",
192: path, i_want?"not ":"");
193: notice(msg_type, bigbuf, NULL);
194: SETFAIL;
195: sprintf(command, "chmod g%cx %s",
196: i_want?'+':'-', path);
197: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
198: VERBOSE(bigbuf);
199: FIX(system(command););
200: } /* if execute_f */
201: if (TST(S_ISGID, setid_f)) {
202: sprintf(bigbuf, "%s is %ssetgid.",
203: path, i_want?"not ":"");
204: notice(msg_type, bigbuf, NULL);
205: SETFAIL;
206: sprintf(command, "chmod g%cs %s",
207: i_want?'+':'-', path);
208: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
209: VERBOSE(bigbuf);
210: FIX(system(command););
211: } /* if setid_f */
212: } /* if group_f */
213:
214: if (others_f){
215: if (TST(S_ISVTX, sticky_f)) {
216: sprintf(bigbuf, "%s is %ssticky.",
217: path, i_want?"not ":"");
218: notice(msg_type, bigbuf, NULL);
219: SETFAIL;
220: sprintf(command, "chmod %ct %s",
221: i_want?'+':'-', path);
222: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
223: VERBOSE(bigbuf);
224: FIX(system(command););
225: } /* if setid_f */
226: if (TST(S_IOREAD, read_f)) {
227: sprintf(bigbuf, "%s is %spublicly readable.",
228: path, i_want?"not ":"");
229: notice(msg_type, bigbuf, NULL);
230: SETFAIL;
231: sprintf(command, "chmod o%cr %s",
232: i_want?'+':'-', path);
233: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
234: VERBOSE(bigbuf);
235: FIX(system(command););
236: } /* if read_f */
237: if (TST(S_IOWRITE, write_f)) {
238: sprintf(bigbuf, "%s is %spublicly writable.",
239: path, i_want?"not ":"");
240: notice(msg_type, bigbuf, NULL);
241: SETFAIL;
242: sprintf(command, "chmod o%cw %s",
243: i_want?'+':'-', path);
244: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
245: VERBOSE(bigbuf);
246: FIX(system(command););
247: } /* if write_f */
248: if (TST(S_IOEXEC, execute_f)) {
249: sprintf(bigbuf, "%s is %spublicly executable.",
250: path, i_want?"not ":"");
251: notice(msg_type, bigbuf, NULL);
252: SETFAIL;
253: sprintf(command, "chmod o%cx %s",
254: i_want?'+':'-', path);
255: sprintf(bigbuf, "Use \"%s\" to fix this.\n", command);
256: VERBOSE(bigbuf);
257: FIX(system(command););
258: } /* if execute_f */
259: } /* if other_f */
260:
261: if (error || warning) {
262: return(FALSE);
263: } else {
264: return(TRUE);
265: } /* if error || warning */
266: } /* chmod_chk() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.