]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: rpc_server: Strip out access check field from s3 handles implementation
authorSamuel Cabrero <scabrero@suse.de>
Tue, 29 Oct 2019 11:39:10 +0000 (12:39 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 24 May 2020 23:55:36 +0000 (23:55 +0000)
The handle based security model is a SAMR specific feature. The access
granted is stored in the handle's associated data after creating it and
the access is verified after searching the handle.

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/rpc_server/rpc_handles.c
source3/rpc_server/rpc_pipes.h
source3/rpc_server/samr/srv_samr_nt.c

index 8ae9d970cede5cce050bdaafd7941e9a3eeece9d..6f1245cd10eb3c28fe74ea3627f6b47b58095dec 100644 (file)
@@ -130,7 +130,6 @@ int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
 struct dcesrv_handle_old {
        struct dcesrv_handle_old *prev, *next;
        struct policy_handle wire_handle;
-       uint32_t access_granted;
        void *data;
 };
 
@@ -456,7 +455,6 @@ bool pipe_access_check(struct pipes_struct *p)
 void *_policy_handle_create(struct pipes_struct *p,
                        struct policy_handle *hnd,
                        uint8_t handle_type,
-                       uint32_t access_granted,
                        size_t data_size,
                        const char *type,
                        NTSTATUS *pstatus)
@@ -487,15 +485,12 @@ void *_policy_handle_create(struct pipes_struct *p,
                *pstatus = NT_STATUS_NO_MEMORY;
                return NULL;
        }
-       rpc_hnd->access_granted = access_granted;
        *pstatus = NT_STATUS_OK;
        return data;
 }
 
 void *_policy_handle_find(struct pipes_struct *p,
                          const struct policy_handle *hnd,
-                         uint32_t access_required,
-                         uint32_t *paccess_granted,
                          const char *name, const char *location,
                          NTSTATUS *pstatus)
 {
@@ -513,26 +508,8 @@ void *_policy_handle_find(struct pipes_struct *p,
                *pstatus = NT_STATUS_INVALID_HANDLE;
                return NULL;
        }
-       if ((access_required & rpc_hnd->access_granted) != access_required) {
-               if (root_mode()) {
-                       DEBUG(4, ("%s: ACCESS should be DENIED (granted: "
-                                 "%#010x; required: %#010x)\n", location,
-                                 rpc_hnd->access_granted, access_required));
-                       DEBUGADD(4,("but overwritten by euid == 0\n"));
-                       goto okay;
-               }
-               DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: "
-                        "%#010x)\n", location, rpc_hnd->access_granted,
-                        access_required));
-               *pstatus = NT_STATUS_ACCESS_DENIED;
-               return NULL;
-       }
 
- okay:
        DEBUG(10, ("found handle of type %s\n", talloc_get_name(data)));
-       if (paccess_granted != NULL) {
-               *paccess_granted = rpc_hnd->access_granted;
-       }
        *pstatus = NT_STATUS_OK;
        return data;
 }
index 5c4ded2c6c46010fa144db1bb7248bdb4f317517..0bdd15ac5e247857b6b8a6eb1feb3372d5b2905a 100644 (file)
@@ -134,21 +134,19 @@ bool pipe_access_check(struct pipes_struct *p);
 void *_policy_handle_create(struct pipes_struct *p,
                        struct policy_handle *hnd,
                        uint8_t handle_type,
-                       uint32_t access_granted,
                        size_t data_size,
                        const char *type,
                        NTSTATUS *pstatus);
