/* 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) ) {
/* 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) ) {
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);
uint32 num_member;
} ALIAS_INFO1;
+typedef struct {
+ UNISTR4 name;
+} ALIAS_INFO2;
+
typedef struct {
UNISTR4 description;
} ALIAS_INFO3;
uint16 level;
union {
ALIAS_INFO1 info1;
+ ALIAS_INFO2 info2;
ALIAS_INFO3 info3;
} alias;
} ALIAS_INFO_CTR;
{
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 */
{
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 */
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;
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);
}
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;
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);
}
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)
return False;
}
- return NT_STATUS_IS_OK(pdb->delete_alias(pdb,
- sid));
+ return NT_STATUS_IS_OK(pdb->delete_alias(pdb, sid));
}
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)
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)
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;
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;
}
/***************************************************************
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 */
/* 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;
}
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 );
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 )
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;
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;
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;
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;
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,