summaryrefslogtreecommitdiff
path: root/src/providers/ldap
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2010-12-20 16:05:14 -0500
committerStephen Gallagher <sgallagh@redhat.com>2010-12-21 17:05:51 -0500
commit2a2f642aae37e3f41cbbda162a74c2b946a4521f (patch)
tree146d6b2ec11a27fb0830a4c48f65cc36a07cef01 /src/providers/ldap
parent6ff6ccd3eec35217708870b0fe7a6362e97de95f (diff)
downloadsssd-2a2f642aae37e3f41cbbda162a74c2b946a4521f.tar.gz
sssd-2a2f642aae37e3f41cbbda162a74c2b946a4521f.tar.bz2
sssd-2a2f642aae37e3f41cbbda162a74c2b946a4521f.zip
Add authorizedService support
https://fedorahosted.org/sssd/ticket/670
Diffstat (limited to 'src/providers/ldap')
-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.c135
-rw-r--r--src/providers/ldap/sdap_access.h2
5 files changed, 144 insertions, 2 deletions
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index a38d5cc2..f0db53f2 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -118,7 +118,8 @@ struct sdap_attr_map rfc2307_user_map[] = {
{ "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL },
{ "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL },
{ "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL },
- { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }
+ { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL },
+ { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL }
};
struct sdap_attr_map rfc2307_group_map[] = {
@@ -157,7 +158,8 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
{ "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL },
{ "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL },
{ "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL },
- { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }
+ { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL },
+ { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, 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 a1d8f05d..d5dad360 100644
--- a/src/providers/ldap/ldap_init.c
+++ b/src/providers/ldap/ldap_init.c
@@ -352,6 +352,8 @@ int sssm_ldap_access_init(struct be_ctx *bectx,
goto done;
}
}
+ } else if (strcasecmp(order_list[c], LDAP_ACCESS_SERVICE_NAME) == 0) {
+ access_ctx->access_rule[c] = LDAP_ACCESS_SERVICE;
} 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 8c629a3b..57865fe0 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -229,6 +229,7 @@ enum sdap_user_attrs {
SDAP_AT_KP_LASTCHANGE,
SDAP_AT_KP_EXPIRATION,
SDAP_AT_PWD_ATTRIBUTE,
+ SDAP_AT_AUTH_SVC,
SDAP_OPTS_USER /* attrs counter */
};
diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c
index fa3f522a..4767812c 100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -72,6 +72,17 @@ static struct tevent_req *sdap_account_expired_send(TALLOC_CTX *mem_ctx,
struct sdap_access_ctx *access_ctx,
const char *username,
struct ldb_message *user_entry);
+static errno_t sdap_access_service_recv(struct tevent_req *req,
+ int *pam_status);
+static void sdap_access_service_done(struct tevent_req *subreq);
+
+static struct tevent_req *sdap_access_service_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_account_expired_done(struct tevent_req *subreq);
static void sdap_access_done(struct tevent_req *req);
@@ -235,6 +246,19 @@ static errno_t select_next_rule(struct tevent_req *req)
tevent_req_set_callback(subreq, sdap_account_expired_done, req);
return EOK;
+
+ case LDAP_ACCESS_SERVICE:
+ subreq = sdap_access_service_send(state, state->ev,
+ state->access_ctx,
+ state->pd,
+ state->user_entry);
+ if (subreq == NULL) {
+ DEBUG(1, ("sdap_access_service_send failed.\n"));
+ return ENOMEM;
+ }
+ tevent_req_set_callback(subreq, sdap_access_service_done, req);
+ return EOK;
+
default:
DEBUG(1, ("Unexpected access rule type. Access denied.\n"));
}
@@ -759,6 +783,117 @@ static void sdap_access_filter_done(struct tevent_req *subreq)
return;
}
+
+struct sdap_access_service_ctx {
+ int pam_status;
+};
+
+static struct tevent_req *sdap_access_service_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_service_ctx *state;
+ struct ldb_message_element *el;
+ unsigned int i;
+ char *service;
+
+ req = tevent_req_create(mem_ctx, &state, struct sdap_access_service_ctx);
+ if (!req) {
+ return NULL;
+ }
+
+ state->pam_status = PAM_PERM_DENIED;
+
+ el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_SERVICE);
+ if (!el || el->num_values == 0) {
+ DEBUG(1, ("Missing authorized services. Access denied\n"));
+ ret = EOK;
+ goto done;
+ }
+
+ for (i = 0; i < el->num_values; i++) {
+ service = (char *)el->values[i].data;
+ if (service[0] == '!' &&
+ strcasecmp(pd->service, service+1) == 0) {
+ /* This service is explicitly denied */
+ state->pam_status = PAM_PERM_DENIED;
+ DEBUG(4, ("Access denied by [%s]\n", service));
+ /* A denial trumps all. Break here */
+ break;
+
+ } else if (strcasecmp(pd->service, service) == 0) {
+ /* This service is explicitly allowed */
+ state->pam_status = PAM_SUCCESS;
+ DEBUG(4, ("Access granted for [%s]\n", service));
+ /* We still need to loop through to make sure
+ * that it's not also explicitly denied
+ */
+ } else if (strcmp("*", service) == 0) {
+ /* This user has access to all services */
+ state->pam_status = PAM_SUCCESS;
+ DEBUG(4, ("Access granted to all services\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 service 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_service_recv(struct tevent_req *req,
+ int *pam_status)
+{
+ struct sdap_access_service_ctx *state =
+ tevent_req_data(req, struct sdap_access_service_ctx);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *pam_status = state->pam_status;
+
+ return EOK;
+}
+
+static void sdap_access_service_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_service_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 9b8e45bd..66193a6d 100644
--- a/src/providers/ldap/sdap_access.h
+++ b/src/providers/ldap/sdap_access.h
@@ -31,6 +31,7 @@
#define LDAP_ACCESS_FILTER_NAME "filter"
#define LDAP_ACCESS_EXPIRE_NAME "expire"
+#define LDAP_ACCESS_SERVICE_NAME "authorized_service"
#define LDAP_ACCOUNT_EXPIRE_SHADOW "shadow"
@@ -38,6 +39,7 @@ enum ldap_access_rule {
LDAP_ACCESS_EMPTY = -1,
LDAP_ACCESS_FILTER = 0,
LDAP_ACCESS_EXPIRE,
+ LDAP_ACCESS_SERVICE,
LDAP_ACCESS_LAST
};