From 1cae5b93f3be2ab2bad5dd63128917538e24aa29 Mon Sep 17 00:00:00 2001 From: Arun Scaria Date: Tue, 28 Jun 2011 01:37:22 +0530 Subject: sbus basic communication - sudo responder --- Makefile.am | 8 +- src/responder/sudo/sudosrv.c | 180 ++++++++++++++++- src/responder/sudo/sudosrv.h | 64 ++++++ src/sss_client/sudo_plugin/sss_sudoplugin.c | 290 ++-------------------------- 4 files changed, 264 insertions(+), 278 deletions(-) create mode 100644 src/responder/sudo/sudosrv.h diff --git a/Makefile.am b/Makefile.am index 24eee962..72450607 100644 --- a/Makefile.am +++ b/Makefile.am @@ -401,11 +401,14 @@ sssd_pam_LDADD = \ libsss_util.la sssd_sudo_SOURCES = \ - src/responder/sudo/sudosrv.c + src/responder/sudo/sudosrv.c \ + src/responder/sudo/sudosrv.h sssd_sudo_LDADD = \ $(TDB_LIBS) \ $(SSSD_LIBS) \ libsss_util.la +sssd_sudo_LDFLAGS = \ + -g sssd_be_SOURCES = \ src/providers/data_provider_be.c \ @@ -777,7 +780,8 @@ libsss_sudoplugin_la_LDFLAGS = \ -module \ -lpam \ -lpam_misc \ - $(DBUS_LIBS) + $(DBUS_LIBS) \ + -g libsss_sudoplugin_CPPFLAGS = \ $(AM_CPPFLAGS) \ diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c index f6b4b1e7..250adf44 100644 --- a/src/responder/sudo/sudosrv.c +++ b/src/responder/sudo/sudosrv.c @@ -2,8 +2,6 @@ SSSD SUDO Responder - - Author - Arun Scaria Copyright (C) Arun Scaria (2011) @@ -34,15 +32,189 @@ #include #include "util/util.h" +#include "sbus/sbus_client.h" +#include "sudosrv.h" -#define CONFDB_SUDO_CONF_ENTRY "config/sudo" +static int sudo_client_destructor(void *ctx) +{ + struct sudo_client *sudocli = talloc_get_type(ctx, struct sudo_client); + if (sudocli->sudoctx) { + //sudocli->sudoctx->sudo_cli = NULL; + DEBUG(4, ("Removed Sudo client\n")); + } + return 0; +} + + +static int sudo_query_validation(DBusMessage *message, struct sbus_connection *conn) +{ + + dbus_uint16_t version = 45674; + struct sudo_client *sudocli; + DBusMessage *reply; + DBusError dbus_error; + char *str; + dbus_bool_t dbret; + void *data; + + data = sbus_conn_get_private_data(conn); + sudocli = talloc_get_type(data, struct sudo_client); + if (!sudocli) { + DEBUG(0, ("Connection holds no valid init data\n")); + return EINVAL; + } + + /* First thing, cancel the timeout */ + DEBUG(4, ("Cancel SUDO ID timeout [%p]\n", sudocli->timeout)); + talloc_zfree(sudocli->timeout); + + dbus_error_init(&dbus_error); + + dbret = dbus_message_get_args(message, &dbus_error, + DBUS_TYPE_STRING, &str, + DBUS_TYPE_INVALID); + if (!dbret) { + DEBUG(1, ("Failed to parse message, killing connection\n")); + if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); + sbus_disconnect(conn); + return EIO; + } + + printf(" The string messahe is : %s ",str); + talloc_set_destructor((TALLOC_CTX *)sudocli, sudo_client_destructor); + + DEBUG(4, ("Got string [%s]\n", str)); + + /* reply that all is ok */ + reply = dbus_message_new_method_return(message); + if (!reply) { + DEBUG(0, ("Dbus Out of memory!\n")); + return ENOMEM; + } + + dbret = dbus_message_append_args(reply, + DBUS_TYPE_UINT16, &version, + DBUS_TYPE_INVALID); + if (!dbret) { + DEBUG(0, ("Failed to build dbus reply\n")); + dbus_message_unref(reply); + sbus_disconnect(conn); + return EIO; + } + + /* send reply back */ + sbus_conn_send_reply(conn, reply); + dbus_message_unref(reply); + + sudocli->initialized = true; + return EOK; + + +} + +static void init_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, void *ptr) +{ + struct sudo_client *sudocli; + + DEBUG(2, ("Client timed out before Identification [%p]!\n", te)); + + sudocli = talloc_get_type(ptr, struct sudo_client); + + sbus_disconnect(sudocli->conn); + talloc_zfree(sudocli); +} + +static int sudo_client_init(struct sbus_connection *conn, void *data) +{ + struct sudo_ctx *sudoctx; + struct sudo_client *sudocli; + struct timeval tv; + + sudoctx = talloc_get_type(data, struct sudo_ctx); + + /* hang off this memory to the connection so that when the connection + * is freed we can potentially call a destructor */ + + sudocli = talloc(conn, struct sudo_client); + if (!sudocli) { + DEBUG(0,("Out of memory?!\n")); + talloc_zfree(conn); + return ENOMEM; + } + sudocli->sudoctx = sudoctx; + sudocli->conn = conn; + sudocli->initialized = false; + + /* + * 5 seconds should be plenty + * + * FIXME: Call to this tevent_timeval_current_ofs() + * hangs and the goes in waiting forever. + * Pls comment if you know why. + */ + tv = tevent_timeval_current_ofs(5, 0); + + sudocli->timeout = tevent_add_timer(sudoctx->ev, sudocli, tv, init_timeout, sudocli); + if (!sudocli->timeout) { + DEBUG(0,("Out of memory?!\n")); + talloc_zfree(conn); + return ENOMEM; + } + DEBUG(4, ("Set-up Backend ID timeout [%p]\n", sudocli->timeout)); + + /* Attach the client context to the connection context, so that it is + * always available when we need to manage the connection. */ + sbus_conn_set_private_data(conn, sudocli); + + return EOK; +} + + +int sudo_server_connect(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sudo_ctx *_ctx) +{ + + char *sudo_address="unix:path=/tmp/sssd/sudo"; + int ret; + struct sbus_connection *serv; + + + DEBUG(1, ("Setting up the sudo server.\n")); + + + ret = sbus_new_server(mem_ctx,ev, sudo_address, + &sudo_interface, &serv, + sudo_client_init, _ctx); + if (ret != EOK) { + DEBUG(0, ("Could not set up sbus server.\n")); + return ret; + } + + return EOK; + +} + int sudo_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) { + struct sudo_ctx *ctx; + int ret; + + ctx = talloc_zero(mem_ctx, struct sudo_ctx); + ctx->ev = ev; + ctx->cdb = cdb; + + + ret =sudo_server_connect(mem_ctx,ev,ctx); + DEBUG(0, ("sudo server returned %d.\n",ret)); + return EOK; } @@ -73,7 +245,7 @@ int main(int argc, const char *argv[]) poptFreeContext(pc); /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_sudo_dbg"; + debug_log_file = "sssd_sudo"; ret = server_setup("sssd[sudo]", 0, CONFDB_SUDO_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; diff --git a/src/responder/sudo/sudosrv.h b/src/responder/sudo/sudosrv.h new file mode 100644 index 00000000..e09eaeb8 --- /dev/null +++ b/src/responder/sudo/sudosrv.h @@ -0,0 +1,64 @@ +/* + SSSD + + SUDO Responder + + Copyright (C) Arun Scaria (2011) + + 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 _SUDOSRV_PRIVATE_H_ +#define _SUDOSRV_PRIVATE_H_ + + +#define CONFDB_SUDO_CONF_ENTRY "config/sudo" + +#define SUDO_INTERFACE "org.freedesktop.sssd.sudo" +#define SUDO_PATH "/org/freedesktop/sssd/sudo" +#define SUDO_METHOD_QUERY "queryService" + +static int sudo_query_validation(DBusMessage *message, struct sbus_connection *conn); +struct sbus_method sudo_methods[] = { + + { SUDO_METHOD_QUERY, sudo_query_validation }, + { NULL, NULL } +}; + +struct sbus_interface sudo_interface = { + SUDO_INTERFACE, + SUDO_PATH, + SBUS_DEFAULT_VTABLE, + sudo_methods, + NULL +}; + +struct sudo_ctx { + struct tevent_context *ev; + struct confdb_ctx *cdb; + + struct sbus_connection *mon_conn; + struct sbus_connection *sbus_srv; + + size_t check_online_ref_count; +}; + +struct sudo_client { + struct sudo_ctx *sudoctx; + struct sbus_connection *conn; + struct tevent_timer *timeout; + bool initialized; +}; + +#endif \ No newline at end of file diff --git a/src/sss_client/sudo_plugin/sss_sudoplugin.c b/src/sss_client/sudo_plugin/sss_sudoplugin.c index 90803e4c..46ed72a2 100644 --- a/src/sss_client/sudo_plugin/sss_sudoplugin.c +++ b/src/sss_client/sudo_plugin/sss_sudoplugin.c @@ -24,25 +24,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see - ----------------TO DO--------------------- - Create/Edit /etc/sudo.conf as below. - --/etc/sudo.conf-- - # Default /etc/sudo.conf file - # - # Format: - # Plugin plugin_name plugin_path - # Path askpass /path/to/askpass - # - # The plugin_path is relative to /usr/local/libexec unless - # fully qualified. - # The plugin_name corresponds to a global symbol in the plugin - # that contains the plugin interface structure. - # - Plugin sss_sudo_policy /usr/lib/sudo/libsss_sudoplugin.so - */ + + /* * Define to the version of sudo package * This declaration is to be removed and @@ -703,16 +689,7 @@ int sss_sudo_make_request(struct sss_cli_req_data *rd, int *errnop) { -/*Here the msg in the rd structure is passed to SSSD with the help of libdbus. - -This isn't coded yet. But I hope the libdbus part can be sompleted today itself*/ - -/* No need to review this function. It is to be cahanged */ - - - const char * param ="hai"; - - + const char * param ="Hello, World!"; DBusMessage* dbus_msg; DBusMessageIter args; DBusConnection* conn; @@ -722,13 +699,13 @@ This isn't coded yet. But I hope the libdbus part can be sompleted today itself* int status; dbus_uint32_t level; - printf("Calling remote method wit %s\n", (const char *)rd->data); + printf("Calling remote method wit %s\n", param); /* initialise the errors */ dbus_error_init(&err); /* connect to the system bus and check for errors */ - conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + conn = dbus_connection_open_private("unix:path=/tmp/sssd/sudo", &err); if (dbus_error_is_set(&err)) { fprintf(stderr, "Connection Error (%s)\n", err.message); dbus_error_free(&err); @@ -737,22 +714,12 @@ This isn't coded yet. But I hope the libdbus part can be sompleted today itself* return SSS_SUDO_SYSTEM_ERR; } - /* request our name on the bus */ - ret = dbus_bus_request_name(conn, "org.sssd.sudo.request", - DBUS_NAME_FLAG_REPLACE_EXISTING ,&err); - if (dbus_error_is_set(&err)) { - fprintf(stderr, "Name Error (%s)\n", err.message); - dbus_error_free(&err); - } - if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { - return SSS_SUDO_SYSTEM_ERR; - } /* create a new method call and check for errors */ - dbus_msg = dbus_message_new_method_call( "org.sssd.sudo.request", /* target */ - "/test/method/Object", /* object */ - "test.method.Type", /* interface */ - "Method"); /* method name */ + dbus_msg = dbus_message_new_method_call( NULL, /* target */ + "/org/freedesktop/sssd/sudo", /* object */ + "org.freedesktop.sssd.sudo", /* interface */ + "queryService"); /* method name */ if (NULL == dbus_msg) { fprintf(stderr, "Message Null\n"); return SSS_SUDO_SYSTEM_ERR; @@ -766,7 +733,7 @@ This isn't coded yet. But I hope the libdbus part can be sompleted today itself* } /* send message and get a handle for a reply */ - if (!dbus_connection_send_with_reply (conn,dbus_msg, &pending, -1)) { + if (!dbus_connection_send (conn,dbus_msg, &pending)) { fprintf(stderr, "Out Of Memory!\n"); exit(1); } @@ -796,18 +763,12 @@ This isn't coded yet. But I hope the libdbus part can be sompleted today itself* /* read the parameters */ if (!dbus_message_iter_init(dbus_msg, &args)) fprintf(stderr, "Message has no arguments!\n"); - else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args)) - fprintf(stderr, "Argument is not boolean!\n"); + else if (DBUS_TYPE_UINT16 != dbus_message_iter_get_arg_type(&args)) + fprintf(stderr, "Argument is not DBUS_TYPE_UINT16!\n"); else dbus_message_iter_get_basic(&args, &status); - if (!dbus_message_iter_next(&args)) - fprintf(stderr, "Message has too few arguments!\n"); - else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args)) - fprintf(stderr, "Argument is not int!\n"); - else - dbus_message_iter_get_basic(&args, &level); - + printf("Got Reply: %d, %d\n", status, level); // free reply and close connection @@ -816,203 +777,12 @@ This isn't coded yet. But I hope the libdbus part can be sompleted today itself* - - - - - - - - return SSS_STATUS_SUCCESS; } -static size_t add_string_item(enum sudo_item_type type, const char *str, - const size_t size, uint8_t *buf) { - size_t rp=0; - uint32_t c; - - if (str == NULL || *str == '\0') return 0; - - c = type; - memcpy(&buf[rp], &c, sizeof(uint32_t)); - rp += sizeof(uint32_t); - - c = size; - memcpy(&buf[rp], &c, sizeof(uint32_t)); - rp += sizeof(uint32_t); - - memcpy(&buf[rp], str, size); - rp += size; - - return rp; -} - - -static size_t add_uint32_t_item(enum sudo_item_type type, const uint32_t val, - uint8_t *buf) { - size_t rp=0; - uint32_t c; - - c = type; - memcpy(&buf[rp], &c, sizeof(uint32_t)); - rp += sizeof(uint32_t); - - c = sizeof(uint32_t); - memcpy(&buf[rp], &c, sizeof(uint32_t)); - rp += sizeof(uint32_t); - - c = val; - memcpy(&buf[rp], &c, sizeof(uint32_t)); - rp += sizeof(uint32_t); - - return rp; -} - - - -static int pack_message_sudo_v1( size_t *size, uint8_t **buffer) { - - int len; - uint8_t *buf; - int rp; - uint32_t terminator = SSS_END_OF_SUDO_REQUEST; - - len = sizeof(uint32_t) + 3*sizeof(uint32_t) +sizeof(uint32_t); // msg.user_id ; - - len += *msg.cwd != '\0' ?2*sizeof(uint32_t) + msg.cwd_size : 0; - - len += *msg.tty != '\0' ?2*sizeof(uint32_t) + msg.tty_size : 0; - - len += msg.runas_user != NULL ?2*sizeof(uint32_t) + msg.runas_user_size : 0; - - len += msg.runas_group != NULL ?2*sizeof(uint32_t) + msg.runas_group_size : 0; - - len += msg.prompt != NULL ?2*sizeof(uint32_t) + msg.prompt_size : 0; - - len += msg.network_addrs != NULL ?2*sizeof(uint32_t) + msg.network_addrs_size : 0; - - len += 3*sizeof(uint32_t); //msg.use_sudoedit - - len += 3*sizeof(uint32_t); // msg.use_set_home ; - - len += 3*sizeof(uint32_t); //msg.use_preserve_environment ; - - len += 3*sizeof(uint32_t); // msg.use_implied_shell ; - - len += 3*sizeof(uint32_t);// msg.use_login_shell ; - - len += 3*sizeof(uint32_t);// msg.use_run_shell ; - - len += 3*sizeof(uint32_t); // msg.use_preserve_groups ; - - len += 3*sizeof(uint32_t); // msg.use_ignore_ticket ; - - len += 3*sizeof(uint32_t);; // msg.use_noninteractive ; - - len += 3*sizeof(uint32_t); // msg.debug_level ; - - len += *msg.command != '\0' ? - 2*sizeof(uint32_t) + msg.command_size : 0; - - len += 3*sizeof(uint32_t) ; //msg.user_env : 0; - - len += 3*sizeof(uint32_t); /* cli_pid */ - - buf = malloc(len); - if (buf == NULL) { - // D(("malloc failed.")); - return SSS_SUDO_BUF_ERR; - } - - rp = 0; - ((uint32_t *)(&buf[rp]))[0] = SSS_START_OF_SUDO_REQUEST; - rp += sizeof(uint32_t); - - - rp += add_uint32_t_item(SSS_SUDO_ITEM_UID, (uint32_t) msg.userid, - &buf[rp]); - - - rp += add_string_item(SSS_SUDO_ITEM_CWD, msg.cwd, - msg.cwd_size, &buf[rp]); - - rp += add_string_item(SSS_SUDO_ITEM_TTY, msg.tty, - msg.tty_size, &buf[rp]); - - rp += add_string_item(SSS_SUDO_ITEM_RUSER, msg.runas_user, - msg.runas_user_size, &buf[rp]); - - rp += add_string_item(SSS_SUDO_ITEM_RGROUP, msg.runas_group, - msg.runas_group_size, &buf[rp]); - - rp += add_string_item(SSS_SUDO_ITEM_PROMPT, msg.prompt, - msg.prompt_size, &buf[rp]); - - rp += add_string_item(SSS_SUDO_ITEM_NETADDR, msg.network_addrs, - msg.network_addrs_size, &buf[rp]); - - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_SUDOEDIT, (uint32_t) msg.use_sudoedit, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_SETHOME, (uint32_t) msg.use_set_home, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_PRESERV_ENV, (uint32_t) msg.use_preserve_environment, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_IMPLIED_SHELL, (uint32_t) msg.use_implied_shell, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_LOGIN_SHELL, (uint32_t) msg.use_login_shell, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_RUN_SHELL, (uint32_t) msg.use_run_shell, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_PRE_GROUPS, (uint32_t) msg.use_preserve_groups, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_IGNORE_TICKET, (uint32_t) msg.use_ignore_ticket, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USE_NON_INTERACTIVE, (uint32_t) msg.use_noninteractive, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_DEBUG_LEVEL, (uint32_t) msg.debug_level, - &buf[rp]); - - - rp += add_string_item(SSS_SUDO_ITEM_COMMAND, msg.command, - msg.command_size, &buf[rp]); - - - rp += add_uint32_t_item(SSS_SUDO_ITEM_USER_ENV, (uint32_t) msg.user_env, - &buf[rp]); - - rp += add_uint32_t_item(SSS_SUDO_ITEM_CLI_PID, (uint32_t) getpid(), - &buf[rp]); - - - - memcpy(&buf[rp], &terminator, sizeof(uint32_t)); - rp += sizeof(uint32_t); - - if (rp != len) { - //D(("error during packet creation.")); - free(buf); - return SSS_SUDO_BUF_ERR; - } - - *size = len; - *buffer = buf; - - return 0; -} @@ -1030,14 +800,6 @@ static int send_and_receive() print_sudo_items(); - ret = pack_message_sudo_v1(&rd.len, &buf); - if (ret == SSS_SUDO_BUF_ERR) { - // D(("pack_message failed.")); - _status = SSS_SUDO_SYSTEM_ERR; - goto done; - } - rd.data = buf; - errnop = 0; ret = sss_sudo_make_request( &rd, &repbuf, &replen, &errnop); @@ -1049,37 +811,21 @@ static int send_and_receive() goto done; } -/* FIXME: add an end signature */ +/* check the reply signature */ if (replen < (2*sizeof(int32_t))) { //D(("response not in expected format.")); _status = SSS_SUDO_SYSTEM_ERR; goto done; } - _status = ((int32_t *)repbuf)[0]; - //ret = eval_response(replen, repbuf); - if (ret != SSS_SUDO_SUCCESS) { - // D(("eval_response failed.")); - _status = ret; - goto done; - } - - if (_status != SSS_SUDO_SUCCESS) { - //D( "received for user %s: %d (%d)", user_information.username, _status, _status); - } done: - if (buf != NULL ) { - free(buf); - } - free(repbuf); - -_status = SSS_STATUS_SUCCESS; + _status = SSS_STATUS_SUCCESS; -if (_status == SSS_STATUS_SUCCESS) - return _status; -else + if (_status == SSS_STATUS_SUCCESS) + return _status; + else return SSS_STATUS_UNAVAIL; } -- cgit