summaryrefslogtreecommitdiffstats
path: root/src/providers
diff options
context:
space:
mode:
authorPierre Ossman <pierre@ossman.eu>2010-12-22 22:29:03 +0100
committerStephen Gallagher <sgallagh@redhat.com>2011-03-24 14:13:43 -0400
commit3612c73e7957721bcbf31d0118e2ac210eb46b88 (patch)
treeacc174c39c5a854e89c7fafe7a4b513c3027ca6d /src/providers
parentff265d170e73d7347c718ee6cf690695bba8caeb (diff)
downloadsssd-3612c73e7957721bcbf31d0118e2ac210eb46b88.tar.gz
sssd-3612c73e7957721bcbf31d0118e2ac210eb46b88.tar.xz
sssd-3612c73e7957721bcbf31d0118e2ac210eb46b88.zip
Add host access control support
https://fedorahosted.org/sssd/ticket/746
Diffstat (limited to 'src/providers')
-rw-r--r--src/providers/ipa/ipa_common.c3
-rw-r--r--src/providers/ldap/ldap_common.c6
-rw-r--r--src/providers/ldap/ldap_init.c2
-rw-r--r--src/providers/ldap/sdap.h1
-rw-r--r--src/providers/ldap/sdap_access.c146
-rw-r--r--src/providers/ldap/sdap_access.h2
6 files changed, 157 insertions, 3 deletions
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 579b8b60e..067f2ee85 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -127,7 +127,8 @@ struct sdap_attr_map ipa_user_map[] = {
{ "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL },
{ "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL},
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
- { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}
+ { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
+ { "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }
};
struct sdap_attr_map ipa_group_map[] = {
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index ce6d41d58..9eb9cc379 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -131,7 +131,8 @@ struct sdap_attr_map rfc2307_user_map[] = {
{ "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL },
{ "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL},
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
- { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}
+ { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
+ { "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }
};
struct sdap_attr_map rfc2307_group_map[] = {
@@ -174,7 +175,8 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
{ "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL },
{ "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL},
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
- { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}
+ { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
+ { "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }
};
struct sdap_attr_map rfc2307bis_group_map[] = {
diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c
index 6b05690ed..62588b776 100644
--- a/src/providers/ldap/ldap_init.c
+++ b/src/providers/ldap/ldap_init.c
@@ -358,6 +358,8 @@ int sssm_ldap_access_init(struct be_ctx *bectx,
}
} else if (strcasecmp(order_list[c], LDAP_ACCESS_SERVICE_NAME) == 0) {
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 {
DEBUG(1, ("Unexpected access rule name [%s].\n", order_list[c]));
ret = EINVAL;
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 31e72cd5b..32dc34448 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -243,6 +243,7 @@ enum sdap_user_attrs {
SDAP_AT_AD_ACCOUNT_EXPIRES,
SDAP_AT_AD_USER_ACCOUNT_CONTROL,
SDAP_AT_NS_ACCOUNT_LOCK,
+ SDAP_AT_AUTHORIZED_HOST,
SDAP_OPTS_USER /* attrs counter */
};
diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c
index 5a6b4a5d3..9b598bc54 100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -85,6 +85,17 @@ static struct tevent_req *sdap_access_service_send(
static void sdap_account_expired_done(struct tevent_req *subreq);
+static errno_t sdap_access_host_recv(struct tevent_req *req,
+ int *pam_status);
+static void sdap_access_host_done(struct tevent_req *subreq);
+
+static struct tevent_req *sdap_access_host_send(
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_access_ctx *access_ctx,
+ struct pam_data *pd,
+ struct ldb_message *user_entry);
+
static void sdap_access_done(struct tevent_req *req);
void sdap_pam_access_handler(struct be_req *breq)
{
@@ -259,6 +270,18 @@ static errno_t select_next_rule(struct tevent_req *req)
tevent_req_set_callback(subreq, sdap_access_service_done, req);
return EOK;
+ case LDAP_ACCESS_HOST:
+ subreq = sdap_access_host_send(state, state->ev,
+ state->access_ctx,
+ state->pd,
+ state->user_entry);
+ if (subreq == NULL) {
+ DEBUG(1, ("sdap_access_host_send failed.\n"));
+ return ENOMEM;
+ }
+ tevent_req_set_callback(subreq, sdap_access_host_done, req);
+ return EOK;
+
default:
DEBUG(1, ("Unexpected access rule type. Access denied.\n"));
}
@@ -1057,6 +1080,129 @@ static void sdap_access_service_done(struct tevent_req *subreq)
return;
}
+struct sdap_access_host_ctx {
+ int pam_status;
+};
+
+static struct tevent_req *sdap_access_host_send(
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_access_ctx *access_ctx,
+ struct pam_data *pd,
+ struct ldb_message *user_entry)
+{
+ errno_t ret;
+ struct tevent_req *req;
+ struct sdap_access_host_ctx *state;
+ struct ldb_message_element *el;
+ unsigned int i;
+ char *host;
+ char hostname[HOST_NAME_MAX+1];
+
+ req = tevent_req_create(mem_ctx, &state, struct sdap_access_host_ctx);
+ if (!req) {
+ return NULL;
+ }
+
+ state->pam_status = PAM_PERM_DENIED;
+
+ el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_HOST);
+ if (!el || el->num_values == 0) {
+ DEBUG(1, ("Missing hosts. Access denied\n"));
+ ret = EOK;
+ goto done;
+ }
+
+ if (gethostname(hostname, sizeof(hostname)) == -1) {
+ DEBUG(1, ("Unable to get system hostname. Access denied\n"));
+ ret = EOK;
+ goto done;
+ }
+
+ /* FIXME: PADL's pam_ldap also calls gethostbyname() on the hostname
+ * in some attempt to get aliases and/or FQDN for the machine.
+ * Not sure this is a good idea, but we might want to add it in
+ * order to be compatible...
+ */
+
+ for (i = 0; i < el->num_values; i++) {
+ host = (char *)el->values[i].data;
+ if (host[0] == '!' &&
+ strcasecmp(hostname, host+1) == 0) {
+ /* This host is explicitly denied */
+ state->pam_status = PAM_PERM_DENIED;
+ DEBUG(4, ("Access denied by [%s]\n", host));
+ /* A denial trumps all. Break here */
+ break;
+
+ } else if (strcasecmp(hostname, host) == 0) {
+ /* This host is explicitly allowed */
+ state->pam_status = PAM_SUCCESS;
+ DEBUG(4, ("Access granted for [%s]\n", host));
+ /* We still need to loop through to make sure
+ * that it's not also explicitly denied
+ */
+ } else if (strcmp("*", host) == 0) {
+ /* This user has access to all hosts */
+ state->pam_status = PAM_SUCCESS;
+ DEBUG(4, ("Access granted to all hosts\n"));
+ /* We still need to loop through to make sure
+ * that it's not also explicitly denied
+ */
+ }
+ }
+
+ if (state->pam_status != PAM_SUCCESS) {
+ DEBUG(4, ("No matching host rule found\n"));
+ }
+
+ ret = EOK;
+
+done:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ tevent_req_post(req, ev);
+
+ return req;
+}
+
+static errno_t sdap_access_host_recv(struct tevent_req *req,
+ int *pam_status)
+{
+ struct sdap_access_host_ctx *state =
+ tevent_req_data(req, struct sdap_access_host_ctx);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *pam_status = state->pam_status;
+
+ return EOK;
+}
+
+static void sdap_access_host_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
+ struct sdap_access_req_ctx *state =
+ tevent_req_data(req, struct sdap_access_req_ctx);
+
+ ret = sdap_access_host_recv(subreq, &state->pam_status);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(1, ("Error retrieving access check result.\n"));
+ state->pam_status = PAM_SYSTEM_ERR;
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ next_access_rule(req);
+
+ return;
+}
+
static errno_t sdap_access_recv(struct tevent_req *req, int *pam_status)
{
struct sdap_access_req_ctx *state =
diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h
index 32c45b817..d78fdb1ed 100644
--- a/src/providers/ldap/sdap_access.h
+++ b/src/providers/ldap/sdap_access.h
@@ -32,6 +32,7 @@
#define LDAP_ACCESS_FILTER_NAME "filter"
#define LDAP_ACCESS_EXPIRE_NAME "expire"
#define LDAP_ACCESS_SERVICE_NAME "authorized_service"
+#define LDAP_ACCESS_HOST_NAME "host"
#define LDAP_ACCOUNT_EXPIRE_SHADOW "shadow"
#define LDAP_ACCOUNT_EXPIRE_AD "ad"
@@ -44,6 +45,7 @@ enum ldap_access_rule {
LDAP_ACCESS_FILTER = 0,
LDAP_ACCESS_EXPIRE,
LDAP_ACCESS_SERVICE,
+ LDAP_ACCESS_HOST,
LDAP_ACCESS_LAST
};