The Samba-Bugzilla – Attachment 4167 Details for
Bug 6333
smbpasswd fails to create users when using ldap/editposix
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
simo's patch #1
0001-Consolidate-user-create-delete-paths-in-smbpasswd.patch (text/plain), 15.74 KB, created by
Guenther Deschner
on 2009-05-19 07:18:02 UTC
(
hide
)
Description:
simo's patch #1
Filename:
MIME Type:
Creator:
Guenther Deschner
Created:
2009-05-19 07:18:02 UTC
Size:
15.74 KB
patch
obsolete
>From: Simo Sorce <idra@samba.org> >Date: Sat, 16 May 2009 18:10:39 -0400 >Subject: [PATCH] Consolidate user create/delete paths in smbpasswd > >This patch changes the way smbpasswd behaves when adding/deleting users. >smbpasswd now calls pdb_create_user/pdb_delete_user, this means that if >add/delete user scripts are configured then they are used to create or >delete unix users as well. If the scripts are not defined the behavioris >unchanged. >This also allow to use smbpasswd -a/-x with ldapsam:editposix to allow >automatic creation/deletion of users. >--- > source3/passdb/passdb.c | 326 +++++++++++++++++++++++++-------------------- > source3/utils/smbpasswd.c | 42 ++---- > 2 files changed, 194 insertions(+), 174 deletions(-) > >diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c >index 6aab5e3..9654e79 100644 >--- a/source3/passdb/passdb.c >+++ b/source3/passdb/passdb.c >@@ -627,7 +627,14 @@ bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid, > } > > /************************************************************* >- Change a password entry in the local smbpasswd file. >+ Change a password entry in the local passdb backend. >+ >+ Assumptions: >+ - always called as root >+ - ignores the account type except when adding a new account >+ - will create/delete the unix account if the relative >+ add/delete user script is configured >+ > *************************************************************/ > > NTSTATUS local_password_change(const char *user_name, >@@ -636,133 +643,135 @@ NTSTATUS local_password_change(const char *user_name, > char **pp_err_str, > char **pp_msg_str) > { >- struct samu *sam_pass=NULL; >- uint32 other_acb; >+ TALLOC_CTX *tosctx; >+ struct samu *sam_pass; >+ uint32_t acb; >+ uint32_t rid; > NTSTATUS result; >+ bool user_exists; >+ int ret; > > *pp_err_str = NULL; > *pp_msg_str = NULL; > >- /* Get the smb passwd entry for this user */ >- >- if ( !(sam_pass = samu_new( NULL )) ) { >+ tosctx = talloc_tos(); >+ if (!tosctx) { > return NT_STATUS_NO_MEMORY; > } > >- become_root(); >- if(!pdb_getsampwnam(sam_pass, user_name)) { >- unbecome_root(); >- TALLOC_FREE(sam_pass); >- >- if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) { >- int tmp_debug = DEBUGLEVEL; >- struct passwd *pwd; >- >- /* Might not exist in /etc/passwd. */ >- >- if (tmp_debug < 1) { >- DEBUGLEVEL = 1; >- } >+ sam_pass = samu_new(tosctx); >+ if (!sam_pass) { >+ result = NT_STATUS_NO_MEMORY; >+ goto done; >+ } > >- if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), user_name)) ) { >- return NT_STATUS_NO_SUCH_USER; >+ /* Get the smb passwd entry for this user */ >+ user_exists = pdb_getsampwnam(sam_pass, user_name); >+ >+ /* Check delete first, we don't need to do anything else if we >+ * are going to delete the acocunt */ >+ if (user_exists && (local_flags & LOCAL_DELETE_USER)) { >+ >+ result = pdb_delete_user(tosctx, sam_pass); >+ if (!NT_STATUS_IS_OK(result)) { >+ ret = asprintf(pp_err_str, >+ "Failed to delete entry for user %s.\n", >+ user_name); >+ if (ret < 0) { >+ *pp_err_str = NULL; > } >- >- /* create the struct samu and initialize the basic Unix properties */ >- >- if ( !(sam_pass = samu_new( NULL )) ) { >- return NT_STATUS_NO_MEMORY; >+ result = NT_STATUS_UNSUCCESSFUL; >+ } else { >+ ret = asprintf(pp_msg_str, >+ "Deleted user %s.\n", >+ user_name); >+ if (ret < 0) { >+ *pp_msg_str = NULL; > } >+ } >+ goto done; >+ } > >- result = samu_set_unix( sam_pass, pwd ); >- >- DEBUGLEVEL = tmp_debug; >+ if (user_exists && (local_flags & LOCAL_ADD_USER)) { >+ /* the entry already existed */ >+ local_flags &= ~LOCAL_ADD_USER; >+ } > >- TALLOC_FREE( pwd ); >+ if (!user_exists && !(local_flags & LOCAL_ADD_USER)) { >+ ret = asprintf(pp_err_str, >+ "Failed to find entry for user %s.\n", >+ user_name); >+ if (ret < 0) { >+ *pp_err_str = NULL; >+ } >+ result = NT_STATUS_NO_SUCH_USER; >+ goto done; >+ } > >- if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PRIMARY_GROUP)) { >- return result; >- } >+ /* First thing add the new user if we are required to do so */ >+ if (local_flags & LOCAL_ADD_USER) { > >- if (!NT_STATUS_IS_OK(result)) { >- if (asprintf(pp_err_str, "Failed to " "initialize account for user %s: %s\n", >- user_name, nt_errstr(result)) < 0) { >- *pp_err_str = NULL; >- } >- return result; >- } >+ if (local_flags & LOCAL_TRUST_ACCOUNT) { >+ acb = ACB_WSTRUST; >+ } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { >+ acb = ACB_DOMTRUST; > } else { >- if (asprintf(pp_err_str, "Failed to find entry for user %s.\n", user_name) < 0) { >- *pp_err_str = NULL; >- } >- return NT_STATUS_NO_SUCH_USER; >+ acb = ACB_NORMAL; > } >- } else { >- unbecome_root(); >- /* the entry already existed */ >- local_flags &= ~LOCAL_ADD_USER; >- } > >- /* the 'other' acb bits not being changed here */ >- other_acb = (pdb_get_acct_ctrl(sam_pass) & (~(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL))); >- if (local_flags & LOCAL_TRUST_ACCOUNT) { >- if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) { >- if (asprintf(pp_err_str, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name) < 0) { >+ result = pdb_create_user(tosctx, user_name, acb, &rid); >+ if (!NT_STATUS_IS_OK(result)) { >+ ret = asprintf(pp_err_str, >+ "Failed to add entry for user %s.\n", >+ user_name); >+ if (ret < 0) { > *pp_err_str = NULL; > } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >+ result = NT_STATUS_UNSUCCESSFUL; >+ goto done; > } >- } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { >- if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) { >- if (asprintf(pp_err_str, "Failed to set 'domain trust account' flags for user %s.\n", user_name) < 0) { >- *pp_err_str = NULL; >- } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >+ >+ sam_pass = samu_new(tosctx); >+ if (!sam_pass) { >+ result = NT_STATUS_NO_MEMORY; >+ goto done; > } >- } else { >- if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) { >- if (asprintf(pp_err_str, "Failed to set 'normal account' flags for user %s.\n", user_name) < 0) { >+ >+ /* Now get back the smb passwd entry for this new user */ >+ user_exists = pdb_getsampwnam(sam_pass, user_name); >+ if (!user_exists) { >+ ret = asprintf(pp_err_str, >+ "Failed to add entry for user %s.\n", >+ user_name); >+ if (ret < 0) { > *pp_err_str = NULL; > } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >+ result = NT_STATUS_UNSUCCESSFUL; >+ goto done; > } > } > >+ acb = pdb_get_acct_ctrl(sam_pass); >+ > /* > * We are root - just write the new password > * and the valid last change time. > */ >- >- if (local_flags & LOCAL_DISABLE_USER) { >- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) { >- if (asprintf(pp_err_str, "Failed to set 'disabled' flag for user %s.\n", user_name) < 0) { >- *pp_err_str = NULL; >- } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >- } >- } else if (local_flags & LOCAL_ENABLE_USER) { >- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) { >- if (asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name) < 0) { >+ if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) { >+ acb |= ACB_PWNOTREQ; >+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { >+ ret = asprintf(pp_err_str, >+ "Failed to set 'no password required' " >+ "flag for user %s.\n", user_name); >+ if (ret < 0) { > *pp_err_str = NULL; > } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >+ result = NT_STATUS_UNSUCCESSFUL; >+ goto done; > } > } > >- if (local_flags & LOCAL_SET_NO_PASSWORD) { >- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) { >- if (asprintf(pp_err_str, "Failed to set 'no password required' flag for user %s.\n", user_name) < 0) { >- *pp_err_str = NULL; >- } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >- } >- } else if (local_flags & LOCAL_SET_PASSWORD) { >+ if (local_flags & LOCAL_SET_PASSWORD) { > /* > * If we're dealing with setting a completely empty user account > * ie. One with a password of 'XXXX', but not set disabled (like >@@ -772,83 +781,106 @@ NTSTATUS local_password_change(const char *user_name, > * and the decision hasn't really been made to disable them (ie. > * don't create them disabled). JRA. > */ >- if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) { >- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) { >- if (asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name) < 0) { >+ if ((pdb_get_lanman_passwd(sam_pass) == NULL) && >+ (acb & ACB_DISABLED)) { >+ acb &= (~ACB_DISABLED); >+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { >+ ret = asprintf(pp_err_str, >+ "Failed to unset 'disabled' " >+ "flag for user %s.\n", >+ user_name); >+ if (ret < 0) { > *pp_err_str = NULL; > } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >- } >- } >- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) { >- if (asprintf(pp_err_str, "Failed to unset 'no password required' flag for user %s.\n", user_name) < 0) { >- *pp_err_str = NULL; >+ result = NT_STATUS_UNSUCCESSFUL; >+ goto done; > } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; > } > >- if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) { >- if (asprintf(pp_err_str, "Failed to set password for user %s.\n", user_name) < 0) { >+ acb &= (~ACB_PWNOTREQ); >+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { >+ ret = asprintf(pp_err_str, >+ "Failed to unset 'no password required'" >+ " flag for user %s.\n", user_name); >+ if (ret < 0) { > *pp_err_str = NULL; > } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >+ result = NT_STATUS_UNSUCCESSFUL; >+ goto done; > } >- } > >- if (local_flags & LOCAL_ADD_USER) { >- if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) { >- if (asprintf(pp_msg_str, "Added user %s.\n", user_name) < 0) { >- *pp_msg_str = NULL; >- } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_OK; >- } else { >- if (asprintf(pp_err_str, "Failed to add entry for user %s.\n", user_name) < 0) { >+ if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) { >+ ret = asprintf(pp_err_str, >+ "Failed to set password for " >+ "user %s.\n", user_name); >+ if (ret < 0) { > *pp_err_str = NULL; > } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >+ result = NT_STATUS_UNSUCCESSFUL; >+ goto done; > } >- } else if (local_flags & LOCAL_DELETE_USER) { >- if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) { >- if (asprintf(pp_err_str, "Failed to delete entry for user %s.\n", user_name) < 0) { >+ } >+ >+ if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) { >+ acb |= ACB_DISABLED; >+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { >+ ret = asprintf(pp_err_str, >+ "Failed to set 'disabled' flag for " >+ "user %s.\n", user_name); >+ if (ret < 0) { > *pp_err_str = NULL; > } >- TALLOC_FREE(sam_pass); >- return NT_STATUS_UNSUCCESSFUL; >- } >- if (asprintf(pp_msg_str, "Deleted user %s.\n", user_name) < 0) { >- *pp_msg_str = NULL; >+ result = NT_STATUS_UNSUCCESSFUL; >+ goto done; > } >- } else { >- result = pdb_update_sam_account(sam_pass); >- if(!NT_STATUS_IS_OK(result)) { >- if (asprintf(pp_err_str, "Failed to modify entry for user %s.\n", user_name) < 0) { >+ } >+ >+ if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) { >+ acb &= (~ACB_DISABLED); >+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) { >+ ret = asprintf(pp_err_str, >+ "Failed to unset 'disabled' flag for " >+ "user %s.\n", user_name); >+ if (ret < 0) { > *pp_err_str = NULL; > } >- TALLOC_FREE(sam_pass); >- return result; >+ result = NT_STATUS_UNSUCCESSFUL; >+ goto done; > } >- if(local_flags & LOCAL_DISABLE_USER) { >- if (asprintf(pp_msg_str, "Disabled user %s.\n", user_name) < 0) { >- *pp_msg_str = NULL; >- } >- } else if (local_flags & LOCAL_ENABLE_USER) { >- if (asprintf(pp_msg_str, "Enabled user %s.\n", user_name) < 0) { >- *pp_msg_str = NULL; >- } >- } else if (local_flags & LOCAL_SET_NO_PASSWORD) { >- if (asprintf(pp_msg_str, "User %s password set to none.\n", user_name) < 0) { >- *pp_msg_str = NULL; >- } >+ } >+ >+ /* now commit changes if any */ >+ result = pdb_update_sam_account(sam_pass); >+ if (!NT_STATUS_IS_OK(result)) { >+ ret = asprintf(pp_err_str, >+ "Failed to modify entry for user %s.\n", >+ user_name); >+ if (ret < 0) { >+ *pp_err_str = NULL; > } >+ goto done; >+ } >+ >+ if (local_flags & LOCAL_ADD_USER) { >+ ret = asprintf(pp_msg_str, "Added user %s.\n", user_name); >+ } else if (local_flags & LOCAL_DISABLE_USER) { >+ ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name); >+ } else if (local_flags & LOCAL_ENABLE_USER) { >+ ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name); >+ } else if (local_flags & LOCAL_SET_NO_PASSWORD) { >+ ret = asprintf(pp_msg_str, >+ "User %s password set to none.\n", user_name); > } > >+ if (ret < 0) { >+ *pp_msg_str = NULL; >+ } >+ >+ result = NT_STATUS_OK; >+ >+done: > TALLOC_FREE(sam_pass); >- return NT_STATUS_OK; >+ return result; > } > > /********************************************************************** >diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c >index 8cca93f..c0b2cac 100644 >--- a/source3/utils/smbpasswd.c >+++ b/source3/utils/smbpasswd.c >@@ -242,26 +242,29 @@ static NTSTATUS password_change(const char *remote_mach, char *username, > char *msg_str = NULL; > > if (remote_mach != NULL) { >- if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER| >- LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) { >+ if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER| >+ LOCAL_DISABLE_USER|LOCAL_ENABLE_USER| >+ LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) { > /* these things can't be done remotely yet */ >+ fprintf(stderr, "Invalid remote operation!\n"); > return NT_STATUS_UNSUCCESSFUL; > } >- ret = remote_password_change(remote_mach, username, >+ ret = remote_password_change(remote_mach, username, > old_passwd, new_pw, &err_str); >- if (err_str != NULL) >- fprintf(stderr, "%s", err_str); >- SAFE_FREE(err_str); >- return ret; >+ } else { >+ ret = local_password_change(username, local_flags, new_pw, >+ &err_str, &msg_str); > } > >- ret = local_password_change(username, local_flags, new_pw, >- &err_str, &msg_str); >- >- if(msg_str) >+ if (msg_str) { > printf("%s", msg_str); >- if(err_str) >+ } >+ if (err_str) { > fprintf(stderr, "%s", err_str); >+ } >+ if (!NT_STATUS_IS_OK(ret) && !err_str) { >+ fprintf(stderr, "Failed to change password!\n"); >+ } > > SAFE_FREE(msg_str); > SAFE_FREE(err_str); >@@ -430,21 +433,8 @@ static int process_root(int local_flags) > } > > if((local_flags & LOCAL_SET_PASSWORD) && (new_passwd == NULL)) { >- struct passwd *passwd; >- >- if (remote_machine == NULL) { >- passwd = getpwnam_alloc(NULL, user_name); >- >- if (!passwd) { >- fprintf(stderr, "Cannot locate Unix account for " >- "'%s'!\n", user_name); >- exit(1); >- } >- TALLOC_FREE(passwd); >- } > > new_passwd = prompt_for_new_password(stdin_passwd_get); >- > if(!new_passwd) { > fprintf(stderr, "Unable to get new password.\n"); > exit(1); >@@ -455,7 +445,6 @@ static int process_root(int local_flags) > if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name, > old_passwd, new_passwd, > local_flags))) { >- fprintf(stderr,"Failed to modify password entry for user %s\n", user_name); > result = 1; > goto done; > } >@@ -550,7 +539,6 @@ static int process_nonroot(int local_flags) > > if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name, old_pw, > new_pw, 0))) { >- fprintf(stderr,"Failed to change password for %s\n", user_name); > result = 1; > goto done; > } >-- >1.6.0.6 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 6333
: 4167 |
4168