Cope with MAXIMUM_ALLOWED_ACCESS requests when opening handles.
authorJeremy Allison <jra@samba.org>
Wed, 22 Oct 2008 00:06:53 +0000 (17:06 -0700)
committerKarolin Seeger <kseeger@samba.org>
Tue, 9 Dec 2008 10:22:20 +0000 (11:22 +0100)
Jeremy.
(cherry picked from commit 82ec832f7edffe2fcfd1bb067e092c159bed2973)
(cherry picked from commit 042e50f8709cfbe45d5b184cb3c4fe1b16bdc3b0)

source/lib/util_sid.c
source/rpc_server/srv_samr_nt.c
source/utils/net_rpc.c

index 53614ed1ac21d16d0bd899e3d3a50bb9c53d8ce9..f656bb13dc8807c582e4471c54ef755a60076cd3 100644 (file)
@@ -664,6 +664,17 @@ bool is_null_sid(const DOM_SID *sid)
        return sid_equal(sid, &null_sid);
 }
 
+bool is_sid_in_token(const NT_USER_TOKEN *token, const DOM_SID *sid)
+{
+        int i;
+
+        for (i=0; i<token->num_sids; i++) {
+                if (sid_compare(sid, &token->user_sids[i]) == 0)
+                        return true;
+        }
+        return false;
+}
+
 NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx,
                              const struct netr_SamInfo3 *info3,
                              DOM_SID **user_sids,
index c59a46c1da8cab781c28f854feaeb8d5cee68a3f..22b18c017027ba80f114ce43d137ec3cf71122b9 100644 (file)
@@ -5,7 +5,7 @@
  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
  *  Copyright (C) Paul Ashton                       1997,
  *  Copyright (C) Marc Jacobsen                            1999,
- *  Copyright (C) Jeremy Allison                    2001-2005,
+ *  Copyright (C) Jeremy Allison                    2001-2008,
  *  Copyright (C) Jean François Micouleau           1998-2001,
  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
@@ -248,6 +248,48 @@ static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_requir
        return NT_STATUS_ACCESS_DENIED;
 }
 
+/*******************************************************************
+ Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
+********************************************************************/
+
+static void map_max_allowed_access(const NT_USER_TOKEN *token,
+                                       uint32_t *pacc_requested)
+{
+       if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
+               return;
+       }
+       *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
+
+       /* At least try for generic read. */
+       *pacc_requested = GENERIC_READ_ACCESS;
+
+       /* root gets anything. */
+       if (geteuid() == sec_initial_uid()) {
+               *pacc_requested |= GENERIC_ALL_ACCESS;
+               return;
+       }
+
+       /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
+
+       if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
+                       is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
+               *pacc_requested |= GENERIC_ALL_ACCESS;
+               return;
+       }
+
+       /* Full access for DOMAIN\Domain Admins. */
+       if ( IS_DC ) {
+               DOM_SID domadmin_sid;
+               sid_copy( &domadmin_sid, get_global_sam_sid() );
+               sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
+               if (is_sid_in_token(token, &domadmin_sid)) {
+                       *pacc_requested |= GENERIC_ALL_ACCESS;
+                       return;
+               }
+       }
+       /* TODO ! Check privileges. */
+}
+
 /*******************************************************************
  Fetch or create a dispinfo struct.
 ********************************************************************/
@@ -586,6 +628,7 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
                return status;
 
        /*check if access can be granted as requested by client. */
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
 
        make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
        se_map_generic( &des_access, &dom_generic_mapping );
@@ -2158,6 +2201,8 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
 
        /* check if access can be granted as requested by client. */
 
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
        se_map_generic(&des_access, &usr_generic_mapping);
 
@@ -3221,6 +3266,8 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
 
        sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
 
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
                            &sid, SAMR_USR_RIGHTS_WRITE_PW);
        se_map_generic(&des_access, &usr_generic_mapping);
@@ -3282,10 +3329,7 @@ NTSTATUS _samr_Connect(pipes_struct *p,
           was observed from a win98 client trying to enumerate users (when configured
           user level access control on shares)   --jerry */
 
-       if (des_access == MAXIMUM_ALLOWED_ACCESS) {
-               /* Map to max possible knowing we're filtered below. */
-               des_access = GENERIC_ALL_ACCESS;
-       }
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
 
        se_map_generic( &des_access, &sam_generic_mapping );
        info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
@@ -3321,6 +3365,8 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
        se_map_generic(&des_access, &sam_generic_mapping);
 
@@ -3370,6 +3416,8 @@ NTSTATUS _samr_Connect4(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
        se_map_generic(&des_access, &sam_generic_mapping);
 
@@ -3419,6 +3467,8 @@ NTSTATUS _samr_Connect5(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
        se_map_generic(&des_access, &sam_generic_mapping);
 
@@ -3586,6 +3636,8 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
 
        /*check if access can be granted as requested by client. */
 
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
        se_map_generic(&des_access,&ali_generic_mapping);
 
@@ -5478,6 +5530,8 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
                return status;
 
        /*check if access can be granted as requested by client. */
+       map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
        se_map_generic(&des_access,&grp_generic_mapping);
 
index a5c2de0df32859a6af273770f2d10f83fe6a3781..ef1ebd3491ff5c952e6225e8ced80b959c33a220 100644 (file)
@@ -4187,17 +4187,6 @@ static void free_user_token(NT_USER_TOKEN *token)
        SAFE_FREE(token->user_sids);
 }
 
-static bool is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
-{
-       int i;
-
-       for (i=0; i<token->num_sids; i++) {
-               if (sid_compare(sid, &token->user_sids[i]) == 0)
-                       return True;
-       }
-       return False;
-}
-
 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
 {
        if (is_sid_in_token(token, sid))