Access control to SAM / _samr_query_sec_obj

Kai Krueger kai at kruegernetz.de
Wed Jun 5 16:06:03 GMT 2002


----- Original Message ----- 
From: "Jeremy Allison" <jra at samba.org> Sent: Wednesday, June 05, 2002 8:07 PM
Subject: Re: Access control to SAM / _samr_query_sec_obj


> Nice patch. I do have one request though. I've (for years)
> been removing magic numerical constants from Samba (like
> the "0xf003f" in the patch above). We know what these numbers
> are in SEC_ACL terms - can you please change the numbers to
> a list of #defined constants :
> 
> ie. The  0x20010 above should map to :
> 
> READ_CONTROL_ACCESS plus a new constant that specifies READ
> access to a SAMR, probably something like SAMR_READ_ACCESS
> (as it's a specific right).
> 
> Thanks,
> 
> Jeremy.
> 

Ok, I've removed all the numerical constants and have added them as #defines in rpc_samr.h.
The names are partly based upon information I got from ACL tools.

As the SDs contained numerical constants as well, that part is included as well, so it is a patch
against a fresh samba HEAD cvs from 31.5.02

Kai


--- ./samba-orig/source/include/rpc_samr.h Wed Jan 30 07:08:15 2002
+++ ./samba/source/include/rpc_samr.h Thu Jun  6 00:37:50 2002
@@ -145,6 +145,170 @@
 #define SAMR_CONNECT           0x39
 #define SAMR_SET_USERINFO      0x3A
 
+//Access bits to the SAM-object
+#define SAMR_ACCESS_UNKNOWN_1        0x00000001
+#define SAMR_ACCESS_SHUTDOWN_SERVER  0x00000002
+#define SAMR_ACCESS_UNKNOWN_4        0x00000004
+#define SAMR_ACCESS_UNKNOWN_8        0x00000008
+#define SAMR_ACCESS_ENUM_DOMAINS     0x00000010
+#define SAMR_ACCESS_OPEN_DOMAIN      0x00000020
+
+#define SAMR_ALL_ACCESS  ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+                           SAMR_ACCESS_OPEN_DOMAIN         | \
+      SAMR_ACCESS_ENUM_DOMAINS        | \
+      SAMR_ACCESS_UNKNOWN_8           | \
+      SAMR_ACCESS_UNKNOWN_4           | \
+      SAMR_ACCESS_SHUTDOWN_SERVER     | \
+      SAMR_ACCESS_UNKNOWN_1 )
+      
+#define SAMR_READ        ( STANDARD_RIGHTS_READ_ACCESS     | \
+                           SAMR_ACCESS_ENUM_DOMAINS )
+
+#define SAMR_WRITE       ( STANDARD_RIGHTS_WRITE_ACCESS    | \
+                           SAMR_ACCESS_UNKNOWN_8           | \
+      SAMR_ACCESS_UNKNOWN_4           | \
+      SAMR_ACCESS_SHUTDOWN_SERVER )
+
+#define SAMR_EXECUTE     ( STANDARD_RIGHTS_EXECUTE_ACCESS  | \
+                           SAMR_ACCESS_OPEN_DOMAIN         | \
+      SAMR_ACCESS_UNKNOWN_1 )            
+
+//Access bits to Domain-objects
+#define DOMAIN_ACCESS_LOOKUP_INFO_1  0x000000001
+#define DOMAIN_ACCESS_SET_INFO_1     0x000000002
+#define DOMAIN_ACCESS_LOOKUP_INFO_2  0x000000004
+#define DOMAIN_ACCESS_SET_INFO_2     0x000000008
+#define DOMAIN_ACCESS_CREATE_USER    0x000000010
+#define DOMAIN_ACCESS_CREATE_GROUP   0x000000020
+#define DOMAIN_ACCESS_CREATE_ALIAS   0x000000040
+#define DOMAIN_ACCESS_UNKNOWN_80     0x000000080
+#define DOMAIN_ACCESS_ENUM_ACCOUNTS  0x000000100
+#define DOMAIN_ACCESS_OPEN_ACCOUNT   0x000000200
+#define DOMAIN_ACCESS_SET_INFO_3     0x000000400
+
+#define DOMAIN_ALL_ACCESS  ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+                             DOMAIN_ACCESS_SET_INFO_3        | \
+        DOMAIN_ACCESS_OPEN_ACCOUNT      | \
+        DOMAIN_ACCESS_ENUM_ACCOUNTS     | \
+        DOMAIN_ACCESS_UNKNOWN_80        | \
+        DOMAIN_ACCESS_CREATE_ALIAS      | \
+        DOMAIN_ACCESS_CREATE_GROUP      | \
+        DOMAIN_ACCESS_CREATE_USER       | \
+        DOMAIN_ACCESS_SET_INFO_2        | \
+        DOMAIN_ACCESS_LOOKUP_INFO_2     | \
+        DOMAIN_ACCESS_SET_INFO_1        | \
+        DOMAIN_ACCESS_LOOKUP_INFO_1 )
+      
+#define DOMAIN_READ        ( STANDARD_RIGHTS_READ_ACCESS     | \
+                             DOMAIN_ACCESS_UNKNOWN_80        | \
+        DOMAIN_ACCESS_LOOKUP_INFO_2 )
+
+#define DOMAIN_WRITE       ( STANDARD_RIGHTS_WRITE_ACCESS    | \
+                             DOMAIN_ACCESS_SET_INFO_3        | \
+        DOMAIN_ACCESS_CREATE_ALIAS      | \
+        DOMAIN_ACCESS_CREATE_GROUP      | \
+        DOMAIN_ACCESS_CREATE_USER       | \
+        DOMAIN_ACCESS_SET_INFO_2        | \
+        DOMAIN_ACCESS_SET_INFO_1 )
+
+#define DOMAIN_EXECUTE     ( STANDARD_RIGHTS_EXECUTE_ACCESS  | \
+                             DOMAIN_ACCESS_OPEN_ACCOUNT      | \
+        DOMAIN_ACCESS_ENUM_ACCOUNTS     | \
+        DOMAIN_ACCESS_LOOKUP_INFO_1 )            
+
+//Access bits to User-objects
+#define USER_ACCESS_GET_NAME_ETC     0x000000001
+#define USER_ACCESS_GET_LOCALE       0x000000002
+#define USER_ACCESS_SET_LOC_COM      0x000000004
+#define USER_ACCESS_GET_LOGONINFO    0x000000008
+#define USER_ACCESS_UNKNOWN_10       0x000000010
+#define USER_ACCESS_SET_ATTRIBUTES   0x000000020
+#define USER_ACCESS_CHANGE_PASSWORD  0x000000040
+#define USER_ACCESS_SET_PASSWORD     0x000000080
+#define USER_ACCESS_GET_GROUPS       0x000000100
+#define USER_ACCESS_UNKNOWN_200      0x000000200
+#define USER_ACCESS_UNKNOWN_400      0x000000400
+
+#define USER_ALL_ACCESS    ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+                             USER_ACCESS_UNKNOWN_400       | \
+        USER_ACCESS_UNKNOWN_200       | \
+        USER_ACCESS_GET_GROUPS        | \
+        USER_ACCESS_SET_PASSWORD      | \
+        USER_ACCESS_CHANGE_PASSWORD   | \
+        USER_ACCESS_SET_ATTRIBUTES    | \
+        USER_ACCESS_UNKNOWN_10        | \
+        USER_ACCESS_GET_LOGONINFO     | \
+        USER_ACCESS_SET_LOC_COM       | \
+        USER_ACCESS_GET_LOCALE        | \
+        USER_ACCESS_GET_NAME_ETC )
+      
+#define USER_READ          ( STANDARD_RIGHTS_READ_ACCESS     | \
+                             USER_ACCESS_UNKNOWN_200         | \
+        USER_ACCESS_GET_GROUPS          | \
+        USER_ACCESS_UNKNOWN_10          | \
+        USER_ACCESS_GET_LOGONINFO       | \
+        USER_ACCESS_GET_LOCALE )
+
+#define USER_WRITE         ( STANDARD_RIGHTS_WRITE_ACCESS    | \
+                             USER_ACCESS_CHANGE_PASSWORD     | \
+        USER_ACCESS_SET_LOC_COM )
+        
+#define USER_EXECUTE       ( STANDARD_RIGHTS_EXECUTE_ACCESS  | \
+                             USER_ACCESS_CHANGE_PASSWORD     | \
+        USER_ACCESS_GET_NAME_ETC )
+
+//Access bits to Group-objects        
+#define GROUP_ACCESS_LOOKUP_INFO     0x00000001
+#define GROUP_ACCESS_SET_INFO        0x00000002
+#define GROUP_ACCESS_ADD_MEMBER      0x00000004
+#define GROUP_ACCESS_REMOVE_MEMBER   0x00000008
+#define GROUP_ACCESS_GET_MEMBERS     0x00000010
+
+#define GROUP_ALL_ACCESS   ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+                             GROUP_ACCESS_GET_MEMBERS        | \
+        GROUP_ACCESS_REMOVE_MEMBER      | \
+        GROUP_ACCESS_ADD_MEMBER         | \
+        GROUP_ACCESS_SET_INFO           | \
+        GROUP_ACCESS_LOOKUP_INFO )
+      
+#define GROUP_READ         ( STANDARD_RIGHTS_READ_ACCESS     | \
+                             GROUP_ACCESS_GET_MEMBERS )
+
+#define GROUP_WRITE        ( STANDARD_RIGHTS_WRITE_ACCESS    | \
+                             GROUP_ACCESS_REMOVE_MEMBER      | \
+        GROUP_ACCESS_ADD_MEMBER         | \
+        GROUP_ACCESS_SET_INFO )
+        
+#define GROUP_EXECUTE      ( STANDARD_RIGHTS_EXECUTE_ACCESS  | \
+                             GROUP_ACCESS_LOOKUP_INFO )
+        
+//Access bits to Alias-objects
+#define ALIAS_ACCESS_ADD_MEMBER      0x00000001
+#define ALIAS_ACCESS_REMOVE_MEMBER   0x00000002
+#define ALIAS_ACCESS_GET_MEMBERS     0x00000004
+#define ALIAS_ACCESS_LOOKUP_INFO     0x00000008
+#define ALIAS_ACCESS_SET_INFO        0x00000010
+
+#define ALIAS_ALL_ACCESS   ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+                             ALIAS_ACCESS_GET_MEMBERS        | \
+        ALIAS_ACCESS_REMOVE_MEMBER      | \
+        ALIAS_ACCESS_ADD_MEMBER         | \
+        ALIAS_ACCESS_SET_INFO           | \
+        ALIAS_ACCESS_LOOKUP_INFO )
+      
+#define ALIAS_READ         ( STANDARD_RIGHTS_READ_ACCESS     | \
+                             ALIAS_ACCESS_GET_MEMBERS )
+
+#define ALIAS_WRITE        ( STANDARD_RIGHTS_WRITE_ACCESS    | \
+                             ALIAS_ACCESS_REMOVE_MEMBER      | \
+        ALIAS_ACCESS_ADD_MEMBER         | \
+        ALIAS_ACCESS_SET_INFO )
+        
+#define ALIAS_EXECUTE      ( STANDARD_RIGHTS_EXECUTE_ACCESS  | \
+                             ALIAS_ACCESS_LOOKUP_INFO )
+
+
+
 
 typedef struct _DISP_USER_INFO {
  SAM_ACCOUNT *sam;


--- ./samba-orig/source/rpc_server/srv_samr_nt.c Sun May 26 21:11:52 2002
+++ ./samba/source/rpc_server/srv_samr_nt.c Thu Jun  6 00:38:42 2002
@@ -52,9 +52,18 @@
  /* for use by the \PIPE\samr policy */
  DOM_SID sid;
  uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
+ uint32 acc_granted;
  DISP_INFO disp_info;
 };
 
