From 17ad75d50b84022c790ee2dce16f4a15ea4222d4 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 1 Sep 2016 09:19:20 -0600 Subject: [PATCH] Add a flags option to sudo_parseln() and a flag to only mach comments at the beginning of the line. Use the flag when parsing ldap.conf. --- include/sudo_util.h | 8 ++++++-- lib/util/parseln.c | 17 ++++++++++++----- lib/util/regress/sudo_parseln/parseln_test.c | 2 +- lib/util/sudo_conf.c | 2 +- lib/util/util.exp.in | 1 + plugins/sudoers/env.c | 2 +- plugins/sudoers/ldap.c | 2 +- plugins/sudoers/sudo_nss.c | 4 ++-- 8 files changed, 25 insertions(+), 13 deletions(-) diff --git a/include/sudo_util.h b/include/sudo_util.h index 78d4a2d5b..7495b84ab 100644 --- a/include/sudo_util.h +++ b/include/sudo_util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Todd C. Miller + * Copyright (c) 2013-2016 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -138,6 +138,9 @@ #define sudo_isset(_a, _i) ((_a)[(_i) / NBBY] & (1<<((_i) % NBBY))) #define sudo_isclr(_a, _i) (((_a)[(_i) / NBBY] & (1<<((_i) % NBBY))) == 0) +/* sudo_parseln() flags */ +#define PARSELN_COMM_BOL 1 /* comments only at begining of line */ + /* * Macros to quiet gcc's warn_unused_result attribute. */ @@ -190,7 +193,8 @@ __dso_public bool sudo_lock_region_v1(int fd, int action, off_t len); /* parseln.c */ __dso_public ssize_t sudo_parseln_v1(char **buf, size_t *bufsize, unsigned int *lineno, FILE *fp); -#define sudo_parseln(_a, _b, _c, _d) sudo_parseln_v1((_a), (_b), (_c), (_d)) +__dso_public ssize_t sudo_parseln_v2(char **buf, size_t *bufsize, unsigned int *lineno, FILE *fp, int flags); +#define sudo_parseln(_a, _b, _c, _d, _e) sudo_parseln_v2((_a), (_b), (_c), (_d), (_e)) /* progname.c */ __dso_public void initprogname(const char *); diff --git a/lib/util/parseln.c b/lib/util/parseln.c index a1aae0d89..6f3eac4cd 100644 --- a/lib/util/parseln.c +++ b/lib/util/parseln.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2007, 2013-2015 - * Todd C. Miller + * Copyright (c) 2007, 2013-2016 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -46,7 +45,7 @@ * could also make comment char and line continuation configurable */ ssize_t -sudo_parseln_v1(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp) +sudo_parseln_v2(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp, int flags) { size_t linesize = 0, total = 0; ssize_t len; @@ -68,8 +67,10 @@ sudo_parseln_v1(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp) /* Remove comments or check for line continuation (but not both) */ if ((cp = strchr(line, '#')) != NULL) { - *cp = '\0'; - len = (ssize_t)(cp - line); + if (cp == line || !ISSET(flags, PARSELN_COMM_BOL)) { + *cp = '\0'; + len = (ssize_t)(cp - line); + } } else if (len > 0 && line[len - 1] == '\\' && (len == 1 || line[len - 2] != '\\')) { line[--len] = '\0'; continued = true; @@ -117,3 +118,9 @@ sudo_parseln_v1(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp) debug_return_ssize_t(-1); debug_return_ssize_t(total); } + +ssize_t +sudo_parseln_v1(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp) +{ + return sudo_parseln_v2(bufp, bufsizep, lineno, fp, 0); +} diff --git a/lib/util/regress/sudo_parseln/parseln_test.c b/lib/util/regress/sudo_parseln/parseln_test.c index 9dac11ec2..32dc0ae75 100644 --- a/lib/util/regress/sudo_parseln/parseln_test.c +++ b/lib/util/regress/sudo_parseln/parseln_test.c @@ -51,7 +51,7 @@ main(int argc, char *argv[]) initprogname(argc > 0 ? argv[0] : "parseln_test"); - while (sudo_parseln(&line, &linesize, &lineno, stdin) != -1) + while (sudo_parseln(&line, &linesize, &lineno, stdin, 0) != -1) printf("%6u\t%s\n", lineno, line); free(line); exit(0); diff --git a/lib/util/sudo_conf.c b/lib/util/sudo_conf.c index 08556bb13..399e70be3 100644 --- a/lib/util/sudo_conf.c +++ b/lib/util/sudo_conf.c @@ -609,7 +609,7 @@ sudo_conf_read_v1(const char *conf_file, int conf_types) goto done; } - while (sudo_parseln(&line, &linesize, &conf_lineno, fp) != -1) { + while (sudo_parseln(&line, &linesize, &conf_lineno, fp, 0) != -1) { struct sudo_conf_table *cur; unsigned int i; char *cp; diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in index a7e0efb3c..d29a00669 100644 --- a/lib/util/util.exp.in +++ b/lib/util/util.exp.in @@ -71,6 +71,7 @@ sudo_lock_region_v1 sudo_new_key_val_v1 sudo_parse_gids_v1 sudo_parseln_v1 +sudo_parseln_v2 sudo_secure_dir_v1 sudo_secure_file_v1 sudo_setgroups_v1 diff --git a/plugins/sudoers/env.c b/plugins/sudoers/env.c index 238d91248..daecd55b5 100644 --- a/plugins/sudoers/env.c +++ b/plugins/sudoers/env.c @@ -1184,7 +1184,7 @@ read_env_file(const char *path, int overwrite) debug_return_bool(rval); } - while (sudo_parseln(&line, &linesize, NULL, fp) != -1) { + while (sudo_parseln(&line, &linesize, NULL, fp, 0) != -1) { /* Skip blank or comment lines */ if (*(var = line) == '\0') continue; diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index 5130bcd69..552e15a72 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -2024,7 +2024,7 @@ sudo_ldap_read_config(void) if ((fp = fopen(path_ldap_conf, "r")) == NULL) debug_return_bool(false); - while (sudo_parseln(&line, &linesize, NULL, fp) != -1) { + while (sudo_parseln(&line, &linesize, NULL, fp, PARSELN_COMM_BOL) != -1) { if (*line == '\0') continue; /* skip empty line */ diff --git a/plugins/sudoers/sudo_nss.c b/plugins/sudoers/sudo_nss.c index 77e095f42..18f4de002 100644 --- a/plugins/sudoers/sudo_nss.c +++ b/plugins/sudoers/sudo_nss.c @@ -76,7 +76,7 @@ sudo_read_nss(void) if ((fp = fopen(_PATH_NSSWITCH_CONF, "r")) == NULL) goto nomatch; - while (sudo_parseln(&line, &linesize, NULL, fp) != -1) { + while (sudo_parseln(&line, &linesize, NULL, fp, 0) != -1) { char *cp, *last; /* Skip blank or comment lines */ @@ -156,7 +156,7 @@ sudo_read_nss(void) if ((fp = fopen(_PATH_NETSVC_CONF, "r")) == NULL) goto nomatch; - while (sudo_parseln(&line, &linesize, NULL, fp) != -1) { + while (sudo_parseln(&line, &linesize, NULL, fp, 0) != -1) { /* Skip blank or comment lines */ if (*(cp = line) == '\0') continue; -- 2.40.0