URL: https://github.com/freeipa/freeipa/pull/3655 Author: abbra Title: #3655: [Backport][ipa-4-6] extdom: plugin doesn't allow @ in group name Action: opened
PR body: """ This PR was opened automatically because PR #3616 was pushed to master and backport to ipa-4-6 is required. """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/3655/head:pr3655 git checkout pr3655
From 3a6ad7202c5d7da81652b37a06deb36f3971bba4 Mon Sep 17 00:00:00 2001 From: Tomas Halman <[email protected]> Date: Tue, 3 Sep 2019 16:33:54 +0200 Subject: [PATCH 1/4] extdom: plugin doesn't allow @ in group name Old implementation handles username and group names with one common call. Character @ is used in the call to detect UPN. Group name can legaly contain this character and therefore the common approach doesn't work in such case. Also the original call is less efficient because it tries to resolv username allways then it fallback to group resolution. Here we implement two new separate calls for resolving users and groups. Fixes: https://bugzilla.redhat.com/1746951 Reviewed-By: Alexander Bokovoy <[email protected]> --- .../ipa-extdom-extop/ipa_extdom.h | 8 +- .../ipa-extdom-extop/ipa_extdom_common.c | 271 ++++++++++++------ .../ipa-extdom-extop/ipa_extdom_extop.c | 3 + 3 files changed, 197 insertions(+), 85 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h index e01e74ca59..81691ca1b3 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h @@ -63,6 +63,7 @@ #define EXOP_EXTDOM_OID "2.16.840.1.113730.3.8.10.4" #define EXOP_EXTDOM_V1_OID "2.16.840.1.113730.3.8.10.4.1" +#define EXOP_EXTDOM_V2_OID "2.16.840.1.113730.3.8.10.4.2" #define IPA_EXTDOM_PLUGIN_NAME "ipa-extdom-extop" #define IPA_EXTDOM_FEATURE_DESC "IPA trusted domain ID mapper" @@ -72,7 +73,8 @@ enum extdom_version { EXTDOM_V0 = 0, - EXTDOM_V1 + EXTDOM_V1, + EXTDOM_V2 }; enum input_types { @@ -80,7 +82,9 @@ enum input_types { INP_NAME, INP_POSIX_UID, INP_POSIX_GID, - INP_CERT + INP_CERT, + INP_USERNAME, + INP_GROUPNAME }; enum request_types { diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c index 134b623773..fef794183a 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c @@ -271,7 +271,9 @@ int parse_request_data(struct berval *req_val, struct extdom_req **_req) * sid (1), * name (2), * posix uid (3), - * posix gid (3) + * posix gid (4), + * username (5), + * groupname (6) * }, * requestType ENUMERATED { * simple (1), @@ -337,6 +339,8 @@ int parse_request_data(struct berval *req_val, struct extdom_req **_req) switch (req->input_type) { case INP_NAME: + case INP_USERNAME: + case INP_GROUPNAME: tag = ber_scanf(ber, "{aa}}", &req->data.name.domain_name, &req->data.name.object_name); break; @@ -378,6 +382,8 @@ void free_req_data(struct extdom_req *req) switch (req->input_type) { case INP_NAME: + case INP_USERNAME: + case INP_GROUPNAME: ber_memfree(req->data.name.domain_name); ber_memfree(req->data.name.object_name); break; @@ -407,6 +413,12 @@ int check_request(struct extdom_req *req, enum extdom_version version) } } + if (version == EXTDOM_V0 || version == EXTDOM_V1) { + if (req->input_type == INP_USERNAME || req->input_type == INP_GROUPNAME) { + return LDAP_PROTOCOL_ERROR; + } + } + return LDAP_SUCCESS; } @@ -1157,17 +1169,46 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx, return ret; } -static int handle_name_request(struct ipa_extdom_ctx *ctx, - struct extdom_req *req, - enum request_types request_type, - const char *name, const char *domain_name, - struct berval **berval) + +static int handle_simple_request(struct extdom_req *req, + const char *fq_name, + struct berval **berval) +{ + int ret; + char *sid_str = NULL; + enum sss_id_type id_type; + + ret = sss_nss_getsidbyname(fq_name, &sid_str, &id_type); + switch(ret) { + case 0: + ret = pack_ber_sid(sid_str, berval); + break; + case ENOENT: + ret = LDAP_NO_SUCH_OBJECT; + break; + case ETIMEDOUT: + case ETIME: + ret = LDAP_TIMELIMIT_EXCEEDED; + break; + default: + set_err_msg(req, "Failed to lookup SID by name"); + ret = LDAP_OPERATIONS_ERROR; + break; + } + + free(sid_str); + return ret; +} + +static int handle_username_request(struct ipa_extdom_ctx *ctx, + struct extdom_req *req, + enum request_types request_type, + const char *name, const char *domain_name, + struct berval **berval) { int ret; char *fq_name = NULL; struct passwd pwd; - struct group grp; - char *sid_str = NULL; enum sss_id_type id_type; size_t buf_len; char *buf = NULL; @@ -1189,104 +1230,156 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_SIMPLE) { - ret = sss_nss_getsidbyname(fq_name, &sid_str, &id_type); - if (ret != 0) { - if (ret == ENOENT) { - ret = LDAP_NO_SUCH_OBJECT; - } else if (ret == ETIMEDOUT || ret == ETIME) { - ret = LDAP_TIMELIMIT_EXCEEDED; - } else { - set_err_msg(req, "Failed to lookup SID by name"); - ret = LDAP_OPERATIONS_ERROR; - } - goto done; - } + /* REQ_SIMPLE */ + ret = handle_simple_request(req, fq_name, berval); + goto done; + } - ret = pack_ber_sid(sid_str, berval); - } else { - ret = get_buffer(&buf_len, &buf); - if (ret != LDAP_SUCCESS) { - goto done; - } + /* REQ_FULL || REQ_FULL_WITH_GROUPS */ + ret = get_buffer(&buf_len, &buf); + if (ret != LDAP_SUCCESS) { + goto done; + } - ret = getpwnam_r_wrapper(ctx, fq_name, &pwd, &buf, &buf_len); - if (ret == 0) { - if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type); - if (ret != 0 || !(id_type == SSS_ID_TYPE_UID - || id_type == SSS_ID_TYPE_BOTH)) { - set_err_msg(req, "Failed to read original data"); - if (ret == ENOENT) { - ret = LDAP_NO_SUCH_OBJECT; - } else if (ret == ETIMEDOUT || ret == ETIME) { - ret = LDAP_TIMELIMIT_EXCEEDED; - } else { - ret = LDAP_OPERATIONS_ERROR; - } - goto done; - } - } - ret = pack_ber_user(ctx, - (request_type == REQ_FULL ? RESP_USER - : RESP_USER_GROUPLIST), - domain_name, pwd.pw_name, pwd.pw_uid, - pwd.pw_gid, pwd.pw_gecos, pwd.pw_dir, - pwd.pw_shell, kv_list, berval); - } else if (ret == ENOMEM || ret == ERANGE) { - ret = LDAP_OPERATIONS_ERROR; - goto done; - } else if (ret == ETIMEDOUT) { - ret = LDAP_TIMELIMIT_EXCEEDED; - goto done; - } else { /* no user entry found */ - /* according to the getpwnam() man page there are a couple of - * error codes which can indicate that the user was not found. To - * be on the safe side we fail back to the group lookup on all - * errors. */ - ret = getgrnam_r_wrapper(ctx, fq_name, &grp, &buf, &buf_len); - if (ret != 0) { + ret = getpwnam_r_wrapper(ctx, fq_name, &pwd, &buf, &buf_len); + switch(ret) { + case 0: + if (request_type == REQ_FULL_WITH_GROUPS) { + ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type); + if (ret != 0 || !(id_type == SSS_ID_TYPE_UID + || id_type == SSS_ID_TYPE_BOTH)) { + set_err_msg(req, "Failed to read original data"); if (ret == ENOENT) { ret = LDAP_NO_SUCH_OBJECT; - } else if (ret == ETIMEDOUT) { + } else if (ret == ETIMEDOUT || ret == ETIME) { ret = LDAP_TIMELIMIT_EXCEEDED; } else { ret = LDAP_OPERATIONS_ERROR; } goto done; } + } + ret = pack_ber_user(ctx, + (request_type == REQ_FULL ? RESP_USER + : RESP_USER_GROUPLIST), + domain_name, pwd.pw_name, pwd.pw_uid, + pwd.pw_gid, pwd.pw_gecos, pwd.pw_dir, + pwd.pw_shell, kv_list, berval); + break; + case ENOMEM: + case ERANGE: + ret = LDAP_OPERATIONS_ERROR; + break; + case ETIMEDOUT: + ret = LDAP_TIMELIMIT_EXCEEDED; + break; + default: + ret = LDAP_NO_SUCH_OBJECT; + break; + } - if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname(grp.gr_name, &kv_list, &id_type); - if (ret != 0 || !(id_type == SSS_ID_TYPE_GID - || id_type == SSS_ID_TYPE_BOTH)) { - if (ret == ENOENT) { - ret = LDAP_NO_SUCH_OBJECT; - } else if (ret == ETIMEDOUT || ret == ETIME) { - ret = LDAP_TIMELIMIT_EXCEEDED; - } else { - set_err_msg(req, "Failed to read original data"); - ret = LDAP_OPERATIONS_ERROR; - } - goto done; - } - } +done: + sss_nss_free_kv(kv_list); + free(fq_name); + free(buf); + + return ret; +} - ret = pack_ber_group((request_type == REQ_FULL ? RESP_GROUP - : RESP_GROUP_MEMBERS), - domain_name, grp.gr_name, grp.gr_gid, - grp.gr_mem, kv_list, berval); +static int handle_groupname_request(struct ipa_extdom_ctx *ctx, + struct extdom_req *req, + enum request_types request_type, + const char *name, const char *domain_name, + struct berval **berval) +{ + int ret; + char *fq_name = NULL; + struct group grp; + enum sss_id_type id_type; + size_t buf_len; + char *buf = NULL; + struct sss_nss_kv *kv_list = NULL; + + /* with groups we can be sure that name doesn't contain the domain_name */ + ret = asprintf(&fq_name, "%s%c%s", name, SSSD_DOMAIN_SEPARATOR, + domain_name); + if (ret == -1) { + ret = LDAP_OPERATIONS_ERROR; + set_err_msg(req, "Failed to create fully qualified name"); + fq_name = NULL; /* content is undefined according to + asprintf(3) */ + goto done; + } + + if (request_type == REQ_SIMPLE) { + /* REQ_SIMPLE */ + ret = handle_simple_request(req, fq_name, berval); + goto done; + } + + /* REQ_FULL || REQ_FULL_WITH_GROUPS */ + ret = get_buffer(&buf_len, &buf); + if (ret != LDAP_SUCCESS) { + goto done; + } + + ret = getgrnam_r_wrapper(ctx, fq_name, &grp, &buf, &buf_len); + if (ret != 0) { + if (ret == ENOMEM || ret == ERANGE) { + ret = LDAP_OPERATIONS_ERROR; + } else { + ret = LDAP_NO_SUCH_OBJECT; } + goto done; } + if (request_type == REQ_FULL_WITH_GROUPS) { + ret = sss_nss_getorigbyname(grp.gr_name, &kv_list, &id_type); + if (ret != 0 || !(id_type == SSS_ID_TYPE_GID + || id_type == SSS_ID_TYPE_BOTH)) { + if (ret == ENOENT) { + ret = LDAP_NO_SUCH_OBJECT; + } else { + set_err_msg(req, "Failed to read original data"); + ret = LDAP_OPERATIONS_ERROR; + } + goto done; + } + } + + ret = pack_ber_group((request_type == REQ_FULL ? RESP_GROUP + : RESP_GROUP_MEMBERS), + domain_name, grp.gr_name, grp.gr_gid, + grp.gr_mem, kv_list, berval); + done: sss_nss_free_kv(kv_list); free(fq_name); - free(sid_str); free(buf); return ret; } +static int handle_name_request(struct ipa_extdom_ctx *ctx, + struct extdom_req *req, + enum request_types request_type, + const char *name, const char *domain_name, + struct berval **berval) +{ + int ret; + + + ret = handle_username_request(ctx, req, request_type, + name, domain_name, berval); + if (ret == LDAP_NO_SUCH_OBJECT) { + ret = handle_groupname_request(ctx, req, request_type, + name, domain_name, berval); + } + + return ret; +} + + int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req, struct berval **berval) { @@ -1318,6 +1411,18 @@ int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req, req->data.name.object_name, req->data.name.domain_name, berval); + break; + case INP_GROUPNAME: + ret = handle_groupname_request(ctx, req, req->request_type, + req->data.name.object_name, + req->data.name.domain_name, berval); + + break; + case INP_USERNAME: + ret = handle_username_request(ctx, req, req->request_type, + req->data.name.object_name, + req->data.name.domain_name, berval); + break; default: set_err_msg(req, "Unknown input type"); diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c index 48fcecc1ee..5f9714f982 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c @@ -54,6 +54,7 @@ Slapi_PluginDesc ipa_extdom_plugin_desc = { static char *ipa_extdom_oid_list[] = { EXOP_EXTDOM_OID, EXOP_EXTDOM_V1_OID, + EXOP_EXTDOM_V2_OID, NULL }; @@ -196,6 +197,8 @@ static int ipa_extdom_extop(Slapi_PBlock *pb) version = EXTDOM_V0; } else if (strcasecmp(oid, EXOP_EXTDOM_V1_OID) == 0) { version = EXTDOM_V1; + } else if (strcasecmp(oid, EXOP_EXTDOM_V2_OID) == 0) { + version = EXTDOM_V2; } else { return SLAPI_PLUGIN_EXTENDED_NOT_HANDLED; } From 5f03b83543fe413a7625a41514ade996ee02ccd5 Mon Sep 17 00:00:00 2001 From: Tomas Halman <[email protected]> Date: Tue, 10 Sep 2019 13:32:45 +0200 Subject: [PATCH 2/4] extdom: plugin doesn't use timeout in blocking call Expose nss timeout parameter. Use sss_nss_getorigbyname_timeout instead of sss_nss_getorigbyname Reviewed-By: Alexander Bokovoy <[email protected]> --- .../ipa-extdom-extop/back_extdom.h | 4 ++++ .../ipa-extdom-extop/back_extdom_nss_sss.c | 7 +++++-- .../ipa-extdom-extop/back_extdom_sss_idmap.c | 9 ++++++++- .../ipa-extdom-extop/ipa_extdom.h | 1 + .../ipa-extdom-extop/ipa_extdom_common.c | 16 ++++++++++++++-- .../ipa-extdom-extop/ipa_extdom_extop.c | 1 - 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h index d2937c8c8e..05292cf93a 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h @@ -35,6 +35,9 @@ enum nss_status { NSS_STATUS_RETURN }; +/* default NSS operation timeout 10s (ipaExtdomMaxNssTimeout) */ +#define DEFAULT_MAX_NSS_TIMEOUT (10*1000) + /* NSS backend operations implemented using either nss_sss.so.2 or libsss_nss_idmap API */ struct nss_ops_ctx; @@ -42,6 +45,7 @@ int back_extdom_init_context(struct nss_ops_ctx **nss_context); void back_extdom_free_context(struct nss_ops_ctx **nss_context); void back_extdom_set_timeout(struct nss_ops_ctx *nss_context, unsigned int timeout); +unsigned int back_extdom_get_timeout(struct nss_ops_ctx *nss_context); void back_extdom_evict_user(struct nss_ops_ctx *nss_context, const char *name); void back_extdom_evict_group(struct nss_ops_ctx *nss_context, diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c index 346c7d4301..a61f660702 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c @@ -120,7 +120,7 @@ int back_extdom_init_context(struct nss_ops_ctx **nss_context) } -/* Following three functions cannot be implemented with nss_sss.so.2 +/* Following four functions cannot be implemented with nss_sss.so.2 * As result, we simply do nothing here */ void back_extdom_set_timeout(struct nss_ops_ctx *nss_context, @@ -128,6 +128,10 @@ void back_extdom_set_timeout(struct nss_ops_ctx *nss_context, /* no operation */ } +unsigned int back_extdom_get_timeout(struct nss_ops_ctx *nss_context) { + return DEFAULT_MAX_NSS_TIMEOUT; +} + void back_extdom_evict_user(struct nss_ops_ctx *nss_context, const char *name) { /* no operation */ @@ -273,4 +277,3 @@ enum nss_status back_extdom_getgrouplist(struct nss_ops_ctx *nss_context, return ret; } - diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c index 64b90e3ae8..44d82069d4 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c @@ -96,6 +96,14 @@ void back_extdom_set_timeout(struct nss_ops_ctx *nss_context, nss_context->timeout = timeout; } +unsigned int back_extdom_get_timeout(struct nss_ops_ctx *nss_context) { + if (nss_context == NULL) { + return DEFAULT_MAX_NSS_TIMEOUT; + } + + return nss_context->timeout; +} + void back_extdom_evict_user(struct nss_ops_ctx *nss_context, const char *name) { if (nss_context == NULL) { @@ -257,4 +265,3 @@ enum nss_status back_extdom_getgrouplist(struct nss_ops_ctx *nss_context, } return __convert_sss_nss2nss_status(ret); } - diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h index 81691ca1b3..beb4eedd5a 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h @@ -59,6 +59,7 @@ #include <lber.h> #include <time.h> +#define IPA_389DS_PLUGIN_HELPER_CALLS #include <sss_nss_idmap.h> #define EXOP_EXTDOM_OID "2.16.840.1.113730.3.8.10.4" diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c index fef794183a..2171f3908e 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c @@ -114,6 +114,13 @@ int __nss_to_err(enum nss_status errcode) return -1; } +static int get_timeout(struct ipa_extdom_ctx *ctx) { + if (ctx == NULL || ctx->nss_ctx == NULL) { + return DEFAULT_MAX_NSS_TIMEOUT; + } + return back_extdom_get_timeout(ctx->nss_ctx); +} + int getpwnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name, struct passwd *pwd, char **buf, size_t *buf_len) { @@ -1245,7 +1252,9 @@ static int handle_username_request(struct ipa_extdom_ctx *ctx, switch(ret) { case 0: if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type); + ret = sss_nss_getorigbyname_timeout(pwd.pw_name, + get_timeout(ctx), + &kv_list, &id_type); if (ret != 0 || !(id_type == SSS_ID_TYPE_UID || id_type == SSS_ID_TYPE_BOTH)) { set_err_msg(req, "Failed to read original data"); @@ -1334,7 +1343,10 @@ static int handle_groupname_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname(grp.gr_name, &kv_list, &id_type); + ret = sss_nss_getorigbyname_timeout(grp.gr_name, + get_timeout(ctx), + &kv_list, + &id_type); if (ret != 0 || !(id_type == SSS_ID_TYPE_GID || id_type == SSS_ID_TYPE_BOTH)) { if (ret == ENOENT) { diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c index 5f9714f982..5d22f9f2d5 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c @@ -42,7 +42,6 @@ #include "util.h" #define DEFAULT_MAX_NSS_BUFFER (128*1024*1024) -#define DEFAULT_MAX_NSS_TIMEOUT (10*1000) Slapi_PluginDesc ipa_extdom_plugin_desc = { IPA_EXTDOM_FEATURE_DESC, From de8e65156d01a32c59c2412a9e37c983794c73af Mon Sep 17 00:00:00 2001 From: Tomas Halman <[email protected]> Date: Tue, 10 Sep 2019 13:46:08 +0200 Subject: [PATCH 3/4] extdom: use sss_nss_*_timeout calls Use nss calls with timeout in extdom plugin Reviewed-By: Alexander Bokovoy <[email protected]> --- .../ipa-extdom-extop/ipa_extdom_common.c | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c index 2171f3908e..1e96c495ab 100644 --- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c +++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c @@ -852,7 +852,8 @@ static int handle_uid_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_SIMPLE) { - ret = sss_nss_getsidbyid(uid, &sid_str, &id_type); + ret = sss_nss_getsidbyid_timeout(uid, get_timeout(ctx), + &sid_str, &id_type); if (ret != 0 || !(id_type == SSS_ID_TYPE_UID || id_type == SSS_ID_TYPE_BOTH)) { if (ret == ENOENT) { @@ -881,7 +882,8 @@ static int handle_uid_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type); + ret = sss_nss_getorigbyname_timeout(pwd.pw_name, get_timeout(ctx), + &kv_list, &id_type); if (ret != 0 || !(id_type == SSS_ID_TYPE_UID || id_type == SSS_ID_TYPE_BOTH)) { set_err_msg(req, "Failed to read original data"); @@ -930,7 +932,8 @@ static int handle_gid_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_SIMPLE) { - ret = sss_nss_getsidbyid(gid, &sid_str, &id_type); + ret = sss_nss_getsidbyid_timeout(gid, get_timeout(ctx), + &sid_str, &id_type); if (ret != 0 || id_type != SSS_ID_TYPE_GID) { if (ret == ENOENT) { ret = LDAP_NO_SUCH_OBJECT; @@ -958,7 +961,8 @@ static int handle_gid_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname(grp.gr_name, &kv_list, &id_type); + ret = sss_nss_getorigbyname_timeout(grp.gr_name, get_timeout(ctx), + &kv_list, &id_type); if (ret != 0 || !(id_type == SSS_ID_TYPE_GID || id_type == SSS_ID_TYPE_BOTH)) { set_err_msg(req, "Failed to read original data"); @@ -1005,7 +1009,8 @@ static int handle_cert_request(struct ipa_extdom_ctx *ctx, goto done; } - ret = sss_nss_getlistbycert(input, &fq_names, &id_types); + ret = sss_nss_getlistbycert_timeout(input, get_timeout(ctx), + &fq_names, &id_types); if (ret != 0) { if (ret == ENOENT) { ret = LDAP_NO_SUCH_OBJECT; @@ -1051,7 +1056,8 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx, enum sss_id_type id_type; struct sss_nss_kv *kv_list = NULL; - ret = sss_nss_getnamebysid(input, &fq_name, &id_type); + ret = sss_nss_getnamebysid_timeout(input, get_timeout(ctx), + &fq_name, &id_type); if (ret != 0) { if (ret == ENOENT) { ret = LDAP_NO_SUCH_OBJECT; @@ -1105,7 +1111,8 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type); + ret = sss_nss_getorigbyname_timeout(pwd.pw_name, get_timeout(ctx), + &kv_list, &id_type); if (ret != 0 || !(id_type == SSS_ID_TYPE_UID || id_type == SSS_ID_TYPE_BOTH)) { set_err_msg(req, "Failed to read original data"); @@ -1141,7 +1148,8 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname(grp.gr_name, &kv_list, &id_type); + ret = sss_nss_getorigbyname_timeout(grp.gr_name, get_timeout(ctx), + &kv_list, &id_type); if (ret != 0 || !(id_type == SSS_ID_TYPE_GID || id_type == SSS_ID_TYPE_BOTH)) { set_err_msg(req, "Failed to read original data"); @@ -1177,7 +1185,8 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx, } -static int handle_simple_request(struct extdom_req *req, +static int handle_simple_request(struct ipa_extdom_ctx *ctx, + struct extdom_req *req, const char *fq_name, struct berval **berval) { @@ -1185,7 +1194,8 @@ static int handle_simple_request(struct extdom_req *req, char *sid_str = NULL; enum sss_id_type id_type; - ret = sss_nss_getsidbyname(fq_name, &sid_str, &id_type); + ret = sss_nss_getsidbyname_timeout(fq_name, get_timeout(ctx), + &sid_str, &id_type); switch(ret) { case 0: ret = pack_ber_sid(sid_str, berval); @@ -1238,7 +1248,7 @@ static int handle_username_request(struct ipa_extdom_ctx *ctx, if (request_type == REQ_SIMPLE) { /* REQ_SIMPLE */ - ret = handle_simple_request(req, fq_name, berval); + ret = handle_simple_request(ctx, req, fq_name, berval); goto done; } @@ -1322,7 +1332,7 @@ static int handle_groupname_request(struct ipa_extdom_ctx *ctx, if (request_type == REQ_SIMPLE) { /* REQ_SIMPLE */ - ret = handle_simple_request(req, fq_name, berval); + ret = handle_simple_request(ctx, req, fq_name, berval); goto done; } @@ -1343,10 +1353,8 @@ static int handle_groupname_request(struct ipa_extdom_ctx *ctx, } if (request_type == REQ_FULL_WITH_GROUPS) { - ret = sss_nss_getorigbyname_timeout(grp.gr_name, - get_timeout(ctx), - &kv_list, - &id_type); + ret = sss_nss_getorigbyname_timeout(grp.gr_name, get_timeout(ctx), + &kv_list, &id_type); if (ret != 0 || !(id_type == SSS_ID_TYPE_GID || id_type == SSS_ID_TYPE_BOTH)) { if (ret == ENOENT) { From 4723a7ebc057cb87f5d72efe6976f69f122c112e Mon Sep 17 00:00:00 2001 From: Tomas Halman <[email protected]> Date: Wed, 11 Sep 2019 10:15:48 +0200 Subject: [PATCH 4/4] extdom: add extdom protocol documentation Add the description of extdom protocol and its versions Reviewed-By: Alexander Bokovoy <[email protected]> --- doc/designs/extdom-plugin-protocol.md | 242 ++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 doc/designs/extdom-plugin-protocol.md diff --git a/doc/designs/extdom-plugin-protocol.md b/doc/designs/extdom-plugin-protocol.md new file mode 100644 index 0000000000..cd2e9e2ffd --- /dev/null +++ b/doc/designs/extdom-plugin-protocol.md @@ -0,0 +1,242 @@ +# Extdom plugin protocol + +SSSD on ipa client uses extdom plugin to translate SID to names and POSIX IDs. It can +also return secondary groups for any user. + +## EXTDOM V0 (2.16.840.1.113730.3.8.10.4) + +### V0 request + + /* + * ExtdomRequestValue ::= SEQUENCE { + * inputType ENUMERATED { + * sid (1), + * name (2), + * posix uid (3), + * posix gid (4) + * }, + * requestType ENUMERATED { + * simple (1), + * full (2) + * }, + * data InputData + * } + * + * InputData ::= CHOICE { + * sid OCTET STRING, + * name NameDomainData + * uid PosixUid, + * gid PosixGid + * } + * + * NameDomainData ::= SEQUENCE { + * domain_name OCTET STRING, + * object_name OCTET STRING + * } + * + * PosixUid ::= SEQUENCE { + * domain_name OCTET STRING, + * uid INTEGER + * } + * + * PosixGid ::= SEQUENCE { + * domain_name OCTET STRING, + * gid INTEGER + * } + */ + +### V0 reply + + /* + * ExtdomResponseValue ::= SEQUENCE { + * responseType ENUMERATED { + * sid (1), + * name (2), + * posix_user (3), + * posix_group (4) + * }, + * data OutputData + * } + * + * OutputData ::= CHOICE { + * sid OCTET STRING, + * name NameDomainData, + * user PosixUser, + * group PosixGroup + * } + * + * NameDomainData ::= SEQUENCE { + * domain_name OCTET STRING, + * object_name OCTET STRING + * } + * + * PosixUser ::= SEQUENCE { + * domain_name OCTET STRING, + * user_name OCTET STRING, + * uid INTEGER + * gid INTEGER + * } + * + * PosixGroup ::= SEQUENCE { + * domain_name OCTET STRING, + * group_name OCTET STRING, + * gid INTEGER + * } + */ + +## EXTDOM V1 (2.16.840.1.113730.3.8.10.4.1) + +In V1 version the requestType is extended of `full_with_groups`. +The response introduces new type `posix_user_grouplist` containing +the list of groups + +### V1 request + + /* + * ExtdomRequestValue ::= SEQUENCE { + * inputType ENUMERATED { + * sid (1), + * name (2), + * posix uid (3), + * posix gid (4), + * }, + * requestType ENUMERATED { + * simple (1), + * full (2), + * full_with_groups (3) + * }, + * data InputData + * } + * + * InputData ::= CHOICE { + * sid OCTET STRING, + * name NameDomainData + * uid PosixUid, + * gid PosixGid + * } + * + * NameDomainData ::= SEQUENCE { + * domain_name OCTET STRING, + * object_name OCTET STRING + * } + * + * PosixUid ::= SEQUENCE { + * domain_name OCTET STRING, + * uid INTEGER + * } + * + * PosixGid ::= SEQUENCE { + * domain_name OCTET STRING, + * gid INTEGER + * } + */ + +### V1 reply + + /* + * ExtdomResponseValue ::= SEQUENCE { + * responseType ENUMERATED { + * sid (1), + * name (2), + * posix_user (3), + * posix_group (4), + * posix_user_grouplist (5) + * }, + * data OutputData + * } + * + * OutputData ::= CHOICE { + * sid OCTET STRING, + * name NameDomainData, + * user PosixUser, + * group PosixGroup, + * user_grouplist PosixUserGrouplist + * } + * + * NameDomainData ::= SEQUENCE { + * domain_name OCTET STRING, + * object_name OCTET STRING + * } + * + * PosixUser ::= SEQUENCE { + * domain_name OCTET STRING, + * user_name OCTET STRING, + * uid INTEGER + * gid INTEGER + * } + * + * GroupNameList ::= SEQUENCE OF groupname OCTET STRING + * + * PosixGroup ::= SEQUENCE { + * domain_name OCTET STRING, + * group_name OCTET STRING, + * gid INTEGER + * } + * + * PosixUserGrouplist ::= SEQUENCE { + * domain_name OCTET STRING, + * user_name OCTET STRING, + * uid INTEGER + * gid INTEGER + * gecos OCTET STRING, + * home_directory OCTET STRING, + * shell OCTET STRING, + * grouplist GroupNameList + * } + * + * GroupNameList ::= SEQUENCE OF groupname OCTET STRING + * + */ + +## EXTDOM V2 (2.16.840.1.113730.3.8.10.4.2) + +The `name` request tries to translate name to ID. It first tries translate it +as if it is a user and when it fails, it tries to resolve is as group. + +To make it more efficient when SSSD knows the type of requested object, two new +inputTypes are defined - username and groupname. + +The response is the same as in V1 + +### V2 request + + /* + * ExtdomRequestValue ::= SEQUENCE { + * inputType ENUMERATED { + * sid (1), + * name (2), + * posix uid (3), + * posix gid (4), + * username (5), + * groupname (6) + * }, + * requestType ENUMERATED { + * simple (1), + * full (2), + * full_with_groups (3) + * }, + * data InputData + * } + * + * InputData ::= CHOICE { + * sid OCTET STRING, + * name NameDomainData + * uid PosixUid, + * gid PosixGid + * } + * + * NameDomainData ::= SEQUENCE { + * domain_name OCTET STRING, + * object_name OCTET STRING + * } + * + * PosixUid ::= SEQUENCE { + * domain_name OCTET STRING, + * uid INTEGER + * } + * + * PosixGid ::= SEQUENCE { + * domain_name OCTET STRING, + * gid INTEGER + * } + */
_______________________________________________ FreeIPA-devel mailing list -- [email protected] To unsubscribe send an email to [email protected] Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/[email protected]
