svn commit: samba r17150 - in branches: SAMBA_3_0/source/passdb SAMBA_3_0/source/rpc_server SAMBA_3_0_23/source/passdb SAMBA_3_0_23/source/rpc_server

jerry at samba.org jerry at samba.org
Wed Jul 19 20:59:09 GMT 2006


Author: jerry
Date: 2006-07-19 20:59:04 +0000 (Wed, 19 Jul 2006)
New Revision: 17150

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

Log:
MMC User & group plugins fixes:

* Make sure to lower case all usernames before 
  calling the create, delete, or rename hooks.
* Preserve case for usernames in passdb
* Flush the getpwnam cache after renaming a user
* Add become/unbecome root block in _samr_delete_dom_user()
  when trying to verify the account's existence.




Modified:
   branches/SAMBA_3_0/source/passdb/pdb_interface.c
   branches/SAMBA_3_0/source/passdb/pdb_ldap.c
   branches/SAMBA_3_0/source/passdb/pdb_tdb.c
   branches/SAMBA_3_0/source/rpc_server/srv_samr_nt.c
   branches/SAMBA_3_0_23/source/passdb/pdb_interface.c
   branches/SAMBA_3_0_23/source/passdb/pdb_ldap.c
   branches/SAMBA_3_0_23/source/passdb/pdb_tdb.c
   branches/SAMBA_3_0_23/source/rpc_server/srv_samr_nt.c


Changeset:
Modified: branches/SAMBA_3_0/source/passdb/pdb_interface.c
===================================================================
--- branches/SAMBA_3_0/source/passdb/pdb_interface.c	2006-07-19 20:56:11 UTC (rev 17149)
+++ branches/SAMBA_3_0/source/passdb/pdb_interface.c	2006-07-19 20:59:04 UTC (rev 17150)
@@ -344,6 +344,7 @@
 	if ( !(pwd = Get_Pwnam_alloc(tmp_ctx, name)) ) {
 		pstring add_script;
 		int add_ret;
+		fstring name2;
 
 		if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] != '$') {
 			pstrcpy(add_script, lp_adduser_script());
@@ -357,7 +358,11 @@
 			return NT_STATUS_NO_SUCH_USER;
 		}
 
-		all_string_sub(add_script, "%u", name, sizeof(add_script));
+		/* lowercase the username before creating the Unix account for 
+		   compatibility with previous Samba releases */
+		fstrcpy( name2, name );
+		strlower_m( name2 );
+		all_string_sub(add_script, "%u", name2, sizeof(add_script));
 		add_ret = smbrun(add_script,NULL);
 		DEBUG(add_ret ? 0 : 3, ("_samr_create_user: Running the command `%s' gave %d\n",
 					add_script, add_ret));
@@ -392,6 +397,10 @@
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
+	/* Use the username case specified in the original request */
+
+	pdb_set_username( sam_pass, name, PDB_SET );
+
 	/* Disable the account on creation, it does not have a reasonable password yet. */
 
 	acb_info |= ACB_DISABLED;
@@ -444,6 +453,7 @@
 					struct samu *sam_acct)
 {
 	NTSTATUS status;
+	fstring username;
 
 	status = pdb_delete_sam_account(sam_acct);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -456,7 +466,14 @@
 	 * not necessary present and maybe the sysadmin doesn't want to delete
 	 * the unix side
 	 */
-	smb_delete_user( pdb_get_username(sam_acct) );
+
+	/* always lower case the username before handing it off to 
+	   external scripts */
+
+	fstrcpy( username, pdb_get_username(sam_acct) );
+	strlower_m( username );
+
+	smb_delete_user( username );
 	
 	return status;
 }
@@ -513,6 +530,7 @@
 {
 	struct pdb_methods *pdb = pdb_get_methods();
 	uid_t uid;
+	NTSTATUS status;
 
 	if (csamuser != NULL) {
 		TALLOC_FREE(csamuser);
@@ -529,7 +547,12 @@
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	return pdb->rename_sam_account(pdb, oldname, newname);
+	status = pdb->rename_sam_account(pdb, oldname, newname);
+
+	/* always flush the cache here just to be safe */
+	flush_pwnam_cache();
+
+	return status;
 }
 
 NTSTATUS pdb_update_login_attempts(struct samu *sam_acct, BOOL success)

Modified: branches/SAMBA_3_0/source/passdb/pdb_ldap.c
===================================================================
--- branches/SAMBA_3_0/source/passdb/pdb_ldap.c	2006-07-19 20:56:11 UTC (rev 17149)
+++ branches/SAMBA_3_0/source/passdb/pdb_ldap.c	2006-07-19 20:59:04 UTC (rev 17150)
@@ -1831,6 +1831,7 @@
 	const char *oldname;
 	int rc;
 	pstring rename_script;
+	fstring oldname_lower, newname_lower;
 
 	if (!old_acct) {
 		DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
@@ -1852,10 +1853,17 @@
 	DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n", 
 		   oldname, newname));
 
