1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-26 01:49:31 +03:00

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 commit is contained in:
Jim McDonough
2005-10-11 20:14:04 +00:00
committed by Gerald (Jerry) Carter
parent 8075b99b44
commit 8210b0503a
5 changed files with 309 additions and 47 deletions

View File

@ -269,7 +269,7 @@ struct pdb_search {
* 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 @@ typedef struct pdb_context
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 @@ typedef struct pdb_methods
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);

View File

@ -151,6 +151,7 @@ typedef struct
char *szNameResolveOrder;
char *szPanicAction;
char *szAddUserScript;
char *szRenameUserScript;
char *szDelUserScript;
char *szAddGroupScript;
char *szDelGroupScript;
@ -1061,6 +1062,7 @@ static struct parm_struct parm_table[] = {
{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_passdb_backend, &Globals.szPassdbBackend)
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)

View File

@ -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;

View File

@ -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,6 +600,93 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_AC
return NT_STATUS_OK;
}
/***************************************************************************
Update the TDB SAM account record only
****************************************************************************/
static BOOL tdb_update_samacct_only(TDB_CONTEXT *pwd_tdb,
struct pdb_methods *my_methods,
SAM_ACCOUNT* newpwd, int flag)
{
TDB_DATA key, data;
uint8 *buf = NULL;
fstring keystr;
fstring name;
BOOL ret = True;
/* 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"));
ret = False;
goto done;
}
data.dptr = (char *)buf;
fstrcpy(name, pdb_get_username(newpwd));
strlower_m(name);
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);
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
/* add the account */
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));
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,
pdb_get_user_rid(newpwd));
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
/* add the reference */
if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
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
****************************************************************************/
@ -581,10 +695,6 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
{
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;
@ -618,47 +728,8 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
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"));
ret = False;
goto done;
}
data.dptr = (char *)buf;
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));
/* setup the USER index key */
slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
/* add the account */
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));
ret = False;
goto done;
}
/* 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);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
/* add the reference */
if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
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));
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);

View File

@ -2423,6 +2423,32 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
return r_u->status;
}
/*******************************************************************
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 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
/* 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;