dcesrv_samr.c
来自「samba最新软件」· C语言 代码 · 共 2,389 行 · 第 1/5 页
C
2,389 行
if (rtype == SID_NAME_UNKNOWN) { status = STATUS_SOME_UNMAPPED; continue; } r->out.rids.ids[i] = sid->sub_auths[sid->num_auths-1]; r->out.types.ids[i] = rtype; num_mapped++; } if (num_mapped == 0) { return NT_STATUS_NONE_MAPPED; } return status;}/* samr_LookupRids */static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_LookupRids *r){ struct dcesrv_handle *h; struct samr_domain_state *d_state; int i, total; NTSTATUS status = NT_STATUS_OK; struct lsa_String *names; uint32_t *ids; ZERO_STRUCT(r->out.names); ZERO_STRUCT(r->out.types); DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); d_state = h->data; if (r->in.num_rids == 0) return NT_STATUS_OK; names = talloc_array(mem_ctx, struct lsa_String, r->in.num_rids); ids = talloc_array(mem_ctx, uint32_t, r->in.num_rids); if ((names == NULL) || (ids == NULL)) return NT_STATUS_NO_MEMORY; total = 0; for (i=0; i<r->in.num_rids; i++) { struct ldb_message **res; int count; const char * const attrs[] = { "sAMAccountType", "sAMAccountName", NULL }; uint32_t atype; struct dom_sid *sid; ids[i] = SID_NAME_UNKNOWN; sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rids[i]); if (sid == NULL) { names[i].string = NULL; status = STATUS_SOME_UNMAPPED; continue; } count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, "(objectSid=%s)", ldap_encode_ndr_dom_sid(mem_ctx, sid)); if (count != 1) { names[i].string = NULL; status = STATUS_SOME_UNMAPPED; continue; } names[i].string = samdb_result_string(res[0], "sAMAccountName", NULL); atype = samdb_result_uint(res[0], "sAMAccountType", 0); if (atype == 0) { status = STATUS_SOME_UNMAPPED; continue; } ids[i] = samdb_atype_map(atype); if (ids[i] == SID_NAME_UNKNOWN) { status = STATUS_SOME_UNMAPPED; continue; } } r->out.names.names = names; r->out.names.count = r->in.num_rids; r->out.types.ids = ids; r->out.types.count = r->in.num_rids; return status;}/* samr_OpenGroup */static NTSTATUS dcesrv_samr_OpenGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_OpenGroup *r){ struct samr_domain_state *d_state; struct samr_account_state *a_state; struct dcesrv_handle *h; const char *groupname; struct dom_sid *sid; struct ldb_message **msgs; struct dcesrv_handle *g_handle; const char * const attrs[2] = { "sAMAccountName", NULL }; int ret; ZERO_STRUCTP(r->out.group_handle); DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); d_state = h->data; /* form the group SID */ sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid); if (!sid) { return NT_STATUS_NO_MEMORY; } /* search for the group record */ ret = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &msgs, attrs, "(&(objectSid=%s)(objectclass=group)" "(grouptype=%d))", ldap_encode_ndr_dom_sid(mem_ctx, sid), GTYPE_SECURITY_GLOBAL_GROUP); if (ret == 0) { return NT_STATUS_NO_SUCH_GROUP; } if (ret != 1) { DEBUG(0,("Found %d records matching sid %s\n", ret, dom_sid_string(mem_ctx, sid))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } groupname = samdb_result_string(msgs[0], "sAMAccountName", NULL); if (groupname == NULL) { DEBUG(0,("sAMAccountName field missing for sid %s\n", dom_sid_string(mem_ctx, sid))); 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, msgs[0]->dn); a_state->account_sid = talloc_steal(a_state, sid); a_state->account_name = talloc_strdup(a_state, groupname); if (!a_state->account_name) { return NT_STATUS_NO_MEMORY; } /* create the policy handle */ g_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_GROUP); if (!g_handle) { return NT_STATUS_NO_MEMORY; } g_handle->data = talloc_steal(g_handle, a_state); *r->out.group_handle = g_handle->wire_handle; return NT_STATUS_OK;}/* samr_QueryGroupInfo */static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_QueryGroupInfo *r){ struct dcesrv_handle *h; struct samr_account_state *a_state; struct ldb_message *msg; struct ldb_result *res; const char * const attrs[4] = { "sAMAccountName", "description", "numMembers", NULL }; int ret; r->out.info = NULL; DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP); a_state = h->data; ret = ldb_search_exp_fmt(a_state->sam_ctx, mem_ctx, &res, a_state->account_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=*"); if (ret == LDB_ERR_NO_SUCH_OBJECT) { return NT_STATUS_NO_SUCH_GROUP; } else if (ret != LDB_SUCCESS) { DEBUG(2, ("Error reading group info: %s\n", ldb_errstring(a_state->sam_ctx))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } if (res->count != 1) { DEBUG(2, ("Error finding group info, got %d entries\n", res->count)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } msg = res->msgs[0]; /* allocate the info structure */ r->out.info = talloc(mem_ctx, union samr_GroupInfo); if (r->out.info == NULL) { return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(r->out.info); /* Fill in the level */ switch (r->in.level) { case GROUPINFOALL: QUERY_STRING(msg, all.name, "sAMAccountName"); r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ QUERY_UINT (msg, all.num_members, "numMembers") QUERY_STRING(msg, all.description, "description"); break; case GROUPINFONAME: QUERY_STRING(msg, name, "sAMAccountName"); break; case GROUPINFOATTRIBUTES: r->out.info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ break; case GROUPINFODESCRIPTION: QUERY_STRING(msg, description, "description"); break; case GROUPINFOALL2: QUERY_STRING(msg, all2.name, "sAMAccountName"); r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ QUERY_UINT (msg, all2.num_members, "numMembers") QUERY_STRING(msg, all2.description, "description"); break; default: r->out.info = NULL; return NT_STATUS_INVALID_INFO_CLASS; } return NT_STATUS_OK;}/* samr_SetGroupInfo */static NTSTATUS dcesrv_samr_SetGroupInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_SetGroupInfo *r){ struct dcesrv_handle *h; struct samr_account_state *g_state; struct ldb_message *msg; struct ldb_context *sam_ctx; int ret; DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP); g_state = h->data; sam_ctx = g_state->sam_ctx; msg = ldb_msg_new(mem_ctx); if (msg == NULL) { return NT_STATUS_NO_MEMORY; } msg->dn = ldb_dn_copy(mem_ctx, g_state->account_dn); if (!msg->dn) { return NT_STATUS_NO_MEMORY; } switch (r->in.level) { case GROUPINFODESCRIPTION: SET_STRING(msg, description, "description"); break; case GROUPINFONAME: /* On W2k3 this does not change the name, it changes the * sAMAccountName attribute */ SET_STRING(msg, name, "sAMAccountName"); break; case GROUPINFOATTRIBUTES: /* This does not do anything obviously visible in W2k3 LDAP */ return NT_STATUS_OK; default: return NT_STATUS_INVALID_INFO_CLASS; } /* modify the samdb record */ ret = ldb_modify(g_state->sam_ctx, msg); if (ret != 0) { /* we really need samdb.c to return NTSTATUS */ return NT_STATUS_UNSUCCESSFUL; } return NT_STATUS_OK;}/* samr_AddGroupMember */static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_AddGroupMember *r){ struct dcesrv_handle *h; struct samr_account_state *a_state; struct samr_domain_state *d_state; struct ldb_message *mod; struct dom_sid *membersid; const char *memberdn; struct ldb_result *res; const char * const attrs[] = { NULL }; int ret; DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP); a_state = h->data; d_state = a_state->domain_state; membersid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid); if (membersid == NULL) return NT_STATUS_NO_MEMORY; /* In native mode, AD can also nest domain groups. Not sure yet * whether this is also available via RPC. */ ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res, d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, "(&(objectSid=%s)(objectclass=user))", ldap_encode_ndr_dom_sid(mem_ctx, membersid)); if (ret != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } if (res->count == 0) { return NT_STATUS_NO_SUCH_USER; } if (res->count > 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } memberdn = ldb_dn_alloc_linearized(mem_ctx, res->msgs[0]->dn); if (memberdn == NULL) return NT_STATUS_NO_MEMORY; mod = ldb_msg_new(mem_ctx); if (mod == NULL) { return NT_STATUS_NO_MEMORY; } mod->dn = talloc_reference(mem_ctx, a_state->account_dn); if (samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", memberdn) != 0) return NT_STATUS_UNSUCCESSFUL; ret = ldb_modify(a_state->sam_ctx, mod); switch (ret) { case LDB_SUCCESS: return NT_STATUS_OK; case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: return NT_STATUS_MEMBER_IN_GROUP; case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: return NT_STATUS_ACCESS_DENIED; default: return NT_STATUS_UNSUCCESSFUL; }}/* samr_DeleteDomainGroup */static NTSTATUS dcesrv_samr_DeleteDomainGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_DeleteDomainGroup *r){ struct dcesrv_handle *h; struct samr_account_state *a_state; int ret; *r->out.group_handle = *r->in.group_handle; DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP); a_state = h->data; ret = ldb_delete(a_state->sam_ctx, a_state->account_dn); if (ret != 0) { return NT_STATUS_UNSUCCESSFUL; } ZERO_STRUCTP(r->out.group_handle); return NT_STATUS_OK;}/* samr_DeleteGroupMember */static NTSTATUS dcesrv_samr_DeleteGroupMember(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_DeleteGroupMember *r){ struct dcesrv_handle *h; struct samr_account_state *a_state; struct samr_domain_state *d_state; struct ldb_message *mod; struct dom_sid *membersid; const char *memberdn; struct ldb_result *res; const char * const attrs[] = { NULL }; int ret; DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP); a_state = h->data; d_state = a_state->domain_state; membersid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid); if (membersid == NULL) return NT_STATUS_NO_MEMORY; /* In native mode, AD can also nest domain groups. Not sure yet * whether this is also available via RPC. */ ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res, d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, "(&(objectSid=%s)(objectclass=user))", ldap_encode_ndr_dom_sid(mem_ctx, membersid)); if (ret != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } if (res->count == 0) { return NT_STATUS_NO_SUCH_USER; } if (res->count > 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } memberdn = ldb_dn_alloc_linearized(mem_ctx, res->msgs[0]->dn); if (memberdn == NULL) return NT_STATUS_NO_MEMORY; mod = ldb_msg_new(mem_ctx); if (mod == NULL) { return NT_STATUS_NO_MEMORY; } mod->dn = talloc_reference(mem_ctx, a_state->account_dn); if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", memberdn) != 0) { return NT_STATUS_NO_MEMORY; } ret = ldb_modify(a_state->sam_ctx, mod); switch (ret) { case LDB_SUCCESS: return NT_STATUS_OK; case LDB_ERR_NO_SUCH_AT
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?