Globally replace 'global_sam_sid' with get_global_sam_sid(), a self
[kai/samba.git] / source3 / smbd / uid.c
index 240b4d46bbd42c6f6296ae544efb9d8b804779d3..cb4a975881b2197fc030e59c11ec3040b750bb86 100644 (file)
@@ -1,6 +1,5 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 1.9.
+   Unix SMB/CIFS implementation.
    uid/user handling
    Copyright (C) Andrew Tridgell 1992-1998
    
@@ -433,7 +432,7 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER
 
 /*****************************************************************
  *THE CANONICAL* convert name to SID function.
- Tries winbind first - then uses local lookup.
+ Tries local lookup first - for local domains - then uses winbind.
 *****************************************************************/  
 
 BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
@@ -441,54 +440,51 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N
        extern pstring global_myname;
        extern fstring global_myworkgroup;
        fstring sid;
+       BOOL ret = False;
        
        *name_type = SID_NAME_UNKNOWN;
 
-       if (!winbind_lookup_name(domain, name, psid, name_type) || (*name_type != SID_NAME_USER) ) {
-               BOOL ret = False;
-
-               DEBUG(10, ("lookup_name: winbind lookup for [%s]\\[%s] failed - trying local\n", domain, name));
-
-               /* If we are looking up a domain user, make sure it is
-                  for the local machine only */
-               
-               switch (lp_server_role()) {
-               case ROLE_DOMAIN_PDC:
-               case ROLE_DOMAIN_BDC:
-                       if (strequal(domain, global_myworkgroup)) {
-                               ret = local_lookup_name(name, psid, name_type);
-                       }
-                       /* No break is deliberate here. JRA. */
-               default:
-                       if (ret) {
-                       } else if (strequal(global_myname, domain)) {
-                               ret = local_lookup_name(name, psid, name_type);
-                       } else {
-                               DEBUG(5, ("lookup_name: domain %s is not local\n", domain));
-                       }
+       /* If we are looking up a domain user, make sure it is
+          for the local machine only */
+       
+       switch (lp_server_role()) {
+       case ROLE_DOMAIN_PDC:
+       case ROLE_DOMAIN_BDC:
+               if (strequal(domain, global_myworkgroup)) {
+                       ret = local_lookup_name(name, psid, name_type);
                }
-
+               /* No break is deliberate here. JRA. */
+       default:
                if (ret) {
-                       DEBUG(10,
-                             ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %u)\n",
-                              domain, name, sid_to_string(sid,psid),
-                              (unsigned int)*name_type ));
+               } else if (strequal(global_myname, domain)) {
+                       ret = local_lookup_name(name, psid, name_type);
                } else {
-                       DEBUG(10,("lookup name: (local) [%s]\\[%s] failed.\n", domain, name));
+                       DEBUG(5, ("lookup_name: domain %s is not local\n", domain));
                }
-
-               return ret;
+       }
+       
+       if (ret) {
+               DEBUG(10,
+                     ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %u)\n",
+                      domain, name, sid_to_string(sid,psid),
+                      (unsigned int)*name_type ));
+               return True;
+       } else if (winbind_lookup_name(domain, name, psid, name_type) || (*name_type != SID_NAME_USER) ) {
+               
+               DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
+                         domain, name, sid_to_string(sid, psid), 
+                         (unsigned int)*name_type));
+               return True;
        }
 
-       DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
-                 domain, name, sid_to_string(sid, psid), 
-                 (unsigned int)*name_type));
-       return True;
+       DEBUG(10, ("lookup_name: winbind and local lookups for [%s]\\[%s] failed\n", domain, name));
+
+       return False;
 }
 
 /*****************************************************************
  *THE CANONICAL* convert SID to name function.
- Tries winbind first - then uses local lookup.
+ Tries local lookup first - for local sids, then tries winbind.
 *****************************************************************/  
 
 BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
@@ -508,7 +504,7 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE
                sid_copy(&tmp_sid, sid);
                sid_split_rid(&tmp_sid, &rid);
 
-               if (sid_equal(&global_sam_sid, &tmp_sid)) {
+               if (sid_equal(get_global_sam_sid(), &tmp_sid)) {
 
                        return map_domain_sid_to_name(&tmp_sid, dom_name) &&
                                local_lookup_sid(sid, name, name_type);
@@ -525,7 +521,7 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE
                sid_copy(&tmp_sid, sid);
                sid_split_rid(&tmp_sid, &rid);
                return map_domain_sid_to_name(&tmp_sid, dom_name) &&
-                               lookup_known_rid(&tmp_sid, rid, name, name_type);
+                       lookup_known_rid(&tmp_sid, rid, name, name_type);
        }
        return True;
 }
@@ -550,9 +546,12 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
                        return psid;
                }
        }
+       
+       /* Make sure we report failure, (when psid == NULL) */
+       become_root();
+       psid = local_uid_to_sid(psid, uid);
+        unbecome_root();
 
-       local_uid_to_sid(psid, uid);
-        
        DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
 
        return psid;
@@ -579,7 +578,8 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
                }
        }
 
-       local_gid_to_sid(psid, gid);
+       /* Make sure we report failure, (when psid == NULL) */
+       psid = local_gid_to_sid(psid, gid);
         
        DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
 
@@ -595,20 +595,34 @@ 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)
 {
-       fstring dom_name, name, sid_str;
+       fstring sid_str;
+
+       /* if we know its local then don't try winbindd */
+       if (sid_compare_domain(get_global_sam_sid(), psid) == 0) {
+               return local_sid_to_uid(puid, psid, sidtype);
+       }
+
+/* (tridge) I commented out the slab of code below in order to support foreign SIDs
+   Do we really need to validate the type of SID we have in this case? 
+*/
+#if 0
+       fstring dom_name, name;
        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)) || (name_type != SID_NAME_USER) ) {
+               BOOL result;
                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(puid, psid, sidtype);
+               become_root();
+               result = local_sid_to_uid(puid, psid, sidtype);
+               unbecome_root();
+               return result;
        }
 
        /*
@@ -620,7 +634,7 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
                                (unsigned int)name_type ));
                return False;
        }
-
+#endif
        *sidtype = SID_NAME_USER;
 
        /*
@@ -628,9 +642,13 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
         */
 
        if (!winbind_sid_to_uid(puid, psid)) {
+               BOOL result;
                DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n",
                                sid_to_string(sid_str, psid) ));
-               return False;
+               become_root();
+               result = local_sid_to_uid(puid, psid, sidtype);
+               unbecome_root();
+               return result;
        }
 
        DEBUG(10,("sid_to_uid: winbindd %s -> %u\n",
@@ -661,8 +679,13 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
        if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
                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(pgid, psid, sidtype);
+               if (!local_sid_to_gid(pgid, psid, sidtype)) {
+                       /* this was probably a foreign sid - assume its a group rid 
+                          and continue */
+                       name_type = SID_NAME_DOM_GRP;
+               } else {
+                       return True;
+               }
        }
 
        /*