diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c index 7ad05659a76..43dd5028fdb 100644 --- a/src/lib/idmap/sss_idmap.c +++ b/src/lib/idmap/sss_idmap.c @@ -201,7 +201,7 @@ const char *idmap_error_string(enum idmap_error_code err) } } -bool is_domain_sid(const char *sid) +bool is_str_sid(const char *sid, int count) { const char *p; long long a; @@ -228,15 +228,25 @@ bool is_domain_sid(const char *sid) return false; } c++; - } while(c < 3 && *endptr != '\0'); + } while(c < count && *endptr != '\0'); - if (c != 3 || *endptr != '\0') { + if (c != count || *endptr != '\0') { return false; } return true; } +bool is_principal_sid(const char *str) +{ + return is_str_sid(str, 4); +} + +bool is_domain_sid(const char *str) +{ + return is_str_sid(str, 3); +} + enum idmap_error_code sss_idmap_init(idmap_alloc_func *alloc_func, void *alloc_pvt, idmap_free_func *free_func, diff --git a/src/lib/idmap/sss_idmap.exports b/src/lib/idmap/sss_idmap.exports index 840677794bd..813987ebf86 100644 --- a/src/lib/idmap/sss_idmap.exports +++ b/src/lib/idmap/sss_idmap.exports @@ -62,5 +62,6 @@ SSS_IDMAP_0.5 { sss_idmap_ctx_set_extra_slice_init; sss_idmap_add_auto_domain_ex; + is_principal_sid; } SSS_IDMAP_0.4; diff --git a/src/lib/idmap/sss_idmap.h b/src/lib/idmap/sss_idmap.h index 9c27a160004..a544e8625b0 100644 --- a/src/lib/idmap/sss_idmap.h +++ b/src/lib/idmap/sss_idmap.h @@ -706,6 +706,17 @@ const char *idmap_error_string(enum idmap_error_code err); */ bool is_domain_sid(const char *str); +/** + * @brief Check if given string can be used as principal SID + * + * @param[in] str String to check + * + * @return + * - true: String can be used as principal SID + * - false: String can not be used as principal SID + */ +bool is_principal_sid(const char *str); + /** * @brief Check if a domain is configured with algorithmic mapping * diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index d66ca156afe..6ddfc4c4613 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -467,6 +467,7 @@ struct sdap_domain { * the base DN which will not be based on the DNS domain of the LDAP * server. naming_context might be NULL even after connection to an LDAP * server. */ + char *fspdn; /* Foreign security principal search base */ char *naming_context; struct sdap_search_base **search_bases; diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c index ef995697dea..9b4ab31c9ae 100644 --- a/src/providers/ldap/sdap_async_nested_groups.c +++ b/src/providers/ldap/sdap_async_nested_groups.c @@ -531,34 +531,50 @@ static bool sdap_nested_member_is_fsp(struct sdap_nested_group_ctx *group_ctx, const char *dn) { - char *fspdn, *basedn; - int fspdn_len, dn_len, len_diff; - int reti; - bool ret = false; - - reti = domain_to_basedn(group_ctx, group_ctx->domain->realm, &basedn); - if (reti != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain basedn\n"); - return false; - } + char *fspdn; + size_t fspdn_len, dn_len; + int reti, len_diff; + bool ret = false; + + if (group_ctx->opts->sdom->fspdn == NULL) { + char *basedn; + + reti = domain_to_basedn(group_ctx, group_ctx->domain->realm, &basedn); + if (reti != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain basedn\n"); + return false; + } - fspdn = talloc_asprintf(group_ctx, "%s,%s", - "CN=ForeignSecurityPrincipals", basedn); - if (fspdn == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to run talloc_asprintf\n"); - return false; + fspdn = talloc_asprintf(group_ctx->opts->sdom, "%s,%s", + "CN=ForeignSecurityPrincipals", basedn); + if (fspdn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to run talloc_asprintf\n"); + return false; + } + talloc_free(basedn); + group_ctx->opts->sdom->fspdn = fspdn; + } else { + fspdn = group_ctx->opts->sdom->fspdn; } - talloc_free(basedn); fspdn_len = strlen(fspdn); dn_len = strlen(dn); len_diff = dn_len - fspdn_len; - if (len_diff < 0) { - talloc_free(fspdn); + if (len_diff < sizeof("CN=S-")) { return false; } - ret = strncasecmp(&dn[len_diff], fspdn, fspdn_len) == 0; - talloc_free(fspdn); + ret = (strncasecmp(&dn[len_diff], fspdn, fspdn_len) == 0); + + if (ret) { /* looks like FSP, so just double check to be 100% sure */ + char *fsp_str = talloc_strdup(group_ctx, dn); + + if (fsp_str == NULL) + return false; + fsp_str[len_diff - 1] = '\0'; /* replace comma with NULL */ + ret = is_principal_sid(&fsp_str[3]); + talloc_free(fsp_str); + } + return ret; }