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 + -
显示快捷键?