diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-05-26 14:09:12 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-05-26 14:09:12 +0000 |
commit | 2faee7b1ed84698ae057ac44bdb0a9f686dd945f (patch) | |
tree | ad3fc9e4a42c42c2c895767fd6c025df789aac6b | |
parent | 393183dccc4d100366972bdbbdc6e03a77839120 (diff) | |
download | busybox-w32-2faee7b1ed84698ae057ac44bdb0a9f686dd945f.tar.gz busybox-w32-2faee7b1ed84698ae057ac44bdb0a9f686dd945f.tar.bz2 busybox-w32-2faee7b1ed84698ae057ac44bdb0a9f686dd945f.zip |
Vodz, last_path_87, formatiing changes
-rw-r--r-- | applets/applets.c | 581 |
1 files changed, 306 insertions, 275 deletions
diff --git a/applets/applets.c b/applets/applets.c index 1b69ade92..4af569de3 100644 --- a/applets/applets.c +++ b/applets/applets.c | |||
@@ -20,7 +20,7 @@ | |||
20 | * along with this program; if not, write to the Free Software | 20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | * | 22 | * |
23 | * Based in part on code from sash, Copyright (c) 1999 by David I. Bell | 23 | * Based in part on code from sash, Copyright (c) 1999 by David I. Bell |
24 | * Permission has been granted to redistribute this code under the GPL. | 24 | * Permission has been granted to redistribute this code under the GPL. |
25 | * | 25 | * |
26 | */ | 26 | */ |
@@ -44,7 +44,7 @@ const size_t NUM_APPLETS = (sizeof (applets) / sizeof (struct BB_applet) - 1); | |||
44 | 44 | ||
45 | #ifdef CONFIG_FEATURE_SUID | 45 | #ifdef CONFIG_FEATURE_SUID |
46 | 46 | ||
47 | static void check_suid ( struct BB_applet *app ); | 47 | static void check_suid (struct BB_applet *app); |
48 | 48 | ||
49 | #ifdef CONFIG_FEATURE_SUID_CONFIG | 49 | #ifdef CONFIG_FEATURE_SUID_CONFIG |
50 | 50 | ||
@@ -53,21 +53,22 @@ static void check_suid ( struct BB_applet *app ); | |||
53 | #include "pwd_.h" | 53 | #include "pwd_.h" |
54 | #include "grp_.h" | 54 | #include "grp_.h" |
55 | 55 | ||
56 | static int parse_config_file ( void ); | 56 | static int parse_config_file (void); |
57 | 57 | ||
58 | static int config_ok; | 58 | static int config_ok; |
59 | 59 | ||
60 | #define CONFIG_FILE "/etc/busybox.conf" | 60 | #define CONFIG_FILE "/etc/busybox.conf" |
61 | 61 | ||
62 | /* applets [] is const, so we have to define this "override" structure */ | 62 | /* applets [] is const, so we have to define this "override" structure */ |
63 | struct BB_suid_config { | 63 | struct BB_suid_config |
64 | struct BB_applet *m_applet; | 64 | { |
65 | struct BB_applet *m_applet; | ||
65 | 66 | ||
66 | uid_t m_uid; | 67 | uid_t m_uid; |
67 | gid_t m_gid; | 68 | gid_t m_gid; |
68 | mode_t m_mode; | 69 | mode_t m_mode; |
69 | 70 | ||
70 | struct BB_suid_config *m_next; | 71 | struct BB_suid_config *m_next; |
71 | }; | 72 | }; |
72 | 73 | ||
73 | static struct BB_suid_config *suid_config; | 74 | static struct BB_suid_config *suid_config; |
@@ -78,79 +79,84 @@ static struct BB_suid_config *suid_config; | |||
78 | 79 | ||
79 | 80 | ||
80 | 81 | ||
81 | extern void bb_show_usage(void) | 82 | extern void |
83 | bb_show_usage (void) | ||
82 | { | 84 | { |
83 | const char *format_string; | 85 | const char *format_string; |
84 | const char *usage_string = usage_messages; | 86 | const char *usage_string = usage_messages; |
85 | int i; | 87 | int i; |
86 | 88 | ||
87 | for (i = applet_using - applets; i > 0; ) { | 89 | for (i = applet_using - applets; i > 0;) { |
88 | if (!*usage_string++) { | 90 | if (!*usage_string++) { |
89 | --i; | 91 | --i; |
90 | } | ||
91 | } | 92 | } |
93 | } | ||
92 | 94 | ||
93 | format_string = "%s\n\nUsage: %s %s\n\n"; | 95 | format_string = "%s\n\nUsage: %s %s\n\n"; |
94 | if(*usage_string == '\b') | 96 | if (*usage_string == '\b') |
95 | format_string = "%s\n\nNo help available.\n\n"; | 97 | format_string = "%s\n\nNo help available.\n\n"; |
96 | fprintf(stderr, format_string, bb_msg_full_version, applet_using->name, usage_string); | 98 | fprintf (stderr, format_string, bb_msg_full_version, applet_using->name, |
99 | usage_string); | ||
97 | 100 | ||
98 | exit(EXIT_FAILURE); | 101 | exit (EXIT_FAILURE); |
99 | } | 102 | } |
100 | 103 | ||
101 | static int applet_name_compare(const void *x, const void *y) | 104 | static int |
105 | applet_name_compare (const void *x, const void *y) | ||
102 | { | 106 | { |
103 | const char *name = x; | 107 | const char *name = x; |
104 | const struct BB_applet *applet = y; | 108 | const struct BB_applet *applet = y; |
105 | 109 | ||
106 | return strcmp(name, applet->name); | 110 | return strcmp (name, applet->name); |
107 | } | 111 | } |
108 | 112 | ||
109 | extern const size_t NUM_APPLETS; | 113 | extern const size_t NUM_APPLETS; |
110 | 114 | ||
111 | struct BB_applet *find_applet_by_name(const char *name) | 115 | struct BB_applet * |
116 | find_applet_by_name (const char *name) | ||
112 | { | 117 | { |
113 | return bsearch(name, applets, NUM_APPLETS, sizeof(struct BB_applet), | 118 | return bsearch (name, applets, NUM_APPLETS, sizeof (struct BB_applet), |
114 | applet_name_compare); | 119 | applet_name_compare); |
115 | } | 120 | } |
116 | 121 | ||
117 | void run_applet_by_name(const char *name, int argc, char **argv) | 122 | void |
123 | run_applet_by_name (const char *name, int argc, char **argv) | ||
118 | { | 124 | { |
119 | static int recurse_level = 0; | 125 | static int recurse_level = 0; |
120 | extern int been_there_done_that; /* From busybox.c */ | 126 | extern int been_there_done_that; /* From busybox.c */ |
121 | 127 | ||
122 | #ifdef CONFIG_FEATURE_SUID_CONFIG | 128 | #ifdef CONFIG_FEATURE_SUID_CONFIG |
123 | if ( recurse_level == 0 ) | 129 | if (recurse_level == 0) |
124 | config_ok = parse_config_file ( ); | 130 | config_ok = parse_config_file (); |
125 | #endif | 131 | #endif |
126 | 132 | ||
127 | recurse_level++; | 133 | recurse_level++; |
128 | /* Do a binary search to find the applet entry given the name. */ | 134 | /* Do a binary search to find the applet entry given the name. */ |
129 | if ((applet_using = find_applet_by_name(name)) != NULL) { | 135 | if ((applet_using = find_applet_by_name (name)) != NULL) { |
130 | bb_applet_name = applet_using->name; | 136 | bb_applet_name = applet_using->name; |
131 | if (argv[1] && strcmp(argv[1], "--help") == 0) { | 137 | if (argv[1] && strcmp (argv[1], "--help") == 0) { |
132 | if (strcmp(applet_using->name, "busybox")==0) { | 138 | if (strcmp (applet_using->name, "busybox") == 0) { |
133 | if(argv[2]) | 139 | if (argv[2]) |
134 | applet_using = find_applet_by_name(argv[2]); | 140 | applet_using = find_applet_by_name (argv[2]); |
135 | else | 141 | else |
136 | applet_using = NULL; | 142 | applet_using = NULL; |
137 | } | 143 | } |
138 | if(applet_using) | 144 | if (applet_using) |
139 | bb_show_usage(); | 145 | bb_show_usage (); |
140 | been_there_done_that=1; | 146 | been_there_done_that = 1; |
141 | busybox_main(0, NULL); | 147 | busybox_main (0, NULL); |
142 | } | 148 | } |
143 | #ifdef CONFIG_FEATURE_SUID | 149 | #ifdef CONFIG_FEATURE_SUID |
144 | check_suid ( applet_using ); | 150 | check_suid (applet_using); |
145 | #endif | 151 | #endif |
146 | 152 | ||
147 | exit((*(applet_using->main)) (argc, argv)); | 153 | exit ((*(applet_using->main)) (argc, argv)); |
148 | } | 154 | } |
149 | /* Just in case they have renamed busybox - Check argv[1] */ | 155 | /* Just in case they have renamed busybox - Check argv[1] */ |
150 | if (recurse_level == 1) { | 156 | if (recurse_level == 1) { |
151 | run_applet_by_name("busybox", argc, argv); | 157 | run_applet_by_name ("busybox", argc, argv); |
152 | } | 158 | } |
153 | recurse_level--; | 159 | recurse_level--; |
154 | } | 160 | } |
155 | 161 | ||
156 | 162 | ||
@@ -159,254 +165,279 @@ void run_applet_by_name(const char *name, int argc, char **argv) | |||
159 | #ifdef CONFIG_FEATURE_SUID_CONFIG | 165 | #ifdef CONFIG_FEATURE_SUID_CONFIG |
160 | 166 | ||
161 | /* check if u is member of group g */ | 167 | /* check if u is member of group g */ |
162 | static int ingroup ( uid_t u, gid_t g ) | 168 | static int |
169 | ingroup (uid_t u, gid_t g) | ||
163 | { | 170 | { |
164 | struct group *grp = getgrgid ( g ); | 171 | struct group *grp = getgrgid (g); |
165 | 172 | ||
166 | if ( grp ) { | 173 | if (grp) { |
167 | char **mem; | 174 | char **mem; |
168 | 175 | ||
169 | for ( mem = grp-> gr_mem; *mem; mem++ ) { | 176 | for (mem = grp->gr_mem; *mem; mem++) { |
170 | struct passwd *pwd = getpwnam ( *mem ); | 177 | struct passwd *pwd = getpwnam (*mem); |
171 | 178 | ||
172 | if ( pwd && ( pwd-> pw_uid == u )) | 179 | if (pwd && (pwd->pw_uid == u)) |
173 | return 1; | 180 | return 1; |
174 | } | ||
175 | } | 181 | } |
176 | return 0; | 182 | } |
183 | return 0; | ||
177 | } | 184 | } |
178 | 185 | ||
179 | #endif | 186 | #endif |
180 | 187 | ||
181 | 188 | ||
182 | void check_suid ( struct BB_applet *applet ) | 189 | void |
190 | check_suid (struct BB_applet *applet) | ||
183 | { | 191 | { |
184 | uid_t ruid = getuid ( ); /* real [ug]id */ | 192 | uid_t ruid = getuid (); /* real [ug]id */ |
185 | uid_t rgid = getgid ( ); | 193 | uid_t rgid = getgid (); |
186 | 194 | ||
187 | #ifdef CONFIG_FEATURE_SUID_CONFIG | 195 | #ifdef CONFIG_FEATURE_SUID_CONFIG |
188 | if ( config_ok ) { | 196 | if (config_ok) { |
189 | struct BB_suid_config *sct; | 197 | struct BB_suid_config *sct; |
190 | |||
191 | for ( sct = suid_config; sct; sct = sct-> m_next ) { | ||
192 | if ( sct-> m_applet == applet ) | ||
193 | break; | ||
194 | } | ||
195 | if ( sct ) { | ||
196 | mode_t m = sct-> m_mode; | ||
197 | |||
198 | if ( sct-> m_uid == ruid ) /* same uid */ | ||
199 | m >>= 6; | ||
200 | else if (( sct-> m_gid == rgid ) || ingroup ( ruid, sct-> m_gid )) /* same group / in group */ | ||
201 | m >>= 3; | ||
202 | |||
203 | if (!( m & S_IXOTH )) /* is x bit not set ? */ | ||
204 | bb_error_msg_and_die ( "You have no permission to run this applet!" ); | ||
205 | 198 | ||
206 | if (( sct-> m_mode & ( S_ISGID | S_IXGRP )) == ( S_ISGID | S_IXGRP )) { /* *both* have to be set for sgid */ | 199 | for (sct = suid_config; sct; sct = sct->m_next) { |
207 | if ( setegid ( sct-> m_gid )) | 200 | if (sct->m_applet == applet) |
208 | bb_error_msg_and_die ( "BusyBox binary has insufficient rights to set proper GID for applet!" ); | 201 | break; |
209 | } | ||
210 | else | ||
211 | setgid ( rgid ); /* no sgid -> drop */ | ||
212 | |||
213 | if ( sct-> m_mode & S_ISUID ) { | ||
214 | if ( seteuid ( sct-> m_uid )) | ||
215 | bb_error_msg_and_die ( "BusyBox binary has insufficient rights to set proper UID for applet!" ); | ||
216 | } | ||
217 | else | ||
218 | setuid ( ruid ); /* no suid -> drop */ | ||
219 | } | ||
220 | else { /* default: drop all priviledges */ | ||
221 | setgid ( rgid ); | ||
222 | setuid ( ruid ); | ||
223 | } | ||
224 | return; | ||
225 | } | 202 | } |
226 | else { | 203 | if (sct) { |
227 | #ifndef CONFIG_FEATURE_SUID_CONFIG_QUIET | 204 | mode_t m = sct->m_mode; |
228 | static int onetime = 0; | 205 | |
229 | 206 | if (sct->m_uid == ruid) /* same uid */ | |
230 | if ( !onetime ) { | 207 | m >>= 6; |
231 | onetime = 1; | 208 | else if ((sct->m_gid == rgid) || ingroup (ruid, sct->m_gid)) /* same group / in group */ |
232 | fprintf ( stderr, "Using fallback suid method\n" ); | 209 | m >>= 3; |
233 | } | 210 | |
234 | #endif | 211 | if (!(m & S_IXOTH)) /* is x bit not set ? */ |
212 | bb_error_msg_and_die ("You have no permission to run this applet!"); | ||
213 | |||
214 | if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { /* *both* have to be set for sgid */ | ||
215 | if (setegid (sct->m_gid)) | ||
216 | bb_error_msg_and_die | ||
217 | ("BusyBox binary has insufficient rights to set proper GID for applet!"); | ||
218 | } else | ||
219 | setgid (rgid); /* no sgid -> drop */ | ||
220 | |||
221 | if (sct->m_mode & S_ISUID) { | ||
222 | if (seteuid (sct->m_uid)) | ||
223 | bb_error_msg_and_die | ||
224 | ("BusyBox binary has insufficient rights to set proper UID for applet!"); | ||
225 | } else | ||
226 | setuid (ruid); /* no suid -> drop */ | ||
227 | } else { | ||
228 | /* default: drop all priviledges */ | ||
229 | setgid (rgid); | ||
230 | setuid (ruid); | ||
231 | } | ||
232 | return; | ||
233 | } else { | ||
234 | #ifndef CONFIG_FEATURE_SUID_CONFIG_QUIET | ||
235 | static int onetime = 0; | ||
236 | |||
237 | if (!onetime) { | ||
238 | onetime = 1; | ||
239 | fprintf (stderr, "Using fallback suid method\n"); | ||
235 | } | 240 | } |
236 | #endif | 241 | #endif |
242 | } | ||
243 | #endif | ||
237 | 244 | ||
238 | if ( applet-> need_suid == _BB_SUID_ALWAYS ) { | 245 | if (applet->need_suid == _BB_SUID_ALWAYS) { |
239 | if ( geteuid ( ) != 0 ) | 246 | if (geteuid () != 0) |
240 | bb_error_msg_and_die ( "This applet requires root priviledges!" ); | 247 | bb_error_msg_and_die ("This applet requires root priviledges!"); |
241 | } | 248 | } else if (applet->need_suid == _BB_SUID_NEVER) { |
242 | else if ( applet-> need_suid == _BB_SUID_NEVER ) { | 249 | setgid (rgid); /* drop all priviledges */ |
243 | setgid ( rgid ); /* drop all priviledges */ | 250 | setuid (ruid); |
244 | setuid ( ruid ); | 251 | } |
245 | } | ||
246 | } | 252 | } |
247 | 253 | ||
248 | #ifdef CONFIG_FEATURE_SUID_CONFIG | 254 | #ifdef CONFIG_FEATURE_SUID_CONFIG |
249 | 255 | ||
250 | 256 | ||
251 | #define parse_error(x) { err=x; goto pe_label; } | 257 | #define parse_error(x) { err=x; goto pe_label; } |
252 | 258 | ||
253 | 259 | ||
254 | int parse_config_file ( void ) | 260 | int |
261 | parse_config_file (void) | ||
255 | { | 262 | { |
256 | struct stat st; | 263 | struct stat st; |
257 | char *err = 0; | 264 | char *err = 0; |
258 | FILE *f = 0; | 265 | FILE *f = 0; |
259 | int lc = 0; | 266 | int lc = 0; |
260 | 267 | ||
261 | suid_config = 0; | 268 | suid_config = 0; |
262 | 269 | ||
263 | /* is there a config file ? */ | 270 | /* is there a config file ? */ |
264 | if ( stat ( CONFIG_FILE, &st ) == 0 ) { | 271 | if (stat (CONFIG_FILE, &st) == 0) { |
265 | /* is it owned by root with no write perm. for group and others ? */ | 272 | /* is it owned by root with no write perm. for group and others ? */ |
266 | if ( S_ISREG( st. st_mode ) && ( st. st_uid == 0 ) && (!( st. st_mode & ( S_IWGRP | S_IWOTH )))) { | 273 | if (S_ISREG (st.st_mode) && (st.st_uid == 0) |
267 | /* that's ok .. then try to open it */ | 274 | && (!(st.st_mode & (S_IWGRP | S_IWOTH)))) { |
268 | f = fopen ( CONFIG_FILE, "r" ); | 275 | /* that's ok .. then try to open it */ |
269 | 276 | f = fopen (CONFIG_FILE, "r"); | |
270 | if ( f ) { | 277 | |
271 | char buffer [256]; | 278 | if (f) { |
272 | int section = 0; | 279 | char buffer[256]; |
273 | 280 | int section = 0; | |
274 | while ( fgets ( buffer, sizeof( buffer ) - 1, f )) { | 281 | |
275 | char c = buffer [0]; | 282 | while (fgets (buffer, sizeof (buffer) - 1, f)) { |
276 | char *p; | 283 | char c = buffer[0]; |
277 | 284 | char *p; | |
278 | lc++; | 285 | |
279 | 286 | lc++; | |
280 | p = strchr ( buffer, '#' ); | 287 | |
281 | if ( p ) | 288 | p = strchr (buffer, '#'); |
282 | *p = 0; | 289 | if (p) |
283 | p = buffer + bb_strlen ( buffer ); | 290 | *p = 0; |
284 | while (( p > buffer ) && isspace ( *--p )) | 291 | p = buffer + bb_strlen (buffer); |
285 | *p = 0; | 292 | while ((p > buffer) && isspace (*--p)) |
286 | 293 | *p = 0; | |
287 | if ( p == buffer ) | 294 | |
288 | continue; | 295 | if (p == buffer) |
289 | 296 | continue; | |
290 | if ( c == '[' ) { | 297 | |
291 | p = strchr ( buffer, ']' ); | 298 | if (c == '[') { |
292 | 299 | p = strchr (buffer, ']'); | |
293 | if ( !p || ( p == ( buffer + 1 ))) /* no matching ] or empty [] */ | 300 | |
294 | parse_error ( "malformed section header" ); | 301 | if (!p || (p == (buffer + 1))) /* no matching ] or empty [] */ |
295 | 302 | parse_error ("malformed section header"); | |
296 | *p = 0; | 303 | |
297 | 304 | *p = 0; | |
298 | if ( strcasecmp ( buffer + 1, "SUID" ) == 0 ) | 305 | |
299 | section = 1; | 306 | if (strcasecmp (buffer + 1, "SUID") == 0) |
300 | else | 307 | section = 1; |
301 | section = -1; /* unknown section - just skip */ | 308 | else |
302 | } | 309 | section = -1; /* unknown section - just skip */ |
303 | else if ( section ) { | 310 | } else if (section) { |
304 | switch ( section ) { | 311 | switch (section) { |
305 | case 1: { /* SUID */ | 312 | case 1:{ /* SUID */ |
306 | int l; | 313 | int l; |
307 | struct BB_applet *applet; | 314 | struct BB_applet *applet; |
308 | 315 | ||
309 | p = strchr ( buffer, '=' ); /* <key>[::space::]*=[::space::]*<value> */ | 316 | p = strchr (buffer, '='); /* <key>[::space::]*=[::space::]*<value> */ |
310 | 317 | ||
311 | if ( !p || ( p == ( buffer + 1 ))) /* no = or key is empty */ | 318 | if (!p || (p == (buffer + 1))) /* no = or key is empty */ |
312 | parse_error ( "malformed keyword" ); | 319 | parse_error ("malformed keyword"); |
313 | 320 | ||
314 | l = p - buffer; | 321 | l = p - buffer; |
315 | while ( isspace ( buffer [--l] )) { } /* skip whitespace */ | 322 | while (isspace (buffer[--l])) { |
316 | 323 | /* skip whitespace */ | |
317 | buffer [l+1] = 0; | 324 | } |
318 | 325 | ||
319 | if (( applet = find_applet_by_name ( buffer ))) { | 326 | buffer[l + 1] = 0; |
320 | struct BB_suid_config *sct = xmalloc ( sizeof( struct BB_suid_config )); | 327 | |
321 | 328 | if ((applet = find_applet_by_name (buffer))) { | |
322 | sct-> m_applet = applet; | 329 | struct BB_suid_config *sct = |
323 | sct-> m_next = suid_config; | 330 | xmalloc (sizeof (struct BB_suid_config)); |
324 | suid_config = sct; | 331 | |
325 | 332 | sct->m_applet = applet; | |
326 | while ( isspace ( *++p )) { } /* skip whitespace */ | 333 | sct->m_next = suid_config; |
327 | 334 | suid_config = sct; | |
328 | sct-> m_mode = 0; | 335 | |
329 | 336 | while (isspace (*++p)) { | |
330 | switch ( *p++ ) { | 337 | /* skip whitespace */ |
331 | case 'S': sct-> m_mode |= S_ISUID; break; | 338 | } |
332 | case 's': sct-> m_mode |= S_ISUID; /* no break */ | 339 | |
333 | case 'x': sct-> m_mode |= S_IXUSR; break; | 340 | sct->m_mode = 0; |
334 | case '-': break; | 341 | |
335 | default : parse_error ( "invalid user mode" ); | 342 | switch (*p++) { |
336 | } | 343 | case 'S': |
337 | 344 | sct->m_mode |= S_ISUID; | |
338 | switch ( *p++ ) { | 345 | break; |
339 | case 's': sct-> m_mode |= S_ISGID; /* no break */ | 346 | case 's': |
340 | case 'x': sct-> m_mode |= S_IXGRP; break; | 347 | sct->m_mode |= S_ISUID; |
341 | case 'S': break; | 348 | /* no break */ |
342 | case '-': break; | 349 | case 'x': |
343 | default : parse_error ( "invalid group mode" ); | 350 | sct->m_mode |= S_IXUSR; |
344 | } | 351 | break; |
345 | 352 | case '-': | |
346 | switch ( *p ) { | 353 | break; |
347 | case 't': | 354 | default: |
348 | case 'x': sct-> m_mode |= S_IXOTH; break; | 355 | parse_error ("invalid user mode"); |
349 | case 'T': | 356 | } |
350 | case '-': break; | 357 | |
351 | default : parse_error ( "invalid other mode" ); | 358 | switch (*p++) { |
352 | } | 359 | case 's': |
353 | 360 | sct->m_mode |= S_ISGID; | |
354 | while ( isspace ( *++p )) { } /* skip whitespace */ | 361 | /* no break */ |
355 | 362 | case 'x': | |
356 | if ( isdigit ( *p )) { | 363 | sct->m_mode |= S_IXGRP; |
357 | sct-> m_uid = strtol ( p, &p, 10 ); | 364 | break; |
358 | if ( *p++ != '.' ) | 365 | case 'S': |
359 | parse_error ( "parsing <uid>.<gid>" ); | 366 | break; |
360 | } | 367 | case '-': |
361 | else { | 368 | break; |
362 | struct passwd *pwd; | 369 | default: |
363 | char *p2 = strchr ( p, '.' ); | 370 | parse_error ("invalid group mode"); |
364 | 371 | } | |
365 | if ( !p2 ) | 372 | |
366 | parse_error ( "parsing <uid>.<gid>" ); | 373 | switch (*p) { |
367 | 374 | case 't': | |
368 | *p2 = 0; | 375 | case 'x': |
369 | pwd = getpwnam ( p ); | 376 | sct->m_mode |= S_IXOTH; |
370 | 377 | break; | |
371 | if ( !pwd ) | 378 | case 'T': |
372 | parse_error ( "invalid user name" ); | 379 | case '-': |
373 | 380 | break; | |
374 | sct-> m_uid = pwd-> pw_uid; | 381 | default: |
375 | p = p2 + 1; | 382 | parse_error ("invalid other mode"); |
376 | } | 383 | } |
377 | if ( isdigit ( *p )) | 384 | |
378 | sct-> m_gid = strtol ( p, &p, 10 ); | 385 | while (isspace (*++p)) { |
379 | else { | 386 | /* skip whitespace */ |
380 | struct group *grp = getgrnam ( p ); | 387 | } |
381 | 388 | ||
382 | if ( !grp ) | 389 | if (isdigit (*p)) { |
383 | parse_error ( "invalid group name" ); | 390 | sct->m_uid = strtol (p, &p, 10); |
384 | 391 | if (*p++ != '.') | |
385 | sct-> m_gid = grp-> gr_gid; | 392 | parse_error ("parsing <uid>.<gid>"); |
386 | } | 393 | } else { |
387 | } | 394 | struct passwd *pwd; |
388 | break; | 395 | char *p2 = strchr (p, '.'); |
389 | } | 396 | |
390 | default: /* unknown - skip */ | 397 | if (!p2) |
391 | break; | 398 | parse_error ("parsing <uid>.<gid>"); |
392 | } | 399 | |
393 | } | 400 | *p2 = 0; |
394 | else | 401 | pwd = getpwnam (p); |
395 | parse_error ( "keyword not within section" ); | 402 | |
396 | } | 403 | if (!pwd) |
397 | fclose ( f ); | 404 | parse_error ("invalid user name"); |
398 | return 1; | 405 | |
406 | sct->m_uid = pwd->pw_uid; | ||
407 | p = p2 + 1; | ||
408 | } | ||
409 | if (isdigit (*p)) | ||
410 | sct->m_gid = strtol (p, &p, 10); | ||
411 | else { | ||
412 | struct group *grp = getgrnam (p); | ||
413 | |||
414 | if (!grp) | ||
415 | parse_error ("invalid group name"); | ||
416 | |||
417 | sct->m_gid = grp->gr_gid; | ||
418 | } | ||
419 | } | ||
420 | break; | ||
421 | } | ||
422 | default: /* unknown - skip */ | ||
423 | break; | ||
399 | } | 424 | } |
425 | } else | ||
426 | parse_error ("keyword not within section"); | ||
400 | } | 427 | } |
428 | fclose (f); | ||
429 | return 1; | ||
430 | } | ||
401 | } | 431 | } |
402 | return 0; /* no config file or not readable (not an error) */ | 432 | } |
433 | return 0; /* no config file or not readable (not an error) */ | ||
403 | 434 | ||
404 | pe_label: | 435 | pe_label: |
405 | fprintf ( stderr, "Parse error in %s, line %d: %s\n", CONFIG_FILE, lc, err ); | 436 | fprintf (stderr, "Parse error in %s, line %d: %s\n", CONFIG_FILE, lc, err); |
406 | 437 | ||
407 | if ( f ) | 438 | if (f) |
408 | fclose ( f ); | 439 | fclose (f); |
409 | return 0; | 440 | return 0; |
410 | } | 441 | } |
411 | 442 | ||
412 | #endif | 443 | #endif |