Index: trunk/include/regfi.h
===================================================================
--- trunk/include/regfi.h	(revision 131)
+++ trunk/include/regfi.h	(revision 132)
@@ -6,5 +6,5 @@
  * Windows NT registry I/O library
  *
- * Copyright (C) 2005-2008 Timothy D. Morgan
+ * Copyright (C) 2005-2009 Timothy D. Morgan
  * Copyright (C) 2005 Gerald (Jerry) Carter
  *
@@ -47,4 +47,5 @@
 
 #include "smb_deps.h"
+#include "winsec.h"
 #include "void_stack.h"
 #include "range_list.h"
Index: trunk/include/smb_deps.h
===================================================================
--- trunk/include/smb_deps.h	(revision 131)
+++ trunk/include/smb_deps.h	(revision 132)
@@ -4,5 +4,5 @@
  *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
  *
- * Copyright (C) 2005 Timothy D. Morgan
+ * Copyright (C) 2005,2009 Timothy D. Morgan
  * Copyright (C) 1992-2005 Samba development team 
  *               (see individual files under Subversion for details.)
@@ -23,4 +23,7 @@
  * $Id$
  */
+
+#ifndef _SMB_DEPS_H
+#define _SMB_DEPS_H
 
 #include <stdlib.h>
@@ -73,20 +76,4 @@
 
 /* From smb.h */
-
-#define MAXSUBAUTHS 15
-
-typedef struct sid_info
-{
-  uint8  sid_rev_num;             /**< SID revision number */
-  uint8  num_auths;               /**< Number of sub-authorities */
-  uint8  id_auth[6];              /**< Identifier Authority */
-  /*
-   *  Pointer to sub-authorities.
-   *
-   * @note The values in these uint32's are in *native* byteorder, not
-   * neccessarily little-endian...... JRA.
-   */
-  uint32 sub_auths[MAXSUBAUTHS];
-} DOM_SID;
 
 typedef struct nttime_info
@@ -184,60 +171,4 @@
 
 
-/* From rpc_secdesc.h */
-
-typedef struct security_info_info
-{
-	uint32 mask;
-
-} SEC_ACCESS;
-
-typedef struct security_ace_info
-{
-	uint8 type;  /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */
-	uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */
-	uint16 size;
-
-	SEC_ACCESS info;
-
-	/* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */
-	uint32  obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */
-	struct uuid obj_guid;  /* object GUID */
-	struct uuid inh_guid;  /* inherited object GUID */		
-        /* eof object stuff */
-
-	DOM_SID trustee;
-
-} SEC_ACE;
-
-typedef struct security_acl_info
-{
-	uint16 revision; /* 0x0003 */
-	uint16 size; /* size in bytes of the entire ACL structure */
-	uint32 num_aces; /* number of Access Control Entries */
-
-	SEC_ACE *ace;
-
-} SEC_ACL;
-
-typedef struct security_descriptor_info
-{
-	uint16 revision; /* 0x0001 */
-	uint16 type;     /* SEC_DESC_xxxx flags */
-
-	uint32 off_owner_sid; /* offset to owner sid */
-	uint32 off_grp_sid  ; /* offset to group sid */
-	uint32 off_sacl     ; /* offset to system list of permissions */
-	uint32 off_dacl     ; /* offset to list of permissions */
-
-	SEC_ACL *dacl; /* user ACL */
-	SEC_ACL *sacl; /* system ACL */
-	DOM_SID *owner_sid; 
-	DOM_SID *grp_sid;
-
-} SEC_DESC;
-
-/* End of stuff from rpc_secdesc.h */
-
-
 /* From pstring.h */
 
@@ -247,21 +178,4 @@
 /* End of stuff from pstring.h */
 
-
-/* From rpc_secdes.h */
-
-#define SEC_DESC_DACL_PRESENT		0x0004
-#define SEC_DESC_SACL_PRESENT		0x0010
-#define  SEC_DESC_HEADER_SIZE (2 * sizeof(uint16) + 4 * sizeof(uint32))
-   /* thanks for Jim McDonough <jmcd@us.ibm.com> */
-#define SEC_ACE_OBJECT_PRESENT        0x00000001 
-#define SEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002
-
-#define SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT	0x5
-#define SEC_ACE_TYPE_ACCESS_DENIED_OBJECT     	0x6
-#define SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT      	0x7
-#define SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT	0x8
-
-/* End of stuff from rpc_secdes.h */
-
 /* From rpc_parse/parse_misc.c */
 
