Lines 41-49
Link Here
|
41 |
#include <sys/stat.h> |
41 |
#include <sys/stat.h> |
42 |
|
42 |
|
43 |
#include <ctype.h> |
43 |
#include <ctype.h> |
|
|
44 |
#include <errno.h> |
44 |
#include <signal.h> |
45 |
#include <signal.h> |
45 |
#include <stddef.h> |
46 |
#include <stddef.h> |
46 |
#include <stdlib.h> |
47 |
#include <stdlib.h> |
|
|
48 |
#include <limits.h> |
47 |
#include <unistd.h> |
49 |
#include <unistd.h> |
48 |
|
50 |
|
49 |
#ifdef SETMODE_DEBUG |
51 |
#ifdef SETMODE_DEBUG |
Lines 66-72
Link Here
|
66 |
#define CMD2_OBITS 0x08 |
68 |
#define CMD2_OBITS 0x08 |
67 |
#define CMD2_UBITS 0x10 |
69 |
#define CMD2_UBITS 0x10 |
68 |
|
70 |
|
69 |
static BITCMD *addcmd(BITCMD *, int, int, int, u_int); |
71 |
static BITCMD *addcmd(BITCMD *, mode_t, mode_t, mode_t, mode_t); |
70 |
static void compress_mode(BITCMD *); |
72 |
static void compress_mode(BITCMD *); |
71 |
#ifdef SETMODE_DEBUG |
73 |
#ifdef SETMODE_DEBUG |
72 |
static void dumpmode(BITCMD *); |
74 |
static void dumpmode(BITCMD *); |
Lines 151-167
Link Here
|
151 |
BITCMD *newset; \ |
153 |
BITCMD *newset; \ |
152 |
setlen += SET_LEN_INCR; \ |
154 |
setlen += SET_LEN_INCR; \ |
153 |
newset = realloc(saveset, sizeof(BITCMD) * setlen); \ |
155 |
newset = realloc(saveset, sizeof(BITCMD) * setlen); \ |
154 |
if (!newset) { \ |
156 |
if (newset == NULL) \ |
155 |
if (saveset) \ |
157 |
goto out; \ |
156 |
free(saveset); \ |
|
|
157 |
saveset = NULL; \ |
158 |
return (NULL); \ |
159 |
} \ |
160 |
set = newset + (set - saveset); \ |
158 |
set = newset + (set - saveset); \ |
161 |
saveset = newset; \ |
159 |
saveset = newset; \ |
162 |
endset = newset + (setlen - 2); \ |
160 |
endset = newset + (setlen - 2); \ |
163 |
} \ |
161 |
} \ |
164 |
set = addcmd(set, (a), (b), (c), (d)) |
162 |
set = addcmd(set, (mode_t)(a), (mode_t)(b), (mode_t)(c), (d)) |
165 |
|
163 |
|
166 |
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) |
164 |
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) |
167 |
|
165 |
|
Lines 168-180
Link Here
|
168 |
void * |
166 |
void * |
169 |
setmode(const char *p) |
167 |
setmode(const char *p) |
170 |
{ |
168 |
{ |
171 |
int perm, who; |
169 |
int serrno; |
172 |
char op, *ep; |
170 |
char op, *ep; |
173 |
BITCMD *set, *saveset, *endset; |
171 |
BITCMD *set, *saveset, *endset; |
174 |
sigset_t sigset, sigoset; |
172 |
sigset_t sigset, sigoset; |
175 |
mode_t mask; |
173 |
mode_t mask, perm, permXbits, who; |
176 |
int equalopdone=0, permXbits, setlen; |
|
|
177 |
long perml; |
174 |
long perml; |
|
|
175 |
int equalopdone = 0; /* pacify gcc */ |
176 |
int setlen; |
178 |
|
177 |
|
179 |
if (!*p) |
178 |
if (!*p) |
180 |
return (NULL); |
179 |
return (NULL); |
Lines 203-213
Link Here
|
203 |
* or illegal bits. |
202 |
* or illegal bits. |
204 |
*/ |
203 |
*/ |
205 |
if (isdigit((unsigned char)*p)) { |
204 |
if (isdigit((unsigned char)*p)) { |
|
|
205 |
errno = 0; |
206 |
perml = strtol(p, &ep, 8); |
206 |
perml = strtol(p, &ep, 8); |
207 |
if (*ep || perml < 0 || perml & ~(STANDARD_BITS|S_ISTXT)) { |
207 |
if (*ep) { |
208 |
free(saveset); |
208 |
errno = EINVAL; |
209 |
return (NULL); |
209 |
goto out; |
210 |
} |
210 |
} |
|
|
211 |
if (errno == ERANGE && (perml == LONG_MAX || perml == LONG_MIN)) |
212 |
goto out; |
213 |
if (perml & ~(STANDARD_BITS|S_ISTXT)) { |
214 |
errno = EINVAL; |
215 |
goto out; |
216 |
} |
211 |
perm = (mode_t)perml; |
217 |
perm = (mode_t)perml; |
212 |
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); |
218 |
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); |
213 |
set->cmd = 0; |
219 |
set->cmd = 0; |
Lines 240-247
Link Here
|
240 |
} |
246 |
} |
241 |
|
247 |
|
242 |
getop: if ((op = *p++) != '+' && op != '-' && op != '=') { |
248 |
getop: if ((op = *p++) != '+' && op != '-' && op != '=') { |
243 |
free(saveset); |
249 |
errno = EINVAL; |
244 |
return (NULL); |
250 |
goto out; |
245 |
} |
251 |
} |
246 |
if (op == '=') |
252 |
if (op == '=') |
247 |
equalopdone = 0; |
253 |
equalopdone = 0; |
Lines 330-339
Link Here
|
330 |
dumpmode(saveset); |
336 |
dumpmode(saveset); |
331 |
#endif |
337 |
#endif |
332 |
return (saveset); |
338 |
return (saveset); |
|
|
339 |
out: |
340 |
serrno = errno; |
341 |
free(saveset); |
342 |
errno = serrno; |
343 |
return NULL; |
333 |
} |
344 |
} |
334 |
|
345 |
|
335 |
static BITCMD * |
346 |
static BITCMD * |
336 |
addcmd(BITCMD *set, int op, int who, int oparg, u_int mask) |
347 |
addcmd(BITCMD *set, mode_t op, mode_t who, mode_t oparg, mode_t mask) |
337 |
{ |
348 |
{ |
338 |
switch (op) { |
349 |
switch (op) { |
339 |
case '=': |
350 |
case '=': |