--- ./samba-orig/source/rpc_server/srv_samr_nt.c	Fri Jun  7 17:06:18 2002
+++ ./samba/source/rpc_server/srv_samr_nt.c	Fri Jun  7 21:13:40 2002
@@ -51,11 +51,39 @@
 	/* 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;
 
 	TALLOC_CTX *mem_ctx;
 };
 
+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 *d_size);
+
+
+/*******************************************************************
+ Checks if access to a function can be granted
+********************************************************************/
+
+BOOL access_check_samr_function(uint32 acc_granted, uint32 acc_required, fstring debug)
+{
+	if ((acc_granted & acc_required) != acc_required) {
+		DEBUG(2,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
+			debug, acc_granted, acc_required));
+		/* If nt_user_token is confirmed to work correct, this *
+		 * can be changed to False otherwise it would possibly *
+		 * break access to SAM                                 */
+		return True;
+	}
+	return True;
+}
+
+
 /*******************************************************************
  Create a samr_info struct.
 ********************************************************************/
@@ -381,17 +409,37 @@
 
 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    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;
 
+	if (!access_check_samr_function(info->acc_granted, SAMR_ACCESS_OPEN_DOMAIN,"_samr_open_domain"))
+		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))
@@ -431,11 +479,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;
@@ -445,8 +572,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);
@@ -454,29 +579,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)
+	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)
+		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)
+	if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
 		return NT_STATUS_NO_MEMORY;
 
-	if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
+	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 ((*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;
 
@@ -488,6 +691,7 @@
 		return False;
 
 	*sid = info->sid;
+	*acc_granted = info->acc_granted;
 	return True;
 }
 
@@ -499,17 +703,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,get_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;
@@ -563,16 +803,21 @@
 
 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;
 	
 	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;
 
+	if (!access_check_samr_function(info->acc_granted,DOMAIN_ACCESS_ENUM_ACCOUNTS,"_samr_enum_dom_users"))
+		return NT_STATUS_ACCESS_DENIED;
+	
 	DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
 
 	become_root();
@@ -837,11 +1082,15 @@
 	DOMAIN_GRP *grp=NULL;
 	uint32 num_entries;
 	DOM_SID sid;
+	uint32 acc_granted;
 
 	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;
+		
+	if (!access_check_samr_function(acc_granted, DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
 
@@ -869,12 +1118,16 @@
 	fstring sid_str;
 	DOM_SID sid;
 	NTSTATUS status;
+	uint32  acc_granted;
 	
 	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;
 
+	if (!access_check_samr_function(acc_granted, DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))
+		return NT_STATUS_ACCESS_DENIED;
+	
 	sid_to_string(sid_str, &sid);
 	DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
 
@@ -1087,21 +1340,25 @@
 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;
 
 	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;
+	if (!access_check_samr_function(acc_granted, ALIAS_ACCESS_LOOKUP_INFO, "_samr_query_aliasinfo"))
+		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) {
@@ -1198,6 +1455,7 @@
 	int num_rids = q_u->num_names2;
 	DOM_SID pol_sid;
 	fstring sid_str;
+	uint32  acc_granted;
 
 	r_u->status = NT_STATUS_OK;
 
@@ -1206,7 +1464,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;
 	}
@@ -1353,13 +1611,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) {
@@ -1421,27 +1680,39 @@
 	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    des_access = q_u->access_mask;
+	size_t    sd_size;
 	BOOL ret;
 	NTSTATUS nt_status;
 
 	r_u->status = NT_STATUS_OK;
 
-	/* find the domain policy handle. */
-	if (!find_policy_by_hnd(p, &domain_pol, NULL))
+	/* find the domain policy handle and get domain SID / access bits in the domain policy. */
+	if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
 		return NT_STATUS_INVALID_HANDLE;
+	
+	if (!access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_user"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
 	}
 
-	/* Get the domain SID stored in the domain policy */
-	if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
-		return NT_STATUS_INVALID_HANDLE;
-
 	/* append the user's RID to it */
-	if(!sid_append_rid(&sid, q_u->user_rid))
+	if (!sid_append_rid(&sid, q_u->user_rid))
 		return NT_STATUS_NO_SUCH_USER;
+	
+	/* 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, &nt_status)) {
+		DEBUG(2,("_api_samr_open_user: ACCESS should be DENIED (requested: %#010x)\n",
+			 des_access));
+		/* return NT_STATUS_ACCESS_DENIED */
+	}
 
 	become_root();
 	ret=pdb_getsampwsid(sampass, &sid);
@@ -1454,9 +1725,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))
@@ -1727,9 +1999,10 @@
 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;
 	BOOL ret;
 
 	/*
@@ -1749,16 +2022,19 @@
 	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 (!access_check_samr_function(acc_granted, USER_ACCESS_GET_GROUPS, "_samr_query_usergroups"))
+		return NT_STATUS_ACCESS_DENIED;
 
-	if (!sid_check_is_in_our_domain(&info->sid))
+	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) {
@@ -1908,11 +2184,15 @@
 	BOOL ret;
 	NTSTATUS nt_status;
 	struct passwd *pw;
+	uint32 acc_granted;
 
-	/* 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;
 
+	if (!access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_USER, "_samr_create_user"))
+		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
@@ -1981,7 +2261,7 @@
 	else 
 		pstrcpy(add_script, lp_adduser_script());
 
-	if(*add_script) {
+	if (*add_script) {
   		int add_ret;
   		all_string_sub(add_script, "%u", account, sizeof(account));
   		add_ret = smbrun(add_script,NULL);
@@ -2027,14 +2307,10 @@
  		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) )) {
+	if (!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
 		pdb_free_sam(&sam_pass);
 		return NT_STATUS_NO_SUCH_USER;
 	}
@@ -2070,29 +2346,29 @@
 {
 	struct samr_info *info = NULL;
 
-    /* Access check */
+	/* Access check */
 
