[SCM] Samba Shared Repository - branch v3-4-stable updated - release-3-4-0rc1-13-g518526b

Karolin Seeger kseeger at samba.org
Tue Jun 30 07:16:35 GMT 2009


The branch, v3-4-stable has been updated
       via  518526bf6832a310551eeae018c5b703e9db3e64 (commit)
       via  6e614b50e9fa0e46ae200e681c4505ec3f095f45 (commit)
      from  d96b0c5f9e4e53c7dc53532c28e4ec42c70232a4 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-4-stable


- Log -----------------------------------------------------------------
commit 518526bf6832a310551eeae018c5b703e9db3e64
Author: Karolin Seeger <kseeger at samba.org>
Date:   Tue Jun 30 09:14:23 2009 +0200

    WHATSNEW: Update changes since 3.4.0rc1.
    
    Karolin
    (cherry picked from commit 21c9ca179abc18cb3f898e1885adb293c785508c)

commit 6e614b50e9fa0e46ae200e681c4505ec3f095f45
Author: Jim McDonough <jmcd at samba.org>
Date:   Fri Jun 19 13:46:07 2009 -0400

    Don't require "Modify property" perms to unjoin bug #6481) "net ads leave" stopped working when "modify properties" permissions were not granted (meaning you had to be allowed to disable the account that you were about to delete).
    
    Libnetapi should not delete machine accounts, as this does not
    happen on win32.  The WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE flag
    really means "disable" (both in practice and docs).
    
    However, to keep the functionality in "net ads leave", we
    will still try to do the delete.  If this fails, we try
    to do the disable.
    
    Additionally, it is possible in windows to not disable or
    delete the account, but just tell the local machine that it
    is no longer in the account.  libnet can now do this as well.
    
    Don't use ads realm name for non-ads case.  #6481
    
    Also check that the connection to ads worked.
    (cherry picked from commit 75eacdd7e0faa72775c4a143193edd594bd99ee7)

-----------------------------------------------------------------------

Summary of changes:
 WHATSNEW.txt                             |    5 ++
 source3/lib/netapi/joindomain.c          |    1 +
 source3/libnet/libnet_join.c             |   61 ++++++++++++++++++++---------
 source3/librpc/gen_ndr/libnet_join.h     |    5 +-
 source3/librpc/gen_ndr/ndr_libnet_join.c |    1 +
 source3/librpc/idl/libnet_join.idl       |    1 +
 source3/utils/net_ads.c                  |   11 ++++-
 7 files changed, 62 insertions(+), 23 deletions(-)


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 011f457..e10c567 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -222,6 +222,11 @@ o    David Markey <admin at dmarkey.com>
      * BUG 6514: Improve error message in 'net' when smb.conf is not available.
 
 
+o    Jim McDonough <jmcd at samba.org>
+     * BUG 6481: 'net ads leave' needs to try account deletion, NetUnjoinDomain
+       not.
+
+
 o    Bo Yang <boyang at samba.org>
      * BUG 6499: Fix building of pam_smbpass.
 
diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c
index 9eedc5d..9066d9b 100644
--- a/source3/lib/netapi/joindomain.c
+++ b/source3/lib/netapi/joindomain.c
@@ -203,6 +203,7 @@ WERROR NetUnjoinDomain_l(struct libnetapi_ctx *mem_ctx,
 
 	u->in.domain_name = domain;
 	u->in.unjoin_flags = r->in.unjoin_flags;
+	u->in.delete_machine_account = false;
 	u->in.modify_config = true;
 	u->in.debug = true;
 
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 376befe..5309452 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -1923,6 +1923,12 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
 		W_ERROR_HAVE_NO_MEMORY(r->in.domain_sid);
 	}
 
+	if (!(r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) &&
+	    !r->in.delete_machine_account) {
+		libnet_join_unjoindomain_remove_secrets(mem_ctx, r);
+		return WERR_OK;
+	}
+
 	if (!r->in.dc_name) {
 		struct netr_DsRGetDCNameInfo *info;
 		const char *dc;
@@ -1948,38 +1954,55 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
 		W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
 	}
 
-	status = libnet_join_unjoindomain_rpc(mem_ctx, r);
-	if (!NT_STATUS_IS_OK(status)) {
-		libnet_unjoin_set_error_string(mem_ctx, r,
-			"failed to disable machine account via rpc: %s",
-			get_friendly_nt_error_msg(status));
-		if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
-			return WERR_SETUP_NOT_JOINED;
-		}
-		return ntstatus_to_werror(status);
-	}
-
-	r->out.disabled_machine_account = true;
-
 #ifdef WITH_ADS
