/* split the line to command and arguments */ static char *line_get_command(const char *line, char **args, int aliases) { const char *ptr, *cmdargs; char *cmd, *checkcmd; g_return_val_if_fail(line != NULL, NULL); g_return_val_if_fail(args != NULL, NULL); cmd = checkcmd = NULL; *args = ""; cmdargs = NULL; ptr = line; do { ptr = strchr(ptr, ' '); if (ptr == NULL) { checkcmd = g_strdup(line); cmdargs = ""; } else { checkcmd = g_strndup(line, (int) (ptr-line)); while (*ptr == ' ') ptr++; cmdargs = ptr; } if (aliases ? !alias_find(checkcmd) : !command_find(checkcmd)) { /* not found, use the previous */ g_free(checkcmd); break; } /* found, check if it has subcommands */ g_free_not_null(cmd); if (!aliases) cmd = checkcmd; else { cmd = g_strdup(alias_find(checkcmd)); g_free(checkcmd); } *args = (char *) cmdargs; } while (ptr != NULL); if (cmd != NULL) ascii_strdown(cmd); return cmd; }
static void sig_complete_alias(GList **list, WINDOW_REC *window, const char *word, const char *line, int *want_space) { const char *definition; g_return_if_fail(list != NULL); g_return_if_fail(word != NULL); g_return_if_fail(line != NULL); if (*line != '\0') { if ((definition = alias_find(line)) != NULL) { *list = g_list_append(NULL, g_strdup(definition)); signal_stop(); } } else { *list = completion_get_aliases(word); if (*list != NULL) signal_stop(); } }
/* * Check for host and shost in a list of members. * Returns ALLOW, DENY or UNSPEC. */ static int _hostlist_matches(struct member_list *list) { struct member *m; struct alias *a; int rval, matched = UNSPEC; tq_foreach_rev(list, m) { switch (m->type) { case ALL: matched = !m->negated; break; case NETGROUP: if (netgr_matches(m->name, user_host, user_shost, NULL)) matched = !m->negated; break; case NTWKADDR: if (addr_matches(m->name)) matched = !m->negated; break; case ALIAS: if ((a = alias_find(m->name, HOSTALIAS)) != NULL) { rval = _hostlist_matches(&a->members); if (rval != UNSPEC) matched = m->negated ? !rval : rval; break; } /* FALLTHROUGH */ case WORD: if (hostname_matches(user_shost, user_host, m->name)) matched = !m->negated; break; } if (matched != UNSPEC) break; } return matched; }
/* * Check for user described by pw in a list of members. * Returns ALLOW, DENY or UNSPEC. */ static int _userlist_matches(struct passwd *pw, struct member_list *list) { struct member *m; struct alias *a; int rval, matched = UNSPEC; tq_foreach_rev(list, m) { switch (m->type) { case ALL: matched = !m->negated; break; case NETGROUP: if (netgr_matches(m->name, NULL, NULL, pw->pw_name)) matched = !m->negated; break; case USERGROUP: if (usergr_matches(m->name, pw->pw_name, pw)) matched = !m->negated; break; case ALIAS: if ((a = alias_find(m->name, USERALIAS)) != NULL) { rval = _userlist_matches(pw, &a->members); if (rval != UNSPEC) matched = m->negated ? !rval : rval; break; } /* FALLTHROUGH */ case WORD: if (userpw_matches(m->name, pw->pw_name, pw)) matched = !m->negated; break; } if (matched != UNSPEC) break; } return matched; }
/* * Check for user described by pw in a list of members. * If both lists are empty compare against def_runas_default. * Returns ALLOW, DENY or UNSPEC. */ static int _runaslist_matches(struct member_list *user_list, struct member_list *group_list) { struct member *m; struct alias *a; int rval; int user_matched = UNSPEC; int group_matched = UNSPEC; if (runas_pw != NULL) { /* If no runas user or runas group listed in sudoers, use default. */ if (tq_empty(user_list) && tq_empty(group_list)) return userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw); tq_foreach_rev(user_list, m) { switch (m->type) { case ALL: user_matched = !m->negated; break; case NETGROUP: if (netgr_matches(m->name, NULL, NULL, runas_pw->pw_name)) user_matched = !m->negated; break; case USERGROUP: if (usergr_matches(m->name, runas_pw->pw_name, runas_pw)) user_matched = !m->negated; break; case ALIAS: if ((a = alias_find(m->name, RUNASALIAS)) != NULL) { rval = _runaslist_matches(&a->members, &empty); if (rval != UNSPEC) user_matched = m->negated ? !rval : rval; break; } /* FALLTHROUGH */ case WORD: if (userpw_matches(m->name, runas_pw->pw_name, runas_pw)) user_matched = !m->negated; break; } if (user_matched != UNSPEC) break; } } if (runas_gr != NULL) { if (user_matched == UNSPEC) { if (runas_pw == NULL || strcmp(runas_pw->pw_name, user_name) == 0) user_matched = ALLOW; /* only changing group */ } tq_foreach_rev(group_list, m) { switch (m->type) { case ALL: group_matched = !m->negated; break; case ALIAS: if ((a = alias_find(m->name, RUNASALIAS)) != NULL) { rval = _runaslist_matches(&a->members, &empty); if (rval != UNSPEC) group_matched = m->negated ? !rval : rval; break; } /* FALLTHROUGH */ case WORD: if (group_matches(m->name, runas_gr)) group_matched = !m->negated; break; } if (group_matched != UNSPEC) break; } if (group_matched == UNSPEC) { if (runas_pw != NULL && runas_pw->pw_gid == runas_gr->gr_gid) group_matched = ALLOW; /* runas group matches passwd db */ } } if (user_matched == DENY || group_matched == DENY) return DENY; if (user_matched == group_matched || runas_gr == NULL) return user_matched; return UNSPEC; }