summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
authorJim McDonough <jmcd@samba.org>2005-10-11 20:14:04 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:04:56 -0500
commit254938c636b6062630d54a598b2975d7a984f70d (patch)
treef8008c90b1719919308016dd9723e296a41bfac0 /source3/passdb
parenta5b2ec0ba0b13095d5b129ff2f4d3d6e1fea951a (diff)
downloadsamba-254938c636b6062630d54a598b2975d7a984f70d.tar.gz
samba-254938c636b6062630d54a598b2975d7a984f70d.tar.bz2
samba-254938c636b6062630d54a598b2975d7a984f70d.zip
r10911: part of #2861: add rename support for usrmgr.exe when using tdbsam
This gets it working before replacing tdb with the samba4 version. (This used to be commit 8210b0503a050e12ee1b4335fa6e50d10ad06577)
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/pdb_interface.c58
-rw-r--r--source3/passdb/pdb_tdb.c248
2 files changed, 266 insertions, 40 deletions
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index a9e41984c3..485f405568 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -325,6 +325,41 @@ static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCO
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 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
(*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 @@ BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
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 @@ static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM
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 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
(*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;
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index 755e33940b..f04c82a5b1 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -6,6 +6,7 @@
* Copyright (C) Gerald Carter 2000
* Copyright (C) Jeremy Allison 2001
* Copyright (C) Andrew Bartlett 2002
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
@@ -515,6 +516,32 @@ static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT *
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,50 +600,19 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_AC
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) {
@@ -629,7 +625,9 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
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 +638,40 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
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,6 +680,56 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
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;
}
@@ -666,7 +737,6 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
done:
/* cleanup */
tdb_close (pwd_tdb);
- SAFE_FREE(buf);
return (ret);
}
@@ -695,6 +765,103 @@ static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCO
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 +903,7 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth
(*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);