- struct stat st;
- char *err = 0;
- FILE *f = 0;
- int lc = 0;
-
- suid_config = 0;
-
- // is there a config file ?
- if ( stat ( CONFIG_FILE, &st ) == 0 ) {
- // is it owned by root with no write perm. for group and others ?
- if ( S_ISREG( st. st_mode ) && ( st. st_uid == 0 ) && (!( st. st_mode & ( S_IWGRP | S_IWOTH )))) {
- // that's ok .. then try to open it
- f = fopen ( CONFIG_FILE, "r" );
-
- if ( f ) {
- char buffer [256];
- int section = 0;
-
- while ( fgets ( buffer, sizeof( buffer ) - 1, f )) {
- char c = buffer [0];
- char *p;
-
- lc++;
-
- p = strchr ( buffer, '#' );
- if ( p )
- *p = 0;
- p = buffer + xstrlen ( buffer );
- while (( p > buffer ) && isspace ( *--p ))
- *p = 0;
-
- if ( p == buffer )
- continue;
-
- if ( c == '[' ) {
- p = strchr ( buffer, ']' );
-
- if ( !p || ( p == ( buffer + 1 ))) // no matching ] or empty []
- parse_error ( "malformed section header" );
-
- *p = 0;
-
- if ( strcasecmp ( buffer + 1, "SUID" ) == 0 )
- section = 1;
- else
- section = -1; // unknown section - just skip
- }
- else if ( section ) {
- switch ( section ) {
- case 1: { // SUID
- int l;
- struct BB_applet *applet;
-
- p = strchr ( buffer, '=' ); // <key>[::space::]*=[::space::]*<value>
-
- if ( !p || ( p == ( buffer + 1 ))) // no = or key is empty
- parse_error ( "malformed keyword" );
-
- l = p - buffer;
- while ( isspace ( buffer [--l] )) { } // skip whitespace
-
- buffer [l+1] = 0;
-
- if (( applet = find_applet_by_name ( buffer ))) {
- struct BB_suid_config *sct = xmalloc ( sizeof( struct BB_suid_config ));
-
- sct-> m_applet = applet;
- sct-> m_next = suid_config;
- suid_config = sct;
-
- while ( isspace ( *++p )) { } // skip whitespace
-
- sct-> m_mode = 0;
-
- switch ( *p++ ) {
- case 'S': sct-> m_mode |= S_ISUID; break;
- case 's': sct-> m_mode |= S_ISUID; // no break
- case 'x': sct-> m_mode |= S_IXUSR; break;
- case '-': break;
- default : parse_error ( "invalid user mode" );
- }
-
- switch ( *p++ ) {
- case 's': sct-> m_mode |= S_ISGID; // no break
- case 'x': sct-> m_mode |= S_IXGRP; break;
- case 'S': break;
- case '-': break;
- default : parse_error ( "invalid group mode" );
- }
-
- switch ( *p ) {
- case 't':
- case 'x': sct-> m_mode |= S_IXOTH; break;
- case 'T':
- case '-': break;
- default : parse_error ( "invalid other mode" );
- }
-
- while ( isspace ( *++p )) { } // skip whitespace
-
- if ( isdigit ( *p )) {
- sct-> m_uid = strtol ( p, &p, 10 );
- if ( *p++ != '.' )
- parse_error ( "parsing <uid>.<gid>" );
- }
- else {
- struct passwd *pwd;
- char *p2 = strchr ( p, '.' );
-
- if ( !p2 )
- parse_error ( "parsing <uid>.<gid>" );
-
- *p2 = 0;
- pwd = getpwnam ( p );
-
- if ( !pwd )
- parse_error ( "invalid user name" );
-
- sct-> m_uid = pwd-> pw_uid;
- p = p2 + 1;
- }
- if ( isdigit ( *p ))
- sct-> m_gid = strtol ( p, &p, 10 );
- else {
- struct group *grp = getgrnam ( p );
-
- if ( !grp )
- parse_error ( "invalid group name" );
-
- sct-> m_gid = grp-> gr_gid;
- }
- }
- break;
- }
- default: // unknown - skip
- break;
- }
- }
- else
- parse_error ( "keyword not within section" );
- }
- fclose ( f );
- }
- }