summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArun Scaria <arunscaria91@gmail.com>2011-08-22 22:27:02 +0530
committerArun Scaria <arunscaria91@gmail.com>2011-08-22 22:27:02 +0530
commitcfc1147a5ace11382be8dfbce8b4bac74fa13634 (patch)
tree54430d2f00f6d90c8d73914c0232050a83d76653
parentc9899af4bb3b0a2d7bfc1232eba73d0dcb43ab59 (diff)
downloadsssd_unused-sudo-arun.zip
sssd_unused-sudo-arun.tar.gz
sssd_unused-sudo-arun.tar.xz
Sudo evaluation works properly. But, sudo options not supportedsudo-arun
-rw-r--r--Makefile.am4
-rw-r--r--src/db/sysdb.h8
-rw-r--r--src/responder/sudo/match_sudo.h31
-rw-r--r--src/responder/sudo/match_sudo_cmnd.c131
-rw-r--r--src/responder/sudo/sudosrv.c541
-rw-r--r--src/responder/sudo/sudosrv.h67
-rw-r--r--src/sbus/sssd_dbus_messages_helpers.c54
-rw-r--r--src/sbus/sssd_dbus_messages_helpers.h24
-rw-r--r--src/sss_client/sudo_plugin/missing.h50
-rw-r--r--src/sss_client/sudo_plugin/sss_sudo_cli.h39
-rw-r--r--src/sss_client/sudo_plugin/sss_sudoplugin.c497
11 files changed, 1097 insertions, 349 deletions
diff --git a/Makefile.am b/Makefile.am
index 0d764ba..c6ccdcf 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 e0ad4c8..795bfd0 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 0000000..baeabac
--- /dev/null
+++ b/src/responder/sudo/match_sudo.h
@@ -0,0 +1,31 @@
+/*
+ SSSD
+
+ Authors:
+ Arun Scaria <arunscaria91@gmail.com>
+
+ Copyright (C) 2011 Arun Scaria <arunscaria91@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>
+ */
+
+
+#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 0000000..ea5e482
--- /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 <arunscaria91@gmail.com> (2011)
+
+ Courtesy : The idea and the base logic for this module is derived from
+ the sudo source writtern by Todd C. Miller <Todd.Miller@courtesan.com>.
+
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include<fnmatch.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <talloc.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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 2f0a7e0..6b5a953 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; i<count-1 ;i++){
+ args = talloc_asprintf_append(args," %s",cmnd_args[i]);
+ if(args == NULL ){
+ DEBUG(0,("Linearizing the arguments failed\n"));
+ return ENOMEM;
+ }
+ }
+ *arg_out = args;
+ return EOK;
+}
+
static int sudo_query_validation(DBusMessage *message, struct sbus_connection *conn)
{
struct sudo_client *sudocli;
@@ -864,7 +1287,12 @@ static int sudo_query_validation(DBusMessage *message, struct sbus_connection *c
int ret = -1;
void *data;
char * result;
+ char * user_args;
+ char * safe_cmnd;
+ char * safe_args;
struct sss_sudo_msg_contents * msg;
+ struct sss_valid_sudorules * valid_sudo_rules;
+ unsigned int access_specifier = SUDO_DENY_ACCESS;
TALLOC_CTX * tmpctx;
@@ -877,7 +1305,7 @@ static int sudo_query_validation(DBusMessage *message, struct sbus_connection *c
ret = SSS_SUDO_RESPONDER_CONNECTION_ERR;
goto done;
}
- result = talloc_strdup(sudocli,"PASS");
+ result = talloc_strdup(sudocli,SUDO_DENY_ACCESS_STR);
/* First thing, cancel the timeout */
DEBUG(4, ("Cancel SUDO client timeout [%p]\n", sudocli->timeout));
@@ -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 a2b35e6..b4c68d2 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 bbcee7e..2fcc88c 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 <arunscaria91@gmail.com>
+
+ Copyright (C) 2011 Arun Scaria <arunscaria91@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>
*/
+
#include <sys/time.h>
#include <errno.h>
#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 97152c2..aaa1658 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 <arunscaria91@gmail.com>
+
+ Copyright (C) 2011 Arun Scaria <arunscaria91@gmail.com>
+
+ 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 <http://www.gnu.org/licenses/>
*/
+
#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 d6a7ebd..0000000
--- 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 <Todd.Miller@courtesan.com>
- *
- * 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 <stdio.h>
-#include <stdarg.h>
-
-/*
- * 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 097b8aa..9caecf7 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 <arunscaria91@gmail.com>
@@ -22,6 +20,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
+
#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 12fa4ec..cc1d1f8 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 <pwd.h>
#include <stdarg.h>
-#include "missing.h"
#include <sudo_plugin.h>
#include <security/pam_appl.h>
@@ -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)