-	/* we have to allow the account name to end with a '$' */
-	string_sub2(rename_script, "%unew", newname, sizeof(pstring), 
+	/* We have to allow the account name to end with a '$'.
+	   Also, follow the semantics in _samr_create_user() and lower case the
+	   posix name but preserve the case in passdb */
+
+	fstrcpy( oldname_lower, oldname );
+	strlower_m( oldname_lower );
+	fstrcpy( newname_lower, newname );
+	strlower_m( newname_lower );
+	string_sub2(rename_script, "%unew", newname_lower, sizeof(pstring), 
 		    True, False, True);
-	string_sub2(rename_script, "%uold", oldname, sizeof(pstring), 
+	string_sub2(rename_script, "%uold", oldname_lower, sizeof(pstring), 
 		    True, False, True);
 	rc = smbrun(rename_script, NULL);
 

Modified: branches/SAMBA_3_0/source/passdb/pdb_tdb.c
===================================================================
--- branches/SAMBA_3_0/source/passdb/pdb_tdb.c	2006-07-19 20:56:11 UTC (rev 17149)
+++ branches/SAMBA_3_0/source/passdb/pdb_tdb.c	2006-07-19 20:59:04 UTC (rev 17150)
@@ -1399,6 +1399,8 @@
 	pstring          rename_script;
 	BOOL             interim_account = False;
 	int              rename_ret;
+	fstring          oldname_lower;
+	fstring          newname_lower;
 
 	/* can't do anything without an external script */
 	
@@ -1442,11 +1444,19 @@
 		goto done;
 	}
 
-	/* rename the posix user */
-	string_sub2(rename_script, "%unew", newname, sizeof(pstring), 
-		    True, False, True);
-	string_sub2(rename_script, "%uold", pdb_get_username(old_acct), 
-		    sizeof(pstring), True, False, True);
+	/* Rename the posix user.  Follow the semantics of _samr_create_user()
+	   so that we lower case the posix name but preserve the case in passdb */
+
+	fstrcpy( oldname_lower, pdb_get_username(old_acct) );
+	strlower_m( oldname_lower );
+
+	fstrcpy( newname_lower, newname );
+	strlower_m( newname_lower );
+
+	string_sub2(rename_script, "%unew", newname_lower, sizeof(pstring), 
+		True, False, True);
+	string_sub2(rename_script, "%uold", oldname_lower, sizeof(pstring), 
+		True, False, True);
 	rename_ret = smbrun(rename_script, NULL);
 
 	DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));

Modified: branches/SAMBA_3_0/source/rpc_server/srv_samr_nt.c
===================================================================
--- branches/SAMBA_3_0/source/rpc_server/srv_samr_nt.c	2006-07-19 20:56:11 UTC (rev 17149)
+++ branches/SAMBA_3_0/source/rpc_server/srv_samr_nt.c	2006-07-19 20:59:04 UTC (rev 17150)
@@ -2471,8 +2471,6 @@
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	strlower_m(account);
-
 	nt_status = can_create(p->mem_ctx, account);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
@@ -3214,7 +3212,7 @@
 	if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
 		( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
 		( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
-		DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
+		DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
 	} else  {
 		/* update the UNIX password */
 		if (lp_unix_password_sync() ) {
@@ -3396,10 +3394,25 @@
 	if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info))
 		return NT_STATUS_INVALID_HANDLE;
 
-	/* observed when joining an XP client to a Samba domain */
+	/* This is tricky.  A WinXP domain join sets 
+	  (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
+	  The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the 
+	  standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().  
+	  This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so 
+	  we'll use the set from the WinXP join as the basis. */
 	
-	acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;	
-
+	switch (switch_value) {
+	case 18:
+	case 24:
+	case 25:
+	case 26:
+		acc_required = SA_RIGHT_USER_SET_PASSWORD;
+		break;
+	default:
+		acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
+		break;
+	}
+	
 	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
 		return r_u->status;
 	}
