create-computer-account-in-od   [plain text]


Index: samba/source/passdb/pdb_interface.c
===================================================================
--- samba/source/passdb/pdb_interface.c.orig
+++ samba/source/passdb/pdb_interface.c
@@ -294,15 +294,30 @@ static NTSTATUS pdb_default_create_user(
 					TALLOC_CTX *tmp_ctx, const char *name,
 					uint32 acb_info, uint32 *rid)
 {
-	struct samu *sam_pass;
 	NTSTATUS status;
-	struct passwd *pwd;
-
+	BOOL found = False;
+	struct samu *sam_pass = NULL;
+	struct passwd *pwd = NULL;
+
+	/* In OpenDirectory, there is no separation between the Unix account
+	 * database and the Samba account database. However, since computer
+	 * trust accounts do no show up in the former, we need to use the Samba
+	 * account database to search for the account. For other passdb
+	 * backends like tdbsam, this is exactly the wrong thing to do, so we
+	 * have to conditionalise this on lp_opendirectory().
+	 */
 	if ((sam_pass = samu_new(tmp_ctx)) == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	if ( !(pwd = Get_Pwnam_alloc(tmp_ctx, name)) ) {
+	if (lp_opendirectory()) {
+	    found = pdb_getsampwnam(sam_pass, name);
+	} else {
+	    pwd = Get_Pwnam_alloc(tmp_ctx, name);
+	    found = pwd ? True : False;
+	}
+
+	if (!found) {
 		pstring add_script;
 		int add_ret;
 		fstring name2;
@@ -316,7 +331,8 @@ static NTSTATUS pdb_default_create_user(
 		if (add_script[0] == '\0') {
 			DEBUG(3, ("Could not find user %s and no add script "
 				  "defined\n", name));
-			return NT_STATUS_NO_SUCH_USER;
+			status = NT_STATUS_NO_SUCH_USER;
+			goto done;
 		}
 
 		/* lowercase the username before creating the Unix account for 
@@ -339,26 +355,40 @@ static NTSTATUS pdb_default_create_user(
 		}
 #endif
 
-		flush_pwnam_cache();
-
-		pwd = Get_Pwnam_alloc(tmp_ctx, name);
+		if (lp_opendirectory()) {
+		    found = pdb_getsampwnam(sam_pass, name);
+		} else {
+		    flush_pwnam_cache();
+		    pwd = Get_Pwnam_alloc(tmp_ctx, name);
+		    found = pwd ? True : False;
+		}
 	}
 
 	/* we have a valid SID coming out of this call */
 
-	status = samu_alloc_rid_unix( sam_pass, pwd );
-
-	TALLOC_FREE( pwd );
+	if (!found) {
+		DEBUG(1, ("pdb_default_create_user: failed to add "
+				"a new account for '%s'\n", name));
+		/* I guess this error is as good as any -- jpeach */
+		status = NT_STATUS_INSUFFICIENT_RESOURCES;
+		goto done;
+	}
 
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(3, ("pdb_default_create_user: failed to create a new user structure: %s\n", nt_errstr(status)));
-		return status;
+	if (!lp_opendirectory()) {
+	    status = samu_alloc_rid_unix(sam_pass, pwd);
+	    if (!NT_STATUS_IS_OK(status)) {
+		    DEBUG(3, ("pdb_default_create_user: failed to create "
+			"a new user structure: %s\n", nt_errstr(status)));
+		    goto done;
+	    }
 	}
 
+
 	if (!sid_peek_check_rid(get_global_sam_sid(),
 				pdb_get_user_sid(sam_pass), rid)) {
 		DEBUG(0, ("Could not get RID of fresh user\n"));
-		return NT_STATUS_INTERNAL_ERROR;
+		status = NT_STATUS_INTERNAL_ERROR;
+		goto done;
 	}
 
 	/* Use the username case specified in the original request */
@@ -373,6 +403,8 @@ static NTSTATUS pdb_default_create_user(
 
 	status = pdb_add_sam_account(sam_pass);
 
+done:
+	TALLOC_FREE(pwd);
 	TALLOC_FREE(sam_pass);
 
 	return status;