summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Kamenskiy <alexey.kamenskiy@chinanetcloud.com>2017-10-18 18:28:07 +0800
committerLukas Slebodnik <lslebodn@redhat.com>2017-10-19 16:05:06 +0200
commitf34a8330c1615511795847b0a1454249d782db2a (patch)
treed8c5bd7e556b1549a41c6a406e500f9ce1373728
parentbc854800cc67271205d63136daaf68d7863cea6b (diff)
downloadsssd-f34a8330c1615511795847b0a1454249d782db2a.tar.gz
sssd-f34a8330c1615511795847b0a1454249d782db2a.tar.xz
sssd-f34a8330c1615511795847b0a1454249d782db2a.zip
LDAP: Add support for rhost access control
This patch implements verification of pam_rhost against rules stored in LDAP entry of a user. Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> Reviewed-by: Pavel Březina <pbrezina@redhat.com>
-rw-r--r--Makefile.am1
-rw-r--r--src/config/SSSDConfig/__init__.py.in1
-rw-r--r--src/config/cfg_rules.ini1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ldap.conf1
-rw-r--r--src/db/sysdb.h1
-rw-r--r--src/man/sssd-ldap.5.xml37
-rw-r--r--src/providers/ad/ad_opts.c1
-rw-r--r--src/providers/ipa/ipa_opts.c1
-rw-r--r--src/providers/ldap/ldap_init.c2
-rw-r--r--src/providers/ldap/ldap_opts.c3
-rw-r--r--src/providers/ldap/sdap.h1
-rw-r--r--src/providers/ldap/sdap_access.c88
-rw-r--r--src/providers/ldap/sdap_access.h2
-rw-r--r--src/tests/cmocka/test_sdap_access.c192
-rw-r--r--src/tests/cmocka/test_sdap_access.h36
15 files changed, 367 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index cb2075b93..41a8f32f4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -833,6 +833,7 @@ dist_noinst_HEADERS = \
src/tests/cmocka/common_mock_krb5.h \
src/tests/cmocka/common_mock_be.h \
src/tests/cmocka/test_expire_common.h \
+ src/tests/cmocka/test_sdap_access.h \
src/tests/cmocka/data_provider/mock_dp.h \
src/tests/sbus_codegen_tests_generated.h \
src/sss_client/pam_message.h \
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 227f76180..d99b718e0 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -349,6 +349,7 @@ option_strings = {
'ldap_user_shadow_flag' : _('shadowFlag attribute'),
'ldap_user_authorized_service' : _('Attribute listing authorized PAM services'),
'ldap_user_authorized_host' : _('Attribute listing authorized server hosts'),
+ 'ldap_user_authorized_rhost' : _('Attribute listing authorized server rhosts'),
'ldap_user_krb_last_pwd_change' : _('krbLastPwdChange attribute'),
'ldap_user_krb_password_expiration' : _('krbPasswordExpiration attribute'),
'ldap_pwd_attribute' : _('Attribute indicating that server side password policies are active'),
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index f3d30b9b3..e49e8d43f 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -685,6 +685,7 @@ option = ldap_uri
option = ldap_user_ad_account_expires
option = ldap_user_ad_user_account_control
option = ldap_user_authorized_host
+option = ldap_user_authorized_rhost
option = ldap_user_authorized_service
option = ldap_user_auth_type
option = ldap_user_certificate
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index c2ad3463d..65b6407f6 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -76,6 +76,7 @@ ldap_user_krb_last_pwd_change = str, None, false
ldap_user_krb_password_expiration = str, None, false
ldap_user_authorized_service = str, None, false
ldap_user_authorized_host = str, None, false
+ldap_user_authorized_rhost = str, None, false
ldap_pwd_attribute = str, None, false
ldap_user_ad_account_expires = str, None, false
ldap_user_ad_user_account_control = str, None, false
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 411ee9aed..fbbe32107 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -102,6 +102,7 @@
#define SYSDB_AUTHORIZED_SERVICE "authorizedService"
#define SYSDB_AUTHORIZED_HOST "authorizedHost"
+#define SYSDB_AUTHORIZED_RHOST "authorizedRHost"
#define SYSDB_NETGROUP_TRIPLE "netgroupTriple"
#define SYSDB_ORIG_NETGROUP_MEMBER "originalMemberNisNetgroup"
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index d1b70ac4f..d38bac360 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -830,6 +830,34 @@
</varlistentry>
<varlistentry>
+ <term>ldap_user_authorized_rhost (string)</term>
+ <listitem>
+ <para>
+ If access_provider=ldap and
+ ldap_access_order=rhost, SSSD will use the presence
+ of the rhost attribute in the user's LDAP entry to
+ determine access privilege. Similarly to host
+ verification process.
+ </para>
+ <para>
+ An explicit deny (!rhost) is resolved first. Second,
+ SSSD searches for explicit allow (rhost) and finally
+ for allow_all (*).
+ </para>
+ <para>
+ Please note that the ldap_access_order
+ configuration option <emphasis>must</emphasis>
+ include <quote>rhost</quote> in order for the
+ ldap_user_authorized_rhost option
+ to work.
+ </para>
+ <para>
+ Default: rhost
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ldap_user_certificate (string)</term>
<listitem>
<para>
@@ -2088,6 +2116,15 @@ ldap_access_filter = (employeeType=admin)
to determine access
</para>
<para>
+ <emphasis>rhost</emphasis>: use the rhost attribute
+ to determine whether remote host can access
+ </para>
+ <para>
+ Please note, rhost field in pam is set by application,
+ it is better to check what the application sends to
+ pam, before enabling this access control option
+ </para>
+ <para>
Default: filter
</para>
<para>
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index fc1dc6733..ac7163d56 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -213,6 +213,7 @@ struct sdap_attr_map ad_2008r2_user_map[] = {
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
{ "ldap_ns_account_lock", NULL, SYSDB_NS_ACCOUNT_LOCK, NULL},
{ "ldap_user_authorized_host", NULL, SYSDB_AUTHORIZED_HOST, NULL },
+ { "ldap_user_authorized_rhost", NULL, SYSDB_AUTHORIZED_RHOST, NULL },
{ "ldap_user_nds_login_disabled", NULL, SYSDB_NDS_LOGIN_DISABLED, NULL },
{ "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index 09b78f726..7c7c1ab01 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -201,6 +201,7 @@ struct sdap_attr_map ipa_user_map[] = {
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
{ "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL },
+ { "ldap_user_authorized_rhost", NULL, SYSDB_AUTHORIZED_RHOST, NULL },
{ "ldap_user_nds_login_disabled", "loginDisabled", SYSDB_NDS_LOGIN_DISABLED, NULL },
{ "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c
index b7102adb8..43d905893 100644
--- a/src/providers/ldap/ldap_init.c
+++ b/src/providers/ldap/ldap_init.c
@@ -286,6 +286,8 @@ static errno_t set_access_rules(TALLOC_CTX *mem_ctx,
access_ctx->access_rule[c] = LDAP_ACCESS_SERVICE;
} else if (strcasecmp(order_list[c], LDAP_ACCESS_HOST_NAME) == 0) {
access_ctx->access_rule[c] = LDAP_ACCESS_HOST;
+ } else if (strcasecmp(order_list[c], LDAP_ACCESS_RHOST_NAME) == 0) {
+ access_ctx->access_rule[c] = LDAP_ACCESS_RHOST;
} else if (strcasecmp(order_list[c], LDAP_ACCESS_LOCK_NAME) == 0) {
access_ctx->access_rule[c] = LDAP_ACCESS_LOCKOUT;
} else if (strcasecmp(order_list[c],
diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c
index 3b8154e5c..344effba9 100644
--- a/src/providers/ldap/ldap_opts.c
+++ b/src/providers/ldap/ldap_opts.c
@@ -174,6 +174,7 @@ struct sdap_attr_map rfc2307_user_map[] = {
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
{ "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL },
+ { "ldap_user_authorized_rhost", "rhost", SYSDB_AUTHORIZED_RHOST, NULL },
{ "ldap_user_nds_login_disabled", "loginDisabled", SYSDB_NDS_LOGIN_DISABLED, NULL },
{ "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
@@ -232,6 +233,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
{ "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL },
+ { "ldap_user_authorized_rhost", "rhost", SYSDB_AUTHORIZED_RHOST, NULL },
{ "ldap_user_nds_login_disabled", "loginDisabled", SYSDB_NDS_LOGIN_DISABLED, NULL },
{ "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
@@ -290,6 +292,7 @@ struct sdap_attr_map gen_ad2008r2_user_map[] = {
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
{ "ldap_ns_account_lock", NULL, SYSDB_NS_ACCOUNT_LOCK, NULL},
{ "ldap_user_authorized_host", NULL, SYSDB_AUTHORIZED_HOST, NULL },
+ { "ldap_user_authorized_rhost", NULL, SYSDB_AUTHORIZED_RHOST, NULL },
{ "ldap_user_nds_login_disabled", NULL, SYSDB_NDS_LOGIN_DISABLED, NULL },
{ "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index a128915eb..2ba016ff5 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -279,6 +279,7 @@ enum sdap_user_attrs {
SDAP_AT_AD_USER_ACCOUNT_CONTROL,
SDAP_AT_NS_ACCOUNT_LOCK,
SDAP_AT_AUTHORIZED_HOST,
+ SDAP_AT_AUTHORIZED_RHOST,
SDAP_AT_NDS_LOGIN_DISABLED,
SDAP_AT_NDS_LOGIN_EXPIRATION_TIME,
SDAP_AT_NDS_LOGIN_ALLOWED_TIME_MAP,
diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c
index 4f3357a79..1ee4dcd2b 100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -97,6 +97,8 @@ static errno_t sdap_access_service(struct pam_data *pd,
static errno_t sdap_access_host(struct ldb_message *user_entry);
+errno_t sdap_access_rhost(struct ldb_message *user_entry, char *rhost);
+
enum sdap_access_control_type {
SDAP_ACCESS_CONTROL_FILTER,
SDAP_ACCESS_CONTROL_PPOLICY_LOCK,
@@ -309,6 +311,10 @@ static errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state,
ret = sdap_access_host(state->user_entry);
break;
+ case LDAP_ACCESS_RHOST:
+ ret = sdap_access_rhost(state->user_entry, state->pd->rhost);
+ break;
+
default:
DEBUG(SSSDBG_CRIT_FAILURE,
"Unexpected access rule type. Access denied.\n");
@@ -1298,6 +1304,88 @@ static errno_t sdap_access_host(struct ldb_message *user_entry)
return ret;
}
+errno_t sdap_access_rhost(struct ldb_message *user_entry, char *pam_rhost)
+{
+ errno_t ret;
+ struct ldb_message_element *el;
+ char *be_rhost_rule;
+ unsigned int i;
+
+ /* If user_entry is NULL do not perform any checks */
+ if (user_entry == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "user_entry is NULL, that is not possible, "
+ "so we just reject access\n");
+ return ERR_ACCESS_DENIED;
+ }
+
+ /* If pam_rhost is NULL do not perform any checks */
+ if (pam_rhost == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "pam_rhost is NULL, no rhost check is possible\n");
+ return EOK;
+ }
+
+ /* When the access is local we get empty string as pam_rhost
+ in which case we should not evaluate rhost access rules */
+ /* FIXME: I think ideally should have LDAP to define what to do in
+ * this case */
+ if (pam_rhost[0] == '\0') {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "pam_rhost is empty, possible local access, "
+ "no rhost check possible\n");
+ return EOK;
+ }
+
+ /* If rhost validation is enabled and entry has no relevant attribute -
+ * deny access */
+ el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_RHOST);
+ if (!el || el->num_values == 0) {
+ DEBUG(SSSDBG_CONF_SETTINGS, "Missing rhost entries. Access denied\n");
+ return ERR_ACCESS_DENIED;
+ }
+
+ ret = ENOENT;
+
+ for (i = 0; i < el->num_values; i++) {
+ be_rhost_rule = (char *)el->values[i].data;
+ if (be_rhost_rule[0] == '!'
+ && strcasecmp(pam_rhost, be_rhost_rule+1) == 0) {
+ /* This rhost is explicitly denied */
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "Access from [%s] denied by [%s]\n",
+ pam_rhost, be_rhost_rule);
+ /* A denial trumps all. Break here */
+ return ERR_ACCESS_DENIED;
+ } else if (strcasecmp(pam_rhost, be_rhost_rule) == 0) {
+ /* This rhost is explicitly allowed */
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "Access from [%s] granted by [%s]\n",
+ pam_rhost, be_rhost_rule);
+ /* We still need to loop through to make sure
+ * that it's not also explicitly denied
+ */
+ ret = EOK;
+ } else if (strcmp("*", be_rhost_rule) == 0) {
+ /* This user has access from anywhere */
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "Access from [%s] granted by [*]\n", pam_rhost);
+ /* We still need to loop through to make sure
+ * that it's not also explicitly denied
+ */
+ ret = EOK;
+ }
+ }
+
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "No matching rhost rules found\n");
+ ret = ERR_ACCESS_DENIED;
+ }
+
+ return ret;
+}
+
static void sdap_access_ppolicy_get_lockout_done(struct tevent_req *subreq);
static int sdap_access_ppolicy_retry(struct tevent_req *req);
static errno_t sdap_access_ppolicy_step(struct tevent_req *req);
diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h
index 049daced6..86969d442 100644
--- a/src/providers/ldap/sdap_access.h
+++ b/src/providers/ldap/sdap_access.h
@@ -45,6 +45,7 @@
#define LDAP_ACCESS_EXPIRE_POLICY_RENEW_NAME "pwd_expire_policy_renew"
#define LDAP_ACCESS_SERVICE_NAME "authorized_service"
#define LDAP_ACCESS_HOST_NAME "host"
+#define LDAP_ACCESS_RHOST_NAME "rhost"
#define LDAP_ACCESS_LOCK_NAME "lockout"
#define LDAP_ACCESS_PPOLICY_NAME "ppolicy"
@@ -61,6 +62,7 @@ enum ldap_access_rule {
LDAP_ACCESS_EXPIRE,
LDAP_ACCESS_SERVICE,
LDAP_ACCESS_HOST,
+ LDAP_ACCESS_RHOST,
LDAP_ACCESS_LOCKOUT,
LDAP_ACCESS_EXPIRE_POLICY_REJECT,
LDAP_ACCESS_EXPIRE_POLICY_WARN,
diff --git a/src/tests/cmocka/test_sdap_access.c b/src/tests/cmocka/test_sdap_access.c
index f306d8a42..900cfdba9 100644
--- a/src/tests/cmocka/test_sdap_access.c
+++ b/src/tests/cmocka/test_sdap_access.c
@@ -27,12 +27,15 @@
#include <unistd.h>
#include <sys/types.h>
#include <cmocka.h>
+#include <ldb.h>
#include "tests/common_check.h"
#include "tests/cmocka/test_expire_common.h"
+#include "tests/cmocka/test_sdap_access.h"
/* linking against function from sdap_access.c module */
extern bool nds_check_expired(const char *exp_time_str);
+extern errno_t sdap_access_rhost(struct ldb_message *user_entry, char *pam_rhost);
static void nds_check_expired_wrap(void *in, void *_out)
{
@@ -62,12 +65,199 @@ void test_nds_check_expire(void **state)
assert_false(res);
}
+static int test_sdap_access_rhost_setup(void **state)
+{
+ TALLOC_CTX *mem_ctx;
+ struct test_sdap_access_rhost_ctx *test_ctx;
+ struct ldb_message *user_no_rhost;
+ struct ldb_message *user_allow_somehost;
+ struct ldb_message *user_deny_somehost;
+ struct ldb_message *user_allow_all;
+ struct ldb_message *user_allow_all_deny_somehost;
+ struct ldb_message *user_allow_all_allow_somehost_deny_somehost;
+
+ mem_ctx = talloc_new(NULL);
+ assert_non_null(mem_ctx);
+
+ test_ctx = talloc(mem_ctx, struct test_sdap_access_rhost_ctx);
+ assert_non_null(test_ctx);
+
+ /* Setup empty user entry (with 0 entries for rhost) */
+ user_no_rhost = ldb_msg_new(test_ctx);
+ assert_non_null(user_no_rhost);
+ user_no_rhost->num_elements = 0;
+
+ /* Setup user entry with allow somehost */
+ user_allow_somehost = ldb_msg_new(test_ctx);
+ assert_non_null(user_allow_somehost);
+ ldb_msg_add_string(user_allow_somehost,
+ SYSDB_AUTHORIZED_RHOST,
+ "somehost");
+
+ /* Setup user entry with deny somehost */
+ user_deny_somehost = ldb_msg_new(test_ctx);
+ assert_non_null(user_deny_somehost);
+ ldb_msg_add_string(user_deny_somehost,
+ SYSDB_AUTHORIZED_RHOST,
+ "!somehost");
+
+ /* Setup user entry with allow all */
+ user_allow_all = ldb_msg_new(test_ctx);
+ assert_non_null(user_allow_all);
+ ldb_msg_add_string(user_allow_all,
+ SYSDB_AUTHORIZED_RHOST,
+ "*");
+
+ /* Setup user entry with allow all and deny somehost */
+ user_allow_all_deny_somehost = ldb_msg_new(test_ctx);
+ assert_non_null(user_allow_all_deny_somehost);
+ ldb_msg_add_string(user_allow_all_deny_somehost,
+ SYSDB_AUTHORIZED_RHOST,
+ "*");
+ ldb_msg_add_string(user_allow_all_deny_somehost,
+ SYSDB_AUTHORIZED_RHOST,
+ "!somehost");
+
+ /* Setup user entry with allow all, allow somehost and deny somehost */
+ user_allow_all_allow_somehost_deny_somehost = ldb_msg_new(test_ctx);
+ assert_non_null(user_allow_all_allow_somehost_deny_somehost);
+ ldb_msg_add_string(user_allow_all_allow_somehost_deny_somehost,
+ SYSDB_AUTHORIZED_RHOST,
+ "*");
+ ldb_msg_add_string(user_allow_all_allow_somehost_deny_somehost,
+ SYSDB_AUTHORIZED_RHOST,
+ "!somehost");
+ ldb_msg_add_string(user_allow_all_allow_somehost_deny_somehost,
+ SYSDB_AUTHORIZED_RHOST,
+ "somehost");
+
+ /* Setup test context */
+ test_ctx->user_no_rhost = user_no_rhost;
+ test_ctx->user_allow_somehost = user_allow_somehost;
+ test_ctx->user_deny_somehost = user_deny_somehost;
+ test_ctx->user_allow_all = user_allow_all;
+ test_ctx->user_allow_all_deny_somehost = user_allow_all_deny_somehost;
+ test_ctx->user_allow_all_allow_somehost_deny_somehost = \
+ user_allow_all_allow_somehost_deny_somehost;
+
+ *state = test_ctx;
+
+ return 0;
+}
+
+static int test_sdap_access_rhost_teardown(void **state)
+{
+ struct test_sdap_access_rhost_ctx *test_ctx;
+
+ test_ctx = talloc_get_type(*state, struct test_sdap_access_rhost_ctx);
+ assert_non_null(test_ctx);
+
+ talloc_free(test_ctx);
+
+ return 0;
+}
+
+static void test_sdap_access_rhost(void **state)
+{
+ struct test_sdap_access_rhost_ctx *test_ctx;
+ errno_t ret;
+
+ test_ctx = talloc_get_type(*state, struct test_sdap_access_rhost_ctx);
+ assert_non_null(test_ctx);
+
+ char pam_rhost_mock_empty[] = "";
+ char pam_rhost_mock_somehost[] = "somehost";
+ char pam_rhost_mock_someotherhost[] = "someotherhost";
+
+ /* Test both arguments as NULL */
+ ret = sdap_access_rhost(NULL, NULL);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access granted */
+
+ /* Test with user_entry == NULL and rhost == "somehost" */
+ ret = sdap_access_rhost(NULL, pam_rhost_mock_somehost);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access denied */
+
+ /* Test with user_no_rhost and rhost == NULL */
+ ret = sdap_access_rhost(test_ctx->user_no_rhost, NULL);
+ assert_int_equal(EOK, ret); /* Expected access granted */
+
+ /* Test with user_no_rhost and rhost == "" (local access) */
+ ret = sdap_access_rhost(test_ctx->user_no_rhost, pam_rhost_mock_empty);
+ assert_int_equal(EOK, ret); /* Expected access granted */
+
+ /* Test with user_no_rhost and rhost == "somehost" */
+ ret = sdap_access_rhost(test_ctx->user_no_rhost, pam_rhost_mock_somehost);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access denied */
+
+ /* Test with user_allow_somehost and rhost == "somehost" */
+ ret = sdap_access_rhost(test_ctx->user_allow_somehost,
+ pam_rhost_mock_somehost);
+ assert_int_equal(EOK, ret); /* Expected access allowed */
+
+ /* Test with user_deny_somehost and rhost == "somehost" */
+ ret = sdap_access_rhost(test_ctx->user_deny_somehost,
+ pam_rhost_mock_somehost);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access denied */
+
+ /* Test with user_allow_all and rhost == "somehost" */
+ ret = sdap_access_rhost(test_ctx->user_allow_all,
+ pam_rhost_mock_somehost);
+ assert_int_equal(EOK, ret); /* Expected access allowed */
+
+ /* Test with user_allow_all_deny_somehost and rhost == "somehost" */
+ ret = sdap_access_rhost(test_ctx->user_allow_all_deny_somehost,
+ pam_rhost_mock_somehost);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access denied */
+
+ /* Test with user_allow_all_allow_somehost_deny_somehost
+ * and rhost == "somehost" */
+ ret = sdap_access_rhost(
+ test_ctx->user_allow_all_allow_somehost_deny_somehost,
+ pam_rhost_mock_somehost);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access denied */
+
+ /* Test with user_no_rhost and rhost == "someotherhost" */
+ ret = sdap_access_rhost(test_ctx->user_no_rhost,
+ pam_rhost_mock_someotherhost);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access denied */
+
+ /* Test with user_allow_somehost and rhost == "someotherhost" */
+ ret = sdap_access_rhost(test_ctx->user_allow_somehost,
+ pam_rhost_mock_someotherhost);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access denied */
+
+ /* Test with user_deny_somehost and rhost == "someotherhost" */
+ ret = sdap_access_rhost(test_ctx->user_deny_somehost,
+ pam_rhost_mock_someotherhost);
+ assert_int_equal(ERR_ACCESS_DENIED, ret); /* Expected access denied */
+
+ /* Test with user_allow_all and rhost == "someotherhost" */
+ ret = sdap_access_rhost(test_ctx->user_allow_all,
+ pam_rhost_mock_someotherhost);
+ assert_int_equal(EOK, ret); /* Expected access allowed */
+
+ /* Test with user_allow_all_deny_somehost and rhost == "someotherhost" */
+ ret = sdap_access_rhost(test_ctx->user_allow_all_deny_somehost,
+ pam_rhost_mock_someotherhost);
+ assert_int_equal(EOK, ret); /* Expected access allowed */
+
+ /* Test with user_allow_all_allow_somehost_deny_somehost
+ * and rhost == "someotherhost" */
+ ret = sdap_access_rhost(
+ test_ctx->user_allow_all_allow_somehost_deny_somehost,
+ pam_rhost_mock_someotherhost);
+ assert_int_equal(EOK, ret); /* Expected access allowed */
+}
+
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(test_nds_check_expire,
expire_test_setup,
- expire_test_teardown)
+ expire_test_teardown),
+ cmocka_unit_test_setup_teardown(test_sdap_access_rhost,
+ test_sdap_access_rhost_setup,
+ test_sdap_access_rhost_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
diff --git a/src/tests/cmocka/test_sdap_access.h b/src/tests/cmocka/test_sdap_access.h
new file mode 100644
index 000000000..cc49a8261
--- /dev/null
+++ b/src/tests/cmocka/test_sdap_access.h
@@ -0,0 +1,36 @@
+/*
+ Authors:
+ Alexey Kamenskiy <aleksey.kamensky@gmail.com>
+
+ SSSD tests - sdap access tests
+
+ 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 TEST_SDAP_ACCESS_H
+#define TEST_SDAP_ACCESS_H
+
+struct test_sdap_access_rhost_ctx {
+ struct ldb_message *user_no_rhost;
+ struct ldb_message *user_allow_somehost;
+ struct ldb_message *user_deny_somehost;
+ struct ldb_message *user_allow_all;
+ struct ldb_message *user_allow_all_deny_somehost;
+ struct ldb_message *user_allow_all_allow_somehost_deny_somehost;
+};
+
+static int test_sdap_access_rhost_setup(void **state);
+static int test_sdap_access_rhost_teardown(void **state);
+
+#endif /* TEST_SDAP_ACCESS_H */