@@ -4040,6 +4053,7 @@
 	BOOL can_add_accounts;
 	uint32 acb_info;
 	DISP_INFO *disp_info = NULL;
+	BOOL ret;
 
 	DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
 
@@ -4059,7 +4073,11 @@
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	if(!pdb_getsampwsid(sam_pass, &user_sid)) {
+	become_root();
+	ret = pdb_getsampwsid(sam_pass, &user_sid);
+	unbecome_root();
+
+	if( !ret ) {
 		DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
 			sid_string_static(&user_sid)));
 		TALLOC_FREE(sam_pass);

Modified: branches/SAMBA_3_0_23/source/passdb/pdb_interface.c
===================================================================
--- branches/SAMBA_3_0_23/source/passdb/pdb_interface.c	2006-07-19 20:56:11 UTC (rev 17149)
+++ branches/SAMBA_3_0_23/source/passdb/pdb_interface.c	2006-07-19 20:59:04 UTC (rev 17150)
@@ -344,6 +344,7 @@
 	if ( !(pwd = Get_Pwnam_alloc(tmp_ctx, name)) ) {
 		pstring add_script;
 		int add_ret;
+		fstring name2;
 
 		if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] != '$') {
 			pstrcpy(add_script, lp_adduser_script());
@@ -357,7 +358,11 @@
 			return NT_STATUS_NO_SUCH_USER;
 		}
 
-		all_string_sub(add_script, "%u", name, sizeof(add_script));
+		/* lowercase the username before creating the Unix account for 
+		   compatibility with previous Samba releases */
+		fstrcpy( name2, name );
+		strlower_m( name2 );
+		all_string_sub(add_script, "%u", name2, sizeof(add_script));
 		add_ret = smbrun(add_script,NULL);
 		DEBUG(add_ret ? 0 : 3, ("_samr_create_user: Running the command `%s' gave %d\n",
 					add_script, add_ret));
@@ -383,6 +388,10 @@
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
+	/* Use the username case specified in the original request */
+
+	pdb_set_username( sam_pass, name, PDB_SET );
+
 	/* Disable the account on creation, it does not have a reasonable password yet. */
 
 	acb_info |= ACB_DISABLED;
@@ -435,6 +444,7 @@
 					struct samu *sam_acct)
 {
 	NTSTATUS status;
+	fstring username;
 
 	status = pdb_delete_sam_account(sam_acct);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -447,7 +457,14 @@
 	 * not necessary present and maybe the sysadmin doesn't want to delete
 	 * the unix side
 	 */
-	smb_delete_user( pdb_get_username(sam_acct) );
+
+	/* always lower case the username before handing it off to 
+	   external scripts */
+
+	fstrcpy( username, pdb_get_username(sam_acct) );
+	strlower_m( username );
+
+	smb_delete_user( username );
 	
 	return status;
 }
@@ -504,6 +521,7 @@
 {
 	struct pdb_methods *pdb = pdb_get_methods();
 	uid_t uid;
+	NTSTATUS status;
 
 	if (csamuser != NULL) {
 		TALLOC_FREE(csamuser);
@@ -520,7 +538,12 @@
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	return pdb->rename_sam_account(pdb, oldname, newname);
+	status = pdb->rename_sam_account(pdb, oldname, newname);
+
+	/* always flush the cache here just to be safe */
+	flush_pwnam_cache();
+
+	return status;
 }
 
 NTSTATUS pdb_update_login_attempts(struct samu *sam_acct, BOOL success)

Modified: branches/SAMBA_3_0_23/source/passdb/pdb_ldap.c
===================================================================
--- branches/SAMBA_3_0_23/source/passdb/pdb_ldap.c	2006-07-19 20:56:11 UTC (rev 17149)
+++ branches/SAMBA_3_0_23/source/passdb/pdb_ldap.c	2006-07-19 20:59:04 UTC (rev 17150)
@@ -1830,6 +1830,7 @@
 	const char *oldname;
 	int rc;
 	pstring rename_script;
+	fstring oldname_lower, newname_lower;
 
 	if (!old_acct) {
 		DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
@@ -1851,10 +1852,17 @@
 	DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n", 
 		   oldname, newname));
 
