The Samba-Bugzilla – Attachment 1496 Details for
Bug 2861
Unable to rename user accounts with usermanager
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Add rename support to tdbsam
tdbsam_renames.patch (text/plain), 16.31 KB, created by
Jim McDonough
on 2005-10-10 12:22:39 UTC
(
hide
)
Description:
Add rename support to tdbsam
Filename:
MIME Type:
Creator:
Jim McDonough
Created:
2005-10-10 12:22:39 UTC
Size:
16.31 KB
patch
obsolete
>Index: param/loadparm.c >=================================================================== >--- param/loadparm.c (revision 10871) >+++ param/loadparm.c (working copy) >@@ -151,6 +151,7 @@ > char *szNameResolveOrder; > char *szPanicAction; > char *szAddUserScript; >+ char *szRenameUserScript; > char *szDelUserScript; > char *szAddGroupScript; > char *szDelGroupScript; >@@ -1061,6 +1062,7 @@ > {N_("Logon Options"), P_SEP, P_SEPARATOR}, > > {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED}, >+ {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED}, > {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED}, > {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED}, > {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED}, >@@ -1734,6 +1736,7 @@ > FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules) > FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction) > FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript) >+FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript) > FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript) > > FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount) >Index: rpc_server/srv_samr_nt.c >=================================================================== >--- rpc_server/srv_samr_nt.c (revision 10871) >+++ rpc_server/srv_samr_nt.c (working copy) >@@ -2424,6 +2424,32 @@ > } > > /******************************************************************* >+ set_user_info_7 >+ ********************************************************************/ >+static NTSTATUS set_user_info_7(const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd) >+{ >+ fstring new_name; >+ NTSTATUS rc; >+ >+ if (id7 == NULL) { >+ DEBUG(5, ("set_user_info_7: NULL id7\n")); >+ pdb_free_sam(&pwd); >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ >+ if(!rpcstr_pull(new_name, id7->uni_name.buffer, sizeof(new_name), id7->uni_name.uni_str_len*2, 0)) { >+ DEBUG(5, ("set_user_info_7: failed to get new username\n")); >+ pdb_free_sam(&pwd); >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ >+ rc = pdb_rename_sam_account(pwd, new_name); >+ >+ pdb_free_sam(&pwd); >+ return rc; >+} >+ >+/******************************************************************* > set_user_info_16 > ********************************************************************/ > >@@ -2924,6 +2950,9 @@ > /* ok! user info levels (lots: see MSDEV help), off we go... */ > > switch (switch_value) { >+ case 7: >+ r_u->status = set_user_info_7(ctr->info.id7, pwd); >+ break; > case 16: > if (!set_user_info_16(ctr->info.id16, pwd)) > r_u->status = NT_STATUS_ACCESS_DENIED; >Index: passdb/pdb_tdb.c >=================================================================== >--- passdb/pdb_tdb.c (revision 10871) >+++ passdb/pdb_tdb.c (working copy) >@@ -515,6 +515,32 @@ > return tdbsam_getsampwrid(my_methods, user, rid); > } > >+static BOOL tdb_delete_samacct_only(TDB_CONTEXT *pwd_tdb, >+ struct pdb_methods *my_methods, >+ SAM_ACCOUNT *sam_pass) >+{ >+ TDB_DATA key; >+ fstring keystr; >+ fstring name; >+ >+ fstrcpy(name, pdb_get_username(sam_pass)); >+ strlower_m(name); >+ >+ /* set the search key */ >+ slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); >+ key.dptr = keystr; >+ key.dsize = strlen (keystr) + 1; >+ >+ /* it's outaa here! 8^) */ >+ if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) { >+ DEBUG(5, ("Error deleting entry from tdb passwd database!\n")); >+ DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb))); >+ tdb_close(pwd_tdb); >+ return False; >+ } >+ return True; >+} >+ > /*************************************************************************** > Delete a SAM_ACCOUNT > ****************************************************************************/ >@@ -573,51 +599,20 @@ > return NT_STATUS_OK; > } > >+ > /*************************************************************************** >- Update the TDB SAM >+ Update the TDB SAM account record only > ****************************************************************************/ >- >-static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag) >+static BOOL tdb_update_samacct_only(TDB_CONTEXT *pwd_tdb, >+ struct pdb_methods *my_methods, >+ SAM_ACCOUNT* newpwd, int flag) > { >- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; >- TDB_CONTEXT *pwd_tdb = NULL; > TDB_DATA key, data; > uint8 *buf = NULL; > fstring keystr; > fstring name; > BOOL ret = True; >- uint32 user_rid; > >- /* invalidate the existing TDB iterator if it is open */ >- >- if (tdb_state->passwd_tdb) { >- tdb_close(tdb_state->passwd_tdb); >- tdb_state->passwd_tdb = NULL; >- } >- >- /* open the account TDB passwd*/ >- >- pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); >- >- if (!pwd_tdb) { >- DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", >- tdb_state->tdbsam_location)); >- return False; >- } >- >- if (!pdb_get_group_rid(newpwd)) { >- DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n", >- pdb_get_username(newpwd))); >- ret = False; >- goto done; >- } >- >- if ( !(user_rid = pdb_get_user_rid(newpwd)) ) { >- DEBUG(0,("tdb_update_sam: SAM_ACCOUNT (%s) with no RID!\n", pdb_get_username(newpwd))); >- ret = False; >- goto done; >- } >- > /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */ > if ((data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1) { > DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n")); >@@ -629,7 +624,9 @@ > fstrcpy(name, pdb_get_username(newpwd)); > strlower_m(name); > >- DEBUG(5, ("Storing %saccount %s with RID %d\n", flag == TDB_INSERT ? "(new) " : "", name, user_rid)); >+ DEBUG(5, ("Storing %saccount %s with RID %d\n", >+ flag == TDB_INSERT ? "(new) " : "", name, >+ pdb_get_user_rid(newpwd))); > > /* setup the USER index key */ > slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); >@@ -640,17 +637,40 @@ > if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) { > DEBUG(0, ("Unable to modify passwd TDB!")); > DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb))); >- DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr)); >+ DEBUGADD(0, (" occured while storing the main record (%s)\n", >+ keystr)); > ret = False; > goto done; > } >+ >+done: >+ /* cleanup */ >+ SAFE_FREE(buf); > >+ return (ret); >+} >+ >+/*************************************************************************** >+ Update the TDB SAM RID record only >+****************************************************************************/ >+static BOOL tdb_update_ridrec_only(TDB_CONTEXT *pwd_tdb, >+ struct pdb_methods *my_methods, >+ SAM_ACCOUNT* newpwd, int flag) >+{ >+ TDB_DATA key, data; >+ fstring keystr; >+ fstring name; >+ >+ fstrcpy(name, pdb_get_username(newpwd)); >+ strlower_m(name); >+ > /* setup RID data */ > data.dsize = strlen(name) + 1; > data.dptr = name; > > /* setup the RID index key */ >- slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, user_rid); >+ slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, >+ pdb_get_user_rid(newpwd)); > key.dptr = keystr; > key.dsize = strlen (keystr) + 1; > >@@ -659,14 +679,63 @@ > DEBUG(0, ("Unable to modify TDB passwd !")); > DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb))); > DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr)); >+ return False; >+ } >+ >+ return True; >+ >+} >+ >+/*************************************************************************** >+ Update the TDB SAM >+****************************************************************************/ >+ >+static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag) >+{ >+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; >+ TDB_CONTEXT *pwd_tdb = NULL; >+ BOOL ret = True; >+ uint32 user_rid; >+ >+ /* invalidate the existing TDB iterator if it is open */ >+ >+ if (tdb_state->passwd_tdb) { >+ tdb_close(tdb_state->passwd_tdb); >+ tdb_state->passwd_tdb = NULL; >+ } >+ >+ /* open the account TDB passwd*/ >+ >+ pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); >+ >+ if (!pwd_tdb) { >+ DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", >+ tdb_state->tdbsam_location)); >+ return False; >+ } >+ >+ if (!pdb_get_group_rid(newpwd)) { >+ DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n", >+ pdb_get_username(newpwd))); > ret = False; > goto done; > } > >+ if ( !(user_rid = pdb_get_user_rid(newpwd)) ) { >+ DEBUG(0,("tdb_update_sam: SAM_ACCOUNT (%s) with no RID!\n", pdb_get_username(newpwd))); >+ ret = False; >+ goto done; >+ } >+ >+ if (!tdb_update_samacct_only(pwd_tdb, my_methods, newpwd, flag) || >+ !tdb_update_ridrec_only(pwd_tdb, my_methods, newpwd, flag)) { >+ ret = False; >+ goto done; >+ } >+ > done: > /* cleanup */ > tdb_close (pwd_tdb); >- SAFE_FREE(buf); > > return (ret); > } >@@ -695,6 +764,103 @@ > return NT_STATUS_UNSUCCESSFUL; > } > >+/*************************************************************************** >+ Renames a SAM_ACCOUNT >+ - check for the posix user/rename user script >+ - Add and lock the new user record >+ - rename the posix user >+ - rewrite the rid->username record >+ - delete the old user >+ - unlock the new user record >+***************************************************************************/ >+static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods, >+ SAM_ACCOUNT *oldname, const char *newname) >+{ >+ struct tdbsam_privates *tdb_state = >+ (struct tdbsam_privates *)my_methods->private_data; >+ SAM_ACCOUNT *new_acct = NULL; >+ pstring rename_script; >+ TDB_CONTEXT *pwd_tdb = NULL; >+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; >+ BOOL interim_account = False; >+ >+ if (!*(lp_renameuser_script())) >+ goto done; >+ >+ if (!pdb_copy_sam_account(oldname, &new_acct) || >+ !pdb_set_username(new_acct, newname, PDB_CHANGED)) >+ goto done; >+ >+ /* invalidate the existing TDB iterator if it is open */ >+ >+ if (tdb_state->passwd_tdb) { >+ tdb_close(tdb_state->passwd_tdb); >+ tdb_state->passwd_tdb = NULL; >+ } >+ >+ /* open the account TDB passwd */ >+ >+ pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); >+ >+ if (!pwd_tdb) { >+ DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", >+ tdb_state->tdbsam_location)); >+ goto done; >+ } >+ >+ /* add the new account and lock it */ >+ if (!tdb_update_samacct_only(pwd_tdb, my_methods, new_acct, >+ TDB_INSERT)) >+ goto done; >+ interim_account = True; >+ >+ if (tdb_lock_bystring(pwd_tdb, newname, 30) == -1) { >+ goto done; >+ } >+ >+ /* rename the posix user */ >+ pstrcpy(rename_script, lp_renameuser_script()); >+ >+ if (*rename_script) { >+ int rename_ret; >+ >+ pstring_sub(rename_script, "%unew", newname); >+ pstring_sub(rename_script, "%uold", pdb_get_username(oldname)); >+ rename_ret = smbrun(rename_script, NULL); >+ >+ DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret)); >+ >+ if (rename_ret) >+ goto done; >+ } else { >+ goto done; >+ } >+ >+ /* rewrite the rid->username record */ >+ if (!tdb_update_ridrec_only(pwd_tdb, my_methods, new_acct, TDB_MODIFY)) >+ goto done; >+ interim_account = False; >+ tdb_unlock_bystring(pwd_tdb, newname); >+ >+ tdb_delete_samacct_only(pwd_tdb, my_methods, oldname); >+ >+ ret = NT_STATUS_OK; >+ >+ >+done: >+ /* cleanup */ >+ if (interim_account) { >+ tdb_unlock_bystring(pwd_tdb, newname); >+ tdb_delete_samacct_only(pwd_tdb, my_methods, new_acct); >+ } >+ if (pwd_tdb) >+ tdb_close (pwd_tdb); >+ if (new_acct) >+ pdb_free_sam(&new_acct); >+ >+ return (ret); >+} >+ > static void free_private_data(void **vp) > { > struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp; >@@ -736,6 +902,7 @@ > (*pdb_method)->add_sam_account = tdbsam_add_sam_account; > (*pdb_method)->update_sam_account = tdbsam_update_sam_account; > (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account; >+ (*pdb_method)->rename_sam_account = tdbsam_rename_sam_account; > > tdb_state = TALLOC_ZERO_P(pdb_context->mem_ctx, struct tdbsam_privates); > >Index: passdb/pdb_interface.c >=================================================================== >--- passdb/pdb_interface.c (revision 10871) >+++ passdb/pdb_interface.c (working copy) >@@ -325,6 +325,41 @@ > return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct); > } > >+static NTSTATUS context_rename_sam_account(struct pdb_context *context, SAM_ACCOUNT *oldname, const char *newname) >+{ >+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; >+ >+ struct pdb_methods *pdb_selected; >+ if (!context) { >+ DEBUG(0, ("invalid pdb_context specified!\n")); >+ return ret; >+ } >+ >+ if (!oldname->methods){ >+ pdb_selected = context->pdb_methods; >+ /* There's no passdb backend specified for this account. >+ * Try to delete it in every passdb available >+ * Needed to delete accounts in smbpasswd that are not >+ * in /etc/passwd. >+ */ >+ while (pdb_selected){ >+ if (NT_STATUS_IS_OK(ret = pdb_selected->rename_sam_account(pdb_selected, oldname, newname))) { >+ return ret; >+ } >+ pdb_selected = pdb_selected->next; >+ } >+ return ret; >+ } >+ >+ if (!oldname->methods->rename_sam_account){ >+ DEBUG(0,("invalid oldname->methods->rename_sam_account\n")); >+ return ret; >+ } >+ >+ return oldname->methods->rename_sam_account(oldname->methods, oldname, newname); >+} >+ >+ > static NTSTATUS context_update_login_attempts(struct pdb_context *context, > SAM_ACCOUNT *sam_acct, BOOL success) > { >@@ -850,6 +885,7 @@ > (*context)->pdb_add_sam_account = context_add_sam_account; > (*context)->pdb_update_sam_account = context_update_sam_account; > (*context)->pdb_delete_sam_account = context_delete_sam_account; >+ (*context)->pdb_rename_sam_account = context_rename_sam_account; > (*context)->pdb_update_login_attempts = context_update_login_attempts; > (*context)->pdb_getgrsid = context_getgrsid; > (*context)->pdb_getgrgid = context_getgrgid; >@@ -1103,6 +1139,22 @@ > return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct)); > } > >+NTSTATUS pdb_rename_sam_account(SAM_ACCOUNT *oldname, const char *newname) >+{ >+ struct pdb_context *pdb_context = pdb_get_static_context(False); >+ >+ if (!pdb_context) { >+ return NT_STATUS_NOT_IMPLEMENTED; >+ } >+ >+ if (sam_account_cache != NULL) { >+ pdb_free_sam(&sam_account_cache); >+ sam_account_cache = NULL; >+ } >+ >+ return pdb_context->pdb_rename_sam_account(pdb_context, oldname, newname); >+} >+ > NTSTATUS pdb_update_login_attempts(SAM_ACCOUNT *sam_acct, BOOL success) > { > struct pdb_context *pdb_context = pdb_get_static_context(False); >@@ -1440,6 +1492,11 @@ > return NT_STATUS_NOT_IMPLEMENTED; > } > >+static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd, const char *newname) >+{ >+ return NT_STATUS_NOT_IMPLEMENTED; >+} >+ > static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, SAM_ACCOUNT *newpwd, BOOL success) > { > return NT_STATUS_OK; >@@ -1983,6 +2040,7 @@ > (*methods)->add_sam_account = pdb_default_add_sam_account; > (*methods)->update_sam_account = pdb_default_update_sam_account; > (*methods)->delete_sam_account = pdb_default_delete_sam_account; >+ (*methods)->rename_sam_account = pdb_default_rename_sam_account; > (*methods)->update_login_attempts = pdb_default_update_login_attempts; > > (*methods)->getgrsid = pdb_default_getgrsid; >Index: include/passdb.h >=================================================================== >--- include/passdb.h (revision 10871) >+++ include/passdb.h (working copy) >@@ -269,7 +269,7 @@ > * this SAMBA will load. Increment this if *ANY* changes are made to the interface. > */ > >-#define PASSDB_INTERFACE_VERSION 9 >+#define PASSDB_INTERFACE_VERSION 10 > > typedef struct pdb_context > { >@@ -294,6 +294,8 @@ > NTSTATUS (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); > > NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username); >+ >+ NTSTATUS (*pdb_rename_sam_account)(struct pdb_context *, SAM_ACCOUNT *oldname, const char *newname); > > NTSTATUS (*pdb_update_login_attempts)(struct pdb_context *context, SAM_ACCOUNT *sam_acct, BOOL success); > >@@ -422,6 +424,8 @@ > > NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username); > >+ NTSTATUS (*rename_sam_account)(struct pdb_methods *, SAM_ACCOUNT *oldname, const char *newname); >+ > NTSTATUS (*update_login_attempts)(struct pdb_methods *methods, SAM_ACCOUNT *sam_acct, BOOL success); > > NTSTATUS (*getgrsid)(struct pdb_methods *methods, GROUP_MAP *map, DOM_SID sid);
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 2861
: 1496