diff options
-rw-r--r-- | source3/auth/auth_util.c | 4 | ||||
-rw-r--r-- | source3/groupdb/mapping.c | 1 | ||||
-rw-r--r-- | source3/include/rpc_samr.h | 5 | ||||
-rw-r--r-- | source3/param/loadparm.c | 4 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 86 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 20 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 29 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 40 |
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, |