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