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 /applets | |
| parent | 393183dccc4d100366972bdbbdc6e03a77839120 (diff) | |
| download | busybox-w32-2faee7b1ed84698ae057ac44bdb0a9f686dd945f.tar.gz busybox-w32-2faee7b1ed84698ae057ac44bdb0a9f686dd945f.tar.bz2 busybox-w32-2faee7b1ed84698ae057ac44bdb0a9f686dd945f.zip | |
Vodz, last_path_87, formatiing changes
Diffstat (limited to 'applets')
| -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 |