@@ -269,47 +183,6 @@
 		 prs_struct *ps, int depth);
 bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth);
-bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth);
 
 /* End of stuff from rpc_parse/parse_misc.c */
 
-/* From lib/util_sid.c */
-
-size_t sid_size(const DOM_SID *sid);
-int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2);
-int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2);
-bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
-
-/* End of stuff from lib/util_sid.c */
-
-/* From lib/secace.c */
-
-bool sec_ace_object(uint8 type);
-
-/* End of stuff from lib/secace.c */
-
-/* From rpc_parse/parse_sec.c */
-
-bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
-bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth);
-bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth);
-bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth);
-
-/* End of stuff from rpc_parse/parse_sec.c */
-
-/* From lib/secace.c */
-
-bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2);
-
-/* End of stuff from lib/secace.c */
-
-/* From lib/secacl.c */
-
-bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2);
-
-/* End of stuff from lib/secacl.c */
-
-/* From lib/secdesc.c */
-
-bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2);
-
-/* End of stuff from lib/secdesc.c */
+#endif /* _SMB_DEPS_H */
Index: trunk/include/winsec.h
===================================================================
--- trunk/include/winsec.h	(revision 132)
+++ trunk/include/winsec.h	(revision 132)
@@ -0,0 +1,179 @@
+/*
+ * This file contains miscellaneous pieces of code which regfio.c
+ * depends upon, from the Samba Subversion tree.  See:
+ *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
+ *
+ * Copyright (C) 2005,2009 Timothy D. Morgan
+ * Copyright (C) 1992-2005 Samba development team 
+ *               (see individual files under Subversion for details.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3 of the License.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id $
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "smb_deps.h"
+
+
+/* From smb.h */
+
+#define MAXSUBAUTHS 15
+
+typedef struct sid_info
+{
+  uint8  sid_rev_num;             /**< SID revision number */
+  uint8  num_auths;               /**< Number of sub-authorities */
+  uint8  id_auth[6];              /**< Identifier Authority */
+  /*
+   *  Pointer to sub-authorities.
+   *
+   * @note The values in these uint32's are in *native* byteorder, not
+   * neccessarily little-endian...... JRA.
+   */
+  uint32 sub_auths[MAXSUBAUTHS];
+} DOM_SID;
+
+/* End of stuff from smb.h */
+
+
+/* From rpc_secdesc.h */
+
+typedef struct security_info_info
+{
+	uint32 mask;
+
+} SEC_ACCESS;
+
+typedef struct security_ace_info
+{
+	uint8 type;  /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */
+	uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */
+	uint16 size;
+
+	SEC_ACCESS info;
+
+	/* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */
+	uint32  obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */
+	struct uuid obj_guid;  /* object GUID */
+	struct uuid inh_guid;  /* inherited object GUID */		
+        /* eof object stuff */
+
+	DOM_SID trustee;
+
+} SEC_ACE;
+
+typedef struct security_acl_info
+{
+	uint16 revision; /* 0x0003 */
+	uint16 size; /* size in bytes of the entire ACL structure */
+	uint32 num_aces; /* number of Access Control Entries */
+
+	SEC_ACE *ace;
+
+} SEC_ACL;
+
+typedef struct security_descriptor_info
+{
+	uint16 revision; /* 0x0001 */
+	uint16 type;     /* SEC_DESC_xxxx flags */
+
+	uint32 off_owner_sid; /* offset to owner sid */
+	uint32 off_grp_sid  ; /* offset to group sid */
+	uint32 off_sacl     ; /* offset to system list of permissions */
+	uint32 off_dacl     ; /* offset to list of permissions */
+
+	SEC_ACL *dacl; /* user ACL */
+	SEC_ACL *sacl; /* system ACL */
+	DOM_SID *owner_sid; 
+	DOM_SID *grp_sid;
+
+} SEC_DESC;
+
+/* End of stuff from rpc_secdesc.h */
+
+
+
+/* From rpc_secdes.h */
+
+#define SEC_DESC_DACL_PRESENT		0x0004
+#define SEC_DESC_SACL_PRESENT		0x0010
+#define  SEC_DESC_HEADER_SIZE (2 * sizeof(uint16) + 4 * sizeof(uint32))
+   /* thanks for Jim McDonough <jmcd@us.ibm.com> */
+#define SEC_ACE_OBJECT_PRESENT        0x00000001 
+#define SEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002
+
+#define SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT	0x5
+#define SEC_ACE_TYPE_ACCESS_DENIED_OBJECT     	0x6
+#define SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT      	0x7
+#define SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT	0x8
+
+/* End of stuff from rpc_secdes.h */
+
+/* From rpc_parse/parse_misc.c */
+
+bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth);
+
+/* End of stuff from rpc_parse/parse_misc.c */
+
+/* From lib/util_sid.c */
+
+size_t sid_size(const DOM_SID *sid);
+int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2);
+int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2);
+bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
+
+/* End of stuff from lib/util_sid.c */
+
+/* From lib/secace.c */
+
+bool sec_ace_object(uint8 type);
+
+/* End of stuff from lib/secace.c */
+
+/* From rpc_parse/parse_sec.c */
+
+bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
+bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth);
+bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth);
+bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth);
+
+/* End of stuff from rpc_parse/parse_sec.c */
+
+/* From lib/secace.c */
+
+bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2);
+
+/* End of stuff from lib/secace.c */
+
+/* From lib/secacl.c */
+
+bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2);
+
+/* End of stuff from lib/secacl.c */
+
+/* From lib/secdesc.c */
+
+bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2);
+
+/* End of stuff from lib/secdesc.c */
Index: trunk/lib/Makefile
===================================================================
--- trunk/lib/Makefile	(revision 131)
+++ trunk/lib/Makefile	(revision 132)
@@ -3,5 +3,5 @@
 ################################################################################
 
