svn commit: samba r12421 - in branches/SAMBA_4_0/source: libnet utils/net

abartlet at samba.org abartlet at samba.org
Thu Dec 22 06:47:01 GMT 2005


Author: abartlet
Date: 2005-12-22 06:47:00 +0000 (Thu, 22 Dec 2005)
New Revision: 12421

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12421

Log:
Handle the case where we are a joining as different account types far better.

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/libnet/libnet_join.c
   branches/SAMBA_4_0/source/utils/net/net_join.c


Changeset:
Modified: branches/SAMBA_4_0/source/libnet/libnet_join.c
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_join.c	2005-12-22 01:19:42 UTC (rev 12420)
+++ branches/SAMBA_4_0/source/libnet/libnet_join.c	2005-12-22 06:47:00 UTC (rev 12421)
@@ -595,7 +595,7 @@
 	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 @@
 			/* 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,31 +948,7 @@
 
 		}
 	}
-	/* 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;
 	qui.in.level = 16;
@@ -998,17 +973,88 @@
 		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);

Modified: branches/SAMBA_4_0/source/utils/net/net_join.c
===================================================================
--- branches/SAMBA_4_0/source/utils/net/net_join.c	2005-12-22 01:19:42 UTC (rev 12420)
+++ branches/SAMBA_4_0/source/utils/net/net_join.c	2005-12-22 06:47:00 UTC (rev 12421)
@@ -76,10 +76,9 @@
 	/* do the domain join */
 	status = libnet_Join(libnetctx, r, r);
 	
-	if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
-		DEBUG(0,("libnet_Join returned %s: %s\n",
-			 nt_errstr(status),
-			 r->out.error_string));
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("Joining domain failed: %s\n",
+			 r->out.error_string ? r->out.error_string : nt_errstr(status));
 		talloc_free(r);
 		talloc_free(libnetctx);
 		return -1;



More information about the samba-cvs mailing list