Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-test
[ira/wip.git] / source3 / lib / secdesc.c
index 762dc2f6d8cc4fc4df3da94557c701d2ac32b69c..44ae23271ef45261ea1d6a4a0cce868e78e31703 100644 (file)
@@ -8,7 +8,7 @@
  *  
  *  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; either version 2 of the License, or
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
  *  
  *  This program is distributed in the hope that it will be useful,
  *  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.
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "includes.h"
 
 /* Map generic permissions to file object specific permissions */
 
-struct generic_mapping file_generic_mapping = {
+const struct generic_mapping file_generic_mapping = {
        FILE_GENERIC_READ,
        FILE_GENERIC_WRITE,
        FILE_GENERIC_EXECUTE,
        FILE_GENERIC_ALL
 };
 
-/*******************************************************************
- Works out the linearization size of a SEC_DESC.
-********************************************************************/
-
-size_t sec_desc_size(SEC_DESC *psd)
-{
-       size_t offset;
-
-       if (!psd) return 0;
-
-       offset = SEC_DESC_HEADER_SIZE;
-
-       /* don't align */
-
-       if (psd->owner_sid != NULL)
-               offset += sid_size(psd->owner_sid);
-
-       if (psd->group_sid != NULL)
-               offset += sid_size(psd->group_sid);
-
-       if (psd->sacl != NULL)
-               offset += psd->sacl->size;
-
-       if (psd->dacl != NULL)
-               offset += psd->dacl->size;
-
-       return offset;
-}
-
 /*******************************************************************
  Compares two SEC_DESC structures
 ********************************************************************/
 
-BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
+bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
 {
        /* Trivial case */
 
@@ -94,24 +64,16 @@ BOOL sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
        /* Check owner and group */
 
        if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
-               fstring str1, str2;
-
-               sid_to_string(str1, s1->owner_sid);
-               sid_to_string(str2, s2->owner_sid);
-
                DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
-                          str1, str2));
+                          sid_string_dbg(s1->owner_sid),
+                          sid_string_dbg(s2->owner_sid)));
                return False;
        }
 
        if (!sid_equal(s1->group_sid, s2->group_sid)) {
-               fstring str1, str2;
-
-               sid_to_string(str1, s1->group_sid);
-               sid_to_string(str2, s2->group_sid);
-
                DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
-                          str1, str2));
+                          sid_string_dbg(s1->group_sid),
+                          sid_string_dbg(s2->group_sid)));
                return False;
        }
 
@@ -191,7 +153,9 @@ SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BU
  Creates a SEC_DESC structure
 ********************************************************************/
 
-SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type,
+SEC_DESC *make_sec_desc(TALLOC_CTX *ctx,
+                       enum security_descriptor_revision revision,
+                       uint16 type,
                        const DOM_SID *owner_sid, const DOM_SID *grp_sid,
                        SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
 {
@@ -242,11 +206,11 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type,
        }
 
        if (dst->owner_sid != NULL) {
-               offset += sid_size(dst->owner_sid);
+               offset += ndr_size_dom_sid(dst->owner_sid, 0);
        }
 
        if (dst->group_sid != NULL) {
-               offset += sid_size(dst->group_sid);
+               offset += ndr_size_dom_sid(dst->group_sid, 0);
        }
 
        *sd_size = (size_t)offset;
@@ -281,25 +245,21 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
                           struct security_descriptor *secdesc,
                           uint8 **data, size_t *len)
 {
-       prs_struct ps;
-       
-       if (!prs_init(&ps, sec_desc_size(secdesc), mem_ctx, MARSHALL)) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       DATA_BLOB blob;
+       enum ndr_err_code ndr_err;
 
-       if (!sec_io_desc("security_descriptor", &secdesc, &ps, 1)) {
-               prs_mem_free(&ps);
-               return NT_STATUS_INVALID_PARAMETER;
-       }
+       ndr_err = ndr_push_struct_blob(
+               &blob, mem_ctx, secdesc,
+               (ndr_push_flags_fn_t)ndr_push_security_descriptor);
 
-       if (!(*data = (uint8 *)talloc_memdup(mem_ctx, ps.data_p,
-                                            prs_offset(&ps)))) {
-               prs_mem_free(&ps);
-               return NT_STATUS_NO_MEMORY;
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(0, ("ndr_push_security_descriptor failed: %s\n",
+                         ndr_errstr(ndr_err)));
+               return ndr_map_error2ntstatus(ndr_err);;
        }
 
-       *len = prs_offset(&ps);
-       prs_mem_free(&ps);
+       *data = blob.data;
+       *len = blob.length;
        return NT_STATUS_OK;
 }
 
