summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2015-05-27 18:23:49 +0200
committerJakub Hrozek <jhrozek@redhat.com>2015-06-19 18:48:13 +0200
commitcaacea0dbfdc92613ae992681053b1d2665b80ca (patch)
treed4d68bac948aa1cd23b5ebdf0ee91def503856be
parent7d8b7d82f0a91ed656320577fc781f24a66db9f8 (diff)
downloadsssd-caacea0dbfdc92613ae992681053b1d2665b80ca.tar.gz
sssd-caacea0dbfdc92613ae992681053b1d2665b80ca.tar.xz
sssd-caacea0dbfdc92613ae992681053b1d2665b80ca.zip
LDAP/IPA: add user lookup by certificate
Related to https://fedorahosted.org/sssd/ticket/2596 Reviewed-by: Pavel Březina <pbrezina@redhat.com>
-rw-r--r--src/providers/data_provider.h6
-rw-r--r--src/providers/data_provider_be.c5
-rw-r--r--src/providers/ipa/ipa_subdomains_id.c14
-rw-r--r--src/providers/ldap/ldap_id.c55
4 files changed, 73 insertions, 7 deletions
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 657d2b798..13a700308 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -128,6 +128,7 @@
#define BE_FILTER_ENUM 3
#define BE_FILTER_SECID 4
#define BE_FILTER_UUID 5
+#define BE_FILTER_CERT 6
#define BE_REQ_USER 0x0001
#define BE_REQ_GROUP 0x0002
@@ -140,14 +141,17 @@
#define BE_REQ_HOST 0x0010
#define BE_REQ_BY_SECID 0x0011
#define BE_REQ_USER_AND_GROUP 0x0012
-#define BE_REQ_BY_UUID 0x0013
+#define BE_REQ_BY_UUID 0x0013
+#define BE_REQ_BY_CERT 0x0014
#define BE_REQ_TYPE_MASK 0x00FF
#define BE_REQ_FAST 0x1000
#define DP_SEC_ID "secid"
+#define DP_CERT "cert"
/* sizeof() counts the trailing \0 so we must substract 1 for the string
* length */
#define DP_SEC_ID_LEN (sizeof(DP_SEC_ID) - 1)
+#define DP_CERT_LEN (sizeof(DP_CERT) - 1)
#define EXTRA_NAME_IS_UPN "U"
#define EXTRA_INPUT_MAYBE_WITH_VIEW "V"
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 34c7b2c76..f5bdfb676 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -1199,6 +1199,11 @@ static int be_get_account_info(struct sbus_request *dbus_req, void *user_data)
ret = split_name_extended(req, &filter[DP_SEC_ID_LEN + 1],
&req->filter_value,
&req->extra_value);
+ } else if (strncmp(filter, DP_CERT"=", DP_CERT_LEN + 1) == 0) {
+ req->filter_type = BE_FILTER_CERT;
+ ret = split_name_extended(req, &filter[DP_CERT_LEN + 1],
+ &req->filter_value,
+ &req->extra_value);
} else if (strcmp(filter, ENUM_INDICATOR) == 0) {
req->filter_type = BE_FILTER_ENUM;
req->filter_value = NULL;
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index b5c0aa0b5..610b1c58b 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -934,6 +934,20 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx,
ret = EOK;
goto done;
+ } else if (ar->filter_type == BE_FILTER_CERT) {
+ ret = sysdb_search_object_by_cert(mem_ctx, dom, ar->filter_value, attrs,
+ &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to make request to our cache: [%d]: [%s]\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ *_msg = res->msgs[0];
+
+ ret = EOK;
+ goto done;
} else if (ar->filter_type == BE_FILTER_IDNUM) {
errno = 0;
id = strtouint32(ar->filter_value, NULL, 10);
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index d4f46f1dc..ff117d829 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -28,6 +28,7 @@
#include "util/util.h"
#include "util/strtonum.h"
+#include "util/cert.h"
#include "db/sysdb.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async.h"
@@ -78,12 +79,13 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
struct tevent_req *req;
struct users_get_state *state;
const char *attr_name = NULL;
- char *clean_name;
+ char *clean_name = NULL;
char *endptr;
int ret;
uid_t uid;
enum idmap_error_code err;
char *sid;
+ char *user_filter = NULL;
req = tevent_req_create(memctx, &state, struct users_get_state);
if (!req) return NULL;
@@ -194,6 +196,23 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
goto done;
}
break;
+ case BE_FILTER_CERT:
+ attr_name = ctx->opts->user_map[SDAP_AT_USER_CERT].name;
+ if (attr_name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Certificate search not configured for this backend.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = sss_cert_derb64_to_ldap_filter(state, name, attr_name,
+ &user_filter);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sss_cert_derb64_to_ldap_filter failed.\n");
+ goto done;
+ }
+ break;
default:
ret = EINVAL;
goto done;
@@ -205,29 +224,39 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
goto done;
}
+ if (user_filter == NULL) {
+ user_filter = talloc_asprintf(state, "(%s=%s)", attr_name, clean_name);
+ talloc_free(clean_name);
+ if (user_filter == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
if (state->use_id_mapping || filter_type == BE_FILTER_SECID) {
/* When mapping IDs or looking for SIDs, we don't want to limit
* ourselves to users with a UID value. But there must be a SID to map
* from.
*/
state->filter = talloc_asprintf(state,
- "(&(%s=%s)(objectclass=%s)(%s=*)(%s=*))",
- attr_name, clean_name,
+ "(&%s(objectclass=%s)(%s=*)(%s=*))",
+ user_filter,
ctx->opts->user_map[SDAP_OC_USER].name,
ctx->opts->user_map[SDAP_AT_USER_NAME].name,
ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name);
} else {
/* When not ID-mapping, make sure there is a non-NULL UID */
state->filter = talloc_asprintf(state,
- "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
- attr_name, clean_name,
+ "(&%s(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
+ user_filter,
ctx->opts->user_map[SDAP_OC_USER].name,
ctx->opts->user_map[SDAP_AT_USER_NAME].name,
ctx->opts->user_map[SDAP_AT_USER_UID].name,
ctx->opts->user_map[SDAP_AT_USER_UID].name);
}
- talloc_zfree(clean_name);
+ talloc_zfree(user_filter);
if (!state->filter) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to build the base filter\n");
ret = ENOMEM;
@@ -1537,6 +1566,16 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
noexist_delete);
break;
+ case BE_REQ_BY_CERT:
+ subreq = users_get_send(state, be_ctx->ev, id_ctx,
+ sdom, conn,
+ ar->filter_value,
+ ar->filter_type,
+ ar->extra_value,
+ ar->attr_type,
+ noexist_delete);
+ break;
+
default: /*fail*/
ret = EINVAL;
state->err = "Invalid request type";
@@ -1602,6 +1641,10 @@ sdap_handle_acct_req_done(struct tevent_req *subreq)
ret = sdap_get_user_and_group_recv(subreq, &state->dp_error,
&state->sdap_ret);
break;
+ case BE_REQ_BY_CERT:
+ err = "User lookup by certificate failed";
+ ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret);
+ break;
default: /*fail*/
ret = EINVAL;
break;