summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/pdb_interface.c86
-rw-r--r--source3/passdb/pdb_tdb.c20
2 files changed, 84 insertions, 22 deletions
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 7ff0214c72..5fdc8ac819 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -426,6 +426,13 @@ static int smb_delete_user(const char *unix_user)
pstring del_script;
int ret;
+ /* safety check */
+
+ if ( strequal( unix_user, "root" ) ) {
+ DEBUG(0,("smb_delete_user: Refusing to delete local system root account!\n"));
+ return -1;
+ }
+
pstrcpy(del_script, lp_deluser_script());
if (! *del_script)
return -1;
@@ -462,11 +469,22 @@ static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods,
NTSTATUS pdb_delete_user(TALLOC_CTX *mem_ctx, struct samu *sam_acct)
{
struct pdb_methods *pdb = pdb_get_methods();
+ uid_t uid = -1;
if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
+ /* sanity check to make sure we don't delete root */
+
+ if ( !sid_to_uid( pdb_get_user_sid(sam_acct), &uid ) ) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if ( uid == 0 ) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
return pdb->delete_user(pdb, mem_ctx, sam_acct);
}
@@ -516,6 +534,7 @@ NTSTATUS pdb_delete_sam_account(struct samu *sam_acct)
NTSTATUS pdb_rename_sam_account(struct samu *oldname, const char *newname)
{
struct pdb_methods *pdb = pdb_get_methods();
+ uid_t uid;
if ( !pdb ) {
return NT_STATUS_NOT_IMPLEMENTED;
@@ -526,6 +545,16 @@ NTSTATUS pdb_rename_sam_account(struct samu *oldname, const char *newname)
csamuser = NULL;
}
+ /* sanity check to make sure we don't rename root */
+
+ if ( !sid_to_uid( pdb_get_user_sid(oldname), &uid ) ) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if ( uid == 0 ) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
return pdb->rename_sam_account(pdb, oldname, newname);
}
@@ -976,8 +1005,7 @@ BOOL pdb_find_alias(const char *name, DOM_SID *sid)
return False;
}
- return NT_STATUS_IS_OK(pdb->find_alias(pdb,
- name, sid));
+ return NT_STATUS_IS_OK(pdb->find_alias(pdb, name, sid));
}
NTSTATUS pdb_create_alias(const char *name, uint32 *rid)
@@ -999,8 +1027,7 @@ BOOL pdb_delete_alias(const DOM_SID *sid)
return False;
}
- return NT_STATUS_IS_OK(pdb->delete_alias(pdb,
- sid));
+ return NT_STATUS_IS_OK(pdb->delete_alias(pdb, sid));
}
@@ -1012,8 +1039,7 @@ BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
return False;
}
- return NT_STATUS_IS_OK(pdb->get_aliasinfo(pdb, sid,
- info));
+ return NT_STATUS_IS_OK(pdb->get_aliasinfo(pdb, sid, info));
}
BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
@@ -1024,8 +1050,7 @@ BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
return False;
}
- return NT_STATUS_IS_OK(pdb->set_aliasinfo(pdb, sid,
- info));
+ return NT_STATUS_IS_OK(pdb->set_aliasinfo(pdb, sid, info));
}
NTSTATUS pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
@@ -1192,9 +1217,21 @@ BOOL pdb_rid_algorithm(void)
return pdb->rid_algorithm(pdb);
}
+/********************************************************************
+ Allocate a new RID from the passdb backend. Verify that it is free
+ by calling lookup_global_sam_rid() to verify that the RID is not
+ in use. This handles servers that have existing users or groups
+ with add RIDs (assigned from previous algorithmic mappings)
+********************************************************************/
+
BOOL pdb_new_rid(uint32 *rid)
{
struct pdb_methods *pdb = pdb_get_methods();
+ const char *name = NULL;
+ enum SID_NAME_USE type;
+ uint32 allocated_rid = 0;
+ int i;
+ TALLOC_CTX *ctx;
if ( !pdb ) {
return False;
@@ -1215,7 +1252,38 @@ BOOL pdb_new_rid(uint32 *rid)
return False;
}
- return pdb->new_rid(pdb, rid);
+ if ( (ctx = talloc_init("pdb_new_rid")) == NULL ) {
+ DEBUG(0,("pdb_new_rid: Talloc initialization failure\n"));
+ return False;
+ }
+
+ /* Attempt to get an unused RID (max tires is 250...yes that it is
+ and arbitrary number I pulkled out of my head). -- jerry */
+
+ for ( i=0; allocated_rid==0 && i<250; i++ ) {
+ /* get a new RID */
+
+ if ( !pdb->new_rid(pdb, &allocated_rid) ) {
+ return False;
+ }
+
+ /* validate that the RID is not in use */
+
+ if ( lookup_global_sam_rid( ctx, allocated_rid, &name, &type, NULL ) ) {
+ allocated_rid = 0;
+ }
+ }
+
+ TALLOC_FREE( ctx );
+
+ if ( allocated_rid == 0 ) {
+ DEBUG(0,("pdb_new_rid: Failed to find unused RID\n"));
+ return False;
+ }
+
+ *rid = allocated_rid;
+
+ return True;
}
/***************************************************************
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index b7161ff589..94ae328812 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -1382,19 +1382,12 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
BOOL interim_account = False;
int rename_ret;
- /* make sure we have an open handle to the tdb. Should have happened
- at module initialization time */
-
- if ( !tdbsam ) {
- DEBUG(0,("tdbsam_getsampwrid: tdbsam not open!\n"));
- return NT_STATUS_NO_SUCH_USER;
- }
-
/* can't do anything without an external script */
pstrcpy(rename_script, lp_renameuser_script() );
- if ( ! *rename_script )
+ if ( ! *rename_script ) {
return NT_STATUS_ACCESS_DENIED;
+ }
/* invalidate the existing TDB iterator if it is open */
@@ -1421,8 +1414,7 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
/* add the new account and lock it */
- if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) )
- {
+ if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) ) {
goto done;
}
@@ -1441,13 +1433,15 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
- if (rename_ret)
+ if (rename_ret) {
goto done;
+ }
/* rewrite the rid->username record */
- if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) )
+ if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) ) {
goto done;
+ }
interim_account = False;
tdb_unlock_bystring( tdbsam, newname );