From 922eb763d7365716fd3c20aa069746fc9bfb8ab3 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Tue, 4 Dec 2001 21:53:47 +0000 Subject: added a boolean to the group mapping functions to specify if we need or not the privileges. Usually we don't need them, so the memory is free early. lib/util_sid.c: added some helper functions to check an SID. passdb/passdb.c: renamed local_lookup_rid() to local_lookup_sid() and pass an RID all the way. If the group doesn't exist on the domain SID, don't return a faked one as it can collide with a builtin one. Some rpc structures have been badly designed, they return only rids and force the client to do subsequent lsa_lookup_sid() on the domain sid and the builtin sid ! rpc_server/srv_util.c: wrote a new version of get_domain_user_groups(). Only the samr code uses it atm. It uses the group mapping code instead of a bloody hard coded crap. The netlogon code will use it too, but I have to do some test first. J.F. (This used to be commit 6c87e96149101995b7d049657d5c26eefef37d8c) --- source3/groupdb/mapping.c | 96 +++++++++++++++++++++--------- source3/include/mapping.h | 3 + source3/lib/util_sid.c | 49 +++++++++++++++- source3/passdb/nispass.c | 3 +- source3/passdb/passdb.c | 46 ++++++--------- source3/passdb/pdb_ldap.c | 3 +- source3/passdb/pdb_nisplus.c | 3 +- source3/passdb/pdb_smbpasswd.c | 3 +- source3/rpc_server/srv_lsa_nt.c | 14 +++-- source3/rpc_server/srv_samr_nt.c | 124 +++++++++++++-------------------------- source3/rpc_server/srv_util.c | 77 ++++++++++++++++++++++++ source3/smbd/uid.c | 2 +- source3/utils/smbgroupedit.c | 14 +++-- 13 files changed, 278 insertions(+), 159 deletions(-) diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 137f971228..06fc30ad47 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -252,7 +252,7 @@ free a privilege list BOOL free_privilege(PRIVILEGE_SET *priv_set) { if (priv_set->count==0) { - DEBUG(10,("free_privilege: count=0, nothing to clear ?\n")); + DEBUG(100,("free_privilege: count=0, nothing to clear ?\n")); return False; } @@ -485,7 +485,7 @@ BOOL default_group_mapping(void) /**************************************************************************** return the sid and the type of the unix group ****************************************************************************/ -BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) +BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv) { TDB_DATA kbuf, dbuf; pstring key; @@ -533,6 +533,10 @@ BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) return False; } + /* we don't want the privileges */ + if (with_priv==MAPPING_WITHOUT_PRIV) + free_privilege(set); + sid_copy(&map->sid, &sid); return True; @@ -542,7 +546,7 @@ BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map) /**************************************************************************** return the sid and the type of the unix group ****************************************************************************/ -BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) +BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv) { TDB_DATA kbuf, dbuf, newkey; fstring string_sid; @@ -575,7 +579,7 @@ BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) set->set=(LUID_ATTR *)malloc(set->count*sizeof(LUID_ATTR)); if (set->set==NULL) { - DEBUG(0,("get_group_map_from_sid: could not allocate memory for privileges\n")); + DEBUG(0,("get_group_map_from_gid: could not allocate memory for privileges\n")); return False; } @@ -589,9 +593,12 @@ BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) continue; } - if (gid==map->gid) + if (gid==map->gid) { + if (!with_priv) + free_privilege(&map->priv_set); return True; - + } + free_privilege(set); } @@ -601,7 +608,7 @@ BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map) /**************************************************************************** return the sid and the type of the unix group ****************************************************************************/ -BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map) +BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map, BOOL with_priv) { TDB_DATA kbuf, dbuf, newkey; fstring string_sid; @@ -634,7 +641,7 @@ BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map) set->set=(LUID_ATTR *)malloc(set->count*sizeof(LUID_ATTR)); if (set->set==NULL) { - DEBUG(0,("get_group_map_from_sid: could not allocate memory for privileges\n")); + DEBUG(0,("get_group_map_from_ntname: could not allocate memory for privileges\n")); return False; } @@ -648,8 +655,11 @@ BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map) continue; } - if (StrCaseCmp(name, map->nt_name)==0) + if (StrCaseCmp(name, map->nt_name)==0) { + if (!with_priv) + free_privilege(&map->priv_set); return True; + } free_privilege(set); } @@ -692,7 +702,7 @@ BOOL group_map_remove(DOM_SID sid) enumerate the group mapping ****************************************************************************/ BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, - int *num_entries, BOOL unix_only) + int *num_entries, BOOL unix_only, BOOL with_priv) { TDB_DATA kbuf, dbuf, newkey; fstring string_sid; @@ -744,17 +754,20 @@ BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, SAFE_FREE(dbuf.dptr); if (ret != dbuf.dsize) { + DEBUG(11,("enum_group_mapping: error in memory size\n")); free_privilege(set); continue; } /* list only the type or everything if UNKNOWN */ if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) { + DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name)); free_privilege(set); continue; } if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) { + DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name)); free_privilege(set); continue; } @@ -762,6 +775,7 @@ BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, string_to_sid(&map.sid, string_sid); decode_sid_name_use(group_type, map.sid_name_use); + DEBUG(11,("enum_group_mapping: returning group %s of type %s\n", map.nt_name ,group_type)); mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP)); if (!mapt) { @@ -782,6 +796,8 @@ BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, mapt[entries].priv_set.count=set->count; mapt[entries].priv_set.control=set->control; mapt[entries].priv_set.set=set->set; + if (!with_priv) + free_privilege(&(mapt[entries].priv_set)); entries++; } @@ -860,31 +876,39 @@ void convert_priv_to_text(PRIVILEGE_SET *se_priv, char *privilege) /* get a domain group from it's SID */ -BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) +BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv) { struct group *grp; DEBUG(10, ("get_domain_group_from_sid\n")); /* if the group is NOT in the database, it CAN NOT be a domain group */ - if(!get_group_map_from_sid(sid, map)) + if(!get_group_map_from_sid(sid, map, with_priv)) return False; DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n")); /* if it's not a domain group, continue */ - if (map->sid_name_use!=SID_NAME_DOM_GRP) + if (map->sid_name_use!=SID_NAME_DOM_GRP) { + if (with_priv) + free_privilege(&map->priv_set); return False; + } DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n")); - if (map->gid==-1) + if (map->gid==-1) { + if (with_priv) + free_privilege(&map->priv_set); return False; + } DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%d\n",map->gid)); if ( (grp=getgrgid(map->gid)) == NULL) { DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n")); + if (with_priv) + free_privilege(&map->priv_set); return False; } @@ -896,20 +920,29 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map) /* get a local (alias) group from it's SID */ -BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) +BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv) { struct group *grp; /* The group is in the mapping table */ - if(get_group_map_from_sid(sid, map)) { - if (map->sid_name_use!=SID_NAME_ALIAS) + if(get_group_map_from_sid(sid, map, with_priv)) { + if (map->sid_name_use!=SID_NAME_ALIAS) { + if (with_priv) + free_privilege(&map->priv_set); return False; - - if (map->gid==-1) + } + + if (map->gid==-1) { + if (with_priv) + free_privilege(&map->priv_set); return False; + } - if ( (grp=getgrgid(map->gid)) == NULL) + if ( (grp=getgrgid(map->gid)) == NULL) { + if (with_priv) + free_privilege(&map->priv_set); return False; + } } else { /* the group isn't in the mapping table. * make one based on the unix information */ @@ -937,21 +970,30 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map) /* get a builtin group from it's SID */ -BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map) +BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv) { struct group *grp; - if(!get_group_map_from_sid(sid, map)) + if(!get_group_map_from_sid(sid, map, with_priv)) return False; - if (map->sid_name_use!=SID_NAME_WKN_GRP) + if (map->sid_name_use!=SID_NAME_WKN_GRP) { + if (with_priv) + free_privilege(&map->priv_set); return False; + } - if (map->gid==-1) + if (map->gid==-1) { + if (with_priv) + free_privilege(&map->priv_set); return False; + } - if ( (grp=getgrgid(map->gid)) == NULL) + if ( (grp=getgrgid(map->gid)) == NULL) { + if (with_priv) + free_privilege(&map->priv_set); return False; + } return True; } @@ -961,7 +1003,7 @@ BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map) /**************************************************************************** Returns a GROUP_MAP struct based on the gid. ****************************************************************************/ -BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) +BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv) { struct group *grp; @@ -971,7 +1013,7 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map) /* * make a group map from scratch if doesn't exist. */ - if (!get_group_map_from_gid(gid, map)) { + if (!get_group_map_from_gid(gid, map, with_priv)) { map->gid=gid; map->sid_name_use=SID_NAME_ALIAS; map->systemaccount=PR_ACCESS_FROM_NETWORK; diff --git a/source3/include/mapping.h b/source3/include/mapping.h index 4a7db6360d..9b46989ccb 100644 --- a/source3/include/mapping.h +++ b/source3/include/mapping.h @@ -33,6 +33,9 @@ #define ENUM_ONLY_MAPPED True #define ENUM_ALL_MAPPED False +#define MAPPING_WITH_PRIV True +#define MAPPING_WITHOUT_PRIV False + #define PR_NONE 0x0000 #define PR_LOG_ON_LOCALLY 0x0001 #define PR_ACCESS_FROM_NETWORK 0x0002 diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 7e9299b053..923037f479 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -581,6 +581,53 @@ BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2) } +/***************************************************************** + Check if the SID is our domain SID (S-1-5-21-x-y-z). +*****************************************************************/ +BOOL sid_check_is_domain(const DOM_SID *sid) +{ + return sid_equal(sid, &global_sam_sid); +} + + +/***************************************************************** + Check if the SID is the builtin SID (S-1-5-32). +*****************************************************************/ +BOOL sid_check_is_builtin(const DOM_SID *sid) +{ + return sid_equal(sid, &global_sid_Builtin); +} + + +/***************************************************************** + Check if the SID is our domain SID (S-1-5-21-x-y-z). +*****************************************************************/ +BOOL sid_check_is_in_our_domain(const DOM_SID *sid) +{ + DOM_SID dom_sid; + uint32 rid; + + sid_copy(&dom_sid, sid); + sid_split_rid(&dom_sid, &rid); + + return sid_equal(&dom_sid, &global_sam_sid); +} + +/***************************************************************** + Check if the SID is our domain SID (S-1-5-21-x-y-z). +*****************************************************************/ +BOOL sid_check_is_in_builtin(const DOM_SID *sid) +{ + DOM_SID dom_sid; + uint32 rid; + + sid_copy(&dom_sid, sid); + sid_split_rid(&dom_sid, &rid); + + return sid_equal(&dom_sid, &global_sid_Builtin); +} + + /***************************************************************** Calculates size of a sid. *****************************************************************/ @@ -608,7 +655,7 @@ BOOL non_mappable_sid(DOM_SID *sid) if (sid_equal(&dom, &global_sid_Builtin)) return True; - if (sid_equal(&dom, &global_sid_Creator_Owner_Domain)) + if (sid_equal(&dom, &global_sid_Creator_Owner_Domain)) return True; if (sid_equal(&dom, &global_sid_NT_Authority)) diff --git a/source3/passdb/nispass.c b/source3/passdb/nispass.c index 0f41b47549..3b7b90307d 100644 --- a/source3/passdb/nispass.c +++ b/source3/passdb/nispass.c @@ -308,8 +308,7 @@ static BOOL make_sam_from_nisp_object(struct sam_passwd *pw_buf, nis_object *obj else { GROUP_MAP map; - if (get_group_map_from_gid(pw_buf->smb_grpid, &map)) { - free_privileges(&map.priv_set); + if (get_group_map_from_gid(pw_buf->smb_grpid, &map, MAPPING_WITHOUT_PRIV)) { pw_buf->group_rid = map.rid; } else diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index e469718b5c..f54121cf63 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -143,8 +143,7 @@ BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd) pdb_set_user_rid(*new_sam_acct, pdb_uid_to_user_rid(pwd->pw_uid)); /* call the mapping code here */ - if(get_group_map_from_gid(pwd->pw_gid, &map)) { - free_privilege(&map.priv_set); + if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) { sid_peek_rid(&map.sid, &rid); } else rid=pdb_gid_to_group_rid(pwd->pw_gid); @@ -405,8 +404,7 @@ BOOL pdb_name_to_rid(const char *user_name, uint32 *u_rid, uint32 *g_rid) /* absolutely no idea what to do about the unix GID to Domain RID mapping */ /* map it ! */ - if (get_group_map_from_gid(pw->pw_gid, &map)) { - free_privilege(&map.priv_set); + if (get_group_map_from_gid(pw->pw_gid, &map, MAPPING_WITHOUT_PRIV)) { sid_peek_rid(&map.sid, g_rid); } else *g_rid = pdb_gid_to_group_rid(pw->pw_gid); @@ -491,13 +489,16 @@ BOOL pdb_rid_is_user(uint32 rid) Convert a rid into a name. Used in the lookup SID rpc. ********************************************************************/ -BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) +BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use) { - BOOL is_user = pdb_rid_is_user(rid); + uint32 rid; + BOOL is_user; + sid_peek_rid(sid, &rid); + is_user = pdb_rid_is_user(rid); *psid_name_use = SID_NAME_UNKNOWN; - DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" : + DEBUG(5,("local_lookup_sid: looking up %s RID %u.\n", is_user ? "user" : "group", (unsigned int)rid)); if(is_user) { @@ -529,7 +530,7 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) *psid_name_use = SID_NAME_USER; - DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid, + DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid, pass ? "succeeded" : "failed" )); if(!pass) { @@ -539,7 +540,7 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) fstrcpy(name, pass->pw_name); - DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name, + DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name, (unsigned int)rid )); } @@ -547,11 +548,7 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) gid_t gid; struct group *gr; GROUP_MAP map; - DOM_SID local_sid; - sid_copy(&local_sid, &global_sam_sid); - sid_append_rid(&local_sid, rid); - /* * Don't try to convert the rid to a name if running * in appliance mode @@ -561,10 +558,9 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) return False; /* check if it's a mapped group */ - if (get_group_map_from_sid(local_sid, &map)) { - free_privilege(&map.priv_set); + if (get_group_map_from_sid(*sid, &map, MAPPING_WITHOUT_PRIV)) { if (map.gid!=-1) { - DEBUG(5,("local_local_rid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid)); + DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid)); fstrcpy(name, map.nt_name); *psid_name_use = map.sid_name_use; return True; @@ -576,17 +572,17 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) *psid_name_use = SID_NAME_ALIAS; - DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid, + DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid, gr ? "succeeded" : "failed" )); if(!gr) { slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid); - return True; + return False; } fstrcpy( name, gr->gr_name); - DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name, + DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name, (unsigned int)rid )); } @@ -647,8 +643,7 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid, GROUP_MAP map; /* check if it's a mapped group */ - if (get_group_map_from_ntname(user, &map)) { - free_privilege(&map.priv_set); + if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) { if (map.gid!=-1) { /* yes it's a mapped group to a valid unix group */ sid_copy(&local_sid, &map.sid); @@ -675,8 +670,7 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid, * JFM, 30/11/2001 */ - if(get_group_map_from_gid(grp->gr_gid, &map)){ - free_privilege(&map.priv_set); + if(get_group_map_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)){ return False; } @@ -759,8 +753,7 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) sid_copy(psid, &global_sam_sid); - if (get_group_map_from_gid(gid, &map)) { - free_privilege(&map.priv_set); + if (get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) { sid_copy(psid, &map.sid); } else { @@ -801,8 +794,7 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) if (pdb_rid_is_user(rid)) return False; - if (get_group_map_from_sid(*psid, &map)) { - free_privilege(&map.priv_set); + if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) { /* the SID is in the mapping table but not mapped */ if (map.gid==-1) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index d0eebbed89..f426f926b1 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -585,8 +585,7 @@ static BOOL init_ldap_from_sam (LDAPMod *** mods, int ldap_state, const SAM_ACCO if ( !sampass->group_rid) { GROUP_MAP map; - if (get_group_map_from_gid(pdb_get_gid(sampass), &map)) { - free_privilege(&map.priv_set); + if (get_group_map_from_gid(pdb_get_gid(sampass), &map, MAPPING_WITHOUT_PRIV)) { sid_peek_rid(&map.sid, &sampass->group_rid); } else diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c index aff0870a8d..9fc4a0a65a 100644 --- a/source3/passdb/pdb_nisplus.c +++ b/source3/passdb/pdb_nisplus.c @@ -501,8 +501,7 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass, rid=pdb_get_group_rid(sampass); if (rid==0) { - if (get_group_map_from_gid(pdb_get_gid(sampass), &map)) { - free_privilege(&map.priv_set); + if (get_group_map_from_gid(pdb_get_gid(sampass), &map, MAPPING_WITHOUT_PRIV)) { sid_peek_rid(&map.sid, &rid); } else rid=pdb_gid_to_group_rid(pdb_get_gid(sampass)); diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index c189d9a9b7..e5b1ec97f7 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -1225,8 +1225,7 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw uint32 rid; GROUP_MAP map; - if (get_group_map_from_gid(pwfile->pw_gid, &map)) { - free_privilege(&map.priv_set); + if (get_group_map_from_gid(pwfile->pw_gid, &map, MAPPING_WITHOUT_PRIV)) { sid_peek_rid(&map.sid, &rid); } else diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index b16e3836f6..da5597132d 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -622,7 +622,7 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU return NT_STATUS_INVALID_HANDLE; /* get the list of mapped groups (domain, local, builtin) */ - if(!enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED)) + if(!enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) return NT_STATUS_OK; if (q_u->enum_context >= num_entries) @@ -727,7 +727,7 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LS if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - if (!get_group_map_from_sid(info->sid, &map)) + if (!get_group_map_from_sid(info->sid, &map, MAPPING_WITH_PRIV)) return NT_STATUS_NO_SUCH_GROUP; DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", map.priv_set.count)); @@ -768,7 +768,7 @@ NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - if (!get_group_map_from_sid(info->sid, &map)) + if (!get_group_map_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_GROUP; /* @@ -799,7 +799,7 @@ NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - if (!get_group_map_from_sid(info->sid, &map)) + if (!get_group_map_from_sid(info->sid, &map, MAPPING_WITH_PRIV)) return NT_STATUS_NO_SUCH_GROUP; map.systemaccount=q_u->access; @@ -807,6 +807,8 @@ NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA if(!add_mapping_entry(&map, TDB_REPLACE)) return NT_STATUS_NO_SUCH_GROUP; + free_privilege(&map.priv_set); + return r_u->status; } @@ -829,7 +831,7 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - if (!get_group_map_from_sid(info->sid, &map)) + if (!get_group_map_from_sid(info->sid, &map, MAPPING_WITH_PRIV)) return NT_STATUS_NO_SUCH_GROUP; set=&q_u->set; @@ -873,7 +875,7 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - if (!get_group_map_from_sid(info->sid, &map)) + if (!get_group_map_from_sid(info->sid, &map, MAPPING_WITH_PRIV)) return NT_STATUS_NO_SUCH_GROUP; if (q_u->allrights!=0) { diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 13340d0a60..cc81bac630 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -539,16 +539,6 @@ NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN return r_u->status; } -static uint32 get_lsa_policy_samr_rid(struct samr_info *info) -{ - if (!info) { - DEBUG(3,("Error getting policy\n")); - return 0xffffffff; - } - - return info->sid.sub_auths[info->sid.num_auths-1]; -} - /******************************************************************* _samr_get_usrdom_pwinfo ********************************************************************/ @@ -560,14 +550,11 @@ NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, r_u->status = NT_STATUS_OK; /* find the policy handle. open a policy on it. */ - if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) { + if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - } - /* find the user's rid */ - if (get_lsa_policy_samr_rid(info) == 0xffffffff) { + if (!sid_check_is_in_our_domain(&info->sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; - } init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK); @@ -813,12 +800,9 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM /* well-known aliases */ if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) { - enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED); - - if (num_entries != 0) { - for (i=0; inext) { uint32 trid; - if(!get_group_from_gid(grp->gr_gid, &smap)) { + if(!get_group_from_gid(grp->gr_gid, &smap, MAPPING_WITHOUT_PRIV)) continue; - } - - /* - * free early the privilege struct as it's not used - * and prevent leaking mem. - */ - free_privilege(&smap.priv_set); if (smap.sid_name_use!=SID_NAME_ALIAS) { continue; } sid_split_rid(&smap.sid, &trid); + + if (!sid_equal(sid, &smap.sid)) + continue; /* Don't return winbind groups as they are not local! */ if (strchr_m(smap.nt_name, *sep) != NULL) { @@ -937,14 +917,7 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO *p_num_entries = 0; - enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); - - /* - * free early the privilege struct as it's not used - * and prevent leaking mem. - */ - for (i=0; istatus = NT_STATUS_OK; @@ -1217,11 +1189,11 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - alias_rid = get_lsa_policy_samr_rid(info); - if(alias_rid == 0xffffffff) - return NT_STATUS_NO_SUCH_ALIAS; + if (!sid_check_is_in_our_domain(&info->sid) && + !sid_check_is_in_builtin(&info->sid)) + return NT_STATUS_OBJECT_TYPE_MISMATCH; - if(!local_lookup_rid(alias_rid, alias, &type)) + if(!local_lookup_sid(&info->sid, alias, &type)) return NT_STATUS_NO_SUCH_ALIAS; switch (q_u->switch_level) { @@ -1748,10 +1720,11 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - /* find the user's rid */ - if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff) + if (!sid_check_is_in_our_domain(&info->sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; + sid_peek_rid(&info->sid, &rid); + DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid)); ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR)); @@ -1861,7 +1834,6 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S * JFM, 12/2/2001 */ - r_u->status = NT_STATUS_OK; DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__)); @@ -1870,10 +1842,11 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info)) return NT_STATUS_INVALID_HANDLE; - /* find the user's rid */ - if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff) + if (!sid_check_is_in_our_domain(&info->sid)) return NT_STATUS_OBJECT_TYPE_MISMATCH; + sid_peek_rid(&info->sid, &rid); + pdb_init_sam(&sam_pass); become_root(); @@ -1885,11 +1858,10 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S return NT_STATUS_NO_SUCH_USER; } - *groups = 0; - - get_domain_user_groups(groups, pdb_get_username(sam_pass)); - gids = NULL; - num_groups = make_dom_gids(p->mem_ctx, groups, &gids); + if(!new_get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) { + samr_clear_sam_passwd(sam_pass); + return NT_STATUS_NO_SUCH_GROUP; + } /* construct the response. lkclXXXX: gids are not copied! */ init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status); @@ -2304,12 +2276,12 @@ NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OP * JFM. */ - /* associate the user's SID with the new handle. */ - if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) - return NT_STATUS_NO_MEMORY; + /* associate the user's SID with the new handle. */ + if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) + return NT_STATUS_NO_MEMORY; - ZERO_STRUCTP(info); - info->sid = sid; + ZERO_STRUCTP(info); + info->sid = sid; /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info)) @@ -2808,18 +2780,16 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ if (sid_equal(&alias_sid, &global_sid_Builtin)) { DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n")); - if(!get_local_group_from_sid(als_sid, &map)) + if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; } else { if (sid_equal(&alias_sid, &global_sam_sid)) { DEBUG(10, ("lookup on Server SID\n")); - if(!get_local_group_from_sid(als_sid, &map)) + if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; } } - free_privilege(&map.priv_set); - if(!get_uid_list_of_group(map.gid, &uid, &num_uids)) return NT_STATUS_NO_SUCH_ALIAS; @@ -2877,11 +2847,9 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ sid_append_rid(&group_sid, group_rid); DEBUG(10, ("lookup on Domain SID\n")); - if(!get_domain_group_from_sid(group_sid, &map)) + if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_GROUP; - free_privilege(&map.priv_set); - if(!get_uid_list_of_group(map.gid, &uid, &num_uids)) return NT_STATUS_NO_SUCH_GROUP; @@ -2925,21 +2893,19 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD if (sid_compare(&alias_sid, &global_sam_sid)>0) { DEBUG(10, ("adding member on Server SID\n")); - if(!get_local_group_from_sid(alias_sid, &map)) + if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; } else { if (sid_compare(&alias_sid, &global_sid_Builtin)>0) { DEBUG(10, ("adding member on BUILTIN SID\n")); - if( !get_local_group_from_sid(alias_sid, &map)) + if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; } else return NT_STATUS_NO_SUCH_ALIAS; } - free_privilege(&map.priv_set); - sid_split_rid(&q_u->sid.sid, &rid); uid=pdb_user_rid_to_uid(rid); @@ -3004,11 +2970,9 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD DEBUG(10, ("lookup on Domain SID\n")); - if(!get_domain_group_from_sid(group_sid, &map)) + if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_GROUP; - free_privilege(&map.priv_set); - if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL) return NT_STATUS_NO_SUCH_USER; @@ -3089,11 +3053,9 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S DEBUG(10, ("lookup on Domain SID\n")); - if(!get_domain_group_from_sid(group_sid, &map)) + if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; - free_privilege(&map.priv_set); - gid=map.gid; /* check if group really exists */ @@ -3148,11 +3110,9 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S DEBUG(10, ("lookup on Local SID\n")); - if(!get_local_group_from_sid(alias_sid, &map)) + if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_ALIAS; - free_privilege(&map.priv_set); - gid=map.gid; /* check if group really exists */ @@ -3312,11 +3272,9 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - if (!get_domain_group_from_sid(group_sid, &map)) + if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_INVALID_HANDLE; - free_privilege(&map.priv_set); - ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR)); if (ctr==NULL) return NT_STATUS_NO_MEMORY; @@ -3357,7 +3315,7 @@ NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - if (!get_domain_group_from_sid(group_sid, &map)) + if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV)) return NT_STATUS_NO_SUCH_GROUP; ctr=q_u->ctr; @@ -3399,7 +3357,7 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_ if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid)) return NT_STATUS_INVALID_HANDLE; - if (!get_local_group_from_sid(group_sid, &map)) + if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV)) return NT_STATUS_NO_SUCH_GROUP; ctr=&q_u->ctr; @@ -3463,11 +3421,9 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string)); /* check if that group really exists */ - if (!get_domain_group_from_sid(info->sid, &map)) + if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV)) return NT_STATUS_NO_SUCH_GROUP; - free_privilege(&map.priv_set); - /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index 40831cbad7..70ee377e2c 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -150,6 +150,83 @@ int make_dom_gids(TALLOC_CTX *ctx, char *gids_str, DOM_GID **ppgids) return count; } +/******************************************************************* + gets a domain user's groups + ********************************************************************/ +BOOL new_get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SAM_ACCOUNT *sam_pass) +{ + GROUP_MAP *map=NULL; + int i, num, num_entries, cur_gid=0; + struct group *grp; + DOM_GID *gids; + fstring user_name; + uint32 grid; + uint32 tmp_rid; + + fstrcpy(user_name, pdb_get_username(sam_pass)); + grid=pdb_get_group_rid(sam_pass); + + DEBUG(10,("new_get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name)); + + /* first get the list of the domain groups */ + if (!enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) + return False; + DEBUG(10,("new_get_domain_user_groups: there are %d mapped groups\n", num_entries)); + + + /* + * alloc memory. In the worse case, we alloc memory for nothing. + * but I prefer to alloc for nothing + * than reallocing everytime. + */ + gids = (DOM_GID *)talloc(ctx, sizeof(DOM_GID) * num_entries); + + /* for each group, check if the user is a member of*/ + for(i=0; igr_mem[num]!=NULL; num++) { + if(strcmp(grp->gr_mem[num], user_name)==0) { + /* we found the user, add the group to the list */ + sid_peek_rid(&map[i].sid, &(gids[cur_gid].g_rid)); + gids[cur_gid].attr=map[i].sid_name_use; + DEBUG(10,("new_get_domain_user_groups: user found in group %s\n", map[i].nt_name)); + cur_gid++; + break; + } + } + } + + /* we have checked the groups */ + /* we must now check the gid of the user or the primary group rid, that's the same */ + for (i=0; i Unix group\n"); - if (!enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED)) + if (!enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED, MAPPING_WITH_PRIV)) return -1; for (i=0; i