summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-07-19 20:59:04 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:38:16 -0500
commit9f6fb43eeefb18578040a0f3b5af941460ec5ca9 (patch)
tree254203e7f1a8039cb16746266aa65d24eef6c93b
parent02f272f3c65b63e80cced94e499e9b18c6e6b005 (diff)
downloadsamba-9f6fb43eeefb18578040a0f3b5af941460ec5ca9.tar.gz
samba-9f6fb43eeefb18578040a0f3b5af941460ec5ca9.tar.bz2
samba-9f6fb43eeefb18578040a0f3b5af941460ec5ca9.zip
r17150: 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. (This used to be commit bbe11b7a950e7d85001f042bbd1ea3bf33ecda7b)
-rw-r--r--source3/passdb/pdb_interface.c29
-rw-r--r--source3/passdb/pdb_ldap.c14
-rw-r--r--source3/passdb/pdb_tdb.c20
-rw-r--r--source3/rpc_server/srv_samr_nt.c32
4 files changed, 77 insertions, 18 deletions
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 20aa72d24e..7f2a8f25b3 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -344,6 +344,7 @@ static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
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 @@ static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
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 @@ static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
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 @@ static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods,
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 @@ static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods,
* 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 @@ NTSTATUS pdb_rename_sam_account(struct samu *oldname, const char *newname)
{
struct pdb_methods *pdb = pdb_get_methods();
uid_t uid;
+ NTSTATUS status;
if (csamuser != NULL) {
TALLOC_FREE(csamuser);
@@ -529,7 +547,12 @@ NTSTATUS pdb_rename_sam_account(struct samu *oldname, const char *newname)
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)
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 83f8d7183c..7dc76dafe7 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -1831,6 +1831,7 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
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 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
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);
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index ac8cbbe91a..b16368baf1 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -1399,6 +1399,8 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
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 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
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));
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 9c453b04a4..3a70c93a1c 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -2471,8 +2471,6 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
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 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
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 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
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. */
+
+ 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;
+ }
- acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
-
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 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
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 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
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);