-	if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) {
+	/* for net ads leave, try to delete the account.  If it works,
+	   no sense in disabling.  If it fails, we can still try to
+	   disable it. jmcd */
+
+	if (r->in.delete_machine_account) {
 		ADS_STATUS ads_status;
-		libnet_unjoin_connect_ads(mem_ctx, r);
-		ads_status = libnet_unjoin_remove_machine_acct(mem_ctx, r);
+		ads_status = libnet_unjoin_connect_ads(mem_ctx, r);
+		if (ADS_ERR_OK(ads_status)) {
+			/* dirty hack */
+			r->out.dns_domain_name =
+				talloc_strdup(mem_ctx,
+					      r->in.ads->server.realm);
+			ads_status =
+				libnet_unjoin_remove_machine_acct(mem_ctx, r);
+		}
 		if (!ADS_ERR_OK(ads_status)) {
 			libnet_unjoin_set_error_string(mem_ctx, r,
 				"failed to remove machine account from AD: %s",
 				ads_errstr(ads_status));
 		} else {
 			r->out.deleted_machine_account = true;
-			/* dirty hack */
-			r->out.dns_domain_name = talloc_strdup(mem_ctx,
-							       r->in.ads->server.realm);
 			W_ERROR_HAVE_NO_MEMORY(r->out.dns_domain_name);
+			libnet_join_unjoindomain_remove_secrets(mem_ctx, r);
+			return WERR_OK;
 		}
 	}
 #endif /* WITH_ADS */
 
+	/* The WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE flag really means
+	   "disable".  */
+	if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) {
+		status = libnet_join_unjoindomain_rpc(mem_ctx, r);
+		if (!NT_STATUS_IS_OK(status)) {
+			libnet_unjoin_set_error_string(mem_ctx, r,
+				"failed to disable machine account via rpc: %s",
+				get_friendly_nt_error_msg(status));
+			if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
+				return WERR_SETUP_NOT_JOINED;
+			}
+			return ntstatus_to_werror(status);
+		}
+
+		r->out.disabled_machine_account = true;
+	}
+
+	/* If disable succeeded or was not requested at all, we
+	   should be getting rid of our end of things */
+
 	libnet_join_unjoindomain_remove_secrets(mem_ctx, r);
 
 	return WERR_OK;
diff --git a/source3/librpc/gen_ndr/libnet_join.h b/source3/librpc/gen_ndr/libnet_join.h
index ed49062..cf915cb 100644
--- a/source3/librpc/gen_ndr/libnet_join.h
+++ b/source3/librpc/gen_ndr/libnet_join.h
@@ -2,13 +2,13 @@
 
 #include <stdint.h>
 
+#include "libcli/util/ntstatus.h"
+
 #include "librpc/gen_ndr/wkssvc.h"
 #include "librpc/gen_ndr/security.h"
 #ifndef _HEADER_libnetjoin
 #define _HEADER_libnetjoin
 
-enum netr_SchannelType;
-
 
 struct libnet_JoinCtx {
 	struct {
@@ -58,6 +58,7 @@ struct libnet_UnjoinCtx {
 		const char * admin_password;
 		const char * machine_password;
 		uint32_t unjoin_flags;
+		uint8_t delete_machine_account;
 		uint8_t modify_config;
 		struct dom_sid *domain_sid;/* [ref] */
 		struct ads_struct *ads;/* [ref] */
diff --git a/source3/librpc/gen_ndr/ndr_libnet_join.c b/source3/librpc/gen_ndr/ndr_libnet_join.c
index 79fcd16..ba31ea6 100644
--- a/source3/librpc/gen_ndr/ndr_libnet_join.c
+++ b/source3/librpc/gen_ndr/ndr_libnet_join.c
@@ -89,6 +89,7 @@ _PUBLIC_ void ndr_print_libnet_UnjoinCtx(struct ndr_print *ndr, const char *name
 		ndr_print_ptr(ndr, "machine_password", r->in.machine_password);
 #endif
 		ndr_print_wkssvc_joinflags(ndr, "unjoin_flags", r->in.unjoin_flags);
+		ndr_print_uint8(ndr, "delete_machine_account", r->in.delete_machine_account);
 		ndr_print_uint8(ndr, "modify_config", r->in.modify_config);
 		ndr_print_ptr(ndr, "domain_sid", r->in.domain_sid);
 		ndr->depth++;
diff --git a/source3/librpc/idl/libnet_join.idl b/source3/librpc/idl/libnet_join.idl
index c600ea0..80429dc 100644
--- a/source3/librpc/idl/libnet_join.idl
+++ b/source3/librpc/idl/libnet_join.idl
@@ -53,6 +53,7 @@ interface libnetjoin
 		[in] string admin_password,
 		[in] string machine_password,
 		[in] wkssvc_joinflags unjoin_flags,
+		[in] boolean8 delete_machine_account,
 		[in] boolean8 modify_config,
 		[in] dom_sid *domain_sid,
 		[in] ads_struct *ads,
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 8e927be..ed2e17b 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -910,8 +910,12 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
 	r->in.admin_account	= c->opt_user_name;
 	r->in.admin_password	= net_prompt_pass(c, c->opt_user_name);
 	r->in.modify_config	= lp_config_backend_is_registry();
+
+	/* Try to delete it, but if that fails, disable it.  The
+	   WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE really means "disable */
 	r->in.unjoin_flags	= WKSSVC_JOIN_FLAGS_JOIN_TYPE |
 				  WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE;
+	r->in.delete_machine_account = true;
 
 	werr = libnet_Unjoin(ctx, r);
 	if (!W_ERROR_IS_OK(werr)) {
@@ -921,7 +925,7 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
 		goto done;
 	}
 
-	if (W_ERROR_IS_OK(werr)) {
+	if (r->out.deleted_machine_account) {
 		d_printf("Deleted account for '%s' in realm '%s'\n",
 			r->in.machine_name, r->out.dns_domain_name);
 		goto done;
@@ -935,7 +939,10 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
 		goto done;
 	}
 
-	d_fprintf(stderr, "Failed to disable machine account for '%s' in realm '%s'\n",
+	/* Based on what we requseted, we shouldn't get here, but if
+	   we did, it means the secrets were removed, and therefore
+	   we have left the domain */
+	d_fprintf(stderr, "Machine '%s' Left domain '%s'\n",
 		  r->in.machine_name, r->out.dns_domain_name);
 
  done:


-- 
Samba Shared Repository


More information about the samba-cvs mailing list