Access control to SAM / _samr_query_sec_obj

Kai Krueger kai at kruegernetz.de
Fri May 31 14:20:02 GMT 2002


Hi,

currently, as far as I can see, the access control to the SAM database is
only based upon file access to the db-files. On normal installations
therefore only the root user can change, delete or add things instead of the
entire administrators group. As this is IMHO rather "unhelpfull", especially
if you are trying to administer your samba-server from windows machines, I'm
thinking about implementing a more "NT-like" access control to the SAM-db.
Is there currently anybody else working in that region?

I've started off with implementing default Security Descriptors for the
global SAM object, the domain object and the alias objects (only SD for user
objects were available till now), which are needed in the later to come
se_access_check()s of the open/connect RPCs. These default SDs are based
upon the SDs I received from my Win2k pro workstation. I don't have access
to a Windows PDC, so I couldn't do it for global domain groups. :(
The new _samr_query_sec_obj() can destinguish between the domain SID, SID
S-0-0 that seems to represent the SAM-object and SIDs with appended RID.
However I don't know how to find out if those SIDs represent Users, Groups,
or Alliases, so SDs for useres are still always created in this case instead
of the correct ones. Does anybody know an easy way to figure out which is
correct?


Any comments or improvements are appreciated

Kai




--- ./samba/source/rpc_server/srv_samr_nt.c Sun May 26 21:11:52 2002
+++ ./samba/source/rpc_server/srv_samr_nt.c Fri May 31 19:51:43 2002
@@ -402,11 +402,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, 0x20031);
+ 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, 0xf003f);
+ 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, 0x20385);
+ 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, 0xf07ff);
+ 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 +495,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,23 +502,62 @@
  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, 0x2035b);
  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, 0xf07ff);
  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);

+ //extended access for the user
  init_sec_access(&mask,0x20044);
  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_ali_obj_sd
+ ********************************************************************/
+
+static NTSTATUS samr_make_ali_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;
+ 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, 0x2000c);
+ 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, 0xf001f);
+ 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;
@@ -470,6 +586,9 @@
 {
  DOM_SID pol_sid;
  fstring str_sid;
+ SEC_DESC * psd = NULL;
+ size_t sd_size;
+ int rid;

  r_u->status = NT_STATUS_OK;

@@ -480,7 +599,38 @@

  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;



More information about the samba-technical mailing list