dcesrv_samr.c
来自「samba最新软件」· C语言 代码 · 共 2,389 行 · 第 1/5 页
C
2,389 行
ldb_errstring(d_state->sam_ctx))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } a_state->account_name = talloc_steal(a_state, account_name); if (!a_state->account_name) { return NT_STATUS_NO_MEMORY; } /* create the policy handle */ u_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_USER); if (!u_handle) { return NT_STATUS_NO_MEMORY; } u_handle->data = talloc_steal(u_handle, a_state); *r->out.user_handle = u_handle->wire_handle; *r->out.access_granted = 0xf07ff; /* TODO: fix access mask calculations */ *r->out.rid = sid->sub_auths[sid->num_auths-1]; return NT_STATUS_OK;}/* samr_CreateUser */static NTSTATUS dcesrv_samr_CreateUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_CreateUser *r){ struct samr_CreateUser2 r2; uint32_t access_granted = 0; /* a simple wrapper around samr_CreateUser2 works nicely */ r2.in.domain_handle = r->in.domain_handle; r2.in.account_name = r->in.account_name; r2.in.acct_flags = ACB_NORMAL; r2.in.access_mask = r->in.access_mask; r2.out.user_handle = r->out.user_handle; r2.out.access_granted = &access_granted; r2.out.rid = r->out.rid; return dcesrv_samr_CreateUser2(dce_call, mem_ctx, &r2);}/* samr_EnumDomainUsers */static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_EnumDomainUsers *r){ struct dcesrv_handle *h; struct samr_domain_state *d_state; struct ldb_result *res; int ret, num_filtered_entries, i, first; struct samr_SamEntry *entries; const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL }; *r->out.resume_handle = 0; r->out.sam = NULL; r->out.num_entries = 0; DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); d_state = h->data; /* don't have to worry about users in the builtin domain, as there are none */ ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res, d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=user"); if (ret != LDB_SUCCESS) { DEBUG(3, ("Failed to search for Domain Users in %s: %s\n", ldb_dn_get_linearized(d_state->domain_dn), ldb_errstring(d_state->sam_ctx))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } /* convert to SamEntry format */ entries = talloc_array(mem_ctx, struct samr_SamEntry, res->count); if (!entries) { return NT_STATUS_NO_MEMORY; } num_filtered_entries = 0; for (i=0;i<res->count;i++) { /* Check if a mask has been requested */ if (r->in.acct_flags && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res->msgs[i], d_state->domain_dn) & r->in.acct_flags) == 0)) { continue; } entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res->msgs[i], "objectSid", 0); entries[num_filtered_entries].name.string = samdb_result_string(res->msgs[i], "sAMAccountName", ""); num_filtered_entries++; } /* sort the results by rid */ qsort(entries, num_filtered_entries, sizeof(struct samr_SamEntry), (comparison_fn_t)compare_SamEntry); /* find the first entry to return */ for (first=0; first<num_filtered_entries && entries[first].idx <= *r->in.resume_handle; first++) ; /* return the rest, limit by max_size. Note that we use the w2k3 element size value of 54 */ r->out.num_entries = num_filtered_entries - first; r->out.num_entries = MIN(r->out.num_entries, 1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER)); r->out.sam = talloc(mem_ctx, struct samr_SamArray); if (!r->out.sam) { return NT_STATUS_NO_MEMORY; } r->out.sam->entries = entries+first; r->out.sam->count = r->out.num_entries; if (first == num_filtered_entries) { return NT_STATUS_OK; } if (r->out.num_entries < num_filtered_entries - first) { *r->out.resume_handle = entries[first+r->out.num_entries-1].idx; return STATUS_MORE_ENTRIES; } return NT_STATUS_OK;}/* samr_CreateDomAlias */static NTSTATUS dcesrv_samr_CreateDomAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_CreateDomAlias *r){ struct samr_domain_state *d_state; struct samr_account_state *a_state; struct dcesrv_handle *h; const char *alias_name, *name; struct ldb_message *msg; struct dom_sid *sid; struct dcesrv_handle *a_handle; int ret; ZERO_STRUCTP(r->out.alias_handle); *r->out.rid = 0; DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); d_state = h->data; if (d_state->builtin) { DEBUG(5, ("Cannot create a domain alias in the BUILTIN domain")); return NT_STATUS_ACCESS_DENIED; } alias_name = r->in.alias_name->string; if (alias_name == NULL) { return NT_STATUS_INVALID_PARAMETER; } /* Check if alias already exists */ name = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL, "sAMAccountName", "(sAMAccountName=%s)(objectclass=group))", ldb_binary_encode_string(mem_ctx, alias_name)); if (name != NULL) { return NT_STATUS_ALIAS_EXISTS; } msg = ldb_msg_new(mem_ctx); if (msg == NULL) { return NT_STATUS_NO_MEMORY; } /* add core elements to the ldb_message for the alias */ msg->dn = ldb_dn_copy(mem_ctx, d_state->domain_dn); ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name); if (!msg->dn) { return NT_STATUS_NO_MEMORY; } samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", alias_name); samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", "group"); samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); /* create the alias */ ret = ldb_add(d_state->sam_ctx, msg); switch (ret) { case LDB_SUCCESS: break; case LDB_ERR_ENTRY_ALREADY_EXISTS: return NT_STATUS_ALIAS_EXISTS; case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: return NT_STATUS_ACCESS_DENIED; default: DEBUG(0,("Failed to create alias record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(d_state->sam_ctx))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } a_state = talloc(d_state, struct samr_account_state); if (!a_state) { return NT_STATUS_NO_MEMORY; } a_state->sam_ctx = d_state->sam_ctx; a_state->access_mask = r->in.access_mask; a_state->domain_state = talloc_reference(a_state, d_state); a_state->account_dn = talloc_steal(a_state, msg->dn); /* retrieve the sid for the alias just created */ sid = samdb_search_dom_sid(d_state->sam_ctx, a_state, msg->dn, "objectSid", NULL); a_state->account_name = talloc_strdup(a_state, alias_name); if (!a_state->account_name) { return NT_STATUS_NO_MEMORY; } /* create the policy handle */ a_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_ALIAS); if (a_handle == NULL) return NT_STATUS_NO_MEMORY; a_handle->data = talloc_steal(a_handle, a_state); *r->out.alias_handle = a_handle->wire_handle; *r->out.rid = sid->sub_auths[sid->num_auths-1]; return NT_STATUS_OK;}/* samr_EnumDomainAliases */static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_EnumDomainAliases *r){ struct dcesrv_handle *h; struct samr_domain_state *d_state; struct ldb_message **res; int ldb_cnt, count, i, first; struct samr_SamEntry *entries; const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL }; *r->out.resume_handle = 0; r->out.sam = NULL; r->out.num_entries = 0; DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); d_state = h->data; /* search for all domain groups in this domain. This could possibly be cached and resumed based on resume_key */ ldb_cnt = samdb_search_domain(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, d_state->domain_sid, "(&(|(grouptype=%d)(grouptype=%d)))" "(objectclass=group))", GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); if (ldb_cnt == -1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } if (ldb_cnt == 0) { return NT_STATUS_OK; } /* convert to SamEntry format */ entries = talloc_array(mem_ctx, struct samr_SamEntry, ldb_cnt); if (!entries) { return NT_STATUS_NO_MEMORY; } count = 0; for (i=0;i<ldb_cnt;i++) { struct dom_sid *alias_sid; alias_sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid"); if (alias_sid == NULL) continue; entries[count].idx = alias_sid->sub_auths[alias_sid->num_auths-1]; entries[count].name.string = samdb_result_string(res[i], "sAMAccountName", ""); count += 1; } /* sort the results by rid */ qsort(entries, count, sizeof(struct samr_SamEntry), (comparison_fn_t)compare_SamEntry); /* find the first entry to return */ for (first=0; first<count && entries[first].idx <= *r->in.resume_handle; first++) ; if (first == count) { return NT_STATUS_OK; } r->out.num_entries = count - first; r->out.num_entries = MIN(r->out.num_entries, 1000); r->out.sam = talloc(mem_ctx, struct samr_SamArray); if (!r->out.sam) { return NT_STATUS_NO_MEMORY; } r->out.sam->entries = entries+first; r->out.sam->count = r->out.num_entries; if (r->out.num_entries < count - first) { *r->out.resume_handle = entries[first+r->out.num_entries-1].idx; return STATUS_MORE_ENTRIES; } return NT_STATUS_OK;}/* samr_GetAliasMembership */static NTSTATUS dcesrv_samr_GetAliasMembership(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_GetAliasMembership *r){ struct dcesrv_handle *h; struct samr_domain_state *d_state; struct ldb_message **res; int i, count = 0; DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); d_state = h->data; if (r->in.sids->num_sids > 0) { const char *filter; const char * const attrs[2] = { "objectSid", NULL }; filter = talloc_asprintf(mem_ctx, "(&(|(grouptype=%d)(grouptype=%d))" "(objectclass=group)(|", GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); if (filter == NULL) return NT_STATUS_NO_MEMORY; for (i=0; i<r->in.sids->num_sids; i++) { const char *memberdn; memberdn = samdb_search_string(d_state->sam_ctx, mem_ctx, NULL, "distinguishedName", "(objectSid=%s)", ldap_encode_ndr_dom_sid(mem_ctx, r->in.sids->sids[i].sid)); if (memberdn == NULL) continue; filter = talloc_asprintf(mem_ctx, "%s(member=%s)", filter, memberdn); if (filter == NULL) return NT_STATUS_NO_MEMORY; } count = samdb_search_domain(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, d_state->domain_sid, "%s))", filter); if (count < 0) return NT_STATUS_INTERNAL_DB_CORRUPTION; } r->out.rids->count = 0; r->out.rids->ids = talloc_array(mem_ctx, uint32_t, count); if (r->out.rids->ids == NULL) return NT_STATUS_NO_MEMORY; for (i=0; i<count; i++) { struct dom_sid *alias_sid; alias_sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid"); if (alias_sid == NULL) { DEBUG(0, ("Could not find objectSid\n")); continue; } r->out.rids->ids[r->out.rids->count] = alias_sid->sub_auths[alias_sid->num_auths-1]; r->out.rids->count += 1; } return NT_STATUS_OK;}/* samr_LookupNames */static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_LookupNames *r){ struct dcesrv_handle *h; struct samr_domain_state *d_state; int i, num_mapped; NTSTATUS status = NT_STATUS_OK; const char * const attrs[] = { "sAMAccountType", "objectSid", NULL }; int count; ZERO_STRUCT(r->out.rids); ZERO_STRUCT(r->out.types); DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); d_state = h->data; if (r->in.num_names == 0) { return NT_STATUS_OK; } r->out.rids.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names); r->out.types.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names); if (!r->out.rids.ids || !r->out.types.ids) { return NT_STATUS_NO_MEMORY; } r->out.rids.count = r->in.num_names; r->out.types.count = r->in.num_names; num_mapped = 0; for (i=0;i<r->in.num_names;i++) { struct ldb_message **res; struct dom_sid *sid; uint32_t atype, rtype; r->out.rids.ids[i] = 0; r->out.types.ids[i] = SID_NAME_UNKNOWN; count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, r->in.names[i].string)); if (count != 1) { status = STATUS_SOME_UNMAPPED; continue; } sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid"); if (sid == NULL) { status = STATUS_SOME_UNMAPPED; continue; } atype = samdb_result_uint(res[0], "sAMAccountType", 0); if (atype == 0) { status = STATUS_SOME_UNMAPPED; continue; } rtype = samdb_atype_map(atype);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?