-#define policy_handle_create(_p, _hnd, _hnd_type, _access, _type, _pstatus) \
-       (_type *)_policy_handle_create((_p), (_hnd), (_hnd_type), (_access), sizeof(_type), #_type, \
+#define policy_handle_create(_p, _hnd, _hnd_type, _type, _pstatus) \
+       (_type *)_policy_handle_create((_p), (_hnd), (_hnd_type), sizeof(_type), #_type, \
                                       (_pstatus))
 
 void *_policy_handle_find(struct pipes_struct *p,
                          const struct policy_handle *hnd,
-                         uint32_t access_required, uint32_t *paccess_granted,
                          const char *name, const char *location,
                          NTSTATUS *pstatus);
-#define policy_handle_find(_p, _hnd, _access_required, _access_granted, _type, _pstatus) \
-       (_type *)_policy_handle_find((_p), (_hnd), (_access_required), \
-                                    (_access_granted), #_type, __location__, (_pstatus))
+#define policy_handle_find(_p, _hnd, _type, _pstatus) \
+       (_type *)_policy_handle_find((_p), (_hnd), \
+       #_type, __location__, (_pstatus))
 
 #endif /* _RPC_PIPES_H_ */
index 62796dbe5407634911d1fdc8651b1addb8952dda..a3f6ad1a4089c1bfdc20f5504a79a4fba064556a 100644 (file)
@@ -75,24 +75,28 @@ enum samr_handle {
 };
 
 struct samr_connect_info {
-       uint8_t dummy;
+       uint32_t access_granted;
 };
 
 struct samr_domain_info {
        struct dom_sid sid;
        struct disp_info *disp_info;
+       uint32_t access_granted;
 };
 
 struct samr_user_info {
        struct dom_sid sid;
+       uint32_t access_granted;
 };
 
 struct samr_group_info {
        struct dom_sid sid;
+       uint32_t access_granted;
 };
 
 struct samr_alias_info {
        struct dom_sid sid;
+       uint32_t access_granted;
 };
 
 typedef struct disp_info {
@@ -142,6 +146,29 @@ static const struct generic_mapping ali_generic_mapping = {
 
 /*******************************************************************
 *******************************************************************/
+static NTSTATUS samr_handle_access_check(uint32_t access_granted,
+                                        uint32_t access_required,
+                                        uint32_t *paccess_granted)
+{
+       if ((access_required & access_granted) != access_required) {
+               if (root_mode()) {
+                       DBG_INFO("ACCESS should be DENIED (granted: "
+                                "%#010x; required: %#010x) but overwritten "
+                                "by euid == 0\n", access_granted,
+                                access_required);
+                       goto okay;
+               }
+               DBG_NOTICE("ACCESS DENIED (granted: %#010x; required: "
+                          "%#010x)\n", access_granted, access_required);
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+okay:
+       if (paccess_granted != NULL) {
+               *paccess_granted = access_granted;
+       }
+       return NT_STATUS_OK;
+}
 
 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
                                      const struct generic_mapping *map,
@@ -454,6 +481,7 @@ NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
                          struct samr_OpenDomain *r)
 {
        struct samr_domain_info *dinfo;
+       struct samr_connect_info *cinfo = NULL;
        struct security_descriptor *psd = NULL;
        uint32_t    acc_granted;
        uint32_t    des_access = r->in.access_mask;
@@ -463,12 +491,17 @@ NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
 
        /* find the connection policy handle. */
 
-       (void)policy_handle_find(p, r->in.connect_handle, 0, NULL,
+       cinfo = policy_handle_find(p, r->in.connect_handle,
                                   struct samr_connect_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(cinfo->access_granted, 0, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        /*check if access can be granted as requested by client. */
        map_max_allowed_access(p->session_info->security_token,
                               p->session_info->unix_token,
@@ -510,7 +543,6 @@ NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
        dinfo = policy_handle_create(p,
                                r->out.domain_handle,
                                SAMR_HANDLE_DOMAIN,
-                               acc_granted,
                                struct samr_domain_info,
                                &status);
        if (!NT_STATUS_IS_OK(status)) {
@@ -518,6 +550,7 @@ NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
        }
        dinfo->sid = *r->in.sid;
        dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
+       dinfo->access_granted = acc_granted;
 
        DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
 
@@ -543,12 +576,18 @@ NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
        DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
 
        uinfo = policy_handle_find(p, r->in.user_handle,
-                                  SAMR_USER_ACCESS_GET_ATTRIBUTES, NULL,
                                   struct samr_user_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(uinfo->access_granted,
+                                         SAMR_USER_ACCESS_GET_ATTRIBUTES,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (!sid_check_is_in_our_sam(&uinfo->sid)) {
                return NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
@@ -602,12 +641,18 @@ NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
        NTSTATUS status;
 
        uinfo = policy_handle_find(p, r->in.handle,
-                                  SAMR_USER_ACCESS_SET_ATTRIBUTES, NULL,
                                   struct samr_user_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(uinfo->access_granted,
+                                         SAMR_USER_ACCESS_SET_ATTRIBUTES,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (!(sampass = samu_new( p->mem_ctx))) {
                DEBUG(0,("No memory!\n"));
                return NT_STATUS_NO_MEMORY;
@@ -702,11 +747,19 @@ NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
        struct security_descriptor * psd = NULL;
        size_t sd_size = 0;
        struct dom_sid_buf buf;
+       struct samr_connect_info *cinfo = NULL;
+       NTSTATUS acc_status;
 
-       (void)policy_handle_find(p, r->in.handle,
-                                  SEC_STD_READ_CONTROL, NULL,
+       cinfo = policy_handle_find(p, r->in.handle,
                                   struct samr_connect_info, &status);
-       if (NT_STATUS_IS_OK(status)) {
+       if (cinfo != NULL) {
+               acc_status = samr_handle_access_check(cinfo->access_granted,
+                                                     SEC_STD_READ_CONTROL,
+                                                     NULL);
+       } else {
+               acc_status = NT_STATUS_INVALID_HANDLE;
+       }
+       if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(acc_status)) {
                DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
                status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
                                             &sam_generic_mapping, NULL, 0);
@@ -714,9 +767,15 @@ NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
        }
 
        dinfo = policy_handle_find(p, r->in.handle,
-                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_domain_info, &status);
-       if (NT_STATUS_IS_OK(status)) {
+       if (dinfo != NULL) {
+               acc_status = samr_handle_access_check(dinfo->access_granted,
+                                                     SEC_STD_READ_CONTROL,
+                                                     NULL);
+       } else {
+               acc_status = NT_STATUS_INVALID_HANDLE;
+       }
+       if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(acc_status)) {
                DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
                         "with SID: %s\n",
                         dom_sid_str_buf(&dinfo->sid, &buf)));
@@ -730,9 +789,15 @@ NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
        }
 
        uinfo = policy_handle_find(p, r->in.handle,
-                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_user_info, &status);
-       if (NT_STATUS_IS_OK(status)) {
+       if (uinfo != NULL) {
+               acc_status = samr_handle_access_check(uinfo->access_granted,
+                                                     SEC_STD_READ_CONTROL,
+                                                     NULL);
+       } else {
+               acc_status = NT_STATUS_INVALID_HANDLE;
+       }
+       if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(acc_status)) {
                DEBUG(10,("_samr_QuerySecurity: querying security on user "
                          "Object with SID: %s\n",
                          dom_sid_str_buf(&uinfo->sid, &buf)));
@@ -751,9 +816,15 @@ NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
        }
 
        ginfo = policy_handle_find(p, r->in.handle,
-                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_group_info, &status);
-       if (NT_STATUS_IS_OK(status)) {
+       if (ginfo != NULL) {
+               acc_status = samr_handle_access_check(ginfo->access_granted,
+                                                     SEC_STD_READ_CONTROL,
+                                                     NULL);
+       } else {
+               acc_status = NT_STATUS_INVALID_HANDLE;
+       }
+       if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(acc_status)) {
                /*
                 * TODO: different SDs have to be generated for aliases groups
                 * and users.  Currently all three get a default user SD
@@ -769,9 +840,16 @@ NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
        }
 
        ainfo = policy_handle_find(p, r->in.handle,
-                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_alias_info, &status);
-       if (NT_STATUS_IS_OK(status)) {
+       if (ainfo != NULL) {
+               acc_status = samr_handle_access_check(ainfo->access_granted,
+                                                     SEC_STD_READ_CONTROL,
+                                                     NULL);
+       } else {
+               acc_status = NT_STATUS_INVALID_HANDLE;
+       }
+
+       if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(acc_status)) {
                /*
                 * TODO: different SDs have to be generated for aliases groups
                 * and users.  Currently all three get a default user SD
@@ -865,12 +943,18 @@ NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
        DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
        if (!samr_array) {
                return NT_STATUS_NO_MEMORY;
@@ -998,12 +1082,18 @@ NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
        struct samr_SamEntry *samr_entries = NULL;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
 
        samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
@@ -1076,12 +1166,18 @@ NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
        struct dom_sid_buf buf;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
                 dom_sid_str_buf(&dinfo->sid, &buf)));
 
@@ -1353,12 +1449,18 @@ NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
        DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (sid_check_is_builtin(&dinfo->sid)) {
                DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
                return NT_STATUS_OK;
@@ -1602,12 +1704,18 @@ NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
        DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
 
        ainfo = policy_handle_find(p, r->in.alias_handle,
-                                  SAMR_ALIAS_ACCESS_LOOKUP_INFO, NULL,
                                   struct samr_alias_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ainfo->access_granted,
+                                         SAMR_ALIAS_ACCESS_LOOKUP_INFO,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        alias_info = talloc_zero(p->mem_ctx, union samr_AliasInfo);
        if (!alias_info) {
                return NT_STATUS_NO_MEMORY;
@@ -1674,12 +1782,18 @@ NTSTATUS _samr_LookupNames(struct pipes_struct *p,
        DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  0 /* Don't know the acc_bits yet */, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         0 /* Don't know the acc_bits yet */,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (num_rids > MAX_SAM_ENTRIES) {
                num_rids = MAX_SAM_ENTRIES;
                DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
@@ -2056,12 +2170,18 @@ NTSTATUS _samr_LookupRids(struct pipes_struct *p,
        DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  0 /* Don't know the acc_bits yet */, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         0 /* Don't know the acc_bits yet */,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (num_rids > 1000) {
                DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
                          "to samba4 idl this is not possible\n", num_rids));
@@ -2140,12 +2260,18 @@ NTSTATUS _samr_OpenUser(struct pipes_struct *p,
        NTSTATUS status;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if ( !(sampass = samu_new( p->mem_ctx )) ) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -2237,13 +2363,13 @@ NTSTATUS _samr_OpenUser(struct pipes_struct *p,
        uinfo = policy_handle_create(p,
                                r->out.user_handle,
                                SAMR_HANDLE_USER,
-                               acc_granted,
                                struct samr_user_info,
                                &nt_status);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
        uinfo->sid = sid;
+       uinfo->access_granted = acc_granted;
 
        return NT_STATUS_OK;
 }
@@ -2952,12 +3078,18 @@ NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
        }
 
        uinfo = policy_handle_find(p, r->in.user_handle,
-                                  acc_required, &acc_granted,
                                   struct samr_user_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(uinfo->access_granted,
+                                         acc_required,
+                                         &acc_granted);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        domain_sid = uinfo->sid;
 
        sid_split_rid(&domain_sid, &rid);
@@ -3126,12 +3258,18 @@ NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
        DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
 
        uinfo = policy_handle_find(p, r->in.user_handle,
-                                  SAMR_USER_ACCESS_GET_GROUPS, NULL,
                                   struct samr_user_info, &result);
        if (!NT_STATUS_IS_OK(result)) {
                return result;
        }
 
+       result = samr_handle_access_check(uinfo->access_granted,
+                                         SAMR_USER_ACCESS_GET_GROUPS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(result)) {
+               return result;
+       }
+
        rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
        if (!rids) {
                return NT_STATUS_NO_MEMORY;
@@ -3582,12 +3720,18 @@ NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
        }
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  acc_required, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         acc_required,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
        if (!dom_info) {
                return NT_STATUS_NO_MEMORY;
@@ -3707,12 +3851,18 @@ NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
        enum sec_privilege needed_priv = SEC_PRIV_INVALID;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
                                   struct samr_domain_info, &nt_status);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
 
+       nt_status = samr_handle_access_check(dinfo->access_granted,
+                                            SAMR_DOMAIN_ACCESS_CREATE_USER,
+                                            NULL);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               return nt_status;
+       }
+
        if (sid_check_is_builtin(&dinfo->sid)) {
                DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
                return NT_STATUS_ACCESS_DENIED;
@@ -3810,13 +3960,13 @@ NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
        uinfo = policy_handle_create(p,
                                r->out.user_handle,
                                SAMR_HANDLE_USER,
-                               acc_granted,
                                struct samr_user_info,
                                &nt_status);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
        uinfo->sid = sid;
+       uinfo->access_granted = acc_granted;
 
        /* After a "set" ensure we have no cached display info. */
        force_flush_samr_cache(&sid);
@@ -3857,6 +4007,7 @@ NTSTATUS _samr_Connect(struct pipes_struct *p,
        struct policy_handle hnd;
        uint32_t    des_access = r->in.access_mask;
        NTSTATUS status;
+       struct samr_connect_info *cinfo = NULL;
 
        /* Access check */
 
@@ -3880,16 +4031,17 @@ NTSTATUS _samr_Connect(struct pipes_struct *p,
 
        /* set up the SAMR connect_anon response */
 
-       (void)policy_handle_create(p,
-                               &hnd,
-                               SAMR_HANDLE_CONNECT,
-                               acc_granted,
-                               struct samr_connect_info,
-                               &status);
+       cinfo = policy_handle_create(p,
+                                    &hnd,
+                                    SAMR_HANDLE_CONNECT,
+                                    struct samr_connect_info,
+                                    &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       cinfo->access_granted = acc_granted;
+
        *r->out.connect_handle = hnd;
        return NT_STATUS_OK;
 }
@@ -3908,6 +4060,7 @@ NTSTATUS _samr_Connect2(struct pipes_struct *p,
        NTSTATUS  nt_status;
        size_t    sd_size;
        const char *fn = "_samr_Connect2";
+       struct samr_connect_info *cinfo = NULL;
 
        switch (p->opnum) {
        case NDR_SAMR_CONNECT2:
@@ -3947,16 +4100,17 @@ NTSTATUS _samr_Connect2(struct pipes_struct *p,
        if ( !NT_STATUS_IS_OK(nt_status) )
                return nt_status;
 
-       (void)policy_handle_create(p,
-                               &hnd,
-                               SAMR_HANDLE_CONNECT,
-                               acc_granted,
-                               struct samr_connect_info,
-                               &nt_status);
+       cinfo = policy_handle_create(p,
+                                    &hnd,
+                                    SAMR_HANDLE_CONNECT,
+                                    struct samr_connect_info,
+                                    &nt_status);
         if (!NT_STATUS_IS_OK(nt_status)) {
                 return nt_status;
         }
 
+       cinfo->access_granted = acc_granted;
+
        DEBUG(5,("%s: %d\n", fn, __LINE__));
 
        *r->out.connect_handle = hnd;
@@ -4036,18 +4190,25 @@ NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
        const char *domain_name;
        struct dom_sid *sid = NULL;
        struct dom_sid_buf buf;
+       struct samr_connect_info *cinfo = NULL;
 
        /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
           Reverted that change so we will work with RAS servers again */
 
-       (void)policy_handle_find(p, r->in.connect_handle,
-                                 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
+       cinfo = policy_handle_find(p, r->in.connect_handle,
                                  struct samr_connect_info,
                                  &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(cinfo->access_granted,
+                                         SAMR_ACCESS_LOOKUP_DOMAIN,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        domain_name = r->in.domain_name->string;
        if (!domain_name) {
                return NT_STATUS_INVALID_PARAMETER;
@@ -4085,10 +4246,17 @@ NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
        uint32_t num_entries = 2;
        struct samr_SamEntry *entry_array = NULL;
        struct samr_SamArray *sam;
+       struct samr_connect_info *cinfo = NULL;
 
-       (void)policy_handle_find(p, r->in.connect_handle,
-                                 SAMR_ACCESS_ENUM_DOMAINS, NULL,
-                                 struct samr_connect_info, &status);
+       cinfo = policy_handle_find(p, r->in.connect_handle,
+                                  struct samr_connect_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = samr_handle_access_check(cinfo->access_granted,
+                                         SAMR_ACCESS_ENUM_DOMAINS,
+                                         NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -4138,12 +4306,18 @@ NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
        NTSTATUS  status;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        /* append the alias' RID to it */
 
        if (!sid_compose(&sid, &dinfo->sid, alias_rid))
@@ -4191,13 +4365,13 @@ NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
        ainfo = policy_handle_create(p,
                                r->out.alias_handle,
                                SAMR_HANDLE_ALIAS,
-                               acc_granted,
                                struct samr_alias_info,
                                &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
        ainfo->sid = sid;
+       ainfo->access_granted = acc_granted;
 
        return NT_STATUS_OK;
 }
@@ -5118,12 +5292,19 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
                return NT_STATUS_INVALID_INFO_CLASS;
        }
 
-       uinfo = policy_handle_find(p, r->in.user_handle, acc_required, NULL,
+       uinfo = policy_handle_find(p, r->in.user_handle,
                                   struct samr_user_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(uinfo->access_granted,
+                                         acc_required,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
                  dom_sid_str_buf(&uinfo->sid, &buf),
                  r->in.level));
@@ -5384,13 +5565,19 @@ NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
        DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
-                                  | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
+                                         | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (!sid_check_is_our_sam(&dinfo->sid) &&
            !sid_check_is_builtin(&dinfo->sid))
                return NT_STATUS_OBJECT_TYPE_MISMATCH;
@@ -5450,12 +5637,18 @@ NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
        struct dom_sid_buf buf;
 
        ainfo = policy_handle_find(p, r->in.alias_handle,
-                                  SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
                                   struct samr_alias_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ainfo->access_granted,
+                                         SAMR_ALIAS_ACCESS_GET_MEMBERS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
 
        become_root();
@@ -5509,12 +5702,18 @@ NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
        struct dom_sid_buf buf;
 
        ginfo = policy_handle_find(p, r->in.group_handle,
-                                  SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
                                   struct samr_group_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ginfo->access_granted,
+                                         SAMR_GROUP_ACCESS_GET_MEMBERS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        rids = talloc_zero(p->mem_ctx, struct samr_RidAttrArray);
        if (!rids) {
                return NT_STATUS_NO_MEMORY;
@@ -5574,12 +5773,18 @@ NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
        NTSTATUS status;
 
        ainfo = policy_handle_find(p, r->in.alias_handle,
-                                  SAMR_ALIAS_ACCESS_ADD_MEMBER, NULL,
                                   struct samr_alias_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ainfo->access_granted,
+                                         SAMR_ALIAS_ACCESS_ADD_MEMBER,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
 
        /******** BEGIN SeAddUsers BLOCK *********/
@@ -5609,12 +5814,18 @@ NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
        NTSTATUS status;
 
        ainfo = policy_handle_find(p, r->in.alias_handle,
-                                  SAMR_ALIAS_ACCESS_REMOVE_MEMBER, NULL,
                                   struct samr_alias_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ainfo->access_granted,
+                                         SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
                   dom_sid_str_buf(&ainfo->sid, &buf)));
 
@@ -5646,12 +5857,18 @@ NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
        uint32_t group_rid;
 
        ginfo = policy_handle_find(p, r->in.group_handle,
-                                  SAMR_GROUP_ACCESS_ADD_MEMBER, NULL,
                                   struct samr_group_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ginfo->access_granted,
+                                         SAMR_GROUP_ACCESS_ADD_MEMBER,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
 
        if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
@@ -5691,12 +5908,18 @@ NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
         */
 
        ginfo = policy_handle_find(p, r->in.group_handle,
-                                  SAMR_GROUP_ACCESS_REMOVE_MEMBER, NULL,
                                   struct samr_group_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ginfo->access_granted,
+                                         SAMR_GROUP_ACCESS_REMOVE_MEMBER,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
                                &group_rid)) {
                return NT_STATUS_INVALID_HANDLE;
@@ -5730,12 +5953,18 @@ NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
        DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
 
        uinfo = policy_handle_find(p, r->in.user_handle,
-                                  SEC_STD_DELETE, NULL,
                                   struct samr_user_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(uinfo->access_granted,
+                                         SEC_STD_DELETE,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (!sid_check_is_in_our_sam(&uinfo->sid))
                return NT_STATUS_CANNOT_DELETE;
 
@@ -5800,12 +6029,18 @@ NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
        DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
 
        ginfo = policy_handle_find(p, r->in.group_handle,
-                                  SEC_STD_DELETE, NULL,
                                   struct samr_group_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ginfo->access_granted,
+                                         SEC_STD_DELETE,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
 
        if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
@@ -5851,12 +6086,18 @@ NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
        DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
 
        ainfo = policy_handle_find(p, r->in.alias_handle,
-                                  SEC_STD_DELETE, NULL,
                                   struct samr_alias_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ainfo->access_granted,
+                                         SEC_STD_DELETE,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
 
        /* Don't let Windows delete builtin groups */
@@ -5904,12 +6145,18 @@ NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
        struct samr_group_info *ginfo;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_CREATE_GROUP,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (!sid_check_is_our_sam(&dinfo->sid)) {
                return NT_STATUS_ACCESS_DENIED;
        }
@@ -5941,13 +6188,13 @@ NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
        ginfo = policy_handle_create(p,
                                r->out.group_handle,
                                SAMR_HANDLE_GROUP,
-                               GENERIC_RIGHTS_GROUP_ALL_ACCESS,
                                struct samr_group_info,
                                &status);
         if (!NT_STATUS_IS_OK(status)) {
                 return status;
         }
        sid_compose(&ginfo->sid, &dinfo->sid, *r->out.rid);
+       ginfo->access_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
 
        force_flush_samr_cache(&dinfo->sid);
 
@@ -5969,12 +6216,18 @@ NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
        NTSTATUS result;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
                                   struct samr_domain_info, &result);
        if (!NT_STATUS_IS_OK(result)) {
                return result;
        }
 
+       result = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(result)) {
+               return result;
+       }
+
        if (!sid_check_is_our_sam(&dinfo->sid)) {
                return NT_STATUS_ACCESS_DENIED;
        }
@@ -6018,13 +6271,13 @@ NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
        ainfo = policy_handle_create(p,
                                r->out.alias_handle,
                                SAMR_HANDLE_ALIAS,
-                               GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
                                struct samr_alias_info,
                                &result);
         if (!NT_STATUS_IS_OK(result)) {
                 return result;
         }
        ainfo->sid = info_sid;
+       ainfo->access_granted = GENERIC_RIGHTS_ALIAS_ALL_ACCESS;
 
        force_flush_samr_cache(&info_sid);
 
@@ -6050,12 +6303,18 @@ NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
        const char *group_description = NULL;
 
        ginfo = policy_handle_find(p, r->in.group_handle,
-                                  SAMR_GROUP_ACCESS_LOOKUP_INFO, NULL,
                                   struct samr_group_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ginfo->access_granted,
+                                         SAMR_GROUP_ACCESS_LOOKUP_INFO,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        map = talloc_zero(p->mem_ctx, GROUP_MAP);
        if (!map) {
                return NT_STATUS_NO_MEMORY;
@@ -6153,12 +6412,18 @@ NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
        bool ret;
 
        ginfo = policy_handle_find(p, r->in.group_handle,
-                                  SAMR_GROUP_ACCESS_SET_INFO, NULL,
                                   struct samr_group_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ginfo->access_granted,
+                                         SAMR_GROUP_ACCESS_SET_INFO,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        map = talloc_zero(p->mem_ctx, GROUP_MAP);
        if (!map) {
                return NT_STATUS_NO_MEMORY;
@@ -6220,12 +6485,18 @@ NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
        NTSTATUS status;
 
        ainfo = policy_handle_find(p, r->in.alias_handle,
-                                  SAMR_ALIAS_ACCESS_SET_INFO, NULL,
                                   struct samr_alias_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(ainfo->access_granted,
+                                         SAMR_ALIAS_ACCESS_SET_INFO,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        info = talloc_zero(p->mem_ctx, struct acct_info);
        if (!info) {
                return NT_STATUS_NO_MEMORY;
@@ -6378,12 +6649,18 @@ NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
        bool ret;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        /*check if access can be granted as requested by client. */
        map_max_allowed_access(p->session_info->security_token,
                               p->session_info->unix_token,
@@ -6427,13 +6704,13 @@ NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
        ginfo = policy_handle_create(p,
                                r->out.group_handle,
                                SAMR_HANDLE_GROUP,
-                               acc_granted,
                                struct samr_group_info,
                                &status);
         if (!NT_STATUS_IS_OK(status)) {
                 return status;
         }
        ginfo->sid = info_sid;
+       ginfo->access_granted = acc_granted;
 
        return NT_STATUS_OK;
 }
@@ -6455,12 +6732,18 @@ NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
        /* Find the policy handle. Open a policy on it. */
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
                                   struct samr_domain_info, &result);
        if (!NT_STATUS_IS_OK(result)) {
                return result;
        }
 
+       result = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(result)) {
+               return result;
+       }
+
        DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
                  dom_sid_str_buf(&dinfo->sid, &buf)));
 
@@ -6599,6 +6882,7 @@ NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
 {
        NTSTATUS status;
        uint32_t acc_required = 0;
+       struct samr_domain_info *dinfo = NULL;
 
        DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
 
@@ -6623,13 +6907,19 @@ NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
                return NT_STATUS_INVALID_INFO_CLASS;
        }
 
-       (void)policy_handle_find(p, r->in.domain_handle,
-                                  acc_required, NULL,
+       dinfo = policy_handle_find(p, r->in.domain_handle,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         acc_required,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
 
        switch (r->in.level) {
@@ -6681,12 +6971,18 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
        DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if ((r->in.level < 1) || (r->in.level > 3)) {
                DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
                        "Unknown info level (%u)\n",
@@ -6819,12 +7115,18 @@ NTSTATUS _samr_RidToSid(struct pipes_struct *p,
        struct dom_sid sid;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
-                                  0, NULL,
                                   struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
+       status = samr_handle_access_check(dinfo->access_granted,
+                                         0,
+                                         NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
                return NT_STATUS_NO_MEMORY;
        }