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