X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source4%2Flibnet%2Flibnet_join.c;h=553bde615be3e07df2978b6998a865e8ed164e0f;hb=37d53832a4623653f706e77985a79d84bd7c6694;hp=7a897b12804be426eb3a74da84d84e193d7ef31c;hpb=a5a79e8b8cbdf24d5c2db45ece4110ed5d85e58f;p=kai%2Fsamba.git
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 7a897b12804..553bde615be 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -7,7 +7,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -16,182 +16,22 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see .
*/
#include "includes.h"
#include "libnet/libnet.h"
-#include "librpc/gen_ndr/ndr_drsuapi.h"
+#include "librpc/gen_ndr/ndr_drsuapi_c.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
-#include "libcli/cldap/cldap.h"
-#include "passdb/secrets.h"
+#include "param/secrets.h"
#include "dsdb/samdb/samdb.h"
-
-/*
- * find out Site specific stuff:
- * 1.) setup an CLDAP socket
- * 2.) lookup the Site name
- * 3.) Add entry CN=,CN=Servers,CN=,CN=Sites,CN=Configuration,.
- * TODO: 4.) use DsAddEntry() to create CN=NTDS Settings,CN=,CN=Servers,CN=...
- */
-static NTSTATUS libnet_JoinSite(struct libnet_context *ctx,
- struct dcerpc_pipe *drsuapi_pipe,
- struct policy_handle drsuapi_bind_handle,
- struct ldb_context *remote_ldb,
- struct libnet_JoinDomain *libnet_r)
-{
- NTSTATUS status;
- TALLOC_CTX *tmp_ctx;
-
- struct cldap_socket *cldap = NULL;
- struct cldap_netlogon search;
-
- struct ldb_dn *server_dn;
- struct ldb_message *msg;
- int rtn;
-
- const char *site_name;
- const char *server_dn_str;
- const char *config_dn_str;
-
- tmp_ctx = talloc_named(libnet_r, 0, "libnet_JoinSite temp context");
- if (!tmp_ctx) {
- libnet_r->out.error_string = NULL;
- return NT_STATUS_NO_MEMORY;
- }
-
- /* Resolve the site name. */
-
- ZERO_STRUCT(search);
- search.in.dest_address = libnet_r->out.samr_binding->host;
- search.in.acct_control = -1;
- search.in.version = 6;
-
- cldap = cldap_socket_init(tmp_ctx, NULL);
- status = cldap_netlogon(cldap, tmp_ctx, &search);
- if (!NT_STATUS_IS_OK(status)) {
- /* Default to using Default-First-Site-Name rather than returning status at this point. */
- site_name = talloc_asprintf(tmp_ctx, "%s", "Default-First-Site-Name");
- if (!site_name) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- } else {
- site_name = search.out.netlogon.logon5.site_name;
- }
-
- config_dn_str = talloc_asprintf(tmp_ctx, "CN=Configuration,%s", libnet_r->out.domain_dn_str);
- if (!config_dn_str) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- server_dn_str = talloc_asprintf(tmp_ctx, "CN=%s,CN=Servers,CN=%s,CN=Sites,%s",
- libnet_r->in.netbios_name, site_name, config_dn_str);
- if (!server_dn_str) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- /*
- Add entry CN=,CN=Servers,CN=,CN=Sites,CN=Configuration,.
- */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- rtn = ldb_msg_add_string(msg, "objectClass", "server");
- if (rtn != 0) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- rtn = ldb_msg_add_string(msg, "systemFlags", "50000000");
- if (rtn != 0) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- rtn = ldb_msg_add_string(msg, "serverReference",libnet_r->out.account_dn_str);
- if (rtn != 0) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- server_dn = ldb_dn_explode(tmp_ctx, server_dn_str);
- if (server_dn == NULL) {
- libnet_r->out.error_string = talloc_asprintf(libnet_r,
- "Invalid server dn: %s",
- server_dn_str);
- talloc_free(tmp_ctx);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- msg->dn = server_dn;
-
- rtn = ldb_add(remote_ldb, msg);
- if (rtn == LDB_ERR_ENTRY_ALREADY_EXISTS) {
- int i;
-
- /* make a 'modify' msg, and only for serverReference */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
- msg->dn = server_dn;
-
- rtn = ldb_msg_add_string(msg, "serverReference",libnet_r->out.account_dn_str);
- if (rtn != 0) {
- libnet_r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- /* mark all the message elements (should be just one)
- as LDB_FLAG_MOD_REPLACE */
- for (i=0;inum_elements;i++) {
- msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
- }
-
- rtn = ldb_modify(remote_ldb, msg);
- if (rtn != 0) {
- libnet_r->out.error_string
- = talloc_asprintf(libnet_r,
- "Failed to modify server entry %s: %s: %d",
- server_dn_str,
- ldb_errstring(remote_ldb), rtn);
- talloc_free(tmp_ctx);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
- } else if (rtn != 0) {
- libnet_r->out.error_string
- = talloc_asprintf(libnet_r,
- "Failed to add server entry %s: %s: %d",
- server_dn_str,
- ldb_errstring(remote_ldb), rtn);
- talloc_free(tmp_ctx);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
- DEBUG(0, ("We still need to perform a DsAddEntry() so that we can create the CN=NTDS Settings container.\n"));
-
- /* Store the server DN in libnet_r */
- libnet_r->out.server_dn_str = server_dn_str;
- talloc_steal(libnet_r, server_dn_str);
-
- talloc_free(tmp_ctx);
- return NT_STATUS_OK;
-}
+#include "db_wrap.h"
+#include "libcli/security/security.h"
+#include "auth/credentials/credentials.h"
+#include "auth/credentials/credentials_krb5.h"
+#include "librpc/gen_ndr/ndr_samr_c.h"
+#include "param/param.h"
/*
* complete a domain join, when joining to a AD domain:
@@ -222,7 +62,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
struct GUID drsuapi_bind_guid;
struct ldb_context *remote_ldb;
- const struct ldb_dn *account_dn;
+ struct ldb_dn *account_dn;
const char *account_dn_str;
const char *remote_ldb_url;
struct ldb_result *res;
@@ -230,12 +70,11 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
int ret, rtn;
- unsigned int kvno;
-
const char * const attrs[] = {
"msDS-KeyVersionNumber",
"servicePrincipalName",
"dNSHostName",
+ "objectGUID",
NULL,
};
@@ -272,13 +111,13 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
status = dcerpc_pipe_connect_b(tmp_ctx,
&drsuapi_pipe,
drsuapi_binding,
- &dcerpc_table_drsuapi,
+ &ndr_table_drsuapi,
ctx->cred,
ctx->event_ctx);
if (!NT_STATUS_IS_OK(status)) {
r->out.error_string = talloc_asprintf(r,
"Connection to DRSUAPI pipe of PDC of domain '%s' failed: %s",
- r->in.domain_name,
+ r->out.domain_name,
nt_errstr(status));
talloc_free(tmp_ctx);
return status;
@@ -296,16 +135,14 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
r->out.error_string
= talloc_asprintf(r,
- "dcerpc_drsuapi_DsBind for [%s\\%s] failed - %s\n",
- r->in.domain_name, r->in.account_name,
+ "dcerpc_drsuapi_DsBind failed - %s",
dcerpc_errstr(tmp_ctx, drsuapi_pipe->last_fault_code));
talloc_free(tmp_ctx);
return status;
} else {
r->out.error_string
= talloc_asprintf(r,
- "dcerpc_drsuapi_DsBind for [%s\\%s] failed - %s\n",
- r->in.domain_name, r->in.account_name,
+ "dcerpc_drsuapi_DsBind failed - %s",
nt_errstr(status));
talloc_free(tmp_ctx);
return status;
@@ -313,7 +150,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
} else if (!W_ERROR_IS_OK(r_drsuapi_bind.out.result)) {
r->out.error_string
= talloc_asprintf(r,
- "DsBind failed - %s\n",
+ "DsBind failed - %s",
win_errstr(r_drsuapi_bind.out.result));
talloc_free(tmp_ctx);
return NT_STATUS_UNSUCCESSFUL;
@@ -323,8 +160,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
ZERO_STRUCT(r_crack_names);
r_crack_names.in.bind_handle = &drsuapi_bind_handle;
r_crack_names.in.level = 1;
- r_crack_names.in.req.req1.unknown1 = 0x000004e4;
- r_crack_names.in.req.req1.unknown2 = 0x00000407;
+ r_crack_names.in.req.req1.codepage = 1252; /* western european */
+ r_crack_names.in.req.req1.language = 0x00000407; /* german */
r_crack_names.in.req.req1.count = 1;
r_crack_names.in.req.req1.names = names;
r_crack_names.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
@@ -342,7 +179,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
r->out.error_string
= talloc_asprintf(r,
- "dcerpc_drsuapi_DsCrackNames for [%s] failed - %s\n",
+ "dcerpc_drsuapi_DsCrackNames for [%s] failed - %s",
names[0].str,
dcerpc_errstr(tmp_ctx, drsuapi_pipe->last_fault_code));
talloc_free(tmp_ctx);
@@ -350,7 +187,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
} else {
r->out.error_string
= talloc_asprintf(r,
- "dcerpc_drsuapi_DsCrackNames for [%s] failed - %s\n",
+ "dcerpc_drsuapi_DsCrackNames for [%s] failed - %s",
names[0].str,
nt_errstr(status));
talloc_free(tmp_ctx);
@@ -359,34 +196,32 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
} else if (!W_ERROR_IS_OK(r_crack_names.out.result)) {
r->out.error_string
= talloc_asprintf(r,
- "DsCrackNames failed - %s\n", win_errstr(r_crack_names.out.result));
+ "DsCrackNames failed - %s", win_errstr(r_crack_names.out.result));
talloc_free(tmp_ctx);
return NT_STATUS_UNSUCCESSFUL;
} else if (r_crack_names.out.level != 1
|| !r_crack_names.out.ctr.ctr1
- || r_crack_names.out.ctr.ctr1->count != 1
- || !r_crack_names.out.ctr.ctr1->array[0].result_name
- || r_crack_names.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
- r->out.error_string = talloc_asprintf(r, "DsCrackNames failed\n");
+ || r_crack_names.out.ctr.ctr1->count != 1) {
+ r->out.error_string = talloc_asprintf(r, "DsCrackNames failed");
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INVALID_PARAMETER;
+ } else if (r_crack_names.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
+ r->out.error_string = talloc_asprintf(r, "DsCrackNames failed: %d", r_crack_names.out.ctr.ctr1->array[0].status);
talloc_free(tmp_ctx);
return NT_STATUS_UNSUCCESSFUL;
+ } else if (r_crack_names.out.ctr.ctr1->array[0].result_name == NULL) {
+ r->out.error_string = talloc_asprintf(r, "DsCrackNames failed: no result name");
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INVALID_PARAMETER;
}
/* Store the DN of our machine account. */
account_dn_str = r_crack_names.out.ctr.ctr1->array[0].result_name;
- account_dn = ldb_dn_explode(tmp_ctx, account_dn_str);
- if (!account_dn) {
- r->out.error_string = talloc_asprintf(r, "Invalid account dn: %s",
- account_dn_str);
- talloc_free(tmp_ctx);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Now we know the user's DN, open with LDAP, read and modify a few things */
remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s",
- drsuapi_binding->host);
+ drsuapi_binding->target_hostname);
if (!remote_ldb_url) {
r->out.error_string = NULL;
talloc_free(tmp_ctx);
@@ -401,18 +236,32 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
return NT_STATUS_UNSUCCESSFUL;
}
+ account_dn = ldb_dn_new(tmp_ctx, remote_ldb, account_dn_str);
+ if (! ldb_dn_validate(account_dn)) {
+ r->out.error_string = talloc_asprintf(r, "Invalid account dn: %s",
+ account_dn_str);
+ talloc_free(tmp_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
/* search for the user's record */
ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE,
- NULL, attrs, &res);
- if (ret != LDB_SUCCESS || res->count != 1) {
- r->out.error_string = talloc_asprintf(r, "ldb_search for %s failed - %s\n",
+ NULL, attrs, &res);
+ if (ret != LDB_SUCCESS) {
+ r->out.error_string = talloc_asprintf(r, "ldb_search for %s failed - %s",
account_dn_str, ldb_errstring(remote_ldb));
talloc_free(tmp_ctx);
return NT_STATUS_UNSUCCESSFUL;
}
- /* If we have a kvno recorded in AD, we need it locally as well */
- kvno = ldb_msg_find_uint(res->msgs[0], "msDS-KeyVersionNumber", 0);
+ talloc_steal(tmp_ctx, res);
+
+ if (res->count != 1) {
+ r->out.error_string = talloc_asprintf(r, "ldb_search for %s failed - found %d entries",
+ account_dn_str, res->count);
+ talloc_free(tmp_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
/* Prepare a new message, for the modify */
msg = ldb_msg_new(tmp_ctx);
@@ -470,8 +319,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
if (rtn != 0) {
r->out.error_string
= talloc_asprintf(r,
- "Failed to replace entries on %s\n",
- ldb_dn_linearize(tmp_ctx, msg->dn));
+ "Failed to replace entries on %s",
+ ldb_dn_get_linearized(msg->dn));
talloc_free(tmp_ctx);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -492,7 +341,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
r->out.error_string
= talloc_asprintf(r,
- "dcerpc_drsuapi_DsCrackNames for [%s] failed - %s\n",
+ "dcerpc_drsuapi_DsCrackNames for [%s] failed - %s",
r->in.domain_name,
dcerpc_errstr(tmp_ctx, drsuapi_pipe->last_fault_code));
talloc_free(tmp_ctx);
@@ -500,7 +349,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
} else {
r->out.error_string
= talloc_asprintf(r,
- "dcerpc_drsuapi_DsCrackNames for [%s] failed - %s\n",
+ "dcerpc_drsuapi_DsCrackNames for [%s] failed - %s",
r->in.domain_name,
nt_errstr(status));
talloc_free(tmp_ctx);
@@ -509,7 +358,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
} else if (!W_ERROR_IS_OK(r_crack_names.out.result)) {
r->out.error_string
= talloc_asprintf(r,
- "DsCrackNames failed - %s\n", win_errstr(r_crack_names.out.result));
+ "DsCrackNames failed - %s", win_errstr(r_crack_names.out.result));
talloc_free(tmp_ctx);
return NT_STATUS_UNSUCCESSFUL;
} else if (r_crack_names.out.level != 1
@@ -517,7 +366,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
|| r_crack_names.out.ctr.ctr1->count != 1
|| !r_crack_names.out.ctr.ctr1->array[0].result_name
|| r_crack_names.out.ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
- r->out.error_string = talloc_asprintf(r, "DsCrackNames failed\n");
+ r->out.error_string = talloc_asprintf(r, "DsCrackNames failed");
talloc_free(tmp_ctx);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -530,12 +379,15 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
r->out.domain_dn_str = r_crack_names.out.ctr.ctr1->array[0].result_name;
talloc_steal(r, r_crack_names.out.ctr.ctr1->array[0].result_name);
- r->out.kvno = kvno;
+ /* Store the KVNO of the account, critical for some kerberos
+ * operations */
+ r->out.kvno = ldb_msg_find_attr_as_uint(res->msgs[0], "msDS-KeyVersionNumber", 0);
+
+ /* Store the account GUID. */
+ r->out.account_guid = samdb_result_guid(res->msgs[0], "objectGUID");
- if (r->in.acct_type == ACB_SVRTRUST) {
- status = libnet_JoinSite(ctx,
- drsuapi_pipe, drsuapi_bind_handle,
- remote_ldb, r);
+ if (r->in.acct_type == ACB_SVRTRUST) {
+ status = libnet_JoinSite(remote_ldb, r);
}
talloc_free(tmp_ctx);
@@ -544,21 +396,23 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
/*
* do a domain join using DCERPC/SAMR calls
- * 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation)
- * is it correct to contact the the pdc of the domain of the user who's password should be set?
- * 2. do a samr_Connect to get a policy handle
- * 3. do a samr_LookupDomain to get the domain sid
- * 4. do a samr_OpenDomain to get a domain handle
- * 5. do a samr_CreateAccount to try and get a new account
+ * - connect to the LSA pipe, to try and find out information about the domain
+ * - create a secondary connection to SAMR pipe
+ * - do a samr_Connect to get a policy handle
+ * - do a samr_LookupDomain to get the domain sid
+ * - do a samr_OpenDomain to get a domain handle
+ * - do a samr_CreateAccount to try and get a new account
*
* If that fails, do:
- * 5.1. do a samr_LookupNames to get the users rid
- * 5.2. do a samr_OpenUser to get a user handle
+ * - do a samr_LookupNames to get the users rid
+ * - do a samr_OpenUser to get a user handle
+ * - potentially delete and recreate the user
+ * - assert the account is of the right type with samrQueryUserInfo
*
- * 6. call libnet_SetPassword_samr_handle to set the password
+ * - call libnet_SetPassword_samr_handle to set the password,
+ * and pass a samr_UserInfo21 struct to set full_name and the account flags
*
- * 7. do a samrSetUserInfo to set the account flags
- * 8. do some ADS specific things when we join as Domain Controller,
+ * - do some ADS specific things when we join as Domain Controller,
* look at libnet_joinADSDomain() for the details
*/
NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_JoinDomain *r)
@@ -566,17 +420,10 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
TALLOC_CTX *tmp_ctx;
NTSTATUS status, cu_status;
- struct libnet_RpcConnect *c;
- struct lsa_ObjectAttribute attr;
- struct lsa_QosInfo qos;
- struct lsa_OpenPolicy2 lsa_open_policy;
- struct policy_handle lsa_p_handle;
- struct lsa_QueryInfoPolicy2 lsa_query_info2;
- struct lsa_QueryInfoPolicy lsa_query_info;
-
- struct dcerpc_binding *samr_binding;
+
+ struct libnet_RpcConnect *connect_with_info;
struct dcerpc_pipe *samr_pipe;
- struct dcerpc_pipe *lsa_pipe;
+
struct samr_Connect sc;
struct policy_handle p_handle;
struct samr_OpenDomain od;
@@ -586,8 +433,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
struct samr_CreateUser2 cu;
struct policy_handle *u_handle = NULL;
struct samr_QueryUserInfo qui;
- struct samr_SetUserInfo sui;
- union samr_UserInfo u_info;
+ struct samr_UserInfo21 u_info21;
union libnet_SetPassword r2;
struct samr_GetUserPwInfo pwp;
struct lsa_String samr_account_name;
@@ -596,12 +442,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
uint32_t rid, access_granted;
int policy_min_pw_len = 0;
- struct dom_sid *domain_sid = NULL;
struct dom_sid *account_sid = NULL;
- const char *domain_name = NULL;
const char *password_str = NULL;
- const char *realm = NULL; /* Also flag for remote being AD */
-
r->out.error_string = NULL;
r2.samr_handle.out.error_string = NULL;
@@ -619,162 +461,50 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return NT_STATUS_NO_MEMORY;
}
- samr_pipe = talloc(tmp_ctx, struct dcerpc_pipe);
- if (!samr_pipe) {
+ connect_with_info = talloc(tmp_ctx, struct libnet_RpcConnect);
+ if (!connect_with_info) {
r->out.error_string = NULL;
talloc_free(tmp_ctx);
return NT_STATUS_NO_MEMORY;
}
-
- c = talloc(tmp_ctx, struct libnet_RpcConnect);
- if (!c) {
- r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- /* prepare connect to the LSA pipe of PDC */
+
+ /* prepare connect to the SAMR pipe of PDC */
if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) {
- c->level = LIBNET_RPC_CONNECT_PDC;
- c->in.name = r->in.domain_name;
+ connect_with_info->in.binding = NULL;
+ connect_with_info->in.name = r->in.domain_name;
} else {
- c->level = LIBNET_RPC_CONNECT_BINDING;
- c->in.binding = r->in.binding;
+ connect_with_info->in.binding = r->in.binding;
+ connect_with_info->in.name = NULL;
}
- c->in.dcerpc_iface = &dcerpc_table_lsarpc;
-
- /* connect to the LSA pipe of the PDC */
- status = libnet_RpcConnect(ctx, c, c);
+ /* This level makes a connection to the LSA pipe on the way,
+ * to get some useful bits of information about the domain */
+ connect_with_info->level = LIBNET_RPC_CONNECT_DC_INFO;
+ connect_with_info->in.dcerpc_iface = &ndr_table_samr;
+
+ /*
+ establish the SAMR connection
+ */
+ status = libnet_RpcConnect(ctx, tmp_ctx, connect_with_info);
if (!NT_STATUS_IS_OK(status)) {
- if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) {
+ if (r->in.binding) {
r->out.error_string = talloc_asprintf(mem_ctx,
- "Connection to LSA pipe of PDC of domain '%s' failed: %s",
- r->in.domain_name, nt_errstr(status));
+ "Connection to SAMR pipe of DC %s failed: %s",
+ r->in.binding, connect_with_info->out.error_string);
} else {
r->out.error_string = talloc_asprintf(mem_ctx,
- "Connection to LSA pipe with binding '%s' failed: %s",
- r->in.binding, nt_errstr(status));
- }
- talloc_free(tmp_ctx);
- return status;
- }
- lsa_pipe = c->out.dcerpc_pipe;
-
- /* Get an LSA policy handle */
-
- ZERO_STRUCT(lsa_p_handle);
- qos.len = 0;
- qos.impersonation_level = 2;
- qos.context_mode = 1;
- qos.effective_only = 0;
-
- attr.len = 0;
- attr.root_dir = NULL;
- attr.object_name = NULL;
- attr.attributes = 0;
- attr.sec_desc = NULL;
- attr.sec_qos = &qos;
-
- lsa_open_policy.in.attr = &attr;
-
- lsa_open_policy.in.system_name = talloc_asprintf(tmp_ctx, "\\");
- if (!lsa_open_policy.in.system_name) {
- r->out.error_string = NULL;
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- lsa_open_policy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- lsa_open_policy.out.handle = &lsa_p_handle;
-
- status = dcerpc_lsa_OpenPolicy2(lsa_pipe, tmp_ctx, &lsa_open_policy);
-
- /* This now fails on ncacn_ip_tcp against Win2k3 SP1 */
- if (NT_STATUS_IS_OK(status)) {
- /* Look to see if this is ADS (a fault indicates NT4 or Samba 3.0) */
-
- lsa_query_info2.in.handle = &lsa_p_handle;
- lsa_query_info2.in.level = LSA_POLICY_INFO_DNS;
-
- status = dcerpc_lsa_QueryInfoPolicy2(lsa_pipe, tmp_ctx,
- &lsa_query_info2);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(mem_ctx,
- "lsa_QueryInfoPolicy2 failed: %s",
- nt_errstr(status));
- talloc_free(tmp_ctx);
- return status;
- }
- realm = lsa_query_info2.out.info->dns.dns_domain.string;
- }
-
- /* Grab the domain SID (regardless of the result of the previous call */
-
- lsa_query_info.in.handle = &lsa_p_handle;
- lsa_query_info.in.level = LSA_POLICY_INFO_DOMAIN;
-
- status = dcerpc_lsa_QueryInfoPolicy(lsa_pipe, tmp_ctx,
- &lsa_query_info);
-
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(mem_ctx,
- "lsa_QueryInfoPolicy2 failed: %s",
- nt_errstr(status));
- talloc_free(tmp_ctx);
- return status;
- }
-
- domain_sid = lsa_query_info.out.info->domain.sid;
- domain_name = lsa_query_info.out.info->domain.name.string;
- } else {
- /* Cause the code further down to try this with just SAMR */
- domain_sid = NULL;
- if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) {
- domain_name = talloc_strdup(tmp_ctx, r->in.domain_name);
- } else {
- /* Bugger, we just lost our way to automaticly find the domain name */
- domain_name = talloc_strdup(tmp_ctx, lp_workgroup());
+ "Connection to SAMR pipe of PDC for %s failed: %s",
+ r->in.domain_name, connect_with_info->out.error_string);
}
- }
-
- /*
- establish a SAMR connection, on the same CIFS transport
- */
-
- /* Find the original binding string */
- samr_binding = talloc(tmp_ctx, struct dcerpc_binding);
- if (!samr_binding) {
- return NT_STATUS_NO_MEMORY;
- }
- *samr_binding = *lsa_pipe->binding;
-
- /* Make binding string for samr, not the other pipe */
- status = dcerpc_epm_map_binding(tmp_ctx, samr_binding,
- &dcerpc_table_samr,
- lsa_pipe->conn->event_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(mem_ctx,
- "Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s",
- DCERPC_NETLOGON_UUID,
- nt_errstr(status));
talloc_free(tmp_ctx);
return status;
}
- /* Setup a SAMR connection */
- status = dcerpc_secondary_connection(lsa_pipe, &samr_pipe, samr_binding);
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(mem_ctx,
- "SAMR secondary connection failed: %s",
- nt_errstr(status));
- talloc_free(tmp_ctx);
- return status;
- }
+ samr_pipe = connect_with_info->out.dcerpc_pipe;
- status = dcerpc_pipe_auth(samr_pipe, samr_binding, &dcerpc_table_samr, ctx->cred);
+ status = dcerpc_pipe_auth(tmp_ctx, &samr_pipe,
+ connect_with_info->out.dcerpc_pipe->binding,
+ &ndr_table_samr, ctx->cred);
if (!NT_STATUS_IS_OK(status)) {
r->out.error_string = talloc_asprintf(mem_ctx,
"SAMR bind failed: %s",
@@ -799,11 +529,22 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
+ /* If this is a connection on ncacn_ip_tcp to Win2k3 SP1, we don't get back this useful info */
+ if (!connect_with_info->out.domain_name) {
+ if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) {
+ connect_with_info->out.domain_name = talloc_strdup(tmp_ctx, r->in.domain_name);
+ } else {
+ /* Bugger, we just lost our way to automaticly find the domain name */
+ connect_with_info->out.domain_name = talloc_strdup(tmp_ctx, lp_workgroup(global_loadparm));
+ connect_with_info->out.realm = talloc_strdup(tmp_ctx, lp_realm(global_loadparm));
+ }
+ }
+
/* Perhaps we didn't get a SID above, because we are against ncacn_ip_tcp */
- if (!domain_sid) {
+ if (!connect_with_info->out.domain_sid) {
struct lsa_String name;
struct samr_LookupDomain l;
- name.string = domain_name;
+ name.string = connect_with_info->out.domain_name;
l.in.connect_handle = &p_handle;
l.in.domain_name = &name;
@@ -815,23 +556,23 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
talloc_free(tmp_ctx);
return status;
}
- domain_sid = l.out.sid;
+ connect_with_info->out.domain_sid = l.out.sid;
}
/* prepare samr_OpenDomain */
ZERO_STRUCT(d_handle);
od.in.connect_handle = &p_handle;
od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- od.in.sid = domain_sid;
+ od.in.sid = connect_with_info->out.domain_sid;
od.out.domain_handle = &d_handle;
/* do a samr_OpenDomain to get a domain handle */
status = dcerpc_samr_OpenDomain(samr_pipe, tmp_ctx, &od);
if (!NT_STATUS_IS_OK(status)) {
r->out.error_string = talloc_asprintf(mem_ctx,
- "samr_OpenDomain for [%s] failed: %s",
- r->in.domain_name,
- nt_errstr(status));
+ "samr_OpenDomain for [%s] failed: %s",
+ dom_sid_string(tmp_ctx, connect_with_info->out.domain_sid),
+ nt_errstr(status));
talloc_free(tmp_ctx);
return status;
}
@@ -876,7 +617,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
/* check if we got one RID for the user */
if (ln.out.rids.count != 1) {
r->out.error_string = talloc_asprintf(mem_ctx,
- "samr_LookupNames for [%s] returns %d RIDs\n",
+ "samr_LookupNames for [%s] returns %d RIDs",
r->in.account_name, ln.out.rids.count);
talloc_free(tmp_ctx);
return NT_STATUS_INVALID_PARAMETER;
@@ -921,16 +662,16 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu);
if (!NT_STATUS_IS_OK(status)) {
r->out.error_string = talloc_asprintf(mem_ctx,
- "samr_CreateUser2 (recreate) for [%s] failed: %s\n",
- r->in.domain_name, nt_errstr(status));
+ "samr_CreateUser2 (recreate) for [%s] failed: %s",
+ r->in.account_name, nt_errstr(status));
talloc_free(tmp_ctx);
return status;
}
}
} else if (!NT_STATUS_IS_OK(status)) {
r->out.error_string = talloc_asprintf(mem_ctx,
- "samr_CreateUser2 for [%s] failed: %s\n",
- r->in.domain_name, nt_errstr(status));
+ "samr_CreateUser2 for [%s] failed: %s",
+ r->in.account_name, nt_errstr(status));
talloc_free(tmp_ctx);
return status;
}
@@ -953,7 +694,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
status = NT_STATUS_INVALID_PARAMETER;
r->out.error_string
= talloc_asprintf(mem_ctx,
- "samr_QueryUserInfo failed to return qui.out.info for [%s]: %s\n",
+ "samr_QueryUserInfo failed to return qui.out.info for [%s]: %s",
r->in.account_name, nt_errstr(status));
talloc_free(tmp_ctx);
return status;
@@ -997,7 +738,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
= talloc_asprintf(mem_ctx,
"We asked to create a new machine account (%s) of type %s, "
"but we got an account of type %s. This is unexpected. "
- "Perhaps delete the account and try again.\n",
+ "Perhaps delete the account and try again.",
r->in.account_name, new_account_type, old_account_type);
talloc_free(tmp_ctx);
return NT_STATUS_INVALID_PARAMETER;
@@ -1009,8 +750,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
= talloc_asprintf(mem_ctx,
"The machine account (%s) already exists in the domain %s, "
"but is a %s. You asked to join as a %s. Please delete "
- "the account and try again.\n",
- r->in.account_name, domain_name, old_account_type, new_account_type);
+ "the account and try again.",
+ r->in.account_name, connect_with_info->out.domain_name, old_account_type, new_account_type);
talloc_free(tmp_ctx);
return NT_STATUS_USER_EXISTS;
}
@@ -1018,7 +759,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
acct_flags = qui.out.info->info16.acct_flags;
}
- acct_flags = (acct_flags & ~ACB_DISABLED);
+ acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ));
/* Find out what password policy this user has */
pwp.in.user_handle = u_handle;
@@ -1032,11 +773,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
password_str = generate_random_str(tmp_ctx, MAX(8, policy_min_pw_len));
+ /* set full_name and reset flags */
+ ZERO_STRUCT(u_info21);
+ u_info21.full_name.string = r->in.account_name;
+ u_info21.acct_flags = acct_flags;
+ u_info21.fields_present = SAMR_FIELD_FULL_NAME | SAMR_FIELD_ACCT_FLAGS;
+
r2.samr_handle.level = LIBNET_SET_PASSWORD_SAMR_HANDLE;
r2.samr_handle.in.account_name = r->in.account_name;
r2.samr_handle.in.newpassword = password_str;
r2.samr_handle.in.user_handle = u_handle;
r2.samr_handle.in.dcerpc_pipe = samr_pipe;
+ r2.samr_handle.in.info21 = &u_info21;
status = libnet_SetPassword(ctx, tmp_ctx, &r2);
if (!NT_STATUS_IS_OK(status)) {
@@ -1045,27 +793,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
- /* reset flags (if required) */
- if (acct_flags != qui.out.info->info16.acct_flags) {
- ZERO_STRUCT(u_info);
- u_info.info16.acct_flags = acct_flags;
-
- sui.in.user_handle = u_handle;
- sui.in.info = &u_info;
- sui.in.level = 16;
-
- dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(mem_ctx,
- "samr_SetUserInfo for [%s] failed to remove ACB_DISABLED flag: %s",
- r->in.account_name,
- nt_errstr(status));
- talloc_free(tmp_ctx);
- return status;
- }
- }
-
- account_sid = dom_sid_add_rid(mem_ctx, domain_sid, rid);
+ account_sid = dom_sid_add_rid(mem_ctx, connect_with_info->out.domain_sid, rid);
if (!account_sid) {
r->out.error_string = NULL;
talloc_free(tmp_ctx);
@@ -1074,24 +802,22 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
/* Finish out by pushing various bits of status data out for the caller to use */
r->out.join_password = password_str;
- talloc_steal(mem_ctx, password_str);
+ talloc_steal(mem_ctx, r->out.join_password);
- r->out.domain_sid = domain_sid;
- talloc_steal(mem_ctx, domain_sid);
+ r->out.domain_sid = connect_with_info->out.domain_sid;
+ talloc_steal(mem_ctx, r->out.domain_sid);
r->out.account_sid = account_sid;
- talloc_steal(mem_ctx, account_sid);
-
- r->out.domain_name = domain_name;
- talloc_steal(mem_ctx, domain_name);
- r->out.realm = realm;
- talloc_steal(mem_ctx, realm);
- r->out.lsa_pipe = lsa_pipe;
- talloc_steal(mem_ctx, lsa_pipe);
+ 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_binding;
- talloc_steal(mem_ctx, samr_binding);
+ 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;
@@ -1102,7 +828,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
/* Now, if it was AD, then we want to start looking changing a
* few more things. Otherwise, we are done. */
- if (realm) {
+ if (r->out.realm) {
status = libnet_JoinADSDomain(ctx, r);
return status;
}
@@ -1119,7 +845,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
struct libnet_JoinDomain *r2;
int ret, rtn;
struct ldb_context *ldb;
- const struct ldb_dn *base_dn;
+ struct ldb_dn *base_dn;
struct ldb_message **msgs, *msg;
const char *sct;
const char * const attrs[] = {
@@ -1127,12 +853,13 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
"secret",
"priorSecret",
"priorChanged",
+ "krb5Keytab",
+ "privateKeytab",
NULL
};
uint32_t acct_type = 0;
const char *account_name;
const char *netbios_name;
- char *filter;
r->out.error_string = NULL;
@@ -1148,9 +875,9 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
return NT_STATUS_NO_MEMORY;
}
- if (r->in.secure_channel_type == SEC_CHAN_BDC) {
+ if (r->in.join_type == SEC_CHAN_BDC) {
acct_type = ACB_SVRTRUST;
- } else if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
+ } else if (r->in.join_type == SEC_CHAN_WKSTA) {
acct_type = ACB_WSTRUST;
} else {
r->out.error_string = NULL;
@@ -1158,10 +885,10 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
return NT_STATUS_INVALID_PARAMETER;
}
- if ((r->in.netbios_name != NULL) && (r->in.level != LIBNET_JOIN_AUTOMATIC)) {
+ if (r->in.netbios_name != NULL) {
netbios_name = r->in.netbios_name;
} else {
- netbios_name = talloc_reference(tmp_mem, lp_netbios_name());
+ netbios_name = talloc_reference(tmp_mem, lp_netbios_name(global_loadparm));
if (!netbios_name) {
r->out.error_string = NULL;
talloc_free(tmp_mem);
@@ -1184,7 +911,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
if (!ldb) {
r->out.error_string
= talloc_asprintf(mem_ctx,
- "Could not open secrets database\n");
+ "Could not open secrets database");
talloc_free(tmp_mem);
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
@@ -1209,7 +936,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
/*
* now prepare the record for secrets.ldb
*/
- sct = talloc_asprintf(tmp_mem, "%d", r->in.secure_channel_type);
+ sct = talloc_asprintf(tmp_mem, "%d", r->in.join_type);
if (!sct) {
r->out.error_string = NULL;
talloc_free(tmp_mem);
@@ -1223,15 +950,15 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
return NT_STATUS_NO_MEMORY;
}
- base_dn = ldb_dn_explode(tmp_mem, "cn=Primary Domains");
+ 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_build_child(tmp_mem, "flatname", r2->out.domain_name, base_dn);
- if (!msg->dn) {
+ msg->dn = ldb_dn_copy(tmp_mem, base_dn);
+ if ( ! ldb_dn_add_child_fmt(msg->dn, "flatname=%s", r2->out.domain_name)) {
r->out.error_string = NULL;
talloc_free(tmp_mem);
return NT_STATUS_NO_MEMORY;
@@ -1319,6 +1046,12 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
"(|" SECRETS_PRIMARY_DOMAIN_FILTER "(realm=%s))",
r2->out.domain_name, r2->out.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,
@@ -1327,6 +1060,8 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
talloc_free(tmp_mem);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
} else {
+ const struct ldb_val *private_keytab;
+ const struct ldb_val *krb5_keytab;
const struct ldb_val *prior_secret;
const struct ldb_val *prior_modified_time;
int i;
@@ -1376,44 +1111,37 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
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_keytab = ldb_msg_find_ldb_val(msgs[0], "krb5Keytab");
+ if (krb5_keytab) {
+ rtn = samdb_msg_set_value(ldb, tmp_mem, msg, "krb5Keytab", krb5_keytab);
+ if (rtn == -1) {
+ r->out.error_string = NULL;
+ talloc_free(tmp_mem);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
}
/* create the secret */
ret = samdb_add(ldb, tmp_mem, msg);
if (ret != 0) {
- r->out.error_string = talloc_asprintf(mem_ctx, "Failed to create secret record %s\n",
- ldb_dn_linearize(ldb, msg->dn));
+ 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;
}
- if (r2->out.realm) {
- struct cli_credentials *creds;
- /* Make a credentials structure from it */
- creds = cli_credentials_init(mem_ctx);
- if (!creds) {
- r->out.error_string = NULL;
- talloc_free(tmp_mem);
- return NT_STATUS_NO_MEMORY;
- }
- cli_credentials_set_conf(creds);
- filter = talloc_asprintf(mem_ctx, "dn=%s", ldb_dn_linearize(mem_ctx, msg->dn));
- status = cli_credentials_set_secrets(creds, NULL, filter);
- if (!NT_STATUS_IS_OK(status)) {
- r->out.error_string = talloc_asprintf(mem_ctx, "Failed to read secrets for keytab update for %s\n",
- filter);
- talloc_free(tmp_mem);
- return status;
- }
- ret = cli_credentials_update_keytab(creds);
- if (ret != 0) {
- r->out.error_string = talloc_asprintf(mem_ctx, "Failed to update keytab for %s\n",
- filter);
- talloc_free(tmp_mem);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
-
/* move all out parameter to the callers TALLOC_CTX */
r->out.error_string = NULL;
r->out.join_password = r2->out.join_password;
@@ -1428,7 +1156,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Join *r)
{
- switch (r->in.secure_channel_type) {
+ switch (r->in.join_type) {
case SEC_CHAN_WKSTA:
return libnet_Join_primary_domain(ctx, mem_ctx, r);
case SEC_CHAN_BDC:
@@ -1438,9 +1166,7 @@ NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct lib
}
r->out.error_string = talloc_asprintf(mem_ctx,
- "Invalid secure channel type specified (%08X) attempting to join domain %s",
- r->in.secure_channel_type, r->in.domain_name);
+ "Invalid join type specified (%08X) attempting to join domain %s",
+ r->in.join_type, r->in.domain_name);
return NT_STATUS_INVALID_PARAMETER;
}
-
-