+struct generic_mapping sam_generic_mapping = {SAMR_READ, SAMR_WRITE, SAMR_EXECUTE, SAMR_ALL_ACCESS };
+struct generic_mapping dom_generic_mapping = {DOMAIN_READ, DOMAIN_WRITE, DOMAIN_EXECUTE, DOMAIN_ALL_ACCESS };
+struct generic_mapping usr_generic_mapping = {USER_READ, USER_WRITE, USER_EXECUTE, USER_ALL_ACCESS };
+struct generic_mapping grp_generic_mapping = {GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, GROUP_ALL_ACCESS };
+struct generic_mapping ali_generic_mapping = {ALIAS_READ, ALIAS_WRITE, ALIAS_EXECUTE, ALIAS_ALL_ACCESS };
+
+static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
+
 /*******************************************************************
  Create a samr_info struct.
 ********************************************************************/
@@ -352,17 +361,45 @@
 
 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
 {
- struct samr_info *info;
+ struct    samr_info *info;
+ SEC_DESC *psd = NULL;
+ uint32    acc_granted;
+ uint32    acc_required;
+ uint32    des_access = q_u->flags;
+ size_t    sd_size;
+ NTSTATUS  status;
 
  r_u->status = NT_STATUS_OK;
 
  /* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
   return NT_STATUS_INVALID_HANDLE;
 
+ /*check if function is granted*/
+ acc_granted = info->acc_granted;
+ acc_required = SAMR_ACCESS_OPEN_DOMAIN; //SAMR: open domain
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_open_domain: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
+ /*check if access can be granted as requested by client. */
+ samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
+ se_map_generic(&des_access,&dom_generic_mapping);
+ if(!se_access_check(psd,p->pipe_user.nt_user_token, des_access, &acc_granted, &status))
+ {
+  DEBUG(2,("_samr_open_domain: ACCESS should be DENIED  (requested: %#010x)\n",
+      des_access));
+  //return r_u->status = status;    
+ }
+  
+ 
  /* associate the domain SID with the (unique) handle. */
  if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
   return NT_STATUS_NO_MEMORY;
+ info->acc_granted = acc_granted;
 
  /* get a (unique) handle.  open a policy on it. */
  if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
@@ -402,11 +439,90 @@
  return r_u->status;
 }
 
