%{ #include #include #include #include #include #include "dgamelaunch.h" extern int yylex(void); extern void yyerror(const char*); extern char *yytext; extern unsigned int line, col; static const char* lookup_token (int t); %} %union { char* s; int kt; unsigned long i; } %token TYPE_SUSER TYPE_SGROUP TYPE_SGID TYPE_SUID TYPE_MAX %token TYPE_PATH_NETHACK TYPE_PATH_DGLDIR TYPE_PATH_SPOOL %token TYPE_PATH_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT %token TYPE_VALUE %token TYPE_NUMBER %type KeyType %% Configuration: KeyPairs | { fprintf(stderr, "%s: no settings, proceeding with defaults\n", config); } ; KeyPairs: KeyPairs KeyPair | KeyPair ; KeyPair: KeyType '=' TYPE_VALUE { struct group* gr; struct passwd* usr; if (!myconfig) { myconfig = calloc(1, sizeof(struct dg_config)); myconfig->shed_uid = (uid_t)-1; myconfig->shed_gid = (gid_t)-1; } switch ($1) { case TYPE_SGROUP: myconfig->shed_group = strdup($3); if ((gr = getgrnam($3)) != NULL) myconfig->shed_gid = gr->gr_gid; else fprintf(stderr, "%s: no such group '%s'\n", config, $3); break; case TYPE_SUSER: if (!strcmp($3, "root")) { fprintf(stderr, "%s: I refuse to run as root! Aborting.\n", config); graceful_exit(1); } myconfig->shed_user = strdup($3); if ((usr = getpwnam($3)) != NULL) { if (usr->pw_uid != 0) myconfig->shed_uid = usr->pw_uid; else { fprintf(stderr, "%s: I refuse to run as %s (uid 0!) Aborting.\n", config, $3); graceful_exit(1); } } else fprintf(stderr, "%s: no such user '%s'\n", config, $3); break; case TYPE_PATH_CHROOT: if (myconfig->chroot) free(myconfig->chroot); myconfig->chroot = strdup ($3); break; case TYPE_PATH_NETHACK: if (myconfig->nethack) free(myconfig->nethack); myconfig->nethack = strdup ($3); break; case TYPE_PATH_DGLDIR: if (myconfig->dglroot) free(myconfig->dglroot); myconfig->dglroot = strdup ($3); break; case TYPE_PATH_BANNER: if (myconfig->banner) free(myconfig->banner); myconfig->banner = strdup($3); break; case TYPE_PATH_CANNED: if (myconfig->rcfile) free(myconfig->rcfile); myconfig->rcfile = strdup($3); break; case TYPE_PATH_SPOOL: if (myconfig->spool) free (myconfig->spool); myconfig->spool = strdup($3); break; default: fprintf(stderr, "%s: token %s does not take a string, bailing out\n", config, lookup_token($1)); exit(1); } free($3); } | KeyType '=' TYPE_NUMBER { if (!myconfig) myconfig = calloc(1, sizeof(struct dg_config)); switch ($1) { case TYPE_SUID: if (!myconfig->shed_user) { /* Naive user protection - do not allow running as user root */ if ($3 == 0) { fprintf(stderr, "%s: I refuse to run as uid 0 (root)! Aborting.\n", config); graceful_exit(1); } myconfig->shed_uid = $3; } break; case TYPE_SGID: if (!myconfig->shed_group) { myconfig->shed_gid = $3; } break; case TYPE_MAX: myconfig->max = $3; break; default: fprintf(stderr, "%s: token %s does not take a number, bailing out\n", config, lookup_token($1)); exit(1); } }; KeyType : TYPE_SUSER { $$ = TYPE_SUSER; } | TYPE_SGROUP { $$ = TYPE_SGROUP; } | TYPE_SUID { $$ = TYPE_SUID; } | TYPE_SGID { $$ = TYPE_SGID; } | TYPE_MAX { $$ = TYPE_MAX; } | TYPE_PATH_CHROOT { $$ = TYPE_PATH_CHROOT; } | TYPE_PATH_NETHACK { $$ = TYPE_PATH_NETHACK; } | TYPE_PATH_DGLDIR { $$ = TYPE_PATH_DGLDIR; } | TYPE_PATH_SPOOL { $$ = TYPE_PATH_SPOOL; } | TYPE_PATH_BANNER { $$ = TYPE_PATH_BANNER; } | TYPE_PATH_CANNED { $$ = TYPE_PATH_CANNED; } ; %% const char* lookup_token (int t) { switch (t) { case TYPE_SUSER: return "shed_user"; case TYPE_SGROUP: return "shed_group"; case TYPE_SUID: return "shed_uid"; case TYPE_SGID: return "shed_gid"; case TYPE_MAX: return "maxusers"; case TYPE_PATH_CHROOT: return "chroot_path"; case TYPE_PATH_NETHACK: return "nethack"; case TYPE_PATH_DGLDIR: return "dglroot"; case TYPE_PATH_SPOOL: return "spooldir"; case TYPE_PATH_BANNER: return "banner"; case TYPE_PATH_CANNED: return "rc_template"; default: abort(); } } void yyerror(char const* s) { fprintf(stderr, "%s: couldn't parse \"%s\" at line %d, column %d: %s\n", config, yytext, line, col, s); }