diff --git a/source3/include/ads_protos.h b/source3/include/ads_protos.h index 2565e2ca9b9..0cd7c2cac07 100644 --- a/source3/include/ads_protos.h +++ b/source3/include/ads_protos.h @@ -110,5 +110,10 @@ ADS_STATUS ads_do_search_all_sd_flags(ADS_STRUCT *ads, const char *bind_path, int scope, const char *expr, const char **attrs, uint32 sd_flags, LDAPMessage **res); - - +ADS_STATUS ads_get_tokensids(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *dn, + DOM_SID *user_sid, + DOM_SID *primary_group_sid, + DOM_SID **sids, + size_t *num_sids); diff --git a/source3/include/gpo.h b/source3/include/gpo.h index a13c81b554d..431702e3001 100644 --- a/source3/include/gpo.h +++ b/source3/include/gpo.h @@ -94,3 +94,10 @@ struct GP_EXT { #define GPO_CACHE_DIR "gpo_cache" #define GPT_INI "GPT.INI" + +struct GPO_SID_TOKEN { + DOM_SID object_sid; + DOM_SID primary_group_sid; + size_t num_token_sids; + DOM_SID *token_sids; +}; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 48be73230e7..f5f273d3f2f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -3196,4 +3196,108 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } +/** + * pull all token-sids from an LDAP dn + * @param ads connection to ads server + * @param mem_ctx TALLOC_CTX for allocating sid array + * @param dn of LDAP object + * @param user_sid pointer to DOM_SID (objectSid) + * @param primary_group_sid pointer to DOM_SID (self composed) + * @param sids pointer to sid array to allocate + * @param num_sids counter of SIDs pulled + * @return status of token query + **/ + ADS_STATUS ads_get_tokensids(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *dn, + DOM_SID *user_sid, + DOM_SID *primary_group_sid, + DOM_SID **sids, + size_t *num_sids) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + int count = 0; + size_t tmp_num_sids; + DOM_SID *tmp_sids; + DOM_SID tmp_user_sid; + DOM_SID tmp_primary_group_sid; + uint32 pgid; + const char *attrs[] = { + "objectSid", + "tokenGroups", + "primaryGroupID", + NULL + }; + + status = ads_search_retry_dn(ads, &res, dn, attrs); + if (!ADS_ERR_OK(status)) { + return status; + } + + count = ads_count_replies(ads, res); + if (count != 1) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_SUCH_OBJECT); + } + + if (!ads_pull_sid(ads, res, "objectSid", &tmp_user_sid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (!ads_pull_uint32(ads, res, "primaryGroupID", &pgid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + { + /* hack to compose the primary group sid without knowing the + * domsid */ + + DOM_SID domsid; + uint32 dummy_rid; + + sid_copy(&domsid, &tmp_user_sid); + + if (!sid_split_rid(&domsid, &dummy_rid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (!sid_compose(&tmp_primary_group_sid, &domsid, pgid)) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + } + + tmp_num_sids = ads_pull_sids(ads, mem_ctx, res, "tokenGroups", &tmp_sids); + + if (tmp_num_sids == 0 || !tmp_sids) { + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_NO_MEMORY); + } + + if (num_sids) { + *num_sids = tmp_num_sids; + } + + if (sids) { + *sids = tmp_sids; + } + + if (user_sid) { + *user_sid = tmp_user_sid; + } + + if (primary_group_sid) { + *primary_group_sid = tmp_primary_group_sid; + } + + DEBUG(10,("ads_get_tokensids: returned %d sids\n", (int)tmp_num_sids + 2)); + + ads_msgfree(ads, res); + return ADS_ERROR_LDAP(LDAP_SUCCESS); +} + #endif diff --git a/source3/libgpo/gpo_ldap.c b/source3/libgpo/gpo_ldap.c index b19ef0cd7e9..f82924e415d 100644 --- a/source3/libgpo/gpo_ldap.c +++ b/source3/libgpo/gpo_ldap.c @@ -570,6 +570,68 @@ ADS_STATUS add_gplink_to_gpo_list(ADS_STRUCT *ads, return ADS_ERROR(LDAP_SUCCESS); } +/**************************************************************** +****************************************************************/ + +ADS_STATUS ads_get_gpo_sid_token(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *dn, + struct GPO_SID_TOKEN **token) +{ + ADS_STATUS status; + DOM_SID object_sid; + DOM_SID primary_group_sid; + DOM_SID *ad_token_sids; + size_t num_ad_token_sids = 0; + DOM_SID *token_sids; + size_t num_token_sids = 0; + struct GPO_SID_TOKEN *new_token = NULL; + int i; + + new_token = TALLOC_ZERO_P(mem_ctx, struct GPO_SID_TOKEN); + ADS_ERROR_HAVE_NO_MEMORY(new_token); + + status = ads_get_tokensids(ads, mem_ctx, dn, + &object_sid, &primary_group_sid, + &ad_token_sids, &num_ad_token_sids); + if (!ADS_ERR_OK(status)) { + return status; + } + + new_token->object_sid = object_sid; + new_token->primary_group_sid = primary_group_sid; + + token_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, 1); + ADS_ERROR_HAVE_NO_MEMORY(token_sids); + + for (i = 0; i < num_ad_token_sids; i++) { + + if (sid_check_is_in_builtin(&ad_token_sids[i])) { + continue; + } + + if (!add_sid_to_array_unique(mem_ctx, &ad_token_sids[i], + &token_sids, &num_token_sids)) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + } + + /* Add S-1-5-11 to token */ + if (!add_sid_to_array_unique(mem_ctx, &global_sid_Authenticated_Users, + &token_sids, &num_token_sids)) { + return ADS_ERROR(LDAP_NO_MEMORY); + } + + + new_token->token_sids = token_sids; + new_token->num_token_sids = num_token_sids; + + *token = new_token; + + return ADS_ERROR_LDAP(LDAP_SUCCESS); +} + + /**************************************************************** get the full list of GROUP_POLICY_OBJECTs for a given dn ****************************************************************/