/* * Copyright (c) 1996, 1998-2000, 2004, 2007-2013 * 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 * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _SUDOERS_PARSE_H #define _SUDOERS_PARSE_H #undef UNSPEC #define UNSPEC -1 #undef DENY #define DENY 0 #undef ALLOW #define ALLOW 1 #undef IMPLIED #define IMPLIED 2 #define SUDO_DIGEST_SHA224 0 #define SUDO_DIGEST_SHA256 1 #define SUDO_DIGEST_SHA384 2 #define SUDO_DIGEST_SHA512 3 #define SUDO_DIGEST_INVALID 4 struct sudo_digest { int digest_type; char *digest_str; }; /* * A command with option args and digest. * XXX - merge into struct member */ struct sudo_command { char *cmnd; char *args; struct sudo_digest *digest; }; /* * Tags associated with a command. * Possible values: true, false, IMPLIED, UNSPEC. */ struct cmndtag { __signed int nopasswd: 3; __signed int noexec: 3; __signed int setenv: 3; __signed int log_input: 3; __signed int log_output: 3; }; /* * SELinux-specific container struct. * Currently just contains a role and type. */ struct selinux_info { char *role; char *type; }; /* * Solaris privileges container struct * Currently just contains permitted and limit privileges. * It could have PFEXEC and PRIV_AWARE flags added in the future. */ struct solaris_privs_info { char *privs; char *limitprivs; }; /* * The parsed sudoers file is stored as a collection of linked lists, * modelled after the yacc grammar. * * Other than the alias struct, which is stored in a red-black tree, * the data structure used is basically a doubly-linked tail queue without * a separate head struct--the first entry acts as the head where the prev * pointer does double duty as the tail pointer. This makes it possible * to trivally append sub-lists. In addition, the prev pointer is always * valid (even if it points to itself). Unlike a circle queue, the next * pointer of the last entry is NULL and does not point back to the head. * * Note that each list struct must contain a "prev" and "next" pointer as * the first two members of the struct (in that order). */ /* * Tail queue list head structure. */ TQ_DECLARE(defaults) TQ_DECLARE(userspec) TQ_DECLARE(member) TQ_DECLARE(privilege) TQ_DECLARE(cmndspec) /* * Structure describing a user specification and list thereof. */ struct userspec { struct userspec *prev, *next; struct member_list users; /* list of users */ struct privilege_list privileges; /* list of privileges */ }; /* * Structure describing a privilege specification. */ struct privilege { struct privilege *prev, *next; struct member_list hostlist; /* list of hosts */ struct cmndspec_list cmndlist; /* list of Cmnd_Specs */ }; /* * Structure describing a linked list of Cmnd_Specs. */ struct cmndspec { struct cmndspec *prev, *next; struct member_list runasuserlist; /* list of runas users */ struct member_list runasgrouplist; /* list of runas groups */ struct member *cmnd; /* command to allow/deny */ char *digest; /* optional command digest */ struct cmndtag tags; /* tag specificaion */ #ifdef HAVE_SELINUX char *role, *type; /* SELinux role and type */ #endif #ifdef HAVE_PRIV_SET char *privs, *limitprivs; /* Solaris privilege sets */ #endif }; /* * Generic structure to hold users, hosts, commands. */ struct member { struct member *prev, *next; char *name; /* member name */ short type; /* type (see gram.h) */ short negated; /* negated via '!'? */ }; struct runascontainer { struct member *runasusers; struct member *runasgroups; }; /* * Generic structure to hold {User,Host,Runas,Cmnd}_Alias * Aliases are stored in a red-black tree, sorted by name and type. */ struct alias { char *name; /* alias name */ unsigned short type; /* {USER,HOST,RUNAS,CMND}ALIAS */ bool used; /* "used" flag for cycle detection */ struct member_list members; /* list of alias members */ }; /* * Structure describing a Defaults entry and a list thereof. */ struct defaults { struct defaults *prev, *next; char *var; /* variable name */ char *val; /* variable value */ struct member_list binding; /* user/host/runas binding */ int type; /* DEFAULTS{,_USER,_RUNAS,_HOST} */ int op; /* true, false, '+', '-' */ }; /* * Parsed sudoers info. */ extern struct userspec_list userspecs; extern struct defaults_list defaults; /* alias.c */ bool no_aliases(void); char *alias_add(char *name, int type, struct member *members); int alias_compare(const void *a1, const void *a2); struct alias *alias_get(char *name, int type); struct alias *alias_remove(char *name, int type); void alias_apply(int (*func)(void *, void *), void *cookie); void alias_free(void *a); void alias_put(struct alias *a); void init_aliases(void); /* gram.c */ void init_parser(const char *, bool); /* match_addr.c */ bool addr_matches(char *n); /* match.c */ bool command_matches(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest); bool group_matches(char *sudoers_group, struct group *gr); bool hostname_matches(char *shost, char *lhost, char *pattern); bool netgr_matches(char *netgr, char *lhost, char *shost, char *user); bool usergr_matches(char *group, char *user, struct passwd *pw); bool userpw_matches(char *sudoers_user, char *user, struct passwd *pw); int cmnd_matches(struct member *m); int cmndlist_matches(struct member_list *list); int hostlist_matches(struct member_list *list); int runaslist_matches(struct member_list *user_list, struct member_list *group_list, struct member **matching_user, struct member **matching_group); int userlist_matches(struct passwd *pw, struct member_list *list); /* toke.c */ void init_lexer(void); /* hexchar.c */ int hexchar(const char *s); /* base64.c */ size_t base64_decode(const char *str, unsigned char *dst, size_t dsize); #endif /* _SUDOERS_PARSE_H */