Index: trunk/lib/winsec.c
===================================================================
--- trunk/lib/winsec.c	(revision 133)
+++ trunk/lib/winsec.c	(revision 134)
@@ -28,399 +28,312 @@
 
 
-/*******************************************************************
- * Parses a SEC_DESC structure.
- *******************************************************************/
-bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
-{
-  uint32 old_offset;
-  uint32 max_offset = 0; /* after we're done, move offset to end */
-  uint32 tmp_offset = 0;
-
-  SEC_DESC *psd;
-
-  if (ppsd == NULL || ps == NULL)
-    return false;
-
-  psd = *ppsd;
-  if (psd == NULL) 
-  {
-    if((psd = (SEC_DESC*)zalloc(sizeof(SEC_DESC))) == NULL)
-      return false;
-    *ppsd = psd;
-  }
-
-  depth++;
-
-  /* start of security descriptor stored for back-calc offset purposes */
-  old_offset = ps->data_offset;
-
-  if(!prs_uint16("revision ", ps, depth, &psd->revision)
-     || !prs_uint16("type     ", ps, depth, &psd->type))
-  {
-    free(psd);
-    *ppsd = NULL;
-    return false;
-  }
-
-  if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid)
-     || !prs_uint32("off_grp_sid  ", ps, depth, &psd->off_grp_sid)
-     || !prs_uint32("off_sacl     ", ps, depth, &psd->off_sacl)
-     || !prs_uint32("off_dacl     ", ps, depth, &psd->off_dacl))
-  {
-    free(psd);
-    *ppsd = NULL;    
-    return false;
-  }
-  max_offset = MAX(max_offset, ps->data_offset);
-
-  if (psd->off_owner_sid != 0) 
-  {
-    tmp_offset = ps->data_offset;
-    if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
-    {
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-
-    /* reading */
-    if((psd->owner_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
-    {
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-
-    if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
-    {
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-
-    max_offset = MAX(max_offset, ps->data_offset);
-
-    if (!prs_set_offset(ps,tmp_offset))
-    {
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-  }
-
-  if (psd->off_grp_sid != 0) 
-  {
-    tmp_offset = ps->data_offset;
-    if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
-    {
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-
-    /* reading */
-    if((psd->grp_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
-    {
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-
-    if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
-    {
-      free(psd->grp_sid);
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-			
-    max_offset = MAX(max_offset, ps->data_offset);
-
-    if (!prs_set_offset(ps,tmp_offset))
-    {
-      free(psd->grp_sid);
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-  }
-
-  if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) 
-  {
-    tmp_offset = ps->data_offset;
-    if(!prs_set_offset(ps, old_offset + psd->off_sacl)
-       || !sec_io_acl("sacl", &psd->sacl, ps, depth))
-    {
-      free(psd->grp_sid);
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-    max_offset = MAX(max_offset, ps->data_offset);
-    if (!prs_set_offset(ps,tmp_offset))
-    {
-      free(psd->grp_sid);
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-  }
-
-  if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) 
-  {
-    tmp_offset = ps->data_offset;
-    if(!prs_set_offset(ps, old_offset + psd->off_dacl)
-       || !sec_io_acl("dacl", &psd->dacl, ps, depth))
-    {
-      free(psd->grp_sid);
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-    max_offset = MAX(max_offset, ps->data_offset);
-    if (!prs_set_offset(ps,tmp_offset))
-    {
-      free(psd->grp_sid);
-      free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-  }
-
-  if(!prs_set_offset(ps, max_offset))
-  {
-    free(psd->grp_sid);
-    free(psd->owner_sid);
-    free(psd);
-    *ppsd = NULL;
-    return false;
-  }
-
-  return true;
-}
-
-
-/*******************************************************************
- Reads or writes a DOM_SID structure.
-********************************************************************/
-bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
-{
-  int i;
-
-  if (sid == NULL)
-    return false;
-  depth++;
-
-  if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
-    return false;
-
-  if(!prs_uint8 ("num_auths  ", ps, depth, &sid->num_auths))
-    return false;
-
-  for (i = 0; i < 6; i++)
-  {
-    fstring tmp;
-    snprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
-    if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
-      return false;
-  }
-
-  /* oops! XXXX should really issue a warning here... */
-  if (sid->num_auths > MAXSUBAUTHS)
-    sid->num_auths = MAXSUBAUTHS;
-
-  if(!prs_uint32s("sub_auths ", ps, depth, 
-		  sid->sub_auths, sid->num_auths))
-  { return false; }
-
-  return true;
-}
-
-
-
-/*******************************************************************
- Reads or writes a SEC_ACCESS structure.
-********************************************************************/
-bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
-{
-  if (t == NULL)
-    return false;
-
-  depth++;
-	
-  if(!prs_uint32("mask", ps, depth, &t->mask))
-    return false;
-
-  return true;
-}
-
-
-/*******************************************************************
- Reads or writes a SEC_ACE structure.
-********************************************************************/
-bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
-{
-  uint32 old_offset;
-  uint32 offset_ace_size;
-
-  if (psa == NULL)
-    return false;
-
-  depth++;
-	
-  old_offset = ps->data_offset;
-
-  if(!prs_uint8("type ", ps, depth, &psa->type))
-    return false;
-
-  if(!prs_uint8("flags", ps, depth, &psa->flags))
-    return false;
-
-  if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
-    return false;
-
-  if(!sec_io_access("info ", &psa->info, ps, depth))
-    return false;
-
-  /* check whether object access is present */
-  if (!sec_ace_object(psa->type)) 
-  {
-    if (!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
-      return false;
-  } 
-  else 
-  {
-    if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
-      return false;
-
-    if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
-      if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
-	return false;
-
-    if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
-      if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
-	return false;
-
-    if(!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
-      return false;
-  }
-
-  if(!prs_uint16_post("size ", ps, depth, &psa->size, 
-		      offset_ace_size, old_offset))
-  { return false; }
-
-  return true;
-}
-
-
-/*******************************************************************
- Reads or writes a SEC_ACL structure.  
-
- First of the xx_io_xx functions that allocates its data structures
- for you as it reads them.
-********************************************************************/
-bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
-{
-  unsigned int i;
-  uint32 old_offset;
-  uint32 offset_acl_size;
-  SEC_ACL* psa;
+/******************************************************************************
+ * Parses a WINSEC_DESC structure and substructures.
+ ******************************************************************************/
+WINSEC_DESC* winsec_parse_desc(const uint8_t* buf, uint32_t buf_len)
+{
+  WINSEC_DESC* ret_val;
+
+  if (buf == NULL || buf_len <  WINSEC_DESC_HEADER_SIZE)
+    return NULL;
+
+  if((ret_val = (WINSEC_DESC*)zalloc(sizeof(WINSEC_DESC))) == NULL)
+    return NULL;
+
+  ret_val->revision = buf[0];
+  ret_val->sbz1 = buf[1];
+  ret_val->control = SVAL(buf, 0x2);
+
+  if(!(ret_val->control & WINSEC_DESC_SELF_RELATIVE))
+    fprintf(stderr, "DEBUG: NOT self-relative!\n");
+
+  ret_val->off_owner_sid = IVAL(buf, 0x4);
+  ret_val->off_grp_sid = IVAL(buf, 0x8);
+  ret_val->off_sacl = IVAL(buf, 0xC);
+  ret_val->off_dacl = IVAL(buf, 0x10);
+
+  /* A basic sanity check to ensure our offsets are within our buffer.
+   * Additional length checking is done in secondary parsing functions.
+   */
+  if((ret_val->off_owner_sid >= buf_len)
+     || (ret_val->off_grp_sid >= buf_len)
+     || (ret_val->off_sacl >= buf_len)
+     || (ret_val->off_dacl >= buf_len))
+  {
+    free(ret_val);
+    return NULL;
+  }
+
+  if(ret_val->off_owner_sid != 0)
+  {
+    ret_val->owner_sid = winsec_parse_dom_sid(buf + ret_val->off_owner_sid, 
+					      buf_len - ret_val->off_owner_sid);
+    if(ret_val->owner_sid == NULL)
+    {
+      free(ret_val);
+      return NULL;
+    }
+  }
+
+  if (ret_val->off_grp_sid != 0) 
+  {
+    ret_val->grp_sid = winsec_parse_dom_sid(buf + ret_val->off_grp_sid, 
+					    buf_len - ret_val->off_grp_sid);
+    if(ret_val->grp_sid == NULL)
+    {
+      if(ret_val->owner_sid != NULL)
+	free(ret_val->owner_sid);
+      free(ret_val);
+      return NULL;
+    }
+  }
+
+  if ((ret_val->control & WINSEC_DESC_SACL_PRESENT) && ret_val->off_sacl)
+  {
+    ret_val->sacl = winsec_parse_acl(buf + ret_val->off_sacl,
+				     buf_len - ret_val->off_sacl);
+    if(ret_val->sacl == NULL)
+    {
+      if(ret_val->owner_sid != NULL)
+	free(ret_val->owner_sid);
+      if(ret_val->grp_sid != NULL)
+	free(ret_val->grp_sid);
+      free(ret_val);
+      return NULL;
+    }
+  }
+
+  if ((ret_val->control & WINSEC_DESC_DACL_PRESENT) && ret_val->off_dacl != 0) 
+  {
+    ret_val->dacl = winsec_parse_acl(buf + ret_val->off_dacl,
+				     buf_len - ret_val->off_dacl);
+    if(ret_val->dacl == NULL)
+    {
+      if(ret_val->owner_sid != NULL)
+	free(ret_val->owner_sid);
+      if(ret_val->grp_sid != NULL)
+	free(ret_val->grp_sid);
+      if(ret_val->sacl != NULL)
+	free(ret_val->sacl);
+      free(ret_val);
+      return NULL;
+    }
+  }
+
+  return ret_val;
+}
+
+
+/******************************************************************************
+ * Parses a WINSEC_ACL structure and all substructures.
+ ******************************************************************************/
+WINSEC_ACL* winsec_parse_acl(const uint8_t* buf, uint32_t buf_len)
+{
+  uint32_t i, offset;
+  WINSEC_ACL* ret_val;
 
   /*
    * Note that the size is always a multiple of 4 bytes due to the
-   * nature of the data structure.  Therefore the prs_align() calls
-   * have been removed as they through us off when doing two-layer
-   * marshalling such as in the printing code (RPC_BUFFER).  --jerry
+   * nature of the data structure.
    */
-
-  if (ppsa == NULL || ps == NULL)
-    return false;
-
-  psa = *ppsa;
-
-  if(psa == NULL) 
-  {
-    /*
-     * This is a read and we must allocate the stuct to read into.
-     */
-    if((psa = (SEC_ACL*)zalloc(sizeof(SEC_ACL))) == NULL)
-      return false;
-    *ppsa = psa;
-  }
-
-  depth++;	
-  old_offset = ps->data_offset;
-
-  if(!prs_uint16("revision", ps, depth, &psa->revision)
-     || !prs_uint16_pre("size     ", ps, depth, &psa->size, &offset_acl_size)
-     || !prs_uint32("num_aces ", ps, depth, &psa->num_aces))
-  {
-    free(psa);
-    *ppsa = NULL;
-    return false;
-  }
-
-  /*
-   * Even if the num_aces is zero, allocate memory as there's a difference
+  if (buf == NULL || buf_len < 8)
+    return NULL;
+
+  if((ret_val = (WINSEC_ACL*)zalloc(sizeof(WINSEC_ACL))) == NULL)
+    return NULL;
+  
+  ret_val->revision = SVAL(buf, 0x0);
+  ret_val->size     = SVAL(buf, 0x2);
+  ret_val->num_aces = IVAL(buf, 0x4);
+
+  /* The num_aces can be at most around 4k because anything greater
+   * wouldn't fit in the 16 bit size even if every ace was as small as
+   * possible. 
+   */
+  if((ret_val->size > buf_len) || (ret_val->num_aces > 4095))
+  {
+    free(ret_val);
+    return NULL;
+  }
+
+  /* Even if the num_aces is zero, allocate memory as there's a difference
    * between a non-present DACL (allow all access) and a DACL with no ACE's
    * (allow no access).
    */
-  if((psa->ace = (SEC_ACE*)zcalloc(sizeof(SEC_ACE), psa->num_aces+1)) == NULL)
-  {
-    free(psa);
-    *ppsa = NULL;
-    return false;
-  }
-
-  for (i = 0; i < psa->num_aces; i++) 
-  {
-    fstring tmp;
-    snprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
-    if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
-    {
-      free(psa);
-      *ppsa = NULL;
-      return false;
-    }
-  }
-
-  if(!prs_uint16_post("size     ", ps, depth, &psa->size, 
-		      offset_acl_size, old_offset))
-  { 
-    free(psa);
-    *ppsa = NULL;
-    return false; 
-  }
-
-  return true;
-}
-
-
-/*****************************************************************
- Calculates size of a sid.
-*****************************************************************/  
-size_t sid_size(const DOM_SID *sid)
+  if((ret_val->aces = (WINSEC_ACE**)zcalloc(sizeof(WINSEC_ACE*),
+					   ret_val->num_aces+1)) == NULL)
+  {
+    free(ret_val);
+    return NULL;
+  }
+
+  offset = 8;
+  for(i=0; i < ret_val->num_aces; i++)
+  {
+    ret_val->aces[i] = winsec_parse_ace(buf+offset, buf_len-offset);
+    if(ret_val->aces[i] == NULL)
+    {
+      free(ret_val->aces);
+      free(ret_val);
+      return NULL;
+    }
+
+    offset += ret_val->aces[i]->size;
+    if(offset > buf_len)
+    {
+      free(ret_val->aces);
+      free(ret_val);
+      return NULL;
+    }
+  }
+
+  return ret_val;
+}
+
+
+/******************************************************************************
+ * Parses a WINSEC_ACE structure and all substructures.
+ ******************************************************************************/
+WINSEC_ACE* winsec_parse_ace(const uint8_t* buf, uint32_t buf_len)
+{
+  uint32_t offset;
+  WINSEC_ACE* ret_val;
+
+  if(buf == NULL || buf_len < WINSEC_ACE_MIN_SIZE)
+    return NULL;
+
+  if((ret_val = (WINSEC_ACE*)zalloc(sizeof(WINSEC_ACE))) == NULL)
+    return NULL;
+
+  ret_val->type = buf[0];
+  ret_val->flags = buf[1];
+  ret_val->size = SVAL(buf, 0x2);
+  ret_val->access_mask = IVAL(buf, 0x4);
+
+  offset = 0x8;
+
+  /* check whether object access is present */
+  if (winsec_ace_object(ret_val->type))
+  {
+    ret_val->obj_flags = IVAL(buf, offset);
+    offset += 4;
+
+    if(ret_val->obj_flags & WINSEC_ACE_OBJECT_PRESENT)
+    {
+      ret_val->obj_guid = winsec_parse_uuid(buf+offset, buf_len-offset);
+      if(ret_val->obj_guid == NULL)
+      {
+	free(ret_val);
+	return NULL;
+      }
+      offset += sizeof(WINSEC_UUID);
+    }
+
+    if(ret_val->obj_flags & WINSEC_ACE_OBJECT_INHERITED_PRESENT)
+    {
+      ret_val->inh_guid = winsec_parse_uuid(buf+offset, buf_len-offset);
+      if(ret_val->inh_guid == NULL)
+      {
+	if(ret_val->obj_guid != NULL)
+	  free(ret_val->obj_guid);
+	free(ret_val);
+	return NULL;
+      }
+      offset += sizeof(WINSEC_UUID);
+    }
+  }
+
+  ret_val->trustee = winsec_parse_dom_sid(buf+offset, buf_len-offset);
+  if(ret_val->trustee == NULL)
+  {
+    if(ret_val->obj_guid != NULL)
+      free(ret_val->obj_guid);
+    if(ret_val->inh_guid != NULL)
+      free(ret_val->inh_guid);
+    free(ret_val);
+	return NULL;
+  }
+  
+  return ret_val;
+}
+
+
+/******************************************************************************
+ * Parses a WINSEC_DOM_SID structure.
+ ******************************************************************************/
+WINSEC_DOM_SID* winsec_parse_dom_sid(const uint8_t* buf, uint32_t buf_len)
+{
+  uint32_t i;
+  WINSEC_DOM_SID* ret_val;
+
+  if(buf == NULL || buf_len < 8)
+    return NULL;
+
+  if((ret_val = (WINSEC_DOM_SID*)zalloc(sizeof(WINSEC_DOM_SID))) == NULL)
+    return NULL;
+
+  ret_val->sid_rev_num = buf[0];
+  ret_val->num_auths = buf[1];
+  memcpy(ret_val->id_auth, buf+2, 6);
+
+  /* XXX: should really issue a warning here... */
+  if (ret_val->num_auths > WINSEC_MAX_SUBAUTHS)
+    ret_val->num_auths = WINSEC_MAX_SUBAUTHS;
+
+  if(buf_len < ret_val->num_auths*sizeof(uint32_t)+8)
+  {
+    free(ret_val);
+    return NULL;
+  }
+  
+  for(i=0; i < ret_val->num_auths; i++)
+    ret_val->sub_auths[i] = IVAL(buf, 8+i*sizeof(uint32_t));
+
+  return ret_val;
+}
+
+
+/******************************************************************************
+ * Parses a WINSEC_UUID struct.
+ ******************************************************************************/
+WINSEC_UUID* winsec_parse_uuid(const uint8_t* buf, uint32_t buf_len)
+{
+  WINSEC_UUID* ret_val;
+
+  if(buf == NULL || buf_len < sizeof(WINSEC_UUID))
+    return false;
+
+  if((ret_val = (WINSEC_UUID*)zalloc(sizeof(WINSEC_UUID))) == NULL)
+    return NULL;
+  
+  ret_val->time_low = IVAL(buf, 0x0);
+  ret_val->time_mid = SVAL(buf, 0x4);
+  ret_val->time_hi_and_version = SVAL(buf, 0x6);
+  
+  memcpy(ret_val->clock_seq, buf+0x8, 2);
+  memcpy(ret_val->node, buf+0xB, 6);
+
+  return ret_val;
+}
+
+
+/******************************************************************************
+ * Calculates the size of a SID.
+ ******************************************************************************/
+/*size_t sid_size(const WINSEC_DOM_SID *sid)*/
+size_t winsec_sid_size(const WINSEC_DOM_SID* sid)
 {
   if (sid == NULL)
     return 0;
 
-  return sid->num_auths * sizeof(uint32) + 8;
-}
-
-
-/*****************************************************************
- Compare the auth portion of two sids.
-*****************************************************************/  
-int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
+  return sid->num_auths * sizeof(uint32_t) + 8;
+}
+
+
+/******************************************************************************
+ * Compare the auth portion of two SIDs.
+ ******************************************************************************/
+/*int sid_compare_auth(const WINSEC_DOM_SID *sid1, const WINSEC_DOM_SID *sid2)*/
+int winsec_sid_compare_auth(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2)
 {
   int i;
@@ -444,8 +357,9 @@
 
 
-/*****************************************************************
- Compare two sids.
-*****************************************************************/  
-int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
+/******************************************************************************
+ * Compare two SIDs.
+ ******************************************************************************/
+/*int sid_compare(const WINSEC_DOM_SID *sid1, const WINSEC_DOM_SID *sid2)*/
+int winsec_sid_compare(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2)
 {
   int i;
@@ -466,38 +380,64 @@
       return sid1->sub_auths[i] - sid2->sub_auths[i];
 
-  return sid_compare_auth(sid1, sid2);
-}
-
-
-/*****************************************************************
- Compare two sids.
-*****************************************************************/  
-bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
-{
-  return sid_compare(sid1, sid2) == 0;
-}
-
-
-
-/*******************************************************************
- Check if ACE has OBJECT type.
-********************************************************************/
-bool sec_ace_object(uint8 type)
-{
-  if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
-      type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
-      type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
-      type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
+  return winsec_sid_compare_auth(sid1, sid2);
+}
+
+
+/******************************************************************************
+ * Compare two SIDs.
+ ******************************************************************************/
+bool winsec_sid_equal(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2)
+{
+  return winsec_sid_compare(sid1, sid2) == 0;
+}
+
+
+/******************************************************************************
+ * Compares two WINSEC_DESC structures.
+ ******************************************************************************/
+bool winsec_desc_equal(WINSEC_DESC* s1, WINSEC_DESC* s2)
+{
+  /* Trivial cases */
+  if (!s1 && !s2)
     return true;
-  }
-  return false;
-}
-
-
-/*******************************************************************
- Compares two SEC_ACE structures
-********************************************************************/
-bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
-{
+  if (!s1 || !s2)
+    return false;
+
+  /* Check top level stuff */
+  if (s1->revision != s2->revision)
+    return false;
+
+  if (s1->control != s2->control)
+    return false;
+
+  /* Check owner and group */
+  if (!winsec_sid_equal(s1->owner_sid, s2->owner_sid))
+    return false;
+
+  if (!winsec_sid_equal(s1->grp_sid, s2->grp_sid)) 
+    return false;
+
+  /* Check ACLs present in one but not the other */
+  if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
+      (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) 
+  { return false; }
+
+  /* Sigh - we have to do it the hard way by iterating over all
+     the ACEs in the ACLs */
+  if(!winsec_acl_equal(s1->dacl, s2->dacl) || !winsec_acl_equal(s1->sacl, s2->sacl)) 
+    return false;
+
+  return true;
+}
+
+
+
+/******************************************************************************
+ * Compares two WINSEC_ACL structures.
+ ******************************************************************************/
+bool winsec_acl_equal(WINSEC_ACL* s1, WINSEC_ACL* s2)
+{
+  unsigned int i, j;
+
   /* Trivial cases */
   if (!s1 && !s2) 
@@ -507,11 +447,29 @@
 
   /* Check top level stuff */
-  if (s1->type != s2->type || s1->flags != s2->flags ||
-      s1->info.mask != s2->info.mask) 
-  { return false; }
-
-  /* Check SID */
-  if (!sid_equal(&s1->trustee, &s2->trustee))
-    return false;
+  if (s1->revision != s2->revision)
+    return false;
+
+  if (s1->num_aces != s2->num_aces)
+    return false;
+
+  /* The ACEs could be in any order so check each ACE in s1 against 
+     each ACE in s2. */
+
+  for (i = 0; i < s1->num_aces; i++)
+  {
+    bool found = false;
+
+    for (j = 0; j < s2->num_aces; j++) 
+    {
+      if (winsec_ace_equal(s1->aces[i], s2->aces[j])) 
+      {
+	found = true;
+	break;
+      }
+    }
+
+    if (!found)
+      return false;
+  }
 
   return true;
@@ -519,11 +477,9 @@
 
 
-/*******************************************************************
- Compares two SEC_ACL structures
-********************************************************************/
-bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
-{
-  unsigned int i, j;
-
+/******************************************************************************
+ * Compares two WINSEC_ACE structures.
+ ******************************************************************************/
+bool winsec_ace_equal(WINSEC_ACE* s1, WINSEC_ACE* s2)
+{
   /* Trivial cases */
   if (!s1 && !s2) 
@@ -533,29 +489,11 @@
 
   /* Check top level stuff */
-  if (s1->revision != s2->revision)
-    return false;
-
-  if (s1->num_aces != s2->num_aces)
-    return false;
-
-  /* The ACEs could be in any order so check each ACE in s1 against 
-     each ACE in s2. */
-
-  for (i = 0; i < s1->num_aces; i++) 
-  {
-    bool found = false;
-
-    for (j = 0; j < s2->num_aces; j++) 
-    {
-      if (sec_ace_equal(&s1->ace[i], &s2->ace[j])) 
-      {
-	found = true;
-	break;
-      }
-    }
-
-    if (!found)
-      return false;
-  }
+  if (s1->type != s2->type || s1->flags != s2->flags ||
+      s1->access_mask != s2->access_mask)
+  { return false; }
+
+  /* Check SID */
+  if (!winsec_sid_equal(s1->trustee, s2->trustee))
+    return false;
 
   return true;
@@ -563,39 +501,15 @@
 
 
-/*******************************************************************
- Compares two SEC_DESC structures
-********************************************************************/
-bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
-{
-  /* Trivial cases */
-  if (!s1 && !s2)
-    return true;
-  if (!s1 || !s2)
-    return false;
-
-  /* Check top level stuff */
-  if (s1->revision != s2->revision)
-    return false;
-
-  if (s1->type!= s2->type)
-    return false;
-
-  /* Check owner and group */
-  if (!sid_equal(s1->owner_sid, s2->owner_sid))
-    return false;
-
-  if (!sid_equal(s1->grp_sid, s2->grp_sid)) 
-    return false;
-
-  /* Check ACLs present in one but not the other */
-  if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
-      (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) 
-  { return false; }
-
-  /* Sigh - we have to do it the hard way by iterating over all
-     the ACEs in the ACLs */
-  if(!sec_acl_equal(s1->dacl, s2->dacl) || !sec_acl_equal(s1->sacl, s2->sacl)) 
-    return false;
-
-  return true;
-}
+/******************************************************************************
+ * Check if ACE has OBJECT type.
+ ******************************************************************************/
+bool winsec_ace_object(uint8_t type)
+{
+  if (type == WINSEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
+      type == WINSEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
+      type == WINSEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
+      type == WINSEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) 
+  { return true; }
+
+  return false;
+}
