From cfc1147a5ace11382be8dfbce8b4bac74fa13634 Mon Sep 17 00:00:00 2001 From: Arun Scaria Date: Mon, 22 Aug 2011 22:27:02 +0530 Subject: Sudo evaluation works properly. But, sudo options not supported --- Makefile.am | 4 +- src/db/sysdb.h | 8 + src/responder/sudo/match_sudo.h | 31 ++ src/responder/sudo/match_sudo_cmnd.c | 131 +++++++ src/responder/sudo/sudosrv.c | 541 +++++++++++++++++++++++++--- src/responder/sudo/sudosrv.h | 67 +++- src/sbus/sssd_dbus_messages_helpers.c | 54 ++- src/sbus/sssd_dbus_messages_helpers.h | 24 +- src/sss_client/sudo_plugin/missing.h | 50 --- src/sss_client/sudo_plugin/sss_sudo_cli.h | 39 +- src/sss_client/sudo_plugin/sss_sudoplugin.c | 497 ++++++++++++++----------- 11 files changed, 1097 insertions(+), 349 deletions(-) create mode 100644 src/responder/sudo/match_sudo.h create mode 100644 src/responder/sudo/match_sudo_cmnd.c delete mode 100644 src/sss_client/sudo_plugin/missing.h diff --git a/Makefile.am b/Makefile.am index 0d764ba9..c6ccdcf3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -405,6 +405,7 @@ sssd_pam_LDADD = \ sssd_sudo_SOURCES = \ src/responder/sudo/sudosrv.c \ + src/responder/sudo/match_sudo_cmnd.c \ $(SSSD_RESPONDER_OBJ) sssd_sudo_LDADD = \ $(TDB_LIBS) \ @@ -780,8 +781,7 @@ dist_noinst_DATA += \ libsss_sudoplugin_LTLIBRARIES = libsss_sudoplugin.la libsss_sudoplugin_la_SOURCES = \ src/sss_client/sudo_plugin/sss_sudoplugin.c \ - src/sss_client/sudo_plugin/sss_sudo_cli.h \ - src/sss_client/sudo_plugin/missing.h + src/sss_client/sudo_plugin/sss_sudo_cli.h libsss_sudoplugin_la_LDFLAGS = \ -module \ diff --git a/src/db/sysdb.h b/src/db/sysdb.h index e0ad4c8e..795bfd0f 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -61,6 +61,14 @@ #define SYSDB_SUDO_ORDER_ATTR "sudoOrder" #define SYSDB_SUDO_DEFAULT_RULE "defaults" +#define SYSDB_SUDO_DEFAULT_RUNAS_USER_NAME "root" +#define SYSDB_SUDO_DEFAULT_RUNAS_USER_ID 0 +#define SYSDB_SUDO_DEFAULT_RUNAS_USER_ID_STR "0" + +#define SYSDB_SUDO_DEFAULT_RUNAS_GROUP_NAME "root" +#define SYSDB_SUDO_DEFAULT_RUNAS_GROUP_ID 0 +#define SYSDB_SUDO_DEFAULT_RUNAS_GROUP_ID_STR "0" + #define SYSDB_SUDO_USER_MATCH_ATTR "("SYSDB_SUDO_USER_ATTR"=%s)" #define SYSDB_NAME "name" diff --git a/src/responder/sudo/match_sudo.h b/src/responder/sudo/match_sudo.h new file mode 100644 index 00000000..baeabac2 --- /dev/null +++ b/src/responder/sudo/match_sudo.h @@ -0,0 +1,31 @@ +/* + SSSD + + Authors: + Arun Scaria + + Copyright (C) 2011 Arun Scaria + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + */ + + +#ifndef MATCH_SUDO_H_ +#define MATCH_SUDO_H_ + + +#define SUDO_MATCH_TRUE 1 +#define SUDO_MATCH_FALSE 0 + +#endif /* MATCH_SUDO_H_ */ diff --git a/src/responder/sudo/match_sudo_cmnd.c b/src/responder/sudo/match_sudo_cmnd.c new file mode 100644 index 00000000..ea5e4829 --- /dev/null +++ b/src/responder/sudo/match_sudo_cmnd.c @@ -0,0 +1,131 @@ + /* + SSSD + + SUDO Responder - match_sudo_cmnd.c + + Copyright (C) Arun Scaria (2011) + + Courtesy : The idea and the base logic for this module is derived from + the sudo source writtern by Todd C. Miller . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "match_sudo.h" + +#define has_meta(s) (strpbrk((s), "\\?*[]") != NULL) + + +int command_args_match(char *sudoers_cmnd, + char *sudoers_args, + char *user_cmnd, + char *user_args) { + int flags = 0; + + /* + * If no args specified in sudoers, any user args are allowed. + * If the empty string is specified in sudoers, no user args are allowed. + */ + if (!sudoers_args || + (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args))) + return SUDO_MATCH_TRUE; + /* + * If args are specified in sudoers, they must match the user args. + * If running as sudoedit, all args are assumed to be paths. + */ + if (sudoers_args) { + /* For sudoedit, all args are assumed to be pathnames. */ + if (strcmp(sudoers_cmnd, "sudoedit") == 0) + flags = FNM_PATHNAME; + if (fnmatch(sudoers_args, user_args ? user_args : "", flags) == 0) + return SUDO_MATCH_TRUE; + } + return SUDO_MATCH_FALSE; +} + +int command_matches_fnmatch(TALLOC_CTX * memctx, + char *sudoers_cmnd, + char *sudoers_args, + char *user_cmnd, + char *user_args, + char ** safe_cmnd, + char ** safe_args) { + /* + * Return true if fnmatch(3) succeeds AND + * a) there are no args in sudoers OR + * b) there are no args on command line and none required by sudoers OR + * c) there are args in sudoers and on command line and they match + * else return false. + */ + if (fnmatch(sudoers_cmnd, user_cmnd, FNM_PATHNAME) != 0) + return SUDO_MATCH_FALSE; + if (command_args_match(sudoers_cmnd, sudoers_args,user_cmnd,user_args)) { + *safe_cmnd = talloc_strdup(memctx,user_cmnd); + *safe_args = talloc_strdup(memctx,user_args); + return SUDO_MATCH_TRUE; + } else + return SUDO_MATCH_FALSE; +} + + +int command_matches(TALLOC_CTX * memctx, + char *sudoers_cmnd, + char *sudoers_args, + char *user_cmnd, + char *user_args, + char ** safe_cmnd, + char ** safe_args) +{ + /* Check for pseudo-commands */ + if (sudoers_cmnd[0] != '/') { + /* + * Return true if both sudoers_cmnd and user_cmnd are "sudoedit" AND + * a) there are no args in sudoers OR + * b) there are no args on command line and none req by sudoers OR + * c) there are args in sudoers and on command line and they match + */ + if (strcmp(sudoers_cmnd, "sudoedit") != 0 || + strcmp(user_cmnd, "sudoedit") != 0) + return SUDO_MATCH_FALSE; + if (command_args_match(sudoers_cmnd, sudoers_args,user_cmnd,user_args)){ + *safe_cmnd = talloc_strdup(memctx, sudoers_cmnd); + *safe_args = talloc_strdup(memctx, sudoers_args); + return SUDO_MATCH_TRUE; + } else + return SUDO_MATCH_FALSE; + } + + // if (has_meta(sudoers_cmnd)) { + /* + * If sudoers_cmnd has meta characters in it, we need to + * use glob(3) and/or fnmatch(3) to do the matching. + */ + return command_matches_fnmatch(memctx,sudoers_cmnd, sudoers_args,user_cmnd,user_args,safe_cmnd, safe_args); + // } + //return command_matches_normal(sudoers_cmnd, sudoers_args,user_cmnd,user_args); +} + + + diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c index 2f0a7e09..6b5a9538 100644 --- a/src/responder/sudo/sudosrv.c +++ b/src/responder/sudo/sudosrv.c @@ -46,23 +46,13 @@ #include "responder/common/responder_packet.h" #include "responder/sudo/sudosrv.h" +#include "match_sudo.h" #include "sss_client/sudo_plugin/sss_sudo_cli.h" #include "sbus/sbus_client.h" #include "responder/common/responder_packet.h" #include "providers/data_provider.h" #include "monitor/monitor_interfaces.h" -#define FILTER_APPEND_CHECK(filter_in,filter_out, append_str, str_arg) \ - do { \ - filter_out = talloc_asprintf_append(filter_in,append_str, str_arg); \ - if (!filter_out) { \ - DEBUG(0, ("Failed to build filter\n")); \ - ret = ENOMEM; \ - goto done; \ - } \ - }while(0); - - static int sudo_client_destructor(void *ctx) { @@ -101,8 +91,13 @@ char * get_host_name(TALLOC_CTX* mem_ctx){ errno_t prepare_filter( TALLOC_CTX * mem_ctx, const char * username, uid_t user_id, + const char * runas_user, + uid_t runas_uid, + const char * runas_group, + gid_t runas_gid, char * host, struct ldb_result *groups_res, + struct ldb_result *groups_res_runas, char ** filter_out) { int i,ret=EOK; @@ -116,25 +111,46 @@ errno_t prepare_filter( TALLOC_CTX * mem_ctx, goto done; } - FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_USER_ATTR"=#%d)",user_id); + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_USER_ATTR"=#%u)",user_id); - FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_USER_ATTR"=+*)",NULL); + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_USER_ATTR"=%s)","+*"); for(i=0;i< groups_res->count;i++){ group_name = ldb_msg_find_attr_as_string(groups_res->msgs[i], SYSDB_NAME, NULL); if( !group_name){ DEBUG(0,("Failed to get group name from group search result")); - ret = ENOENT; - goto done; + /* Not fatal */ } FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_USER_ATTR"=%%%s)",group_name); } - FILTER_APPEND_CHECK(filter,filter,")(|("SYSDB_SUDO_HOST_ATTR"=+*)",NULL); + FILTER_APPEND_CHECK(filter,filter,")(|("SYSDB_SUDO_HOST_ATTR"=%s)","+*"); - FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_HOST_ATTR"=ALL)",NULL); + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_HOST_ATTR"=%s)","ALL"); FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_HOST_ATTR"=%s))",host); + FILTER_APPEND_CHECK(filter,filter,"(|(|("SYSDB_SUDO_RUNAS_USER_ATTR"=%s)",runas_user); + + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_RUNAS_USER_ATTR"=#%u)",runas_uid); + + for(i=0;i< groups_res_runas->count;i++){ + group_name = ldb_msg_find_attr_as_string(groups_res_runas->msgs[i], SYSDB_NAME, NULL); + if( !group_name){ + DEBUG(0,("Failed to get group name from runas group search result")); + /* Not fatal */ + } + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_RUNAS_USER_ATTR"=%%%s)",group_name); + } + + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_RUNAS_USER_ATTR"=%s)","+*"); + + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_RUNAS_USER_ATTR"=%s))","ALL"); + + FILTER_APPEND_CHECK(filter,filter,"(|("SYSDB_SUDO_RUNAS_GROUP_ATTR"=%s)",runas_group); + + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_RUNAS_GROUP_ATTR"=#%u)",runas_gid); + + FILTER_APPEND_CHECK(filter,filter,"("SYSDB_SUDO_RUNAS_GROUP_ATTR"=%s)))","ALL"); done: *filter_out = filter; @@ -394,11 +410,87 @@ errno_t eliminate_sudorules_by_sudouser_netgroups(TALLOC_CTX * mem_ctx, } +errno_t eliminate_sudorules_by_sudo_runasuser_netgroups(TALLOC_CTX * mem_ctx, + struct sss_sudorule_list ** head, + const char * user_name, + const char * domain_name) { + + + struct sss_sudorule_list * list_head = *head , *current_node, *tmp_node; + struct ldb_message_element *el; + int flag =0; + int i=0, valid_user_count = 0; + char * tmpuser; + + DEBUG(0,("\n\n\nIn rule elimination based on runas user net groups\n")); + current_node = list_head; + while(current_node != NULL) { + DEBUG(0, ("\n--sudoOrder: %f\n", + ldb_msg_find_attr_as_double((struct ldb_message *)current_node->data, + SYSDB_SUDO_ORDER_ATTR, + 0.0))); + DEBUG(0, ("--dn: %s----\n", + ldb_dn_get_linearized(((struct ldb_message *)current_node->data)->dn))); + el = ldb_msg_find_element((struct ldb_message *)current_node->data, + SYSDB_SUDO_USER_ATTR); + + if (!el) { + DEBUG(0, ("Failed to get sudo hosts for sudorule [%s]\n", + ldb_dn_get_linearized(((struct ldb_message *)current_node->data)->dn))); + DLIST_REMOVE(list_head,current_node); + continue; + } + flag = 0; + /* + * TODO: The elimination of sudo rules based on hosts an user net groups depends + * on the innetgr(). This makes the code less efficient since we are calling the + * sssd in loop. Find a good solution to resolve the membserNisnetgroup attribute. + * + * CAUTION: Most of the contents of the netgroup is stored on LDAP. But they leave + * a generic memberNisNetgroup entry in the LDAP entry, so that if the local machine + * chooses, they can add an "override" locally. So there's no guarantee that + * memberNisNetgroup maps to something else on the LDAP server. + * + */ + + for (i = 0; i < el->num_values; i++) { + + DEBUG(0, ("sudoUser: %s\n" ,(const char *) (el->values[i].data))); + tmpuser = ( char *) (el->values[i].data); + if(tmpuser[0] == '+'){ + tmpuser++; + if(innetgr(tmpuser,NULL,user_name,domain_name) == 1){ + flag = 1; + } + } + else{ + valid_user_count++; + break; + } + } + + if(flag == 1 || valid_user_count > 0){ + current_node = current_node -> next; + continue; + } + tmp_node = current_node->next; + DLIST_REMOVE(list_head,current_node); + current_node = tmp_node; + } + *head = list_head; + DEBUG(0,("Rule elimination based on runas user net groups is over\n")); + return EOK; +} + errno_t search_sudo_rules(struct sudo_client *sudocli, struct sysdb_ctx *sysdb, struct sss_domain_info * domain, const char * user_name, uid_t user_id, + const char * runas_user, + uid_t runas_uid, + const char * runas_group, + gid_t runas_gid, struct sss_sudo_msg_contents *sudo_msg, struct sss_valid_sudorules **valid_sudorules_out) { TALLOC_CTX *tmp_mem_ctx; @@ -420,7 +512,7 @@ errno_t search_sudo_rules(struct sudo_client *sudocli, char * filter_default = NULL; struct ldb_message **sudo_rules_msgs; struct ldb_message **default_rule; - struct ldb_result *res; + struct ldb_result *res, *res_runas; int ret; size_t count = 0, count_default = 0; int i = 0; @@ -441,10 +533,20 @@ errno_t search_sudo_rules(struct sudo_client *sudocli, user_name, &res); if (ret) { - if (ret == ENOENT) { - ret = EOK; - } - goto done; + DEBUG(0, ("Failed to get groups of the requested sudoUser \n")); + if(ret != ENOENT) + goto done; + } + + ret = sysdb_get_groups_by_user(tmp_mem_ctx, + sysdb, + domain, + runas_user, + &res_runas); + if (ret) { + DEBUG(0, ("Failed to get groups of the runas sudoUser \n")); + if(ret != ENOENT) + goto done; } host = get_host_name(tmp_mem_ctx); @@ -454,14 +556,14 @@ errno_t search_sudo_rules(struct sudo_client *sudocli, } DEBUG(0, ("Host - %s\n",host)); - filter_default = talloc_asprintf(tmp_mem_ctx,SYSDB_SUDO_CONTAINER_ATTR"="SYSDB_SUDO_DEFAULT_RULE); + filter_default = talloc_asprintf(tmp_mem_ctx,"%s=%s",SYSDB_SUDO_CONTAINER_ATTR,SYSDB_SUDO_DEFAULT_RULE); if (!filter_default) { DEBUG(0, ("Failed to build filter for default rule \n")); ret = ENOMEM; goto done; } - ret = prepare_filter(tmp_mem_ctx,user_name,user_id,host,res,&filter); + ret = prepare_filter(tmp_mem_ctx,user_name,user_id, runas_user, runas_uid, runas_group, runas_gid, host, res, res_runas, &filter); if (ret!=EOK) { DEBUG(0, ("Failed to build filter(Non default) - %s\n",filter)); goto done; @@ -599,15 +701,21 @@ errno_t search_sudo_rules(struct sudo_client *sudocli, errno_t find_sudorules_for_user_in_db_list(TALLOC_CTX * ctx, struct sudo_client *sudocli, - struct sss_sudo_msg_contents * sudo_msg) { + struct sss_sudo_msg_contents * sudo_msg, + struct sss_valid_sudorules ** valid_sudorules) { struct sysdb_ctx **sysdblist; - struct ldb_message *ldb_msg; + struct ldb_message *ldb_msg = NULL , * ldb_msg_runas_ctx = NULL; size_t no_ldbs = 0; const char *attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, NULL}; + const char *attrs_group[] = { SYSDB_NAME, SYSDB_GIDNUM, NULL}; uid_t user_id; int i = 0,ret; const char * user_name; struct sss_valid_sudorules * res_sudorules_valid; + const char * runas_user , * runas_group; + uid_t runas_uid = 0; + gid_t runas_gid = 0; + sysdblist = sudocli->sudoctx->rctx->db_list->dbs; no_ldbs = sudocli->sudoctx->rctx->db_list->num_dbs; @@ -639,16 +747,100 @@ errno_t find_sudorules_for_user_in_db_list(TALLOC_CTX * ctx, } user_name = ldb_msg_find_attr_as_string(ldb_msg, SYSDB_NAME, NULL); - user_id = ldb_msg_find_attr_as_uint64(ldb_msg, SYSDB_UIDNUM, 0); - if ( user_name == NULL || user_id == 0){ - DEBUG(0, ("Error in getting user_name and user id. fatal error")); + user_id = sudo_msg->userid; + if ( user_name == NULL){ + DEBUG(0, ("Error in getting user_name. fatal error")); return ENOENT; } + if(sudo_msg->runas_user != NULL){ + if(sudo_msg->runas_user[0] == '#'){ + runas_uid = atoi(sudo_msg->runas_user+1); + ret = sysdb_search_user_by_uid(ctx, + sysdblist[i], + sysdblist[i]->domain, + runas_uid, + attrs, + &ldb_msg_runas_ctx); + if(ret != EOK || ldb_msg_runas_ctx == NULL){ + DEBUG(0,("The runas user with uid(%d) is not found - Fatal\n",runas_uid)); + return ENOENT; + } + runas_user = ldb_msg_find_attr_as_string(ldb_msg_runas_ctx,SYSDB_NAME, NULL); + } + else { + runas_user = sudo_msg->runas_user; + ret = sysdb_search_user_by_name(ctx, + sysdblist[i], + sysdblist[i]->domain, + runas_user, + attrs, + &ldb_msg_runas_ctx); + if(ret != EOK || ldb_msg_runas_ctx == NULL){ + DEBUG(0,("The runas user with uid(%d) is not found - Fatal\n",runas_uid)); + return ENOENT; + } + runas_uid = ldb_msg_find_attr_as_uint64(ldb_msg_runas_ctx, SYSDB_UIDNUM, -1 ); + } + + if(runas_user == NULL || runas_uid == -1 ){ + DEBUG(0, ("User requested to run as some user, but granted to be super user - Fatal \n")); + return ENOENT; + } + } + else { + runas_user = SYSDB_SUDO_DEFAULT_RUNAS_USER_NAME; + runas_uid = SYSDB_SUDO_DEFAULT_RUNAS_USER_ID; + } + + if(sudo_msg->runas_group != NULL){ + if(sudo_msg->runas_group[0] == '#'){ + runas_gid = atoi(sudo_msg->runas_group+1); + ret = sysdb_search_group_by_gid(ctx, + sysdblist[i], + sysdblist[i]->domain, + runas_gid, + attrs_group, + &ldb_msg_runas_ctx); + if(ret != EOK || ldb_msg_runas_ctx == NULL){ + DEBUG(0,("The runas group with gid(%d) is not found - Fatal\n",runas_gid)); + return ENOENT; + } + runas_group = ldb_msg_find_attr_as_string(ldb_msg_runas_ctx, SYSDB_NAME, NULL); + } + else { + runas_group = sudo_msg->runas_group; + ret = sysdb_search_user_by_name(ctx, + sysdblist[i], + sysdblist[i]->domain, + runas_group, + attrs_group, + &ldb_msg_runas_ctx); + if(ret != EOK || ldb_msg_runas_ctx == NULL){ + DEBUG(0,("The runas group with gid(%d) is not found - Fatal\n",runas_gid)); + return ENOENT; + } + runas_gid = ldb_msg_find_attr_as_uint64(ldb_msg_runas_ctx, SYSDB_UIDNUM, -1); + } + + if( runas_group == NULL || runas_gid == -1) { + DEBUG(0, ("User requested to run as some group, but granted to be super user group - Fatal \n")); + return ENOENT; + } + } + else { + runas_group = SYSDB_SUDO_DEFAULT_RUNAS_GROUP_NAME; + runas_gid = SYSDB_SUDO_DEFAULT_RUNAS_GROUP_ID; + } + ret = search_sudo_rules(sudocli, sysdblist[i], sysdblist[i]->domain, "tom"/*user_name*/, user_id, + runas_user, + runas_uid, + runas_group, + runas_gid, sudo_msg, &res_sudorules_valid); if(ret != EOK){ @@ -658,11 +850,213 @@ errno_t find_sudorules_for_user_in_db_list(TALLOC_CTX * ctx, if(res_sudorules_valid == NULL || res_sudorules_valid->non_defaults == NULL){ /* All the rules are eliminated and nothing left for evaluation */ DEBUG(0, ("No rule left for evaluation\n")); + return ENOENT; } + *valid_sudorules = res_sudorules_valid; /* Do the evaluation now */ + return ret; +} - return ret; +errno_t load_settings( hash_table_t *settings_table,struct sss_sudo_msg_contents *contents){ + + + hash_table_t * local_table = NULL; + hash_entry_t *entry; + struct hash_iter_context_t *iter; + + if( !settings_table ) { + DEBUG(0,("Table is not valid.")); + return SSS_SBUS_DHASH_NULL; + } + local_table = settings_table; + + iter = new_hash_iter_context(local_table); + while ((entry = iter->next(iter)) != NULL) { + + if(entry->key.type != HASH_KEY_STRING && entry->value.type != HASH_VALUE_PTR) { + DEBUG(0,("fatal: Unexpected hashtable")); + return SSS_SBUS_DHASH_INVALID; + } + + CHECK_KEY_AND_SET_MESSAGE_STR(entry->key.str, + SSS_SUDO_ITEM_RUSER, + contents->runas_user, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_STR(entry->key.str, + SSS_SUDO_ITEM_RGROUP, + contents->runas_group, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_STR(entry->key.str, + SSS_SUDO_ITEM_PROMPT, + contents->prompt, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_STR(entry->key.str, + SSS_SUDO_ITEM_NETADDR, + contents->network_addrs, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_SUDOEDIT, + contents->use_sudoedit, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_SETHOME, + contents->use_set_home, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_PRESERV_ENV , + contents->use_preserve_environment, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_IMPLIED_SHELL, + contents->use_implied_shell, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_LOGIN_SHELL, + contents->use_login_shell, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_RUN_SHELL, + contents->use_run_shell, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_PRE_GROUPS, + contents->use_preserve_groups, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_IGNORE_TICKET, + contents->use_ignore_ticket, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_USE_NON_INTERACTIVE, + contents->use_noninteractive, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_DEBUG_LEVEL, + contents->debug_level, + ((char *) entry->value.ptr)); + CHECK_KEY_AND_SET_MESSAGE_INT(entry->key.str, + SSS_SUDO_ITEM_CLI_PID, + contents->cli_pid, + ((char *) entry->value.ptr)); + } + free(iter); + return SSS_SBUS_CONV_SUCCESS; +} + +errno_t evaluate_sudo_valid_rules(TALLOC_CTX* mem_ctx, + struct sss_valid_sudorules * valid_rules, + char * user_cmnd, + char * user_args, + char ** safe_cmnd, + char ** safe_args, + unsigned int * access){ + + struct sss_sudorule_list * list_head = valid_rules->non_defaults , *current_node; + struct ldb_message_element *el; + int i=0; + char * tmpcmd, *space; + struct sudo_cmd_ctx * sudo_cmnd; + struct sss_sudo_command_list * list_cmnds_head = NULL, *list_cmnds_node; + + *access = SUDO_DENY_ACCESS; + DEBUG(0,("\n\n\nIn rule evaluation based on commands\n")); + sudo_cmnd = talloc_zero(mem_ctx,struct sudo_cmd_ctx); + if(!sudo_cmnd){ + DEBUG(0,("Failed to allocate command structure.\n")); + return ENOMEM; + } + current_node = list_head; + while(current_node != NULL) { + + el = ldb_msg_find_element(current_node->data, + SYSDB_SUDO_COMMAND_ATTR); + if (!el) { + DEBUG(0, ("Failed to get sudo commands for sudorule\n")); + } + for (i = 0; i < el->num_values; i++) { + tmpcmd = talloc_asprintf(mem_ctx, + "%s", + (const char *) (el->values[i].data)); + if (!tmpcmd) { + DEBUG(0, ("Failed to build commands string - dn: %s\n", + ldb_dn_get_linearized(current_node->data->dn))); + return ENOMEM; + } + /* + * Make a list of commands inside an entry with commands with negation in the + * front of the list and the commands without negation follows them. This helps + * to endure that we are evaluating the commands with ! first. + */ + + if(tmpcmd[0]=='!') { + list_cmnds_node = talloc_zero(mem_ctx, struct sss_sudo_command_list); + list_cmnds_node->values = &(el->values[i]); + list_cmnds_node->next = NULL; + list_cmnds_node->prev = NULL; + DLIST_ADD( list_cmnds_head , list_cmnds_node); + } + else { + list_cmnds_node = talloc_zero(mem_ctx, struct sss_sudo_command_list); + list_cmnds_node->values = &(el->values[i]); + list_cmnds_node->next = NULL; + list_cmnds_node->prev = NULL; + DLIST_ADD_END( list_cmnds_head , list_cmnds_node, struct sss_sudo_command_list*); + } + } + + DLIST_FOR_EACH(list_cmnds_node, list_cmnds_head){ + tmpcmd = (char *)list_cmnds_node->values->data; + + DEBUG(0, ("sudoCommand under test: %s\n" ,tmpcmd)); + space = strchr(tmpcmd,' '); + if(space) { + *space = '\0'; + /* + * FIXME: breaking commands at space is not optimal, a patch is needed. + */ + sudo_cmnd->arg= (space +1); + } + else + sudo_cmnd->arg = NULL; + + + if(tmpcmd[0]=='!') { + sudo_cmnd->fqcomnd = (tmpcmd+1); + sudo_cmnd->negated = 1; + } + else if(strcmp(tmpcmd,"ALL")) { + sudo_cmnd->fqcomnd=tmpcmd; + sudo_cmnd->negated = 0; + } + else { + *safe_cmnd = user_cmnd; + *safe_args = user_args; + return SUDO_ALLOW_ACCESS; + } + if (command_matches(mem_ctx, + sudo_cmnd->fqcomnd, + sudo_cmnd->arg, + user_cmnd, + user_args, + safe_cmnd, + safe_args) == SUDO_MATCH_TRUE){ + if(sudo_cmnd->negated) + *access = SUDO_DENY_ACCESS; + else + *access = SUDO_ALLOW_ACCESS; + } + else + *access = SUDO_DENY_ACCESS; + DEBUG(0, ("%s matched and %s \n" ,tmpcmd,sudo_cmnd->negated?"negated":"not negated")); + } + + + current_node = current_node->next; + } + + DEBUG(0,("Rule evaluation based on commands is over\n")); + return EOK; } @@ -675,7 +1069,7 @@ errno_t sudo_query_parse(TALLOC_CTX *mem_ctx, hash_table_t *env_table; char **ui; char **command_array; - int count = 0; + int count = 0 , ret =-1; struct sss_sudo_msg_contents *contents; contents = talloc_zero(mem_ctx,struct sss_sudo_msg_contents); @@ -781,7 +1175,12 @@ errno_t sudo_query_parse(TALLOC_CTX *mem_ctx, DEBUG(0,("settings table corrupted!\n")); return SSS_SUDO_RESPONDER_MESSAGE_ERR; } - contents->settings_table = settings_table; + contents->settings_table = settings_table; + ret = load_settings(settings_table,contents); + if (ret != SSS_SBUS_CONV_SUCCESS ){ + DEBUG(0,("Settings table failed to parse!\n")); + return SSS_SUDO_RESPONDER_MESSAGE_ERR; + } dbus_message_iter_next(&msg_iter); @@ -802,7 +1201,7 @@ errno_t format_sudo_result_reply(TALLOC_CTX * mem_ctx, struct sss_sudo_msg_contents *sudo_msg_packet, const char * result){ - dbus_uint32_t header = SSS_SUDO_RESPONDER_HEADER,command_size; + dbus_uint32_t header = SSS_SUDO_REPLY_HEADER,command_size; DBusMessage *reply; DBusMessageIter msg_iter; DBusMessageIter subItem; @@ -857,6 +1256,30 @@ errno_t format_sudo_result_reply(TALLOC_CTX * mem_ctx, } +errno_t get_serialised_args(TALLOC_CTX* mem_ctx, char ** cmnd_args, int count, char ** arg_out){ + + char * args = NULL; + int i = 0 ; + if(cmnd_args == NULL) { + *arg_out = NULL; + return EOK; + } + args = talloc_strdup(mem_ctx, (cmnd_args[0]?cmnd_args[0]:NULL)); + if(args == NULL && (cmnd_args == NULL || *cmnd_args ) ){ + DEBUG(0,("Linearizing the arguments failed\n")); + return ENOMEM; + } + for ( i=1; itimeout)); @@ -901,13 +1329,45 @@ static int sudo_query_validation(DBusMessage *message, struct sbus_connection *c goto done; } - ret = find_sudorules_for_user_in_db_list(tmpctx,sudocli,msg); + ret = find_sudorules_for_user_in_db_list(tmpctx,sudocli,msg, &valid_sudo_rules); + if(ret != EOK ){ + DEBUG(0, ("finding sudorules with given criterion failed\n")); + ret = SSS_SUDO_RESPONDER_PARSE_ERR; + goto done; + } + + ret = get_serialised_args(tmpctx, + (msg->command_count > 1)? msg->command+1: NULL, + msg->command_count-1, + & user_args); if(ret != EOK ){ - DEBUG(0, ("sysdb_search_user_by_uid() failed - No sudo commands found with given criterion\n")); + DEBUG(0, ("get_serialised_args() failed\n")); ret = SSS_SUDO_RESPONDER_PARSE_ERR; goto done; } + ret = evaluate_sudo_valid_rules(tmpctx, + valid_sudo_rules, + msg->fq_command, + user_args, + &safe_cmnd, + &safe_args, + &access_specifier); + if(ret != EOK ){ + DEBUG(0, ("sudo rule evaluation failed\n")); + ret = SSS_SUDO_RESPONDER_PARSE_ERR; + goto done; + } + + if(access_specifier == SUDO_ALLOW_ACCESS){ + DEBUG(0,("EValuation returned a ALLOW_ACCESS ticket\n")); + result = talloc_strdup(sudocli,SUDO_ALLOW_ACCESS_STR); + } + else + { + DEBUG(0,("EValuation returned a DENY_ACCESS ticket\n")); + } + /* * TODO: Evaluate the list of non eliminated sudo rules and make necessary @@ -933,14 +1393,13 @@ static int sudo_query_validation(DBusMessage *message, struct sbus_connection *c goto done; } - - /* send reply back */ sbus_conn_send_reply(conn, reply); ret = EOK; done: talloc_zfree(tmpctx); + sudocli->initialized = true; /*if(message) dbus_message_unref(message); if(reply) @@ -1034,11 +1493,7 @@ int sudo_server_init(TALLOC_CTX *mem_ctx, int ret; struct sbus_connection *serv; - DEBUG(1, ("Setting up the sudo server.\n")); - - - ret = sbus_new_server(mem_ctx, _ctx->rctx->ev, SSS_SUDO_SERVICE_PIPE, @@ -1050,9 +1505,7 @@ int sudo_server_init(TALLOC_CTX *mem_ctx, DEBUG(0, ("Could not set up sudo sbus server.\n")); return ret; } - return EOK; - } struct cli_protocol_version *register_cli_protocol_version(void) diff --git a/src/responder/sudo/sudosrv.h b/src/responder/sudo/sudosrv.h index a2b35e6e..b4c68d2d 100644 --- a/src/responder/sudo/sudosrv.h +++ b/src/responder/sudo/sudosrv.h @@ -44,9 +44,6 @@ #define SUDO_DP_PATH "/org/freedesktop/sssd/sudo/dataprovider" #define SUDO_DP_METHOD_QUERY "queryDPService" - -#define SSS_SUDO_RESPONDER_HEADER 0x43256 - #define SSS_SUDO_SBUS_SERVICE_VERSION 0x0001 #define SSS_SUDO_SBUS_SERVICE_NAME "sudo" @@ -54,6 +51,10 @@ #define CONFDB_SUDO_ENTRY_NEG_TIMEOUT "entry_negative_timeout" #define CONFDB_SUDO_ID_TIMEOUT "sudo_id_timeout" +#define SUDO_ALLOW_ACCESS 1 +#define SUDO_DENY_ACCESS 0 + + static int sudo_query_validation(DBusMessage *message, struct sbus_connection *conn); struct sbus_method sudo_methods[] = { @@ -77,6 +78,29 @@ struct sbus_interface sudo_dp_interface = { NULL }; +int command_args_match(char *sudoers_cmnd, + char *sudoers_args, + char *user_cmnd, + char *user_args); + +int command_matches_fnmatch(TALLOC_CTX* memctx, + char *sudoers_cmnd, + char *sudoers_args, + char *user_cmnd, + char *user_args, + char ** safe_cmnd, + char ** safe_args); + +int command_matches(TALLOC_CTX * memctx, + char *sudoers_cmnd, + char *sudoers_args, + char *user_cmnd, + char *user_args, + char ** safe_cmnd, + char ** safe_args); + + + struct sudo_ctx { struct resp_ctx *rctx; struct sss_nc_ctx *ncache; @@ -107,12 +131,49 @@ struct sss_sudorule_list struct sss_sudorule_list *prev; } ; +struct sss_sudo_command_list +{ + struct ldb_val *values; + + struct sss_sudo_command_list *next; + struct sss_sudo_command_list *prev; +} ; + struct sss_valid_sudorules { struct ldb_message *default_rule; struct sss_sudorule_list *non_defaults; }; +#define FILTER_APPEND_CHECK(filter_in,filter_out, append_str, str_arg) \ + do { \ + (filter_out) = talloc_asprintf_append((filter_in), (append_str), (str_arg)); \ + if (!(filter_out)) { \ + DEBUG(0, ("Failed to build filter\n")); \ + ret = ENOMEM; \ + goto done; \ + } \ + }while(0); + + +#define BOOL_STR_TO_INT(bool_str) (!strcmp((bool_str),"TRUE"))?1 : 0 ; + +#define CHECK_KEY_AND_SET_MESSAGE_STR(key,str_key,var, value) \ + do { \ + if( !strcmp((key),(str_key))){ \ + (var) = (value); \ + } \ + } while (0); + +#define CHECK_KEY_AND_SET_MESSAGE_INT(key,str_key,var, value) \ + do { \ + if( !strcmp((key),(str_key))){ \ + (var) = BOOL_STR_TO_INT(value); \ + } \ + } while (0); + + + enum error_types_sudo_responder{ SSS_SUDO_RESPONDER_SUCCESS = 0x01, diff --git a/src/sbus/sssd_dbus_messages_helpers.c b/src/sbus/sssd_dbus_messages_helpers.c index bbcee7e3..2fcc88c5 100644 --- a/src/sbus/sssd_dbus_messages_helpers.c +++ b/src/sbus/sssd_dbus_messages_helpers.c @@ -1,10 +1,26 @@ /* - * sssd_dbus_messages_helpers.c - * - * Created on: Jul 9, 2011 - * Author: r00tkit + SSSD + + Authors: + Arun Scaria + + Copyright (C) 2011 Arun Scaria + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see */ + #include #include #include "util/util.h" @@ -38,7 +54,7 @@ int dbus_dhash_to_msg_iter(hash_table_t **table_in, msg_iter = msg_iter_start; if( !table_in && !*table_in) { - fprintf(stderr,"Table is not valid."); + DEBUG(0,("Table is not valid.")); return SSS_SBUS_DHASH_NULL; } local_table = *table_in; @@ -47,7 +63,7 @@ int dbus_dhash_to_msg_iter(hash_table_t **table_in, DBUS_TYPE_ARRAY, "{ss}", &sub_iter)) { - fprintf(stderr, "Out Of Memory!\n"); + DEBUG(0,("Out Of Memory!\n")); return SSS_SBUS_ITER_MESSAGE_ERR; } @@ -55,7 +71,7 @@ int dbus_dhash_to_msg_iter(hash_table_t **table_in, while ((entry = iter->next(iter)) != NULL) { if(entry->key.type != HASH_KEY_STRING && entry->value.type != HASH_VALUE_PTR) { - fprintf(stderr,"fatal: Unexpected hashtable"); + DEBUG(0,("fatal: Unexpected hashtable")); return SSS_SBUS_DHASH_INVALID; } @@ -66,23 +82,23 @@ int dbus_dhash_to_msg_iter(hash_table_t **table_in, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter)) { - fprintf(stderr, "Out Of Memory!\n"); + DEBUG(0,( "Out Of Memory!\n")); return SSS_SBUS_ITER_MESSAGE_ERR; } if (!dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &str_key)) { - fprintf(stderr, "Out Of Memory!\n"); + DEBUG(0,("Out Of Memory!\n")); return SSS_SBUS_ITER_MESSAGE_ERR; } if (!dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &str_value)) { - fprintf(stderr, "Out Of Memory!\n"); + DEBUG(0,( "Out Of Memory!\n")); return SSS_SBUS_ITER_MESSAGE_ERR; } free(str_key); free(str_value); if (!dbus_message_iter_close_container(&sub_iter,&dict_iter)) { - fprintf(stderr, "Out Of Memory!\n"); + DEBUG(0,( "Out Of Memory!\n")); return SSS_SBUS_ITER_MESSAGE_ERR; } @@ -91,7 +107,7 @@ int dbus_dhash_to_msg_iter(hash_table_t **table_in, } free(iter); if (!dbus_message_iter_close_container(msg_iter,&sub_iter)) { - fprintf(stderr, "Out Of Memory!\n"); + DEBUG(0,( "Out Of Memory!\n")); return SSS_SBUS_ITER_MESSAGE_ERR; } @@ -117,12 +133,12 @@ int dbus_msg_iter_to_dhash(DBusMessageIter *iter, hash_table_t **table_out) callback_delete, NULL); if (err_h != HASH_SUCCESS) { - fprintf(stderr, "couldn't create hash table (%s)\n", hash_error_string(err_h)); + DEBUG(0,( "couldn't create hash table (%s)\n", hash_error_string(err_h))); return err_h; } if(DBUS_TYPE_ARRAY != dbus_message_iter_get_arg_type(&msg_iter)) { - fprintf(stderr,"message Iter is invalid\n"); + DEBUG(0,("message Iter is invalid\n")); return SSS_SBUS_ITER_INVALID_ERR; } @@ -133,14 +149,14 @@ int dbus_msg_iter_to_dhash(DBusMessageIter *iter, hash_table_t **table_out) while(1){ if(DBUS_TYPE_DICT_ENTRY != dbus_message_iter_get_arg_type(&sub_iter)) { - fprintf(stderr,"dict content failed"); + DEBUG(0,("dict content failed")); } else { dbus_message_iter_recurse(&sub_iter, &dict_iter); } if(DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&dict_iter)) { - printf("string array content failed"); + DEBUG(0,("string array content failed")); return SSS_SBUS_ITER_MESSAGE_ERR; } else { @@ -148,18 +164,16 @@ int dbus_msg_iter_to_dhash(DBusMessageIter *iter, hash_table_t **table_out) value.type = HASH_VALUE_PTR; dbus_message_iter_get_basic(&dict_iter, &tmp); key.str = tmp; - fprintf(stdout,"%s : ",key.str); dbus_message_iter_next (&dict_iter); if(DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&dict_iter)) { - printf("string array content failed"); + DEBUG(0,("string array content failed")); return SSS_SBUS_ITER_MESSAGE_ERR; } dbus_message_iter_get_basic(&dict_iter, &tmp); value.ptr = tmp; - fprintf(stdout,"%s\n",(char *)value.ptr); if ((err_h = hash_enter(local_table, &key, &value)) != HASH_SUCCESS) { - fprintf(stderr, "couldn't add to table \"%s\" (%s)\n", key.str, hash_error_string(err_h)); + DEBUG(0,( "couldn't add to table \"%s\" (%s)\n", key.str, hash_error_string(err_h))); return err_h; } if(!dbus_message_iter_next (&sub_iter)) { diff --git a/src/sbus/sssd_dbus_messages_helpers.h b/src/sbus/sssd_dbus_messages_helpers.h index 97152c26..aaa1658a 100644 --- a/src/sbus/sssd_dbus_messages_helpers.h +++ b/src/sbus/sssd_dbus_messages_helpers.h @@ -1,10 +1,26 @@ /* - * sssd_dbus_messages_helpers.h - * - * Created on: Jul 9, 2011 - * Author: r00tkit + SSSD + + Authors: + Arun Scaria + + Copyright (C) 2011 Arun Scaria + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see */ + #ifndef SSSD_DBUS_MESSAGES_HELPERS_H_ #define SSSD_DBUS_MESSAGES_HELPERS_H_ diff --git a/src/sss_client/sudo_plugin/missing.h b/src/sss_client/sudo_plugin/missing.h deleted file mode 100644 index d6a7ebdf..00000000 --- a/src/sss_client/sudo_plugin/missing.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 1996, 1998-2005, 2008, 2009-2010 - * 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. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - * - * Auto generated by the sudo package. - */ - -#ifndef _SUDO_MISSING_H -#define _SUDO_MISSING_H - -#include -#include - -/* - * Macros and functions that may be missing on some operating systems. - */ - - -/* - * If we lack getprogname(), emulate with __progname if possible. - * Otherwise, add a prototype for use with our own getprogname.c. - */ -#ifndef HAVE_GETPROGNAME -# ifdef HAVE___PROGNAME -extern const char *__progname; -# define getprogname() (__progname) -# else -const char *getprogname(void); -void setprogname(const char *); -#endif /* HAVE___PROGNAME */ -#endif /* !HAVE_GETPROGNAME */ - - -#endif /* _SUDO_MISSING_H */ diff --git a/src/sss_client/sudo_plugin/sss_sudo_cli.h b/src/sss_client/sudo_plugin/sss_sudo_cli.h index 097b8aaf..9caecf77 100644 --- a/src/sss_client/sudo_plugin/sss_sudo_cli.h +++ b/src/sss_client/sudo_plugin/sss_sudo_cli.h @@ -1,8 +1,6 @@ /* SSSD - sss_sudo_cli.h - Authors: Arun Scaria @@ -22,6 +20,7 @@ along with this program. If not, see */ + #ifndef _SSS_SUDO_CLI_H_ #define _SSS_SUDO_CLI_H_ @@ -53,6 +52,10 @@ #define INIT_ENV_TABLE_SIZE 10 +#define SUDO_CLIENT_TIMEOUT 60000 + +#define SSS_SUDO_REPLY_HEADER 0x43256 + #ifndef _SSSCLI_H /* If sss_cli.h is not included */ @@ -61,15 +64,8 @@ struct sss_cli_req_data { const void *data; }; -enum sss_status { - SSS_STATUS_SUCCESS, - SSS_STATUS_FAILED, - SSS_STATUS_TRYAGAIN, - SSS_STATUS_UNAVAIL - -}; -#endif +#endif @@ -83,7 +79,10 @@ enum error_types_sudo{ SSS_SUDO_LOG_ERR, SSS_SUDO_LOG_NOTICE, SSS_SUDO_MESSAGE_ERR, - SSS_SUDO_REPLY_ERR + SSS_SUDO_MESSAGE_OK, + SSS_SUDO_REPLY_ERR, + SSS_SUDO_REPLY_OK, + SSS_SUDO_SEND_AND_RECIEVE_OK }; @@ -126,12 +125,21 @@ struct sss_sudo_msg_contents int command_count; /* Clients pid */ - int cli_pid; + pid_t cli_pid; hash_table_t *settings_table; hash_table_t *env_table; }; +struct sudo_result_contents{ + dbus_uint32_t header; + char * result_str; + char ** command_array; + dbus_uint32_t command_array_out_size; + hash_table_t *env_table_out; + char ** env_array; +}; + #define SSS_SUDO_ITEM_RUSER "runas_user" #define SSS_SUDO_ITEM_RGROUP "runas_group" #define SSS_SUDO_ITEM_PROMPT "prompt" @@ -149,5 +157,12 @@ struct sss_sudo_msg_contents #define SSS_SUDO_ITEM_CLI_PID "client_pid" +#define SUDO_ALLOW_ACCESS_STR "ALLOW" +#define SUDO_DENY_ACCESS_STR "DENY" + +#define SUDO_ALLOW_CMD_EXECUTION 1 +#define SUDO_DENY_CMD_EXECUTION 0 +#define SUDO_ERR_CMD_EXECUTION -1 + #endif /* _SSS_SUDO_CLI_H_ */ diff --git a/src/sss_client/sudo_plugin/sss_sudoplugin.c b/src/sss_client/sudo_plugin/sss_sudoplugin.c index 12fa4ec5..cc1d1f80 100644 --- a/src/sss_client/sudo_plugin/sss_sudoplugin.c +++ b/src/sss_client/sudo_plugin/sss_sudoplugin.c @@ -31,8 +31,6 @@ /* * Define to the version of sudo package - * This declaration is to be removed and - * it is to be imported from config.h */ #define SUDO_PACKAGE_STRING "sudo 1.8.1" @@ -80,7 +78,6 @@ #include #include -#include "missing.h" #include #include @@ -225,9 +222,7 @@ int policy_open(unsigned int version, char * const user_env[]) { char * const *ui; - struct passwd *pw; const char *runas_user = NULL; - struct group *gr; const char *runas_group = NULL; @@ -426,20 +421,37 @@ int policy_open(unsigned int version, - if (runas_user != NULL) { - if ((pw = getpwnam(runas_user)) == NULL) { + /* + * No need to check the user or group status here. + * TODO: Sgallagh, Pls conform this. :) + * + * + * if (runas_user != NULL) { + if(runas_user[0] == '#'){ + if ((pw = getpwuid(atoi(runas_user+1))) == NULL) { + sudo_log(SUDO_CONV_ERROR_MSG, "unknown user %s\n", runas_user); + return 0; + } + } + else if ((pw = getpwnam(runas_user)) == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "unknown user %s\n", runas_user); return 0; } runas_uid = pw->pw_uid; } if (runas_group != NULL) { - if ((gr = getgrnam(runas_group)) == NULL) { + if(runas_group[0] == '#'){ + if ((gr = getgrgid(atoi(runas_group+1))) == NULL) { + sudo_log(SUDO_CONV_ERROR_MSG, "unknown group %s\n", runas_user); + return 0; + } + } + else if ((gr = getgrnam(runas_group)) == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "unknown group %s\n", runas_group); return 0; } runas_gid = gr->gr_gid; - } + }*/ /* fill Plugin state. */ plugin_state.envp = user_env; @@ -820,7 +832,87 @@ int create_settings_hash_table(hash_table_t ** table_out) { return HASH_SUCCESS; } +void free_connection(DBusConnection *conn, + DBusError *err, + hash_table_t *settings_table, + DBusMessage *msg, + DBusMessage *reply ){ + if(msg != NULL) + dbus_message_unref(msg); + + if(reply != NULL) + dbus_message_unref(reply); + + if (err != NULL && dbus_error_is_set(err)) + dbus_error_free(err); + + if(settings_table != NULL) + hash_destroy(settings_table); + + if(conn != NULL) + dbus_connection_close(conn); + +} + + +//////////////////// + +int get_reply_message(DBusConnection* conn, + DBusError *err, + DBusMessage *dbus_msg, + DBusMessage *dbus_reply, + struct sudo_result_contents * sudo_result, + DBusMessageIter * msg_iter){ + +int ret = -1,count =0; +ret = dbus_message_get_args(dbus_reply, + err, + DBUS_TYPE_UINT32,&sudo_result->header, + DBUS_TYPE_STRING,&sudo_result->result_str, + DBUS_TYPE_ARRAY,DBUS_TYPE_STRING,&sudo_result->command_array, + &sudo_result->command_array_out_size, + DBUS_TYPE_INVALID); + if (!ret) { + fprintf (stderr,"Failed to parse reply, killing connection\n"); + free_connection(conn,&err,(hash_table_t *)NULL,dbus_msg,dbus_reply); + return SSS_SUDO_REPLY_ERR; + } + + if(sudo_result->header != SSS_SUDO_REPLY_HEADER){ + sudo_log(SUDO_CONV_ERROR_MSG, "Reply header mismatch - Detected unreliable packet. Access denied\n"); + return SSS_SUDO_REPLY_ERR; + } + + fprintf(stdout,"----------Reply--------:\n" + "Header : %d \nResult status : %s\n" + "Command : ", sudo_result->header,sudo_result->result_str); + + for(count =0;count< sudo_result->command_array_out_size;count++){ + printf("%s ", sudo_result->command_array[count]); + } + if (!dbus_message_iter_init(dbus_reply, msg_iter)) { + fprintf(stderr, "Reply iterator failed!\n"); + free_connection(conn,err,(hash_table_t *)NULL,dbus_msg,dbus_reply); + return SSS_SUDO_REPLY_ERR; + } + + printf("\n"); + dbus_message_iter_next(msg_iter); + dbus_message_iter_next(msg_iter); + dbus_message_iter_next(msg_iter); + + if(dbus_msg_iter_to_dhash(msg_iter, &sudo_result->env_table_out) != SSS_SBUS_CONV_SUCCESS){ + fprintf(stderr, "env message iterator corrupted!\n"); + free_connection(conn,err,(hash_table_t *)NULL,dbus_msg,dbus_reply); + return SSS_SUDO_REPLY_ERR; + } + printf("---------Reply End----------\n"); + + return SSS_SUDO_REPLY_OK; + +} +/////////////////////// int validate_message_content( void ) @@ -845,41 +937,127 @@ int validate_message_content( void ) return SSS_SUDO_VALIDATION_SUCCESS; } -void free_connection(DBusConnection *conn, - DBusError *err, - hash_table_t *settings_table, - DBusMessage *msg, - DBusMessage *reply ){ - if(msg != NULL) - dbus_message_unref(msg); - if(reply != NULL) - dbus_message_unref(reply); +int frame_sudo_message(DBusConnection* conn, + DBusError *err, + DBusMessage *dbus_msg, + struct sss_sudo_msg_contents * sudo_msg, + DBusMessageIter * msg_iter){ - if (err != NULL && dbus_error_is_set(err)) - dbus_error_free(err); + int ret = -1,count =0; + DBusMessageIter sub_iter; + char ** command_array; - if(settings_table != NULL) - hash_destroy(settings_table); - if(conn != NULL) - dbus_connection_close(conn); + if(!dbus_message_iter_open_container(msg_iter, + DBUS_TYPE_STRUCT, + NULL, + &sub_iter)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + if (!dbus_message_iter_append_basic(&sub_iter, + DBUS_TYPE_UINT32, + &sudo_msg->userid)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + + if (!dbus_message_iter_append_basic(&sub_iter, + DBUS_TYPE_STRING, + &sudo_msg->cwd)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + + + + if (!dbus_message_iter_append_basic(&sub_iter, + DBUS_TYPE_STRING, + &sudo_msg->tty)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + if (!dbus_message_iter_append_basic(&sub_iter, + DBUS_TYPE_STRING, + &sudo_msg->fq_command)) { + fprintf(stderr, "Out Of Memory! - at FQ command\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + + if (!dbus_message_iter_close_container(msg_iter,&sub_iter)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } -} + if (!dbus_message_iter_append_basic(msg_iter, + DBUS_TYPE_UINT32, + &sudo_msg->command_count)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + + if(!dbus_message_iter_open_container(msg_iter, + DBUS_TYPE_ARRAY, + "s", + &sub_iter)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + + for(command_array = sudo_msg->command ; *command_array != NULL ; command_array++) { + if (!dbus_message_iter_append_basic(&sub_iter, + DBUS_TYPE_STRING, + command_array)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } -int sss_sudo_make_request(struct sss_cli_req_data *rd, - uint8_t **repbuf, - size_t *replen, - int *errnop) + } + + if (!dbus_message_iter_close_container(msg_iter,&sub_iter)) { + fprintf(stderr, "Out Of Memory!\n"); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + //////// + + if(dbus_dhash_to_msg_iter(&sudo_msg->settings_table,msg_iter) != SSS_SBUS_CONV_SUCCESS){ + fprintf(stderr,"fatal: message framing failed."); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + return SSS_SUDO_MESSAGE_ERR; + } + + if(dbus_dhash_to_msg_iter(&sudo_msg->env_table,msg_iter) != SSS_SBUS_CONV_SUCCESS){ + fprintf(stderr,"fatal: message framing failed."); + free_connection(conn,&err,sudo_msg->settings_table,dbus_msg,(DBusMessage *)NULL); + free_connection(NULL,NULL,sudo_msg->env_table,NULL,NULL); + return SSS_SUDO_MESSAGE_ERR; + } + + return SSS_SUDO_MESSAGE_OK; + +} + +int sss_sudo_make_request(struct sudo_result_contents ** sudo_result_out) { char ** command_array,**ui; - char * result_str; int err_status,count; - dbus_uint32_t status,command_array_out_size; + dbus_uint32_t header,command_array_out_size; + struct sudo_result_contents * sudo_result = NULL; DBusConnection* conn; DBusError err; @@ -887,29 +1065,24 @@ int sss_sudo_make_request(struct sss_cli_req_data *rd, DBusMessage* dbus_msg; DBusMessage* dbus_reply; DBusMessageIter msg_iter; - DBusMessageIter sub_iter; - dbus_bool_t ret=FALSE; + dbus_bool_t ret = -1; - hash_table_t *env_table = NULL; - hash_table_t *settings_table = NULL; - hash_table_t *env_table_out = NULL; - - fprintf(stdout,"Calling remote method to pack message\n"); + fprintf(stdout,"Sending message\n"); if(validate_message_content() != SSS_SUDO_VALIDATION_SUCCESS) { return SSS_SUDO_VALIDATION_ERR; } - err_status = create_env_hash_table(msg.user_env,&env_table); + err_status = create_env_hash_table(msg.user_env,&msg.env_table); if(err_status != HASH_SUCCESS) { fprintf(stderr, "ccouldn't create table: %s\n", hash_error_string(err_status)); return SSS_SUDO_MESSAGE_ERR; } - err_status = create_settings_hash_table(&settings_table); + err_status = create_settings_hash_table(&msg.settings_table); if(err_status != HASH_SUCCESS) { fprintf(stderr, "ccouldn't create table: %s\n", hash_error_string(err_status)); return SSS_SUDO_MESSAGE_ERR; @@ -932,13 +1105,13 @@ int sss_sudo_make_request(struct sss_cli_req_data *rd, /* create a new method call and check for errors */ - dbus_msg = dbus_message_new_method_call( NULL, /* target */ + dbus_msg = dbus_message_new_method_call( NULL, /* target */ SUDO_SERVER_PATH, /* object */ SUDO_SERVER_INTERFACE, /* interface */ SUDO_METHOD_QUERY); /* method name */ if (NULL == dbus_msg) { fprintf(stderr, "Message Null\n"); - free_connection(conn,&err,settings_table,(DBusMessage *)NULL,(DBusMessage *)NULL); + free_connection(conn,&err,msg.settings_table,(DBusMessage *)NULL,(DBusMessage *)NULL); return SSS_SUDO_MESSAGE_ERR; } @@ -948,111 +1121,24 @@ int sss_sudo_make_request(struct sss_cli_req_data *rd, dbus_message_iter_init_append(dbus_msg, &msg_iter); if(dbus_error_is_set(&err)){ fprintf(stderr, "Failed to initialize the iterator.\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - - - if(!dbus_message_iter_open_container(&msg_iter, - DBUS_TYPE_STRUCT, - NULL, - &sub_iter)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - if (!dbus_message_iter_append_basic(&sub_iter, - DBUS_TYPE_UINT32, - &msg.userid)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - - if (!dbus_message_iter_append_basic(&sub_iter, - DBUS_TYPE_STRING, - &msg.cwd)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - - - - if (!dbus_message_iter_append_basic(&sub_iter, - DBUS_TYPE_STRING, - &msg.tty)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - if (!dbus_message_iter_append_basic(&sub_iter, - DBUS_TYPE_STRING, - &msg.fq_command)) { - fprintf(stderr, "Out Of Memory! - at FQ command\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - - if (!dbus_message_iter_close_container(&msg_iter,&sub_iter)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - - if (!dbus_message_iter_append_basic(&msg_iter, - DBUS_TYPE_UINT32, - &msg.command_count)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - - if(!dbus_message_iter_open_container(&msg_iter, - DBUS_TYPE_ARRAY, - "s", - &sub_iter)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - - for(command_array = msg.command ; *command_array != NULL ; command_array++) { - - if (!dbus_message_iter_append_basic(&sub_iter, - DBUS_TYPE_STRING, - command_array)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - - } - - if (!dbus_message_iter_close_container(&msg_iter,&sub_iter)) { - fprintf(stderr, "Out Of Memory!\n"); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); - return SSS_SUDO_MESSAGE_ERR; - } - //////// - - if(dbus_dhash_to_msg_iter(&settings_table,&msg_iter) != SSS_SBUS_CONV_SUCCESS){ - fprintf(stderr,"fatal: message framing failed."); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); + free_connection(conn,&err,msg.settings_table,dbus_msg,(DBusMessage *)NULL); return SSS_SUDO_MESSAGE_ERR; } - if(dbus_dhash_to_msg_iter(&env_table,&msg_iter) != SSS_SBUS_CONV_SUCCESS){ - fprintf(stderr,"fatal: message framing failed."); - free_connection(conn,&err,settings_table,dbus_msg,(DBusMessage *)NULL); + ret = frame_sudo_message(conn, + &err, + dbus_msg, + &msg, + &msg_iter); + if( ret != SSS_SUDO_MESSAGE_OK){ + sudo_log(SUDO_CONV_ERROR_MSG,"Failed to frame the message to sssd - Fatal (Access denied)\n"); + free_connection(conn,&err,(hash_table_t *)NULL,dbus_msg,(DBusMessage *)NULL); return SSS_SUDO_MESSAGE_ERR; } - hash_destroy(settings_table); - /* send message and get a handle for a reply */ dbus_reply = dbus_connection_send_with_reply_and_block (conn,dbus_msg, - -1, + SUDO_CLIENT_TIMEOUT, &err); fprintf(stdout,"Request Sent\n"); if (dbus_error_is_set(&err)) { @@ -1065,54 +1151,22 @@ int sss_sudo_make_request(struct sss_cli_req_data *rd, free_connection(conn,&err,(hash_table_t *)NULL,dbus_msg,(DBusMessage *)NULL); return SSS_SUDO_REPLY_ERR; } + sudo_result= (struct sudo_result_contents *)malloc(sizeof(struct sudo_result_contents)); - ret = dbus_message_get_args(dbus_reply, - &err, - DBUS_TYPE_UINT32,&status, - DBUS_TYPE_STRING,&result_str, - DBUS_TYPE_ARRAY,DBUS_TYPE_STRING,&command_array, - &command_array_out_size, - DBUS_TYPE_INVALID); - if (!ret) { - fprintf (stderr,"Failed to parse reply, killing connection\n"); - free_connection(conn,&err,(hash_table_t *)NULL,dbus_msg,dbus_reply); - return SSS_SUDO_REPLY_ERR; - } - - fprintf(stdout,"----------Reply--------:\n" - "Header : %d \nResult status : %s\n" - "Command : ", status,result_str); - - for(count =0;count< command_array_out_size;count++){ - printf("%s ", command_array[count]); - } - if (!dbus_message_iter_init(dbus_reply, &msg_iter)) { - fprintf(stderr, "Reply iterator failed!\n"); - free_connection(conn,&err,(hash_table_t *)NULL,dbus_msg,dbus_reply); - return SSS_SUDO_REPLY_ERR; - } - - printf("\n"); - dbus_message_iter_next(&msg_iter); - dbus_message_iter_next(&msg_iter); - dbus_message_iter_next(&msg_iter); + ret = get_reply_message(conn, + &err, + dbus_msg, + dbus_reply, + sudo_result, + &msg_iter); + if(ret != SSS_SUDO_REPLY_OK){ - if(dbus_msg_iter_to_dhash(&msg_iter, &env_table_out) != SSS_SBUS_CONV_SUCCESS){ - fprintf(stderr, "env message iterator corrupted!\n"); - free_connection(conn,&err,(hash_table_t *)NULL,dbus_msg,dbus_reply); - return SSS_SUDO_REPLY_ERR; } - printf("---------Reply End----------\n"); /* free connection now */ free_connection(conn,&err,(hash_table_t *)NULL,dbus_msg,dbus_reply); - - - if(strncmp(result_str,"PASS",4)==0) - return SSS_STATUS_SUCCESS; - else - return SSS_STATUS_FAILED; - + *sudo_result_out = sudo_result; + return SSS_SUDO_SEND_AND_RECIEVE_OK; } void free_all( void ) @@ -1122,55 +1176,48 @@ void free_all( void ) free(msg.prompt); free(msg.runas_user); free(msg.runas_group); - //free(msg.network_addrs); + free(msg.network_addrs); free(user_information.username); } -int send_and_receive() +int send_and_receive(struct sudo_result_contents ** sudo_result) { int ret; - int errnop; - struct sss_cli_req_data rd; - uint8_t *buf = NULL; - uint8_t *repbuf = NULL; - size_t replen; - int _status = SSS_SUDO_SYSTEM_ERR; + int status = SSS_SUDO_FAILED; print_sudo_items(); + ret = sss_sudo_make_request(sudo_result); - errnop = 0; - ret = sss_sudo_make_request( &rd, &repbuf, &replen, &errnop); - if (ret != SSS_SUDO_SUCCESS) { - if (errnop != 0) { - fprintf( stderr, "Request to sssd failed. %d", errnop); - } - _status = SSS_SUDO_SYSTEM_ERR; + if (ret != SSS_SUDO_SEND_AND_RECIEVE_OK) { + fprintf( stderr, "Request to sssd failed.\n"); + status = SSS_SUDO_FAILED; goto done; } - /* check the reply signature */ - if (replen < (2*sizeof(int32_t))) { - //D(("response not in expected format.")); - _status = SSS_SUDO_SYSTEM_ERR; + if(strncmp((*sudo_result)->result_str,SUDO_ALLOW_ACCESS_STR,4)==0){ + /* + * TODO: Convert the environment table to environment vector + * and save to sudo_result->env_array. + */ + status = SSS_SUDO_SUCCESS; + } + else + { + status = SSS_SUDO_FAILED; goto done; } - done: - _status = SSS_SUDO_SUCCESS; - - if (_status == SSS_SUDO_SUCCESS) - return _status; + if (status == SSS_SUDO_SUCCESS) + return status; else return SSS_SUDO_FAILED; } - - /* * Plugin policy check function. * The check_policy function is called by sudo to determine @@ -1184,7 +1231,9 @@ int policy_check(int argc, char * const argv[], pam_handle_t *pamh; char *pam_user; char *pam_action; - int pam_ret; + int pam_ret = PAM_AUTHTOK_ERR; + int sudo_ret = SSS_SUDO_FAILED; + struct sudo_result_contents * sudo_result = NULL; if (!argc || argv[0] == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "no command specified\n"); @@ -1281,22 +1330,42 @@ int policy_check(int argc, char * const argv[], msg.command = (char **) argv; msg.command_count = argc; - if(pam_ret==PAM_SUCCESS) { - pam_ret = send_and_receive(); + if(pam_ret == PAM_SUCCESS) { + sudo_ret = send_and_receive(&sudo_result); + if(sudo_ret != SSS_SUDO_SUCCESS){ + sudo_ret = SSS_SUDO_FAILED; + free(pam_action); + goto done; + } + } + else{ + sudo_ret = SSS_SUDO_FAILED; + free(pam_action); + goto done; } free(pam_action); - free_all(); /* Setup command info. */ *command_info_out = build_command_info(command); if (*command_info_out == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n"); return ERROR; } - if(pam_ret==SSS_SUDO_SUCCESS) - return TRUE; + *user_env_out = msg.user_env;/*sudo_result->env_array*/; - return FALSE; + done: + if(sudo_ret==SSS_SUDO_SUCCESS){ + free_all(); + return SUDO_ALLOW_CMD_EXECUTION; + } + sudo_log(SUDO_CONV_ERROR_MSG, + "User %s is not allowed run command %s on this Host machine( '%s' ) as user %s\n", + user_information.username, + msg.fq_command, + msg.network_addrs, + msg.runas_user ); + free_all(); + return SUDO_DENY_CMD_EXECUTION; } int policy_list(int argc, char * const argv[], int verbose, const char *list_user) -- cgit