summaryrefslogtreecommitdiff
path: root/src/sss_client
diff options
context:
space:
mode:
Diffstat (limited to 'src/sss_client')
-rw-r--r--src/sss_client/sudo/sss_sudo.c107
-rw-r--r--src/sss_client/sudo/sss_sudo.h40
-rw-r--r--src/sss_client/sudo/sss_sudo_private.h1
-rw-r--r--src/sss_client/sudo/sss_sudo_response.c12
-rw-r--r--src/sss_client/sudo_testcli/sudo_testcli.c64
5 files changed, 158 insertions, 66 deletions
diff --git a/src/sss_client/sudo/sss_sudo.c b/src/sss_client/sudo/sss_sudo.c
index 378df984..e2bb3e00 100644
--- a/src/sss_client/sudo/sss_sudo.c
+++ b/src/sss_client/sudo/sss_sudo.c
@@ -18,17 +18,22 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "config.h"
+
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include "util/util.h"
#include "sss_client/sss_cli.h"
#include "sss_client/sudo/sss_sudo.h"
#include "sss_client/sudo/sss_sudo_private.h"
-static int sss_sudo_create_query(const char *username,
- char **_query,
- int *_query_len);
+int sss_sudo_create_query(uid_t uid,
+ const char *username,
+ uint8_t **_query,
+ size_t *_query_len);
static void sss_sudo_free_rules(unsigned int num_rules,
struct sss_sudo_rule *rules);
@@ -37,19 +42,34 @@ static void sss_sudo_free_attrs(unsigned int num_attrs,
struct sss_sudo_attr *attrs);
static int sss_sudo_send_recv_generic(enum sss_cli_command command,
- struct sss_cli_req_data *request,
+ uid_t uid,
+ const char *username,
uint32_t *_error,
+ char **_domainname,
struct sss_sudo_result **_result)
{
+ struct sss_cli_req_data request;
+ uint8_t *query_buf = NULL;
+ size_t query_len = 0;
uint8_t *reply_buf = NULL;
size_t reply_len = 0;
int errnop = 0;
int ret = 0;
+ /* create query */
+
+ ret = sss_sudo_create_query(uid, username, &query_buf, &query_len);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ request.len = query_len;
+ request.data = (const void*)query_buf;
+
/* send query and receive response */
errnop = 0;
- ret = sss_sudo_make_request(command, request,
+ ret = sss_sudo_make_request(command, &request,
&reply_buf, &reply_len, &errnop);
if (ret != SSS_STATUS_SUCCESS) {
ret = errnop;
@@ -59,69 +79,76 @@ static int sss_sudo_send_recv_generic(enum sss_cli_command command,
/* parse structure */
ret = sss_sudo_parse_response((const char*)reply_buf, reply_len,
- _result, _error);
+ _domainname, _result, _error);
done:
+ free(query_buf);
free(reply_buf);
return ret;
}
-int sss_sudo_send_recv(const char *username,
+int sss_sudo_send_recv(uid_t uid,
+ const char *username,
+ const char *domainname,
uint32_t *_error,
struct sss_sudo_result **_result)
{
- struct sss_cli_req_data request;
- char *query = NULL;
- int query_len = 0;
- int ret = 0;
+ char *fullname = NULL;
+ int ret;
- /* create query */
-
- ret = sss_sudo_create_query(username, &query, &query_len);
- if (ret != EOK) {
- goto done;
+ if (username == NULL || strlen(username) == 0) {
+ return EINVAL;
}
- request.len = query_len;
- request.data = (const void*)query;
-
- /* send query and recieve response */
+ if (domainname != NULL) {
+ ret = asprintf(&fullname, "%s@%s", username, domainname);
+ if (ret == -1) {
+ return ENOMEM;
+ }
+ } else {
+ fullname = strdup(username);
+ if (fullname == NULL) {
+ return ENOMEM;
+ }
+ }
- ret = sss_sudo_send_recv_generic(SSS_SUDO_GET_SUDORULES, &request,
- _error, _result);
+ /* send query and receive response */
-done:
- free(query);
+ ret = sss_sudo_send_recv_generic(SSS_SUDO_GET_SUDORULES, uid, fullname,
+ _error, NULL, _result);
+ free(fullname);
return ret;
}
-int sss_sudo_send_recv_defaults(uint32_t *_error,
+int sss_sudo_send_recv_defaults(uid_t uid,
+ const char *username,
+ uint32_t *_error,
+ char **_domainname,
struct sss_sudo_result **_result)
{
- struct sss_cli_req_data request;
-
- request.len = 0;
- request.data = (const void*)NULL;
+ if (username == NULL || strlen(username) == 0) {
+ return EINVAL;
+ }
- return sss_sudo_send_recv_generic(SSS_SUDO_GET_DEFAULTS, &request,
- _error, _result);
+ return sss_sudo_send_recv_generic(SSS_SUDO_GET_DEFAULTS, uid, username,
+ _error, _domainname, _result);
}
-int sss_sudo_create_query(const char *username, char **_query, int *_query_len)
+int sss_sudo_create_query(uid_t uid, const char *username,
+ uint8_t **_query, size_t *_query_len)
{
- char *data = NULL;
- int data_len = strlen(username) + 1;
-
- if (data_len <= 1) {
- return EINVAL;
- }
+ uint8_t *data = NULL;
+ size_t username_len = strlen(username) * sizeof(char) + 1;
+ size_t data_len = sizeof(uid_t) + username_len;
+ size_t offset = 0;
- data = (char*)malloc(data_len * sizeof(char));
+ data = (uint8_t*)malloc(data_len * sizeof(uint8_t));
if (data == NULL) {
return ENOMEM;
}
- memcpy(data, username, data_len);
+ SAFEALIGN_SET_VALUE(data, uid, uid_t, &offset);
+ memcpy(data + offset, username, username_len);
*_query = data;
*_query_len = data_len;
diff --git a/src/sss_client/sudo/sss_sudo.h b/src/sss_client/sudo/sss_sudo.h
index fe01e65d..1a275cfa 100644
--- a/src/sss_client/sudo/sss_sudo.h
+++ b/src/sss_client/sudo/sss_sudo.h
@@ -30,6 +30,7 @@
*/
#include <stdint.h>
+#include <sys/types.h>
/** The value returned when the communication with SUDO is successful and
* the user was found in one of the domains
@@ -89,7 +90,9 @@ struct sss_sudo_result {
* @brief Send a request to SSSD to retreive all SUDO rules for a given
* user.
*
+ * @param[in] uid The uid of the user to retreive the rules for.
* @param[in] username The username to retreive the rules for
+ * @param[in] domainname The domain name the user is a member of.
* @param[out] _error The result of the search in SSSD's domains. If the
* user was present in the domain, the _error code is
* SSS_SUDO_ERROR_OK and the _result structure is
@@ -109,7 +112,9 @@ struct sss_sudo_result {
* tell whether the result contains any rules or whether SSSD knew the
* user at all. That information is transferred in the _error parameter.
*/
-int sss_sudo_send_recv(const char *username,
+int sss_sudo_send_recv(uid_t uid,
+ const char *username,
+ const char *domainname,
uint32_t *_error,
struct sss_sudo_result **_result);
@@ -117,24 +122,35 @@ int sss_sudo_send_recv(const char *username,
* @brief Send a request to SSSD to retrieve the default options, commonly
* stored in the "cn=defaults" record,
*
- * @param[out] _error The result of the search in SSSD's domains. If the
- * options were present in the domain, the _error code
- * is SSS_SUDO_ERROR_OK and the _result structure is
- * returned even if it was empty (in other words
- * _result->num_rules == 0). Other problems are returned
- * as errno codes.
+ * @param[in] uid The uid of the user to retreive the rules for.
*
- * @param[out] _result Newly allocated structure sss_result that contains
- * the options. If no options were found this structure
- * is "empty", which means that the num_rules member
- * is 0.
+ * @param[in] username The username to retreive the rules for.
+ *
+ * @param[out] _error The result of the search in SSSD's domains. If the
+ * options were present in the domain, the _error code
+ * is SSS_SUDO_ERROR_OK and the _result structure is
+ * returned even if it was empty (in other words
+ * _result->num_rules == 0). Other problems are returned
+ * as errno codes.
+ *
+ * @param[out] _domainname The domain name the user is a member of.
+ *
+ * @param[out] _result Newly allocated structure sss_result that contains
+ * the options. If no options were found this structure
+ * is "empty", which means that the num_rules member
+ * is 0.
*
* @return 0 on success and other errno values on failure. The return value
* denotes whether communication with SSSD was successful. It does not
* tell whether the result contains any rules or whether SSSD knew the
* user at all. That information is transferred in the _error parameter.
+ *
+ * @note The _domainname should be freed using free().
*/
-int sss_sudo_send_recv_defaults(uint32_t *_error,
+int sss_sudo_send_recv_defaults(uid_t uid,
+ const char *username,
+ uint32_t *_error,
+ char **_domainname,
struct sss_sudo_result **_result);
/**
diff --git a/src/sss_client/sudo/sss_sudo_private.h b/src/sss_client/sudo/sss_sudo_private.h
index 674bf125..2827a94d 100644
--- a/src/sss_client/sudo/sss_sudo_private.h
+++ b/src/sss_client/sudo/sss_sudo_private.h
@@ -26,6 +26,7 @@
int sss_sudo_parse_response(const char *message,
size_t message_len,
+ char **_domainname,
struct sss_sudo_result **_result,
uint32_t *_error);
diff --git a/src/sss_client/sudo/sss_sudo_response.c b/src/sss_client/sudo/sss_sudo_response.c
index 4e74d83a..471d42ed 100644
--- a/src/sss_client/sudo/sss_sudo_response.c
+++ b/src/sss_client/sudo/sss_sudo_response.c
@@ -51,10 +51,12 @@ static int sss_sudo_parse_string(const char *message,
int sss_sudo_parse_response(const char *message,
size_t message_len,
+ char **_domainname,
struct sss_sudo_result **_result,
uint32_t *_error)
{
struct sss_sudo_result *result = NULL;
+ char *domainname = NULL;
size_t cursor = 0;
int ret = EOK;
int i = 0;
@@ -65,6 +67,16 @@ int sss_sudo_parse_response(const char *message,
return ret;
}
+ /* domain name */
+ ret = sss_sudo_parse_string(message, message_len, &cursor, &domainname);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ if (_domainname != NULL) {
+ *_domainname = domainname;
+ }
+
/* result */
result = malloc(sizeof(struct sss_sudo_result));
if (result == NULL) {
diff --git a/src/sss_client/sudo_testcli/sudo_testcli.c b/src/sss_client/sudo_testcli/sudo_testcli.c
index b498acec..d86fb752 100644
--- a/src/sss_client/sudo_testcli/sudo_testcli.c
+++ b/src/sss_client/sudo_testcli/sudo_testcli.c
@@ -23,6 +23,8 @@
#include <errno.h>
#include <string.h>
#include <talloc.h>
+#include <sys/types.h>
+#include <pwd.h>
#include "sss_client/sss_cli.h"
#include "sss_client/sudo/sss_sudo.h"
@@ -38,40 +40,74 @@ int main(int argc, char **argv)
{
int ret = 0;
struct sss_sudo_result *result = NULL;
+ struct passwd *passwd = NULL;
+ const char *username = NULL;
+ char *domainname = NULL;
+ uid_t uid = 0;
uint32_t error = 0;
- if (argc > 2) {
- fprintf(stderr, "Usage: sss_sudo_cli username\n");
+ if (argc > 3) {
+ fprintf(stderr, "Usage: sss_sudo_cli username [uid]\n");
goto fail;
}
- /* get sss_result - it will send new query to responder */
-
- if (argc == 1) {
- ret = sss_sudo_send_recv_defaults(&error, &result);
- if (ret != EOK) {
- fprintf(stderr, "sss_sudo_send_recv_defaults() failed: %s\n", strerror(ret));
- goto fail;
- }
+ username = argv[1];
+ if (argc == 3) {
+ uid = atoi(argv[2]);
} else {
- ret = sss_sudo_send_recv(argv[1], &error, &result);
- if (ret != EOK) {
- fprintf(stderr, "sss_sudo_send_recv() failed: %s\n", strerror(ret));
+ passwd = getpwnam(username);
+ if (passwd == NULL) {
+ fprintf(stderr, "Unknown user\n");
goto fail;
}
+ uid = passwd->pw_uid;
+ }
+
+ /* get sss_result - it will send new query to responder */
+
+ /* get default options */
+
+ ret = sss_sudo_send_recv_defaults(uid, username, &error,
+ &domainname, &result);
+ if (ret != EOK) {
+ fprintf(stderr, "sss_sudo_send_recv_defaults() failed: %s\n",
+ strerror(ret));
+ goto fail;
+ }
+
+ printf("User [%s:%llu] found in domain: %s\n\n",
+ username, (unsigned long long)uid,
+ domainname != NULL ? domainname : "<NULL>");
+
+ printf("=== Printing response data [default options] ===\n");
+ printf("Response code: %d\n\n", error);
+ if (error == SSS_SUDO_ERROR_OK) {
+ print_sss_result(result);
+ }
+
+ sss_sudo_free_result(result);
+
+ /* get rules */
+
+ ret = sss_sudo_send_recv(uid, username, domainname, &error, &result);
+ if (ret != EOK) {
+ fprintf(stderr, "sss_sudo_send_recv() failed: %s\n", strerror(ret));
+ goto fail;
}
- printf("=== Printing response data ===\n");
+ printf("\n=== Printing response data [rules] ===\n");
printf("Response code: %d\n\n", error);
if (error == SSS_SUDO_ERROR_OK) {
print_sss_result(result);
}
+ free(domainname);
sss_sudo_free_result(result);
return 0;
fail:
+ free(domainname);
sss_sudo_free_result(result);
return 1;
}