-	/* we have to allow the account name to end with a '$' */
-	string_sub2(rename_script, "%unew", newname, sizeof(pstring), 
+	/* We have to allow the account name to end with a '$'.
+	   Also, follow the semantics in _samr_create_user() and lower case the
+	   posix name but preserve the case in passdb */
+
+	fstrcpy( oldname_lower, oldname );
+	strlower_m( oldname_lower );
+	fstrcpy( newname_lower, newname );
+	strlower_m( newname_lower );
+	string_sub2(rename_script, "%unew", newname_lower, sizeof(pstring), 
 		    True, False, True);
-	string_sub2(rename_script, "%uold", oldname, sizeof(pstring), 
+	string_sub2(rename_script, "%uold", oldname_lower, sizeof(pstring), 
 		    True, False, True);
 	rc = smbrun(rename_script, NULL);
 

Modified: branches/SAMBA_3_0_23/source/passdb/pdb_tdb.c
===================================================================
--- branches/SAMBA_3_0_23/source/passdb/pdb_tdb.c	2006-07-19 20:56:11 UTC (rev 17149)
+++ branches/SAMBA_3_0_23/source/passdb/pdb_tdb.c	2006-07-19 20:59:04 UTC (rev 17150)
@@ -1388,6 +1388,8 @@
 	pstring          rename_script;
 	BOOL             interim_account = False;
 	int              rename_ret;
+	fstring          oldname_lower;
+	fstring          newname_lower;
 
 	/* can't do anything without an external script */
 	
@@ -1431,11 +1433,19 @@
 		goto done;
 	}
 
-	/* rename the posix user */
-	string_sub2(rename_script, "%unew", newname, sizeof(pstring), 
-		    True, False, True);
-	string_sub2(rename_script, "%uold", pdb_get_username(old_acct), 
-		    sizeof(pstring), True, False, True);
+	/* Rename the posix user.  Follow the semantics of _samr_create_user()
+	   so that we lower case the posix name but preserve the case in passdb */
+
+	fstrcpy( oldname_lower, pdb_get_username(old_acct) );
+	strlower_m( oldname_lower );
+
+	fstrcpy( newname_lower, newname );
+	strlower_m( newname_lower );
+
+	string_sub2(rename_script, "%unew", newname_lower, sizeof(pstring), 
+		True, False, True);
+	string_sub2(rename_script, "%uold", oldname_lower, sizeof(pstring), 
+		True, False, True);
 	rename_ret = smbrun(rename_script, NULL);
 
 	DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));

Modified: branches/SAMBA_3_0_23/source/rpc_server/srv_samr_nt.c
===================================================================
--- branches/SAMBA_3_0_23/source/rpc_server/srv_samr_nt.c	2006-07-19 20:56:11 UTC (rev 17149)
+++ branches/SAMBA_3_0_23/source/rpc_server/srv_samr_nt.c	2006-07-19 20:59:04 UTC (rev 17150)
@@ -2463,8 +2463,6 @@
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	strlower_m(account);
-
 	nt_status = can_create(p->mem_ctx, account);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
@@ -3203,7 +3201,7 @@
 	if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
 		( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
 		( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
-		DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
+		DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
 	} else  {
 		/* update the UNIX password */
 		if (lp_unix_password_sync() ) {
@@ -3385,10 +3383,25 @@
 	if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info))
 		return NT_STATUS_INVALID_HANDLE;
 
-	/* observed when joining an XP client to a Samba domain */
+	/* This is tricky.  A WinXP domain join sets 
+	  (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY)
+	  The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the 
+	  standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser().  
+	  This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so 
+	  we'll use the set from the WinXP join as the basis. */
 	
-	acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;	
-
+	switch (switch_value) {
+	case 18:
+	case 24:
+	case 25:
+	case 26:
+		acc_required = SA_RIGHT_USER_SET_PASSWORD;
+		break;
+	default:
+		acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
+		break;
+	}
+	
 	if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
 		return r_u->status;
 	}
@@ -4027,6 +4040,7 @@
 	BOOL can_add_accounts;
 	uint32 acb_info;
 	DISP_INFO *disp_info = NULL;
+	BOOL ret;
 
 	DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
 
@@ -4046,7 +4060,11 @@
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	if(!pdb_getsampwsid(sam_pass, &user_sid)) {
+	become_root();
+	ret = pdb_getsampwsid(sam_pass, &user_sid);
+	unbecome_root();
+
+	if( !ret ) {
 		DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
 			sid_string_static(&user_sid)));
 		TALLOC_FREE(sam_pass);



More information about the samba-cvs mailing list