-    if (!pipe_access_check(p)) {
-	    DEBUG(3, ("access denied to samr_connect_anon\n"));
-	    r_u->status = NT_STATUS_ACCESS_DENIED;
-	    return r_u->status;
-    }
+	if (!pipe_access_check(p)) {
+		DEBUG(3, ("access denied to samr_connect_anon\n"));
+		r_u->status = NT_STATUS_ACCESS_DENIED;
+		return r_u->status;
+	}
 
-    /* set up the SAMR connect_anon response */
+	/* set up the SAMR connect_anon response */
 
-    r_u->status = NT_STATUS_OK;
+	r_u->status = NT_STATUS_OK;
 
-    /* associate the user's SID with the new handle. */
-    if ((info = get_samr_info_by_sid(NULL)) == NULL)
-        return NT_STATUS_NO_MEMORY;
-
-    info->status = q_u->unknown_0;
-
-    /* get a (unique) handle.  open a policy on it. */
-    if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
-        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	/* associate the user's SID with the new handle. */
+	if ((info = get_samr_info_by_sid(NULL)) == NULL)
+		return NT_STATUS_NO_MEMORY;
 
-    return r_u->status;
+	info->status = q_u->unknown_0;
+
+	/* get a (unique) handle.  open a policy on it. */
+	if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+	return r_u->status;
 }
 
 /*******************************************************************
@@ -2102,32 +2378,47 @@
 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
 {
 	struct samr_info *info = NULL;
+	SEC_DESC *psd = NULL;
+	uint32    acc_granted;
+	uint32    des_access = q_u->access_mask;
+	size_t    sd_size;
+	NTSTATUS  nt_status;
 
-    DEBUG(5,("_samr_connect: %d\n", __LINE__));
 
-    /* Access check */
+	DEBUG(5,("_samr_connect: %d\n", __LINE__));
 
-    if (!pipe_access_check(p)) {
-	    DEBUG(3, ("access denied to samr_connect\n"));
-	    r_u->status = NT_STATUS_ACCESS_DENIED;
-	    return r_u->status;
-    }
+	/* Access check */
 
-    r_u->status = NT_STATUS_OK;
+	if (!pipe_access_check(p)) {
+		DEBUG(3, ("access denied to samr_connect\n"));
+		r_u->status = NT_STATUS_ACCESS_DENIED;
+		return r_u->status;
+	}
+
+	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, &nt_status)) {
+		DEBUG(2, ("_samr_connect: ACCESS should be DENIED (requested: %#10x)\n",
+			des_access));
+		/* return NT_STATUS_ACCESS_DENIED */
+	}
+
+	r_u->status = NT_STATUS_OK;
 
-    /* associate the user's SID with the new handle. */
+	/* associate the user's SID and access granted with the new handle. */
 	if ((info = get_samr_info_by_sid(NULL)) == NULL)
-        return NT_STATUS_NO_MEMORY;
+		return NT_STATUS_NO_MEMORY;
 
-    info->status = q_u->access_mask;
+	info->acc_granted = acc_granted;
+	info->status = q_u->access_mask;
 
-    /* get a (unique) handle.  open a policy on it. */
-    if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
-        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	/* get a (unique) handle.  open a policy on it. */
+	if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 
-    DEBUG(5,("_samr_connect: %d\n", __LINE__));
+	DEBUG(5,("_samr_connect: %d\n", __LINE__));
 