-FILES=regfi.o smb_deps.o void_stack.o range_list.o lru_cache.o
+FILES=regfi.o smb_deps.o winsec.o void_stack.o range_list.o lru_cache.o
 
 all: $(FILES)
@@ -12,4 +12,7 @@
 smb_deps.o: smb_deps.c
 	$(CC) $(CFLAGS) $(OPTS) $(INC) -c -o $@ smb_deps.c
+
+winsec.o: winsec.c
+	$(CC) $(CFLAGS) $(OPTS) $(INC) -c -o $@ winsec.c
 
 void_stack.o: void_stack.c
Index: trunk/lib/regfi.c
===================================================================
--- trunk/lib/regfi.c	(revision 131)
+++ trunk/lib/regfi.c	(revision 132)
@@ -6,5 +6,5 @@
  * Windows NT registry parsing library
  *
- * Copyright (C) 2005-2008 Timothy D. Morgan
+ * Copyright (C) 2005-2009 Timothy D. Morgan
  * Copyright (C) 2005 Gerald (Jerry) Carter
  *
Index: trunk/lib/smb_deps.c
===================================================================
--- trunk/lib/smb_deps.c	(revision 131)
+++ trunk/lib/smb_deps.c	(revision 132)
@@ -4,5 +4,5 @@
  *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
  *
- * Copyright (C) 2005-2006 Timothy D. Morgan
+ * Copyright (C) 2005-2006,2009 Timothy D. Morgan
  * Copyright (C) 1992-2005 Samba development team 
  *               (see individual files under Subversion for details.)
@@ -556,718 +556,2 @@
   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;
