mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-29 13:28:10 +00:00
Eliminate most use of parsed_sudoers in cvtsudoers
This commit is contained in:
parent
b2e3adccf3
commit
5d1dddc467
@ -78,17 +78,17 @@ static struct option long_opts[] = {
|
|||||||
__dso_public int main(int argc, char *argv[]);
|
__dso_public int main(int argc, char *argv[]);
|
||||||
static void help(void) __attribute__((__noreturn__));
|
static void help(void) __attribute__((__noreturn__));
|
||||||
static void usage(int);
|
static void usage(int);
|
||||||
static bool convert_sudoers_sudoers(const char *output_file, struct cvtsudoers_config *conf);
|
static bool convert_sudoers_sudoers(struct sudoers_parse_tree *parse_tree, const char *output_file, struct cvtsudoers_config *conf);
|
||||||
static bool parse_sudoers(const char *input_file, struct cvtsudoers_config *conf);
|
static bool parse_sudoers(const char *input_file, struct cvtsudoers_config *conf);
|
||||||
static bool cvtsudoers_parse_filter(char *expression);
|
static bool cvtsudoers_parse_filter(char *expression);
|
||||||
static struct cvtsudoers_config *cvtsudoers_conf_read(const char *conf_file);
|
static struct cvtsudoers_config *cvtsudoers_conf_read(const char *conf_file);
|
||||||
static void cvtsudoers_conf_free(struct cvtsudoers_config *conf);
|
static void cvtsudoers_conf_free(struct cvtsudoers_config *conf);
|
||||||
static int cvtsudoers_parse_defaults(char *expression);
|
static int cvtsudoers_parse_defaults(char *expression);
|
||||||
static int cvtsudoers_parse_suppression(char *expression);
|
static int cvtsudoers_parse_suppression(char *expression);
|
||||||
static void filter_userspecs(struct cvtsudoers_config *conf);
|
static void filter_userspecs(struct sudoers_parse_tree *parse_tree, struct cvtsudoers_config *conf);
|
||||||
static void filter_defaults(struct cvtsudoers_config *conf);
|
static void filter_defaults(struct sudoers_parse_tree *parse_tree, struct cvtsudoers_config *conf);
|
||||||
static void alias_remove_unused(void);
|
static void alias_remove_unused(struct sudoers_parse_tree *parse_tree);
|
||||||
static void alias_prune(struct cvtsudoers_config *conf);
|
static void alias_prune(struct sudoers_parse_tree *parse_tree, struct cvtsudoers_config *conf);
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
@ -309,7 +309,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
switch (input_format) {
|
switch (input_format) {
|
||||||
case format_ldif:
|
case format_ldif:
|
||||||
if (!parse_ldif(input_file, conf))
|
if (!parse_ldif(&parsed_policy, input_file, conf))
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case format_sudoers:
|
case format_sudoers:
|
||||||
@ -321,23 +321,23 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Apply filters. */
|
/* Apply filters. */
|
||||||
filter_userspecs(conf);
|
filter_userspecs(&parsed_policy, conf);
|
||||||
filter_defaults(conf);
|
filter_defaults(&parsed_policy, conf);
|
||||||
if (filters != NULL) {
|
if (filters != NULL) {
|
||||||
alias_remove_unused();
|
alias_remove_unused(&parsed_policy);
|
||||||
if (conf->prune_matches && conf->expand_aliases)
|
if (conf->prune_matches && conf->expand_aliases)
|
||||||
alias_prune(conf);
|
alias_prune(&parsed_policy, conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (output_format) {
|
switch (output_format) {
|
||||||
case format_json:
|
case format_json:
|
||||||
exitcode = !convert_sudoers_json(output_file, conf);
|
exitcode = !convert_sudoers_json(&parsed_policy, output_file, conf);
|
||||||
break;
|
break;
|
||||||
case format_ldif:
|
case format_ldif:
|
||||||
exitcode = !convert_sudoers_ldif(output_file, conf);
|
exitcode = !convert_sudoers_ldif(&parsed_policy, output_file, conf);
|
||||||
break;
|
break;
|
||||||
case format_sudoers:
|
case format_sudoers:
|
||||||
exitcode = !convert_sudoers_sudoers(output_file, conf);
|
exitcode = !convert_sudoers_sudoers(&parsed_policy, output_file, conf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sudo_fatalx("error: unhandled output format %d", output_format);
|
sudo_fatalx("error: unhandled output format %d", output_format);
|
||||||
@ -677,7 +677,8 @@ open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
userlist_matches_filter(struct member_list *users, struct cvtsudoers_config *conf)
|
userlist_matches_filter(struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct member_list *users, struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
struct cvtsudoers_string *s;
|
struct cvtsudoers_string *s;
|
||||||
struct member *m, *next;
|
struct member *m, *next;
|
||||||
@ -703,7 +704,7 @@ userlist_matches_filter(struct member_list *users, struct cvtsudoers_config *con
|
|||||||
pw.pw_uid = (uid_t)-1;
|
pw.pw_uid = (uid_t)-1;
|
||||||
pw.pw_gid = (gid_t)-1;
|
pw.pw_gid = (gid_t)-1;
|
||||||
|
|
||||||
if (user_matches(&parsed_policy, &pw, m) == true)
|
if (user_matches(parse_tree, &pw, m) == true)
|
||||||
matched = true;
|
matched = true;
|
||||||
} else {
|
} else {
|
||||||
STAILQ_FOREACH(s, &filters->users, entries) {
|
STAILQ_FOREACH(s, &filters->users, entries) {
|
||||||
@ -729,7 +730,7 @@ userlist_matches_filter(struct member_list *users, struct cvtsudoers_config *con
|
|||||||
if (pw == NULL)
|
if (pw == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (user_matches(&parsed_policy, pw, m) == true)
|
if (user_matches(parse_tree, pw, m) == true)
|
||||||
matched = true;
|
matched = true;
|
||||||
sudo_pw_delref(pw);
|
sudo_pw_delref(pw);
|
||||||
|
|
||||||
@ -751,7 +752,8 @@ userlist_matches_filter(struct member_list *users, struct cvtsudoers_config *con
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
hostlist_matches_filter(struct member_list *hostlist, struct cvtsudoers_config *conf)
|
hostlist_matches_filter(struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct member_list *hostlist, struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
struct cvtsudoers_string *s;
|
struct cvtsudoers_string *s;
|
||||||
struct member *m, *next;
|
struct member *m, *next;
|
||||||
@ -804,7 +806,7 @@ hostlist_matches_filter(struct member_list *hostlist, struct cvtsudoers_config *
|
|||||||
|
|
||||||
/* Only need one host in the filter to match. */
|
/* Only need one host in the filter to match. */
|
||||||
/* XXX - can't use netgroup_tuple with NULL pw */
|
/* XXX - can't use netgroup_tuple with NULL pw */
|
||||||
if (host_matches(&parsed_policy, NULL, lhost, shost, m) == true) {
|
if (host_matches(parse_tree, NULL, lhost, shost, m) == true) {
|
||||||
matched = true;
|
matched = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -835,13 +837,14 @@ hostlist_matches_filter(struct member_list *hostlist, struct cvtsudoers_config *
|
|||||||
* Display Defaults entries
|
* Display Defaults entries
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
print_defaults_sudoers(struct sudo_lbuf *lbuf, bool expand_aliases)
|
print_defaults_sudoers(struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct sudo_lbuf *lbuf, bool expand_aliases)
|
||||||
{
|
{
|
||||||
struct defaults *def, *next;
|
struct defaults *def, *next;
|
||||||
debug_decl(print_defaults_sudoers, SUDOERS_DEBUG_UTIL)
|
debug_decl(print_defaults_sudoers, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(def, &parsed_policy.defaults, entries, next) {
|
TAILQ_FOREACH_SAFE(def, &parse_tree->defaults, entries, next) {
|
||||||
sudoers_format_default_line(lbuf, &parsed_policy, def, &next,
|
sudoers_format_default_line(lbuf, parse_tree, def, &next,
|
||||||
expand_aliases);
|
expand_aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -872,11 +875,12 @@ print_alias_sudoers(struct sudoers_parse_tree *parse_tree, struct alias *a,
|
|||||||
* Display aliases
|
* Display aliases
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
print_aliases_sudoers(struct sudo_lbuf *lbuf)
|
print_aliases_sudoers(struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct sudo_lbuf *lbuf)
|
||||||
{
|
{
|
||||||
debug_decl(print_aliases_sudoers, SUDOERS_DEBUG_UTIL)
|
debug_decl(print_aliases_sudoers, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
alias_apply(&parsed_policy, print_alias_sudoers, lbuf);
|
alias_apply(parse_tree, print_alias_sudoers, lbuf);
|
||||||
|
|
||||||
debug_return_bool(!sudo_lbuf_error(lbuf));
|
debug_return_bool(!sudo_lbuf_error(lbuf));
|
||||||
}
|
}
|
||||||
@ -893,7 +897,8 @@ convert_sudoers_output(const char *buf)
|
|||||||
* Apply filters to userspecs, removing non-matching entries.
|
* Apply filters to userspecs, removing non-matching entries.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
filter_userspecs(struct cvtsudoers_config *conf)
|
filter_userspecs(struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
struct userspec *us, *next_us;
|
struct userspec *us, *next_us;
|
||||||
struct privilege *priv, *next_priv;
|
struct privilege *priv, *next_priv;
|
||||||
@ -907,20 +912,20 @@ filter_userspecs(struct cvtsudoers_config *conf)
|
|||||||
* host lists. It acts more like a grep than a true filter.
|
* host lists. It acts more like a grep than a true filter.
|
||||||
* In the future, we may want to add a prune option.
|
* In the future, we may want to add a prune option.
|
||||||
*/
|
*/
|
||||||
TAILQ_FOREACH_SAFE(us, &parsed_policy.userspecs, entries, next_us) {
|
TAILQ_FOREACH_SAFE(us, &parse_tree->userspecs, entries, next_us) {
|
||||||
if (!userlist_matches_filter(&us->users, conf)) {
|
if (!userlist_matches_filter(parse_tree, &us->users, conf)) {
|
||||||
TAILQ_REMOVE(&parsed_policy.userspecs, us, entries);
|
TAILQ_REMOVE(&parse_tree->userspecs, us, entries);
|
||||||
free_userspec(us);
|
free_userspec(us);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, next_priv) {
|
TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, next_priv) {
|
||||||
if (!hostlist_matches_filter(&priv->hostlist, conf)) {
|
if (!hostlist_matches_filter(parse_tree, &priv->hostlist, conf)) {
|
||||||
TAILQ_REMOVE(&us->privileges, priv, entries);
|
TAILQ_REMOVE(&us->privileges, priv, entries);
|
||||||
free_privilege(priv);
|
free_privilege(priv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TAILQ_EMPTY(&us->privileges)) {
|
if (TAILQ_EMPTY(&us->privileges)) {
|
||||||
TAILQ_REMOVE(&parsed_policy.userspecs, us, entries);
|
TAILQ_REMOVE(&parse_tree->userspecs, us, entries);
|
||||||
free_userspec(us);
|
free_userspec(us);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -934,7 +939,8 @@ filter_userspecs(struct cvtsudoers_config *conf)
|
|||||||
* Returns true if matched, else false.
|
* Returns true if matched, else false.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
alias_matches(const char *name, const char *alias_name, int alias_type)
|
alias_matches(struct sudoers_parse_tree *parse_tree, const char *name,
|
||||||
|
const char *alias_name, int alias_type)
|
||||||
{
|
{
|
||||||
struct alias *a;
|
struct alias *a;
|
||||||
struct member *m;
|
struct member *m;
|
||||||
@ -944,12 +950,12 @@ alias_matches(const char *name, const char *alias_name, int alias_type)
|
|||||||
if (strcmp(name, alias_name) == 0)
|
if (strcmp(name, alias_name) == 0)
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
|
|
||||||
a = alias_get(&parsed_policy, alias_name, alias_type);
|
a = alias_get(parse_tree, alias_name, alias_type);
|
||||||
if (a != NULL) {
|
if (a != NULL) {
|
||||||
TAILQ_FOREACH(m, &a->members, entries) {
|
TAILQ_FOREACH(m, &a->members, entries) {
|
||||||
if (m->type != ALIAS)
|
if (m->type != ALIAS)
|
||||||
continue;
|
continue;
|
||||||
if (alias_matches(name, m->name, alias_type)) {
|
if (alias_matches(parse_tree, name, m->name, alias_type)) {
|
||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -966,9 +972,9 @@ alias_matches(const char *name, const char *alias_name, int alias_type)
|
|||||||
* This does *not* check Defaults for used aliases, only userspecs.
|
* This does *not* check Defaults for used aliases, only userspecs.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
alias_used_by_userspecs(struct member_list *user_aliases,
|
alias_used_by_userspecs(struct sudoers_parse_tree *parse_tree,
|
||||||
struct member_list *runas_aliases, struct member_list *host_aliases,
|
struct member_list *user_aliases, struct member_list *runas_aliases,
|
||||||
struct member_list *cmnd_aliases)
|
struct member_list *host_aliases, struct member_list *cmnd_aliases)
|
||||||
{
|
{
|
||||||
struct privilege *priv, *priv_next;
|
struct privilege *priv, *priv_next;
|
||||||
struct userspec *us, *us_next;
|
struct userspec *us, *us_next;
|
||||||
@ -978,12 +984,12 @@ alias_used_by_userspecs(struct member_list *user_aliases,
|
|||||||
debug_decl(alias_used_by_userspecs, SUDOERS_DEBUG_ALIAS)
|
debug_decl(alias_used_by_userspecs, SUDOERS_DEBUG_ALIAS)
|
||||||
|
|
||||||
/* Iterate over the policy, checking for aliases. */
|
/* Iterate over the policy, checking for aliases. */
|
||||||
TAILQ_FOREACH_SAFE(us, &parsed_policy.userspecs, entries, us_next) {
|
TAILQ_FOREACH_SAFE(us, &parse_tree->userspecs, entries, us_next) {
|
||||||
TAILQ_FOREACH_SAFE(m, &us->users, entries, m_next) {
|
TAILQ_FOREACH_SAFE(m, &us->users, entries, m_next) {
|
||||||
if (m->type == ALIAS) {
|
if (m->type == ALIAS) {
|
||||||
/* If alias is used, remove from user_aliases and free. */
|
/* If alias is used, remove from user_aliases and free. */
|
||||||
TAILQ_FOREACH_SAFE(am, user_aliases, entries, am_next) {
|
TAILQ_FOREACH_SAFE(am, user_aliases, entries, am_next) {
|
||||||
if (alias_matches(am->name, m->name, USERALIAS)) {
|
if (alias_matches(parse_tree, am->name, m->name, USERALIAS)) {
|
||||||
TAILQ_REMOVE(user_aliases, am, entries);
|
TAILQ_REMOVE(user_aliases, am, entries);
|
||||||
free_member(am);
|
free_member(am);
|
||||||
}
|
}
|
||||||
@ -995,7 +1001,7 @@ alias_used_by_userspecs(struct member_list *user_aliases,
|
|||||||
if (m->type == ALIAS) {
|
if (m->type == ALIAS) {
|
||||||
/* If alias is used, remove from host_aliases and free. */
|
/* If alias is used, remove from host_aliases and free. */
|
||||||
TAILQ_FOREACH_SAFE(am, host_aliases, entries, am_next) {
|
TAILQ_FOREACH_SAFE(am, host_aliases, entries, am_next) {
|
||||||
if (alias_matches(am->name, m->name, HOSTALIAS)) {
|
if (alias_matches(parse_tree, am->name, m->name, HOSTALIAS)) {
|
||||||
TAILQ_REMOVE(host_aliases, am, entries);
|
TAILQ_REMOVE(host_aliases, am, entries);
|
||||||
free_member(am);
|
free_member(am);
|
||||||
}
|
}
|
||||||
@ -1008,7 +1014,7 @@ alias_used_by_userspecs(struct member_list *user_aliases,
|
|||||||
if (m->type == ALIAS) {
|
if (m->type == ALIAS) {
|
||||||
/* If alias is used, remove from runas_aliases and free. */
|
/* If alias is used, remove from runas_aliases and free. */
|
||||||
TAILQ_FOREACH_SAFE(am, runas_aliases, entries, am_next) {
|
TAILQ_FOREACH_SAFE(am, runas_aliases, entries, am_next) {
|
||||||
if (alias_matches(am->name, m->name, RUNASALIAS)) {
|
if (alias_matches(parse_tree, am->name, m->name, RUNASALIAS)) {
|
||||||
TAILQ_REMOVE(runas_aliases, am, entries);
|
TAILQ_REMOVE(runas_aliases, am, entries);
|
||||||
free_member(am);
|
free_member(am);
|
||||||
}
|
}
|
||||||
@ -1021,7 +1027,7 @@ alias_used_by_userspecs(struct member_list *user_aliases,
|
|||||||
if (m->type == ALIAS) {
|
if (m->type == ALIAS) {
|
||||||
/* If alias is used, remove from runas_aliases and free. */
|
/* If alias is used, remove from runas_aliases and free. */
|
||||||
TAILQ_FOREACH_SAFE(am, runas_aliases, entries, am_next) {
|
TAILQ_FOREACH_SAFE(am, runas_aliases, entries, am_next) {
|
||||||
if (alias_matches(am->name, m->name, RUNASALIAS)) {
|
if (alias_matches(parse_tree, am->name, m->name, RUNASALIAS)) {
|
||||||
TAILQ_REMOVE(runas_aliases, am, entries);
|
TAILQ_REMOVE(runas_aliases, am, entries);
|
||||||
free_member(am);
|
free_member(am);
|
||||||
}
|
}
|
||||||
@ -1032,7 +1038,7 @@ alias_used_by_userspecs(struct member_list *user_aliases,
|
|||||||
if ((m = cs->cmnd)->type == ALIAS) {
|
if ((m = cs->cmnd)->type == ALIAS) {
|
||||||
/* If alias is used, remove from cmnd_aliases and free. */
|
/* If alias is used, remove from cmnd_aliases and free. */
|
||||||
TAILQ_FOREACH_SAFE(am, cmnd_aliases, entries, am_next) {
|
TAILQ_FOREACH_SAFE(am, cmnd_aliases, entries, am_next) {
|
||||||
if (alias_matches(am->name, m->name, CMNDALIAS)) {
|
if (alias_matches(parse_tree, am->name, m->name, CMNDALIAS)) {
|
||||||
TAILQ_REMOVE(cmnd_aliases, am, entries);
|
TAILQ_REMOVE(cmnd_aliases, am, entries);
|
||||||
free_member(am);
|
free_member(am);
|
||||||
}
|
}
|
||||||
@ -1049,7 +1055,8 @@ alias_used_by_userspecs(struct member_list *user_aliases,
|
|||||||
* Apply filters to host/user-based Defaults, removing non-matching entries.
|
* Apply filters to host/user-based Defaults, removing non-matching entries.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
filter_defaults(struct cvtsudoers_config *conf)
|
filter_defaults(struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
struct member_list user_aliases = TAILQ_HEAD_INITIALIZER(user_aliases);
|
struct member_list user_aliases = TAILQ_HEAD_INITIALIZER(user_aliases);
|
||||||
struct member_list runas_aliases = TAILQ_HEAD_INITIALIZER(runas_aliases);
|
struct member_list runas_aliases = TAILQ_HEAD_INITIALIZER(runas_aliases);
|
||||||
@ -1065,7 +1072,7 @@ filter_defaults(struct cvtsudoers_config *conf)
|
|||||||
if (filters == NULL && conf->defaults == CVT_DEFAULTS_ALL)
|
if (filters == NULL && conf->defaults == CVT_DEFAULTS_ALL)
|
||||||
debug_return;
|
debug_return;
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(def, &parsed_policy.defaults, entries, def_next) {
|
TAILQ_FOREACH_SAFE(def, &parse_tree->defaults, entries, def_next) {
|
||||||
bool keep = true;
|
bool keep = true;
|
||||||
|
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
@ -1076,7 +1083,7 @@ filter_defaults(struct cvtsudoers_config *conf)
|
|||||||
break;
|
break;
|
||||||
case DEFAULTS_USER:
|
case DEFAULTS_USER:
|
||||||
if (!ISSET(conf->defaults, CVT_DEFAULTS_USER) ||
|
if (!ISSET(conf->defaults, CVT_DEFAULTS_USER) ||
|
||||||
!userlist_matches_filter(def->binding, conf))
|
!userlist_matches_filter(parse_tree, def->binding, conf))
|
||||||
keep = false;
|
keep = false;
|
||||||
alias_type = USERALIAS;
|
alias_type = USERALIAS;
|
||||||
break;
|
break;
|
||||||
@ -1087,7 +1094,7 @@ filter_defaults(struct cvtsudoers_config *conf)
|
|||||||
break;
|
break;
|
||||||
case DEFAULTS_HOST:
|
case DEFAULTS_HOST:
|
||||||
if (!ISSET(conf->defaults, CVT_DEFAULTS_HOST) ||
|
if (!ISSET(conf->defaults, CVT_DEFAULTS_HOST) ||
|
||||||
!hostlist_matches_filter(def->binding, conf))
|
!hostlist_matches_filter(parse_tree, def->binding, conf))
|
||||||
keep = false;
|
keep = false;
|
||||||
alias_type = HOSTALIAS;
|
alias_type = HOSTALIAS;
|
||||||
break;
|
break;
|
||||||
@ -1129,14 +1136,14 @@ filter_defaults(struct cvtsudoers_config *conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TAILQ_REMOVE(&parsed_policy.defaults, def, entries);
|
TAILQ_REMOVE(&parse_tree->defaults, def, entries);
|
||||||
free_default(def, &prev_binding);
|
free_default(def, &prev_binding);
|
||||||
if (prev_binding != NULL) {
|
if (prev_binding != NULL) {
|
||||||
/* Remove and free Defaults that share the same binding. */
|
/* Remove and free Defaults that share the same binding. */
|
||||||
while (def_next != NULL && def_next->binding == prev_binding) {
|
while (def_next != NULL && def_next->binding == prev_binding) {
|
||||||
def = def_next;
|
def = def_next;
|
||||||
def_next = TAILQ_NEXT(def, entries);
|
def_next = TAILQ_NEXT(def, entries);
|
||||||
TAILQ_REMOVE(&parsed_policy.defaults, def, entries);
|
TAILQ_REMOVE(&parse_tree->defaults, def, entries);
|
||||||
free_default(def, &prev_binding);
|
free_default(def, &prev_binding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1146,25 +1153,25 @@ filter_defaults(struct cvtsudoers_config *conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove now-unreferenced aliases. */
|
/* Remove now-unreferenced aliases. */
|
||||||
alias_used_by_userspecs(&user_aliases, &runas_aliases, &host_aliases,
|
alias_used_by_userspecs(parse_tree, &user_aliases, &runas_aliases,
|
||||||
&cmnd_aliases);
|
&host_aliases, &cmnd_aliases);
|
||||||
TAILQ_FOREACH_SAFE(m, &user_aliases, entries, m_next) {
|
TAILQ_FOREACH_SAFE(m, &user_aliases, entries, m_next) {
|
||||||
a = alias_remove(&parsed_policy, m->name, USERALIAS);
|
a = alias_remove(parse_tree, m->name, USERALIAS);
|
||||||
alias_free(a);
|
alias_free(a);
|
||||||
free_member(m);
|
free_member(m);
|
||||||
}
|
}
|
||||||
TAILQ_FOREACH_SAFE(m, &runas_aliases, entries, m_next) {
|
TAILQ_FOREACH_SAFE(m, &runas_aliases, entries, m_next) {
|
||||||
a = alias_remove(&parsed_policy, m->name, RUNASALIAS);
|
a = alias_remove(parse_tree, m->name, RUNASALIAS);
|
||||||
alias_free(a);
|
alias_free(a);
|
||||||
free_member(m);
|
free_member(m);
|
||||||
}
|
}
|
||||||
TAILQ_FOREACH_SAFE(m, &host_aliases, entries, m_next) {
|
TAILQ_FOREACH_SAFE(m, &host_aliases, entries, m_next) {
|
||||||
a = alias_remove(&parsed_policy, m->name, HOSTALIAS);
|
a = alias_remove(parse_tree, m->name, HOSTALIAS);
|
||||||
alias_free(a);
|
alias_free(a);
|
||||||
free_member(m);
|
free_member(m);
|
||||||
}
|
}
|
||||||
TAILQ_FOREACH_SAFE(m, &cmnd_aliases, entries, m_next) {
|
TAILQ_FOREACH_SAFE(m, &cmnd_aliases, entries, m_next) {
|
||||||
a = alias_remove(&parsed_policy, m->name, CMNDALIAS);
|
a = alias_remove(parse_tree, m->name, CMNDALIAS);
|
||||||
alias_free(a);
|
alias_free(a);
|
||||||
free_member(m);
|
free_member(m);
|
||||||
}
|
}
|
||||||
@ -1176,7 +1183,7 @@ filter_defaults(struct cvtsudoers_config *conf)
|
|||||||
* Remove unreferenced aliases.
|
* Remove unreferenced aliases.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
alias_remove_unused(void)
|
alias_remove_unused(struct sudoers_parse_tree *parse_tree)
|
||||||
{
|
{
|
||||||
struct rbtree *used_aliases;
|
struct rbtree *used_aliases;
|
||||||
debug_decl(alias_remove_unused, SUDOERS_DEBUG_ALIAS)
|
debug_decl(alias_remove_unused, SUDOERS_DEBUG_ALIAS)
|
||||||
@ -1186,12 +1193,12 @@ alias_remove_unused(void)
|
|||||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
|
|
||||||
/* Move all referenced aliases to used_aliases. */
|
/* Move all referenced aliases to used_aliases. */
|
||||||
if (!alias_find_used(&parsed_policy, used_aliases))
|
if (!alias_find_used(parse_tree, used_aliases))
|
||||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
|
|
||||||
/* Only unreferenced aliases are left, swap and free the unused ones. */
|
/* Only unreferenced aliases are left, swap and free the unused ones. */
|
||||||
free_aliases(parsed_policy.aliases);
|
free_aliases(parse_tree->aliases);
|
||||||
parsed_policy.aliases = used_aliases;
|
parse_tree->aliases = used_aliases;
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
@ -1208,10 +1215,10 @@ alias_prune_helper(struct sudoers_parse_tree *parse_tree, struct alias *a,
|
|||||||
/* XXX - misue of these functions */
|
/* XXX - misue of these functions */
|
||||||
switch (a->type) {
|
switch (a->type) {
|
||||||
case USERALIAS:
|
case USERALIAS:
|
||||||
userlist_matches_filter(&a->members, conf);
|
userlist_matches_filter(parse_tree, &a->members, conf);
|
||||||
break;
|
break;
|
||||||
case HOSTALIAS:
|
case HOSTALIAS:
|
||||||
hostlist_matches_filter(&a->members, conf);
|
hostlist_matches_filter(parse_tree, &a->members, conf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1224,11 +1231,12 @@ alias_prune_helper(struct sudoers_parse_tree *parse_tree, struct alias *a,
|
|||||||
* Prune out non-matching entries from within aliases.
|
* Prune out non-matching entries from within aliases.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
alias_prune(struct cvtsudoers_config *conf)
|
alias_prune(struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
debug_decl(alias_prune, SUDOERS_DEBUG_ALIAS)
|
debug_decl(alias_prune, SUDOERS_DEBUG_ALIAS)
|
||||||
|
|
||||||
alias_apply(&parsed_policy, alias_prune_helper, conf);
|
alias_apply(parse_tree, alias_prune_helper, conf);
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
@ -1237,7 +1245,8 @@ alias_prune(struct cvtsudoers_config *conf)
|
|||||||
* Convert back to sudoers.
|
* Convert back to sudoers.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
convert_sudoers_sudoers(const char *output_file, struct cvtsudoers_config *conf)
|
convert_sudoers_sudoers(struct sudoers_parse_tree *parse_tree,
|
||||||
|
const char *output_file, struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
struct sudo_lbuf lbuf;
|
struct sudo_lbuf lbuf;
|
||||||
@ -1255,7 +1264,7 @@ convert_sudoers_sudoers(const char *output_file, struct cvtsudoers_config *conf)
|
|||||||
|
|
||||||
/* Print Defaults */
|
/* Print Defaults */
|
||||||
if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS)) {
|
if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS)) {
|
||||||
if (!print_defaults_sudoers(&lbuf, conf->expand_aliases))
|
if (!print_defaults_sudoers(parse_tree, &lbuf, conf->expand_aliases))
|
||||||
goto done;
|
goto done;
|
||||||
if (lbuf.len > 0) {
|
if (lbuf.len > 0) {
|
||||||
sudo_lbuf_print(&lbuf);
|
sudo_lbuf_print(&lbuf);
|
||||||
@ -1265,7 +1274,7 @@ convert_sudoers_sudoers(const char *output_file, struct cvtsudoers_config *conf)
|
|||||||
|
|
||||||
/* Print Aliases */
|
/* Print Aliases */
|
||||||
if (!conf->expand_aliases && !ISSET(conf->suppress, SUPPRESS_ALIASES)) {
|
if (!conf->expand_aliases && !ISSET(conf->suppress, SUPPRESS_ALIASES)) {
|
||||||
if (!print_aliases_sudoers(&lbuf))
|
if (!print_aliases_sudoers(parse_tree, &lbuf))
|
||||||
goto done;
|
goto done;
|
||||||
if (lbuf.len > 1) {
|
if (lbuf.len > 1) {
|
||||||
sudo_lbuf_print(&lbuf);
|
sudo_lbuf_print(&lbuf);
|
||||||
@ -1275,7 +1284,7 @@ convert_sudoers_sudoers(const char *output_file, struct cvtsudoers_config *conf)
|
|||||||
|
|
||||||
/* Print User_Specs, separated by blank lines. */
|
/* Print User_Specs, separated by blank lines. */
|
||||||
if (!ISSET(conf->suppress, SUPPRESS_PRIVS)) {
|
if (!ISSET(conf->suppress, SUPPRESS_PRIVS)) {
|
||||||
if (!sudoers_format_userspecs(&lbuf, &parsed_policy, "\n",
|
if (!sudoers_format_userspecs(&lbuf, parse_tree, "\n",
|
||||||
conf->expand_aliases, true)) {
|
conf->expand_aliases, true)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -94,11 +94,11 @@ struct cvtsudoers_string *cvtsudoers_string_alloc(const char *s);
|
|||||||
void cvtsudoers_string_free(struct cvtsudoers_string *ls);
|
void cvtsudoers_string_free(struct cvtsudoers_string *ls);
|
||||||
|
|
||||||
/* cvtsudoers_json.c */
|
/* cvtsudoers_json.c */
|
||||||
bool convert_sudoers_json(const char *output_file, struct cvtsudoers_config *conf);
|
bool convert_sudoers_json(struct sudoers_parse_tree *parse_tree, const char *output_file, struct cvtsudoers_config *conf);
|
||||||
|
|
||||||
/* cvtsudoers_ldif.c */
|
/* cvtsudoers_ldif.c */
|
||||||
bool convert_sudoers_ldif(const char *output_file, struct cvtsudoers_config *conf);
|
bool convert_sudoers_ldif(struct sudoers_parse_tree *parse_tree, const char *output_file, struct cvtsudoers_config *conf);
|
||||||
bool parse_ldif(const char *input_file, struct cvtsudoers_config *conf);
|
bool parse_ldif(struct sudoers_parse_tree *parse_tree, const char *input_file, struct cvtsudoers_config *conf);
|
||||||
void get_hostname(void);
|
void get_hostname(void);
|
||||||
|
|
||||||
/* cvtsudoers_pwutil.c */
|
/* cvtsudoers_pwutil.c */
|
||||||
|
@ -330,8 +330,9 @@ defaults_to_word_type(int defaults_type)
|
|||||||
* that closes the object.
|
* that closes the object.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_member_json_int(FILE *fp, char *name, int type, bool negated,
|
print_member_json_int(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
enum word_type word_type, bool last_one, int indent, bool expand_aliases)
|
char *name, int type, bool negated, enum word_type word_type,
|
||||||
|
bool last_one, int indent, bool expand_aliases)
|
||||||
{
|
{
|
||||||
struct json_value value;
|
struct json_value value;
|
||||||
const char *typestr = NULL;
|
const char *typestr = NULL;
|
||||||
@ -475,9 +476,9 @@ print_member_json_int(FILE *fp, char *name, int type, bool negated,
|
|||||||
struct alias *a;
|
struct alias *a;
|
||||||
struct member *m;
|
struct member *m;
|
||||||
|
|
||||||
if ((a = alias_get(&parsed_policy, value.u.string, alias_type)) != NULL) {
|
if ((a = alias_get(parse_tree, value.u.string, alias_type)) != NULL) {
|
||||||
TAILQ_FOREACH(m, &a->members, entries) {
|
TAILQ_FOREACH(m, &a->members, entries) {
|
||||||
print_member_json_int(fp, m->name, m->type,
|
print_member_json_int(fp, parse_tree, m->name, m->type,
|
||||||
negated ? !m->negated : m->negated,
|
negated ? !m->negated : m->negated,
|
||||||
alias_to_word_type(alias_type),
|
alias_to_word_type(alias_type),
|
||||||
last_one && TAILQ_NEXT(m, entries) == NULL, indent, true);
|
last_one && TAILQ_NEXT(m, entries) == NULL, indent, true);
|
||||||
@ -508,11 +509,12 @@ print_member_json_int(FILE *fp, char *name, int type, bool negated,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_member_json(FILE *fp, struct member *m, enum word_type word_type,
|
print_member_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
bool last_one, int indent, bool expand_aliases)
|
struct member *m, enum word_type word_type, bool last_one,
|
||||||
|
int indent, bool expand_aliases)
|
||||||
{
|
{
|
||||||
print_member_json_int(fp, m->name, m->type, m->negated, word_type,
|
print_member_json_int(fp, parse_tree, m->name, m->type, m->negated,
|
||||||
last_one, indent, expand_aliases);
|
word_type, last_one, indent, expand_aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -542,7 +544,7 @@ print_alias_json(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v
|
|||||||
|
|
||||||
closure->indent += 4;
|
closure->indent += 4;
|
||||||
TAILQ_FOREACH(m, &a->members, entries) {
|
TAILQ_FOREACH(m, &a->members, entries) {
|
||||||
print_member_json(closure->fp, m,
|
print_member_json(closure->fp, parse_tree, m,
|
||||||
alias_to_word_type(closure->alias_type),
|
alias_to_word_type(closure->alias_type),
|
||||||
TAILQ_NEXT(m, entries) == NULL, closure->indent, false);
|
TAILQ_NEXT(m, entries) == NULL, closure->indent, false);
|
||||||
}
|
}
|
||||||
@ -554,7 +556,8 @@ print_alias_json(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v
|
|||||||
* Print the binding for a Defaults entry of the specified type.
|
* Print the binding for a Defaults entry of the specified type.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_binding_json(FILE *fp, struct member_list *binding, int type, int indent, bool expand_aliases)
|
print_binding_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct member_list *binding, int type, int indent, bool expand_aliases)
|
||||||
{
|
{
|
||||||
struct member *m;
|
struct member *m;
|
||||||
debug_decl(print_binding_json, SUDOERS_DEBUG_UTIL)
|
debug_decl(print_binding_json, SUDOERS_DEBUG_UTIL)
|
||||||
@ -567,7 +570,7 @@ print_binding_json(FILE *fp, struct member_list *binding, int type, int indent,
|
|||||||
|
|
||||||
/* Print each member object in binding. */
|
/* Print each member object in binding. */
|
||||||
TAILQ_FOREACH(m, binding, entries) {
|
TAILQ_FOREACH(m, binding, entries) {
|
||||||
print_member_json(fp, m, defaults_to_word_type(type),
|
print_member_json(fp, parse_tree, m, defaults_to_word_type(type),
|
||||||
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,20 +656,21 @@ get_defaults_type(struct defaults *def)
|
|||||||
* Export all Defaults in JSON format.
|
* Export all Defaults in JSON format.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
print_defaults_json(FILE *fp, int indent, bool expand_aliases, bool need_comma)
|
print_defaults_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
int indent, bool expand_aliases, bool need_comma)
|
||||||
{
|
{
|
||||||
struct json_value value;
|
struct json_value value;
|
||||||
struct defaults *def, *next;
|
struct defaults *def, *next;
|
||||||
int type;
|
int type;
|
||||||
debug_decl(print_defaults_json, SUDOERS_DEBUG_UTIL)
|
debug_decl(print_defaults_json, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
if (TAILQ_EMPTY(&parsed_policy.defaults))
|
if (TAILQ_EMPTY(&parse_tree->defaults))
|
||||||
debug_return_bool(need_comma);
|
debug_return_bool(need_comma);
|
||||||
|
|
||||||
fprintf(fp, "%s\n%*s\"Defaults\": [\n", need_comma ? "," : "", indent, "");
|
fprintf(fp, "%s\n%*s\"Defaults\": [\n", need_comma ? "," : "", indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(def, &parsed_policy.defaults, entries, next) {
|
TAILQ_FOREACH_SAFE(def, &parse_tree->defaults, entries, next) {
|
||||||
type = get_defaults_type(def);
|
type = get_defaults_type(def);
|
||||||
if (type == -1) {
|
if (type == -1) {
|
||||||
sudo_warnx(U_("unknown defaults entry \"%s\""), def->var);
|
sudo_warnx(U_("unknown defaults entry \"%s\""), def->var);
|
||||||
@ -677,7 +681,8 @@ print_defaults_json(FILE *fp, int indent, bool expand_aliases, bool need_comma)
|
|||||||
/* Found it, print object container and binding (if any). */
|
/* Found it, print object container and binding (if any). */
|
||||||
fprintf(fp, "%*s{\n", indent, "");
|
fprintf(fp, "%*s{\n", indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
print_binding_json(fp, def->binding, def->type, indent, expand_aliases);
|
print_binding_json(fp, parse_tree, def->binding, def->type,
|
||||||
|
indent, expand_aliases);
|
||||||
|
|
||||||
/* Validation checks. */
|
/* Validation checks. */
|
||||||
/* XXX - validate values in addition to names? */
|
/* XXX - validate values in addition to names? */
|
||||||
@ -732,8 +737,8 @@ print_defaults_json(FILE *fp, int indent, bool expand_aliases, bool need_comma)
|
|||||||
* Iterates through the entire aliases tree.
|
* Iterates through the entire aliases tree.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
print_aliases_by_type_json(FILE *fp, int alias_type, const char *title,
|
print_aliases_by_type_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
int indent, bool need_comma)
|
int alias_type, const char *title, int indent, bool need_comma)
|
||||||
{
|
{
|
||||||
struct json_alias_closure closure;
|
struct json_alias_closure closure;
|
||||||
debug_decl(print_aliases_by_type_json, SUDOERS_DEBUG_UTIL)
|
debug_decl(print_aliases_by_type_json, SUDOERS_DEBUG_UTIL)
|
||||||
@ -744,7 +749,7 @@ print_aliases_by_type_json(FILE *fp, int alias_type, const char *title,
|
|||||||
closure.alias_type = alias_type;
|
closure.alias_type = alias_type;
|
||||||
closure.title = title;
|
closure.title = title;
|
||||||
closure.need_comma = need_comma;
|
closure.need_comma = need_comma;
|
||||||
alias_apply(&parsed_policy, print_alias_json, &closure);
|
alias_apply(parse_tree, print_alias_json, &closure);
|
||||||
if (closure.count != 0) {
|
if (closure.count != 0) {
|
||||||
print_indent(fp, closure.indent);
|
print_indent(fp, closure.indent);
|
||||||
fputs("]\n", fp);
|
fputs("]\n", fp);
|
||||||
@ -761,18 +766,19 @@ print_aliases_by_type_json(FILE *fp, int alias_type, const char *title,
|
|||||||
* Export all aliases in JSON format.
|
* Export all aliases in JSON format.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
print_aliases_json(FILE *fp, int indent, bool need_comma)
|
print_aliases_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
int indent, bool need_comma)
|
||||||
{
|
{
|
||||||
debug_decl(print_aliases_json, SUDOERS_DEBUG_UTIL)
|
debug_decl(print_aliases_json, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
need_comma = print_aliases_by_type_json(fp, USERALIAS, "User_Aliases",
|
need_comma = print_aliases_by_type_json(fp, parse_tree, USERALIAS,
|
||||||
indent, need_comma);
|
"User_Aliases", indent, need_comma);
|
||||||
need_comma = print_aliases_by_type_json(fp, RUNASALIAS, "Runas_Aliases",
|
need_comma = print_aliases_by_type_json(fp, parse_tree, RUNASALIAS,
|
||||||
indent, need_comma);
|
"Runas_Aliases", indent, need_comma);
|
||||||
need_comma = print_aliases_by_type_json(fp, HOSTALIAS, "Host_Aliases",
|
need_comma = print_aliases_by_type_json(fp, parse_tree, HOSTALIAS,
|
||||||
indent, need_comma);
|
"Host_Aliases", indent, need_comma);
|
||||||
need_comma = print_aliases_by_type_json(fp, CMNDALIAS, "Command_Aliases",
|
need_comma = print_aliases_by_type_json(fp, parse_tree, CMNDALIAS,
|
||||||
indent, need_comma);
|
"Command_Aliases", indent, need_comma);
|
||||||
|
|
||||||
debug_return_bool(need_comma);
|
debug_return_bool(need_comma);
|
||||||
}
|
}
|
||||||
@ -783,7 +789,8 @@ print_aliases_json(FILE *fp, int indent, bool need_comma)
|
|||||||
* merge adjacent entries that are identical in all but the command.
|
* merge adjacent entries that are identical in all but the command.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_cmndspec_json(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp,
|
print_cmndspec_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct cmndspec *cs, struct cmndspec **nextp,
|
||||||
struct defaults_list *options, bool expand_aliases, int indent)
|
struct defaults_list *options, bool expand_aliases, int indent)
|
||||||
{
|
{
|
||||||
struct cmndspec *next = *nextp;
|
struct cmndspec *next = *nextp;
|
||||||
@ -804,7 +811,7 @@ print_cmndspec_json(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp,
|
|||||||
fprintf(fp, "%*s\"runasusers\": [\n", indent, "");
|
fprintf(fp, "%*s\"runasusers\": [\n", indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
||||||
print_member_json(fp, m, TYPE_RUNASUSER,
|
print_member_json(fp, parse_tree, m, TYPE_RUNASUSER,
|
||||||
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
||||||
}
|
}
|
||||||
indent -= 4;
|
indent -= 4;
|
||||||
@ -816,7 +823,7 @@ print_cmndspec_json(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp,
|
|||||||
fprintf(fp, "%*s\"runasgroups\": [\n", indent, "");
|
fprintf(fp, "%*s\"runasgroups\": [\n", indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
||||||
print_member_json(fp, m, TYPE_RUNASGROUP,
|
print_member_json(fp, parse_tree, m, TYPE_RUNASGROUP,
|
||||||
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
||||||
}
|
}
|
||||||
indent -= 4;
|
indent -= 4;
|
||||||
@ -997,7 +1004,7 @@ print_cmndspec_json(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp,
|
|||||||
#endif /* HAVE_SELINUX */
|
#endif /* HAVE_SELINUX */
|
||||||
;
|
;
|
||||||
|
|
||||||
print_member_json(fp, cs->cmnd, TYPE_COMMAND,
|
print_member_json(fp, parse_tree, cs->cmnd, TYPE_COMMAND,
|
||||||
last_one, indent, expand_aliases);
|
last_one, indent, expand_aliases);
|
||||||
if (last_one)
|
if (last_one)
|
||||||
break;
|
break;
|
||||||
@ -1020,7 +1027,8 @@ print_cmndspec_json(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp,
|
|||||||
* Print a User_Spec in JSON format at the specified indent level.
|
* Print a User_Spec in JSON format at the specified indent level.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_userspec_json(FILE *fp, struct userspec *us, int indent, bool expand_aliases)
|
print_userspec_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct userspec *us, int indent, bool expand_aliases)
|
||||||
{
|
{
|
||||||
struct privilege *priv;
|
struct privilege *priv;
|
||||||
struct member *m;
|
struct member *m;
|
||||||
@ -1041,7 +1049,7 @@ print_userspec_json(FILE *fp, struct userspec *us, int indent, bool expand_alias
|
|||||||
fprintf(fp, "%*s\"User_List\": [\n", indent, "");
|
fprintf(fp, "%*s\"User_List\": [\n", indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
TAILQ_FOREACH(m, &us->users, entries) {
|
TAILQ_FOREACH(m, &us->users, entries) {
|
||||||
print_member_json(fp, m, TYPE_USERNAME,
|
print_member_json(fp, parse_tree, m, TYPE_USERNAME,
|
||||||
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
||||||
}
|
}
|
||||||
indent -= 4;
|
indent -= 4;
|
||||||
@ -1051,7 +1059,7 @@ print_userspec_json(FILE *fp, struct userspec *us, int indent, bool expand_alias
|
|||||||
fprintf(fp, "%*s\"Host_List\": [\n", indent, "");
|
fprintf(fp, "%*s\"Host_List\": [\n", indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
TAILQ_FOREACH(m, &priv->hostlist, entries) {
|
TAILQ_FOREACH(m, &priv->hostlist, entries) {
|
||||||
print_member_json(fp, m, TYPE_HOSTNAME,
|
print_member_json(fp, parse_tree, m, TYPE_HOSTNAME,
|
||||||
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
TAILQ_NEXT(m, entries) == NULL, indent, expand_aliases);
|
||||||
}
|
}
|
||||||
indent -= 4;
|
indent -= 4;
|
||||||
@ -1061,7 +1069,7 @@ print_userspec_json(FILE *fp, struct userspec *us, int indent, bool expand_alias
|
|||||||
fprintf(fp, "%*s\"Cmnd_Specs\": [\n", indent, "");
|
fprintf(fp, "%*s\"Cmnd_Specs\": [\n", indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, next) {
|
TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, next) {
|
||||||
print_cmndspec_json(fp, cs, &next, &priv->defaults,
|
print_cmndspec_json(fp, parse_tree, cs, &next, &priv->defaults,
|
||||||
expand_aliases, indent);
|
expand_aliases, indent);
|
||||||
}
|
}
|
||||||
indent -= 4;
|
indent -= 4;
|
||||||
@ -1077,18 +1085,19 @@ print_userspec_json(FILE *fp, struct userspec *us, int indent, bool expand_alias
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
print_userspecs_json(FILE *fp, int indent, bool expand_aliases, bool need_comma)
|
print_userspecs_json(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
int indent, bool expand_aliases, bool need_comma)
|
||||||
{
|
{
|
||||||
struct userspec *us;
|
struct userspec *us;
|
||||||
debug_decl(print_userspecs_json, SUDOERS_DEBUG_UTIL)
|
debug_decl(print_userspecs_json, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
if (TAILQ_EMPTY(&parsed_policy.userspecs))
|
if (TAILQ_EMPTY(&parse_tree->userspecs))
|
||||||
debug_return_bool(need_comma);
|
debug_return_bool(need_comma);
|
||||||
|
|
||||||
fprintf(fp, "%s\n%*s\"User_Specs\": [\n", need_comma ? "," : "", indent, "");
|
fprintf(fp, "%s\n%*s\"User_Specs\": [\n", need_comma ? "," : "", indent, "");
|
||||||
indent += 4;
|
indent += 4;
|
||||||
TAILQ_FOREACH(us, &parsed_policy.userspecs, entries) {
|
TAILQ_FOREACH(us, &parse_tree->userspecs, entries) {
|
||||||
print_userspec_json(fp, us, indent, expand_aliases);
|
print_userspec_json(fp, parse_tree, us, indent, expand_aliases);
|
||||||
}
|
}
|
||||||
indent -= 4;
|
indent -= 4;
|
||||||
fprintf(fp, "%*s]", indent, "");
|
fprintf(fp, "%*s]", indent, "");
|
||||||
@ -1100,7 +1109,8 @@ print_userspecs_json(FILE *fp, int indent, bool expand_aliases, bool need_comma)
|
|||||||
* Export the parsed sudoers file in JSON format.
|
* Export the parsed sudoers file in JSON format.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
convert_sudoers_json(const char *output_file, struct cvtsudoers_config *conf)
|
convert_sudoers_json(struct sudoers_parse_tree *parse_tree,
|
||||||
|
const char *output_file, struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
bool ret = true, need_comma = false;
|
bool ret = true, need_comma = false;
|
||||||
const int indent = 4;
|
const int indent = 4;
|
||||||
@ -1117,18 +1127,20 @@ convert_sudoers_json(const char *output_file, struct cvtsudoers_config *conf)
|
|||||||
|
|
||||||
/* Dump Defaults in JSON format. */
|
/* Dump Defaults in JSON format. */
|
||||||
if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS)) {
|
if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS)) {
|
||||||
need_comma = print_defaults_json(output_fp, indent,
|
need_comma = print_defaults_json(output_fp, parse_tree, indent,
|
||||||
conf->expand_aliases, need_comma);
|
conf->expand_aliases, need_comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump Aliases in JSON format. */
|
/* Dump Aliases in JSON format. */
|
||||||
if (!conf->expand_aliases && !ISSET(conf->suppress, SUPPRESS_ALIASES))
|
if (!conf->expand_aliases && !ISSET(conf->suppress, SUPPRESS_ALIASES)) {
|
||||||
need_comma = print_aliases_json(output_fp, indent, need_comma);
|
need_comma = print_aliases_json(output_fp, parse_tree, indent,
|
||||||
|
need_comma);
|
||||||
|
}
|
||||||
|
|
||||||
/* Dump User_Specs in JSON format. */
|
/* Dump User_Specs in JSON format. */
|
||||||
if (!ISSET(conf->suppress, SUPPRESS_PRIVS)) {
|
if (!ISSET(conf->suppress, SUPPRESS_PRIVS)) {
|
||||||
print_userspecs_json(output_fp, indent, conf->expand_aliases,
|
print_userspecs_json(output_fp, parse_tree, indent,
|
||||||
need_comma);
|
conf->expand_aliases, need_comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close JSON output. */
|
/* Close JSON output. */
|
||||||
|
@ -157,7 +157,8 @@ print_options_ldif(FILE *fp, struct defaults_list *options)
|
|||||||
* Print global Defaults in a single sudoRole object.
|
* Print global Defaults in a single sudoRole object.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
print_global_defaults_ldif(FILE *fp, const char *base)
|
print_global_defaults_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
const char *base)
|
||||||
{
|
{
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
struct sudo_lbuf lbuf;
|
struct sudo_lbuf lbuf;
|
||||||
@ -167,14 +168,14 @@ print_global_defaults_ldif(FILE *fp, const char *base)
|
|||||||
|
|
||||||
sudo_lbuf_init(&lbuf, NULL, 0, NULL, 80);
|
sudo_lbuf_init(&lbuf, NULL, 0, NULL, 80);
|
||||||
|
|
||||||
TAILQ_FOREACH(opt, &parsed_policy.defaults, entries) {
|
TAILQ_FOREACH(opt, &parse_tree->defaults, entries) {
|
||||||
/* Skip bound Defaults (unsupported). */
|
/* Skip bound Defaults (unsupported). */
|
||||||
if (opt->type == DEFAULTS) {
|
if (opt->type == DEFAULTS) {
|
||||||
count++;
|
count++;
|
||||||
} else {
|
} else {
|
||||||
lbuf.len = 0;
|
lbuf.len = 0;
|
||||||
sudo_lbuf_append(&lbuf, "# ");
|
sudo_lbuf_append(&lbuf, "# ");
|
||||||
sudoers_format_default_line(&lbuf, &parsed_policy, opt, false, true);
|
sudoers_format_default_line(&lbuf, parse_tree, opt, false, true);
|
||||||
fprintf(fp, "# Unable to translate %s:%d\n%s\n",
|
fprintf(fp, "# Unable to translate %s:%d\n%s\n",
|
||||||
opt->file, opt->lineno, lbuf.buf);
|
opt->file, opt->lineno, lbuf.buf);
|
||||||
}
|
}
|
||||||
@ -195,7 +196,7 @@ print_global_defaults_ldif(FILE *fp, const char *base)
|
|||||||
print_attribute_ldif(fp, "cn", "defaults");
|
print_attribute_ldif(fp, "cn", "defaults");
|
||||||
print_attribute_ldif(fp, "description", "Default sudoOption's go here");
|
print_attribute_ldif(fp, "description", "Default sudoOption's go here");
|
||||||
|
|
||||||
print_options_ldif(fp, &parsed_policy.defaults);
|
print_options_ldif(fp, &parse_tree->defaults);
|
||||||
putc('\n', fp);
|
putc('\n', fp);
|
||||||
|
|
||||||
debug_return_bool(!ferror(fp));
|
debug_return_bool(!ferror(fp));
|
||||||
@ -206,8 +207,8 @@ print_global_defaults_ldif(FILE *fp, const char *base)
|
|||||||
* See print_member_int() in parse.c.
|
* See print_member_int() in parse.c.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_member_ldif(FILE *fp, char *name, int type, bool negated,
|
print_member_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree, char *name,
|
||||||
int alias_type, const char *attr_name)
|
int type, bool negated, int alias_type, const char *attr_name)
|
||||||
{
|
{
|
||||||
struct alias *a;
|
struct alias *a;
|
||||||
struct member *m;
|
struct member *m;
|
||||||
@ -239,9 +240,9 @@ print_member_ldif(FILE *fp, char *name, int type, bool negated,
|
|||||||
free(attr_val);
|
free(attr_val);
|
||||||
break;
|
break;
|
||||||
case ALIAS:
|
case ALIAS:
|
||||||
if ((a = alias_get(&parsed_policy, name, alias_type)) != NULL) {
|
if ((a = alias_get(parse_tree, name, alias_type)) != NULL) {
|
||||||
TAILQ_FOREACH(m, &a->members, entries) {
|
TAILQ_FOREACH(m, &a->members, entries) {
|
||||||
print_member_ldif(fp, m->name, m->type,
|
print_member_ldif(fp, parse_tree, m->name, m->type,
|
||||||
negated ? !m->negated : m->negated, alias_type, attr_name);
|
negated ? !m->negated : m->negated, alias_type, attr_name);
|
||||||
}
|
}
|
||||||
alias_put(a);
|
alias_put(a);
|
||||||
@ -268,7 +269,8 @@ print_member_ldif(FILE *fp, char *name, int type, bool negated,
|
|||||||
* merge adjacent entries that are identical in all but the command.
|
* merge adjacent entries that are identical in all but the command.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_cmndspec_ldif(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp, struct defaults_list *options)
|
print_cmndspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct cmndspec *cs, struct cmndspec **nextp, struct defaults_list *options)
|
||||||
{
|
{
|
||||||
struct cmndspec *next = *nextp;
|
struct cmndspec *next = *nextp;
|
||||||
struct member *m;
|
struct member *m;
|
||||||
@ -280,7 +282,7 @@ print_cmndspec_ldif(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp, stru
|
|||||||
/* Print runasuserlist as sudoRunAsUser attributes */
|
/* Print runasuserlist as sudoRunAsUser attributes */
|
||||||
if (cs->runasuserlist != NULL) {
|
if (cs->runasuserlist != NULL) {
|
||||||
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
||||||
print_member_ldif(fp, m->name, m->type, m->negated,
|
print_member_ldif(fp, parse_tree, m->name, m->type, m->negated,
|
||||||
RUNASALIAS, "sudoRunAsUser");
|
RUNASALIAS, "sudoRunAsUser");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,7 +290,7 @@ print_cmndspec_ldif(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp, stru
|
|||||||
/* Print runasgrouplist as sudoRunAsGroup attributes */
|
/* Print runasgrouplist as sudoRunAsGroup attributes */
|
||||||
if (cs->runasgrouplist != NULL) {
|
if (cs->runasgrouplist != NULL) {
|
||||||
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
||||||
print_member_ldif(fp, m->name, m->type, m->negated,
|
print_member_ldif(fp, parse_tree, m->name, m->type, m->negated,
|
||||||
RUNASALIAS, "sudoRunAsGroup");
|
RUNASALIAS, "sudoRunAsGroup");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,8 +439,8 @@ print_cmndspec_ldif(FILE *fp, struct cmndspec *cs, struct cmndspec **nextp, stru
|
|||||||
#endif /* HAVE_SELINUX */
|
#endif /* HAVE_SELINUX */
|
||||||
;
|
;
|
||||||
|
|
||||||
print_member_ldif(fp, cs->cmnd->name, cs->cmnd->type, cs->cmnd->negated,
|
print_member_ldif(fp, parse_tree, cs->cmnd->name, cs->cmnd->type,
|
||||||
CMNDALIAS, "sudoCommand");
|
cs->cmnd->negated, CMNDALIAS, "sudoCommand");
|
||||||
if (last_one)
|
if (last_one)
|
||||||
break;
|
break;
|
||||||
cs = next;
|
cs = next;
|
||||||
@ -532,7 +534,8 @@ bad:
|
|||||||
* Print a single User_Spec.
|
* Print a single User_Spec.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
print_userspec_ldif(FILE *fp, struct userspec *us, struct cvtsudoers_config *conf)
|
print_userspec_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct userspec *us, struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
struct privilege *priv;
|
struct privilege *priv;
|
||||||
struct member *m;
|
struct member *m;
|
||||||
@ -568,16 +571,16 @@ print_userspec_ldif(FILE *fp, struct userspec *us, struct cvtsudoers_config *con
|
|||||||
free(dn);
|
free(dn);
|
||||||
|
|
||||||
TAILQ_FOREACH(m, &us->users, entries) {
|
TAILQ_FOREACH(m, &us->users, entries) {
|
||||||
print_member_ldif(fp, m->name, m->type, m->negated,
|
print_member_ldif(fp, parse_tree, m->name, m->type, m->negated,
|
||||||
USERALIAS, "sudoUser");
|
USERALIAS, "sudoUser");
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH(m, &priv->hostlist, entries) {
|
TAILQ_FOREACH(m, &priv->hostlist, entries) {
|
||||||
print_member_ldif(fp, m->name, m->type, m->negated,
|
print_member_ldif(fp, parse_tree, m->name, m->type, m->negated,
|
||||||
HOSTALIAS, "sudoHost");
|
HOSTALIAS, "sudoHost");
|
||||||
}
|
}
|
||||||
|
|
||||||
print_cmndspec_ldif(fp, cs, &next, &priv->defaults);
|
print_cmndspec_ldif(fp, parse_tree, cs, &next, &priv->defaults);
|
||||||
|
|
||||||
if (conf->sudo_order != 0) {
|
if (conf->sudo_order != 0) {
|
||||||
char numbuf[(((sizeof(conf->sudo_order) * 8) + 2) / 3) + 2];
|
char numbuf[(((sizeof(conf->sudo_order) * 8) + 2) / 3) + 2];
|
||||||
@ -596,13 +599,14 @@ print_userspec_ldif(FILE *fp, struct userspec *us, struct cvtsudoers_config *con
|
|||||||
* Print User_Specs.
|
* Print User_Specs.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
print_userspecs_ldif(FILE *fp, struct cvtsudoers_config *conf)
|
print_userspecs_ldif(FILE *fp, struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
struct userspec *us;
|
struct userspec *us;
|
||||||
debug_decl(print_userspecs_ldif, SUDOERS_DEBUG_UTIL)
|
debug_decl(print_userspecs_ldif, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
TAILQ_FOREACH(us, &parsed_policy.userspecs, entries) {
|
TAILQ_FOREACH(us, &parse_tree->userspecs, entries) {
|
||||||
if (!print_userspec_ldif(fp, us, conf))
|
if (!print_userspec_ldif(fp, parse_tree, us, conf))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
@ -612,7 +616,8 @@ print_userspecs_ldif(FILE *fp, struct cvtsudoers_config *conf)
|
|||||||
* Export the parsed sudoers file in LDIF format.
|
* Export the parsed sudoers file in LDIF format.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
convert_sudoers_ldif(const char *output_file, struct cvtsudoers_config *conf)
|
convert_sudoers_ldif(struct sudoers_parse_tree *parse_tree,
|
||||||
|
const char *output_file, struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
FILE *output_fp = stdout;
|
FILE *output_fp = stdout;
|
||||||
@ -632,11 +637,11 @@ convert_sudoers_ldif(const char *output_file, struct cvtsudoers_config *conf)
|
|||||||
|
|
||||||
/* Dump global Defaults in LDIF format. */
|
/* Dump global Defaults in LDIF format. */
|
||||||
if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS))
|
if (!ISSET(conf->suppress, SUPPRESS_DEFAULTS))
|
||||||
print_global_defaults_ldif(output_fp, conf->sudoers_base);
|
print_global_defaults_ldif(output_fp, parse_tree, conf->sudoers_base);
|
||||||
|
|
||||||
/* Dump User_Specs in LDIF format, expanding Aliases. */
|
/* Dump User_Specs in LDIF format, expanding Aliases. */
|
||||||
if (!ISSET(conf->suppress, SUPPRESS_PRIVS))
|
if (!ISSET(conf->suppress, SUPPRESS_PRIVS))
|
||||||
print_userspecs_ldif(output_fp, conf);
|
print_userspecs_ldif(output_fp, parse_tree, conf);
|
||||||
|
|
||||||
/* Clean up. */
|
/* Clean up. */
|
||||||
rbdestroy(seen_users, seen_user_free);
|
rbdestroy(seen_users, seen_user_free);
|
||||||
@ -834,7 +839,8 @@ role_order_cmp(const void *va, const void *vb)
|
|||||||
* Parse list of sudoOption and store in global defaults list.
|
* Parse list of sudoOption and store in global defaults list.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ldif_store_options(struct cvtsudoers_str_list *options)
|
ldif_store_options(struct sudoers_parse_tree *parse_tree,
|
||||||
|
struct cvtsudoers_str_list *options)
|
||||||
{
|
{
|
||||||
struct defaults *d;
|
struct defaults *d;
|
||||||
struct cvtsudoers_string *ls;
|
struct cvtsudoers_string *ls;
|
||||||
@ -860,7 +866,7 @@ ldif_store_options(struct cvtsudoers_str_list *options)
|
|||||||
U_("unable to allocate memory"));
|
U_("unable to allocate memory"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TAILQ_INSERT_TAIL(&parsed_policy.defaults, d, entries);
|
TAILQ_INSERT_TAIL(&parse_tree->defaults, d, entries);
|
||||||
}
|
}
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
@ -913,8 +919,9 @@ str_list_cache(struct rbtree *cache, struct cvtsudoers_str_list **strlistp)
|
|||||||
* data structures.
|
* data structures.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
role_to_sudoers(struct sudo_role *role, bool store_options,
|
role_to_sudoers(struct sudoers_parse_tree *parse_tree, struct sudo_role *role,
|
||||||
bool reuse_userspec, bool reuse_privilege, bool reuse_runas)
|
bool store_options, bool reuse_userspec, bool reuse_privilege,
|
||||||
|
bool reuse_runas)
|
||||||
{
|
{
|
||||||
struct privilege *priv;
|
struct privilege *priv;
|
||||||
struct cvtsudoers_string *ls;
|
struct cvtsudoers_string *ls;
|
||||||
@ -928,7 +935,7 @@ role_to_sudoers(struct sudo_role *role, bool store_options,
|
|||||||
|
|
||||||
if (reuse_userspec) {
|
if (reuse_userspec) {
|
||||||
/* Re-use the previous userspec */
|
/* Re-use the previous userspec */
|
||||||
us = TAILQ_LAST(&parsed_policy.userspecs, userspec_list);
|
us = TAILQ_LAST(&parse_tree->userspecs, userspec_list);
|
||||||
} else {
|
} else {
|
||||||
/* Allocate a new userspec and fill in the user list. */
|
/* Allocate a new userspec and fill in the user list. */
|
||||||
if ((us = calloc(1, sizeof(*us))) == NULL) {
|
if ((us = calloc(1, sizeof(*us))) == NULL) {
|
||||||
@ -1039,7 +1046,7 @@ role_to_sudoers(struct sudo_role *role, bool store_options,
|
|||||||
|
|
||||||
/* Add finished userspec to the list if new. */
|
/* Add finished userspec to the list if new. */
|
||||||
if (!reuse_userspec)
|
if (!reuse_userspec)
|
||||||
TAILQ_INSERT_TAIL(&parsed_policy.userspecs, us, entries);
|
TAILQ_INSERT_TAIL(&parse_tree->userspecs, us, entries);
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
@ -1049,8 +1056,8 @@ role_to_sudoers(struct sudo_role *role, bool store_options,
|
|||||||
* store in the global sudoers data structures.
|
* store in the global sudoers data structures.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ldif_to_sudoers(struct sudo_role_list *roles, unsigned int numroles,
|
ldif_to_sudoers(struct sudoers_parse_tree *parse_tree,
|
||||||
bool store_options)
|
struct sudo_role_list *roles, unsigned int numroles, bool store_options)
|
||||||
{
|
{
|
||||||
struct sudo_role **role_array, *role = NULL;
|
struct sudo_role **role_array, *role = NULL;
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
@ -1098,7 +1105,7 @@ ldif_to_sudoers(struct sudo_role_list *roles, unsigned int numroles,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
role_to_sudoers(role, store_options, reuse_userspec,
|
role_to_sudoers(parse_tree, role, store_options, reuse_userspec,
|
||||||
reuse_privilege, reuse_runas);
|
reuse_privilege, reuse_runas);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1138,10 +1145,12 @@ char *unquote_cn(const char *src)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a sudoers file in LDIF format, https://tools.ietf.org/html/rfc2849
|
* Parse a sudoers file in LDIF format, https://tools.ietf.org/html/rfc2849
|
||||||
* Parsed sudoRole objects are stored in the global sudoers data structures.
|
* Parsed sudoRole objects are stored in the specified parse_tree which
|
||||||
|
* must already be initialized.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
|
parse_ldif(struct sudoers_parse_tree *parse_tree, const char *input_file,
|
||||||
|
struct cvtsudoers_config *conf)
|
||||||
{
|
{
|
||||||
struct sudo_role_list roles = STAILQ_HEAD_INITIALIZER(roles);
|
struct sudo_role_list roles = STAILQ_HEAD_INITIALIZER(roles);
|
||||||
struct sudo_role *role = NULL;
|
struct sudo_role *role = NULL;
|
||||||
@ -1161,7 +1170,9 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
|
|||||||
input_file = "stdin";
|
input_file = "stdin";
|
||||||
} else if ((fp = fopen(input_file, "r")) == NULL)
|
} else if ((fp = fopen(input_file, "r")) == NULL)
|
||||||
sudo_fatal(U_("unable to open %s"), input_file);
|
sudo_fatal(U_("unable to open %s"), input_file);
|
||||||
init_parser(input_file, false);
|
|
||||||
|
/* Free old contents of the parse tree (if any). */
|
||||||
|
free_parse_tree(parse_tree);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We cache user, group and host lists to make it eay to detect when there
|
* We cache user, group and host lists to make it eay to detect when there
|
||||||
@ -1188,7 +1199,7 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
|
|||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
if (in_role) {
|
if (in_role) {
|
||||||
if (role->cn != NULL && strcmp(role->cn, "defaults") == 0) {
|
if (role->cn != NULL && strcmp(role->cn, "defaults") == 0) {
|
||||||
ldif_store_options(role->options);
|
ldif_store_options(parse_tree, role->options);
|
||||||
sudo_role_free(role);
|
sudo_role_free(role);
|
||||||
role = NULL;
|
role = NULL;
|
||||||
} else if (STAILQ_EMPTY(role->users) ||
|
} else if (STAILQ_EMPTY(role->users) ||
|
||||||
@ -1374,7 +1385,7 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
|
|||||||
free(line);
|
free(line);
|
||||||
|
|
||||||
/* Convert from roles to sudoers data structures. */
|
/* Convert from roles to sudoers data structures. */
|
||||||
ldif_to_sudoers(&roles, numroles, conf->store_options);
|
ldif_to_sudoers(parse_tree, &roles, numroles, conf->store_options);
|
||||||
|
|
||||||
/* Clean up. */
|
/* Clean up. */
|
||||||
rbdestroy(usercache, str_list_free);
|
rbdestroy(usercache, str_list_free);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user