/* Fills the samr_RidWithAttributeArray with the provided sids. * If it happens that we have additional groups that do not belong * to the domain, add their sids as extra sids */ static NTSTATUS group_sids_to_info3(struct netr_SamInfo3 *info3, const struct dom_sid *sids, size_t num_sids) { uint32_t attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; struct samr_RidWithAttributeArray *groups; struct dom_sid *domain_sid; unsigned int i; NTSTATUS status; uint32_t rid; bool ok; domain_sid = info3->base.domain_sid; groups = &info3->base.groups; groups->rids = talloc_array(info3, struct samr_RidWithAttribute, num_sids); if (!groups->rids) { return NT_STATUS_NO_MEMORY; } for (i = 0; i < num_sids; i++) { ok = sid_peek_check_rid(domain_sid, &sids[i], &rid); if (ok) { /* store domain group rid */ groups->rids[groups->count].rid = rid; groups->rids[groups->count].attributes = attributes; groups->count++; continue; } /* if this wasn't a domain sid, add it as extra sid */ status = append_netr_SidAttr(info3, &info3->sids, &info3->sidcount, &sids[i], attributes); if (!NT_STATUS_IS_OK(status)) { return status; } } return NT_STATUS_OK; }
static NTSTATUS merge_resource_sids(const struct PAC_LOGON_INFO *logon_info, struct netr_SamInfo3 *info3) { uint32_t i = 0; const struct PAC_DOMAIN_GROUP_MEMBERSHIP *rg = NULL; if (logon_info->info3.base.user_flags & NETLOGON_RESOURCE_GROUPS) { rg = &logon_info->resource_groups; } if (rg == NULL) { return NT_STATUS_OK; } if (rg->domain_sid == NULL) { DEBUG(10, ("Missing Resource Group Domain SID\n")); return NT_STATUS_INVALID_PARAMETER; } /* The IDL layer would be a better place to check this, but to * guard the integer addition below, we double-check */ if (rg->groups.count > 65535) { DEBUG(10, ("Too much Resource Group RIDs %u\n", (unsigned)rg->groups.count)); return NT_STATUS_INVALID_PARAMETER; } /* * If there are any resource groups (SID Compression) add * them to the extra sids portion of the info3 in the PAC. * * This makes the info3 look like it would if we got the info * from the DC rather than the PAC. */ /* * Construct a SID for each RID in the list and then append it * to the info3. */ for (i = 0; i < rg->groups.count; i++) { NTSTATUS status; struct dom_sid new_sid; uint32_t attributes = rg->groups.rids[i].attributes; sid_compose(&new_sid, rg->domain_sid, rg->groups.rids[i].rid); DEBUG(10, ("Adding SID %s to extra SIDS\n", sid_string_dbg(&new_sid))); status = append_netr_SidAttr(info3, &info3->sids, &info3->sidcount, &new_sid, attributes); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("failed to append SID %s to extra SIDS: %s\n", sid_string_dbg(&new_sid), nt_errstr(status))); return status; } } return NT_STATUS_OK; }