-    return r_u->status;
+	return r_u->status;
 }
 
 /**********************************************************************
@@ -2136,14 +2427,19 @@
 
 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;
 
 	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;
 
+	if (!access_check_samr_function(info->acc_granted, SAMR_ACCESS_OPEN_DOMAIN, "_samr_lookup_domain"))
+		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);
 
 	ZERO_STRUCT(sid);
@@ -2203,11 +2499,19 @@
 
 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 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;
+	
+	if (!access_check_samr_function(info->acc_granted, SAMR_ACCESS_ENUM_DOMAINS, "_samr_enum_domains"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	switch (lp_server_role()) {
 	case ROLE_DOMAIN_PDC:
@@ -2240,21 +2544,34 @@
 	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    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;
+		
+	if (!access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_alias"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	/* append the alias' RID to it */
-	if(!sid_append_rid(&sid, alias_rid))
+	if (!sid_append_rid(&sid, alias_rid))
 		return NT_STATUS_NO_SUCH_USER;
+		
+	/*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 !!!
@@ -2537,15 +2854,21 @@
 	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;
-
+	
+	acc_required = USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES; /* This is probably wrong */	
+	if (!access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))
+		return NT_STATUS_ACCESS_DENIED;
+		
 	DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
 
 	if (ctr == NULL) {
@@ -2615,14 +2938,20 @@
 	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;
+	
+	acc_required = USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES; /* This is probably wrong */	
+	if (!access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
 
@@ -2753,11 +3082,15 @@
 
 	SAM_ACCOUNT *sam_user = NULL;
 	BOOL check;
+	uint32 acc_granted;
 
 	/* 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;
-
+	
+	if (!access_check_samr_function(acc_granted, ALIAS_ACCESS_GET_MEMBERS, "_samr_query_aliasmem"))
+		return NT_STATUS_ACCESS_DENIED;
+		
 	sid_copy(&als_sid, &alias_sid);
 	sid_to_string(alias_sid_str, &alias_sid);
 	sid_split_rid(&alias_sid, &alias_rid);
@@ -2849,12 +3182,15 @@
 
 	SAM_ACCOUNT *sam_user = NULL;
 	BOOL check;
-
+	uint32 acc_granted;
 
 	/* 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;
-
+		
+	if (!access_check_samr_function(acc_granted, GROUP_ACCESS_GET_MEMBERS, "_samr_query_groupmem"))
+		return NT_STATUS_ACCESS_DENIED;
+		
 	/* todo: change to use sid_compare_front */
 
 	sid_split_rid(&group_sid, &group_rid);
@@ -2937,11 +3273,15 @@
 	NTSTATUS ret;
 	SAM_ACCOUNT *sam_user = NULL;
 	BOOL check;
+	uint32 acc_granted;
 
 	/* 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;
-
+	
+	if (!access_check_samr_function(acc_granted, ALIAS_ACCESS_ADD_MEMBER, "_samr_add_aliasmem"))
+		return NT_STATUS_ACCESS_DENIED;
+		
 	sid_to_string(alias_sid_str, &alias_sid);
 	DEBUG(10, ("sid is %s\n", alias_sid_str));
 
@@ -3020,11 +3360,15 @@
 	fstring grp_name;
 	GROUP_MAP map;
 	SAM_ACCOUNT *sam_pass=NULL;
+	uint32 acc_granted;
 
 	/* 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;
-
+	
+	if (!access_check_samr_function(acc_granted, ALIAS_ACCESS_REMOVE_MEMBER, "_samr_del_aliasmem"))
+		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));
 
@@ -3086,11 +3430,15 @@
 	NTSTATUS ret;
 	SAM_ACCOUNT *sam_user;
 	BOOL check;
+	uint32 acc_granted;
 
 	/* 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;
-
+	
+	if (!access_check_samr_function(acc_granted, GROUP_ACCESS_ADD_MEMBER, "_samr_add_groupmem"))
+		return NT_STATUS_ACCESS_DENIED;
+		
 	sid_to_string(group_sid_str, &group_sid);
 	DEBUG(10, ("sid is %s\n", group_sid_str));
 
@@ -3167,6 +3515,7 @@
 	GROUP_MAP map;
 	fstring grp_name;
 	struct group *grp;
+	uint32 acc_granted;
 
 	/*
 	 * delete the group member named q_u->rid
@@ -3175,16 +3524,19 @@
 	 */
 
 	/* 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;
-
-	if(!sid_check_is_in_our_domain(&group_sid))
+	
+	if (!access_check_samr_function(acc_granted, GROUP_ACCESS_REMOVE_MEMBER, "_samr_del_groupmem"))
+		return NT_STATUS_ACCESS_DENIED;
+		
+	if (!sid_check_is_in_our_domain(&group_sid))
 		return NT_STATUS_NO_SUCH_GROUP;
 
 	sid_copy(&user_sid, get_global_sam_sid());
 	sid_append_rid(&user_sid, q_u->rid);
 
-	if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
+	if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
 		return NT_STATUS_NO_SUCH_GROUP;
 
 	if ((grp=getgrgid(map.gid)) == NULL)
@@ -3195,14 +3547,14 @@
 
 	/* check if the user exists before trying to remove it from the group */
 	pdb_init_sam(&sam_pass);
-	if(!pdb_getsampwsid(sam_pass, &user_sid)) {
+	if (!pdb_getsampwsid(sam_pass, &user_sid)) {
 		DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
 		pdb_free_sam(&sam_pass);
 		return NT_STATUS_NO_SUCH_USER;
 	}
 
 	/* if the user is not in the group */
-	if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
+	if (!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
 		pdb_free_sam(&sam_pass);
 		return NT_STATUS_MEMBER_NOT_IN_GROUP;
 	}
@@ -3210,7 +3562,7 @@
 	smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
 
 	/* check if the user has been removed then ... */
-	if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
+	if (user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
 		pdb_free_sam(&sam_pass);
 		return NT_STATUS_ACCESS_DENIED;		/* don't know what to reply else */
 	}
@@ -3246,12 +3598,16 @@
 {
 	DOM_SID user_sid;
 	SAM_ACCOUNT *sam_pass=NULL;
+	uint32 acc_granted;
 
 	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;
+		
+	if (!access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_user"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	if (!sid_check_is_in_our_domain(&user_sid))
 		return NT_STATUS_CANNOT_DELETE;
@@ -3300,12 +3656,16 @@
 	gid_t gid;
 	struct group *grp;
 	GROUP_MAP map;
+	uint32 acc_granted;
 
 	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;
+		
+	if (!access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_group"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	sid_copy(&dom_sid, &group_sid);
 	sid_to_string(group_sid_str, &dom_sid);
@@ -3357,12 +3717,16 @@
 	gid_t gid;
 	struct group *grp;
 	GROUP_MAP map;
+	uint32 acc_granted;
 
 	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;
+	
+	if (!access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_alias"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	sid_copy(&dom_sid, &alias_sid);
 	sid_to_string(alias_sid_str, &dom_sid);
@@ -3414,12 +3778,16 @@
 	struct group *grp;
 	struct samr_info *info;
 	PRIVILEGE_SET priv_set;
+	uint32 acc_granted;
 
 	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;
+	
+	if (!access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_GROUP, "_samr_create_dom_group"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	if (!sid_equal(&dom_sid, get_global_sam_sid()))
 		return NT_STATUS_ACCESS_DENIED;
@@ -3472,12 +3840,16 @@
 	struct group *grp;
 	struct samr_info *info;
 	PRIVILEGE_SET priv_set;
+	uint32 acc_granted;
 
 	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;
+		
+	if (!access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_ALIAS, "_samr_create_alias"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	if (!sid_equal(&dom_sid, get_global_sam_sid()))
 		return NT_STATUS_ACCESS_DENIED;
@@ -3531,9 +3903,13 @@
 	uid_t *uid=NULL;
 	int num_uids=0;
 	GROUP_INFO_CTR *ctr;
+	uint32 acc_granted;
 
-	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;
+	
+	if (!access_check_samr_function(acc_granted, GROUP_ACCESS_LOOKUP_INFO, "_samr_query_groupinfo"))
+		return NT_STATUS_ACCESS_DENIED;
 
 	if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
 		return NT_STATUS_INVALID_HANDLE;
@@ -3578,10 +3954,14 @@
 	DOM_SID group_sid;
 	GROUP_MAP map;
 	GROUP_INFO_CTR *ctr;
+	uint32 acc_granted;
 
-	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;
-
+	
+	if (!access_check_samr_function(acc_granted, GROUP_ACCESS_SET_INFO, "_samr_set_groupinfo"))
+		return NT_STATUS_ACCESS_DENIED;
+		
 	if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
 		return NT_STATUS_NO_SUCH_GROUP;
 	
@@ -3620,10 +4000,14 @@
 	DOM_SID group_sid;
 	GROUP_MAP map;
 	ALIAS_INFO_CTR *ctr;
+	uint32 acc_granted;
 
-	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;
-
+	
+	if (!access_check_samr_function(acc_granted, ALIAS_ACCESS_SET_INFO, "_samr_set_aliasinfo"))
+		return NT_STATUS_ACCESS_DENIED;
+		
 	if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
 		return NT_STATUS_NO_SUCH_GROUP;
 	
@@ -3679,10 +4063,27 @@
 	DOM_SID info_sid;
 	GROUP_MAP map;
 	struct samr_info *info;
+	SEC_DESC         *psd = NULL;
+	uint32            acc_granted;
+	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;
+	
+	if (!access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_group"))
+		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, get_global_sam_sid()))
