Added code to do SID to uid/gid conversion. Needed for ACL support.
authorJeremy Allison <jra@samba.org>
Wed, 23 Aug 2000 00:45:40 +0000 (00:45 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 23 Aug 2000 00:45:40 +0000 (00:45 +0000)
Jeremy.

source/include/proto.h
source/lib/util_sid.c
source/nsswitch/wb_client.c
source/passdb/passdb.c
source/printing/nt_printing.c

index d647acf608495141824354c5465263c6f3c0bb26..e782507cf79a6b1cf1fcc49b38eeeeae3f190e98 100644 (file)
@@ -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  */
 
index 52e9f63039e0a7b3b4a49937887376cd5193eeee..439bb74a831fa220507c2e05dc3d3f5edd69f569 100644 (file)
@@ -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;
index 47f1520efa667b4ced17acb0611e7b4bbf0b4d5c..bdfd25acce788e1cfc99b591585f2d687b5b80e5 100644 (file)
@@ -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;
+}
index f0fe2499dfd237f8668555a85ac890ad57b8d10d..a05783ac36a0cba37434b18811608311c976e9d4 100644 (file)
@@ -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;
+}
index 2444c388472e23e65afa21027e363c9398ba69ac..510432ea740d8405af014c60a14e308fcab7203a 100644 (file)
@@ -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 */