@@ -309,25 +269,33 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
 NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
                             struct security_descriptor **psecdesc)
 {
-       prs_struct ps;
-       struct security_descriptor *secdesc = NULL;
+       DATA_BLOB blob;
+       enum ndr_err_code ndr_err;
+       struct security_descriptor *result;
 
-       if (!(secdesc = TALLOC_ZERO_P(mem_ctx, struct security_descriptor))) {
-               return NT_STATUS_NO_MEMORY;
+       if ((data == NULL) || (len == 0)) {
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!prs_init(&ps, 0, secdesc, UNMARSHALL)) {
+       result = TALLOC_ZERO_P(mem_ctx, struct security_descriptor);
+       if (result == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       prs_give_memory(&ps, (char *)data, len, False);
+       blob = data_blob_const(data, len);
 
-       if (!sec_io_desc("security_descriptor", &secdesc, &ps, 1)) {
-               return NT_STATUS_INVALID_PARAMETER;
+       ndr_err = ndr_pull_struct_blob(
+               &blob, result, result,
+               (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(0, ("ndr_pull_security_descriptor failed: %s\n",
+                         ndr_errstr(ndr_err)));
+               TALLOC_FREE(result);
+               return ndr_map_error2ntstatus(ndr_err);;
        }
 
-       prs_mem_free(&ps);
-       *psecdesc = secdesc;
+       *psecdesc = result;
        return NT_STATUS_OK;
 }
 
@@ -338,8 +306,9 @@ NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
 SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid,
                                 SEC_ACL *dacl, size_t *sd_size)
 {
-       return make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
-                            owner_sid, grp_sid, NULL, dacl, sd_size);
+       return make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
+                            SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, NULL,
+                            dacl, sd_size);
 }
 
 /*******************************************************************
@@ -465,7 +434,7 @@ NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t
    non-container object. */
 
 SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, 
-                                     BOOL child_container)
+                                     bool child_container)
 {
        SEC_DESC_BUF *sdb;
        SEC_DESC *sd;
@@ -480,15 +449,18 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
 
        the_acl = parent_ctr->dacl;
 
-       if (!(new_ace_list = TALLOC_ARRAY(ctx, SEC_ACE, the_acl->num_aces))) 
-               return NULL;
+       if (the_acl->num_aces) {
+               if (!(new_ace_list = TALLOC_ARRAY(ctx, SEC_ACE, the_acl->num_aces))) 
+                       return NULL;
+       } else {
+               new_ace_list = NULL;
+       }
 
        for (i = 0; i < the_acl->num_aces; i++) {
                SEC_ACE *ace = &the_acl->aces[i];
                SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
                uint8 new_flags = 0;
-               BOOL inherit = False;
-               fstring sid_str;
+               bool inherit = False;
 
                /* The OBJECT_INHERIT_ACE flag causes the ACE to be
                   inherited by non-container children objects.  Container
@@ -544,12 +516,12 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
                init_sec_ace(new_ace, &ace->trustee, ace->type,
                             new_ace->access_mask, new_flags);
 
-               sid_to_string(sid_str, &ace->trustee);
-
                DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
-                         " inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
+                         " inherited as %s:%d/0x%02x/0x%08x\n",
+                         sid_string_dbg(&ace->trustee),
                          ace->type, ace->flags, ace->access_mask,
-                         sid_str, new_ace->type, new_ace->flags,
+                         sid_string_dbg(&ace->trustee),
+                         new_ace->type, new_ace->flags,
                          new_ace->access_mask));
 
                new_ace_list_ndx++;
@@ -563,7 +535,8 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
           correct.  Perhaps the user and group should be passed in as
           parameters by the caller? */
 
-       sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+       sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
+                          SEC_DESC_SELF_RELATIVE,
                           parent_ctr->owner_sid,
                           parent_ctr->group_sid,
                           parent_ctr->sacl,