full_name = name[i].string;
if (full_name == NULL) {
- return NT_STATUS_NO_MEMORY;
+ prid[i].sid_type = type;
+ prid[i].rid = 0;
+ prid[i].sid_index = (uint32_t)-1;
+ continue;
}
DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
dom_idx = -1;
if (type != SID_NAME_UNKNOWN) {
- sid_split_rid(&sid, &rid);
+ if (type == SID_NAME_DOMAIN) {
+ rid = (uint32_t)-1;
+ } else {
+ sid_split_rid(&sid, &rid);
+ }
dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
mapped_count++;
}
struct lsa_EnumTrustDom *r)
{
struct lsa_info *info;
- uint32 next_idx;
+ uint32_t count;
struct trustdom_info **domains;
- struct lsa_DomainInfo *lsa_domains = NULL;
+ struct lsa_DomainInfo *entries;
int i;
-
- /*
- * preferred length is set to 5 as a "our" preferred length
- * nt sets this parameter to 2
- * update (20.08.2002): it's not preferred length, but preferred size!
- * it needs further investigation how to optimally choose this value
- */
- uint32 max_num_domains =
- r->in.max_size < 5 ? r->in.max_size : 10;
- uint32 num_domains;
NTSTATUS nt_status;
- uint32 num_thistime;
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
return NT_STATUS_ACCESS_DENIED;
become_root();
- nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
+ nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
unbecome_root();
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
- if (*r->in.resume_handle < num_domains) {
- num_thistime = MIN(num_domains, max_num_domains);
-
- nt_status = STATUS_MORE_ENTRIES;
+ entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
+ if (!entries) {
+ return NT_STATUS_NO_MEMORY;
+ }
- if (*r->in.resume_handle + num_thistime > num_domains) {
- num_thistime = num_domains - *r->in.resume_handle;
- nt_status = NT_STATUS_OK;
- }
+ for (i=0; i<count; i++) {
+ init_lsa_StringLarge(&entries[i].name, domains[i]->name);
+ entries[i].sid = &domains[i]->sid;
+ }
- next_idx = *r->in.resume_handle + num_thistime;
- } else {
- num_thistime = 0;
- next_idx = 0xffffffff;
- nt_status = NT_STATUS_NO_MORE_ENTRIES;
+ if (*r->in.resume_handle >= count) {
+ *r->out.resume_handle = -1;
+ TALLOC_FREE(entries);
+ return NT_STATUS_NO_MORE_ENTRIES;
}
- /* set up the lsa_enum_trust_dom response */
+ /* return the rest, limit by max_size. Note that we
+ use the w2k3 element size value of 60 */
+ r->out.domains->count = count - *r->in.resume_handle;
+ r->out.domains->count = MIN(r->out.domains->count,
+ 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
- lsa_domains = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo,
- num_thistime);
- if (!lsa_domains) {
- return NT_STATUS_NO_MEMORY;
- }
+ r->out.domains->domains = entries + *r->in.resume_handle;
- for (i=0; i<num_thistime; i++) {
- init_lsa_StringLarge(&lsa_domains[i].name, domains[i]->name);
- lsa_domains[i].sid = &domains[i]->sid;
+ if (r->out.domains->count < count - *r->in.resume_handle) {
+ *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
+ return STATUS_MORE_ENTRIES;
}
- *r->out.resume_handle = next_idx;
- r->out.domains->count = num_thistime;
- r->out.domains->domains = lsa_domains;
-
- return nt_status;
+ return NT_STATUS_OK;
}
#define LSA_AUDIT_NUM_CATEGORIES_NT4 7
q.in.handle = NULL;
q.in.sids = r->in.sids;
q.in.level = r->in.level;
- q.in.unknown1 = r->in.unknown1;
- q.in.unknown2 = r->in.unknown2;
+ q.in.lookup_options = r->in.lookup_options;
+ q.in.client_revision = r->in.client_revision;
q.in.names = r->in.names;
q.in.count = r->in.count;
NTSTATUS _lsa_CreateAccount(pipes_struct *p,
struct lsa_CreateAccount *r)
{
+ NTSTATUS status;
struct lsa_info *handle;
struct lsa_info *info;
+ uint32_t acc_granted;
+ struct security_descriptor *psd;
+ size_t sd_size;
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
/* check if the user has enough rights */
- /*
- * I don't know if it's the right one. not documented.
- * but guessed with rpcclient.
- */
- if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT))
+ if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* Work out max allowed. */
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &r->in.access_mask);
+
+ /* map the generic bits to the lsa policy ones */
+ se_map_generic(&r->in.access_mask, &lsa_account_mapping);
+
+ status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
+ &lsa_account_mapping,
+ r->in.sid, LSA_POLICY_ALL_ACCESS);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = access_check_object(psd, p->server_info->ptok,
+ NULL, 0, r->in.access_mask,
+ &acc_granted, "_lsa_CreateAccount");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if ( is_privileged_sid( r->in.sid ) )
return NT_STATUS_OBJECT_NAME_COLLISION;
}
info->sid = *r->in.sid;
- info->access = r->in.access_mask;
+ info->access = acc_granted;
info->type = LSA_HANDLE_ACCOUNT_TYPE;
/* get a (unique) handle. open a policy on it. */
return NT_STATUS_OK;
}
+/***************************************************************************
+ _lsa_Delete
+ ***************************************************************************/
+
+NTSTATUS _lsa_Delete(pipes_struct *p,
+ struct lsa_Delete *r)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
/*
* From here on the server routines are just dummy ones to make smbd link with
* librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
* pulling the server stubs across one by one.
*/
-NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
{
p->rng_fault_state = True;