X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/yaid/blobdiff_plain/c039c9363c583e347cd269f6c741d302d416d1a6..5436f0c5283f835026f1a7b044ee714e6f341ce3:/policy.c diff --git a/policy.c b/policy.c index 32a4550..9cb9af9 100644 --- a/policy.c +++ b/policy.c @@ -441,15 +441,22 @@ fail: /* Open a policy file by NAME. The description WHAT and query Q are used for * formatting error messages for the log. + * + * This function is somewhat careful only to read from actual regular files, + * though (if the filesystem object identified by NAME is a symlink, say) it + * might open a device node or other exotic thing without reading it. This + * is likely harmless, since we're running as an unprivileged user anyway. */ int open_policy_file(struct policy_file *pf, const char *name, - const char *what, const struct query *q) + const char *what, const struct query *q, unsigned f) { struct stat st; if ((pf->fp = fopen(name, "r")) == 0) { - logmsg(q, LOG_ERR, "failed to open %s `%s': %s", - what, name, strerror(errno)); + if (errno != ENOENT || !(f & OPF_NOENTOK)) { + logmsg(q, LOG_ERR, "failed to open %s `%s': %s", + what, name, strerror(errno)); + } goto err_0; } @@ -490,22 +497,20 @@ int read_policy_file(struct policy_file *pf) t = parse_policy(pf->fp, &pf->p); switch (t) { case T_OK: + case T_EOL: nextline(pf->fp); - return (0); + return (t); case T_ERROR: logmsg(pf->q, LOG_ERR, "%s:%d: parse error in %s", pf->name, pf->lno, pf->what); pf->err = 1; - break; + return (t); case T_EOF: if (ferror(pf->fp)) { logmsg(pf->q, LOG_ERR, "failed to read %s `%s': %s", pf->what, pf->name, strerror(errno)); } - return (-1); - case T_EOL: - nextline(pf->fp); - break; + return (t); default: abort(); } @@ -528,12 +533,15 @@ int load_policy_file(const char *file, policy_v *pv) { struct policy_file pf; policy_v v = DA_INIT; + int t = 0; - if (open_policy_file(&pf, file, "policy file", 0)) + if (open_policy_file(&pf, file, "policy file", 0, 0)) return (-1); - while (!read_policy_file(&pf)) { - DA_PUSH(&v, pf.p); - init_policy(&pf.p); + while ((t = read_policy_file(&pf)) < T_EOF) { + if (t == T_OK) { + DA_PUSH(&v, pf.p); + init_policy(&pf.p); + } } close_policy_file(&pf); if (!pf.err) {