*/
#include "rpc_server/lsa/lsa.h"
+#include "libds/common/flag_mapping.h"
static const struct {
const char *domain;
const char *name;
const char *sid;
- int rtype;
+ enum lsa_SidType rtype;
} well_known[] = {
{
.name = "EVERYONE",
static NTSTATUS lookup_well_known_names(TALLOC_CTX *mem_ctx, const char *domain,
const char *name, const char **authority_name,
- struct dom_sid **sid, uint32_t *rtype)
+ struct dom_sid **sid, enum lsa_SidType *rtype)
{
- int i;
+ unsigned int i;
for (i=0; well_known[i].sid; i++) {
if (domain) {
if (strcasecmp_m(domain, well_known[i].domain) == 0
static NTSTATUS lookup_well_known_sids(TALLOC_CTX *mem_ctx,
const char *sid_str, const char **authority_name,
- const char **name, uint32_t *rtype)
+ const char **name, enum lsa_SidType *rtype)
{
- int i;
+ unsigned int i;
for (i=0; well_known[i].sid; i++) {
if (strcasecmp_m(sid_str, well_known[i].sid) == 0) {
*authority_name = well_known[i].domain;
static NTSTATUS dcesrv_lsa_lookup_name(struct tevent_context *ev_ctx,
struct loadparm_context *lp_ctx,
struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
- const char *name, const char **authority_name,
- struct dom_sid **sid, enum lsa_SidType *rtype)
+ const char *name, const char **authority_name,
+ struct dom_sid **sid, enum lsa_SidType *rtype,
+ uint32_t *rid)
{
- int ret, atype, i;
+ int ret, i;
+ uint32_t atype;
struct ldb_message **res;
const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
const char *p;
/* Look up table of well known names */
status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype);
if (NT_STATUS_IS_OK(status)) {
+ dom_sid_split_rid(NULL, *sid, NULL, rid);
+ return NT_STATUS_OK;
+ }
+
+ if (username == NULL) {
+ *authority_name = NAME_BUILTIN;
+ *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
+ *rtype = SID_NAME_DOMAIN;
+ *rid = 0xFFFFFFFF;
return NT_STATUS_OK;
}
*authority_name = NAME_NT_AUTHORITY;
*sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
*rtype = SID_NAME_DOMAIN;
+ dom_sid_split_rid(NULL, *sid, NULL, rid);
return NT_STATUS_OK;
}
if (strcasecmp_m(username, NAME_BUILTIN) == 0) {
*authority_name = NAME_BUILTIN;
*sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
*rtype = SID_NAME_DOMAIN;
+ *rid = 0xFFFFFFFF;
return NT_STATUS_OK;
}
if (strcasecmp_m(username, state->domain_dns) == 0) {
*authority_name = state->domain_name;
*sid = state->domain_sid;
*rtype = SID_NAME_DOMAIN;
+ *rid = 0xFFFFFFFF;
return NT_STATUS_OK;
}
if (strcasecmp_m(username, state->domain_name) == 0) {
*authority_name = state->domain_name;
*sid = state->domain_sid;
*rtype = SID_NAME_DOMAIN;
+ *rid = 0xFFFFFFFF;
return NT_STATUS_OK;
}
if (!name) {
return NT_STATUS_NO_MEMORY;
}
- status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
+ status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
if (NT_STATUS_IS_OK(status)) {
return status;
}
if (!name) {
return NT_STATUS_NO_MEMORY;
}
- status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
+ status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
if (NT_STATUS_IS_OK(status)) {
return status;
}
if (!name) {
return NT_STATUS_NO_MEMORY;
}
- status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype);
+ status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
if (NT_STATUS_IS_OK(status)) {
return status;
}
*authority_name = NAME_NT_AUTHORITY;
*sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
*rtype = SID_NAME_DOMAIN;
+ dom_sid_split_rid(NULL, *sid, NULL, rid);
return NT_STATUS_OK;
}
/* Look up table of well known names */
- return lookup_well_known_names(mem_ctx, domain, username, authority_name,
- sid, rtype);
+ status = lookup_well_known_names(mem_ctx, domain, username, authority_name,
+ sid, rtype);
+ if (NT_STATUS_IS_OK(status)) {
+ dom_sid_split_rid(NULL, *sid, NULL, rid);
+ }
+ return status;
} else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) {
*authority_name = NAME_BUILTIN;
domain_dn = state->builtin_dn;
}
ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs);
- if (ret == 1) {
- domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
- if (domain_sid == NULL) {
- return NT_STATUS_INVALID_SID;
- }
- } else {
+ if (ret != 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
+ if (domain_sid == NULL) {
return NT_STATUS_INVALID_SID;
}
if (!*username) {
*sid = domain_sid;
*rtype = SID_NAME_DOMAIN;
+ *rid = 0xFFFFFFFF;
return NT_STATUS_OK;
}
ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
"(&(sAMAccountName=%s)(objectSid=*))",
ldb_binary_encode_string(mem_ctx, username));
- if (ret == -1) {
- return NT_STATUS_INVALID_SID;
+ if (ret < 0) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
for (i=0; i < ret; i++) {
continue;
}
- atype = samdb_result_uint(res[i], "sAMAccountType", 0);
+ atype = ldb_msg_find_attr_as_uint(res[i], "sAMAccountType", 0);
*rtype = ds_atype_map(atype);
if (*rtype == SID_NAME_UNKNOWN) {
return STATUS_SOME_UNMAPPED;
}
+ dom_sid_split_rid(NULL, *sid, NULL, rid);
return NT_STATUS_OK;
}
uint32_t *sid_index)
{
struct dom_sid *authority_sid;
- int i;
+ uint32_t i;
if (rtype != SID_NAME_DOMAIN) {
authority_sid = dom_sid_dup(mem_ctx, sid);
return NT_STATUS_NOT_FOUND;
}
+ /* need to re-add a check for an allocated sid */
+
ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
"objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
- if (ret == 1) {
- *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
+ if ((ret < 0) || (ret > 1)) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ if (ret == 0) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
+ if (!*name) {
+ *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL);
if (!*name) {
- *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL);
- if (!*name) {
- *name = talloc_strdup(mem_ctx, sid_str);
- NT_STATUS_HAVE_NO_MEMORY(*name);
- }
+ *name = talloc_strdup(mem_ctx, sid_str);
+ NT_STATUS_HAVE_NO_MEMORY(*name);
}
-
- atype = samdb_result_uint(res[0], "sAMAccountType", 0);
-
- *rtype = ds_atype_map(atype);
-
- return NT_STATUS_OK;
}
- /* need to re-add a check for an allocated sid */
+ atype = ldb_msg_find_attr_as_uint(res[0], "sAMAccountType", 0);
+ *rtype = ds_atype_map(atype);
- return NT_STATUS_NOT_FOUND;
+ return NT_STATUS_OK;
}
{
struct lsa_policy_state *state;
struct lsa_RefDomainList *domains = NULL;
- int i;
+ uint32_t i;
NTSTATUS status = NT_STATUS_OK;
+ struct dcesrv_handle *h;
+
+ DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
if (r->in.level < LSA_LOOKUP_NAMES_ALL ||
r->in.level > LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC) {
return NT_STATUS_INVALID_PARAMETER;
}
+ state = h->data;
+
*r->out.domains = NULL;
/* NOTE: the WSPP test suite tries SIDs with invalid revision numbers,
MS-DTYP 2.4.2
*/
- status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
domains = talloc_zero(r->out.domains, struct lsa_RefDomainList);
if (domains == NULL) {
return NT_STATUS_NO_MEMORY;
r2.in.names = r->in.names;
r2.in.level = r->in.level;
r2.in.count = r->in.count;
- r2.in.unknown1 = r->in.unknown1;
- r2.in.unknown2 = r->in.unknown2;
+ r2.in.lookup_options = r->in.lookup_options;
+ r2.in.client_revision = r->in.client_revision;
r2.out.count = r->out.count;
r2.out.names = r->out.names;
r2.out.domains = r->out.domains;
{
struct lsa_LookupSids2 r2;
NTSTATUS status;
- int i;
+ uint32_t i;
ZERO_STRUCT(r2);
r2.in.names = NULL;
r2.in.level = r->in.level;
r2.in.count = r->in.count;
- r2.in.unknown1 = 0;
- r2.in.unknown2 = 0;
+ r2.in.lookup_options = 0;
+ r2.in.client_revision = 0;
r2.out.count = r->out.count;
r2.out.names = NULL;
r2.out.domains = r->out.domains;
return status;
}
-
-/*
- lsa_LookupNames3
-*/
-NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
- TALLOC_CTX *mem_ctx,
- struct lsa_LookupNames3 *r)
+static NTSTATUS dcesrv_lsa_LookupNames_common(struct dcesrv_call_state *dce_call,
+ TALLOC_CTX *mem_ctx,
+ struct lsa_policy_state *policy_state,
+ struct lsa_LookupNames3 *r)
{
- struct lsa_policy_state *policy_state;
- struct dcesrv_handle *policy_handle;
- int i;
struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
struct lsa_RefDomainList *domains;
-
- DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
+ uint32_t i;
if (r->in.level < LSA_LOOKUP_NAMES_ALL ||
r->in.level > LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC) {
return NT_STATUS_INVALID_PARAMETER;
}
- policy_state = policy_handle->data;
-
*r->out.domains = NULL;
domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
const char *name = r->in.names[i].string;
const char *authority_name;
struct dom_sid *sid;
- uint32_t sid_index;
+ uint32_t sid_index, rid;
enum lsa_SidType rtype;
NTSTATUS status2;
r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
r->out.sids->sids[i].flags = 0;
- status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, policy_state, mem_ctx, name, &authority_name, &sid, &rtype);
+ status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, policy_state, mem_ctx, name,
+ &authority_name, &sid, &rtype, &rid);
if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
continue;
}
return NT_STATUS_OK;
}
+/*
+ lsa_LookupNames3
+*/
+NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
+ TALLOC_CTX *mem_ctx,
+ struct lsa_LookupNames3 *r)
+{
+ struct lsa_policy_state *policy_state;
+ struct dcesrv_handle *policy_handle;
+
+ DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
+
+ policy_state = policy_handle->data;
+
+ return dcesrv_lsa_LookupNames_common(dce_call,
+ mem_ctx,
+ policy_state,
+ r);
+}
+
/*
lsa_LookupNames4
NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct lsa_LookupNames4 *r)
{
- struct lsa_LookupNames3 r2;
- struct lsa_OpenPolicy2 pol;
+ struct lsa_policy_state *policy_state;
+ struct lsa_LookupNames3 q;
NTSTATUS status;
- struct dcesrv_handle *h;
-
- ZERO_STRUCT(r2);
-
- /* No policy handle on the wire, so make one up here */
- r2.in.handle = talloc(mem_ctx, struct policy_handle);
- if (!r2.in.handle) {
- return NT_STATUS_NO_MEMORY;
- }
- pol.out.handle = r2.in.handle;
- pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- pol.in.attr = NULL;
- pol.in.system_name = NULL;
- status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
+ status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &policy_state);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- /* ensure this handle goes away at the end of this call */
- DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
- talloc_steal(mem_ctx, h);
+ ZERO_STRUCT(q);
+
+ q.in.handle = NULL;
+ q.in.num_names = r->in.num_names;
+ q.in.names = r->in.names;
+ q.in.level = r->in.level;
+ q.in.sids = r->in.sids;
+ q.in.count = r->in.count;
+ q.in.lookup_options = r->in.lookup_options;
+ q.in.client_revision = r->in.client_revision;
+
+ q.out.count = r->out.count;
+ q.out.sids = r->out.sids;
+ q.out.domains = r->out.domains;
+
+ status = dcesrv_lsa_LookupNames_common(dce_call,
+ mem_ctx,
+ policy_state,
+ &q);
+
+ talloc_free(policy_state);
+
+ r->out.count = q.out.count;
+ r->out.sids = q.out.sids;
+ r->out.domains = q.out.domains;
- r2.in.num_names = r->in.num_names;
- r2.in.names = r->in.names;
- r2.in.level = r->in.level;
- r2.in.sids = r->in.sids;
- r2.in.count = r->in.count;
- r2.in.lookup_options = r->in.lookup_options;
- r2.in.client_revision = r->in.client_revision;
- r2.out.domains = r->out.domains;
- r2.out.sids = r->out.sids;
- r2.out.count = r->out.count;
-
- status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2);
-
- r->out.domains = r2.out.domains;
- r->out.sids = r2.out.sids;
- r->out.count = r2.out.count;
return status;
}
{
struct lsa_policy_state *state;
struct dcesrv_handle *h;
- int i;
+ uint32_t i;
struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
struct lsa_RefDomainList *domains;
const char *name = r->in.names[i].string;
const char *authority_name;
struct dom_sid *sid;
- uint32_t rtype, sid_index;
+ uint32_t sid_index, rid=0;
+ enum lsa_SidType rtype;
NTSTATUS status2;
r->out.sids->count++;
r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
r->out.sids->sids[i].unknown = 0;
- status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, state, mem_ctx, name,
- &authority_name, &sid, &rtype);
+ status2 = dcesrv_lsa_lookup_name(dce_call->event_ctx, lp_ctx, state, mem_ctx, name,
+ &authority_name, &sid, &rtype, &rid);
if (!NT_STATUS_IS_OK(status2)) {
continue;
}
}
r->out.sids->sids[i].sid_type = rtype;
- r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
+ r->out.sids->sids[i].rid = rid;
r->out.sids->sids[i].sid_index = sid_index;
r->out.sids->sids[i].unknown = 0;
{
struct lsa_LookupNames2 r2;
NTSTATUS status;
- int i;
+ uint32_t i;
ZERO_STRUCT(r2);