summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/auth/auth_util.c4
-rw-r--r--source3/groupdb/mapping.c1
-rw-r--r--source3/include/rpc_samr.h5
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/passdb/pdb_interface.c86
-rw-r--r--source3/passdb/pdb_tdb.c20
-rw-r--r--source3/rpc_parse/parse_samr.c29
-rw-r--r--source3/rpc_server/srv_samr_nt.c40
8 files changed, 162 insertions, 27 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 2ece2a6150..31bc2664b8 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -834,7 +834,7 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
/* We can only create a mapping if winbind is running
and the nested group functionality has been enabled */
- if ( lp_winbind_nested_groups() ) {
+ if ( lp_winbind_nested_groups() && winbind_ping() ) {
become_root();
status = create_builtin_administrators( );
if ( !NT_STATUS_IS_OK(status) ) {
@@ -860,7 +860,7 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
/* We can only create a mapping if winbind is running
and the nested group functionality has been enabled */
- if ( lp_winbind_nested_groups() ) {
+ if ( lp_winbind_nested_groups() && winbind_ping() ) {
become_root();
status = create_builtin_users( );
if ( !NT_STATUS_IS_OK(status) ) {
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c
index 830584979b..5569dbf4ed 100644
--- a/source3/groupdb/mapping.c
+++ b/source3/groupdb/mapping.c
@@ -1164,6 +1164,7 @@ NTSTATUS pdb_default_set_aliasinfo(struct pdb_methods *methods,
if (!pdb_getgrsid(&map, *sid))
return NT_STATUS_NO_SUCH_ALIAS;
+ fstrcpy(map.nt_name, info->acct_name);
fstrcpy(map.comment, info->acct_desc);
return pdb_update_group_mapping_entry(&map);
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index ccb4fc9e44..8a3c4a8420 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -1204,6 +1204,10 @@ typedef struct {
} ALIAS_INFO1;
typedef struct {
+ UNISTR4 name;
+} ALIAS_INFO2;
+
+typedef struct {
UNISTR4 description;
} ALIAS_INFO3;
@@ -1216,6 +1220,7 @@ typedef struct {
uint16 level;
union {
ALIAS_INFO1 info1;
+ ALIAS_INFO2 info2;
ALIAS_INFO3 info3;
} alias;
} ALIAS_INFO_CTR;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 7b831d1e98..0bde5805b0 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -3212,7 +3212,7 @@ static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
{
uint32 low, high;
- if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
+ if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
return False;
/* Parse OK */
@@ -3229,7 +3229,7 @@ static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
{
uint32 low, high;
- if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
+ if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
return False;
/* Parse OK */
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 );
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index 2f8fe74ed3..2a9daa0e47 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -3554,6 +3554,28 @@ BOOL samr_io_alias_info3(const char *desc, ALIAS_INFO3 *al3,
reads or writes a structure.
********************************************************************/
+BOOL samr_io_alias_info2(const char *desc, ALIAS_INFO2 *al2,
+ prs_struct *ps, int depth)
+{
+ if (al2 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_alias_info2");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if (!prs_unistr4("name", ps, depth, &al2->name))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
BOOL samr_alias_info_ctr(const char *desc, prs_struct *ps, int depth, ALIAS_INFO_CTR * ctr)
{
if ( !ctr )
@@ -3572,6 +3594,10 @@ BOOL samr_alias_info_ctr(const char *desc, prs_struct *ps, int depth, ALIAS_INFO
if(!samr_io_alias_info1("alias_info1", &ctr->alias.info1, ps, depth))
return False;
break;
+ case 2:
+ if(!samr_io_alias_info2("alias_info2", &ctr->alias.info2, ps, depth))
+ return False;
+ break;
case 3:
if(!samr_io_alias_info3("alias_info3", &ctr->alias.info3, ps, depth))
return False;
@@ -4474,6 +4500,9 @@ BOOL samr_io_r_delete_dom_alias(const char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
if(!prs_align(ps))
return False;
+ if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
+ return False;
+
if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 6a4c9f7133..dc17977041 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -3464,9 +3464,14 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info))
return NT_STATUS_INVALID_HANDLE;
- /* observed when joining XP client to Samba domain */
+#if 0 /* this really should be applied on a per info level basis --jerry */
+
+ /* observed when joining XP client to Samba domain */
acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
+#else
+ acc_required = SA_RIGHT_USER_SET_ATTRIBUTES;
+#endif
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
return r_u->status;
@@ -4093,12 +4098,22 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S
if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, &disp_info))
return NT_STATUS_INVALID_HANDLE;
+ /* copy the handle to the outgoing reply */
+
+ memcpy( &r_u->pol, &q_u->alias_pol, sizeof(r_u->pol) );
+
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
return r_u->status;
}
DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
+ /* Don't let Windows delete builtin groups */
+
+ if ( sid_check_is_in_builtin( &alias_sid ) ) {
+ return NT_STATUS_SPECIAL_ACCOUNT;
+ }
+
if (!sid_check_is_in_our_domain(&alias_sid))
return NT_STATUS_NO_SUCH_ALIAS;
@@ -4453,7 +4468,30 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_
ctr=&q_u->ctr;
+ /* get the current group information */
+
+ if ( !pdb_get_aliasinfo( &group_sid, &info ) ) {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
switch (ctr->level) {
+ case 2:
+ /* We currently do not support renaming groups in the
+ the BUILTIN domain. Refer to util_builtin.c to understand
+ why. The eventually needs to be fixed to be like Windows
+ where you can rename builtin groups, just not delete them */
+
+ if ( sid_check_is_in_builtin( &group_sid ) ) {
+ return NT_STATUS_SPECIAL_ACCOUNT;
+ }
+
+ if ( ctr->alias.info2.name.string ) {
+ unistr2_to_ascii( info.acct_name, ctr->alias.info2.name.string,
+ sizeof(info.acct_name)-1 );
+ }
+ else
+ fstrcpy( info.acct_name, "" );
+ break;
case 3:
if ( ctr->alias.info3.description.string ) {
unistr2_to_ascii( info.acct_desc,