From 641d9e85ea6a134be1d3359b41b8872f6ef65872 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Aug 2000 00:45:40 +0000 Subject: Added code to do SID to uid/gid conversion. Needed for ACL support. Jeremy. (This used to be commit 81c5380f91839b6416c8a42739dadf00e7388528) --- source3/include/proto.h | 21 ++--- source3/lib/util_sid.c | 4 +- source3/nsswitch/wb_client.c | 188 ++++++++++++++++++++++++++++++++++++++--- source3/passdb/passdb.c | 75 +++++++++++++++- source3/printing/nt_printing.c | 4 +- 5 files changed, 266 insertions(+), 26 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index d647acf608..e782507cf7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -441,7 +441,7 @@ void become_user_permanently(uid_t uid, gid_t gid); void generate_wellknown_sids(void); BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain); -BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, uint8 *psid_name_use); +BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, enum SID_NAME_USE *psid_name_use); BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain); void split_domain_name(const char *fullname, char *domain, char *name); char *sid_to_string(fstring sidstr_out, DOM_SID *sid); @@ -1275,15 +1275,14 @@ void expire_workgroups_and_servers(time_t t); /*The following definitions come from nsswitch/wb_client.c */ -BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type); -BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, - uint8 *name_type); -BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid); -BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid); -BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type); -BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type); +BOOL winbind_lookup_name(char *name, DOM_SID *sid, enum SID_NAME_USE *name_type); +BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type); +BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type); +BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type); DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid); DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid); +BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype); +BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype); /*The following definitions come from nsswitch/wb_common.c */ @@ -1627,10 +1626,12 @@ gid_t pdb_user_rid_to_gid(uint32 user_rid); uint32 pdb_uid_to_user_rid(uid_t uid); uint32 pdb_gid_to_group_rid(gid_t gid); BOOL pdb_rid_is_user(uint32 rid); -BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use); -BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use); +BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use); +BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use); DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid); +BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type); DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid); +BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type); /*The following definitions come from passdb/secrets.c */ diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 52e9f63039..439bb74a83 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -46,7 +46,7 @@ const DOM_SID *global_sid_everyone = &global_sid_World; typedef struct _known_sid_users { uint32 rid; - uint8 sid_name_use; + enum SID_NAME_USE sid_name_use; char *known_user_name; } known_sid_users; @@ -134,7 +134,7 @@ BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain) Looks up a known username from one of the known domains. ***************************************************************************/ -BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, uint8 *psid_name_use) +BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) { int i = 0; struct sid_name_map_info *psnm; diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c index 47f1520efa..bdfd25acce 100644 --- a/source3/nsswitch/wb_client.c +++ b/source3/nsswitch/wb_client.c @@ -27,7 +27,7 @@ /* Call winbindd to convert a name to a sid */ -BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type) +BOOL winbind_lookup_name(char *name, DOM_SID *sid, enum SID_NAME_USE *name_type) { struct winbindd_request request; struct winbindd_response response; @@ -45,7 +45,7 @@ BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type) if ((result = winbindd_request(WINBINDD_LOOKUPNAME, &request, &response)) == NSS_STATUS_SUCCESS) { string_to_sid(sid, response.data.sid.sid); - *name_type = response.data.sid.type; + *name_type = (enum SID_NAME_USE)response.data.sid.type; } return result == NSS_STATUS_SUCCESS; @@ -53,8 +53,7 @@ BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type) /* Call winbindd to convert sid to name */ -BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, - uint8 *name_type) +BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) { struct winbindd_request request; struct winbindd_response response; @@ -96,7 +95,40 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, if (result == NSS_STATUS_SUCCESS) { parse_domain_user(response.data.name.name, dom_name, name); - *name_type = response.data.name.type; + *name_type = (enum SID_NAME_USE)response.data.name.type; + } + + return (result == NSS_STATUS_SUCCESS); +} + +/* Call winbindd to convert SID to uid */ + +static BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid) +{ + struct winbindd_request request; + struct winbindd_response response; + int result; + fstring sid_str; + + if (!puid) + return False; + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + sid_to_string(sid_str, sid); + fstrcpy(request.data.sid, sid_str); + + /* Make request */ + + result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response); + + /* Copy out result */ + + if (result == NSS_STATUS_SUCCESS) { + *puid = response.data.uid; } return (result == NSS_STATUS_SUCCESS); @@ -104,7 +136,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, /* Call winbindd to convert uid to sid */ -BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) +static BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) { struct winbindd_request request; struct winbindd_response response; @@ -135,9 +167,42 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) return (result == NSS_STATUS_SUCCESS); } -/* Call winbindd to convert uid to sid */ +/* Call winbindd to convert SID to gid */ -BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) +static BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid) +{ + struct winbindd_request request; + struct winbindd_response response; + int result; + fstring sid_str; + + if (!pgid) + return False; + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + sid_to_string(sid_str, sid); + fstrcpy(request.data.sid, sid_str); + + /* Make request */ + + result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response); + + /* Copy out result */ + + if (result == NSS_STATUS_SUCCESS) { + *pgid = response.data.gid; + } + + return (result == NSS_STATUS_SUCCESS); +} + +/* Call winbindd to convert gid to sid */ + +static BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) { struct winbindd_request request; struct winbindd_response response; @@ -175,7 +240,7 @@ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) Tries winbind first - then uses local lookup. *****************************************************************/ -BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type) +BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) { extern pstring global_myname; @@ -193,7 +258,7 @@ BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type) Tries winbind first - then uses local lookup. *****************************************************************/ -BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type) +BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) { if (!winbind_lookup_sid(sid, dom_name, name, name_type)) { fstring sid_str; @@ -243,3 +308,106 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) return psid; } + +/***************************************************************** + *THE CANNONICAL* convert SID to uid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + + *sidtype = SID_NAME_UNKNOWN; + + /* + * First we must look up the name and decide if this is a user sid. + */ + + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { + fstring sid_str; + DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", + sid_to_string(sid_str, psid) )); + + return local_sid_to_uid(psid, puid, sidtype); + } + + /* + * Ensure this is a user sid. + */ + + if (name_type != SID_NAME_USER) { + DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", + (unsigned int)name_type )); + return False; + } + + *sidtype = SID_NAME_USER; + + /* + * Get the uid for this SID. + */ + + if (!winbind_sid_to_uid(puid, psid)) { + DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + return False; + } + + return True; +} + +/***************************************************************** + *THE CANNONICAL* convert SID to gid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + + *sidtype = SID_NAME_UNKNOWN; + + /* + * First we must look up the name and decide if this is a group sid. + */ + + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { + fstring sid_str; + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", + sid_to_string(sid_str, psid) )); + + return local_sid_to_gid(psid, pgid, sidtype); + } + + /* + * Ensure this is a group sid. + */ + + if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { + DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n", + (unsigned int)name_type )); + + return local_sid_to_gid(psid, pgid, sidtype); + } + + *sidtype = name_type; + + /* + * Get the gid for this SID. + */ + + if (!winbind_sid_to_gid(pgid, psid)) { + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + return False; + } + + return True; +} diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index f0fe2499df..a05783ac36 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -1091,7 +1091,7 @@ 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, uint8 *psid_name_use) +BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) { BOOL is_user = pdb_rid_is_user(rid); @@ -1159,7 +1159,7 @@ BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use) Convert a name into a SID. Used in the lookup name rpc. ********************************************************************/ -BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use) +BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use) { extern DOM_SID global_sid_World_Domain; struct passwd *pass = NULL; @@ -1219,6 +1219,42 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) return psid; } + +/**************************************************************************** + Convert a SID to uid - locally. +****************************************************************************/ + +BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + extern DOM_SID global_sam_sid; + DOM_SID dom_sid; + uint32 rid; + + *name_type = SID_NAME_UNKNOWN; + + sid_copy(&dom_sid, psid); + sid_split_rid(&dom_sid, &rid); + + /* + * We can only convert to a uid if this is our local + * Domain SID (ie. we are the controling authority). + */ + + if (!sid_equal(&global_sam_sid, &dom_sid)) + return False; + + *puid = pdb_user_rid_to_uid(rid); + + /* + * Ensure this uid really does exist. + */ + + if(!sys_getpwuid(*puid)) + return False; + + return True; +} + /**************************************************************************** Convert a gid to SID - locally. ****************************************************************************/ @@ -1232,3 +1268,38 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) return psid; } + +/**************************************************************************** + Convert a SID to gid - locally. +****************************************************************************/ + +BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + extern DOM_SID global_sam_sid; + DOM_SID dom_sid; + uint32 rid; + + *name_type = SID_NAME_UNKNOWN; + + sid_copy(&dom_sid, psid); + sid_split_rid(&dom_sid, &rid); + + /* + * We can only convert to a gid if this is our local + * Domain SID (ie. we are the controling authority). + */ + + if (!sid_equal(&global_sam_sid, &dom_sid)) + return False; + + *pgid = pdb_user_rid_to_gid(rid); + + /* + * Ensure this gid really does exist. + */ + + if(!getgrgid(*pgid)) + return False; + + return True; +} diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 2444c38847..510432ea74 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1967,7 +1967,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(void) SEC_DESC *psd = NULL; DOM_SID owner_sid; size_t sd_size; - uint8 name_type; + enum SID_NAME_USE name_type; /* Create an ACE where Everyone is allowed to print */ @@ -2067,7 +2067,7 @@ BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr) if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) { DOM_SID owner_sid; - uint8 name_type; + enum SID_NAME_USE name_type; /* Change sd owner to workgroup administrator */ -- cgit