dsdb: Ensure "authenticated users" is processed for group memberships
authorAndrew Bartlett <abartlet@samba.org>
Sat, 29 Dec 2012 04:13:54 +0000 (15:13 +1100)
committerStefan Metzmacher <metze@samba.org>
Mon, 21 Jan 2013 15:12:45 +0000 (16:12 +0100)
This change moves the addition of "Authenticated Users" from the very end of the
token processing to the start.  The reason is that we need to see if
"Authenticated Users" is a member of other builtin groups, just as we
would for any other SID.  This picks up the "Pre-Windows 2000 Compatible Access"
group, which is in turn often used in ACLs on LDAP objects.

Without this change, the eventual token does not contain S-1-5-32-554
and users other than "Administrator" are unable to read uidNumber
(in particular).

Andrew Bartlett

Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/auth/session.c
source4/dsdb/common/util_groups.c
source4/dsdb/samdb/samdb.c

index de417cc54b110c83f53ed651bb5e8595d0dfa6d3..bb0b5bca6368791882f6879960f9fb0785b55f02 100644 (file)
@@ -102,22 +102,56 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
                sids[i] = user_info_dc->sids[i];
        }
 
-       if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
+       /*
+        * Finally add the "standard" sids.
+        * The only difference between guest and "anonymous"
+        * is the addition of Authenticated_Users.
+        */
+
+       if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) {
+               sids = talloc_realloc(tmp_ctx, sids, struct dom_sid, num_sids + 2);
+               NT_STATUS_HAVE_NO_MEMORY(sids);
+
+               if (!dom_sid_parse(SID_WORLD, &sids[num_sids])) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+               num_sids++;
+
+               if (!dom_sid_parse(SID_NT_NETWORK, &sids[num_sids])) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+               num_sids++;
+       }
+
+       if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) {
+               sids = talloc_realloc(tmp_ctx, sids, struct dom_sid, num_sids + 1);
+               NT_STATUS_HAVE_NO_MEMORY(sids);
+
+               if (!dom_sid_parse(SID_NT_AUTHENTICATED_USERS, &sids[num_sids])) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+               num_sids++;
+       }
+
+
+
+       if (num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &sids[PRIMARY_USER_SID_INDEX])) {
                /* Don't expand nested groups of system, anonymous etc*/
-       } else if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
+       } else if (num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &sids[PRIMARY_USER_SID_INDEX])) {
                /* Don't expand nested groups of system, anonymous etc*/
        } else if (sam_ctx) {
                filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
                                         GROUP_TYPE_BUILTIN_LOCAL_GROUP);
 
                /* Search for each group in the token */
-               for (i = 0; i < user_info_dc->num_sids; i++) {
+               for (i = 0; i < num_sids; i++) {
                        char *sid_string;
                        const char *sid_dn;
                        DATA_BLOB sid_blob;
-                       
+                       int ret;
+
                        sid_string = dom_sid_string(tmp_ctx,
-                                                     &user_info_dc->sids[i]);
+                                                     &sids[i]);
                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, user_info_dc);
                        
                        sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
index b5aecbafe916fe81f5659e7c64dba04a77715cb3..6a96ce89d1ad47f843c732d232ddab6f577dbdef 100644 (file)
@@ -126,6 +126,31 @@ NTSTATUS dsdb_expand_nested_groups(struct ldb_context *sam_ctx,
                                  filter);
        }
 
+       /*
+        * We have the problem with the caller creating a <SID=S-....>
+        * DN for ForeignSecurityPrincipals as they also have
+        * duplicate objects with the SAME SID under CN=Configuration.
+        * This causes a SID= DN to fail with NO_SUCH_OBJECT on Samba
+        * and on Windows.  So, we allow this to fail, and
+        * double-check if we can find it with a search in the main
+        * domain partition.
+        */
+       if (ret == LDB_ERR_NO_SUCH_OBJECT && only_childs) {
+               char *sid_string = dom_sid_string(tmp_ctx,
+                                                 &sid);
+               if (!sid_string) {
+                       talloc_free(tmp_ctx);
+                       return NT_STATUS_OK;
+               }
+
+               ret = dsdb_search(sam_ctx, tmp_ctx, &res,
+                                 ldb_get_default_basedn(sam_ctx),
+                                 LDB_SCOPE_SUBTREE,
+                                 attrs, DSDB_SEARCH_SHOW_EXTENDED_DN,
+                                 "(&(objectClass=foreignSecurityPrincipal)(objectSID=%s))",
+                                 sid_string);
+       }
+
        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                talloc_free(tmp_ctx);
                return NT_STATUS_OK;
index 713448c4e819a8d338adc4e91c9ad33c443c61fd..361ece79f0a224fcb0066f2b40f1a5093dd1f80a 100644 (file)
@@ -143,37 +143,6 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx,
                }
        }
 
-       /*
-        * Finally add the "standard" sids.
-        * The only difference between guest and "anonymous"
-        * is the addition of Authenticated_Users.
-        */
-
-       if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) {
-               ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid, ptoken->num_sids + 2);
-               NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
-
-               if (!dom_sid_parse(SID_WORLD, &ptoken->sids[ptoken->num_sids])) {
-                       return NT_STATUS_INTERNAL_ERROR;
-               }
-               ptoken->num_sids++;
-
-               if (!dom_sid_parse(SID_NT_NETWORK, &ptoken->sids[ptoken->num_sids])) {
-                       return NT_STATUS_INTERNAL_ERROR;
-               }
-               ptoken->num_sids++;
-       }
-
-       if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) {
-               ptoken->sids = talloc_realloc(ptoken, ptoken->sids, struct dom_sid, ptoken->num_sids + 1);
-               NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
-
-               if (!dom_sid_parse(SID_NT_AUTHENTICATED_USERS, &ptoken->sids[ptoken->num_sids])) {
-                       return NT_STATUS_INTERNAL_ERROR;
-               }
-               ptoken->num_sids++;
-       }
-
        /* The caller may have requested simple privilages, for example if there isn't a local DB */
        if (session_info_flags & AUTH_SESSION_INFO_SIMPLE_PRIVILEGES) {
                /* Shortcuts to prevent recursion and avoid lookups */