libnet_join.c
来自「samba最新软件」· C语言 代码 · 共 1,213 行 · 第 1/3 页
C
1,213 行
talloc_steal(mem_ctx, r->out.domain_sid); r->out.account_sid = account_sid; talloc_steal(mem_ctx, r->out.account_sid); r->out.domain_name = connect_with_info->out.domain_name; talloc_steal(mem_ctx, r->out.domain_name); r->out.realm = connect_with_info->out.realm; talloc_steal(mem_ctx, r->out.realm); r->out.samr_pipe = samr_pipe; talloc_steal(mem_ctx, samr_pipe); r->out.samr_binding = samr_pipe->binding; talloc_steal(mem_ctx, r->out.samr_binding); r->out.user_handle = u_handle; talloc_steal(mem_ctx, u_handle); r->out.error_string = r2.samr_handle.out.error_string; talloc_steal(mem_ctx, r2.samr_handle.out.error_string); r->out.kvno = 0; r->out.server_dn_str = NULL; talloc_free(tmp_ctx); /* Now, if it was AD, then we want to start looking changing a * few more things. Otherwise, we are done. */ if (r->out.realm) { status = libnet_JoinADSDomain(ctx, r); return status; } return status;}NTSTATUS libnet_set_join_secrets(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_set_join_secrets *r){ TALLOC_CTX *tmp_mem; int ret, rtn; struct ldb_context *ldb; struct ldb_dn *base_dn; struct ldb_message **msgs, *msg; const char *sct; const char * const attrs[] = { "whenChanged", "secret", "priorSecret", "priorChanged", "krb5Keytab", "privateKeytab", NULL }; tmp_mem = talloc_new(mem_ctx); if (!tmp_mem) { return NT_STATUS_NO_MEMORY; } /* Open the secrets database */ ldb = secrets_db_connect(tmp_mem, ctx->lp_ctx); if (!ldb) { r->out.error_string = talloc_asprintf(mem_ctx, "Could not open secrets database"); talloc_free(tmp_mem); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } /* * now prepare the record for secrets.ldb */ sct = talloc_asprintf(tmp_mem, "%d", r->in.join_type); if (!sct) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } msg = ldb_msg_new(tmp_mem); if (!msg) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } base_dn = ldb_dn_new(tmp_mem, ldb, "cn=Primary Domains"); if (!base_dn) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } msg->dn = ldb_dn_copy(tmp_mem, base_dn); if ( ! ldb_dn_add_child_fmt(msg->dn, "flatname=%s", r->in.domain_name)) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "flatname", r->in.domain_name); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } if (r->in.realm) { rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "realm", r->in.realm); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "objectClass", "primaryDomain"); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "objectClass", "primaryDomain"); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "secret", r->in.join_password); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "samAccountName", r->in.account_name); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "secureChannelType", sct); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } if (r->in.kvno) { rtn = samdb_msg_add_uint(ldb, tmp_mem, msg, "msDS-KeyVersionNumber", r->in.kvno); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } if (r->in.domain_sid) { rtn = samdb_msg_add_dom_sid(ldb, tmp_mem, msg, "objectSid", r->in.domain_sid); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } /* * search for the secret record * - remove the records we find * - and fetch the old secret and store it under priorSecret */ ret = gendb_search(ldb, tmp_mem, base_dn, &msgs, attrs, "(|" SECRETS_PRIMARY_DOMAIN_FILTER "(realm=%s))", r->in.domain_name, r->in.realm); if (ret == 0) { rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secretsKeytab", "secrets.keytab"); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } else if (ret == -1) { r->out.error_string = talloc_asprintf(mem_ctx, "Search for domain: %s and realm: %s failed: %s", r->in.domain_name, r->in.realm, ldb_errstring(ldb)); talloc_free(tmp_mem); return NT_STATUS_INTERNAL_DB_CORRUPTION; } else { const struct ldb_val *private_keytab; const struct ldb_val *krb5_main_keytab; const struct ldb_val *prior_secret; const struct ldb_val *prior_modified_time; int i; for (i = 0; i < ret; i++) { ldb_delete(ldb, msgs[i]->dn); } prior_secret = ldb_msg_find_ldb_val(msgs[0], "secret"); if (prior_secret) { rtn = samdb_msg_set_value(ldb, tmp_mem, msg, "priorSecret", prior_secret); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secret", r->in.join_password); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } prior_modified_time = ldb_msg_find_ldb_val(msgs[0], "whenChanged"); if (prior_modified_time) { rtn = samdb_msg_set_value(ldb, tmp_mem, msg, "priorWhenChanged", prior_modified_time); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "samAccountName", r->in.account_name); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secureChannelType", sct); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } /* We will want to keep the keytab names */ private_keytab = ldb_msg_find_ldb_val(msgs[0], "privateKeytab"); if (private_keytab) { rtn = samdb_msg_set_value(ldb, tmp_mem, msg, "privateKeytab", private_keytab); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } krb5_main_keytab = ldb_msg_find_ldb_val(msgs[0], "krb5Keytab"); if (krb5_main_keytab) { rtn = samdb_msg_set_value(ldb, tmp_mem, msg, "krb5Keytab", krb5_main_keytab); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } } /* create the secret */ ret = ldb_add(ldb, msg); if (ret != 0) { r->out.error_string = talloc_asprintf(mem_ctx, "Failed to create secret record %s", ldb_dn_get_linearized(msg->dn)); talloc_free(tmp_mem); return NT_STATUS_INTERNAL_DB_CORRUPTION; } return NT_STATUS_OK;}static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Join *r){ NTSTATUS status; TALLOC_CTX *tmp_mem; struct libnet_JoinDomain *r2; struct libnet_set_join_secrets *r3; uint32_t acct_type = 0; const char *account_name; const char *netbios_name; r->out.error_string = NULL; tmp_mem = talloc_new(mem_ctx); if (!tmp_mem) { return NT_STATUS_NO_MEMORY; } r2 = talloc(tmp_mem, struct libnet_JoinDomain); if (!r2) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } if (r->in.join_type == SEC_CHAN_BDC) { acct_type = ACB_SVRTRUST; } else if (r->in.join_type == SEC_CHAN_WKSTA) { acct_type = ACB_WSTRUST; } else { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_INVALID_PARAMETER; } if (r->in.netbios_name != NULL) { netbios_name = r->in.netbios_name; } else { netbios_name = talloc_reference(tmp_mem, lp_netbios_name(ctx->lp_ctx)); if (!netbios_name) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } } account_name = talloc_asprintf(tmp_mem, "%s$", netbios_name); if (!account_name) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } /* * join the domain */ ZERO_STRUCTP(r2); r2->in.domain_name = r->in.domain_name; r2->in.account_name = account_name; r2->in.netbios_name = netbios_name; r2->in.level = LIBNET_JOINDOMAIN_AUTOMATIC; r2->in.acct_type = acct_type; r2->in.recreate_account = false; status = libnet_JoinDomain(ctx, r2, r2); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_steal(mem_ctx, r2->out.error_string); talloc_free(tmp_mem); return status; } r3 = talloc(tmp_mem, struct libnet_set_join_secrets); if (!r3) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(r3); r3->in.domain_name = r2->out.domain_name; r3->in.realm = r2->out.realm; r3->in.account_name = account_name; r3->in.netbios_name = netbios_name; r3->in.join_type = r->in.join_type; r3->in.join_password = r2->out.join_password; r3->in.kvno = r2->out.kvno; r3->in.domain_sid = r2->out.domain_sid; status = libnet_set_join_secrets(ctx, r3, r3); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_steal(mem_ctx, r3->out.error_string); talloc_free(tmp_mem); return status; } /* move all out parameter to the callers TALLOC_CTX */ r->out.error_string = NULL; r->out.join_password = r2->out.join_password; talloc_steal(mem_ctx, r2->out.join_password); r->out.domain_sid = r2->out.domain_sid; talloc_steal(mem_ctx, r2->out.domain_sid); r->out.domain_name = r2->out.domain_name; talloc_steal(mem_ctx, r2->out.domain_name); talloc_free(tmp_mem); return NT_STATUS_OK;}NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Join *r){ switch (r->in.join_type) { case SEC_CHAN_WKSTA: return libnet_Join_primary_domain(ctx, mem_ctx, r); case SEC_CHAN_BDC: return libnet_Join_primary_domain(ctx, mem_ctx, r); case SEC_CHAN_DOMAIN: break; } r->out.error_string = talloc_asprintf(mem_ctx, "Invalid join type specified (%08X) attempting to join domain %s", r->in.join_type, r->in.domain_name); return NT_STATUS_INVALID_PARAMETER;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?