-}
-
-/* End of stuff from rpc_parse/parse_misc.c */
-
-/* From lib/util_sid.c */
-
-/*****************************************************************
- Calculates size of a sid.
-*****************************************************************/  
-size_t sid_size(const 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)
-{
-  int i;
-
-  if (sid1 == sid2)
-    return 0;
-  if (!sid1)
-    return -1;
-  if (!sid2)
-    return 1;
-
-  if (sid1->sid_rev_num != sid2->sid_rev_num)
-    return sid1->sid_rev_num - sid2->sid_rev_num;
-
-  for (i = 0; i < 6; i++)
-    if (sid1->id_auth[i] != sid2->id_auth[i])
-      return sid1->id_auth[i] - sid2->id_auth[i];
-
-  return 0;
-}
-
-
-/*****************************************************************
- Compare two sids.
-*****************************************************************/  
-int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
-{
-  int i;
-
-  if (sid1 == sid2)
-    return 0;
-  if (!sid1)
-    return -1;
-  if (!sid2)
-    return 1;
-
-  /* Compare most likely different rids, first: i.e start at end */
-  if (sid1->num_auths != sid2->num_auths)
-    return sid1->num_auths - sid2->num_auths;
-
-  for (i = sid1->num_auths-1; i >= 0; --i)
-    if (sid1->sub_auths[i] != sid2->sub_auths[i])
-      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;
-}
-
-/* End of stuff from lib/util_sid.c */
-
-/* From lib/secace.c */
-
-/*******************************************************************
- 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 true;
-  }
-  return false;
-}
-
-/* End of stuff from lib/secace.c */
-
-/* From rpc_parse/parse_sec.c */
-
-/*******************************************************************
- 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;
-  }
-
-  /* Theorectically an ACE can have a size greater than the
-   * sum of its components. When marshalling, pad with extra null bytes 
-   * up to the
-   * correct size. 
-   */
-  if (!ps->io && (psa->size > ps->data_offset - old_offset)) 
-  {
-    uint32 extra_len = psa->size - (ps->data_offset - old_offset);
-    uint32 i;
-    uint8 c = 0;
-
-    for (i = 0; i < extra_len; i++) 
-    {
-      if (!prs_uint8("ace extra space", ps, depth, &c))
-	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;
-
-  /*
-   * 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
-   */
-
-  if (ppsa == NULL || ps == NULL)
-    return false;
-
-  psa = *ppsa;
-
-  if(ps->io && 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;
-  }
-
-  if (ps->io) 
-  {
-    /*
-     * 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;
-    }
-  }
-
-  /* Theoretically an ACL can have a size greater than the
-   *  sum of its components. When marshalling, pad with extra null 
-   *  bytes up to the
-   *  correct size. 
-   */
-  if (!ps->io && (psa->size > ps->data_offset - old_offset)) 
-  {
-    uint32 extra_len = psa->size - (ps->data_offset - old_offset);
-    uint8 c = 0;
-
-    for (i = 0; i < extra_len; i++) 
-    {
-      if (!prs_uint8("acl extra space", ps, depth, &c))
-      {
-	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;
-}
-
-
-/*******************************************************************
- Reads or writes a SEC_DESC structure.
- If reading and the *ppsd = NULL, allocates the 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(ps->io) 
-    {
-      if((psd = (SEC_DESC*)zalloc(sizeof(SEC_DESC))) == NULL)
-	return false;
-      *ppsd = psd;
-    } 
-    else 
-    {
-      /* Marshalling - just ignore. */
-      return true;
-    }
-  }
-
-  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 (!ps->io)
-  {
-    uint32 offset = SEC_DESC_HEADER_SIZE;
-
-    /*
-     * Work out the offsets here, as we write it out.
-     */
-
-    if (psd->sacl != NULL) 
-    {
-      psd->off_sacl = offset;
-      offset += psd->sacl->size;
-    } 
-    else
-      psd->off_sacl = 0;
-
-    if (psd->dacl != NULL) 
-    {
-      psd->off_dacl = offset;
-      offset += psd->dacl->size;
-    } 
-    else 
-      psd->off_dacl = 0;
-
-    if (psd->owner_sid != NULL) 
-    {
-      psd->off_owner_sid = offset;
-      offset += sid_size(psd->owner_sid);
-    } 
-    else
-      psd->off_owner_sid = 0;
-
-    if (psd->grp_sid != NULL) 
-    {
-      psd->off_grp_sid = offset;
-      offset += sid_size(psd->grp_sid);
-    } 
-    else
-      psd->off_grp_sid = 0;
-  }
-
-  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;
-    }
-
-    if (ps->io) 
-    {
-      /* 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))
-    {
-      if(ps->io)
-	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))
-    {
-      if(ps->io)
-	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))
-    {
-      if(ps->io)
-	free(psd->owner_sid);
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-
-    if (ps->io) 
-    {
-      /* 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))
-    {
-      if(ps->io)
-      {
-	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))
-    {
-      if(ps->io)
-      {
-	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))
-    {
-      if(ps->io)
-      {
-	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))
-    {
-      if(ps->io)
-      {
-	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))
-    {
-      if(ps->io)
-      {
-	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))
-    {
-      if(ps->io)
-      {
-	free(psd->grp_sid);
-	free(psd->owner_sid);
-      }
-      free(psd);
-      *ppsd = NULL;
-      return false;
-    }
-  }
-
-  if(!prs_set_offset(ps, max_offset))
-  {
-      if(ps->io)
-      {
-	free(psd->grp_sid);
-	free(psd->owner_sid);
-      }
-      free(psd);
-      *ppsd = NULL;
-      return false;
-  }
-
-  return true;
-}
-
-/* End of stuff from rpc_parse/parse_sec.c */
-
-/* From lib/secace.c */
-
-/*******************************************************************
- Compares two SEC_ACE structures
-********************************************************************/
-bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
-{
-  /* Trivial cases */
-  if (!s1 && !s2) 
-    return true;
-  if (!s1 || !s2) 
-    return false;
-
-  /* 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;
-
-  return true;
-}
-
-/* End of stuff from lib/secace.c */
-
-/* From lib/secacl.c */
-
-/*******************************************************************
- Compares two SEC_ACL structures
-********************************************************************/
-
-bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
-{
-  unsigned int i, j;
-
-  /* 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->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;
-  }
-
-  return true;
-}
-
-/* End of stuff from lib/secacl.c */
-
-/* From lib/secdesc.c */
-
-/*******************************************************************
- 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;
-}
-
-/* End of stuff from lib/secdesc.c */
Index: trunk/lib/winsec.c
===================================================================
--- trunk/lib/winsec.c	(revision 132)
+++ trunk/lib/winsec.c	(revision 132)
@@ -0,0 +1,745 @@
+/*
+ * This file contains miscellaneous pieces of code which regfio.c
+ * depends upon, from the Samba Subversion tree.  See:
+ *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
+ *
+ * Copyright (C) 2005-2006,2009 Timothy D. Morgan
+ * Copyright (C) 1992-2005 Samba development team 
+ *               (see individual files under Subversion for details.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3 of the License.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id $
+ */
+
+#include "../include/winsec.h"
+
+
+
+/* From rpc_parse/parse_misc.c */
+
+/*******************************************************************
+ 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;
+}
+
+/* End of stuff from rpc_parse/parse_misc.c */
+
+/* From lib/util_sid.c */
+
+/*****************************************************************
+ Calculates size of a sid.
+*****************************************************************/  
+size_t sid_size(const 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)
+{
+  int i;
+
+  if (sid1 == sid2)
+    return 0;
+  if (!sid1)
+    return -1;
+  if (!sid2)
+    return 1;
+
+  if (sid1->sid_rev_num != sid2->sid_rev_num)
+    return sid1->sid_rev_num - sid2->sid_rev_num;
+
+  for (i = 0; i < 6; i++)
+    if (sid1->id_auth[i] != sid2->id_auth[i])
+      return sid1->id_auth[i] - sid2->id_auth[i];
+
+  return 0;
+}
+
+
+/*****************************************************************
+ Compare two sids.
+*****************************************************************/  
+int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
+{
+  int i;
+
+  if (sid1 == sid2)
+    return 0;
+  if (!sid1)
+    return -1;
+  if (!sid2)
+    return 1;
+
+  /* Compare most likely different rids, first: i.e start at end */
+  if (sid1->num_auths != sid2->num_auths)
+    return sid1->num_auths - sid2->num_auths;
+
+  for (i = sid1->num_auths-1; i >= 0; --i)
+    if (sid1->sub_auths[i] != sid2->sub_auths[i])
+      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;
+}
+
+/* End of stuff from lib/util_sid.c */
+
+/* From lib/secace.c */
+
+/*******************************************************************
+ 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 true;
+  }
+  return false;
+}
+
+/* End of stuff from lib/secace.c */
+
+/* From rpc_parse/parse_sec.c */
+
+/*******************************************************************
+ 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;
+  }
+
+  /* Theorectically an ACE can have a size greater than the
+   * sum of its components. When marshalling, pad with extra null bytes 
+   * up to the
+   * correct size. 
+   */
+  if (!ps->io && (psa->size > ps->data_offset - old_offset)) 
+  {
+    uint32 extra_len = psa->size - (ps->data_offset - old_offset);
+    uint32 i;
+    uint8 c = 0;
+
+    for (i = 0; i < extra_len; i++) 
+    {
+      if (!prs_uint8("ace extra space", ps, depth, &c))
+	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;
+
+  /*
+   * 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
+   */
+
+  if (ppsa == NULL || ps == NULL)
+    return false;
+
+  psa = *ppsa;
+
+  if(ps->io && 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;
+  }
+
+  if (ps->io) 
+  {
+    /*
+     * 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;
+    }
+  }
+
+  /* Theoretically an ACL can have a size greater than the
+   *  sum of its components. When marshalling, pad with extra null 
+   *  bytes up to the
+   *  correct size. 
+   */
+  if (!ps->io && (psa->size > ps->data_offset - old_offset)) 
+  {
+    uint32 extra_len = psa->size - (ps->data_offset - old_offset);
+    uint8 c = 0;
+
+    for (i = 0; i < extra_len; i++) 
+    {
+      if (!prs_uint8("acl extra space", ps, depth, &c))
+      {
+	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;
+}
+
+
+/*******************************************************************
+ Reads or writes a SEC_DESC structure.
+ If reading and the *ppsd = NULL, allocates the 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(ps->io) 
+    {
+      if((psd = (SEC_DESC*)zalloc(sizeof(SEC_DESC))) == NULL)
+	return false;
+      *ppsd = psd;
+    } 
+    else 
+    {
+      /* Marshalling - just ignore. */
+      return true;
+    }
+  }
+
+  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 (!ps->io)
+  {
+    uint32 offset = SEC_DESC_HEADER_SIZE;
+
+    /*
+     * Work out the offsets here, as we write it out.
+     */
+
+    if (psd->sacl != NULL) 
+    {
+      psd->off_sacl = offset;
+      offset += psd->sacl->size;
+    } 
+    else
+      psd->off_sacl = 0;
+
+    if (psd->dacl != NULL) 
+    {
+      psd->off_dacl = offset;
+      offset += psd->dacl->size;
+    } 
+    else 
+      psd->off_dacl = 0;
+
+    if (psd->owner_sid != NULL) 
+    {
+      psd->off_owner_sid = offset;
+      offset += sid_size(psd->owner_sid);
+    } 
+    else
+      psd->off_owner_sid = 0;
+
+    if (psd->grp_sid != NULL) 
+    {
+      psd->off_grp_sid = offset;
+      offset += sid_size(psd->grp_sid);
+    } 
+    else
+      psd->off_grp_sid = 0;
+  }
+
+  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;
+    }
+
+    if (ps->io) 
+    {
+      /* 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))
+    {
+      if(ps->io)
+	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))
+    {
+      if(ps->io)
+	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))
+    {
+      if(ps->io)
+	free(psd->owner_sid);
+      free(psd);
+      *ppsd = NULL;
+      return false;
+    }
+
+    if (ps->io) 
+    {
+      /* 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))
+    {
+      if(ps->io)
+      {
+	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))
+    {
+      if(ps->io)
+      {
+	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))
+    {
+      if(ps->io)
+      {
+	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))
+    {
+      if(ps->io)
+      {
+	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))
+    {
+      if(ps->io)
+      {
+	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))
+    {
+      if(ps->io)
+      {
+	free(psd->grp_sid);
+	free(psd->owner_sid);
+      }
+      free(psd);
+      *ppsd = NULL;
+      return false;
+    }
+  }
+
+  if(!prs_set_offset(ps, max_offset))
+  {
+      if(ps->io)
+      {
+	free(psd->grp_sid);
+	free(psd->owner_sid);
+      }
+      free(psd);
+      *ppsd = NULL;
+      return false;
+  }
+
+  return true;
+}
+
+/* End of stuff from rpc_parse/parse_sec.c */
+
+/* From lib/secace.c */
+
+/*******************************************************************
+ Compares two SEC_ACE structures
+********************************************************************/
+bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
+{
+  /* Trivial cases */
+  if (!s1 && !s2) 
+    return true;
+  if (!s1 || !s2) 
+    return false;
+
+  /* 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;
+
+  return true;
+}
+
+/* End of stuff from lib/secace.c */
+
+/* From lib/secacl.c */
+
+/*******************************************************************
+ Compares two SEC_ACL structures
+********************************************************************/
+
+bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
+{
+  unsigned int i, j;
+
+  /* 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->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;
+  }
+
+  return true;
+}
+
+/* End of stuff from lib/secacl.c */
+
+/* From lib/secdesc.c */
+
+/*******************************************************************
+ 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;
+}
+
+/* End of stuff from lib/secdesc.c */
