libnet_samsync_ldb.c

来自「samba最新软件」· C语言 代码 · 共 1,250 行 · 第 1/3 页

C
1,250
字号
	if (ret == -1) {		*error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	} else if (ret == 0) {		return NT_STATUS_NO_SUCH_ALIAS;	} else if (ret > 1) {		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	ret = ldb_delete(state->sam_ldb, msgs[0]->dn);	if (ret != 0) {		*error_string = talloc_asprintf(mem_ctx, "Failed to delete alias record %s: %s",						ldb_dn_get_linearized(msgs[0]->dn),						ldb_errstring(state->sam_ldb));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	return NT_STATUS_OK;}static NTSTATUS samsync_ldb_handle_alias_member(TALLOC_CTX *mem_ctx,						struct samsync_ldb_state *state,						enum netr_SamDatabaseID database,						struct netr_DELTA_ENUM *delta,						char **error_string) {	uint32_t rid = delta->delta_id_union.rid;	struct netr_DELTA_ALIAS_MEMBER *alias_member = delta->delta_union.alias_member;	struct ldb_message *msg;	struct ldb_message **msgs;	int ret;	const char *attrs[] = { NULL };	int i;	msg = ldb_msg_new(mem_ctx);	if (msg == NULL) {		return NT_STATUS_NO_MEMORY;	}	/* search for the alias, by rid */	ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[database], &msgs, attrs,			   "(&(objectClass=group)(objectSid=%s))", 			   ldap_encode_ndr_dom_sid(mem_ctx, dom_sid_add_rid(mem_ctx, state->dom_sid[database], rid))); 			if (ret == -1) {		*error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	} else if (ret == 0) {		return NT_STATUS_NO_SUCH_GROUP;	} else if (ret > 1) {		*error_string = talloc_asprintf(mem_ctx, "More than one group/alias with SID: %s", 						dom_sid_string(mem_ctx, 							       dom_sid_add_rid(mem_ctx, 									       state->dom_sid[database], 									       rid)));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	} else {		msg->dn = talloc_steal(msg, msgs[0]->dn);	}		talloc_free(msgs);	for (i=0; i<alias_member->sids.num_sids; i++) {		struct ldb_dn *alias_member_dn;		/* search for members, in the top basedn (normal users are builtin aliases) */		ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN], &msgs, attrs,				   "(objectSid=%s)", 				   ldap_encode_ndr_dom_sid(mem_ctx, alias_member->sids.sids[i].sid)); 		if (ret == -1) {			*error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));			return NT_STATUS_INTERNAL_DB_CORRUPTION;		} else if (ret == 0) {			NTSTATUS nt_status;			nt_status = samsync_ldb_add_foreignSecurityPrincipal(mem_ctx, state,									     alias_member->sids.sids[i].sid, 									     &alias_member_dn, 									     error_string);			if (!NT_STATUS_IS_OK(nt_status)) {				return nt_status;			}		} else if (ret > 1) {			return NT_STATUS_INTERNAL_DB_CORRUPTION;		} else {			alias_member_dn = msgs[0]->dn;		}		samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "member", ldb_dn_alloc_linearized(mem_ctx, alias_member_dn));			talloc_free(msgs);	}	ret = samdb_replace(state->sam_ldb, mem_ctx, msg);	if (ret != 0) {		*error_string = talloc_asprintf(mem_ctx, "Failed to modify group record %s: %s",						ldb_dn_get_linearized(msg->dn),						ldb_errstring(state->sam_ldb));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	return NT_STATUS_OK;}static NTSTATUS samsync_ldb_handle_account(TALLOC_CTX *mem_ctx,					   struct samsync_ldb_state *state,					   enum netr_SamDatabaseID database,					   struct netr_DELTA_ENUM *delta,					   char **error_string) {	struct dom_sid *sid = delta->delta_id_union.sid;	struct netr_DELTA_ACCOUNT *account = delta->delta_union.account;	struct ldb_message *msg;	struct ldb_message **msgs;	struct ldb_dn *privilege_dn;	int ret;	const char *attrs[] = { NULL };	int i;	msg = ldb_msg_new(mem_ctx);	if (msg == NULL) {		return NT_STATUS_NO_MEMORY;	}	/* search for the account, by sid, in the top basedn */	ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN], &msgs, attrs,			   "(objectSid=%s)", ldap_encode_ndr_dom_sid(mem_ctx, sid)); 	if (ret == -1) {		*error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	} else if (ret == 0) {		NTSTATUS nt_status;		nt_status = samsync_ldb_add_foreignSecurityPrincipal(mem_ctx, state,								     sid,								     &privilege_dn,								     error_string);		privilege_dn = talloc_steal(msg, privilege_dn);		if (!NT_STATUS_IS_OK(nt_status)) {			return nt_status;		}	} else if (ret > 1) {		*error_string = talloc_asprintf(mem_ctx, "More than one account with SID: %s", 						dom_sid_string(mem_ctx, sid));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	} else {		privilege_dn = talloc_steal(msg, msgs[0]->dn);	}	msg->dn = privilege_dn;	for (i=0; i< account->privilege_entries; i++) {		samdb_msg_add_string(state->sam_ldb, mem_ctx, msg, "privilege",				     account->privilege_name[i].string);	}	ret = samdb_replace(state->sam_ldb, mem_ctx, msg);	if (ret != 0) {		*error_string = talloc_asprintf(mem_ctx, "Failed to modify privilege record %s",						ldb_dn_get_linearized(msg->dn));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	return NT_STATUS_OK;}static NTSTATUS samsync_ldb_delete_account(TALLOC_CTX *mem_ctx,					   struct samsync_ldb_state *state,					   enum netr_SamDatabaseID database,					   struct netr_DELTA_ENUM *delta,					   char **error_string) {	struct dom_sid *sid = delta->delta_id_union.sid;	struct ldb_message *msg;	struct ldb_message **msgs;	int ret;	const char *attrs[] = { NULL };	msg = ldb_msg_new(mem_ctx);	if (msg == NULL) {		return NT_STATUS_NO_MEMORY;	}	/* search for the account, by sid, in the top basedn */	ret = gendb_search(state->sam_ldb, mem_ctx, state->base_dn[SAM_DATABASE_DOMAIN], &msgs, attrs,			   "(objectSid=%s)", 			   ldap_encode_ndr_dom_sid(mem_ctx, sid)); 	if (ret == -1) {		*error_string = talloc_asprintf(mem_ctx, "gendb_search failed: %s", ldb_errstring(state->sam_ldb));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	} else if (ret == 0) {		return NT_STATUS_NO_SUCH_USER;	} else if (ret > 1) {		*error_string = talloc_asprintf(mem_ctx, "More than one account with SID: %s", 						dom_sid_string(mem_ctx, sid));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	} else {		msg->dn = talloc_steal(msg, msgs[0]->dn);	}	samdb_msg_add_delete(state->sam_ldb, mem_ctx, msg,  			     "privilage"); 	ret = samdb_replace(state->sam_ldb, mem_ctx, msg);	if (ret != 0) {		*error_string = talloc_asprintf(mem_ctx, "Failed to modify privilege record %s",						ldb_dn_get_linearized(msg->dn));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	return NT_STATUS_OK;}static NTSTATUS libnet_samsync_ldb_fn(TALLOC_CTX *mem_ctx, 						      void *private, 							      enum netr_SamDatabaseID database,				      struct netr_DELTA_ENUM *delta,				      char **error_string){	NTSTATUS nt_status = NT_STATUS_OK;	struct samsync_ldb_state *state = talloc_get_type(private, struct samsync_ldb_state);	*error_string = NULL;	switch (delta->delta_type) {	case NETR_DELTA_DOMAIN:	{		nt_status = samsync_ldb_handle_domain(mem_ctx, 						      state,						      database,						      delta,						      error_string);		break;	}	case NETR_DELTA_USER:	{		nt_status = samsync_ldb_handle_user(mem_ctx, 						    state,						    database,						    delta,						    error_string);		break;	}	case NETR_DELTA_DELETE_USER:	{		nt_status = samsync_ldb_delete_user(mem_ctx, 						    state,						    database,						    delta,						    error_string);		break;	}	case NETR_DELTA_GROUP:	{		nt_status = samsync_ldb_handle_group(mem_ctx, 						     state,						     database,						     delta,						     error_string);		break;	}	case NETR_DELTA_DELETE_GROUP:	{		nt_status = samsync_ldb_delete_group(mem_ctx, 						     state,						     database,						     delta,						     error_string);		break;	}	case NETR_DELTA_GROUP_MEMBER:	{		nt_status = samsync_ldb_handle_group_member(mem_ctx, 							    state,							    database,							    delta,							    error_string);		break;	}	case NETR_DELTA_ALIAS:	{		nt_status = samsync_ldb_handle_alias(mem_ctx, 						     state,						     database,						     delta,						     error_string);		break;	}	case NETR_DELTA_DELETE_ALIAS:	{		nt_status = samsync_ldb_delete_alias(mem_ctx, 						     state,						     database,						     delta,						     error_string);		break;	}	case NETR_DELTA_ALIAS_MEMBER:	{		nt_status = samsync_ldb_handle_alias_member(mem_ctx, 							    state,							    database,							    delta,							    error_string);		break;	}	case NETR_DELTA_ACCOUNT:	{		nt_status = samsync_ldb_handle_account(mem_ctx, 						       state,						       database,						       delta,						       error_string);		break;	}	case NETR_DELTA_DELETE_ACCOUNT:	{		nt_status = samsync_ldb_delete_account(mem_ctx, 						       state,						       database,						       delta,						       error_string);		break;	}	default:		/* Can't dump them all right now */		break;	}	if (!NT_STATUS_IS_OK(nt_status) && !*error_string) {		*error_string = talloc_asprintf(mem_ctx, "Failed to handle samsync delta: %s", nt_errstr(nt_status));	}	return nt_status;}static NTSTATUS libnet_samsync_ldb_init(TALLOC_CTX *mem_ctx, 							void *private,					struct libnet_SamSync_state *samsync_state,					char **error_string){	struct samsync_ldb_state *state = talloc_get_type(private, struct samsync_ldb_state);	const char *server = dcerpc_server_name(samsync_state->netlogon_pipe);	char *ldap_url;	state->samsync_state = samsync_state;	ZERO_STRUCT(state->dom_sid);	if (state->samsync_state->domain_sid) {		state->dom_sid[SAM_DATABASE_DOMAIN] = dom_sid_dup(state, state->samsync_state->domain_sid);	}	state->dom_sid[SAM_DATABASE_BUILTIN] = dom_sid_parse_talloc(state, SID_BUILTIN);	if (state->samsync_state->realm) {		if (!server || !*server) {			/* huh?  how do we not have a server name?  */			*error_string = talloc_strdup(mem_ctx, "No DCE/RPC server name available.  How did we connect?");			return NT_STATUS_INVALID_PARAMETER;		}		ldap_url = talloc_asprintf(state, "ldap://%s", server);				state->remote_ldb = ldb_wrap_connect(mem_ctx, 						     state->samsync_state->machine_net_ctx->event_ctx,						     state->samsync_state->machine_net_ctx->lp_ctx, 						     ldap_url, 						     NULL, state->samsync_state->machine_net_ctx->cred,						     0, NULL);		if (!state->remote_ldb) {			*error_string = talloc_asprintf(mem_ctx, "Failed to connect to remote LDAP server at %s (used to extract additional data in SamSync replication)", ldap_url);			return NT_STATUS_NO_LOGON_SERVERS;		}	} else {		state->remote_ldb = NULL;	}	return NT_STATUS_OK;}NTSTATUS libnet_samsync_ldb(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_samsync_ldb *r){	NTSTATUS nt_status;	struct libnet_SamSync r2;	struct samsync_ldb_state *state = talloc(mem_ctx, struct samsync_ldb_state);	if (!state) {		return NT_STATUS_NO_MEMORY;	}	state->secrets         = NULL;	state->trusted_domains = NULL;	state->sam_ldb         = ldb_wrap_connect(mem_ctx, 						  ctx->event_ctx,						  ctx->lp_ctx, 						  lp_sam_url(ctx->lp_ctx), 						  r->in.session_info,						  ctx->cred, 0, NULL);	r2.out.error_string    = NULL;	r2.in.binding_string   = r->in.binding_string;	r2.in.rid_crypt	       = true;	r2.in.init_fn          = libnet_samsync_ldb_init;	r2.in.delta_fn         = libnet_samsync_ldb_fn;	r2.in.fn_ctx           = state;	r2.in.machine_account  = NULL; /* TODO:  Create a machine account, fill this in, and the delete it */	nt_status              = libnet_SamSync_netlogon(ctx, state, &r2);	r->out.error_string    = r2.out.error_string;	talloc_steal(mem_ctx, r->out.error_string);	if (!NT_STATUS_IS_OK(nt_status)) {		talloc_free(state);		return nt_status;	}	talloc_free(state);	return nt_status;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?