aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griebl <griebl@gmx.de>2002-06-06 17:30:16 +0000
committerRobert Griebl <griebl@gmx.de>2002-06-06 17:30:16 +0000
commit0c789a4255aeb74eb8d9d844c3a48aba18602288 (patch)
treeaeb34ab6ff9e1198dcbeef0319fb0a5385e29eeb
parentfe1ef2bc62883539f37e0070f62c765602232a77 (diff)
downloadbusybox-w32-0c789a4255aeb74eb8d9d844c3a48aba18602288.tar.gz
busybox-w32-0c789a4255aeb74eb8d9d844c3a48aba18602288.tar.bz2
busybox-w32-0c789a4255aeb74eb8d9d844c3a48aba18602288.zip
If config file can not be parsed, use compiled in BB_SUID_... values as a
fallback method
-rw-r--r--applets/applets.c126
1 files changed, 71 insertions, 55 deletions
diff --git a/applets/applets.c b/applets/applets.c
index 2ab44059a..9dcfe6b85 100644
--- a/applets/applets.c
+++ b/applets/applets.c
@@ -53,8 +53,9 @@ 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
56static void parse_error ( int line, const char *err ); 56static int parse_config_file ( void );
57static void parse_config_file ( void ); 57
58static int config_ok;
58 59
59#define CONFIG_FILE "/etc/busybox.conf" 60#define CONFIG_FILE "/etc/busybox.conf"
60 61
@@ -119,7 +120,7 @@ void run_applet_by_name(const char *name, int argc, char **argv)
119 120
120#ifdef CONFIG_FEATURE_SUID_CONFIG 121#ifdef CONFIG_FEATURE_SUID_CONFIG
121 if ( recurse_level == 0 ) 122 if ( recurse_level == 0 )
122 parse_config_file ( ); 123 config_ok = parse_config_file ( );
123#endif 124#endif
124 125
125 recurse_level++; 126 recurse_level++;
@@ -183,42 +184,53 @@ void check_suid ( struct BB_applet *applet )
183 uid_t rgid = getgid ( ); 184 uid_t rgid = getgid ( );
184 185
185#ifdef CONFIG_FEATURE_SUID_CONFIG 186#ifdef CONFIG_FEATURE_SUID_CONFIG
186 struct BB_suid_config *sct; 187 if ( config_ok ) {
187 188 struct BB_suid_config *sct;
188 for ( sct = suid_config; sct; sct = sct-> m_next ) {
189 if ( sct-> m_applet == applet )
190 break;
191 }
192 if ( sct ) {
193 mode_t m = sct-> m_mode;
194 189
195 if ( sct-> m_uid == ruid ) // same uid 190 for ( sct = suid_config; sct; sct = sct-> m_next ) {
196 m >>= 6; 191 if ( sct-> m_applet == applet )
197 else if (( sct-> m_gid == rgid ) || ingroup ( ruid, sct-> m_gid )) // same group / in group 192 break;
198 m >>= 3; 193 }
194 if ( sct ) {
195 mode_t m = sct-> m_mode;
196
197 if ( sct-> m_uid == ruid ) // same uid
198 m >>= 6;
199 else if (( sct-> m_gid == rgid ) || ingroup ( ruid, sct-> m_gid )) // same group / in group
200 m >>= 3;
199 201
200 if (!( m & S_IXOTH )) // is x bit not set ? 202 if (!( m & S_IXOTH )) // is x bit not set ?
201 error_msg_and_die ( "You have no permission to run this applet!" ); 203 error_msg_and_die ( "You have no permission to run this applet!" );
202 204
203 if (( sct-> m_mode & ( S_ISGID | S_IXGRP )) == ( S_ISGID | S_IXGRP )) { // *both* have to be set for sgid 205 if (( sct-> m_mode & ( S_ISGID | S_IXGRP )) == ( S_ISGID | S_IXGRP )) { // *both* have to be set for sgid
204 if ( setegid ( sct-> m_gid )) 206 if ( setegid ( sct-> m_gid ))
205 error_msg_and_die ( "BusyBox binary has insufficient rights to set proper GID for applet!" ); 207 error_msg_and_die ( "BusyBox binary has insufficient rights to set proper GID for applet!" );
208 }
209 else
210 setgid ( rgid ); // no sgid -> drop
211
212 if ( sct-> m_mode & S_ISUID ) {
213 if ( seteuid ( sct-> m_uid ))
214 error_msg_and_die ( "BusyBox binary has insufficient rights to set proper UID for applet!" );
215 }
216 else
217 setuid ( ruid ); // no suid -> drop
206 } 218 }
207 else 219 else { // default: drop all priviledges
208 setgid ( rgid ); // no sgid -> drop 220 setgid ( rgid );
209 221 setuid ( ruid );
210 if ( sct-> m_mode & S_ISUID ) { 222 }
211 if ( seteuid ( sct-> m_uid )) 223 return;
212 error_msg_and_die ( "BusyBox binary has insufficient rights to set proper UID for applet!" );
213 }
214 else
215 setuid ( ruid ); // no suid -> drop
216 } 224 }
217 else { // default: drop all priviledges 225 else {
218 setgid ( rgid ); 226 static int onetime = 0;
219 setuid ( ruid ); 227
228 if ( !onetime ) {
229 onetime = 1;
230 fprintf ( stderr, "Using fallback suid method\n" );
231 }
220 } 232 }
221#else 233#endif
222 234
223 if ( applet-> need_suid == _BB_SUID_ALWAYS ) { 235 if ( applet-> need_suid == _BB_SUID_ALWAYS ) {
224 if ( geteuid ( ) != 0 ) 236 if ( geteuid ( ) != 0 )
@@ -228,23 +240,20 @@ void check_suid ( struct BB_applet *applet )
228 setgid ( rgid ); // drop all priviledges 240 setgid ( rgid ); // drop all priviledges
229 setuid ( ruid ); 241 setuid ( ruid );
230 } 242 }
231#endif
232} 243}
233 244
234#ifdef CONFIG_FEATURE_SUID_CONFIG 245#ifdef CONFIG_FEATURE_SUID_CONFIG
235 246
236void parse_error ( int line, const char *err )
237{
238 char msg [512];
239 snprintf ( msg, sizeof( msg ) - 1, "Parse error in %s, line %d: %s", CONFIG_FILE, line, err );
240 247
241 error_msg_and_die ( msg ); 248#define parse_error(x) { err=x; goto pe_label; }
242}
243 249
244 250
245void parse_config_file ( void ) 251int parse_config_file ( void )
246{ 252{
247 struct stat st; 253 struct stat st;
254 char *err = 0;
255 FILE *f = 0;
256 int lc = 0;
248 257
249 suid_config = 0; 258 suid_config = 0;
250 259
@@ -253,12 +262,11 @@ void parse_config_file ( void )
253 // is it owned by root with no write perm. for group and others ? 262 // is it owned by root with no write perm. for group and others ?
254 if ( S_ISREG( st. st_mode ) && ( st. st_uid == 0 ) && (!( st. st_mode & ( S_IWGRP | S_IWOTH )))) { 263 if ( S_ISREG( st. st_mode ) && ( st. st_uid == 0 ) && (!( st. st_mode & ( S_IWGRP | S_IWOTH )))) {
255 // that's ok .. then try to open it 264 // that's ok .. then try to open it
256 FILE *f = fopen ( CONFIG_FILE, "r" ); 265 f = fopen ( CONFIG_FILE, "r" );
257 266
258 if ( f ) { 267 if ( f ) {
259 char buffer [4096]; 268 char buffer [256];
260 int section = 0; 269 int section = 0;
261 int lc = 0;
262 270
263 while ( fgets ( buffer, sizeof( buffer ) - 1, f )) { 271 while ( fgets ( buffer, sizeof( buffer ) - 1, f )) {
264 char c = buffer [0]; 272 char c = buffer [0];
@@ -280,7 +288,7 @@ void parse_config_file ( void )
280 p = strchr ( buffer, ']' ); 288 p = strchr ( buffer, ']' );
281 289
282 if ( !p || ( p == ( buffer + 1 ))) // no matching ] or empty [] 290 if ( !p || ( p == ( buffer + 1 ))) // no matching ] or empty []
283 parse_error ( lc, "malformed section header" ); 291 parse_error ( "malformed section header" );
284 292
285 *p = 0; 293 *p = 0;
286 294
@@ -298,7 +306,7 @@ void parse_config_file ( void )
298 p = strchr ( buffer, '=' ); // <key>[::space::]*=[::space::]*<value> 306 p = strchr ( buffer, '=' ); // <key>[::space::]*=[::space::]*<value>
299 307
300 if ( !p || ( p == ( buffer + 1 ))) // no = or key is empty 308 if ( !p || ( p == ( buffer + 1 ))) // no = or key is empty
301 parse_error ( lc, "malformed keyword" ); 309 parse_error ( "malformed keyword" );
302 310
303 l = p - buffer; 311 l = p - buffer;
304 while ( isspace ( buffer [--l] )) { } // skip whitespace 312 while ( isspace ( buffer [--l] )) { } // skip whitespace
@@ -321,7 +329,7 @@ void parse_config_file ( void )
321 case 's': sct-> m_mode |= S_ISUID; // no break 329 case 's': sct-> m_mode |= S_ISUID; // no break
322 case 'x': sct-> m_mode |= S_IXUSR; break; 330 case 'x': sct-> m_mode |= S_IXUSR; break;
323 case '-': break; 331 case '-': break;
324 default : parse_error ( lc, "invalid user mode" ); 332 default : parse_error ( "invalid user mode" );
325 } 333 }
326 334
327 switch ( *p++ ) { 335 switch ( *p++ ) {
@@ -329,7 +337,7 @@ void parse_config_file ( void )
329 case 'x': sct-> m_mode |= S_IXGRP; break; 337 case 'x': sct-> m_mode |= S_IXGRP; break;
330 case 'S': break; 338 case 'S': break;
331 case '-': break; 339 case '-': break;
332 default : parse_error ( lc, "invalid group mode" ); 340 default : parse_error ( "invalid group mode" );
333 } 341 }
334 342
335 switch ( *p ) { 343 switch ( *p ) {
@@ -337,7 +345,7 @@ void parse_config_file ( void )
337 case 'x': sct-> m_mode |= S_IXOTH; break; 345 case 'x': sct-> m_mode |= S_IXOTH; break;
338 case 'T': 346 case 'T':
339 case '-': break; 347 case '-': break;
340 default : parse_error ( lc, "invalid other mode" ); 348 default : parse_error ( "invalid other mode" );
341 } 349 }
342 350
343 while ( isspace ( *++p )) { } // skip whitespace 351 while ( isspace ( *++p )) { } // skip whitespace
@@ -345,20 +353,20 @@ void parse_config_file ( void )
345 if ( isdigit ( *p )) { 353 if ( isdigit ( *p )) {
346 sct-> m_uid = strtol ( p, &p, 10 ); 354 sct-> m_uid = strtol ( p, &p, 10 );
347 if ( *p++ != '.' ) 355 if ( *p++ != '.' )
348 parse_error ( lc, "parsing <uid>.<gid>" ); 356 parse_error ( "parsing <uid>.<gid>" );
349 } 357 }
350 else { 358 else {
351 struct passwd *pwd; 359 struct passwd *pwd;
352 char *p2 = strchr ( p, '.' ); 360 char *p2 = strchr ( p, '.' );
353 361
354 if ( !p2 ) 362 if ( !p2 )
355 parse_error ( lc, "parsing <uid>.<gid>" ); 363 parse_error ( "parsing <uid>.<gid>" );
356 364
357 *p2 = 0; 365 *p2 = 0;
358 pwd = getpwnam ( p ); 366 pwd = getpwnam ( p );
359 367
360 if ( !pwd ) 368 if ( !pwd )
361 parse_error ( lc, "invalid user name" ); 369 parse_error ( "invalid user name" );
362 370
363 sct-> m_uid = pwd-> pw_uid; 371 sct-> m_uid = pwd-> pw_uid;
364 p = p2 + 1; 372 p = p2 + 1;
@@ -369,7 +377,7 @@ void parse_config_file ( void )
369 struct group *grp = getgrnam ( p ); 377 struct group *grp = getgrnam ( p );
370 378
371 if ( !grp ) 379 if ( !grp )
372 parse_error ( lc, "invalid group name" ); 380 parse_error ( "invalid group name" );
373 381
374 sct-> m_gid = grp-> gr_gid; 382 sct-> m_gid = grp-> gr_gid;
375 } 383 }
@@ -381,12 +389,20 @@ void parse_config_file ( void )
381 } 389 }
382 } 390 }
383 else 391 else
384 parse_error ( lc, "keyword not within section" ); 392 parse_error ( "keyword not within section" );
385 } 393 }
386 fclose ( f ); 394 fclose ( f );
387 } 395 }
388 } 396 }
389 } 397 }
398 return 1;
399
400pe_label:
401 fprintf ( stderr, "Parse error in %s, line %d: %s\n", CONFIG_FILE, lc, err );
402
403 if ( f )
404 fclose ( f );
405 return 0;
390} 406}
391 407
392#endif 408#endif