+
+/*******************************************************************
+ samr_make_sam_obj_sd
+ ********************************************************************/
+
+static NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
+{
+ extern DOM_SID global_sid_World;
+ DOM_SID adm_sid;
+ DOM_SID act_sid;
+
+ SEC_ACE ace[3];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ //basic access for every one
+ init_sec_access(&mask, SAMR_EXECUTE | SAMR_READ);
+ init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ //full access for builtin aliases Administrators and Account Operators
+ init_sec_access(&mask, SAMR_ALL_ACCESS);
+ init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
+  return NT_STATUS_NO_MEMORY;
+
+ if((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
+  return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ samr_make_dom_obj_sd
+ ********************************************************************/
+
+static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
+{
+ extern DOM_SID global_sid_World;
+ DOM_SID adm_sid;
+ DOM_SID act_sid;
+
+ SEC_ACE ace[3];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ //basic access for every one
+ init_sec_access(&mask, DOMAIN_EXECUTE | DOMAIN_READ);
+ init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ //full access for builtin aliases Administrators and Account Operators
+ init_sec_access(&mask, DOMAIN_ALL_ACCESS);
+ init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
+  return NT_STATUS_NO_MEMORY;
+
+ if((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
+  return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
+
 /*******************************************************************
  samr_make_usr_obj_sd
  ********************************************************************/
 
-static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
+static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
 {
  extern DOM_SID global_sid_World;
  DOM_SID adm_sid;
@@ -416,8 +532,6 @@
  SEC_ACCESS mask;
 
  SEC_ACL *psa = NULL;
- SEC_DESC *psd = NULL;
- size_t sd_size;
 
  sid_copy(&adm_sid, &global_sid_Builtin);
  sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
@@ -425,29 +539,107 @@
  sid_copy(&act_sid, &global_sid_Builtin);
  sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
 
- init_sec_access(&mask, 0x2035b);
+ //basic access for every one
+ init_sec_access(&mask, USER_EXECUTE | USER_READ);
  init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
 
- init_sec_access(&mask, 0xf07ff);
+ //full access for builtin aliases Administrators and Account Operators
+ init_sec_access(&mask, USER_ALL_ACCESS);
  init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
  init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
 
- init_sec_access(&mask,0x20044);
+ //extended access for the user
+ init_sec_access(&mask,READ_CONTROL_ACCESS | USER_ACCESS_CHANGE_PASSWORD | USER_ACCESS_SET_LOC_COM);
  init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
 
  if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
   return NT_STATUS_NO_MEMORY;
 
- if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
+ if((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
+  return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ samr_make_grp_obj_sd
+ ********************************************************************/
+
+static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
+{
+ extern DOM_SID global_sid_World;
+ DOM_SID adm_sid;
+ DOM_SID act_sid;
+
+ SEC_ACE ace[3];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ //basic access for every one
+ init_sec_access(&mask, GROUP_EXECUTE | GROUP_READ);
+ init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ //full access for builtin aliases Administrators and Account Operators
+ init_sec_access(&mask, GROUP_ALL_ACCESS);
+ init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
+  return NT_STATUS_NO_MEMORY;
+
+ if((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
+  return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ samr_make_ali_obj_sd
+ ********************************************************************/
+
+static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
+{
+ extern DOM_SID global_sid_World;
+ DOM_SID adm_sid;
+ DOM_SID act_sid;
+
+ SEC_ACE ace[3];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ //basic access for every one
+ init_sec_access(&mask, ALIAS_EXECUTE | ALIAS_READ);
+ init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ //full access for builtin aliases Administrators and Account Operators
+ init_sec_access(&mask, ALIAS_ALL_ACCESS);
+ init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
   return NT_STATUS_NO_MEMORY;
 
- if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
+ if((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
   return NT_STATUS_NO_MEMORY;
 
  return NT_STATUS_OK;
 }
 
-static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
+static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
 {
  struct samr_info *info = NULL;
 
@@ -459,6 +651,7 @@
   return False;
 
  *sid = info->sid;
+ *acc_granted = info->acc_granted;
  return True;
 }
 
@@ -470,17 +663,53 @@
 {
  DOM_SID pol_sid;
  fstring str_sid;
+ SEC_DESC * psd = NULL;
+ size_t sd_size;
+ int rid;
+ uint32 acc_granted;
 
  r_u->status = NT_STATUS_OK;
 
  /* Get the SID. */
-
- if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
+ if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
+ 
+ 
 
  DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
 
- r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
+ /*Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID)*/
+
+ //To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function
+ if (pol_sid.sid_rev_num == 0)
+ {
+     DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
+     r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
+ }
+ else if (sid_equal(&pol_sid,&global_sam_sid))  //check if it is our domain SID
+
+ {
+     DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
+     r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
+ }
+ else if (sid_equal(&pol_sid,&global_sid_Builtin)) //check if it is the Builtin  Domain
+ {
+     /*TODO: Builtin probably needs a different SD with restricted write access*/
+     DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
+     r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
+ }
+ else if (sid_check_is_in_our_domain(&pol_sid) ||
+       sid_check_is_in_builtin(&pol_sid))
+ {
+         /* TODO: different SDs have to be generated for aliases groups and users.
+           Currently all three get a default user SD  */
+         DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
+         r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
+ }
+ else return NT_STATUS_OBJECT_TYPE_MISMATCH;
+
+ if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
+                 return NT_STATUS_NO_MEMORY;
 
  if (NT_STATUS_IS_OK(r_u->status))
   r_u->ptr = 1;
@@ -534,16 +763,29 @@
 
 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
 {
+ struct samr_info *info;
  SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
  int num_entries = 0;
  int total_entries = 0;
+ uint32 acc_granted;
+ uint32 acc_required;
  
  r_u->status = NT_STATUS_OK;
 
  /* find the policy handle.  open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
   return NT_STATUS_INVALID_HANDLE;
 
+ /*Access check on funktion*/
+ acc_granted = info->acc_granted;
+ acc_required = DOMAIN_ACCESS_ENUM_ACCOUNTS;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_enum_dom_users: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
  DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
 
  become_root();
@@ -556,7 +798,7 @@
 
  samr_clear_passwd_fields(pass, num_entries);
 
- /* 
+ /*
   * Note from JRA. total_entries is not being used here. Currently if there is a
   * large user base then it looks like NT will enumerate until get_sampwd_entries
   * returns False due to num_entries being zero. This will cause an access denied
@@ -673,7 +915,7 @@
   grp = glist = getgrent_list();
   if (grp == NULL)
    return NT_STATUS_NO_MEMORY;
-  
+
   for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
    uint32 trid;
    
@@ -808,11 +1050,22 @@
  DOMAIN_GRP *grp=NULL;
  uint32 num_entries;
  DOM_SID sid;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  r_u->status = NT_STATUS_OK;
 
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
+ 
+ /*Access check on funktion*/
+ acc_required = DOMAIN_ACCESS_ENUM_ACCOUNTS;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_enum_dom_groups: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
 
@@ -840,12 +1093,23 @@
  fstring sid_str;
  DOM_SID sid;
  NTSTATUS status;
+ uint32  acc_granted;
+ uint32  acc_required;
  
  r_u->status = NT_STATUS_OK;
 
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
 
+ /*Access check on funktion*/
+ acc_required = DOMAIN_ACCESS_ENUM_ACCOUNTS;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_enum_dom_aliases: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
  sid_to_string(sid_str, &sid);
  DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
 
@@ -1058,21 +1322,33 @@
 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
 {
  struct samr_info *info = NULL;
+ DOM_SID   sid;
  GROUP_MAP map;
+ uint32    acc_granted;
+ uint32    acc_required;
 
  r_u->status = NT_STATUS_OK;
 
  DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
 
  /* find the policy handle.  open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
+ 
+ /*Access check on funktion*/
+ acc_required = ALIAS_ACCESS_LOOKUP_INFO; //Alias: query info
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_query_aliasinfo: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
- if (!sid_check_is_in_our_domain(&info->sid) &&
-     !sid_check_is_in_builtin(&info->sid))
+ if (!sid_check_is_in_our_domain(&sid) &&
+     !sid_check_is_in_builtin(&sid))
   return NT_STATUS_OBJECT_TYPE_MISMATCH;
 
- if(!get_local_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
+ if(!get_local_group_from_sid(sid, &map, MAPPING_WITHOUT_PRIV))
   return NT_STATUS_NO_SUCH_ALIAS;
 
  switch (q_u->switch_level) {
@@ -1169,6 +1445,7 @@
  int num_rids = q_u->num_names2;
  DOM_SID pol_sid;
  fstring sid_str;
+ uint32  acc_granted;
 
  r_u->status = NT_STATUS_OK;
 
@@ -1177,7 +1454,7 @@
  ZERO_ARRAY(rid);
  ZERO_ARRAY(type);
 
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
   init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
   return r_u->status;
  }
@@ -1324,13 +1601,14 @@
  DOM_SID pol_sid;
  int num_rids = q_u->num_rids1;
  int i;
+ uint32 acc_granted;
 
  r_u->status = NT_STATUS_OK;
 
  DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
 
  /* find the policy handle.  open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
 
  if (num_rids > MAX_SAM_ENTRIES) {
@@ -1392,22 +1670,43 @@
  POLICY_HND domain_pol = q_u->domain_pol;
  POLICY_HND *user_pol = &r_u->user_pol;
  struct samr_info *info = NULL;
+ SEC_DESC *psd = NULL;
+ uint32    acc_granted;
+ uint32    acc_required;
+ uint32    des_access = q_u->access_mask;
+ size_t    sd_size;
+ NTSTATUS  status;
  BOOL ret;
 
  r_u->status = NT_STATUS_OK;
 
- /* find the domain policy handle. */
- if (!find_policy_by_hnd(p, &domain_pol, NULL))
-  return NT_STATUS_INVALID_HANDLE;
-
- /* Get the domain SID stored in the domain policy */
- if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
+ /* find the domain policy and get the SID / access bits stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
 
  /* append the user's RID to it */
  if(!sid_append_rid(&sid, q_u->user_rid))
   return NT_STATUS_NO_SUCH_USER;
 
+ /*check if function is granted*/
+ acc_required = DOMAIN_ACCESS_OPEN_ACCOUNT;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_api_samr_open_user: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
+ /*check if access can be granted as requested by client. */
+ samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
+ se_map_generic(&des_access,&usr_generic_mapping);
+ if(!se_access_check(psd,p->pipe_user.nt_user_token, des_access, &acc_granted, &status))
+ {
+  DEBUG(2,("_api_samr_open_usr: ACCESS should be DENIED  (requested: %#010x)\n",
+      des_access));
+  //return r_u->status = status;    
+ }
+ 
  pdb_init_sam(&sampass);
 
  become_root();
@@ -1422,9 +1721,10 @@
 
  pdb_free_sam(&sampass);
 
- /* associate the user's SID with the new handle. */
+ /* associate the user's SID and access bits with the new handle. */
  if ((info = get_samr_info_by_sid(&sid)) == NULL)
   return NT_STATUS_NO_MEMORY;
+ info->acc_granted = acc_granted;
 
  /* get a (unique) handle.  open a policy on it. */
  if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
@@ -1683,9 +1983,11 @@
 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
 {
  SAM_ACCOUNT *sam_pass=NULL;
+ DOM_SID  sid;
  DOM_GID *gids = NULL;
  int num_groups = 0;
- struct samr_info *info = NULL;
+ uint32 acc_granted;
+ uint32 acc_required;
  BOOL ret;
 
  /*
@@ -1705,16 +2007,25 @@
  DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
 
  /* find the policy handle.  open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
-
- if (!sid_check_is_in_our_domain(&info->sid))
+  
+ /*check if function is granted*/
+ acc_required = USER_ACCESS_GET_GROUPS;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_query_usergroups: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
+ if (!sid_check_is_in_our_domain(&sid))
   return NT_STATUS_OBJECT_TYPE_MISMATCH;
 
  pdb_init_sam(&sam_pass);
 
  become_root();
- ret = pdb_getsampwsid(sam_pass, &info->sid);
+ ret = pdb_getsampwsid(sam_pass, &sid);
  unbecome_root();
 
  if (ret == False) {
@@ -1864,11 +2175,22 @@
  BOOL ret;
  NTSTATUS nt_status;
  struct passwd *pw;
+ uint32 acc_granted;
+ uint32 acc_required;
 
- /* find the policy handle.  open a policy on it. */
- if (!find_policy_by_hnd(p, &dom_pol, NULL))
+ /* Get the domain SID stored in the domain policy */
+   if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
-
+ 
+ /*Access check on funktion*/
+ acc_required = DOMAIN_ACCESS_CREATE_USER; 
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_api_samr_create_user: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
  /* find the account: tell the caller if it exists.
    lkclXXXX i have *no* idea if this is a problem or not
     or even if you are supposed to construct a different
@@ -1983,11 +2305,7 @@
    return NT_STATUS_ACCESS_DENIED;  
   }
   
-  /* Get the domain SID stored in the domain policy */
-   if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
-    pdb_free_sam(&sam_pass);
-  return NT_STATUS_INVALID_HANDLE;
- }
+  
 
  /* append the user's RID to it */
  if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
@@ -2049,17 +2367,31 @@
 
 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
 {
- struct samr_info *info = NULL;
+    struct samr_info *info = NULL;
+    SEC_DESC         *psd  = NULL;
+    size_t            sd_size;
+    uint32            des_access = q_u->access_mask;
+    uint32            acc_granted;
+    NTSTATUS          status;
 
     DEBUG(5,("_samr_connect: %d\n", __LINE__));
 
     r_u->status = NT_STATUS_OK;
+    
+    /*check if access can be granted as requested by client. */
+    samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
+    se_map_generic(&des_access,&sam_generic_mapping);
+    if(!se_access_check(psd,p->pipe_user.nt_user_token, des_access, &acc_granted, &status))
+    {
+ DEBUG(2,("_samr_connect: ACCESS should be DENIED\n"));
+ //return r_u->status = status;    
+    }
 
-    /* associate the user's SID with the new handle. */
- if ((info = get_samr_info_by_sid(NULL)) == NULL)
+    /* associate access granted with the new handle. */
+    if ((info = get_samr_info_by_sid(NULL)) == NULL)
         return NT_STATUS_NO_MEMORY;
 
-    info->status = q_u->access_mask;
+    info->acc_granted = acc_granted;
 
     /* get a (unique) handle.  open a policy on it. */
     if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
@@ -2076,13 +2408,26 @@
 
 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
 {
+ struct samr_info *info;
  fstring domain_name;
  DOM_SID sid;
+ uint32  acc_granted;
+ uint32  acc_required;
 
  r_u->status = NT_STATUS_OK;
 
- if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
+ if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
   return NT_STATUS_INVALID_HANDLE;
+ 
+ /*Access check on funktion*/
+ acc_granted  = info->acc_granted;
+ acc_required = SAMR_ACCESS_OPEN_DOMAIN;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_lookup_domain: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
 
@@ -2143,11 +2488,27 @@
 
 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
 {
+ struct samr_info *info;
+ uint32 acc_granted;
+ uint32 acc_required;
  uint32 num_entries = 2;
  fstring dom[2];
  char *name;
 
  r_u->status = NT_STATUS_OK;
+ 
+ if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
+  return NT_STATUS_INVALID_HANDLE;
+ 
+ /*Access check on funktion*/
+ acc_granted  = info->acc_granted;
+ acc_required = SAMR_ACCESS_ENUM_DOMAINS;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_enum_domains: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  switch (lp_server_role()) {
  case ROLE_DOMAIN_PDC:
@@ -2180,21 +2541,43 @@
  POLICY_HND domain_pol = q_u->dom_pol;
  uint32 alias_rid = q_u->rid_alias;
  POLICY_HND *alias_pol = &r_u->pol;
- struct samr_info *info = NULL;
+ struct    samr_info *info = NULL;
+ SEC_DESC *psd = NULL;
+ uint32    acc_granted;
+ uint32    acc_required;
+ uint32    des_access = q_u->access_mask;
+ size_t    sd_size;
+ NTSTATUS  status;
 
  r_u->status = NT_STATUS_OK;
 
- /* get the domain policy. */
- if (!find_policy_by_hnd(p, &domain_pol, NULL))
-  return NT_STATUS_INVALID_HANDLE;
-
- /* Get the domain SID stored in the domain policy */
- if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
+ /* find the domain policy and get the SID / access bits stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
 
  /* append the alias' RID to it */
  if(!sid_append_rid(&sid, alias_rid))
   return NT_STATUS_NO_SUCH_USER;
+  
+ /*check if function is granted*/
+ acc_granted = info->acc_granted;
+ acc_required = DOMAIN_ACCESS_OPEN_ACCOUNT;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_api_samr_open_alias: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
+ /*check if access can be granted as requested by client. */
+ samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
+ se_map_generic(&des_access,&ali_generic_mapping);
+ if(!se_access_check(psd,p->pipe_user.nt_user_token, des_access, &acc_granted, &status))
+ {
+  DEBUG(2,("_api_samr_open_alias: ACCESS should be DENIED  (requested: %#010x)\n",
+      des_access));
+  //return r_u->status = status;    
+ }
 
  /*
   * we should check if the rid really exist !!!
@@ -2477,14 +2860,25 @@
  POLICY_HND *pol = &q_u->pol;
  uint16 switch_value = q_u->switch_value;
  SAM_USERINFO_CTR *ctr = q_u->ctr;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
 
  r_u->status = NT_STATUS_OK;
 
  /* find the policy handle.  open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, pol, &sid))
+ if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*Access check on funktion*/
+ acc_required = USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES; //This is probably wrong
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_set_userinfo: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
 
@@ -2555,15 +2949,26 @@
  SAM_USERINFO_CTR *ctr = q_u->ctr;
  POLICY_HND *pol = &q_u->pol;
  uint16 switch_value = q_u->switch_value;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
 
  r_u->status = NT_STATUS_OK;
 
  /* find the policy handle.  open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, pol, &sid))
+ if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
   return NT_STATUS_INVALID_HANDLE;
 
+ /*check if function is granted*/
+ acc_required = USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES; //This is probably wrong
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_set_userinfo2: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
  DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
 
  if (ctr == NULL) {
@@ -2693,10 +3098,21 @@
 
  SAM_ACCOUNT *sam_user = NULL;
  BOOL check;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  /* find the policy handle.  open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = ALIAS_ACCESS_GET_MEMBERS; //Alias: get members
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_query_aliasmem: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  sid_copy(&als_sid, &alias_sid);
  sid_to_string(alias_sid_str, &alias_sid);
@@ -2789,11 +3205,22 @@
 
  SAM_ACCOUNT *sam_user = NULL;
  BOOL check;
+ uint32 acc_granted;
+ uint32 acc_required;
 
 
  /* find the policy handle.  open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = GROUP_ACCESS_GET_MEMBERS;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_query_groupmem: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  /* todo: change to use sid_compare_front */
 
@@ -2877,10 +3304,21 @@
  NTSTATUS ret;
  SAM_ACCOUNT *sam_user = NULL;
  BOOL check;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = ALIAS_ACCESS_ADD_MEMBER; //Alias: add members
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_add_aliasmem: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  sid_to_string(alias_sid_str, &alias_sid);
  DEBUG(10, ("sid is %s\n", alias_sid_str));
@@ -2960,10 +3398,21 @@
  fstring grp_name;
  GROUP_MAP map;
  SAM_ACCOUNT *sam_pass=NULL;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+ 
+ /*check if function is granted*/
+ acc_required = ALIAS_ACCESS_REMOVE_MEMBER;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_del_aliasmem: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  sid_to_string(alias_sid_str, &alias_sid);
  DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
@@ -3026,10 +3475,21 @@
  NTSTATUS ret;
  SAM_ACCOUNT *sam_user;
  BOOL check;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = GROUP_ACCESS_ADD_MEMBER;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_add_groupmem: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  sid_to_string(group_sid_str, &group_sid);
  DEBUG(10, ("sid is %s\n", group_sid_str));
@@ -3107,6 +3567,8 @@
  GROUP_MAP map;
  fstring grp_name;
  struct group *grp;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  /*
   * delete the group member named q_u->rid
@@ -3115,8 +3577,17 @@
   */
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = GROUP_ACCESS_REMOVE_MEMBER;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_del_groupmem: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  if(!sid_check_is_in_our_domain(&group_sid))
   return NT_STATUS_NO_SUCH_GROUP;
@@ -3186,12 +3657,23 @@
 {
  DOM_SID user_sid;
  SAM_ACCOUNT *sam_pass=NULL;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = DELETE_ACCESS; //User: delete
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_delete_dom_user: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  if (!sid_check_is_in_our_domain(&user_sid))
   return NT_STATUS_CANNOT_DELETE;
@@ -3240,12 +3722,23 @@
  gid_t gid;
  struct group *grp;
  GROUP_MAP map;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = DELETE_ACCESS; //Group: delete
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_delete_dom_group: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  sid_copy(&dom_sid, &group_sid);
  sid_to_string(group_sid_str, &dom_sid);
@@ -3297,12 +3790,23 @@
  gid_t gid;
  struct group *grp;
  GROUP_MAP map;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = DELETE_ACCESS; //Alias: delete
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_delete_dom_alias: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  sid_copy(&dom_sid, &alias_sid);
  sid_to_string(alias_sid_str, &dom_sid);
@@ -3354,12 +3858,23 @@
  struct group *grp;
  struct samr_info *info;
  PRIVILEGE_SET priv_set;
+ uint32 acc_granted;
+ uint32 acc_required;
 
  init_privilege(&priv_set);
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = DOMAIN_ACCESS_CREATE_GROUP;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_create_dom_group: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  if (!sid_equal(&dom_sid, &global_sam_sid))
   return NT_STATUS_ACCESS_DENIED;
@@ -3412,12 +3927,23 @@
  struct group *grp;
  struct samr_info *info;
  PRIVILEGE_SET priv_set;
+ uint32 acc_granted;
+ uint32  acc_required;
 
  init_privilege(&priv_set);
 
  /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = DOMAIN_ACCESS_CREATE_ALIAS;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_create_dom_alias: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  if (!sid_equal(&dom_sid, &global_sam_sid))
   return NT_STATUS_ACCESS_DENIED;
@@ -3471,9 +3997,20 @@
  uid_t *uid=NULL;
  int num_uids=0;
  GROUP_INFO_CTR *ctr;
+ uint32 acc_granted;
+ uint32 acc_required;
 
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = GROUP_ACCESS_LOOKUP_INFO;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_query_groupinfo: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
   return NT_STATUS_INVALID_HANDLE;
@@ -3518,9 +4055,20 @@
  DOM_SID group_sid;
  GROUP_MAP map;
  GROUP_INFO_CTR *ctr;
+ uint32 acc_granted;
+ uint32 acc_required;
 
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = GROUP_ACCESS_SET_INFO;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_set_groupinfo: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
   return NT_STATUS_NO_SUCH_GROUP;
@@ -3560,9 +4108,20 @@
  DOM_SID group_sid;
  GROUP_MAP map;
  ALIAS_INFO_CTR *ctr;
+ uint32 acc_granted;
+ uint32 acc_required;
 
- if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
+  
+ /*check if function is granted*/
+ acc_required = ALIAS_ACCESS_SET_INFO;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_samr_set_aliasinfo: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
 
  if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
   return NT_STATUS_NO_SUCH_GROUP;
@@ -3608,11 +4167,36 @@
  DOM_SID info_sid;
  GROUP_MAP map;
  struct samr_info *info;
+ SEC_DESC         *psd = NULL;
+ uint32            acc_granted;
+ uint32            acc_required;
+ uint32            des_access;
+ size_t            sd_size;
+ NTSTATUS          status;
  fstring sid_string;
 
- if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid)) 
+ if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
   return NT_STATUS_INVALID_HANDLE;
 
+ /*check if function is granted*/
+ acc_required = DOMAIN_ACCESS_OPEN_ACCOUNT;
+ if ((acc_granted & acc_required) != acc_required)
+ {
+  DEBUG(2,("_api_samr_open_group: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+      acc_granted, acc_required));
+  //return NT_STATUS_ACCESS_DENIED;
+ }
+ 
+ /*check if access can be granted as requested by client. */
+ samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
+ se_map_generic(&des_access,&grp_generic_mapping);
+ if(!se_access_check(psd,p->pipe_user.nt_user_token, des_access, &acc_granted, &status))
+ {
+  DEBUG(2,("_api_samr_open_group: ACCESS should be DENIED  (requested: %#010x)\n",
+      des_access));
+  //return r_u->status = status;    
+ }
+ 
  /* this should not be hard-coded like this */
  if (!sid_equal(&sid, &global_sam_sid))
   return NT_STATUS_ACCESS_DENIED;



More information about the samba-technical mailing list