From 335a277662d28b935c9d84a3d7a98276afdffd3e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 Jan 2005 07:50:09 +0000 Subject: r4722: Start to add 'net join' to Samba4. Andrew Bartlett (This used to be commit a9b960609142e15ba5950eb1b22944eb6df18d9c) --- source4/libnet/libnet_join.c | 279 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 source4/libnet/libnet_join.c (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c new file mode 100644 index 0000000000..871e5c5e24 --- /dev/null +++ b/source4/libnet/libnet_join.c @@ -0,0 +1,279 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Andrew Bartlett 2005 + + 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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. +*/ + +#include "includes.h" +#include "libnet/libnet.h" +#include "librpc/gen_ndr/ndr_samr.h" +#include "lib/crypto/crypto.h" + +/* + * 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 + * + * 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 + * + * 6. call libnet_SetPassword_samr_handle to set the password + * + * 7. do a samrSetUserInfo to set the account flags + */ +static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) +{ + NTSTATUS status; + union libnet_rpc_connect c; + struct samr_Connect sc; + struct policy_handle p_handle; + struct samr_LookupDomain ld; + struct samr_String d_name; + struct samr_OpenDomain od; + struct policy_handle d_handle; + struct samr_LookupNames ln; + struct samr_OpenUser ou; + struct samr_CreateUser2 cu; + struct policy_handle u_handle; + struct samr_SetUserInfo sui; + union samr_UserInfo u_info; + union libnet_SetPassword r2; + struct samr_GetUserPwInfo pwp; + struct samr_String samr_account_name; + + uint32 rid, access_granted; + int policy_min_pw_len = 0; + + /* prepare connect to the SAMR pipe of users domain PDC */ + c.pdc.level = LIBNET_RPC_CONNECT_PDC; + c.pdc.in.domain_name = r->samr.in.domain_name; + c.pdc.in.dcerpc_iface_name = DCERPC_SAMR_NAME; + c.pdc.in.dcerpc_iface_uuid = DCERPC_SAMR_UUID; + c.pdc.in.dcerpc_iface_version = DCERPC_SAMR_VERSION; + + /* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */ + status = libnet_rpc_connect(ctx, mem_ctx, &c); + if (!NT_STATUS_IS_OK(status)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "Connection to SAMR pipe of PDC of domain '%s' failed: %s\n", + r->samr.in.domain_name, nt_errstr(status)); + return status; + } + + /* prepare samr_Connect */ + ZERO_STRUCT(p_handle); + sc.in.system_name = NULL; + sc.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + sc.out.connect_handle = &p_handle; + + /* 2. do a samr_Connect to get a policy handle */ + status = dcerpc_samr_Connect(c.pdc.out.dcerpc_pipe, mem_ctx, &sc); + if (!NT_STATUS_IS_OK(status)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_Connect failed: %s\n", + nt_errstr(status)); + goto disconnect; + } + + /* check result of samr_Connect */ + if (!NT_STATUS_IS_OK(sc.out.result)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_Connect failed: %s\n", + nt_errstr(sc.out.result)); + status = sc.out.result; + goto disconnect; + } + + /* prepare samr_LookupDomain */ + d_name.string = r->samr.in.domain_name; + ld.in.connect_handle = &p_handle; + ld.in.domain = &d_name; + + /* 3. do a samr_LookupDomain to get the domain sid */ + status = dcerpc_samr_LookupDomain(c.pdc.out.dcerpc_pipe, mem_ctx, &ld); + if (!NT_STATUS_IS_OK(status)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_LookupDomain for [%s] failed: %s\n", + r->samr.in.domain_name, nt_errstr(status)); + goto disconnect; + } + + /* check result of samr_LookupDomain */ + if (!NT_STATUS_IS_OK(ld.out.result)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_LookupDomain for [%s] failed: %s\n", + r->samr.in.domain_name, nt_errstr(ld.out.result)); + status = ld.out.result; + goto disconnect; + } + + /* prepare samr_OpenDomain */ + ZERO_STRUCT(d_handle); + od.in.connect_handle = &p_handle; + od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + od.in.sid = ld.out.sid; + od.out.domain_handle = &d_handle; + + /* 4. do a samr_OpenDomain to get a domain handle */ + status = dcerpc_samr_OpenDomain(c.pdc.out.dcerpc_pipe, mem_ctx, &od); + if (!NT_STATUS_IS_OK(status)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_OpenDomain for [%s] failed: %s\n", + r->samr.in.domain_name, nt_errstr(status)); + goto disconnect; + } + + /* prepare samr_CreateUser2 */ + ZERO_STRUCT(u_handle); + cu.in.domain_handle = &d_handle; + cu.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + samr_account_name.string = r->samr.in.account_name; + cu.in.account_name = &samr_account_name; + cu.in.acct_flags = r->samr.in.acct_type; + cu.out.user_handle = &u_handle; + cu.out.rid = &rid; + cu.out.access_granted = &access_granted; + + /* 4. do a samr_CreateUser2 to get an account handle, or an error */ + status = dcerpc_samr_CreateUser2(c.pdc.out.dcerpc_pipe, mem_ctx, &cu); + if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_CreateUser2 for [%s] failed: %s\n", + r->samr.in.domain_name, nt_errstr(status)); + goto disconnect; + + } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { + /* prepare samr_LookupNames */ + ln.in.domain_handle = &d_handle; + ln.in.num_names = 1; + ln.in.names = talloc_array_p(mem_ctx, struct samr_String, 1); + if (!ln.in.names) { + r->samr.out.error_string = "Out of Memory"; + return NT_STATUS_NO_MEMORY; + } + ln.in.names[0].string = r->samr.in.account_name; + + /* 5. do a samr_LookupNames to get the users rid */ + status = dcerpc_samr_LookupNames(c.pdc.out.dcerpc_pipe, mem_ctx, &ln); + if (!NT_STATUS_IS_OK(status)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_LookupNames for [%s] failed: %s\n", + r->samr.in.account_name, nt_errstr(status)); + goto disconnect; + } + + + /* check if we got one RID for the user */ + if (ln.out.rids.count != 1) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_LookupNames for [%s] returns %d RIDs\n", + r->samr.in.account_name, ln.out.rids.count); + status = NT_STATUS_INVALID_PARAMETER; + goto disconnect; + } + + /* prepare samr_OpenUser */ + ZERO_STRUCT(u_handle); + ou.in.domain_handle = &d_handle; + ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + ou.in.rid = ln.out.rids.ids[0]; + ou.out.user_handle = &u_handle; + + /* 6. do a samr_OpenUser to get a user handle */ + status = dcerpc_samr_OpenUser(c.pdc.out.dcerpc_pipe, mem_ctx, &ou); + if (!NT_STATUS_IS_OK(status)) { + r->samr.out.error_string = talloc_asprintf(mem_ctx, + "samr_OpenUser for [%s] failed: %s\n", + r->samr.in.account_name, nt_errstr(status)); + goto disconnect; + } + } + + pwp.in.user_handle = &u_handle; + + status = dcerpc_samr_GetUserPwInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &pwp); + if (NT_STATUS_IS_OK(status)) { + policy_min_pw_len = pwp.out.info.min_password_length; + } + + r->samr.out.join_password = generate_random_str(mem_ctx, MAX(8, policy_min_pw_len)); + + r2.samr_handle.level = LIBNET_SET_PASSWORD_SAMR_HANDLE; + r2.samr_handle.in.account_name = r->samr.in.account_name; + r2.samr_handle.in.newpassword = r->samr.out.join_password; + r2.samr_handle.in.user_handle = &u_handle; + r2.samr_handle.in.dcerpc_pipe = c.pdc.out.dcerpc_pipe; + + status = libnet_SetPassword(ctx, mem_ctx, &r2); + + r->samr.out.error_string = r2.samr_handle.out.error_string; + + if (!NT_STATUS_IS_OK(status)) { + goto disconnect; + } + + /* prepare samr_SetUserInfo level 23 */ + ZERO_STRUCT(u_info); + u_info.info16.acct_flags = r->samr.in.acct_type; + + sui.in.user_handle = &u_handle; + sui.in.info = &u_info; + sui.in.level = 16; + + dcerpc_samr_SetUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &sui); + +disconnect: + /* close connection */ + dcerpc_pipe_close(c.pdc.out.dcerpc_pipe); + + return status; +} + +static NTSTATUS libnet_JoinDomain_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) +{ + NTSTATUS status; + union libnet_JoinDomain r2; + + r2.samr.level = LIBNET_JOIN_DOMAIN_SAMR; + r2.samr.in.account_name = r->generic.in.account_name; + r2.samr.in.domain_name = r->generic.in.domain_name; + r2.samr.in.acct_type = r->generic.in.acct_type; + + status = libnet_JoinDomain(ctx, mem_ctx, &r2); + + r->generic.out.error_string = r2.samr.out.error_string; + + return status; +} + +NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) +{ + switch (r->generic.level) { + case LIBNET_JOIN_DOMAIN_GENERIC: + return libnet_JoinDomain_generic(ctx, mem_ctx, r); + case LIBNET_JOIN_DOMAIN_SAMR: + return libnet_JoinDomain_samr(ctx, mem_ctx, r); + } + + return NT_STATUS_INVALID_LEVEL; +} -- cgit From 8799d6b44c15a5e11c1e3528092fbca236561253 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Jan 2005 22:13:18 +0000 Subject: r4762: Store the results of a 'net join' in the LDB. Like Samba3, the storage of the primary domain password is keyed off the domain name, so we can join multiple domains, and just swap 'workgroup =' around. Andrew Bartlett (This used to be commit 54a231780e028c6433cac296f2fbc64e39632dfd) --- source4/libnet/libnet_join.c | 207 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 199 insertions(+), 8 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 871e5c5e24..6d1003078d 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -23,6 +23,7 @@ #include "libnet/libnet.h" #include "librpc/gen_ndr/ndr_samr.h" #include "lib/crypto/crypto.h" +#include "lib/ldb/include/ldb.h" /* * do a domain join using DCERPC/SAMR calls @@ -41,7 +42,8 @@ * * 7. do a samrSetUserInfo to set the account flags */ -static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) +static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, + TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) { NTSTATUS status; union libnet_rpc_connect c; @@ -55,12 +57,14 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, TALLOC_CTX *m struct samr_OpenUser ou; struct samr_CreateUser2 cu; struct policy_handle u_handle; + struct samr_QueryUserInfo qui; struct samr_SetUserInfo sui; union samr_UserInfo u_info; union libnet_SetPassword r2; struct samr_GetUserPwInfo pwp; struct samr_String samr_account_name; + uint32 acct_flags; uint32 rid, access_granted; int policy_min_pw_len = 0; @@ -233,14 +237,53 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, TALLOC_CTX *m } /* prepare samr_SetUserInfo level 23 */ - ZERO_STRUCT(u_info); - u_info.info16.acct_flags = r->samr.in.acct_type; - - sui.in.user_handle = &u_handle; - sui.in.info = &u_info; - sui.in.level = 16; + qui.in.user_handle = &u_handle; + qui.in.level = 16; + + status = dcerpc_samr_QueryUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &qui); + if (!NT_STATUS_IS_OK(status)) { + r->samr.out.error_string + = talloc_asprintf(mem_ctx, + "samr_QueryUserInfo for [%s] failed: %s\n", + r->samr.in.account_name, nt_errstr(status)); + goto disconnect; + } + if (!qui.out.info) { + status = NT_STATUS_INVALID_PARAMETER; + r->samr.out.error_string + = talloc_asprintf(mem_ctx, + "samr_QueryUserInfo failed to return qui.out.info for [%s]: %s\n", + r->samr.in.account_name, nt_errstr(status)); + goto disconnect; + } - dcerpc_samr_SetUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &sui); + if ((qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) + != r->samr.in.acct_type) { + acct_flags = (qui.out.info->info16.acct_flags & ~(ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) + | r->samr.in.acct_type; + } else { + acct_flags = qui.out.info->info16.acct_flags; + } + + acct_flags = (acct_flags & ~ACB_DISABLED); + + 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(c.pdc.out.dcerpc_pipe, mem_ctx, &sui); + if (!NT_STATUS_IS_OK(status)) { + r->samr.out.error_string + = talloc_asprintf(mem_ctx, + "samr_SetUserInfo for [%s] failed to remove ACB_DISABLED flag: %s\n", + r->samr.in.account_name, nt_errstr(status)); + goto disconnect; + } + } disconnect: /* close connection */ @@ -262,6 +305,7 @@ static NTSTATUS libnet_JoinDomain_generic(struct libnet_context *ctx, TALLOC_CTX status = libnet_JoinDomain(ctx, mem_ctx, &r2); r->generic.out.error_string = r2.samr.out.error_string; + r->generic.out.join_password = r2.samr.out.join_password; return status; } @@ -277,3 +321,150 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, unio return NT_STATUS_INVALID_LEVEL; } + + +static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, + TALLOC_CTX *mem_ctx, + union libnet_Join *r) +{ + NTSTATUS status; + int ret; + + struct ldb_wrap *ldb; + union libnet_JoinDomain r2; + const char *base_dn = "cn=Primary Domains"; + const struct ldb_val *prior_secret; + const char *prior_modified_time; + struct ldb_message **msgs, *msg; + char *sct; + const char *attrs[] = { + "whenChanged", + "secret", + "priorSecret" + "priorChanged", + NULL + }; + + r2.generic.level = LIBNET_JOIN_DOMAIN_GENERIC; + + if (r->generic.in.secure_channel_type == SEC_CHAN_BDC) { + r2.generic.in.acct_type = ACB_SVRTRUST; + } else if (r->generic.in.secure_channel_type == SEC_CHAN_WKSTA) { + r2.generic.in.acct_type = ACB_WSTRUST; + } + r2.generic.in.domain_name = r->generic.in.domain_name; + + r2.generic.in.account_name = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name()); + + /* Local secrets are stored in secrets.ldb */ + ldb = secrets_db_connect(mem_ctx); + + /* join domain */ + status = libnet_JoinDomain(ctx, mem_ctx, &r2); + + r->generic.out.error_string = r2.generic.out.error_string; + + /* store in secrets.ldb or samdb.ldb, depending on secret type */ + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + sct = talloc_asprintf(mem_ctx, "%d", r->generic.in.secure_channel_type); + msg = ldb_msg_new(mem_ctx); + + /* search for the secret record */ + ret = samdb_search(ldb, + mem_ctx, base_dn, &msgs, attrs, + "(&(cn=%s)(objectclass=primaryDomain))", + r->generic.in.domain_name); + if (ret == 0) { + msg->dn = talloc_asprintf(mem_ctx, "cn=%s,%s", + r->generic.in.domain_name, + base_dn); + + samdb_msg_add_string(ldb, mem_ctx, msg, "cn", r->generic.in.domain_name); + samdb_msg_add_string(ldb, mem_ctx, msg, "objectClass", "primaryDomain"); + samdb_msg_add_string(ldb, mem_ctx, msg, "secret", r2.generic.out.join_password); + + samdb_msg_add_string(ldb, mem_ctx, msg, "accountName", r2.generic.in.account_name); + + samdb_msg_add_string(ldb, mem_ctx, msg, "secureChannelType", sct); + + /* create the secret */ + ret = samdb_add(ldb, mem_ctx, msg); + if (ret != 0) { + r->generic.out.error_string + = talloc_asprintf(mem_ctx, + "Failed to create secret record %s\n", + msg->dn); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + return NT_STATUS_OK; + } else if (ret != 1) { + r->generic.out.error_string + = talloc_asprintf(mem_ctx, + "Found %d records matching cn=%s under DN %s\n", ret, + r->generic.in.domain_name, base_dn); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + msg->dn = msgs[0]->dn; + + prior_secret = ldb_msg_find_ldb_val(msgs[0], "secret"); + if (prior_secret) { + samdb_msg_set_value(ldb, mem_ctx, msg, "priorSecret", prior_secret); + } + samdb_msg_set_string(ldb, mem_ctx, msg, "secret", r2.generic.out.join_password); + + prior_modified_time = ldb_msg_find_string(msgs[0], + "whenChanged", NULL); + if (prior_modified_time) { + samdb_msg_set_string(ldb, mem_ctx, msg, "priorWhenChanged", + prior_modified_time); + } + + samdb_msg_set_string(ldb, mem_ctx, msg, "accountName", r2.generic.in.account_name); + samdb_msg_set_string(ldb, mem_ctx, msg, "secureChannelType", sct); + + /* update the secret */ + ret = samdb_replace(ldb, mem_ctx, msg); + if (ret != 0) { + DEBUG(0,("Failed to create secret record %s\n", msg->dn)); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + return NT_STATUS_OK; +} + +NTSTATUS libnet_Join_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_Join *r) +{ + NTSTATUS nt_status; + union libnet_Join r2; + r2.generic.in.secure_channel_type = r->generic.in.secure_channel_type; + r2.generic.in.domain_name = r->generic.in.domain_name; + + if ((r->generic.in.secure_channel_type == SEC_CHAN_WKSTA) + || (r->generic.in.secure_channel_type == SEC_CHAN_BDC)) { + r2.generic.level = LIBNET_JOIN_PRIMARY; + nt_status = libnet_Join(ctx, mem_ctx, &r2); + } else { + r->generic.out.error_string + = talloc_asprintf(mem_ctx, "Invalid secure channel type specified (%08X) attempting to join domain %s", + r->generic.in.secure_channel_type, r->generic.in.domain_name); + return NT_STATUS_INVALID_PARAMETER; + } + r->generic.out.error_string = r2.generic.out.error_string; + return nt_status; +} + +NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_Join *r) +{ + switch (r->generic.level) { + case LIBNET_JOIN_GENERIC: + return libnet_Join_generic(ctx, mem_ctx, r); + case LIBNET_JOIN_PRIMARY: + return libnet_Join_primary_domain(ctx, mem_ctx, r); + } + + return NT_STATUS_INVALID_LEVEL; +} + -- cgit From 759da3b915e2006d4c87b5ace47f399accd9ce91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 07:08:20 +0000 Subject: r5037: got rid of all of the TALLOC_DEPRECATED stuff. My apologies for the large commit. I thought this was worthwhile to get done for consistency. (This used to be commit ec32b22ed5ec224f6324f5e069d15e92e38e15c0) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 6d1003078d..bf8524c495 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -170,7 +170,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, /* prepare samr_LookupNames */ ln.in.domain_handle = &d_handle; ln.in.num_names = 1; - ln.in.names = talloc_array_p(mem_ctx, struct samr_String, 1); + ln.in.names = talloc_array(mem_ctx, struct samr_String, 1); if (!ln.in.names) { r->samr.out.error_string = "Out of Memory"; return NT_STATUS_NO_MEMORY; -- cgit From e82aad1ce39a6b7a2e51b9e2cb494d74ec70e158 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 05:09:35 +0000 Subject: r5298: - got rid of pstring.h from includes.h. This at least makes it a bit less likely that anyone will use pstring for new code - got rid of winbind_client.h from includes.h. This one triggered a huge change, as winbind_client.h was including system/filesys.h and defining the old uint32 and uint16 types, as well as its own pstring and fstring. (This used to be commit 9db6c79e902ec538108d6b7d3324039aabe1704f) --- source4/libnet/libnet_join.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index bf8524c495..42c041aa83 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -64,8 +64,8 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, struct samr_GetUserPwInfo pwp; struct samr_String samr_account_name; - uint32 acct_flags; - uint32 rid, access_granted; + uint32_t acct_flags; + uint32_t rid, access_granted; int policy_min_pw_len = 0; /* prepare connect to the SAMR pipe of users domain PDC */ -- cgit From abc28d66e9c472300271cb250313b3e8d0293abd Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 13 Feb 2005 00:26:43 +0000 Subject: r5364: Rename string fields called 'domain' and 'name' to be 'domain_name'. (This used to be commit 6749b9404d4e9876ecd964e038c608f05d2c0b69) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 42c041aa83..9257b8db3d 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -111,7 +111,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, /* prepare samr_LookupDomain */ d_name.string = r->samr.in.domain_name; ld.in.connect_handle = &p_handle; - ld.in.domain = &d_name; + ld.in.domain_name = &d_name; /* 3. do a samr_LookupDomain to get the domain sid */ status = dcerpc_samr_LookupDomain(c.pdc.out.dcerpc_pipe, mem_ctx, &ld); -- cgit From b1b14817eaa6e6579596d54166e17bc8d5605c01 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 27 Feb 2005 11:35:47 +0000 Subject: r5585: LDB interfaces change: changes: - ldb_wrap disappears from code and become a private structure of db_wrap.c thanks to our move to talloc in ldb code, we do not need to expose it anymore - removal of ldb_close() function form the code thanks to our move to talloc in ldb code, we do not need it anymore use talloc_free() to close and free an ldb database - some minor updates to ldb modules code to cope with the change and fix some bugs I found out during the process (This used to be commit d58be9e74b786a11a57e89df36081d55730dfe0a) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 9257b8db3d..2a9311b663 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -330,7 +330,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, NTSTATUS status; int ret; - struct ldb_wrap *ldb; + struct ldb_context *ldb; union libnet_JoinDomain r2; const char *base_dn = "cn=Primary Domains"; const struct ldb_val *prior_secret; -- cgit From a25443dbebbe63da502fb2f36908eac9ac7605b9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 Mar 2005 08:11:49 +0000 Subject: r5900: Use flatname to specify the netbios domain name (matches what win2k3 uses for trusted domain records) in the secrets join records. Andrew Bartlett (This used to be commit a6c502832c4ef471bd423b795f210abf3bb96ca5) --- source4/libnet/libnet_join.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 2a9311b663..f8acac8fb2 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -375,14 +375,14 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, /* search for the secret record */ ret = samdb_search(ldb, mem_ctx, base_dn, &msgs, attrs, - "(&(cn=%s)(objectclass=primaryDomain))", + "(&(flatname=%s)(objectclass=primaryDomain))", r->generic.in.domain_name); if (ret == 0) { - msg->dn = talloc_asprintf(mem_ctx, "cn=%s,%s", + msg->dn = talloc_asprintf(mem_ctx, "flatname=%s,%s", r->generic.in.domain_name, base_dn); - samdb_msg_add_string(ldb, mem_ctx, msg, "cn", r->generic.in.domain_name); + samdb_msg_add_string(ldb, mem_ctx, msg, "flatname", r->generic.in.domain_name); samdb_msg_add_string(ldb, mem_ctx, msg, "objectClass", "primaryDomain"); samdb_msg_add_string(ldb, mem_ctx, msg, "secret", r2.generic.out.join_password); -- cgit From 645711c602313940dcf80ec786557920ecfbf884 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 Mar 2005 08:00:45 +0000 Subject: r5941: Commit this patch much earlier than I would normally prefer, but metze needs a working tree... The main volume of this patch was what I started working on today: - Cleans up memory handling around DCE/RPC pipes, to have a parent talloc context. - Uses sepereate inner loops for some of the DCE/RPC tests The other and more important part of this patch fixes issues surrounding the new credentials framwork: This makes the struct cli_credentials always a talloc() structure, rather than on the stack. Parts of the cli_credentials code already assumed this. There were other issues, particularly in the DCERPC over SMB handling, as well as little things that had to be tidied up before test_w2k3.sh would start to pass. Andrew Bartlett (This used to be commit 0453f9d05d2e336fba1f85dbf2718d01fa2bf778) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index f8acac8fb2..2dcffd93e1 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -287,7 +287,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, disconnect: /* close connection */ - dcerpc_pipe_close(c.pdc.out.dcerpc_pipe); + talloc_free(c.pdc.out.dcerpc_pipe); return status; } -- cgit From d735487aad2f722d3d13994b47a998ef5164c660 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Mar 2005 00:05:44 +0000 Subject: r5983: Start support for being a domain member in Samba4. This adds the auth_domain module to the auth subsystem, and cleans up some small details around the join process (ensuring all the right info is in the DB). Andrew Bartlett (This used to be commit 858cbfb8210239aa85a01da95e5beb9546a998a5) --- source4/libnet/libnet_join.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 2dcffd93e1..1186853520 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -386,7 +386,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, samdb_msg_add_string(ldb, mem_ctx, msg, "objectClass", "primaryDomain"); samdb_msg_add_string(ldb, mem_ctx, msg, "secret", r2.generic.out.join_password); - samdb_msg_add_string(ldb, mem_ctx, msg, "accountName", r2.generic.in.account_name); + samdb_msg_add_string(ldb, mem_ctx, msg, "samAccountName", r2.generic.in.account_name); samdb_msg_add_string(ldb, mem_ctx, msg, "secureChannelType", sct); @@ -423,7 +423,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, prior_modified_time); } - samdb_msg_set_string(ldb, mem_ctx, msg, "accountName", r2.generic.in.account_name); + samdb_msg_set_string(ldb, mem_ctx, msg, "samAccountName", r2.generic.in.account_name); samdb_msg_set_string(ldb, mem_ctx, msg, "secureChannelType", sct); /* update the secret */ -- cgit From 79f6bcd5ae1711075ce0e75392ce83a72766698e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Mar 2005 01:30:43 +0000 Subject: r5988: Fix the -P option (use machine account credentials) to use the Samba4 secrets system, and not the old system from Samba3. This allowed the code from auth_domain to be shared - we now only lookup the secrets.ldb in lib/credentials.c. In order to link the resultant binary, samdb_search() has been moved from deep inside rpc_server into lib/gendb.c, along with the existing gendb_search_v(). The vast majority of this patch is the simple rename that followed, (Depending on the whole SAMDB for just this function seemed pointless, and brought in futher dependencies, such as smbencrypt.c). Andrew Bartlett (This used to be commit e13c671619bd290a8b3cae8555cb281a9a185ee0) --- source4/libnet/libnet_join.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 1186853520..1f02cc83b6 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -24,6 +24,7 @@ #include "librpc/gen_ndr/ndr_samr.h" #include "lib/crypto/crypto.h" #include "lib/ldb/include/ldb.h" +#include "include/secrets.h" /* * do a domain join using DCERPC/SAMR calls @@ -373,9 +374,9 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, msg = ldb_msg_new(mem_ctx); /* search for the secret record */ - ret = samdb_search(ldb, + ret = gendb_search(ldb, mem_ctx, base_dn, &msgs, attrs, - "(&(flatname=%s)(objectclass=primaryDomain))", + SECRETS_PRIMARY_DOMAIN_FILTER, r->generic.in.domain_name); if (ret == 0) { msg->dn = talloc_asprintf(mem_ctx, "flatname=%s,%s", -- cgit From cf687fce843bf00edf54f8e89005fc79f77b5412 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 30 Apr 2005 08:15:44 +0000 Subject: r6525: Remove incorrect comment. Andrew Bartlett (This used to be commit 7c8a0d86d4c486198ed2cf52fad2a878ed635c8b) --- source4/libnet/libnet_join.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 1f02cc83b6..e8fdc28dbd 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -364,8 +364,6 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, status = libnet_JoinDomain(ctx, mem_ctx, &r2); r->generic.out.error_string = r2.generic.out.error_string; - - /* store in secrets.ldb or samdb.ldb, depending on secret type */ if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 4c36a59f434665fa94a4ea6c1ce086adf2ed8be0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jun 2005 00:38:51 +0000 Subject: r7203: Fill in the error message and fail if we can't open the secrets database. Andrew Bartlett (This used to be commit 27257170f4ad08c1a86be9c2a5edfa0b3da0b7a0) --- source4/libnet/libnet_join.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index e8fdc28dbd..65e0006bbe 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -359,6 +359,12 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, /* Local secrets are stored in secrets.ldb */ ldb = secrets_db_connect(mem_ctx); + if (!ldb) { + r->generic.out.error_string + = talloc_asprintf(mem_ctx, + "Could not open secrets database\n"); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } /* join domain */ status = libnet_JoinDomain(ctx, mem_ctx, &r2); -- cgit From 4fa6a156bc087c5d8a9c796b9e93939273006404 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Sat, 2 Jul 2005 14:33:55 +0000 Subject: r8077: Propagate changes in rpc connect routine to functions using it (it's quite common). rafal (This used to be commit 798b00c24ae30a08ac81342d13130a6a2f9d3a08) --- source4/libnet/libnet_join.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 65e0006bbe..c76b16e10e 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -47,7 +47,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) { NTSTATUS status; - union libnet_rpc_connect c; + struct libnet_RpcConnect c; struct samr_Connect sc; struct policy_handle p_handle; struct samr_LookupDomain ld; @@ -70,14 +70,14 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, int policy_min_pw_len = 0; /* prepare connect to the SAMR pipe of users domain PDC */ - c.pdc.level = LIBNET_RPC_CONNECT_PDC; - c.pdc.in.domain_name = r->samr.in.domain_name; - c.pdc.in.dcerpc_iface_name = DCERPC_SAMR_NAME; - c.pdc.in.dcerpc_iface_uuid = DCERPC_SAMR_UUID; - c.pdc.in.dcerpc_iface_version = DCERPC_SAMR_VERSION; + c.level = LIBNET_RPC_CONNECT_PDC; + c.in.domain_name = r->samr.in.domain_name; + c.in.dcerpc_iface_name = DCERPC_SAMR_NAME; + c.in.dcerpc_iface_uuid = DCERPC_SAMR_UUID; + c.in.dcerpc_iface_version = DCERPC_SAMR_VERSION; /* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */ - status = libnet_rpc_connect(ctx, mem_ctx, &c); + status = libnet_RpcConnect(ctx, mem_ctx, &c); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "Connection to SAMR pipe of PDC of domain '%s' failed: %s\n", @@ -92,7 +92,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, sc.out.connect_handle = &p_handle; /* 2. do a samr_Connect to get a policy handle */ - status = dcerpc_samr_Connect(c.pdc.out.dcerpc_pipe, mem_ctx, &sc); + status = dcerpc_samr_Connect(c.out.dcerpc_pipe, mem_ctx, &sc); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_Connect failed: %s\n", @@ -115,7 +115,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, ld.in.domain_name = &d_name; /* 3. do a samr_LookupDomain to get the domain sid */ - status = dcerpc_samr_LookupDomain(c.pdc.out.dcerpc_pipe, mem_ctx, &ld); + status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_LookupDomain for [%s] failed: %s\n", @@ -140,7 +140,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, od.out.domain_handle = &d_handle; /* 4. do a samr_OpenDomain to get a domain handle */ - status = dcerpc_samr_OpenDomain(c.pdc.out.dcerpc_pipe, mem_ctx, &od); + status = dcerpc_samr_OpenDomain(c.out.dcerpc_pipe, mem_ctx, &od); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_OpenDomain for [%s] failed: %s\n", @@ -160,7 +160,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, cu.out.access_granted = &access_granted; /* 4. do a samr_CreateUser2 to get an account handle, or an error */ - status = dcerpc_samr_CreateUser2(c.pdc.out.dcerpc_pipe, mem_ctx, &cu); + status = dcerpc_samr_CreateUser2(c.out.dcerpc_pipe, mem_ctx, &cu); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_CreateUser2 for [%s] failed: %s\n", @@ -179,7 +179,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, ln.in.names[0].string = r->samr.in.account_name; /* 5. do a samr_LookupNames to get the users rid */ - status = dcerpc_samr_LookupNames(c.pdc.out.dcerpc_pipe, mem_ctx, &ln); + status = dcerpc_samr_LookupNames(c.out.dcerpc_pipe, mem_ctx, &ln); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_LookupNames for [%s] failed: %s\n", @@ -205,7 +205,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, ou.out.user_handle = &u_handle; /* 6. do a samr_OpenUser to get a user handle */ - status = dcerpc_samr_OpenUser(c.pdc.out.dcerpc_pipe, mem_ctx, &ou); + status = dcerpc_samr_OpenUser(c.out.dcerpc_pipe, mem_ctx, &ou); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_OpenUser for [%s] failed: %s\n", @@ -216,7 +216,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, pwp.in.user_handle = &u_handle; - status = dcerpc_samr_GetUserPwInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &pwp); + status = dcerpc_samr_GetUserPwInfo(c.out.dcerpc_pipe, mem_ctx, &pwp); if (NT_STATUS_IS_OK(status)) { policy_min_pw_len = pwp.out.info.min_password_length; } @@ -227,7 +227,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, r2.samr_handle.in.account_name = r->samr.in.account_name; r2.samr_handle.in.newpassword = r->samr.out.join_password; r2.samr_handle.in.user_handle = &u_handle; - r2.samr_handle.in.dcerpc_pipe = c.pdc.out.dcerpc_pipe; + r2.samr_handle.in.dcerpc_pipe = c.out.dcerpc_pipe; status = libnet_SetPassword(ctx, mem_ctx, &r2); @@ -241,7 +241,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, qui.in.user_handle = &u_handle; qui.in.level = 16; - status = dcerpc_samr_QueryUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &qui); + status = dcerpc_samr_QueryUserInfo(c.out.dcerpc_pipe, mem_ctx, &qui); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, @@ -276,7 +276,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, sui.in.info = &u_info; sui.in.level = 16; - dcerpc_samr_SetUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &sui); + dcerpc_samr_SetUserInfo(c.out.dcerpc_pipe, mem_ctx, &sui); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, @@ -288,7 +288,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, disconnect: /* close connection */ - talloc_free(c.pdc.out.dcerpc_pipe); + talloc_free(c.out.dcerpc_pipe); return status; } -- cgit From 0b92507760910872d5f0f3fe2c45f4f3af3466eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Jul 2005 08:09:02 +0000 Subject: r8232: remove samr_String and netr_String as they are the same as lsa_String metze (This used to be commit e601042c07d7b6eed0dc34e5b136d9266b8a0f81) --- source4/libnet/libnet_join.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index c76b16e10e..53b6db51b1 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -51,7 +51,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, struct samr_Connect sc; struct policy_handle p_handle; struct samr_LookupDomain ld; - struct samr_String d_name; + struct lsa_String d_name; struct samr_OpenDomain od; struct policy_handle d_handle; struct samr_LookupNames ln; @@ -63,7 +63,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, union samr_UserInfo u_info; union libnet_SetPassword r2; struct samr_GetUserPwInfo pwp; - struct samr_String samr_account_name; + struct lsa_String samr_account_name; uint32_t acct_flags; uint32_t rid, access_granted; @@ -171,7 +171,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, /* prepare samr_LookupNames */ ln.in.domain_handle = &d_handle; ln.in.num_names = 1; - ln.in.names = talloc_array(mem_ctx, struct samr_String, 1); + ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1); if (!ln.in.names) { r->samr.out.error_string = "Out of Memory"; return NT_STATUS_NO_MEMORY; -- cgit From 96ead1a02b9cd5d8dbaf448322d4d3a15300e0f0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 9 Jul 2005 01:54:28 +0000 Subject: r8248: Make these comments more accurate. Andrew Bartlett (This used to be commit 00e1cf79410eb7d31958ba272d87eb2d379c3613) --- source4/libnet/libnet_join.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 53b6db51b1..4910f6b4ff 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -69,14 +69,14 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, uint32_t rid, access_granted; int policy_min_pw_len = 0; - /* prepare connect to the SAMR pipe of users domain PDC */ + /* prepare connect to the SAMR pipe of PDC */ c.level = LIBNET_RPC_CONNECT_PDC; c.in.domain_name = r->samr.in.domain_name; c.in.dcerpc_iface_name = DCERPC_SAMR_NAME; c.in.dcerpc_iface_uuid = DCERPC_SAMR_UUID; c.in.dcerpc_iface_version = DCERPC_SAMR_VERSION; - /* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */ + /* 1. connect to the SAMR pipe of the PDC */ status = libnet_RpcConnect(ctx, mem_ctx, &c); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, @@ -237,7 +237,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, goto disconnect; } - /* prepare samr_SetUserInfo level 23 */ + /* prepare samr_QueryUserInfo (get flags) */ qui.in.user_handle = &u_handle; qui.in.level = 16; @@ -257,7 +257,8 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, r->samr.in.account_name, nt_errstr(status)); goto disconnect; } - + + /* Possibly change account type */ if ((qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) != r->samr.in.acct_type) { acct_flags = (qui.out.info->info16.acct_flags & ~(ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) @@ -268,6 +269,7 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, acct_flags = (acct_flags & ~ACB_DISABLED); + /* reset flags (if required) */ if (acct_flags != qui.out.info->info16.acct_flags) { ZERO_STRUCT(u_info); u_info.info16.acct_flags = acct_flags; -- cgit From 6cec8025b05595d60c23d70f34db9e65ca21b89d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Jul 2005 10:58:05 +0000 Subject: r8847: Rework the Samba4 'net join' code. I'm trying to get this closer to what WinXP does when joining an AD domain, but in the meantime this removes the excess unions, and uses the LSA pipe in same way XP does. Andrew Bartlett (This used to be commit d2789c426090c325f6535cdce380ac0f4e22c3c7) --- source4/libnet/libnet_join.c | 507 +++++++++++++++++++++++++------------------ 1 file changed, 297 insertions(+), 210 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 4910f6b4ff..f12f165a7b 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -22,7 +22,7 @@ #include "includes.h" #include "libnet/libnet.h" #include "librpc/gen_ndr/ndr_samr.h" -#include "lib/crypto/crypto.h" +#include "librpc/gen_ndr/ndr_lsa.h" #include "lib/ldb/include/ldb.h" #include "include/secrets.h" @@ -43,15 +43,23 @@ * * 7. do a samrSetUserInfo to set the account flags */ -static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, - TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) +NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_JoinDomain *r) { + TALLOC_CTX *tmp_ctx; + NTSTATUS 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 dcerpc_pipe *samr_pipe; struct samr_Connect sc; struct policy_handle p_handle; - struct samr_LookupDomain ld; - struct lsa_String d_name; struct samr_OpenDomain od; struct policy_handle d_handle; struct samr_LookupNames ln; @@ -69,21 +77,148 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, uint32_t rid, access_granted; int policy_min_pw_len = 0; - /* prepare connect to the SAMR pipe of PDC */ + struct dom_sid *domain_sid; + const char *domain_name; + const char *realm = NULL; /* Also flag for remote being AD */ + + tmp_ctx = talloc_named(mem_ctx, 0, "libnet_Join temp context"); + if (!tmp_ctx) { + r->out.error_string = NULL; + return NT_STATUS_NO_MEMORY; + } + + + /* prepare connect to the LSA pipe of PDC */ c.level = LIBNET_RPC_CONNECT_PDC; - c.in.domain_name = r->samr.in.domain_name; - c.in.dcerpc_iface_name = DCERPC_SAMR_NAME; - c.in.dcerpc_iface_uuid = DCERPC_SAMR_UUID; - c.in.dcerpc_iface_version = DCERPC_SAMR_VERSION; + c.in.domain_name = r->in.domain_name; + c.in.dcerpc_iface_name = DCERPC_LSARPC_NAME; + c.in.dcerpc_iface_uuid = DCERPC_LSARPC_UUID; + c.in.dcerpc_iface_version = DCERPC_LSARPC_VERSION; + + /* connect to the LSA pipe of the PDC */ + status = libnet_RpcConnect(ctx, tmp_ctx, &c); + if (!NT_STATUS_IS_OK(status)) { + 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)); + talloc_free(tmp_ctx); + return status; + } + + + /* 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, "\\%s", lp_netbios_name()); + lsa_open_policy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + lsa_open_policy.out.handle = &lsa_p_handle; + + status = dcerpc_lsa_OpenPolicy2(c.out.dcerpc_pipe, tmp_ctx, &lsa_open_policy); + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string = talloc_asprintf(mem_ctx, + "lsa_OpenPolicy2 failed: %s", + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } - /* 1. connect to the SAMR pipe of the PDC */ - status = libnet_RpcConnect(ctx, mem_ctx, &c); + lsa_query_info2.in.handle = &lsa_p_handle; + lsa_query_info2.in.level = LSA_POLICY_INFO_DNS; + + status = dcerpc_lsa_QueryInfoPolicy2(c.out.dcerpc_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; + } + + lsa_query_info.in.handle = &lsa_p_handle; + lsa_query_info.in.level = LSA_POLICY_INFO_DOMAIN; + + status = dcerpc_lsa_QueryInfoPolicy(c.out.dcerpc_pipe, tmp_ctx, + &lsa_query_info); + if (!NT_STATUS_IS_OK(status)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, - "Connection to SAMR pipe of PDC of domain '%s' failed: %s\n", - r->samr.in.domain_name, nt_errstr(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; + + r->out.domain_sid = talloc_steal(mem_ctx, domain_sid); + r->out.domain_name = talloc_steal(mem_ctx, domain_name); + r->out.realm = talloc_steal(mem_ctx, realm); + + /* + step 1 - establish a SAMR connection, on the same CIFS transport + */ + + /* Find the original binding string */ + status = dcerpc_parse_binding(tmp_ctx, c.out.dcerpc_pipe->conn->binding_string, &samr_binding); + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string + = talloc_asprintf(mem_ctx, + "Failed to parse dcerpc binding '%s'", + c.out.dcerpc_pipe->conn->binding_string); + talloc_free(tmp_ctx); + return status; + } + + /* Make binding string for samr, not the other pipe */ + status = dcerpc_epm_map_binding(tmp_ctx, samr_binding, + DCERPC_SAMR_UUID, DCERPC_SAMR_VERSION, + c.out.dcerpc_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(c.out.dcerpc_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; + } + + status = dcerpc_pipe_auth(samr_pipe, samr_binding, DCERPC_SAMR_UUID, + DCERPC_SAMR_VERSION, ctx->cred); + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string = talloc_asprintf(mem_ctx, + "SAMR bind failed: %s", + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } /* prepare samr_Connect */ ZERO_STRUCT(p_handle); @@ -92,109 +227,93 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, sc.out.connect_handle = &p_handle; /* 2. do a samr_Connect to get a policy handle */ - status = dcerpc_samr_Connect(c.out.dcerpc_pipe, mem_ctx, &sc); + status = dcerpc_samr_Connect(samr_pipe, tmp_ctx, &sc); if (!NT_STATUS_IS_OK(status)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, + r->out.error_string = talloc_asprintf(mem_ctx, "samr_Connect failed: %s\n", nt_errstr(status)); - goto disconnect; + talloc_free(tmp_ctx); + return status; } /* check result of samr_Connect */ if (!NT_STATUS_IS_OK(sc.out.result)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, + r->out.error_string = talloc_asprintf(mem_ctx, "samr_Connect failed: %s\n", nt_errstr(sc.out.result)); status = sc.out.result; - goto disconnect; - } - - /* prepare samr_LookupDomain */ - d_name.string = r->samr.in.domain_name; - ld.in.connect_handle = &p_handle; - ld.in.domain_name = &d_name; - - /* 3. do a samr_LookupDomain to get the domain sid */ - status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld); - if (!NT_STATUS_IS_OK(status)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, - "samr_LookupDomain for [%s] failed: %s\n", - r->samr.in.domain_name, nt_errstr(status)); - goto disconnect; - } - - /* check result of samr_LookupDomain */ - if (!NT_STATUS_IS_OK(ld.out.result)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, - "samr_LookupDomain for [%s] failed: %s\n", - r->samr.in.domain_name, nt_errstr(ld.out.result)); - status = ld.out.result; - goto disconnect; + talloc_free(tmp_ctx); + return status; } /* prepare samr_OpenDomain */ ZERO_STRUCT(d_handle); od.in.connect_handle = &p_handle; od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - od.in.sid = ld.out.sid; + od.in.sid = domain_sid; od.out.domain_handle = &d_handle; /* 4. do a samr_OpenDomain to get a domain handle */ - status = dcerpc_samr_OpenDomain(c.out.dcerpc_pipe, mem_ctx, &od); + status = dcerpc_samr_OpenDomain(samr_pipe, tmp_ctx, &od); if (!NT_STATUS_IS_OK(status)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, + r->out.error_string = talloc_asprintf(mem_ctx, "samr_OpenDomain for [%s] failed: %s\n", - r->samr.in.domain_name, nt_errstr(status)); - goto disconnect; + r->in.domain_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; } /* prepare samr_CreateUser2 */ ZERO_STRUCT(u_handle); cu.in.domain_handle = &d_handle; cu.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - samr_account_name.string = r->samr.in.account_name; + samr_account_name.string = r->in.account_name; cu.in.account_name = &samr_account_name; - cu.in.acct_flags = r->samr.in.acct_type; + cu.in.acct_flags = r->in.acct_type; cu.out.user_handle = &u_handle; cu.out.rid = &rid; cu.out.access_granted = &access_granted; /* 4. do a samr_CreateUser2 to get an account handle, or an error */ - status = dcerpc_samr_CreateUser2(c.out.dcerpc_pipe, mem_ctx, &cu); + status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, + r->out.error_string = talloc_asprintf(mem_ctx, "samr_CreateUser2 for [%s] failed: %s\n", - r->samr.in.domain_name, nt_errstr(status)); - goto disconnect; + r->in.domain_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { /* prepare samr_LookupNames */ ln.in.domain_handle = &d_handle; ln.in.num_names = 1; - ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1); + ln.in.names = talloc_array(tmp_ctx, struct lsa_String, 1); if (!ln.in.names) { - r->samr.out.error_string = "Out of Memory"; + r->out.error_string = NULL; + talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - ln.in.names[0].string = r->samr.in.account_name; + ln.in.names[0].string = r->in.account_name; /* 5. do a samr_LookupNames to get the users rid */ - status = dcerpc_samr_LookupNames(c.out.dcerpc_pipe, mem_ctx, &ln); + status = dcerpc_samr_LookupNames(samr_pipe, tmp_ctx, &ln); if (!NT_STATUS_IS_OK(status)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, - "samr_LookupNames for [%s] failed: %s\n", - r->samr.in.account_name, nt_errstr(status)); - goto disconnect; + r->out.error_string = talloc_asprintf(mem_ctx, + "samr_LookupNames for [%s] failed: %s\n", + r->in.account_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; } /* check if we got one RID for the user */ if (ln.out.rids.count != 1) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, - "samr_LookupNames for [%s] returns %d RIDs\n", - r->samr.in.account_name, ln.out.rids.count); + r->out.error_string = talloc_asprintf(mem_ctx, + "samr_LookupNames for [%s] returns %d RIDs\n", + r->in.account_name, ln.out.rids.count); status = NT_STATUS_INVALID_PARAMETER; - goto disconnect; + talloc_free(tmp_ctx); + return status; } /* prepare samr_OpenUser */ @@ -205,64 +324,68 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, ou.out.user_handle = &u_handle; /* 6. do a samr_OpenUser to get a user handle */ - status = dcerpc_samr_OpenUser(c.out.dcerpc_pipe, mem_ctx, &ou); + status = dcerpc_samr_OpenUser(samr_pipe, tmp_ctx, &ou); if (!NT_STATUS_IS_OK(status)) { - r->samr.out.error_string = talloc_asprintf(mem_ctx, - "samr_OpenUser for [%s] failed: %s\n", - r->samr.in.account_name, nt_errstr(status)); - goto disconnect; + r->out.error_string = talloc_asprintf(mem_ctx, + "samr_OpenUser for [%s] failed: %s\n", + r->in.account_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; } } pwp.in.user_handle = &u_handle; - status = dcerpc_samr_GetUserPwInfo(c.out.dcerpc_pipe, mem_ctx, &pwp); + status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp); if (NT_STATUS_IS_OK(status)) { policy_min_pw_len = pwp.out.info.min_password_length; } - r->samr.out.join_password = generate_random_str(mem_ctx, MAX(8, policy_min_pw_len)); + r->out.join_password = generate_random_str(mem_ctx, MAX(8, policy_min_pw_len)); r2.samr_handle.level = LIBNET_SET_PASSWORD_SAMR_HANDLE; - r2.samr_handle.in.account_name = r->samr.in.account_name; - r2.samr_handle.in.newpassword = r->samr.out.join_password; + r2.samr_handle.in.account_name = r->in.account_name; + r2.samr_handle.in.newpassword = r->out.join_password; r2.samr_handle.in.user_handle = &u_handle; - r2.samr_handle.in.dcerpc_pipe = c.out.dcerpc_pipe; + r2.samr_handle.in.dcerpc_pipe = samr_pipe; - status = libnet_SetPassword(ctx, mem_ctx, &r2); + status = libnet_SetPassword(ctx, tmp_ctx, &r2); - r->samr.out.error_string = r2.samr_handle.out.error_string; + r->out.error_string = r2.samr_handle.out.error_string; if (!NT_STATUS_IS_OK(status)) { - goto disconnect; + talloc_free(tmp_ctx); + return status; } /* prepare samr_QueryUserInfo (get flags) */ qui.in.user_handle = &u_handle; qui.in.level = 16; - status = dcerpc_samr_QueryUserInfo(c.out.dcerpc_pipe, mem_ctx, &qui); + status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui); if (!NT_STATUS_IS_OK(status)) { - r->samr.out.error_string + r->out.error_string = talloc_asprintf(mem_ctx, "samr_QueryUserInfo for [%s] failed: %s\n", - r->samr.in.account_name, nt_errstr(status)); - goto disconnect; + r->in.account_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; } if (!qui.out.info) { status = NT_STATUS_INVALID_PARAMETER; - r->samr.out.error_string + r->out.error_string = talloc_asprintf(mem_ctx, "samr_QueryUserInfo failed to return qui.out.info for [%s]: %s\n", - r->samr.in.account_name, nt_errstr(status)); - goto disconnect; + r->in.account_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; } /* Possibly change account type */ if ((qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) - != r->samr.in.acct_type) { + != r->in.acct_type) { acct_flags = (qui.out.info->info16.acct_flags & ~(ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) - | r->samr.in.acct_type; + | r->in.acct_type; } else { acct_flags = qui.out.info->info16.acct_flags; } @@ -278,66 +401,43 @@ static NTSTATUS libnet_JoinDomain_samr(struct libnet_context *ctx, sui.in.info = &u_info; sui.in.level = 16; - dcerpc_samr_SetUserInfo(c.out.dcerpc_pipe, mem_ctx, &sui); + dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui); if (!NT_STATUS_IS_OK(status)) { - r->samr.out.error_string + r->out.error_string = talloc_asprintf(mem_ctx, "samr_SetUserInfo for [%s] failed to remove ACB_DISABLED flag: %s\n", - r->samr.in.account_name, nt_errstr(status)); - goto disconnect; + r->in.account_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; } } -disconnect: - /* close connection */ - talloc_free(c.out.dcerpc_pipe); - - return status; -} - -static NTSTATUS libnet_JoinDomain_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) -{ - NTSTATUS status; - union libnet_JoinDomain r2; - - r2.samr.level = LIBNET_JOIN_DOMAIN_SAMR; - r2.samr.in.account_name = r->generic.in.account_name; - r2.samr.in.domain_name = r->generic.in.domain_name; - r2.samr.in.acct_type = r->generic.in.acct_type; - - status = libnet_JoinDomain(ctx, mem_ctx, &r2); - - r->generic.out.error_string = r2.samr.out.error_string; - r->generic.out.join_password = r2.samr.out.join_password; - - return status; -} - -NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_JoinDomain *r) -{ - switch (r->generic.level) { - case LIBNET_JOIN_DOMAIN_GENERIC: - return libnet_JoinDomain_generic(ctx, mem_ctx, r); - case LIBNET_JOIN_DOMAIN_SAMR: - return libnet_JoinDomain_samr(ctx, mem_ctx, r); + /* Now, if it was AD, then we want to start looking changing a + * few more things */ + if (!realm) { + talloc_free(tmp_ctx); + return NT_STATUS_OK; } + + + /* close connection */ + talloc_free(tmp_ctx); - return NT_STATUS_INVALID_LEVEL; + return NT_STATUS_OK; } - static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, - union libnet_Join *r) + struct libnet_Join *r) { NTSTATUS status; int ret; struct ldb_context *ldb; - union libnet_JoinDomain r2; + struct libnet_JoinDomain r2; const char *base_dn = "cn=Primary Domains"; const struct ldb_val *prior_secret; - const char *prior_modified_time; + const struct ldb_val *prior_modified_time; struct ldb_message **msgs, *msg; char *sct; const char *attrs[] = { @@ -348,21 +448,19 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, NULL }; - r2.generic.level = LIBNET_JOIN_DOMAIN_GENERIC; - - if (r->generic.in.secure_channel_type == SEC_CHAN_BDC) { - r2.generic.in.acct_type = ACB_SVRTRUST; - } else if (r->generic.in.secure_channel_type == SEC_CHAN_WKSTA) { - r2.generic.in.acct_type = ACB_WSTRUST; + if (r->in.secure_channel_type == SEC_CHAN_BDC) { + r2.in.acct_type = ACB_SVRTRUST; + } else if (r->in.secure_channel_type == SEC_CHAN_WKSTA) { + r2.in.acct_type = ACB_WSTRUST; } - r2.generic.in.domain_name = r->generic.in.domain_name; + r2.in.domain_name = r->in.domain_name; - r2.generic.in.account_name = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name()); + r2.in.account_name = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name()); /* Local secrets are stored in secrets.ldb */ ldb = secrets_db_connect(mem_ctx); if (!ldb) { - r->generic.out.error_string + r->out.error_string = talloc_asprintf(mem_ctx, "Could not open secrets database\n"); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; @@ -371,107 +469,96 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, /* join domain */ status = libnet_JoinDomain(ctx, mem_ctx, &r2); - r->generic.out.error_string = r2.generic.out.error_string; + r->out.error_string = r2.out.error_string; if (!NT_STATUS_IS_OK(status)) { return status; } - sct = talloc_asprintf(mem_ctx, "%d", r->generic.in.secure_channel_type); + sct = talloc_asprintf(mem_ctx, "%d", r->in.secure_channel_type); msg = ldb_msg_new(mem_ctx); /* search for the secret record */ ret = gendb_search(ldb, mem_ctx, base_dn, &msgs, attrs, - SECRETS_PRIMARY_DOMAIN_FILTER, - r->generic.in.domain_name); + "(|" SECRETS_PRIMARY_DOMAIN_FILTER "(realm=%s))", + r2.out.domain_name, r2.out.realm); + + msg->dn = talloc_asprintf(mem_ctx, "flatname=%s,%s", + r2.out.domain_name, + base_dn); + + samdb_msg_add_string(ldb, mem_ctx, msg, "flatname", r2.out.domain_name); + if (r2.out.realm) { + samdb_msg_add_string(ldb, mem_ctx, msg, "realm", r2.out.realm); + } + samdb_msg_add_string(ldb, mem_ctx, msg, "objectClass", "primaryDomain"); + samdb_msg_add_string(ldb, mem_ctx, msg, "secret", r2.out.join_password); + + samdb_msg_add_string(ldb, mem_ctx, msg, "samAccountName", r2.in.account_name); + + samdb_msg_add_string(ldb, mem_ctx, msg, "secureChannelType", sct); + + if (ret == 0) { - msg->dn = talloc_asprintf(mem_ctx, "flatname=%s,%s", - r->generic.in.domain_name, - base_dn); - - samdb_msg_add_string(ldb, mem_ctx, msg, "flatname", r->generic.in.domain_name); - samdb_msg_add_string(ldb, mem_ctx, msg, "objectClass", "primaryDomain"); - samdb_msg_add_string(ldb, mem_ctx, msg, "secret", r2.generic.out.join_password); - - samdb_msg_add_string(ldb, mem_ctx, msg, "samAccountName", r2.generic.in.account_name); - - samdb_msg_add_string(ldb, mem_ctx, msg, "secureChannelType", sct); - - /* create the secret */ - ret = samdb_add(ldb, mem_ctx, msg); - if (ret != 0) { - r->generic.out.error_string - = talloc_asprintf(mem_ctx, - "Failed to create secret record %s\n", - msg->dn); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - return NT_STATUS_OK; - } else if (ret != 1) { - r->generic.out.error_string + } else if (ret == -1) { + r->out.error_string = talloc_asprintf(mem_ctx, - "Found %d records matching cn=%s under DN %s\n", ret, - r->generic.in.domain_name, base_dn); + "Search for domain: %s and realm: %s failed: %s", + r2.out.domain_name, r2.out.realm, ldb_errstring(ldb)); return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - msg->dn = msgs[0]->dn; + } else { + 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) { - samdb_msg_set_value(ldb, mem_ctx, msg, "priorSecret", prior_secret); - } - samdb_msg_set_string(ldb, mem_ctx, msg, "secret", r2.generic.out.join_password); - - prior_modified_time = ldb_msg_find_string(msgs[0], - "whenChanged", NULL); - if (prior_modified_time) { - samdb_msg_set_string(ldb, mem_ctx, msg, "priorWhenChanged", - prior_modified_time); + prior_secret = ldb_msg_find_ldb_val(msgs[0], "secret"); + if (prior_secret) { + samdb_msg_set_value(ldb, mem_ctx, msg, "priorSecret", prior_secret); + } + samdb_msg_set_string(ldb, mem_ctx, msg, "secret", r2.out.join_password); + + prior_modified_time = ldb_msg_find_ldb_val(msgs[0], + "whenChanged"); + if (prior_modified_time) { + samdb_msg_set_value(ldb, mem_ctx, msg, "priorWhenChanged", + prior_modified_time); + } + + samdb_msg_set_string(ldb, mem_ctx, msg, "samAccountName", r2.in.account_name); + samdb_msg_set_string(ldb, mem_ctx, msg, "secureChannelType", sct); } - - samdb_msg_set_string(ldb, mem_ctx, msg, "samAccountName", r2.generic.in.account_name); - samdb_msg_set_string(ldb, mem_ctx, msg, "secureChannelType", sct); - /* update the secret */ - ret = samdb_replace(ldb, mem_ctx, msg); + /* create the secret */ + ret = samdb_add(ldb, mem_ctx, msg); if (ret != 0) { - DEBUG(0,("Failed to create secret record %s\n", msg->dn)); + r->out.error_string + = talloc_asprintf(mem_ctx, + "Failed to create secret record %s\n", + msg->dn); return NT_STATUS_INTERNAL_DB_CORRUPTION; } return NT_STATUS_OK; } -NTSTATUS libnet_Join_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_Join *r) +NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Join *r) { NTSTATUS nt_status; - union libnet_Join r2; - r2.generic.in.secure_channel_type = r->generic.in.secure_channel_type; - r2.generic.in.domain_name = r->generic.in.domain_name; + struct libnet_Join r2; + r2.in.secure_channel_type = r->in.secure_channel_type; + r2.in.domain_name = r->in.domain_name; - if ((r->generic.in.secure_channel_type == SEC_CHAN_WKSTA) - || (r->generic.in.secure_channel_type == SEC_CHAN_BDC)) { - r2.generic.level = LIBNET_JOIN_PRIMARY; - nt_status = libnet_Join(ctx, mem_ctx, &r2); + if ((r->in.secure_channel_type == SEC_CHAN_WKSTA) + || (r->in.secure_channel_type == SEC_CHAN_BDC)) { + nt_status = libnet_Join_primary_domain(ctx, mem_ctx, &r2); } else { - r->generic.out.error_string + r->out.error_string = talloc_asprintf(mem_ctx, "Invalid secure channel type specified (%08X) attempting to join domain %s", - r->generic.in.secure_channel_type, r->generic.in.domain_name); + r->in.secure_channel_type, r->in.domain_name); return NT_STATUS_INVALID_PARAMETER; } - r->generic.out.error_string = r2.generic.out.error_string; + r->out.error_string = r2.out.error_string; return nt_status; } -NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_Join *r) -{ - switch (r->generic.level) { - case LIBNET_JOIN_GENERIC: - return libnet_Join_generic(ctx, mem_ctx, r); - case LIBNET_JOIN_PRIMARY: - return libnet_Join_primary_domain(ctx, mem_ctx, r); - } - - return NT_STATUS_INVALID_LEVEL; -} -- cgit From 50468b3dfeafb086b7b87efab25c92c167750378 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 2 Aug 2005 21:21:43 +0000 Subject: r8952: Partial work commit to find the DN of the new machine account - we will use ldb to add servicePrincipalNames to this. Andrew Bartlett (This used to be commit c1f8cab3e3d3eaf4af372675656fe1a4da68a9f8) --- source4/libnet/libnet_join.c | 109 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index f12f165a7b..e98217bd35 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -23,6 +23,7 @@ #include "libnet/libnet.h" #include "librpc/gen_ndr/ndr_samr.h" #include "librpc/gen_ndr/ndr_lsa.h" +#include "librpc/gen_ndr/ndr_drsuapi.h" #include "lib/ldb/include/ldb.h" #include "include/secrets.h" @@ -73,6 +74,14 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct samr_GetUserPwInfo pwp; struct lsa_String samr_account_name; + struct dcerpc_pipe *drsuapi_pipe; + struct dcerpc_binding *drsuapi_binding; + struct drsuapi_DsBind r_drsuapi_bind; + struct drsuapi_DsCrackNames r_crack_names; + struct drsuapi_DsNameString names[1]; + struct policy_handle drsuapi_bind_handle; + struct GUID drsuapi_bind_guid; + uint32_t acct_flags; uint32_t rid, access_granted; int policy_min_pw_len = 0; @@ -80,6 +89,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct dom_sid *domain_sid; const char *domain_name; const char *realm = NULL; /* Also flag for remote being AD */ + const char *account_dn; tmp_ctx = talloc_named(mem_ctx, 0, "libnet_Join temp context"); if (!tmp_ctx) { @@ -418,7 +428,104 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru talloc_free(tmp_ctx); return NT_STATUS_OK; } - + + drsuapi_binding = talloc(tmp_ctx, struct dcerpc_binding); + *drsuapi_binding = *samr_binding; + drsuapi_binding->transport = NCACN_IP_TCP; + drsuapi_binding->endpoint = NULL; + drsuapi_binding->flags |= DCERPC_SEAL; + + status = dcerpc_pipe_connect_b(tmp_ctx, + &drsuapi_pipe, + drsuapi_binding, + DCERPC_DRSUAPI_UUID, + DCERPC_DRSUAPI_VERSION, + ctx->cred, + ctx->event_ctx); + + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string = talloc_asprintf(mem_ctx, + "Connection to DRSUAPI pipe of PDC of domain '%s' failed: %s", + r->in.domain_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + + GUID_from_string(DRSUAPI_DS_BIND_GUID, &drsuapi_bind_guid); + + r_drsuapi_bind.in.bind_guid = &drsuapi_bind_guid; + r_drsuapi_bind.in.bind_info = NULL; + r_drsuapi_bind.out.bind_handle = &drsuapi_bind_handle; + + status = dcerpc_drsuapi_DsBind(drsuapi_pipe, tmp_ctx, &r_drsuapi_bind); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { + r->out.error_string + = talloc_asprintf(mem_ctx, + "dcerpc_drsuapi_DsBind for [%s\\%s] failed - %s\n", + domain_name, r->in.account_name, + dcerpc_errstr(tmp_ctx, drsuapi_pipe->last_fault_code)); + talloc_free(tmp_ctx); + return status; + } else { + r->out.error_string + = talloc_asprintf(mem_ctx, + "dcerpc_drsuapi_DsBind for [%s\\%s] failed - %s\n", + domain_name, r->in.account_name, + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + } else if (!W_ERROR_IS_OK(r_crack_names.out.result)) { + r->out.error_string + = talloc_asprintf(mem_ctx, + "DsBind failed - %s\n", win_errstr(r_drsuapi_bind.out.result)); + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + 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.count = 1; + r_crack_names.in.req.req1.names = names; + r_crack_names.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS; + r_crack_names.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; + r_crack_names.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779; + names[0].str = talloc_asprintf(tmp_ctx, "%s\\%s", domain_name, r->in.account_name); + + status = dcerpc_drsuapi_DsCrackNames(drsuapi_pipe, tmp_ctx, &r_crack_names); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { + r->out.error_string + = talloc_asprintf(mem_ctx, + "dcerpc_drsuapi_DsCrackNames for [%s\\%s] failed - %s\n", + domain_name, r->in.account_name, + dcerpc_errstr(tmp_ctx, drsuapi_pipe->last_fault_code)); + talloc_free(tmp_ctx); + return status; + } else { + r->out.error_string + = talloc_asprintf(mem_ctx, + "dcerpc_drsuapi_DsCrackNames for [%s\\%s] failed - %s\n", + domain_name, r->in.account_name, + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + } else if (!W_ERROR_IS_OK(r_crack_names.out.result)) { + r->out.error_string + = talloc_asprintf(mem_ctx, + "DsCrackNames failed - %s\n", win_errstr(r_crack_names.out.result)); + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + account_dn = r_crack_names.out.ctr.ctr1->array[0].result_name; + + printf("Account DN is: %s\n", account_dn); /* close connection */ talloc_free(tmp_ctx); -- cgit From 1af653752073098af31191499c8f49c9a431e5dd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 3 Aug 2005 00:59:35 +0000 Subject: r8970: Add 'ADS' join support to Samba4. We now fill in the servicePrincipalName over LDAP, just like XP does, and store the kvno in our local db. Andrew Bartlett (This used to be commit 5547c4e6f6a0c163aa38fa4d4ed8c627ae12bf80) --- source4/libnet/libnet_join.c | 74 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index e98217bd35..d0008de7d7 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -82,6 +82,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct policy_handle drsuapi_bind_handle; struct GUID drsuapi_bind_guid; + struct ldb_context *remote_ldb; + uint32_t acct_flags; uint32_t rid, access_granted; int policy_min_pw_len = 0; @@ -91,6 +93,17 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru const char *realm = NULL; /* Also flag for remote being AD */ const char *account_dn; + char *remote_ldb_url; + struct ldb_message **msgs, *msg; + int ldb_ret; + + const char *attrs[] = { + "msDS-KeyVersionNumber", + "servicePrincipalName", + "dNSHostName", + NULL, + }; + tmp_ctx = talloc_named(mem_ctx, 0, "libnet_Join temp context"); if (!tmp_ctx) { r->out.error_string = NULL; @@ -476,7 +489,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru talloc_free(tmp_ctx); return status; } - } else if (!W_ERROR_IS_OK(r_crack_names.out.result)) { + } else if (!W_ERROR_IS_OK(r_drsuapi_bind.out.result)) { r->out.error_string = talloc_asprintf(mem_ctx, "DsBind failed - %s\n", win_errstr(r_drsuapi_bind.out.result)); @@ -525,8 +538,57 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru account_dn = r_crack_names.out.ctr.ctr1->array[0].result_name; - printf("Account DN is: %s\n", account_dn); - + remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s", + drsuapi_binding->host); + remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, 0, NULL); + + if (!remote_ldb) { + return NT_STATUS_UNSUCCESSFUL; + } + + /* search for the secret record */ + ldb_ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, + NULL, attrs, &msgs); + + if (ldb_ret != 1) { + r->out.error_string + = talloc_asprintf(mem_ctx, + "ldb_search for %s failed - %s\n", + account_dn, + ldb_errstring(remote_ldb)); + return NT_STATUS_UNSUCCESSFUL; + } + r->out.kvno = ldb_msg_find_uint(msgs[0], "msDS-KeyVersionNumber", 0); + + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + return NT_STATUS_NO_MEMORY; + } + + msg->dn = msgs[0]->dn; + + { + char *service_principal_name[2]; + char *dns_host_name = strlower_talloc(mem_ctx, + talloc_asprintf(mem_ctx, + "%s.%s", lp_netbios_name(), realm)); + service_principal_name[0] = talloc_asprintf(tmp_ctx, "host/%s", dns_host_name); + service_principal_name[1] = talloc_asprintf(tmp_ctx, "host/%s", strlower_talloc(mem_ctx, lp_netbios_name())); + + samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "dNSHostName", dns_host_name); + samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[0]); + samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[1]); + + ldb_ret = samdb_replace(remote_ldb, tmp_ctx, msg); + if (ldb_ret != 0) { + r->out.error_string + = talloc_asprintf(mem_ctx, + "Failed to replace entries on %s\n", + msg->dn); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + /* close connection */ talloc_free(tmp_ctx); @@ -604,7 +666,11 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, samdb_msg_add_string(ldb, mem_ctx, msg, "samAccountName", r2.in.account_name); samdb_msg_add_string(ldb, mem_ctx, msg, "secureChannelType", sct); - + + if (r2.out.kvno) { + samdb_msg_add_uint(ldb, mem_ctx, msg, "msDS-KeyVersionNumber", + r2.out.kvno); + } if (ret == 0) { } else if (ret == -1) { -- cgit From 64cdbaf8f118b0cd6e8e9ce387a75dd9f374b58c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 3 Aug 2005 05:24:13 +0000 Subject: r8981: Add comments, fix typos (in attribute names) and check for errors in SamSync and 'net join'. Andrew Bartlett (This used to be commit 257240b0e29da14f7a2e660182b367304a5fa530) --- source4/libnet/libnet_join.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index d0008de7d7..b72577fa84 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -158,6 +158,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return 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; @@ -175,6 +177,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru 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; @@ -196,7 +200,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru r->out.realm = talloc_steal(mem_ctx, realm); /* - step 1 - establish a SAMR connection, on the same CIFS transport + establish a SAMR connection, on the same CIFS transport */ /* Find the original binding string */ @@ -357,13 +361,15 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } } + /* Find out what password policy this user has */ pwp.in.user_handle = &u_handle; status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp); if (NT_STATUS_IS_OK(status)) { policy_min_pw_len = pwp.out.info.min_password_length; } - + + /* Grab a password of that minimum length */ r->out.join_password = generate_random_str(mem_ctx, MAX(8, policy_min_pw_len)); r2.samr_handle.level = LIBNET_SET_PASSWORD_SAMR_HANDLE; @@ -436,12 +442,21 @@ 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 */ + * few more things. Otherwise, we are done. */ if (!realm) { + r->out.realm = NULL; + r->out.kvno = 0; talloc_free(tmp_ctx); return NT_STATUS_OK; } + /* We need to convert between a samAccountName and domain to a + * DN in the directory. The correct way to do this is with + * DRSUAPI CrackNames */ + + + /* Fiddle with the bindings, so get to DRSUAPI on + * NCACN_IP_TCP, sealed */ drsuapi_binding = talloc(tmp_ctx, struct dcerpc_binding); *drsuapi_binding = *samr_binding; drsuapi_binding->transport = NCACN_IP_TCP; @@ -464,6 +479,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } + /* get a DRSUAPI pipe handle */ GUID_from_string(DRSUAPI_DS_BIND_GUID, &drsuapi_bind_guid); r_drsuapi_bind.in.bind_guid = &drsuapi_bind_guid; @@ -497,6 +513,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return NT_STATUS_UNSUCCESSFUL; } + /* Actually 'crack' the names */ ZERO_STRUCT(r_crack_names); r_crack_names.in.bind_handle = &drsuapi_bind_handle; r_crack_names.in.level = 1; @@ -534,10 +551,21 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru "DsCrackNames failed - %s\n", 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].status != DRSUAPI_DS_NAME_STATUS_OK) { + + r->out.error_string = talloc_asprintf(mem_ctx, "DsCrackNames failed\n"); + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; } account_dn = r_crack_names.out.ctr.ctr1->array[0].result_name; + + /* 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); remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, 0, NULL); @@ -546,7 +574,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return NT_STATUS_UNSUCCESSFUL; } - /* search for the secret record */ + /* search for the user's record */ ldb_ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, NULL, attrs, &msgs); @@ -558,8 +586,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru ldb_errstring(remote_ldb)); return NT_STATUS_UNSUCCESSFUL; } + + /* If we have a kvno recorded in AD, we need it locally as well */ r->out.kvno = ldb_msg_find_uint(msgs[0], "msDS-KeyVersionNumber", 0); + /* Prepare a new message, for the modify */ msg = ldb_msg_new(tmp_ctx); if (!msg) { return NT_STATUS_NO_MEMORY; -- cgit From 3e4c4cff2177af33efdb15f03a1bbcb639505cee Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 18 Aug 2005 15:02:01 +0000 Subject: r9391: Convert all the code to use struct ldb_dn to ohandle ldap like distinguished names Provide more functions to handle DNs in this form (This used to be commit 692e35b7797e39533dd2a1c4b63d9da30f1eb5ba) --- source4/libnet/libnet_join.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index b72577fa84..cef74492b8 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -91,7 +91,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct dom_sid *domain_sid; const char *domain_name; const char *realm = NULL; /* Also flag for remote being AD */ - const char *account_dn; + const struct ldb_dn *account_dn; char *remote_ldb_url; struct ldb_message **msgs, *msg; @@ -561,8 +561,13 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return NT_STATUS_UNSUCCESSFUL; } - account_dn = r_crack_names.out.ctr.ctr1->array[0].result_name; - + account_dn = ldb_dn_explode(mem_ctx, r_crack_names.out.ctr.ctr1->array[0].result_name); + if (account_dn == NULL) { + r->out.error_string + = talloc_asprintf(mem_ctx, "Invalid account dn: %s", + r_crack_names.out.ctr.ctr1->array[0].result_name); + return NT_STATUS_UNSUCCESSFUL; + } /* Now we know the user's DN, open with LDAP, read and modify a few things */ @@ -581,8 +586,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru if (ldb_ret != 1) { r->out.error_string = talloc_asprintf(mem_ctx, - "ldb_search for %s failed - %s\n", - account_dn, + "ldb_search for %s failed - %s\n", + ldb_dn_linearize(mem_ctx, account_dn), ldb_errstring(remote_ldb)); return NT_STATUS_UNSUCCESSFUL; } @@ -615,7 +620,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru r->out.error_string = talloc_asprintf(mem_ctx, "Failed to replace entries on %s\n", - msg->dn); + ldb_dn_linearize(mem_ctx, msg->dn)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } } @@ -635,7 +640,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, struct ldb_context *ldb; struct libnet_JoinDomain r2; - const char *base_dn = "cn=Primary Domains"; + const struct ldb_dn *base_dn = ldb_dn_explode(mem_ctx, "cn=Primary Domains"); const struct ldb_val *prior_secret; const struct ldb_val *prior_modified_time; struct ldb_message **msgs, *msg; @@ -679,13 +684,12 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, /* search for the secret record */ ret = gendb_search(ldb, - mem_ctx, base_dn, &msgs, attrs, + mem_ctx, base_dn, + &msgs, attrs, "(|" SECRETS_PRIMARY_DOMAIN_FILTER "(realm=%s))", r2.out.domain_name, r2.out.realm); - msg->dn = talloc_asprintf(mem_ctx, "flatname=%s,%s", - r2.out.domain_name, - base_dn); + msg->dn = ldb_dn_build_child(mem_ctx, "flatname", r2.out.domain_name, base_dn); samdb_msg_add_string(ldb, mem_ctx, msg, "flatname", r2.out.domain_name); if (r2.out.realm) { @@ -739,7 +743,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, r->out.error_string = talloc_asprintf(mem_ctx, "Failed to create secret record %s\n", - msg->dn); + ldb_dn_linearize(ldb, msg->dn)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } return NT_STATUS_OK; -- cgit From 5a522b31003d50cf476ead83fb322abeb1525957 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Sep 2005 12:26:07 +0000 Subject: r10486: This is a merge of Brad Henry's 'net join' rework, to better perform an ADS join, particularly as a DC. This represents the bulk of his Google SOC work, and I'm very pleased to intergrate it into the tree. (Metze will intergrate the DRSUAPI work later). Both metze and myself have also put a lot of time into this patch, and in mentoring Brad in general. In return, Brad has been a very good student, and has taken the comments well. Since it's last appearance on samba-technical@, I have made correctness and valgrind fixups, as well as adding a new 'BINDING' mode to the libnet_rpc routines. This allows the exact binding string to be passed down from the torture code, including options and exact target host. Andrew Bartlett (This used to be commit d6fa105fdabbeb83a9b0e50dad49d1649afdb2a4) --- source4/libnet/libnet_join.c | 1251 +++++++++++++++++++++++++++++------------- 1 file changed, 882 insertions(+), 369 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index cef74492b8..3edad64259 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -3,6 +3,7 @@ Copyright (C) Stefan Metzmacher 2004 Copyright (C) Andrew Bartlett 2005 + Copyright (C) Brad Henry 2005 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 @@ -25,7 +26,485 @@ #include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "lib/ldb/include/ldb.h" +#include "libcli/cldap/cldap.h" #include "include/secrets.h" +#include "librpc/gen_ndr/drsuapi.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(remote_ldb, 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(remote_ldb, 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(remote_ldb, 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; + msg->elements->flags = LDB_FLAG_MOD_ADD; + + rtn = ldb_add(remote_ldb, msg); + if (rtn != 0) { + libnet_r->out.error_string + = talloc_asprintf(libnet_r, + "Failed to add server entry %s: %s.", + server_dn_str, + ldb_errstring(remote_ldb)); + 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; +} + +/* + * complete a domain join, when joining to a AD domain: + * 1.) connect and bind to the DRSUAPI pipe + * 2.) do a DsCrackNames() to find the machine account dn + * 3.) connect to LDAP + * 4.) do an ldap search to find the "msDS-KeyVersionNumber" of the machine account + * 5.) set the servicePrincipalName's of the machine account via LDAP, (maybe we should use DsWriteAccountSpn()...) + * 6.) do a DsCrackNames() to find the domain dn + * 7.) find out Site specific stuff, look at libnet_JoinSite() for details + */ +static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_JoinDomain *r) +{ + NTSTATUS status; + + TALLOC_CTX *tmp_ctx; + + const char *realm = r->out.realm; + + struct dcerpc_binding *samr_binding = r->out.samr_binding; + + struct dcerpc_pipe *drsuapi_pipe; + struct dcerpc_binding *drsuapi_binding; + struct drsuapi_DsBind r_drsuapi_bind; + struct drsuapi_DsCrackNames r_crack_names; + struct drsuapi_DsNameString names[1]; + struct policy_handle drsuapi_bind_handle; + struct GUID drsuapi_bind_guid; + + struct ldb_context *remote_ldb; + const struct ldb_dn *account_dn; + const char *account_dn_str; + const char *remote_ldb_url; + struct ldb_message **msgs, *msg; + + int rtn; + + unsigned int kvno; + + const char * const attrs[] = { + "msDS-KeyVersionNumber", + "servicePrincipalName", + "dNSHostName", + NULL, + }; + + r->out.error_string = NULL; + + /* We need to convert between a samAccountName and domain to a + * DN in the directory. The correct way to do this is with + * DRSUAPI CrackNames */ + + /* Fiddle with the bindings, so get to DRSUAPI on + * NCACN_IP_TCP, sealed */ + tmp_ctx = talloc_named(r, 0, "libnet_JoinADSDomain temp context"); + if (!tmp_ctx) { + r->out.error_string = NULL; + return NT_STATUS_NO_MEMORY; + } + + drsuapi_binding = talloc(tmp_ctx, struct dcerpc_binding); + if (!drsuapi_binding) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + *drsuapi_binding = *samr_binding; + drsuapi_binding->transport = NCACN_IP_TCP; + drsuapi_binding->endpoint = NULL; + drsuapi_binding->flags |= DCERPC_SEAL; + + status = dcerpc_pipe_connect_b(tmp_ctx, + &drsuapi_pipe, + drsuapi_binding, + DCERPC_DRSUAPI_UUID, + DCERPC_DRSUAPI_VERSION, + 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, + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + + /* get a DRSUAPI pipe handle */ + GUID_from_string(DRSUAPI_DS_BIND_GUID, &drsuapi_bind_guid); + + r_drsuapi_bind.in.bind_guid = &drsuapi_bind_guid; + r_drsuapi_bind.in.bind_info = NULL; + r_drsuapi_bind.out.bind_handle = &drsuapi_bind_handle; + + status = dcerpc_drsuapi_DsBind(drsuapi_pipe, tmp_ctx, &r_drsuapi_bind); + if (!NT_STATUS_IS_OK(status)) { + 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_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, + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + } else if (!W_ERROR_IS_OK(r_drsuapi_bind.out.result)) { + r->out.error_string + = talloc_asprintf(r, + "DsBind failed - %s\n", + win_errstr(r_drsuapi_bind.out.result)); + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + /* Actually 'crack' the names */ + 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.count = 1; + r_crack_names.in.req.req1.names = names; + r_crack_names.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS; + r_crack_names.in.req.req1.format_offered= DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY; + r_crack_names.in.req.req1.format_desired= DRSUAPI_DS_NAME_FORMAT_FQDN_1779; + names[0].str = dom_sid_string(tmp_ctx, r->out.account_sid); + if (!names[0].str) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + status = dcerpc_drsuapi_DsCrackNames(drsuapi_pipe, tmp_ctx, &r_crack_names); + if (!NT_STATUS_IS_OK(status)) { + 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", + names[0].str, + 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_DsCrackNames for [%s] failed - %s\n", + names[0].str, + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + } 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)); + 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"); + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + /* 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); + if (!remote_ldb_url) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, 0, NULL); + if (!remote_ldb) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + /* search for the user's record */ + rtn = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, + NULL, attrs, &msgs); + if (rtn != 1) { + r->out.error_string = talloc_asprintf(r, "ldb_search for %s failed - %s\n", + 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(msgs[0], "msDS-KeyVersionNumber", 0); + + /* Prepare a new message, for the modify */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + msg->dn = msgs[0]->dn; + + { + const char *service_principal_name[2]; + const char *dns_host_name = strlower_talloc(tmp_ctx, + talloc_asprintf(tmp_ctx, + "%s.%s", + r->in.netbios_name, + realm)); + + if (!dns_host_name) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + service_principal_name[0] = talloc_asprintf(tmp_ctx, "host/%s", dns_host_name); + if (!service_principal_name[0]) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + service_principal_name[1] = talloc_asprintf(tmp_ctx, "host/%s", strlower_talloc(tmp_ctx, r->in.netbios_name)); + if (!service_principal_name[1]) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + rtn = samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "dNSHostName", dns_host_name); + if (rtn == -1) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + rtn = samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[0]); + if (rtn == -1) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + rtn = samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[1]); + if (rtn == -1) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + rtn = samdb_replace(remote_ldb, tmp_ctx, msg); + if (rtn != 0) { + r->out.error_string + = talloc_asprintf(r, + "Failed to replace entries on %s\n", + ldb_dn_linearize(tmp_ctx, msg->dn)); + talloc_free(tmp_ctx); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + + /* DsCrackNames to find out the DN of the domain. */ + r_crack_names.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; + r_crack_names.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779; + names[0].str = talloc_asprintf(tmp_ctx, "%s\\", r->out.domain_name); + if (!names[0].str) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + status = dcerpc_drsuapi_DsCrackNames(drsuapi_pipe, tmp_ctx, &r_crack_names); + if (!NT_STATUS_IS_OK(status)) { + 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", + r->in.domain_name, + 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_DsCrackNames for [%s] failed - %s\n", + r->in.domain_name, + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + } 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)); + 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"); + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + /* Store the account DN. */ + r->out.account_dn_str = account_dn_str; + talloc_steal(r, account_dn_str); + + /* Store the domain DN. */ + 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; + + status = libnet_JoinSite(ctx, + drsuapi_pipe, drsuapi_bind_handle, + remote_ldb, r); + talloc_free(tmp_ctx); + + return status; +} /* * do a domain join using DCERPC/SAMR calls @@ -43,13 +522,15 @@ * 6. call libnet_SetPassword_samr_handle to set the password * * 7. do a samrSetUserInfo to set the account flags + * 8. 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) { TALLOC_CTX *tmp_ctx; - NTSTATUS status; - struct libnet_RpcConnect c; + NTSTATUS status, cu_status; + struct libnet_RpcConnect *c; struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; struct lsa_OpenPolicy2 lsa_open_policy; @@ -59,6 +540,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct dcerpc_binding *samr_binding; struct dcerpc_pipe *samr_pipe; + struct dcerpc_pipe *lsa_pipe; struct samr_Connect sc; struct policy_handle p_handle; struct samr_OpenDomain od; @@ -66,68 +548,78 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct samr_LookupNames ln; struct samr_OpenUser ou; struct samr_CreateUser2 cu; - struct policy_handle u_handle; + struct policy_handle *u_handle = NULL; struct samr_QueryUserInfo qui; struct samr_SetUserInfo sui; union samr_UserInfo u_info; union libnet_SetPassword r2; struct samr_GetUserPwInfo pwp; struct lsa_String samr_account_name; - - struct dcerpc_pipe *drsuapi_pipe; - struct dcerpc_binding *drsuapi_binding; - struct drsuapi_DsBind r_drsuapi_bind; - struct drsuapi_DsCrackNames r_crack_names; - struct drsuapi_DsNameString names[1]; - struct policy_handle drsuapi_bind_handle; - struct GUID drsuapi_bind_guid; - - struct ldb_context *remote_ldb; - + uint32_t acct_flags; uint32_t rid, access_granted; int policy_min_pw_len = 0; - struct dom_sid *domain_sid; - const char *domain_name; + 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 */ - const struct ldb_dn *account_dn; - - char *remote_ldb_url; - struct ldb_message **msgs, *msg; - int ldb_ret; - - const char *attrs[] = { - "msDS-KeyVersionNumber", - "servicePrincipalName", - "dNSHostName", - NULL, - }; - + + + r->out.error_string = NULL; + r2.samr_handle.out.error_string = NULL; + tmp_ctx = talloc_named(mem_ctx, 0, "libnet_Join temp context"); if (!tmp_ctx) { r->out.error_string = NULL; return NT_STATUS_NO_MEMORY; } - - + + u_handle = talloc(tmp_ctx, struct policy_handle); + if (!u_handle) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + samr_pipe = talloc(tmp_ctx, struct dcerpc_pipe); + if (!samr_pipe) { + 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 */ - c.level = LIBNET_RPC_CONNECT_PDC; - c.in.domain_name = r->in.domain_name; - c.in.dcerpc_iface_name = DCERPC_LSARPC_NAME; - c.in.dcerpc_iface_uuid = DCERPC_LSARPC_UUID; - c.in.dcerpc_iface_version = DCERPC_LSARPC_VERSION; - + if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) { + c->level = LIBNET_RPC_CONNECT_PDC; + c->in.domain_name = r->in.domain_name; + } else { + c->level = LIBNET_RPC_CONNECT_BINDING; + c->in.binding = r->in.binding; + } + c->in.dcerpc_iface_name = DCERPC_LSARPC_NAME; + c->in.dcerpc_iface_uuid = DCERPC_LSARPC_UUID; + c->in.dcerpc_iface_version = DCERPC_LSARPC_VERSION; + /* connect to the LSA pipe of the PDC */ - status = libnet_RpcConnect(ctx, tmp_ctx, &c); + + status = libnet_RpcConnect(ctx, c, c); if (!NT_STATUS_IS_OK(status)) { 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)); talloc_free(tmp_ctx); return status; - } - + } + lsa_pipe = c->out.dcerpc_pipe; /* Get an LSA policy handle */ @@ -145,11 +637,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru attr.sec_qos = &qos; lsa_open_policy.in.attr = &attr; - lsa_open_policy.in.system_name = talloc_asprintf(tmp_ctx, "\\%s", lp_netbios_name()); + + 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(c.out.dcerpc_pipe, tmp_ctx, &lsa_open_policy); + status = dcerpc_lsa_OpenPolicy2(lsa_pipe, tmp_ctx, &lsa_open_policy); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "lsa_OpenPolicy2 failed: %s", @@ -157,20 +656,20 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru talloc_free(tmp_ctx); return 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(c.out.dcerpc_pipe, tmp_ctx, + 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)); + "lsa_QueryInfoPolicy2 failed: %s", + nt_errstr(status)); talloc_free(tmp_ctx); return status; } @@ -182,57 +681,53 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru lsa_query_info.in.handle = &lsa_p_handle; lsa_query_info.in.level = LSA_POLICY_INFO_DOMAIN; - status = dcerpc_lsa_QueryInfoPolicy(c.out.dcerpc_pipe, tmp_ctx, + 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)); + "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; - - r->out.domain_sid = talloc_steal(mem_ctx, domain_sid); - r->out.domain_name = talloc_steal(mem_ctx, domain_name); - r->out.realm = talloc_steal(mem_ctx, realm); /* establish a SAMR connection, on the same CIFS transport */ /* Find the original binding string */ - status = dcerpc_parse_binding(tmp_ctx, c.out.dcerpc_pipe->conn->binding_string, &samr_binding); + status = dcerpc_parse_binding(tmp_ctx, lsa_pipe->conn->binding_string, &samr_binding); if (!NT_STATUS_IS_OK(status)) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "Failed to parse dcerpc binding '%s'", - c.out.dcerpc_pipe->conn->binding_string); + r->out.error_string = talloc_asprintf(mem_ctx, + "Failed to parse lsa binding '%s'", + lsa_pipe->conn->binding_string); talloc_free(tmp_ctx); return status; } /* Make binding string for samr, not the other pipe */ - status = dcerpc_epm_map_binding(tmp_ctx, samr_binding, + status = dcerpc_epm_map_binding(tmp_ctx, samr_binding, DCERPC_SAMR_UUID, DCERPC_SAMR_VERSION, - c.out.dcerpc_pipe->conn->event_ctx); + 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)); + 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(c.out.dcerpc_pipe, &samr_pipe, samr_binding); + 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)); + "SAMR secondary connection failed: %s", + nt_errstr(status)); talloc_free(tmp_ctx); return status; } @@ -241,11 +736,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru DCERPC_SAMR_VERSION, ctx->cred); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, - "SAMR bind failed: %s", - nt_errstr(status)); + "SAMR bind failed: %s", + nt_errstr(status)); talloc_free(tmp_ctx); return status; - } + } /* prepare samr_Connect */ ZERO_STRUCT(p_handle); @@ -257,7 +752,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru status = dcerpc_samr_Connect(samr_pipe, tmp_ctx, &sc); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, - "samr_Connect failed: %s\n", + "samr_Connect failed: %s", nt_errstr(status)); talloc_free(tmp_ctx); return status; @@ -266,13 +761,13 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* check result of samr_Connect */ if (!NT_STATUS_IS_OK(sc.out.result)) { r->out.error_string = talloc_asprintf(mem_ctx, - "samr_Connect failed: %s\n", + "samr_Connect failed: %s", nt_errstr(sc.out.result)); status = sc.out.result; talloc_free(tmp_ctx); return status; } - + /* prepare samr_OpenDomain */ ZERO_STRUCT(d_handle); od.in.connect_handle = &p_handle; @@ -281,32 +776,34 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru od.out.domain_handle = &d_handle; /* 4. do a samr_OpenDomain to get a domain handle */ - status = dcerpc_samr_OpenDomain(samr_pipe, tmp_ctx, &od); + 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\n", - r->in.domain_name, nt_errstr(status)); + "samr_OpenDomain for [%s] failed: %s", + r->in.domain_name, + nt_errstr(status)); talloc_free(tmp_ctx); return status; } - + /* prepare samr_CreateUser2 */ - ZERO_STRUCT(u_handle); + ZERO_STRUCTP(u_handle); cu.in.domain_handle = &d_handle; cu.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; samr_account_name.string = r->in.account_name; cu.in.account_name = &samr_account_name; cu.in.acct_flags = r->in.acct_type; - cu.out.user_handle = &u_handle; + cu.out.user_handle = u_handle; cu.out.rid = &rid; cu.out.access_granted = &access_granted; /* 4. do a samr_CreateUser2 to get an account handle, or an error */ - status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu); + cu_status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu); + status = cu_status; if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { 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\n", + r->in.domain_name, nt_errstr(status)); talloc_free(tmp_ctx); return status; @@ -326,13 +823,13 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru status = dcerpc_samr_LookupNames(samr_pipe, tmp_ctx, &ln); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, - "samr_LookupNames for [%s] failed: %s\n", - r->in.account_name, nt_errstr(status)); + "samr_LookupNames for [%s] failed: %s", + r->in.account_name, + nt_errstr(status)); talloc_free(tmp_ctx); return status; } - /* check if we got one RID for the user */ if (ln.out.rids.count != 1) { r->out.error_string = talloc_asprintf(mem_ctx, @@ -344,75 +841,76 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } /* prepare samr_OpenUser */ - ZERO_STRUCT(u_handle); + ZERO_STRUCTP(u_handle); ou.in.domain_handle = &d_handle; ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; ou.in.rid = ln.out.rids.ids[0]; - ou.out.user_handle = &u_handle; + rid = ou.in.rid; + ou.out.user_handle = u_handle; /* 6. do a samr_OpenUser to get a user handle */ - status = dcerpc_samr_OpenUser(samr_pipe, tmp_ctx, &ou); + status = dcerpc_samr_OpenUser(samr_pipe, tmp_ctx, &ou); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, - "samr_OpenUser for [%s] failed: %s\n", - r->in.account_name, nt_errstr(status)); + "samr_OpenUser for [%s] failed: %s", + r->in.account_name, + nt_errstr(status)); talloc_free(tmp_ctx); return status; } } - /* Find out what password policy this user has */ - pwp.in.user_handle = &u_handle; + pwp.in.user_handle = u_handle; - status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp); + status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp); if (NT_STATUS_IS_OK(status)) { policy_min_pw_len = pwp.out.info.min_password_length; } /* Grab a password of that minimum length */ - r->out.join_password = generate_random_str(mem_ctx, MAX(8, policy_min_pw_len)); + + password_str = generate_random_str(tmp_ctx, MAX(8, policy_min_pw_len)); r2.samr_handle.level = LIBNET_SET_PASSWORD_SAMR_HANDLE; - r2.samr_handle.in.account_name = r->in.account_name; - r2.samr_handle.in.newpassword = r->out.join_password; - r2.samr_handle.in.user_handle = &u_handle; - r2.samr_handle.in.dcerpc_pipe = samr_pipe; - - status = libnet_SetPassword(ctx, tmp_ctx, &r2); - - r->out.error_string = r2.samr_handle.out.error_string; + 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; + status = libnet_SetPassword(ctx, tmp_ctx, &r2); if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); + r->out.error_string = talloc_steal(mem_ctx, r2.samr_handle.out.error_string); + talloc_free(tmp_ctx); return status; } /* prepare samr_QueryUserInfo (get flags) */ - qui.in.user_handle = &u_handle; + qui.in.user_handle = u_handle; qui.in.level = 16; status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui); if (!NT_STATUS_IS_OK(status)) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "samr_QueryUserInfo for [%s] failed: %s\n", - r->in.account_name, nt_errstr(status)); - talloc_free(tmp_ctx); + r->out.error_string = talloc_asprintf(mem_ctx, + "samr_QueryUserInfo for [%s] failed: %s", + r->in.account_name, + nt_errstr(status)); + talloc_free(tmp_ctx); return status; } + if (!qui.out.info) { 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", r->in.account_name, nt_errstr(status)); - talloc_free(tmp_ctx); + talloc_free(tmp_ctx); return status; } - /* Possibly change account type */ - if ((qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) - != r->in.acct_type) { + /* Possibly change account type (if we are creating a new account) */ + if (((qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) + != r->in.acct_type) && (!NT_STATUS_EQUAL(cu_status, NT_STATUS_USER_EXISTS))) { acct_flags = (qui.out.info->info16.acct_flags & ~(ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) | r->in.acct_type; } else { @@ -422,212 +920,70 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru acct_flags = (acct_flags & ~ACB_DISABLED); /* reset flags (if required) */ - if (acct_flags != qui.out.info->info16.acct_flags) { + 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.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\n", - r->in.account_name, nt_errstr(status)); - talloc_free(tmp_ctx); - return status; - } - } - - /* Now, if it was AD, then we want to start looking changing a - * few more things. Otherwise, we are done. */ - if (!realm) { - r->out.realm = NULL; - r->out.kvno = 0; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* We need to convert between a samAccountName and domain to a - * DN in the directory. The correct way to do this is with - * DRSUAPI CrackNames */ - - - /* Fiddle with the bindings, so get to DRSUAPI on - * NCACN_IP_TCP, sealed */ - drsuapi_binding = talloc(tmp_ctx, struct dcerpc_binding); - *drsuapi_binding = *samr_binding; - drsuapi_binding->transport = NCACN_IP_TCP; - drsuapi_binding->endpoint = NULL; - drsuapi_binding->flags |= DCERPC_SEAL; - - status = dcerpc_pipe_connect_b(tmp_ctx, - &drsuapi_pipe, - drsuapi_binding, - DCERPC_DRSUAPI_UUID, - DCERPC_DRSUAPI_VERSION, - ctx->cred, - ctx->event_ctx); - - if (!NT_STATUS_IS_OK(status)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "Connection to DRSUAPI pipe of PDC of domain '%s' failed: %s", - r->in.domain_name, nt_errstr(status)); - talloc_free(tmp_ctx); - return status; - } - - /* get a DRSUAPI pipe handle */ - GUID_from_string(DRSUAPI_DS_BIND_GUID, &drsuapi_bind_guid); - - r_drsuapi_bind.in.bind_guid = &drsuapi_bind_guid; - r_drsuapi_bind.in.bind_info = NULL; - r_drsuapi_bind.out.bind_handle = &drsuapi_bind_handle; - - status = dcerpc_drsuapi_DsBind(drsuapi_pipe, tmp_ctx, &r_drsuapi_bind); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "dcerpc_drsuapi_DsBind for [%s\\%s] failed - %s\n", - domain_name, r->in.account_name, - dcerpc_errstr(tmp_ctx, drsuapi_pipe->last_fault_code)); - talloc_free(tmp_ctx); - return status; - } else { - r->out.error_string - = talloc_asprintf(mem_ctx, - "dcerpc_drsuapi_DsBind for [%s\\%s] failed - %s\n", - domain_name, r->in.account_name, - nt_errstr(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; } - } else if (!W_ERROR_IS_OK(r_drsuapi_bind.out.result)) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "DsBind failed - %s\n", win_errstr(r_drsuapi_bind.out.result)); - talloc_free(tmp_ctx); - return NT_STATUS_UNSUCCESSFUL; } - /* Actually 'crack' the names */ - 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.count = 1; - r_crack_names.in.req.req1.names = names; - r_crack_names.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS; - r_crack_names.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; - r_crack_names.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779; - names[0].str = talloc_asprintf(tmp_ctx, "%s\\%s", domain_name, r->in.account_name); - - status = dcerpc_drsuapi_DsCrackNames(drsuapi_pipe, tmp_ctx, &r_crack_names); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "dcerpc_drsuapi_DsCrackNames for [%s\\%s] failed - %s\n", - domain_name, r->in.account_name, - dcerpc_errstr(tmp_ctx, drsuapi_pipe->last_fault_code)); - talloc_free(tmp_ctx); - return status; - } else { - r->out.error_string - = talloc_asprintf(mem_ctx, - "dcerpc_drsuapi_DsCrackNames for [%s\\%s] failed - %s\n", - domain_name, r->in.account_name, - nt_errstr(status)); - talloc_free(tmp_ctx); - return status; - } - } else if (!W_ERROR_IS_OK(r_crack_names.out.result)) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "DsCrackNames failed - %s\n", 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].status != DRSUAPI_DS_NAME_STATUS_OK) { - - r->out.error_string = talloc_asprintf(mem_ctx, "DsCrackNames failed\n"); + account_sid = dom_sid_add_rid(mem_ctx, domain_sid, rid); + if (!account_sid) { + r->out.error_string = NULL; talloc_free(tmp_ctx); - return NT_STATUS_UNSUCCESSFUL; - } - - account_dn = ldb_dn_explode(mem_ctx, r_crack_names.out.ctr.ctr1->array[0].result_name); - if (account_dn == NULL) { - r->out.error_string - = talloc_asprintf(mem_ctx, "Invalid account dn: %s", - r_crack_names.out.ctr.ctr1->array[0].result_name); - 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); - remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, 0, NULL); - - if (!remote_ldb) { - return NT_STATUS_UNSUCCESSFUL; - } - - /* search for the user's record */ - ldb_ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, - NULL, attrs, &msgs); - - if (ldb_ret != 1) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "ldb_search for %s failed - %s\n", - ldb_dn_linearize(mem_ctx, account_dn), - ldb_errstring(remote_ldb)); - return NT_STATUS_UNSUCCESSFUL; - } - - /* If we have a kvno recorded in AD, we need it locally as well */ - r->out.kvno = ldb_msg_find_uint(msgs[0], "msDS-KeyVersionNumber", 0); - - /* Prepare a new message, for the modify */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { return NT_STATUS_NO_MEMORY; } - msg->dn = msgs[0]->dn; - - { - char *service_principal_name[2]; - char *dns_host_name = strlower_talloc(mem_ctx, - talloc_asprintf(mem_ctx, - "%s.%s", lp_netbios_name(), realm)); - service_principal_name[0] = talloc_asprintf(tmp_ctx, "host/%s", dns_host_name); - service_principal_name[1] = talloc_asprintf(tmp_ctx, "host/%s", strlower_talloc(mem_ctx, lp_netbios_name())); + r->out.join_password = password_str; + talloc_steal(mem_ctx, password_str); + + r->out.domain_sid = domain_sid; + talloc_steal(mem_ctx, 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); + 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.user_handle = cu.out.user_handle; + talloc_steal(mem_ctx, cu.out.user_handle); + r->out.error_string = r2.samr_handle.out.error_string; + talloc_steal(mem_ctx, r2.samr_handle.out.error_string); + r->out.realm = NULL; + r->out.kvno = 0; + r->out.server_dn_str = NULL; + talloc_free(tmp_ctx); - samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "dNSHostName", dns_host_name); - samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[0]); - samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[1]); + /* Now, if it was AD, then we want to start looking changing a + * few more things. Otherwise, we are done. */ + if (realm + && (r->in.acct_type == ACB_SVRTRUST) + && (!NT_STATUS_EQUAL(cu_status, NT_STATUS_USER_EXISTS))) { - ldb_ret = samdb_replace(remote_ldb, tmp_ctx, msg); - if (ldb_ret != 0) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "Failed to replace entries on %s\n", - ldb_dn_linearize(mem_ctx, msg->dn)); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } + status = libnet_JoinADSDomain(ctx, r); + return status; } - /* close connection */ - talloc_free(tmp_ctx); - return NT_STATUS_OK; } @@ -636,137 +992,294 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, struct libnet_Join *r) { NTSTATUS status; - int ret; - + TALLOC_CTX *tmp_mem; + struct libnet_JoinDomain *r2; + int ret, rtn; struct ldb_context *ldb; - struct libnet_JoinDomain r2; - const struct ldb_dn *base_dn = ldb_dn_explode(mem_ctx, "cn=Primary Domains"); - const struct ldb_val *prior_secret; - const struct ldb_val *prior_modified_time; + const struct ldb_dn *base_dn; struct ldb_message **msgs, *msg; - char *sct; - const char *attrs[] = { + const char *sct; + const char * const attrs[] = { "whenChanged", "secret", - "priorSecret" + "priorSecret", "priorChanged", NULL }; + 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.secure_channel_type == SEC_CHAN_BDC) { - r2.in.acct_type = ACB_SVRTRUST; + acct_type = ACB_SVRTRUST; } else if (r->in.secure_channel_type == SEC_CHAN_WKSTA) { - r2.in.acct_type = ACB_WSTRUST; + acct_type = ACB_WSTRUST; + } else { + r->out.error_string = NULL; + talloc_free(tmp_mem); + return NT_STATUS_INVALID_PARAMETER; } - r2.in.domain_name = r->in.domain_name; - r2.in.account_name = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name()); + if ((r->in.netbios_name != NULL) && (r->in.level != LIBNET_JOIN_AUTOMATIC)) { + netbios_name = r->in.netbios_name; + } else { + netbios_name = talloc_asprintf(tmp_mem, "%s", lp_netbios_name()); + if (!netbios_name) { + r->out.error_string = NULL; + talloc_free(tmp_mem); + return NT_STATUS_NO_MEMORY; + } + } - /* Local secrets are stored in secrets.ldb */ - ldb = secrets_db_connect(mem_ctx); + 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; + } + + /* + * Local secrets are stored in secrets.ldb + * open it to make sure we can write the info into it after the join + */ + ldb = secrets_db_connect(tmp_mem); if (!ldb) { r->out.error_string = talloc_asprintf(mem_ctx, "Could not open secrets database\n"); + talloc_free(tmp_mem); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - /* join domain */ - status = libnet_JoinDomain(ctx, mem_ctx, &r2); - - r->out.error_string = r2.out.error_string; + /* + * 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; + 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; } - - sct = talloc_asprintf(mem_ctx, "%d", r->in.secure_channel_type); - msg = ldb_msg_new(mem_ctx); - - /* search for the secret record */ - ret = gendb_search(ldb, - mem_ctx, base_dn, - &msgs, attrs, - "(|" SECRETS_PRIMARY_DOMAIN_FILTER "(realm=%s))", - r2.out.domain_name, r2.out.realm); - - msg->dn = ldb_dn_build_child(mem_ctx, "flatname", r2.out.domain_name, base_dn); - samdb_msg_add_string(ldb, mem_ctx, msg, "flatname", r2.out.domain_name); - if (r2.out.realm) { - samdb_msg_add_string(ldb, mem_ctx, msg, "realm", r2.out.realm); + /* + * now prepare the record for secrets.ldb + */ + sct = talloc_asprintf(tmp_mem, "%d", r->in.secure_channel_type); + if (!sct) { + r->out.error_string = NULL; + talloc_free(tmp_mem); + return NT_STATUS_NO_MEMORY; } - samdb_msg_add_string(ldb, mem_ctx, msg, "objectClass", "primaryDomain"); - samdb_msg_add_string(ldb, mem_ctx, msg, "secret", r2.out.join_password); - samdb_msg_add_string(ldb, mem_ctx, msg, "samAccountName", r2.in.account_name); + 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_explode(tmp_mem, "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) { + r->out.error_string = NULL; + talloc_free(tmp_mem); + return NT_STATUS_NO_MEMORY; + } - samdb_msg_add_string(ldb, mem_ctx, msg, "secureChannelType", sct); + rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "flatname", r2->out.domain_name); + if (rtn == -1) { + r->out.error_string = NULL; + talloc_free(tmp_mem); + return NT_STATUS_NO_MEMORY; + } + + if (r2->out.realm) { + rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "realm", r2->out.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, "secret", r2->out.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", r2->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 (r2->out.kvno) { + rtn = samdb_msg_add_uint(ldb, tmp_mem, msg, "msDS-KeyVersionNumber", + r2->out.kvno); + if (rtn == -1) { + r->out.error_string = NULL; + talloc_free(tmp_mem); + return NT_STATUS_NO_MEMORY; + } + } - if (r2.out.kvno) { - samdb_msg_add_uint(ldb, mem_ctx, msg, "msDS-KeyVersionNumber", - r2.out.kvno); + if (r2->out.domain_sid) { + rtn = samdb_msg_add_dom_sid(ldb, tmp_mem, msg, "objectSid", + r2->out.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))", + r2->out.domain_name, r2->out.realm); if (ret == 0) { } else if (ret == -1) { r->out.error_string = talloc_asprintf(mem_ctx, "Search for domain: %s and realm: %s failed: %s", - r2.out.domain_name, r2.out.realm, ldb_errstring(ldb)); + r2->out.domain_name, r2->out.realm, ldb_errstring(ldb)); + talloc_free(tmp_mem); return NT_STATUS_INTERNAL_DB_CORRUPTION; } else { + 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) { - samdb_msg_set_value(ldb, mem_ctx, msg, "priorSecret", 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; + } } - samdb_msg_set_string(ldb, mem_ctx, msg, "secret", r2.out.join_password); - + rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secret", r2->out.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) { - samdb_msg_set_value(ldb, mem_ctx, msg, "priorWhenChanged", - 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", r2->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; } - - samdb_msg_set_string(ldb, mem_ctx, msg, "samAccountName", r2.in.account_name); - samdb_msg_set_string(ldb, mem_ctx, msg, "secureChannelType", sct); } /* create the secret */ - ret = samdb_add(ldb, mem_ctx, msg); + 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\n", + ldb_dn_linearize(ldb, msg->dn)); + talloc_free(tmp_mem); return NT_STATUS_INTERNAL_DB_CORRUPTION; } + + /* 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); + talloc_free(tmp_mem); return NT_STATUS_OK; } NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Join *r) { - NTSTATUS nt_status; - struct libnet_Join r2; - r2.in.secure_channel_type = r->in.secure_channel_type; - r2.in.domain_name = r->in.domain_name; - - if ((r->in.secure_channel_type == SEC_CHAN_WKSTA) - || (r->in.secure_channel_type == SEC_CHAN_BDC)) { - nt_status = libnet_Join_primary_domain(ctx, mem_ctx, &r2); - } else { - 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); - return NT_STATUS_INVALID_PARAMETER; + switch (r->in.secure_channel_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 = r2.out.error_string; - return nt_status; + + 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); + return NT_STATUS_INVALID_PARAMETER; } -- cgit From 2ca10397af6f5680f99997d9f92cd6356816376d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 28 Sep 2005 05:38:20 +0000 Subject: r10566: Clean up error messages to provide more accurate info. Andrew Bartlett (This used to be commit 640815008b78ca19a73beb523e6823dd61feffa5) --- source4/libnet/libnet_join.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 3edad64259..166b6a730d 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -613,9 +613,15 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru status = libnet_RpcConnect(ctx, c, c); if (!NT_STATUS_IS_OK(status)) { - 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)); + if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) { + 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)); + } 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; } @@ -835,9 +841,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru r->out.error_string = talloc_asprintf(mem_ctx, "samr_LookupNames for [%s] returns %d RIDs\n", r->in.account_name, ln.out.rids.count); - status = NT_STATUS_INVALID_PARAMETER; talloc_free(tmp_ctx); - return status; + return NT_STATUS_INVALID_PARAMETER; } /* prepare samr_OpenUser */ -- cgit From b7a47635caeb326cc8a5c2bd2307334a4a2ff416 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Oct 2005 23:42:59 +0000 Subject: r10696: Return the realm to the caller, not NULL... Also return an indication of if the join was of a new account, or reworking an existing account. Andrew Bartlett (This used to be commit b6e4b36c4f1f90e42dd0543538956a1d89e3724b) --- source4/libnet/libnet_join.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 166b6a730d..353fd6a7b1 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -974,7 +974,6 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru talloc_steal(mem_ctx, cu.out.user_handle); r->out.error_string = r2.samr_handle.out.error_string; talloc_steal(mem_ctx, r2.samr_handle.out.error_string); - r->out.realm = NULL; r->out.kvno = 0; r->out.server_dn_str = NULL; talloc_free(tmp_ctx); @@ -989,7 +988,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - return NT_STATUS_OK; + return cu_status; } static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, -- cgit From 2e3c91795747108795224f307a9a97a9bd794cfe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 4 Oct 2005 00:59:59 +0000 Subject: r10701: Ensure we return the right user handle. Andrew Bartlett (This used to be commit 732b247a498e0b90b9f0c711baaac51ad6402496) --- source4/libnet/libnet_join.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 353fd6a7b1..a580cc6b13 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -970,8 +970,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru talloc_steal(mem_ctx, samr_pipe); r->out.samr_binding = samr_binding; talloc_steal(mem_ctx, samr_binding); - r->out.user_handle = cu.out.user_handle; - talloc_steal(mem_ctx, cu.out.user_handle); + 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; -- cgit From 1377cca5f4beb43cf67fcc65eed79f14178d6349 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Oct 2005 11:31:45 +0000 Subject: r10810: This adds the hooks required to communicate the current user from the authenticated session down into LDB. This associates a session info structure with the open LDB, allowing a future ldb_ntacl module to allow/deny operations on that basis. Along the way, I cleaned up a few things, and added new helper functions to assist. In particular the LSA pipe uses simpler queries for some of the setup. In ldap_server, I have removed the 'ldasrv:hacked' module, which hasn't been worked on (other than making it continue to compile) since January, and I think the features of this module are being put into ldb anyway. I have also changed the partitions in ldap_server to be initialised after the connection, with the private pointer used to associate the ldb with the incoming session. Andrew Bartlett (This used to be commit fd7203789a2c0929eecea8125b57b833a67fed71) --- source4/libnet/libnet_join.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index a580cc6b13..c71fe0c53e 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -701,6 +701,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru domain_sid = lsa_query_info.out.info->domain.sid; domain_name = lsa_query_info.out.info->domain.name.string; + DEBUG(0, ("Joining domain %s\n", domain_name)); + /* establish a SAMR connection, on the same CIFS transport */ -- cgit From a599edf04cbdeef9014923ba0d3713b8ff84f266 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Oct 2005 06:10:23 +0000 Subject: r10913: This patch isn't as big as it looks ... most of the changes are fixes to make all the ldb code compile without warnings on gcc4. Unfortunately That required a lot of casts :-( I have also added the start of an 'operational' module, which will replace the timestamp module, plus add support for some other operational attributes In ldb_msg_*() I added some new utility functions to make the operational module sane, and remove the 'ldb' argument from the ldb_msg_add_*() functions. That argument was only needed back in the early days of ldb when we didn't use the hierarchical talloc and thus needed a place to get the allocation function from. Now its just a pain to pass around everywhere. Also added a ldb_debug_set() function that calls ldb_debug() plus sets the result using ldb_set_errstring(). That saves on some awkward coding in a few places. (This used to be commit f6818daecca95760c12f79fd307770cbe3346f57) --- source4/libnet/libnet_join.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index c71fe0c53e..e3ed325d92 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -109,19 +109,19 @@ static NTSTATUS libnet_JoinSite(struct libnet_context *ctx, return NT_STATUS_NO_MEMORY; } - rtn = ldb_msg_add_string(remote_ldb, msg, "objectClass", "server"); + 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(remote_ldb, msg, "systemFlags", "50000000"); + 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(remote_ldb, msg, "serverReference",libnet_r->out.account_dn_str); + 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); -- cgit From 17355fbbd4c4a904bb75c1d8ba98948edaf0fe68 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Oct 2005 22:01:15 +0000 Subject: r11094: Connect to SAM, implement getdcname (This used to be commit a14398715eceecf204caf815a8769ba8214d0576) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index e3ed325d92..bbf493a817 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -990,7 +990,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - return cu_status; + return status; } static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, -- cgit From 22a9779328877c4e44af39799a1a20454136e3e5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 20 Oct 2005 03:21:34 +0000 Subject: r11197: indent (This used to be commit a432ba105cbf2ea7b9010365c0a7d1dcc9ff5f7f) --- source4/libnet/libnet_join.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index bbf493a817..78f239eab5 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -657,8 +657,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru status = dcerpc_lsa_OpenPolicy2(lsa_pipe, tmp_ctx, &lsa_open_policy); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, - "lsa_OpenPolicy2 failed: %s", - nt_errstr(status)); + "lsa_OpenPolicy2 failed: %s", + nt_errstr(status)); talloc_free(tmp_ctx); return status; } -- cgit From 2a2a35005749766e407c2a106720e74b7dfcc005 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Oct 2005 12:14:08 +0000 Subject: r11287: Understand the new behaviour of the LSA pipe on ncacn_ip_tcp in Win2k3 SP1. Only a few operations are supported (LookupSids3 and LookupNames4), and these are only supported under schannel. This appears to be the operations Win2k3 SP1 uses to verify part of the PAC back to the server. The test is setup to pass, but not enforce (so far) this new behaviour. Andrew Bartlett (This used to be commit e15e39866e9775ba662f669a19836d33f7633f6f) --- source4/libnet/libnet_join.c | 114 +++++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 48 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 78f239eab5..ec366aeb73 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -227,7 +227,11 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J } *drsuapi_binding = *samr_binding; - drsuapi_binding->transport = NCACN_IP_TCP; + + /* DRSUAPI is only available on IP_TCP, and locally on NCALRPC */ + if (drsuapi_binding->transport != NCALRPC) { + drsuapi_binding->transport = NCACN_IP_TCP; + } drsuapi_binding->endpoint = NULL; drsuapi_binding->flags |= DCERPC_SEAL; @@ -655,52 +659,57 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru lsa_open_policy.out.handle = &lsa_p_handle; status = dcerpc_lsa_OpenPolicy2(lsa_pipe, tmp_ctx, &lsa_open_policy); - if (!NT_STATUS_IS_OK(status)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "lsa_OpenPolicy2 failed: %s", - nt_errstr(status)); - talloc_free(tmp_ctx); - return 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)) { + /* 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)); + "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()); + } } - domain_sid = lsa_query_info.out.info->domain.sid; - domain_name = lsa_query_info.out.info->domain.name.string; - DEBUG(0, ("Joining domain %s\n", domain_name)); /* @@ -766,16 +775,25 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - /* check result of samr_Connect */ - if (!NT_STATUS_IS_OK(sc.out.result)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "samr_Connect failed: %s", - nt_errstr(sc.out.result)); - status = sc.out.result; - talloc_free(tmp_ctx); - return status; + /* Perhaps we didn't get a SID above, because we are against ncacn_ip_tcp */ + if (!domain_sid) { + struct lsa_String name; + struct samr_LookupDomain l; + name.string = domain_name; + l.in.connect_handle = &p_handle; + l.in.domain_name = &name; + + status = dcerpc_samr_LookupDomain(samr_pipe, tmp_ctx, &l); + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string = talloc_asprintf(mem_ctx, + "SAMR LookupDomain failed: %s", + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + domain_sid = l.out.sid; } - + /* prepare samr_OpenDomain */ ZERO_STRUCT(d_handle); od.in.connect_handle = &p_handle; -- cgit From 26fde8dee17b02eb064c6410d781709094ce5160 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 28 Oct 2005 02:09:35 +0000 Subject: r11348: Fixes for 'net join': - Add more servicePrincipalNames - Always add them, not just for BDC accounts, and not just the first time the account is created (it might be an upgrade from an NT4 account). This should fix us for being a domain member in ADS again. (This used to be commit 3821821d4cb459edd331d40be8b84b3c82616a0a) --- source4/libnet/libnet_join.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index ec366aeb73..4927f5fb45 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -390,7 +390,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J msg->dn = msgs[0]->dn; { - const char *service_principal_name[2]; + int i; + const char *service_principal_name[6]; const char *dns_host_name = strlower_talloc(tmp_ctx, talloc_asprintf(tmp_ctx, "%s.%s", @@ -404,17 +405,18 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J } service_principal_name[0] = talloc_asprintf(tmp_ctx, "host/%s", dns_host_name); - if (!service_principal_name[0]) { - r->out.error_string = NULL; - talloc_free(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } - service_principal_name[1] = talloc_asprintf(tmp_ctx, "host/%s", strlower_talloc(tmp_ctx, r->in.netbios_name)); - if (!service_principal_name[1]) { - r->out.error_string = NULL; - talloc_free(tmp_ctx); - return NT_STATUS_NO_MEMORY; + service_principal_name[2] = talloc_asprintf(tmp_ctx, "host/%s/%s", dns_host_name, realm); + service_principal_name[3] = talloc_asprintf(tmp_ctx, "host/%s/%s", strlower_talloc(tmp_ctx, r->in.netbios_name), realm); + service_principal_name[4] = talloc_asprintf(tmp_ctx, "host/%s/%s", dns_host_name, r->out.domain_name); + service_principal_name[5] = talloc_asprintf(tmp_ctx, "host/%s/%s", strlower_talloc(tmp_ctx, r->in.netbios_name), r->out.domain_name); + + for (i=0; i < ARRAY_SIZE(service_principal_name); i++) { + if (!service_principal_name[i]) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } } rtn = samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "dNSHostName", dns_host_name); @@ -502,9 +504,11 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J r->out.kvno = kvno; - status = libnet_JoinSite(ctx, - drsuapi_pipe, drsuapi_bind_handle, - remote_ldb, r); + if (r->in.acct_type == ACB_SVRTRUST) { + status = libnet_JoinSite(ctx, + drsuapi_pipe, drsuapi_bind_handle, + remote_ldb, r); + } talloc_free(tmp_ctx); return status; @@ -1000,10 +1004,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 - && (r->in.acct_type == ACB_SVRTRUST) - && (!NT_STATUS_EQUAL(cu_status, NT_STATUS_USER_EXISTS))) { - + if (realm) { status = libnet_JoinADSDomain(ctx, r); return status; } -- cgit From 900d6fab322dfa8a0ff8a17fb440d269c8d6c678 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 28 Oct 2005 02:13:14 +0000 Subject: r11349: Actually add all the new spns... Andrew Bartlett (This used to be commit 63eede2ad3f0238e1a925325c0be08d79f48c33b) --- source4/libnet/libnet_join.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 4927f5fb45..daa840f76e 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -417,6 +417,12 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } + rtn = samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[i]); + if (rtn == -1) { + r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } } rtn = samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "dNSHostName", dns_host_name); @@ -425,18 +431,6 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - rtn = samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[0]); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } - rtn = samdb_msg_add_string(remote_ldb, tmp_ctx, msg, "servicePrincipalName", service_principal_name[1]); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } rtn = samdb_replace(remote_ldb, tmp_ctx, msg); if (rtn != 0) { -- cgit From 9bdc1a77f5d80827d1e352d30ff7b322a933dc0e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Oct 2005 03:03:32 +0000 Subject: r11407: Push 'recreate account' logic into libnet/libnet_join.c. We don't return the pesky USER_EXISTS 'error' code any more, and it is much easier to handle this inline. Andrew Bartlett (This used to be commit a7eb796cf544db3fe16986d8e233d2defe7a7d1b) --- source4/libnet/libnet_join.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index daa840f76e..a438c5962d 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -144,9 +144,9 @@ static NTSTATUS libnet_JoinSite(struct libnet_context *ctx, if (rtn != 0) { libnet_r->out.error_string = talloc_asprintf(libnet_r, - "Failed to add server entry %s: %s.", + "Failed to add server entry %s: %s: %d", server_dn_str, - ldb_errstring(remote_ldb)); + ldb_errstring(remote_ldb), rtn); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -881,6 +881,36 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru talloc_free(tmp_ctx); return status; } + + if (r->in.recreate_account) { + struct samr_DeleteUser d; + d.in.user_handle = u_handle; + d.out.user_handle = u_handle; + status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d); + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string = talloc_asprintf(mem_ctx, + "samr_DeleteUser (for recreate) of [%s] failed: %s", + r->in.account_name, + nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + + /* We want to recreate, so delete and another samr_CreateUser2 */ + + /* &cu filled in above */ + cu_status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu); + status = cu_status; + if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { + r->out.error_string = talloc_asprintf(mem_ctx, + "samr_CreateUser2 (recreate) for [%s] failed: %s\n", + r->in.domain_name, nt_errstr(status)); + talloc_free(tmp_ctx); + return status; + } + DEBUG(0, ("Recreated account in domain %s\n", domain_name)); + + } } /* Find out what password policy this user has */ pwp.in.user_handle = u_handle; @@ -1093,6 +1123,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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); -- cgit From 56d3064db62c4534f49477a186b746c6c501e3a0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Oct 2005 03:44:29 +0000 Subject: r11410: Fix rejoin as a BDC by modifying, rather than trying to recreate, the server reference. Andrew Bartlett (This used to be commit 302219928f47cdc3822c3a7d9444339092d9d33c) --- source4/libnet/libnet_join.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index a438c5962d..b487056494 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -26,6 +26,7 @@ #include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" #include "libcli/cldap/cldap.h" #include "include/secrets.h" #include "librpc/gen_ndr/drsuapi.h" @@ -138,10 +139,44 @@ static NTSTATUS libnet_JoinSite(struct libnet_context *ctx, } msg->dn = server_dn; - msg->elements->flags = LDB_FLAG_MOD_ADD; rtn = ldb_add(remote_ldb, msg); - if (rtn != 0) { + 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", -- cgit From 5c9590587197dcb95007fdc54318187d5716c7c6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 8 Nov 2005 00:11:45 +0000 Subject: r11567: Ldb API change patch. This patch changes the way lsb_search is called and the meaning of the returned integer. The last argument of ldb_search is changed from struct ldb_message to struct ldb_result which contains a pointer to a struct ldb_message list and a count of the number of messages. The return is not the count of messages anymore but instead it is an ldb error value. I tryed to keep the patch as tiny as possible bu as you can guess I had to change a good amount of places. I also tried to double check all my changes being sure that the calling functions would still behave as before. But this patch is big enough that I fear some bug may have been introduced anyway even if it passes the test suite. So if you are currently working on any file being touched please give it a deep look and blame me for any error. Simo. (This used to be commit 22c8c97e6fb466b41859e090e959d7f1134be780) --- source4/libnet/libnet_join.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index b487056494..0eb109c2cf 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -227,9 +227,10 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J const struct ldb_dn *account_dn; const char *account_dn_str; const char *remote_ldb_url; - struct ldb_message **msgs, *msg; + struct ldb_result *res; + struct ldb_message *msg; - int rtn; + int ret, rtn; unsigned int kvno; @@ -403,9 +404,9 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J } /* search for the user's record */ - rtn = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, - NULL, attrs, &msgs); - if (rtn != 1) { + 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", account_dn_str, ldb_errstring(remote_ldb)); talloc_free(tmp_ctx); @@ -413,7 +414,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J } /* If we have a kvno recorded in AD, we need it locally as well */ - kvno = ldb_msg_find_uint(msgs[0], "msDS-KeyVersionNumber", 0); + kvno = ldb_msg_find_uint(res->msgs[0], "msDS-KeyVersionNumber", 0); /* Prepare a new message, for the modify */ msg = ldb_msg_new(tmp_ctx); @@ -422,7 +423,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - msg->dn = msgs[0]->dn; + msg->dn = res->msgs[0]->dn; { int i; -- cgit From 9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 1 Dec 2005 05:20:39 +0000 Subject: r11995: A big kerberos-related update. This merges Samba4 up to current lorikeet-heimdal, which includes a replacement for some Samba-specific hacks. In particular, the credentials system now supplies GSS client and server credentials. These are imported into GSS with gss_krb5_import_creds(). Unfortunetly this can't take an MEMORY keytab, so we now create a FILE based keytab as provision and join time. Because the keytab is now created in advance, we don't spend .4s at negprot doing sha1 s2k calls. Also, because the keytab is read in real time, any change in the server key will be correctly picked up by the the krb5 code. To mark entries in the secrets which should be exported to a keytab, there is a new kerberosSecret objectClass. The new routine cli_credentials_update_all_keytabs() searches for these, and updates the keytabs. This is called in the provision.js via the ejs wrapper credentials_update_all_keytabs(). We can now (in theory) use a system-provided /etc/krb5.keytab, if krb5Keytab: FILE:/etc/krb5.keytab is added to the secrets.ldb record. By default the attribute privateKeytab: secrets.keytab is set, pointing to allow the whole private directory to be moved without breaking the internal links. (This used to be commit 6b75573df49c6210e1b9d71e108a9490976bd41d) --- source4/libnet/libnet_join.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 0eb109c2cf..1530a9f6a8 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -1094,6 +1094,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, uint32_t acct_type = 0; const char *account_name; const char *netbios_name; + char *filter; r->out.error_string = NULL; @@ -1212,6 +1213,13 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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"); @@ -1341,6 +1349,33 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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; -- cgit From a1827a1deba04e0b4b2a508dc4e4e66603a46d16 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Dec 2005 07:22:25 +0000 Subject: r12227: I realised that I wasn't yet seeing authenticated LDAP for the ldb backend. The idea is that every time we open an LDB, we can provide a session_info and/or credentials. This would allow any ldb to be remote to LDAP. We should also support provisioning to a authenticated ldap server. (They are separate so we can say authenticate as foo for remote, but here we just want a token of SYSTEM). Andrew Bartlett (This used to be commit ae2f3a64ee0b07575624120db45299c65204210b) --- source4/libnet/libnet_join.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 1530a9f6a8..08bd9aa680 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -396,7 +396,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J return NT_STATUS_NO_MEMORY; } - remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, 0, NULL); + remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, + NULL, ctx->cred, 0, NULL); if (!remote_ldb) { r->out.error_string = NULL; talloc_free(tmp_ctx); @@ -1131,7 +1132,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, } } - account_name = talloc_asprintf(tmp_mem, "%s$", netbios_name); + account_name = talloc_asprintf(tmp_mem, "%s$", netbios_name); if (!account_name) { r->out.error_string = NULL; talloc_free(tmp_mem); @@ -1142,7 +1143,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, * Local secrets are stored in secrets.ldb * open it to make sure we can write the info into it after the join */ - ldb = secrets_db_connect(tmp_mem); + ldb = secrets_db_connect(tmp_mem); if (!ldb) { r->out.error_string = talloc_asprintf(mem_ctx, -- cgit From 8e0948bbad959f8809a19e40e6777705013f866c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 22 Dec 2005 06:47:00 +0000 Subject: r12421: Handle the case where we are a joining as different account types far better. Andrew Bartlett (This used to be commit 0ce82e8a41f0fdea9928e3e341680232cc640e18) --- source4/libnet/libnet_join.c | 110 ++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 32 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 08bd9aa680..c55be7e73c 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -595,7 +595,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct samr_GetUserPwInfo pwp; struct lsa_String samr_account_name; - uint32_t acct_flags; + uint32_t acct_flags, old_acct_flags; uint32_t rid, access_granted; int policy_min_pw_len = 0; @@ -936,8 +936,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* We want to recreate, so delete and another samr_CreateUser2 */ /* &cu filled in above */ - cu_status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu); - status = cu_status; + status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { r->out.error_string = talloc_asprintf(mem_ctx, "samr_CreateUser2 (recreate) for [%s] failed: %s\n", @@ -949,30 +948,6 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } } - /* Find out what password policy this user has */ - pwp.in.user_handle = u_handle; - - status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp); - if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; - } - - /* Grab a password of that minimum length */ - - password_str = generate_random_str(tmp_ctx, MAX(8, policy_min_pw_len)); - - 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; - - status = libnet_SetPassword(ctx, tmp_ctx, &r2); - if (!NT_STATUS_IS_OK(status)) { - r->out.error_string = talloc_steal(mem_ctx, r2.samr_handle.out.error_string); - talloc_free(tmp_ctx); - return status; - } /* prepare samr_QueryUserInfo (get flags) */ qui.in.user_handle = u_handle; @@ -998,17 +973,88 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - /* Possibly change account type (if we are creating a new account) */ - if (((qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) - != r->in.acct_type) && (!NT_STATUS_EQUAL(cu_status, NT_STATUS_USER_EXISTS))) { - acct_flags = (qui.out.info->info16.acct_flags & ~(ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)) - | r->in.acct_type; + old_acct_flags = (qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)); + /* Possibly bail if the account is of the wrong type */ + if (old_acct_flags + != r->in.acct_type) { + const char *old_account_type, *new_account_type; + switch (old_acct_flags) { + case ACB_WSTRUST: + old_account_type = "domain member (member)"; + break; + case ACB_SVRTRUST: + old_account_type = "domain controller (bdc)"; + break; + case ACB_DOMTRUST: + old_account_type = "trusted domain"; + break; + default: + return NT_STATUS_INVALID_PARAMETER; + } + switch (r->in.acct_type) { + case ACB_WSTRUST: + new_account_type = "domain member (member)"; + break; + case ACB_SVRTRUST: + new_account_type = "domain controller (bdc)"; + break; + case ACB_DOMTRUST: + new_account_type = "trusted domain"; + break; + default: + return NT_STATUS_INVALID_PARAMETER; + } + + if (!NT_STATUS_EQUAL(cu_status, NT_STATUS_USER_EXISTS)) { + /* We created a new user, but they didn't come out the right type?!? */ + r->out.error_string + = 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", + r->in.account_name, new_account_type, old_account_type); + talloc_free(tmp_ctx); + return NT_STATUS_INVALID_PARAMETER; + } else { + /* The account is of the wrong type, so bail */ + + /* TODO: We should allow a --force option to override, and redo this from the top setting r.in.recreate_account */ + r->out.error_string + = 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); + talloc_free(tmp_ctx); + return NT_STATUS_USER_EXISTS; + } } else { acct_flags = qui.out.info->info16.acct_flags; } acct_flags = (acct_flags & ~ACB_DISABLED); + /* Find out what password policy this user has */ + pwp.in.user_handle = u_handle; + + status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp); + if (NT_STATUS_IS_OK(status)) { + policy_min_pw_len = pwp.out.info.min_password_length; + } + + /* Grab a password of that minimum length */ + + password_str = generate_random_str(tmp_ctx, MAX(8, policy_min_pw_len)); + + 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; + + status = libnet_SetPassword(ctx, tmp_ctx, &r2); + if (!NT_STATUS_IS_OK(status)) { + r->out.error_string = talloc_steal(mem_ctx, r2.samr_handle.out.error_string); + talloc_free(tmp_ctx); + return status; + } + /* reset flags (if required) */ if (acct_flags != qui.out.info->info16.acct_flags) { ZERO_STRUCT(u_info); -- cgit From 758873b9fb46c0c0059a95c6bdeb23b17f2c80c9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 22 Dec 2005 06:58:26 +0000 Subject: r12423: Remove DEBUG(0) printouts in favor of more information to the caller. I assume this works better with SWAT and the like anyway. Andrew Bartlett (This used to be commit b11975703d5e32f6f3ad10079106b1345fa56b5c) --- source4/libnet/libnet_join.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index c55be7e73c..62feb8b544 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -745,8 +745,6 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } } - DEBUG(0, ("Joining domain %s\n", domain_name)); - /* establish a SAMR connection, on the same CIFS transport */ @@ -937,15 +935,13 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* &cu filled in above */ status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu); - if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { + 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)); talloc_free(tmp_ctx); return status; } - DEBUG(0, ("Recreated account in domain %s\n", domain_name)); - } } @@ -1429,6 +1425,8 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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; } -- cgit From 7448b93a2e7a21fe2233706fc7b7ced1e98a41d3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 22 Dec 2005 09:58:51 +0000 Subject: r12430: Clarify libnet_join code. Add/fix comments. Andrew Bartlett (This used to be commit a3372935eee12c99d8c4a29eda45e8d0f1039896) --- source4/libnet/libnet_join.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 62feb8b544..28d12247c9 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -834,7 +834,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru od.in.sid = domain_sid; od.out.domain_handle = &d_handle; - /* 4. do a samr_OpenDomain to get a domain 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, @@ -856,17 +856,10 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru cu.out.rid = &rid; cu.out.access_granted = &access_granted; - /* 4. do a samr_CreateUser2 to get an account handle, or an error */ + /* do a samr_CreateUser2 to get an account handle, or an error */ cu_status = dcerpc_samr_CreateUser2(samr_pipe, tmp_ctx, &cu); status = cu_status; - if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "samr_CreateUser2 for [%s] failed: %s\n", - r->in.domain_name, nt_errstr(status)); - talloc_free(tmp_ctx); - return status; - - } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { /* prepare samr_LookupNames */ ln.in.domain_handle = &d_handle; ln.in.num_names = 1; @@ -943,6 +936,12 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru 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)); + talloc_free(tmp_ctx); + return status; } /* prepare samr_QueryUserInfo (get flags) */ @@ -1078,6 +1077,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return NT_STATUS_NO_MEMORY; } + /* 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); -- cgit From acd6a086b341096fcbea1775ce748587fcc8020a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 14:28:01 +0000 Subject: r12510: Change the DCE/RPC interfaces to take a pointer to a dcerpc_interface_table struct rather then a tuple of interface name, UUID and version. This removes the requirement for having a global list of DCE/RPC interfaces, except for these parts of the code that use that list explicitly (ndrdump and the scanner torture test). This should also allow us to remove the hack that put the authservice parameter in the dcerpc_binding struct as it can now be read directly from dcerpc_interface_table. I will now modify some of these functions to take a dcerpc_syntax_id structure rather then a full dcerpc_interface_table. (This used to be commit 8aae0f168e54c01d0866ad6e0da141dbd828574f) --- source4/libnet/libnet_join.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 28d12247c9..11e1dfc175 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -274,8 +274,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J status = dcerpc_pipe_connect_b(tmp_ctx, &drsuapi_pipe, drsuapi_binding, - DCERPC_DRSUAPI_UUID, - DCERPC_DRSUAPI_VERSION, + &dcerpc_table_drsuapi, ctx->cred, ctx->event_ctx); if (!NT_STATUS_IS_OK(status)) { @@ -644,9 +643,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru c->level = LIBNET_RPC_CONNECT_BINDING; c->in.binding = r->in.binding; } - c->in.dcerpc_iface_name = DCERPC_LSARPC_NAME; - c->in.dcerpc_iface_uuid = DCERPC_LSARPC_UUID; - c->in.dcerpc_iface_version = DCERPC_LSARPC_VERSION; + c->in.dcerpc_iface = &dcerpc_table_lsarpc; /* connect to the LSA pipe of the PDC */ @@ -761,7 +758,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* Make binding string for samr, not the other pipe */ status = dcerpc_epm_map_binding(tmp_ctx, samr_binding, - DCERPC_SAMR_UUID, DCERPC_SAMR_VERSION, + &dcerpc_table_samr, lsa_pipe->conn->event_ctx); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, @@ -782,8 +779,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - status = dcerpc_pipe_auth(samr_pipe, samr_binding, DCERPC_SAMR_UUID, - DCERPC_SAMR_VERSION, ctx->cred); + status = dcerpc_pipe_auth(samr_pipe, samr_binding, &dcerpc_table_samr, ctx->cred); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "SAMR bind failed: %s", -- cgit From 2cd5ca7d25f12aa9198bf8c2deb6aea282f573ee Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Dec 2005 15:38:36 +0000 Subject: r12542: Move some more prototypes out to seperate headers (This used to be commit 0aca5fd5130d980d07398f3291d294202aefe3c2) --- source4/libnet/libnet_join.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 11e1dfc175..af15d81797 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -30,6 +30,7 @@ #include "libcli/cldap/cldap.h" #include "include/secrets.h" #include "librpc/gen_ndr/drsuapi.h" +#include "dsdb/samdb/samdb.h" /* * find out Site specific stuff: -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/libnet/libnet_join.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index af15d81797..a1aa00c5c2 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -22,14 +22,11 @@ #include "includes.h" #include "libnet/libnet.h" -#include "librpc/gen_ndr/ndr_samr.h" -#include "librpc/gen_ndr/ndr_lsa.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" #include "libcli/cldap/cldap.h" #include "include/secrets.h" -#include "librpc/gen_ndr/drsuapi.h" #include "dsdb/samdb/samdb.h" /* -- cgit From 78c50015bb8bd5a1d831a6e7ec796b3367c73145 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 15:40:05 +0000 Subject: r12694: Move some headers to the directory of the subsystem they belong to. (This used to be commit c722f665c90103f3ed57621c460e32ad33e7a8a3) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index a1aa00c5c2..4f566a36a8 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -26,7 +26,7 @@ #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" #include "libcli/cldap/cldap.h" -#include "include/secrets.h" +#include "passdb/secrets.h" #include "dsdb/samdb/samdb.h" /* -- cgit From b135f4467f8413f6ac44df54b8430305f6c26c0c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 03:02:00 +0000 Subject: r12858: This moves the libnet_LookupPdc code to use a GetDC request to find the remote server's name, or in the absence of a local nbt_server to communicate with (or without root access), a node status request. The result is that we are in a better position to use kerberos, as well as to remove the 'password server' mandatory parameter for the samsync and samdump commands. (I need this to put these into SWAT). The only problem I have is that I must create a messaging context, which requires a server ID. As a client process, I don't expect to get messages, but it is currently required for replies, so I generate a random() number. We probably need the servers to accept connections on streamed sockets too, for client-only tasks that want IRPC. Because I wanted to test this code, I have put the NET-API-* tests into our test scripts, to ensure they pass and keep passing. They are good frontends onto the libnet system, and I see no reason not to test them. In doing so the NET-API-RPCCONNECT test was simplified to take a binding string on the command line, removing duplicate code, and testing the combinations in the scripts instead. (I have done a bit of work on the list shares code in libnet_share.c to make it pass 'make test') In the future, I would like to extend the libcli/findds.c code (based off volker's winbind/wb_async_helpers.c, which is why it shows up a bit odd in the patch) to handle getting multiple name replies, sending a getdc request to each in turn. (posted to samba-technical for review, and I'll happily update with any comments) Andrew Bartlett (This used to be commit 7ccddfd3515fc2c0d6f447c768ccbf7a220c3380) --- source4/libnet/libnet_join.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 4f566a36a8..616c80b1a4 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -272,7 +272,7 @@ 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, + &dcerpc_table_drsuapi, ctx->cred, ctx->event_ctx); if (!NT_STATUS_IS_OK(status)) { @@ -635,8 +635,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* prepare connect to the LSA pipe of PDC */ if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) { - c->level = LIBNET_RPC_CONNECT_PDC; - c->in.domain_name = r->in.domain_name; + c->level = LIBNET_RPC_CONNECT_PDC; + c->in.name = r->in.domain_name; } else { c->level = LIBNET_RPC_CONNECT_BINDING; c->in.binding = r->in.binding; @@ -998,7 +998,9 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* We created a new user, but they didn't come out the right type?!? */ r->out.error_string = 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", + "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", r->in.account_name, new_account_type, old_account_type); talloc_free(tmp_ctx); return NT_STATUS_INVALID_PARAMETER; @@ -1008,7 +1010,9 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* TODO: We should allow a --force option to override, and redo this from the top setting r.in.recreate_account */ r->out.error_string = 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", + "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); talloc_free(tmp_ctx); return NT_STATUS_USER_EXISTS; @@ -1045,7 +1049,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } /* reset flags (if required) */ - if (acct_flags != qui.out.info->info16.acct_flags) { + if (acct_flags != qui.out.info->info16.acct_flags) { ZERO_STRUCT(u_info); u_info.info16.acct_flags = acct_flags; @@ -1160,7 +1164,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, if ((r->in.netbios_name != NULL) && (r->in.level != LIBNET_JOIN_AUTOMATIC)) { netbios_name = r->in.netbios_name; } else { - netbios_name = talloc_asprintf(tmp_mem, "%s", lp_netbios_name()); + netbios_name = talloc_reference(tmp_mem, lp_netbios_name()); if (!netbios_name) { r->out.error_string = NULL; talloc_free(tmp_mem); @@ -1437,8 +1441,8 @@ 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 secure channel type specified (%08X) attempting to join domain %s", + r->in.secure_channel_type, r->in.domain_name); return NT_STATUS_INVALID_PARAMETER; } -- cgit From a5a79e8b8cbdf24d5c2db45ece4110ed5d85e58f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 12 Jan 2006 09:33:49 +0000 Subject: r12865: Upgrade the librpc and libnet code. In librpc, always try SMB level authentication, even if trying schannel, but allow fallback to anonymous. This should better function with servers that set restrict anonymous. There are too many parts of Samba that get, parse and modify the binding parameters. Avoid the extra work, and add a binding element to the struct dcerpc_pipe The libnet vampire code has been refactored, to reduce extra layers and to better conform with the standard argument pattern. Also, take advantage of the new libnet_Lookup code, so we don't require the silly 'password server' smb.conf parameter. To better support forcing traffic to be sealed for the vampire operation, the dcerpc_bind_auth() function now takes an auth level parameter. Andrew Bartlett (This used to be commit d65b354959842326fdd4bd7eb7fbeea0390f4afa) --- source4/libnet/libnet_join.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 616c80b1a4..7a897b1280 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -745,14 +745,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru */ /* Find the original binding string */ - status = dcerpc_parse_binding(tmp_ctx, lsa_pipe->conn->binding_string, &samr_binding); - if (!NT_STATUS_IS_OK(status)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "Failed to parse lsa binding '%s'", - lsa_pipe->conn->binding_string); - talloc_free(tmp_ctx); - return status; + 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, -- cgit From e15136af9e208072137cb58fd6a0de894ce10505 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Jan 2006 00:55:30 +0000 Subject: r12882: Allow the netbios name to be specified at all times. Andrew Bartlett (This used to be commit f4f4dcf217314980aa114d61a1546d2c18b55baa) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 7a897b1280..65d264d0f3 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -1158,7 +1158,7 @@ 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()); -- cgit From f2df13958c70d9853cbe7d322716eb323a331b39 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Jan 2006 02:01:15 +0000 Subject: r12883: Fix the build... Andrew Bartlett (This used to be commit 8f7d14048fe29fd2c8b3e3c7aa73b4a854615016) --- source4/libnet/libnet_join.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 65d264d0f3..f7f2851309 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -1158,7 +1158,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_INVALID_PARAMETER; } - if (r->in.netbios_name != NULL) + if (r->in.netbios_name != NULL) { netbios_name = r->in.netbios_name; } else { netbios_name = talloc_reference(tmp_mem, lp_netbios_name()); @@ -1442,5 +1442,3 @@ NTSTATUS libnet_Join(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct lib r->in.secure_channel_type, r->in.domain_name); return NT_STATUS_INVALID_PARAMETER; } - - -- cgit From d790d8d6edbb7744cc6d3f7ca33e05a358038a42 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Jan 2006 02:58:35 +0000 Subject: r12886: Rename 'secure_channel_type' parameter to domain join as 'join_type'. Andrew Bartlett (This used to be commit a3b3e09a9acc66dff7baf1a4ba0ea913bccdbd7d) --- source4/libnet/libnet_join.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index f7f2851309..c961ff0cfe 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -1148,9 +1148,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; @@ -1209,7 +1209,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); @@ -1428,7 +1428,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,7 +1438,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; } -- cgit From b15582ed816f3d477f978976f43b82cfa90bf6dc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Jan 2006 12:52:56 +0000 Subject: r12903: Factor out a new routine libnet_RpcConnectDCInfo, to both connect to the remote sever, and to query it for domain information. Provide and use this information in the SamSync/Vampire callbacks, to allow a parallel connection to LDAP, if we are talking to AD. This allows us to get at some important attributes not exposed in the old protocol. With this, we are able to do a all-GUI vampire of a AD domain from SWAT, including getting all the SIDs, servicePrincipalNames and the like correct. Andrew Bartlett (This used to be commit 918358cee0b4a1b2c9bc9e68d9d53428a634281e) --- source4/libnet/libnet_join.c | 250 ++++++++++++------------------------------- 1 file changed, 68 insertions(+), 182 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index c961ff0cfe..0147679bcd 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -544,21 +544,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 * - * 7. do a samrSetUserInfo to set the account flags - * 8. do some ADS specific things when we join as Domain Controller, + * - do a samrSetUserInfo to set the account flags + * - 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 +568,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_RpcConnectDCInfo *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; @@ -596,9 +591,7 @@ 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 */ @@ -619,162 +612,47 @@ 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) { - r->out.error_string = NULL; - talloc_free(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } - - c = talloc(tmp_ctx, struct libnet_RpcConnect); - if (!c) { + connect_with_info = talloc(tmp_ctx, struct libnet_RpcConnectDCInfo); + if (!connect_with_info) { r->out.error_string = NULL; talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - + /* prepare connect to the LSA 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->level = LIBNET_RPC_CONNECT_PDC; + 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->level = LIBNET_RPC_CONNECT_BINDING; + connect_with_info->in.binding = r->in.binding; } - c->in.dcerpc_iface = &dcerpc_table_lsarpc; - - /* connect to the LSA pipe of the PDC */ - status = libnet_RpcConnect(ctx, c, c); + connect_with_info->in.dcerpc_iface = &dcerpc_table_samr; + /* + establish a SAMR connection, on the same CIFS transport + */ + + status = libnet_RpcConnectDCInfo(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(samr_pipe, + connect_with_info->out.dcerpc_pipe->binding, + &dcerpc_table_samr, ctx->cred); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "SAMR bind failed: %s", @@ -799,11 +677,21 @@ 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()); + } + } + /* 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 +703,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; } @@ -1010,7 +898,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru "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); + 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; } @@ -1065,7 +953,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } } - 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 +962,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; -- cgit From 243e07cfa2c9fc52867ebfa2b7d0f78247e0fecd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 14 Jan 2006 07:27:01 +0000 Subject: r12930: Fix ADS join: I wasn't filling in the flag 'realm' variable any more. Andrew Bartlett (This used to be commit 5c5a2974c94ae6b929ada7aaa2cd12a15b7468b8) --- source4/libnet/libnet_join.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 0147679bcd..a467999023 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -593,8 +593,6 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct dom_sid *account_sid = 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; @@ -988,7 +986,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; } -- cgit From 1f72942873ee28a17947d2124b885c22f9d83ffc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 17 Jan 2006 03:44:37 +0000 Subject: r12976: Patch from Brad Henry : This patch pulls the AD site name generation and site join code from libnet/libnet_join.c and puts it into a new file, libnet/libnet_site.c. This way, a common means for site name, configuration dn and server dn generation exists so it doesn't need to be rewritten in new code (such as the future libnet_leave for example). I've made a couple of changes, but nothing dramatic. Nice work Brad! Andrew Bartlett (This used to be commit 45f67b3f6d506cc8cb9922184a8c0c9b59a8f702) --- source4/libnet/libnet_join.c | 171 +------------------------------------------ 1 file changed, 2 insertions(+), 169 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index a467999023..f4e4091ce3 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -25,174 +25,9 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" -#include "libcli/cldap/cldap.h" #include "passdb/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; -} - /* * complete a domain join, when joining to a AD domain: * 1.) connect and bind to the DRSUAPI pipe @@ -532,10 +367,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J r->out.kvno = kvno; - 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); -- cgit From fc29c3250af5fbcd81725e38fb48ca1ec5ae23bf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 24 Jan 2006 02:25:50 +0000 Subject: r13104: Migrate and set secrets keytab values in the 'net join' code. This avoids falling back to in-memory keytabs. Andrew Bartlett (This used to be commit 59fbce01c6814b8e411e7de6ee66739161520a3c) --- source4/libnet/libnet_join.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index f4e4091ce3..5d1ba294c6 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -844,6 +844,8 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, "secret", "priorSecret", "priorChanged", + "krb5Keytab", + "privateKeytab", NULL }; uint32_t acct_type = 0; @@ -1036,6 +1038,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, @@ -1044,6 +1052,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; @@ -1093,6 +1103,26 @@ 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 */ -- cgit From 4ac2be99588b48b0652a524bf12fb1aa9c3f5fbb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 11:07:23 +0000 Subject: r13924: Split more prototypes out of include/proto.h + initial work on header file dependencies (This used to be commit 122835876748a3eaf5e8d31ad1abddab9acb8781) --- source4/libnet/libnet_join.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 5d1ba294c6..d5d5863f31 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -27,6 +27,8 @@ #include "lib/ldb/include/ldb_errors.h" #include "passdb/secrets.h" #include "dsdb/samdb/samdb.h" +#include "db_wrap.h" +#include "libcli/security/proto.h" /* * complete a domain join, when joining to a AD domain: -- cgit From 3f16241a1d3243447d0244ebac05b447aec94df8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 01:29:56 +0000 Subject: r14363: Remove credentials.h from the global includes. (This used to be commit 98c4c3051391c6f89df5d133665f51bef66b1563) --- source4/libnet/libnet_join.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index d5d5863f31..914c2bfbb1 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -29,6 +29,7 @@ #include "dsdb/samdb/samdb.h" #include "db_wrap.h" #include "libcli/security/proto.h" +#include "auth/credentials/credentials.h" /* * complete a domain join, when joining to a AD domain: -- cgit From 1060f6b3f621cb70b075a879f129e57f10fdbf8a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 23:35:30 +0000 Subject: r14402: Generate seperate headers for RPC client functions. (This used to be commit 7054ebf0249930843a2baf4d023ae8f62cedb109) --- source4/libnet/libnet_join.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 914c2bfbb1..3b0d861e01 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -23,6 +23,7 @@ #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 "passdb/secrets.h" @@ -30,6 +31,7 @@ #include "db_wrap.h" #include "libcli/security/proto.h" #include "auth/credentials/credentials.h" +#include "librpc/gen_ndr/ndr_samr_c.h" /* * complete a domain join, when joining to a AD domain: -- cgit From 8528016978b084213ef53d66e1b6e831b1a01acc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 00:23:11 +0000 Subject: r14464: Don't include ndr_BASENAME.h files unless strictly required, instead try to include just the BASENAME.h files (containing only structs) (This used to be commit 3dd477ca5147f28a962b8437e2611a8222d706bd) --- source4/libnet/libnet_join.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 3b0d861e01..a517aa3733 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -31,7 +31,9 @@ #include "db_wrap.h" #include "libcli/security/proto.h" #include "auth/credentials/credentials.h" +#include "librpc/gen_ndr/ndr_samr.h" #include "librpc/gen_ndr/ndr_samr_c.h" +#include "librpc/gen_ndr/ndr_security.h" /* * complete a domain join, when joining to a AD domain: -- cgit From 4f1c8daa36a7a0372c5fd9eab51f3c16ee81c49d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 12:43:28 +0000 Subject: r14470: Remove some unnecessary headers. (This used to be commit f7312dab3b9aba2b2b82e8a6e0c483a32a03a63a) --- source4/libnet/libnet_join.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index a517aa3733..6cee4fa2df 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -22,7 +22,6 @@ #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" @@ -31,7 +30,6 @@ #include "db_wrap.h" #include "libcli/security/proto.h" #include "auth/credentials/credentials.h" -#include "librpc/gen_ndr/ndr_samr.h" #include "librpc/gen_ndr/ndr_samr_c.h" #include "librpc/gen_ndr/ndr_security.h" -- cgit From d52f31848da2d1d6eb3b026d2922f8a11d64b956 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 25 Mar 2006 11:52:53 +0000 Subject: r14716: Remove username from debug message, it just causes valgrind assertions. Andrew Bartlett (This used to be commit c978fea2a14979d8431b2be9ff35ab47fc1a4a08) --- source4/libnet/libnet_join.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 6cee4fa2df..b105ce78ef 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -136,16 +136,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\n", 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\n", nt_errstr(status)); talloc_free(tmp_ctx); return status; -- cgit From 1af925f394b1084779f5b1b5a10c2ec512d7e5be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 2 Apr 2006 12:02:01 +0000 Subject: r14860: create libcli/security/security.h metze (This used to be commit 9ec706238c173992dc938d537bdf1103bf519dbf) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index b105ce78ef..e50755229d 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -28,7 +28,7 @@ #include "passdb/secrets.h" #include "dsdb/samdb/samdb.h" #include "db_wrap.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" #include "auth/credentials/credentials.h" #include "librpc/gen_ndr/ndr_samr_c.h" #include "librpc/gen_ndr/ndr_security.h" -- cgit From e002300f238dd0937dd9f768e366c006945e8baa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Apr 2006 17:34:49 +0000 Subject: r15328: Move some functions around, remove dependencies. Remove some autogenerated headers (which had prototypes now autogenerated by pidl) Remove ndr_security.h from a few places - it's no longer necessary (This used to be commit c19c2b51d3e1ad347120b06a22bda5ec586c22e8) --- source4/libnet/libnet_join.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index e50755229d..9185015da0 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -31,7 +31,6 @@ #include "libcli/security/security.h" #include "auth/credentials/credentials.h" #include "librpc/gen_ndr/ndr_samr_c.h" -#include "librpc/gen_ndr/ndr_security.h" /* * complete a domain join, when joining to a AD domain: -- cgit From 5f4d86f955d939e96ec9b81c8a9d080aab4354b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 4 May 2006 10:03:41 +0000 Subject: r15426: Implement SPNEGO as the default RPC authentication mechanism. Where this isn't supported, fallback to NTLM. Also, where we get a failure as 'logon failure', try and do a '3 tries' for the password, like we already do for CIFS. (Incomplete: needs a mapping between RPC errors and the logon failure NTSTATUS). Because we don't yet support Kerberos sign/seal to win2k3 SP1 for DCE/RPC, disable this (causing SPNEGO to negotiate NTLM) when kerberos isn't demanded. Andrew Bartlett (This used to be commit b3212d1fb91b26c1d326a289560106dffe1d2e80) --- source4/libnet/libnet_join.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 9185015da0..743076ee72 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -481,9 +481,9 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - samr_pipe = connect_with_info->out.dcerpc_pipe, + samr_pipe = connect_with_info->out.dcerpc_pipe; - status = dcerpc_pipe_auth(samr_pipe, + status = dcerpc_pipe_auth(tmp_ctx, &samr_pipe, connect_with_info->out.dcerpc_pipe->binding, &dcerpc_table_samr, ctx->cred); if (!NT_STATUS_IS_OK(status)) { -- cgit From 538adbf677d225da8abc2adaefafa2a7c305ec17 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 4 May 2006 14:52:03 +0000 Subject: r15435: Turn libnet_RpcConnectDCInfo into another level of libnet_RpcConnect and make it async. Also, update any other usages of old function. Build goes fine and so do tests, comments to follow. rafal (This used to be commit aef0a2de9d2f01a6f619e3fccc8715288f5c37a3) --- source4/libnet/libnet_join.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 743076ee72..fb28eaed2f 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -404,7 +404,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru NTSTATUS status, cu_status; - struct libnet_RpcConnectDCInfo *connect_with_info; + struct libnet_RpcConnect *connect_with_info; struct dcerpc_pipe *samr_pipe; struct samr_Connect sc; @@ -445,7 +445,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return NT_STATUS_NO_MEMORY; } - connect_with_info = talloc(tmp_ctx, struct libnet_RpcConnectDCInfo); + connect_with_info = talloc(tmp_ctx, struct libnet_RpcConnect); if (!connect_with_info) { r->out.error_string = NULL; talloc_free(tmp_ctx); @@ -454,19 +454,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* prepare connect to the LSA pipe of PDC */ if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) { - connect_with_info->level = LIBNET_RPC_CONNECT_PDC; connect_with_info->in.name = r->in.domain_name; } else { - connect_with_info->level = LIBNET_RPC_CONNECT_BINDING; connect_with_info->in.binding = r->in.binding; } + connect_with_info->level = LIBNET_RPC_CONNECT_DC_INFO; connect_with_info->in.dcerpc_iface = &dcerpc_table_samr; + /* establish a SAMR connection, on the same CIFS transport */ - - status = libnet_RpcConnectDCInfo(ctx, connect_with_info); + status = libnet_RpcConnect(ctx, tmp_ctx, connect_with_info); if (!NT_STATUS_IS_OK(status)) { if (r->in.binding) { r->out.error_string = talloc_asprintf(mem_ctx, -- cgit From 5f36534629f7f755c7ad8681ec2322baa50f5504 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 7 May 2006 18:11:47 +0000 Subject: r15500: Add support for interactive prompting on bad passwords to the RPC libraries. This support requires that the bind_ack and alter_ack recv functions also be send the DCE/RPC fault. This would be best done by having the ack run as a normal RPC reply callback, but this isn't easily possible for now. Andrew Bartlett (This used to be commit be6dde22fe728d64d47875699d3421c6d8d872a4) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index fb28eaed2f..608568bc53 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -482,7 +482,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru samr_pipe = connect_with_info->out.dcerpc_pipe; - status = dcerpc_pipe_auth(tmp_ctx, &samr_pipe, + status = dcerpc_pipe_auth(&samr_pipe, connect_with_info->out.dcerpc_pipe->binding, &dcerpc_table_samr, ctx->cred); if (!NT_STATUS_IS_OK(status)) { -- cgit From 7f0a396e3b4f02aea24d6e6d8d6123c5aa737248 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 7 May 2006 19:55:14 +0000 Subject: r15504: Revert -r 15500 and -r 15503 until I'm awake, and can get my head around the mess that is composite functions... Async might be all the rage, but it's bloody painful to debug. Andrew Bartlett (This used to be commit 756e1dad7ce54b83f8170db3434bfcfc4afe7e65) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 608568bc53..fb28eaed2f 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -482,7 +482,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru samr_pipe = connect_with_info->out.dcerpc_pipe; - status = dcerpc_pipe_auth(&samr_pipe, + status = dcerpc_pipe_auth(tmp_ctx, &samr_pipe, connect_with_info->out.dcerpc_pipe->binding, &dcerpc_table_samr, ctx->cred); if (!NT_STATUS_IS_OK(status)) { -- cgit From 345c9f043fa76aecfd9edf017fa77ea393e95d4f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Jun 2006 16:08:43 +0000 Subject: r16226: Fixes for various segfault bugs found against a buggy Samba4. With the current API we need to check both that the RPC didn't fault, and that the query succeeded. Also print the right things in debug messages. Andrew Bartlett (This used to be commit d18e515391f8f5038e9aaaba596099052011b53a) --- source4/libnet/libnet_join.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index fb28eaed2f..1d64257ca3 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -642,7 +642,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru 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)); + r->in.account_name, nt_errstr(status)); talloc_free(tmp_ctx); return status; } @@ -650,7 +650,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } 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)); + r->in.account_name, nt_errstr(status)); talloc_free(tmp_ctx); return status; } -- cgit From a23b63a8e54db7d0ec98ad95cdca11dd4d039e17 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 13 Aug 2006 08:00:36 +0000 Subject: r17516: Change helper function names to make more clear what they are meant to do (This used to be commit ad75cf869550af66119d0293503024d41d834e02) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 1d64257ca3..ce6cca9b49 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -249,7 +249,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J } /* 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); + kvno = ldb_msg_find_attr_as_uint(res->msgs[0], "msDS-KeyVersionNumber", 0); /* Prepare a new message, for the modify */ msg = ldb_msg_new(tmp_ctx); -- cgit From 626d3ad01293853fa815cf348f6dbc65b7a3a57e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 31 Aug 2006 08:15:23 +0000 Subject: r17954: Avoid including \n in error strings (left over from DEBUG() conversion). Make it easier to debug CrackNames failures. Andrew Bartlett (This used to be commit 5dd07074db0b25ea2e929bbdcf89f26e3665bd1c) --- source4/libnet/libnet_join.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index ce6cca9b49..50f60123b8 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -135,14 +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 failed - %s\n", + "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 failed - %s\n", + "dcerpc_drsuapi_DsBind failed - %s", nt_errstr(status)); talloc_free(tmp_ctx); return status; @@ -150,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; @@ -179,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); @@ -187,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); @@ -196,17 +196,23 @@ 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. */ @@ -346,7 +352,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 @@ -354,7 +360,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; } -- cgit From e7ede84c331b112efa5232d0f7dcc6732b95aebe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 18 Sep 2006 09:54:44 +0000 Subject: r18609: error_string should not contain newlines. Guenther (This used to be commit 556666756418ad50c533199c736fe3696a7e20cb) --- source4/libnet/libnet_join.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 50f60123b8..14e3e5b719 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -248,7 +248,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J 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", + 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; @@ -313,7 +313,7 @@ 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", + "Failed to replace entries on %s", ldb_dn_linearize(tmp_ctx, msg->dn)); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -335,7 +335,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); @@ -343,7 +343,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); @@ -602,7 +602,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; @@ -647,7 +647,7 @@ 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", + "samr_CreateUser2 (recreate) for [%s] failed: %s", r->in.account_name, nt_errstr(status)); talloc_free(tmp_ctx); return status; @@ -655,7 +655,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } } else if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, - "samr_CreateUser2 for [%s] failed: %s\n", + "samr_CreateUser2 for [%s] failed: %s", r->in.account_name, nt_errstr(status)); talloc_free(tmp_ctx); return status; @@ -679,7 +679,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; @@ -723,7 +723,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; @@ -735,7 +735,7 @@ 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", + "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; @@ -910,7 +910,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; } @@ -1135,7 +1135,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, /* 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", + r->out.error_string = talloc_asprintf(mem_ctx, "Failed to create secret record %s", ldb_dn_linearize(ldb, msg->dn)); talloc_free(tmp_mem); return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -1154,14 +1154,14 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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", + r->out.error_string = talloc_asprintf(mem_ctx, "Failed to read secrets for keytab update for %s", 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", + r->out.error_string = talloc_asprintf(mem_ctx, "Failed to update keytab for %s", filter); talloc_free(tmp_mem); return NT_STATUS_UNSUCCESSFUL; -- cgit From 9ce0de670bc3a19a189fe45442b929ad0f2ec3b5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Oct 2006 07:25:51 +0000 Subject: r19261: Fix use of unitialised variables. (The binding string is used, if not NULL). This showed up in a manual pre-TP3 test of the 'net samdump' code, and shows the critical need for the windows testing infrustructure on the build farm. Andrew Bartlett (This used to be commit 9cef40779ad987b506b1f514a67b5b1c8aea9969) --- source4/libnet/libnet_join.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 14e3e5b719..5781bc19c2 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -460,9 +460,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* prepare connect to the LSA pipe of PDC */ if (r->in.level == LIBNET_JOINDOMAIN_AUTOMATIC) { + connect_with_info->in.binding = NULL; connect_with_info->in.name = r->in.domain_name; } else { connect_with_info->in.binding = r->in.binding; + connect_with_info->in.name = NULL; } connect_with_info->level = LIBNET_RPC_CONNECT_DC_INFO; -- cgit From 57b8c5cd227d33b2eec34ed503b0b14c04344a87 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 13 Oct 2006 13:01:48 +0000 Subject: r19266: Add a target_hostname element to the binding struct. This allows us to perform a lookup once, resolve the name to an IP, while still communicating the full name to the lower layers, for kerberos etc. This fixes 'net samdump', which was failing due to the schannel target name being *smbserver. Andrew Bartlett (This used to be commit 0546f487f4cc99b5549dc1e457ea243d4bd66333) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 5781bc19c2..57ecddd9da 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -229,7 +229,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J /* 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); -- cgit From 59b66744f7318d8197f0d2029bf3b641dafa327e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 15 Oct 2006 23:14:19 +0000 Subject: r19299: Fix possible memleaks (This used to be commit 6fad80bb09113a60689061a2de67711c9924708b) --- source4/libnet/libnet_join.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 57ecddd9da..8112d043f6 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -247,6 +247,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J /* search for the user's record */ ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, NULL, attrs, &res); + talloc_steal(tmp_ctx, res); if (ret != LDB_SUCCESS || res->count != 1) { r->out.error_string = talloc_asprintf(r, "ldb_search for %s failed - %s", account_dn_str, ldb_errstring(remote_ldb)); -- cgit From 2ac52f809afcd85ee7ed80bbac64594f1e780942 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 16 Oct 2006 01:20:31 +0000 Subject: r19309: Split out checks for LDB_SUCCESS from checks for the expected number of returned entries. Andrew Bartlett (This used to be commit 84efd9ecd994b53817dde8c1ad995afb7ebc8192) --- source4/libnet/libnet_join.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 8112d043f6..96d9e7f0de 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -246,15 +246,23 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J /* search for the user's record */ ret = ldb_search(remote_ldb, account_dn, LDB_SCOPE_BASE, - NULL, attrs, &res); - talloc_steal(tmp_ctx, res); - if (ret != LDB_SUCCESS || res->count != 1) { + 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; } + 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; + } + /* If we have a kvno recorded in AD, we need it locally as well */ kvno = ldb_msg_find_attr_as_uint(res->msgs[0], "msDS-KeyVersionNumber", 0); -- cgit From 5a6e2bc9aeb71c94eeab8c0a5755aded989b039d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Nov 2006 16:11:52 +0000 Subject: r19573: Move secrets.o into param/ (subsystems haven't been integrated yet). (This used to be commit 8143de855c0b65346b2d8e59ecdb78952927de4a) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 96d9e7f0de..b0907c5461 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -25,7 +25,7 @@ #include "librpc/gen_ndr/ndr_drsuapi_c.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" -#include "passdb/secrets.h" +#include "param/secrets.h" #include "dsdb/samdb/samdb.h" #include "db_wrap.h" #include "libcli/security/security.h" -- cgit From 13dbee3ffea6065a826f010e50c9b4eb2c6ad109 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 00:48:36 +0000 Subject: r19598: Ahead of a merge to current lorikeet-heimdal: Break up auth/auth.h not to include the world. Add credentials_krb5.h with the kerberos dependent prototypes. Andrew Bartlett (This used to be commit 2b569c42e0fbb596ea82484d0e1cb22e193037b9) --- source4/libnet/libnet_join.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index b0907c5461..01872eb7fc 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -30,6 +30,7 @@ #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" /* -- cgit From 4889eb9f7aae9349e426d0f6d2217adff67eaebd Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Nov 2006 00:59:34 +0000 Subject: r19831: Big ldb_dn optimization and interfaces enhancement patch This patch changes a lot of the code in ldb_dn.c, and also removes and add a number of manipulation functions around. The aim is to avoid validating a dn if not necessary as the validation code is necessarily slow. This is mainly to speed up internal operations where input is not user generated and so we can assume the DNs need no validation. The code is designed to keep the data as a string if possible. The code is not yet 100% perfect, but pass all the tests so far. A memleak is certainly present, I'll work on that next. Simo. (This used to be commit a580c871d3784602a9cce32d33419e63c8236e63) --- source4/libnet/libnet_join.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 01872eb7fc..e68b0d6235 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -62,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; @@ -219,8 +219,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J /* 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) { + 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); @@ -855,7 +855,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[] = { @@ -961,15 +961,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; -- cgit From a9e31b33b55a873c2f01db5e348560176adf863d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Nov 2006 02:05:19 +0000 Subject: r19832: better prototypes for the linearization functions: - ldb_dn_get_linearized returns a const string - ldb_dn_alloc_linearized allocs astring with the linearized dn (This used to be commit 3929c086d5d0b3f08b1c4f2f3f9602c3f4a9a4bd) --- source4/libnet/libnet_join.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index e68b0d6235..ed98699804 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -324,7 +324,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J r->out.error_string = talloc_asprintf(r, "Failed to replace entries on %s", - ldb_dn_linearize(tmp_ctx, msg->dn)); + ldb_dn_get_linearized(msg->dn)); talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -1148,7 +1148,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, ret = samdb_add(ldb, tmp_mem, msg); if (ret != 0) { r->out.error_string = talloc_asprintf(mem_ctx, "Failed to create secret record %s", - ldb_dn_linearize(ldb, msg->dn)); + ldb_dn_get_linearized(msg->dn)); talloc_free(tmp_mem); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -1163,7 +1163,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(creds); - filter = talloc_asprintf(mem_ctx, "dn=%s", ldb_dn_linearize(mem_ctx, msg->dn)); + filter = talloc_asprintf(mem_ctx, "dn=%s", ldb_dn_get_linearized(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", -- cgit From 542729273c2356abe3637bd65463a20b87b11404 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 28 Nov 2006 17:30:43 +0000 Subject: r19934: - allow to pass a samr_UserInfo21 struct to be passed to libnet_SetPassword() - as the SetUserInfo2() levels 26/25 and 24/23 have the same encryption but 26 and 24 change only the password and 25 and 23 take a info21 and change the password, we now use 26 with fallback to 24 or 25 with fallback to 23. - use samr_SetUserInfo2() to match what w2k3 does (works also against nt4) - pass the info21 to libnet_SetPassword() to set acct_flags and full_name together with the password (to match what w2k3 does) metze (This used to be commit 1b86af32f3069cc75ae645698d3f92a0798e38f7) --- source4/libnet/libnet_join.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index ed98699804..8e3753065e 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -408,9 +408,9 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J * - potentially delete and recreate the user * - assert the account is of the right type with samrQueryUserInfo * - * - 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 * - * - do a samrSetUserInfo to set the account flags * - do some ADS specific things when we join as Domain Controller, * look at libnet_joinADSDomain() for the details */ @@ -432,8 +432,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; @@ -756,7 +755,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; @@ -770,11 +769,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)) { @@ -783,26 +789,6 @@ 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, connect_with_info->out.domain_sid, rid); if (!account_sid) { r->out.error_string = NULL; -- cgit From 1e6807d8a1b74e48b5df144469ddb0179adea081 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 10 Dec 2006 22:21:20 +0000 Subject: r20099: Add some comments, and correct others. Andrew Bartlett (This used to be commit d1b1a4c059bfa93bd55f9ffc718e802695c50cc9) --- source4/libnet/libnet_join.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 8e3753065e..3bd1a9783e 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -467,7 +467,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru 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) { connect_with_info->in.binding = NULL; connect_with_info->in.name = r->in.domain_name; @@ -476,11 +476,13 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru connect_with_info->in.name = NULL; } + /* 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 = &dcerpc_table_samr; /* - establish a SAMR connection, on the same CIFS transport + establish the SAMR connection */ status = libnet_RpcConnect(ctx, tmp_ctx, connect_with_info); if (!NT_STATUS_IS_OK(status)) { -- cgit From e8e61a414a52a49a86cc5f3b71a55141a2bbb56b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 10 Dec 2006 23:28:36 +0000 Subject: r20102: Do not reference remote_ldb before we initialise it. This should fix up many of the build farm failures. Andrew Bartlett (This used to be commit 924af98ffaab3735c3f31014059e7cd0abd71919) --- source4/libnet/libnet_join.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 3bd1a9783e..df61df7f10 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -219,14 +219,6 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J /* Store the DN of our machine account. */ account_dn_str = r_crack_names.out.ctr.ctr1->array[0].result_name; - 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; - } - /* 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", @@ -245,6 +237,14 @@ 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); -- cgit From 334f78d206d37cbb5863af38cb5160d69fcd9183 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 11 Dec 2006 23:59:03 +0000 Subject: r20113: Update the DRSUAPI CrackNames test to explore a few more cases, and in particular to verify more expected results. Also return more details from the join process. Now we also return the machine account's GUID. Andrew Bartlett (This used to be commit 5b32f102af1fc7acb56bf7eaa40068d60a1ee396) --- source4/libnet/libnet_join.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index df61df7f10..627cc97e32 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -76,6 +76,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J "msDS-KeyVersionNumber", "servicePrincipalName", "dNSHostName", + "objectGUID", NULL, }; @@ -264,9 +265,6 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J return NT_STATUS_UNSUCCESSFUL; } - /* If we have a kvno recorded in AD, we need it locally as well */ - kvno = ldb_msg_find_attr_as_uint(res->msgs[0], "msDS-KeyVersionNumber", 0); - /* Prepare a new message, for the modify */ msg = ldb_msg_new(tmp_ctx); if (!msg) { @@ -383,7 +381,12 @@ 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(remote_ldb, r); -- cgit From ba1be45aa252d3acf30e06108aad534128f4b77b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 16 Dec 2006 01:24:43 +0000 Subject: r20205: remove unused var metze (This used to be commit a77e1bd1b48e953773db47a5469b1712794f26cf) --- source4/libnet/libnet_join.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 627cc97e32..871b59eae6 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -70,8 +70,6 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J int ret, rtn; - unsigned int kvno; - const char * const attrs[] = { "msDS-KeyVersionNumber", "servicePrincipalName", -- cgit From 728e4e311c26f7db9afb630267de0ca5ab6734ad Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Dec 2006 23:43:05 +0000 Subject: r20294: Without this we don't do the ADS join against Win2k3 SP1 Andrew Bartlett (This used to be commit 7a7f1a97644ab420cf43282d6979881c5c4c59b6) --- source4/libnet/libnet_join.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 871b59eae6..a60ae47b5f 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -536,6 +536,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } 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()); + connect_with_info->out.realm = talloc_strdup(tmp_ctx, lp_realm()); } } -- cgit From 7d7d01cf4e9bbb43d9579f09751b00118a0c577b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Dec 2006 00:36:57 +0000 Subject: r20397: Another user of the DsCrackNames call needs a rename following IDL clarification. Andrew Bartlett (This used to be commit 77169958fc42d8ea4561f6218919a34c330259d3) --- source4/libnet/libnet_join.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index a60ae47b5f..e2c2e99d11 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -160,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; -- cgit From d2bfa6611924a6f6c2bc0571f71414818d8968fd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 23 Jan 2007 01:33:31 +0000 Subject: r20964: Show the domain name we figured out, rather than a null pointer (in some error cases) Andrew Bartlett (This used to be commit 4195839d1a6102d7c6ae17c1b1db0418c99c9241) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index e2c2e99d11..a40c8607bf 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -117,7 +117,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J 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; -- cgit From c2c8650825b8c8625a97f318d50bcb1da6b92405 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Feb 2007 13:42:54 +0000 Subject: r21141: Attempt to fix the build (This used to be commit 3f41a4b014a47b3c751066f5d1bef7f76f4be831) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index a40c8607bf..f47ea410ae 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -1154,7 +1154,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, } cli_credentials_set_conf(creds); filter = talloc_asprintf(mem_ctx, "dn=%s", ldb_dn_get_linearized(msg->dn)); - status = cli_credentials_set_secrets(creds, NULL, filter); + status = cli_credentials_set_secrets(creds, NULL, 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", filter); -- cgit From e47305005221b33e54c318d2e507f56efd4b6b8f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Feb 2007 05:41:04 +0000 Subject: r21175: Fix the kerberos keytab update code to handle deletes. Fix the join code to know that the ldb layer handles the keytab update. Andrew Bartlett (This used to be commit d3fbc089f4161ae71b21077d50130fdabd8b2d77) --- source4/libnet/libnet_join.c | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index f47ea410ae..44e2dfe5f0 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -860,7 +860,6 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, uint32_t acct_type = 0; const char *account_name; const char *netbios_name; - char *filter; r->out.error_string = NULL; @@ -1143,33 +1142,6 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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_get_linearized(msg->dn)); - status = cli_credentials_set_secrets(creds, NULL, 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", - 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", - 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; -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/libnet/libnet_join.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 44e2dfe5f0..cecf07ed4e 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,8 +16,7 @@ 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" -- cgit From f14bd1a90ab47a418c0ec2492990a417a0bb3bf6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 19 Aug 2007 21:23:03 +0000 Subject: r24557: rename 'dcerpc_table_' -> 'ndr_table_' metze (This used to be commit 84651aee81aaabbebf52ffc3fbcbabb2eec6eed5) --- source4/libnet/libnet_join.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index cecf07ed4e..40debc63dc 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -110,7 +110,7 @@ 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)) { @@ -479,7 +479,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* 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 = &dcerpc_table_samr; + connect_with_info->in.dcerpc_iface = &ndr_table_samr; /* establish the SAMR connection @@ -503,7 +503,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru status = dcerpc_pipe_auth(tmp_ctx, &samr_pipe, connect_with_info->out.dcerpc_pipe->binding, - &dcerpc_table_samr, ctx->cred); + &ndr_table_samr, ctx->cred); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "SAMR bind failed: %s", -- cgit From ffeee68e4b72dd94fee57366bd8d38b8c284c3d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 12:42:09 +0000 Subject: r25026: Move param/param.h out of includes.h (This used to be commit abe8349f9b4387961ff3665d8c589d61cd2edf31) --- source4/libnet/libnet_join.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 40debc63dc..9404bc874d 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -31,6 +31,7 @@ #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: -- cgit From 37d53832a4623653f706e77985a79d84bd7c6694 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Sep 2007 01:17:46 +0000 Subject: r25398: Parse loadparm context to all lp_*() functions. (This used to be commit 3fcc960839c6e5ca4de2c3c042f12f369ac5f238) --- source4/libnet/libnet_join.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 9404bc874d..553bde615b 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -535,8 +535,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru 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()); - connect_with_info->out.realm = talloc_strdup(tmp_ctx, lp_realm()); + 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)); } } @@ -888,7 +888,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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); -- cgit From 2f3551ca7cee59d4d053cceb87abdf1da1b3a1ad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 Oct 2007 18:52:55 +0000 Subject: r25446: Merge some changes I made on the way home from SFO: 2007-09-29 More higher-level passing around of lp_ctx. 2007-09-29 Fix warning. 2007-09-29 Pass loadparm contexts on a higher level. 2007-09-29 Avoid using global loadparm context. (This used to be commit 3468952e771ab31f90b6c374ade01c5550810f42) --- source4/libnet/libnet_join.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 553bde615b..1fd84146de 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -228,7 +228,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J return NT_STATUS_NO_MEMORY; } - remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, + remote_ldb = ldb_wrap_connect(tmp_ctx, global_loadparm, + remote_ldb_url, NULL, ctx->cred, 0, NULL); if (!remote_ldb) { r->out.error_string = NULL; -- cgit From 2151cde58014ea2e822c13d2f8a369b45dc19ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:28:14 +0000 Subject: r25554: Convert last instances of BOOL, True and False to the standard types. (This used to be commit 566aa14139510788548a874e9213d91317f83ca9) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 1fd84146de..4abd2954f8 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -926,7 +926,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, r2->in.netbios_name = netbios_name; r2->in.level = LIBNET_JOINDOMAIN_AUTOMATIC; r2->in.acct_type = acct_type; - r2->in.recreate_account = False; + 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); -- cgit From ca0b72a1fdb7bd965065e833df34662afef0423e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 16 Nov 2007 20:12:00 +0100 Subject: r26003: Split up DB_WRAP, as first step in an attempt to sanitize dependencies. (This used to be commit 56dfcb4f2f8e74c9d8b2fe3a0df043781188a555) --- source4/libnet/libnet_join.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 4abd2954f8..215217bfef 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -26,7 +26,8 @@ #include "lib/ldb/include/ldb_errors.h" #include "param/secrets.h" #include "dsdb/samdb/samdb.h" -#include "db_wrap.h" +#include "ldb_wrap.h" +#include "util/util_ldb.h" #include "libcli/security/security.h" #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_krb5.h" -- cgit From 25143a26481e735c46c61aa3673eb4858a7819be Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 27 Nov 2007 01:25:11 +0100 Subject: r26135: Remove samdb_add(), samdb_delete() and samdb_modify(), which were just wrappers to ldb_add() etc. samdb_replace() remains, as it sets flags on all entries as 'replace'. Andrew Bartlett (This used to be commit 09c0faa5b7e1a560bf13b99a2584012a47377bb6) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 215217bfef..d80ff34d0f 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -1136,7 +1136,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, } /* create the secret */ - ret = samdb_add(ldb, tmp_mem, msg); + 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)); -- cgit From 991ee1aff092187bcfdd0ee1d9eb15361f73d5f7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Nov 2007 16:01:16 +0100 Subject: r26205: Pass loadparm_context to secrets_db_connect() rather than using global context. (This used to be commit 5718b6cfee86ddfc9cf405c98c68ba848df4d9d7) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index d80ff34d0f..25ad0ca440 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -909,7 +909,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, * Local secrets are stored in secrets.ldb * open it to make sure we can write the info into it after the join */ - ldb = secrets_db_connect(tmp_mem); + ldb = secrets_db_connect(tmp_mem, global_loadparm); if (!ldb) { r->out.error_string = talloc_asprintf(mem_ctx, -- cgit From 4c4323009fa83f00ed319de59a3aad48fcd65994 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 02:37:04 +0100 Subject: r26327: Explicit loadparm_context for RPC client functions. (This used to be commit eeb2251d22b3d6e0379444a73af69d1014692b07) --- source4/libnet/libnet_join.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 25ad0ca440..2f14799ced 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -114,7 +114,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J drsuapi_binding, &ndr_table_drsuapi, ctx->cred, - ctx->event_ctx); + ctx->event_ctx, + ctx->lp_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", @@ -506,7 +507,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru status = dcerpc_pipe_auth(tmp_ctx, &samr_pipe, connect_with_info->out.dcerpc_pipe->binding, - &ndr_table_samr, ctx->cred); + &ndr_table_samr, ctx->cred, ctx->lp_ctx); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "SAMR bind failed: %s", -- cgit From 6c77f353d3d952b46b401ab29837ba5b75e353c2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 02:37:13 +0100 Subject: r26328: remove more uses of global_loadparm. (This used to be commit 40ae12c08647c47a9c504d39ee6f61c32b4e5748) --- source4/libnet/libnet_join.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 2f14799ced..6d7fcd09ad 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -230,7 +230,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J return NT_STATUS_NO_MEMORY; } - remote_ldb = ldb_wrap_connect(tmp_ctx, global_loadparm, + remote_ldb = ldb_wrap_connect(tmp_ctx, ctx->lp_ctx, remote_ldb_url, NULL, ctx->cred, 0, NULL); if (!remote_ldb) { @@ -538,8 +538,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru 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)); + connect_with_info->out.domain_name = talloc_strdup(tmp_ctx, lp_workgroup(ctx->lp_ctx)); + connect_with_info->out.realm = talloc_strdup(tmp_ctx, lp_realm(ctx->lp_ctx)); } } @@ -891,7 +891,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, if (r->in.netbios_name != NULL) { netbios_name = r->in.netbios_name; } else { - netbios_name = talloc_reference(tmp_mem, lp_netbios_name(global_loadparm)); + netbios_name = talloc_reference(tmp_mem, lp_netbios_name(ctx->lp_ctx)); if (!netbios_name) { r->out.error_string = NULL; talloc_free(tmp_mem); @@ -910,7 +910,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, * Local secrets are stored in secrets.ldb * open it to make sure we can write the info into it after the join */ - ldb = secrets_db_connect(tmp_mem, global_loadparm); + ldb = secrets_db_connect(tmp_mem, ctx->lp_ctx); if (!ldb) { r->out.error_string = talloc_asprintf(mem_ctx, -- cgit From 4b0199a5493ea2b88558cc40871e63c1dc8dbb56 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 12 Dec 2007 02:15:29 +0100 Subject: r26409: Pass smb ports along. (This used to be commit 2833f320de1f1fd39c710ad0a61c3fa1bb1df31f) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 6d7fcd09ad..8297172a58 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -390,7 +390,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J r->out.account_guid = samdb_result_guid(res->msgs[0], "objectGUID"); if (r->in.acct_type == ACB_SVRTRUST) { - status = libnet_JoinSite(remote_ldb, r); + status = libnet_JoinSite(ctx, remote_ldb, r); } talloc_free(tmp_ctx); -- cgit From ed4fde2acc82a55bcd7f0b05ae37a7a84560d250 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 26 Dec 2007 10:43:35 +0100 Subject: libnet: Rename a variable so it does not shadow a global. (This used to be commit a5b9d2f33279e0f96a36acbf3da7c018aadf08c9) --- source4/libnet/libnet_join.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 8297172a58..22134518d6 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -1064,7 +1064,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_INTERNAL_DB_CORRUPTION; } else { const struct ldb_val *private_keytab; - const struct ldb_val *krb5_keytab; + const struct ldb_val *krb5_main_keytab; const struct ldb_val *prior_secret; const struct ldb_val *prior_modified_time; int i; @@ -1125,9 +1125,10 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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); + 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); -- cgit From 29b25a1b043b1564a25765d553f3950cd5edb782 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 9 Apr 2008 14:56:24 +1000 Subject: Factor out filling in the secrets database. This allows the vampire code to start with a join, but fill in the secrets only when the process is compleated. Andrew Bartlett (This used to be commit c90751040e941d10234131852815e1cec1a54efe) --- source4/libnet/libnet_join.c | 196 +++++++++++++++++++++++++------------------ 1 file changed, 116 insertions(+), 80 deletions(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 22134518d6..4549cd6e93 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -839,13 +839,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } -static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, - TALLOC_CTX *mem_ctx, - struct libnet_Join *r) +NTSTATUS libnet_set_join_secrets(struct libnet_context *ctx, + TALLOC_CTX *mem_ctx, + struct libnet_set_join_secrets *r) { - NTSTATUS status; TALLOC_CTX *tmp_mem; - struct libnet_JoinDomain *r2; int ret, rtn; struct ldb_context *ldb; struct ldb_dn *base_dn; @@ -860,56 +858,13 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, "privateKeytab", NULL }; - 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; - } - - /* - * Local secrets are stored in secrets.ldb - * open it to make sure we can write the info into it after the join - */ + /* Open the secrets database */ ldb = secrets_db_connect(tmp_mem, ctx->lp_ctx); if (!ldb) { r->out.error_string @@ -919,23 +874,6 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - /* - * 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; - } - /* * now prepare the record for secrets.ldb */ @@ -961,21 +899,21 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, } msg->dn = ldb_dn_copy(tmp_mem, base_dn); - if ( ! ldb_dn_add_child_fmt(msg->dn, "flatname=%s", r2->out.domain_name)) { + 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", r2->out.domain_name); + 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 (r2->out.realm) { - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "realm", r2->out.realm); + 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); @@ -997,14 +935,14 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_NO_MEMORY; } - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "secret", r2->out.join_password); + 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", r2->in.account_name); + 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); @@ -1018,9 +956,9 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_NO_MEMORY; } - if (r2->out.kvno) { + if (r->in.kvno) { rtn = samdb_msg_add_uint(ldb, tmp_mem, msg, "msDS-KeyVersionNumber", - r2->out.kvno); + r->in.kvno); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); @@ -1028,9 +966,9 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, } } - if (r2->out.domain_sid) { + if (r->in.domain_sid) { rtn = samdb_msg_add_dom_sid(ldb, tmp_mem, msg, "objectSid", - r2->out.domain_sid); + r->in.domain_sid); if (rtn == -1) { r->out.error_string = NULL; talloc_free(tmp_mem); @@ -1047,7 +985,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, tmp_mem, base_dn, &msgs, attrs, "(|" SECRETS_PRIMARY_DOMAIN_FILTER "(realm=%s))", - r2->out.domain_name, r2->out.realm); + 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) { @@ -1059,7 +997,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, r->out.error_string = talloc_asprintf(mem_ctx, "Search for domain: %s and realm: %s failed: %s", - r2->out.domain_name, r2->out.realm, ldb_errstring(ldb)); + r->in.domain_name, r->in.realm, ldb_errstring(ldb)); talloc_free(tmp_mem); return NT_STATUS_INTERNAL_DB_CORRUPTION; } else { @@ -1082,7 +1020,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return NT_STATUS_NO_MEMORY; } } - rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secret", r2->out.join_password); + 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); @@ -1101,7 +1039,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, } } - rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "samAccountName", r2->in.account_name); + 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); @@ -1146,6 +1084,104 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, 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; -- cgit From 21fc7673780aa1d7c0caab7b17ff9171238913ba Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 12:23:44 +0200 Subject: Specify event_context to ldb_wrap_connect explicitly. (This used to be commit b4e1ae07a284c044704322446c94351c2decff91) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 4549cd6e93..b5b28df81d 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -230,7 +230,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J return NT_STATUS_NO_MEMORY; } - remote_ldb = ldb_wrap_connect(tmp_ctx, ctx->lp_ctx, + remote_ldb = ldb_wrap_connect(tmp_ctx, ctx->event_ctx, ctx->lp_ctx, remote_ldb_url, NULL, ctx->cred, 0, NULL); if (!remote_ldb) { -- cgit From 929adc9efa5cf985f0585214d30d18521aa1a821 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 14 Jun 2008 11:24:17 -0400 Subject: Make up the right dependencies now that ldb depends on libevents (This used to be commit 3b8eec7ca334528cad3cdcd5e3fc5ee555d8d0e0) --- source4/libnet/libnet_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libnet/libnet_join.c') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index b5b28df81d..5776888cb0 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -865,7 +865,7 @@ NTSTATUS libnet_set_join_secrets(struct libnet_context *ctx, } /* Open the secrets database */ - ldb = secrets_db_connect(tmp_mem, ctx->lp_ctx); + ldb = secrets_db_connect(tmp_mem, ctx->event_ctx, ctx->lp_ctx); if (!ldb) { r->out.error_string = talloc_asprintf(mem_ctx, -- cgit