diff options
author | Jeremy Allison <jra@samba.org> | 2009-07-24 14:09:42 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2009-07-24 14:09:42 -0700 |
commit | 1bab4fdaafd5930a02ae5a0d603176720ef15220 (patch) | |
tree | 7ec6fb3cdf29e03fceca04194203e3963f0d5a1f | |
parent | 6b801d6c4cdaaf47191b7051c81cf9498acd64f1 (diff) | |
download | samba-1bab4fdaafd5930a02ae5a0d603176720ef15220.tar.gz samba-1bab4fdaafd5930a02ae5a0d603176720ef15220.tar.bz2 samba-1bab4fdaafd5930a02ae5a0d603176720ef15220.zip |
Fix hash function in acl_xattr to be SHA256, make
the hash function selectable. Upgrade version.
Compiles but not fully tested yet (coming). Make
vfs_acl_tdb.c compile - this needs updating to
match acl_xattr (also coming soon).
Jeremy.
-rw-r--r-- | librpc/gen_ndr/ndr_xattr.c | 139 | ||||
-rw-r--r-- | librpc/gen_ndr/ndr_xattr.h | 9 | ||||
-rw-r--r-- | librpc/gen_ndr/xattr.h | 14 | ||||
-rw-r--r-- | librpc/idl/xattr.idl | 15 | ||||
-rw-r--r-- | source3/modules/vfs_acl_tdb.c | 20 | ||||
-rw-r--r-- | source3/modules/vfs_acl_xattr.c | 142 |
6 files changed, 249 insertions, 90 deletions
diff --git a/librpc/gen_ndr/ndr_xattr.c b/librpc/gen_ndr/ndr_xattr.c index d217a00228..3d09f00864 100644 --- a/librpc/gen_ndr/ndr_xattr.c +++ b/librpc/gen_ndr/ndr_xattr.c @@ -546,7 +546,7 @@ _PUBLIC_ void ndr_print_xattr_DosStreams(struct ndr_print *ndr, const char *name ndr->depth--; } -_PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_hash(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash *r) +_PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_hash_v2(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash_v2 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -561,7 +561,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_hash(struct ndr_push *nd return NDR_ERR_SUCCESS; } -_PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_hash(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash *r) +_PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_hash_v2(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash_v2 *r) { uint32_t _ptr_sd; TALLOC_CTX *_mem_save_sd_0; @@ -586,9 +586,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_hash(struct ndr_pull *nd return NDR_ERR_SUCCESS; } -_PUBLIC_ void ndr_print_security_descriptor_hash(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash *r) +_PUBLIC_ void ndr_print_security_descriptor_hash_v2(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash_v2 *r) { - ndr_print_struct(ndr, name, "security_descriptor_hash"); + ndr_print_struct(ndr, name, "security_descriptor_hash_v2"); ndr->depth++; ndr_print_ptr(ndr, "sd", r->sd); ndr->depth++; @@ -600,6 +600,64 @@ _PUBLIC_ void ndr_print_security_descriptor_hash(struct ndr_print *ndr, const ch ndr->depth--; } +_PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_hash_v3(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash_v3 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->hash_type)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->hash, XATTR_SD_HASH_SIZE)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->sd) { + NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd)); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_hash_v3(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash_v3 *r) +{ + uint32_t _ptr_sd; + TALLOC_CTX *_mem_save_sd_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd)); + if (_ptr_sd) { + NDR_PULL_ALLOC(ndr, r->sd); + } else { + r->sd = NULL; + } + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->hash_type)); + NDR_PULL_ALLOC_N(ndr, r->hash, XATTR_SD_HASH_SIZE); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->hash, XATTR_SD_HASH_SIZE)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->sd) { + _mem_save_sd_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->sd, 0); + NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sd_0, 0); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_security_descriptor_hash_v3(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash_v3 *r) +{ + ndr_print_struct(ndr, name, "security_descriptor_hash_v3"); + ndr->depth++; + ndr_print_ptr(ndr, "sd", r->sd); + ndr->depth++; + if (r->sd) { + ndr_print_security_descriptor(ndr, "sd", r->sd); + } + ndr->depth--; + ndr_print_uint16(ndr, "hash_type", r->hash_type); + ndr_print_array_uint8(ndr, "hash", r->hash, XATTR_SD_HASH_SIZE); + ndr->depth--; +} + static enum ndr_err_code ndr_push_xattr_NTACL_Info(struct ndr_push *ndr, int ndr_flags, const union xattr_NTACL_Info *r) { if (ndr_flags & NDR_SCALARS) { @@ -611,7 +669,11 @@ static enum ndr_err_code ndr_push_xattr_NTACL_Info(struct ndr_push *ndr, int ndr break; } case 2: { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd_hs)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd_hs2)); + break; } + + case 3: { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd_hs3)); break; } default: @@ -628,8 +690,14 @@ static enum ndr_err_code ndr_push_xattr_NTACL_Info(struct ndr_push *ndr, int ndr break; case 2: - if (r->sd_hs) { - NDR_CHECK(ndr_push_security_descriptor_hash(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs)); + if (r->sd_hs2) { + NDR_CHECK(ndr_push_security_descriptor_hash_v2(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs2)); + } + break; + + case 3: + if (r->sd_hs3) { + NDR_CHECK(ndr_push_security_descriptor_hash_v3(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs3)); } break; @@ -645,7 +713,8 @@ static enum ndr_err_code ndr_pull_xattr_NTACL_Info(struct ndr_pull *ndr, int ndr int level; uint16_t _level; TALLOC_CTX *_mem_save_sd_0; - TALLOC_CTX *_mem_save_sd_hs_0; + TALLOC_CTX *_mem_save_sd_hs2_0; + TALLOC_CTX *_mem_save_sd_hs3_0; level = ndr_pull_get_switch_value(ndr, r); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &_level)); @@ -664,12 +733,22 @@ static enum ndr_err_code ndr_pull_xattr_NTACL_Info(struct ndr_pull *ndr, int ndr break; } case 2: { - uint32_t _ptr_sd_hs; - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd_hs)); - if (_ptr_sd_hs) { - NDR_PULL_ALLOC(ndr, r->sd_hs); + uint32_t _ptr_sd_hs2; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd_hs2)); + if (_ptr_sd_hs2) { + NDR_PULL_ALLOC(ndr, r->sd_hs2); + } else { + r->sd_hs2 = NULL; + } + break; } + + case 3: { + uint32_t _ptr_sd_hs3; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd_hs3)); + if (_ptr_sd_hs3) { + NDR_PULL_ALLOC(ndr, r->sd_hs3); } else { - r->sd_hs = NULL; + r->sd_hs3 = NULL; } break; } @@ -689,11 +768,20 @@ static enum ndr_err_code ndr_pull_xattr_NTACL_Info(struct ndr_pull *ndr, int ndr break; case 2: - if (r->sd_hs) { - _mem_save_sd_hs_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->sd_hs, 0); - NDR_CHECK(ndr_pull_security_descriptor_hash(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sd_hs_0, 0); + if (r->sd_hs2) { + _mem_save_sd_hs2_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->sd_hs2, 0); + NDR_CHECK(ndr_pull_security_descriptor_hash_v2(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs2)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sd_hs2_0, 0); + } + break; + + case 3: + if (r->sd_hs3) { + _mem_save_sd_hs3_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->sd_hs3, 0); + NDR_CHECK(ndr_pull_security_descriptor_hash_v3(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs3)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sd_hs3_0, 0); } break; @@ -720,10 +808,19 @@ _PUBLIC_ void ndr_print_xattr_NTACL_Info(struct ndr_print *ndr, const char *name break; case 2: - ndr_print_ptr(ndr, "sd_hs", r->sd_hs); + ndr_print_ptr(ndr, "sd_hs2", r->sd_hs2); + ndr->depth++; + if (r->sd_hs2) { + ndr_print_security_descriptor_hash_v2(ndr, "sd_hs2", r->sd_hs2); + } + ndr->depth--; + break; + + case 3: + ndr_print_ptr(ndr, "sd_hs3", r->sd_hs3); ndr->depth++; - if (r->sd_hs) { - ndr_print_security_descriptor_hash(ndr, "sd_hs", r->sd_hs); + if (r->sd_hs3) { + ndr_print_security_descriptor_hash_v3(ndr, "sd_hs3", r->sd_hs3); } ndr->depth--; break; diff --git a/librpc/gen_ndr/ndr_xattr.h b/librpc/gen_ndr/ndr_xattr.h index 610d4b3296..9bf49d00ef 100644 --- a/librpc/gen_ndr/ndr_xattr.h +++ b/librpc/gen_ndr/ndr_xattr.h @@ -24,9 +24,12 @@ void ndr_print_xattr_DosStream(struct ndr_print *ndr, const char *name, const st enum ndr_err_code ndr_push_xattr_DosStreams(struct ndr_push *ndr, int ndr_flags, const struct xattr_DosStreams *r); enum ndr_err_code ndr_pull_xattr_DosStreams(struct ndr_pull *ndr, int ndr_flags, struct xattr_DosStreams *r); void ndr_print_xattr_DosStreams(struct ndr_print *ndr, const char *name, const struct xattr_DosStreams *r); -enum ndr_err_code ndr_push_security_descriptor_hash(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash *r); -enum ndr_err_code ndr_pull_security_descriptor_hash(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash *r); -void ndr_print_security_descriptor_hash(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash *r); +enum ndr_err_code ndr_push_security_descriptor_hash_v2(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash_v2 *r); +enum ndr_err_code ndr_pull_security_descriptor_hash_v2(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash_v2 *r); +void ndr_print_security_descriptor_hash_v2(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash_v2 *r); +enum ndr_err_code ndr_push_security_descriptor_hash_v3(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash_v3 *r); +enum ndr_err_code ndr_pull_security_descriptor_hash_v3(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash_v3 *r); +void ndr_print_security_descriptor_hash_v3(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash_v3 *r); void ndr_print_xattr_NTACL_Info(struct ndr_print *ndr, const char *name, const union xattr_NTACL_Info *r); enum ndr_err_code ndr_push_xattr_NTACL(struct ndr_push *ndr, int ndr_flags, const struct xattr_NTACL *r); enum ndr_err_code ndr_pull_xattr_NTACL(struct ndr_pull *ndr, int ndr_flags, struct xattr_NTACL *r); diff --git a/librpc/gen_ndr/xattr.h b/librpc/gen_ndr/xattr.h index 1ce58f7ec6..39f1cb0884 100644 --- a/librpc/gen_ndr/xattr.h +++ b/librpc/gen_ndr/xattr.h @@ -17,6 +17,9 @@ #define XATTR_MAX_STREAM_SIZE ( 0x4000 ) #define XATTR_MAX_STREAM_SIZE_TDB ( 0x100000 ) #define XATTR_NTACL_NAME ( "security.NTACL" ) +#define XATTR_SD_HASH_SIZE ( 64 ) +#define XATTR_SD_HASH_TYPE_NONE ( 0x0 ) +#define XATTR_SD_HASH_TYPE_SHA256 ( 0x1 ) struct xattr_DosInfo1 { uint32_t attrib; uint32_t ea_size; @@ -75,14 +78,21 @@ struct xattr_DosStreams { struct xattr_DosStream *streams;/* [unique,size_is(num_streams)] */ }/* [public] */; -struct security_descriptor_hash { +struct security_descriptor_hash_v2 { struct security_descriptor *sd;/* [unique] */ uint8_t hash[16]; }/* [public] */; +struct security_descriptor_hash_v3 { + struct security_descriptor *sd;/* [unique] */ + uint16_t hash_type; + uint8_t *hash; +}/* [public] */; + union xattr_NTACL_Info { struct security_descriptor *sd;/* [unique,case] */ - struct security_descriptor_hash *sd_hs;/* [unique,case(2)] */ + struct security_descriptor_hash_v2 *sd_hs2;/* [unique,case(2)] */ + struct security_descriptor_hash_v3 *sd_hs3;/* [unique,case(3)] */ }/* [switch_type(uint16)] */; struct xattr_NTACL { diff --git a/librpc/idl/xattr.idl b/librpc/idl/xattr.idl index 4191ea67ce..c2b8bb0cc2 100644 --- a/librpc/idl/xattr.idl +++ b/librpc/idl/xattr.idl @@ -123,14 +123,25 @@ interface xattr const char *XATTR_NTACL_NAME = "security.NTACL"; + const int XATTR_SD_HASH_SIZE = 64; + const int XATTR_SD_HASH_TYPE_NONE = 0x0; + const int XATTR_SD_HASH_TYPE_SHA256 = 0x1; + typedef [public] struct { security_descriptor *sd; uint8 hash[16]; - } security_descriptor_hash; + } security_descriptor_hash_v2; /* Hash never used in this version. */ + + typedef [public] struct { + security_descriptor *sd; + uint16 hash_type; + uint8 hash[XATTR_SD_HASH_SIZE]; /* 64 bytes hash. */ + } security_descriptor_hash_v3; typedef [switch_type(uint16)] union { [case(1)] security_descriptor *sd; - [case(2)] security_descriptor_hash *sd_hs; + [case(2)] security_descriptor_hash_v2 *sd_hs2; + [case(3)] security_descriptor_hash_v3 *sd_hs3; } xattr_NTACL_Info; typedef [public] struct { diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 5d1bb8728c..026c5226ef 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -156,15 +156,15 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, return NT_STATUS_REVISION_MISMATCH; } - *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_hs->sd->type | SEC_DESC_SELF_RELATIVE, + *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE, (security_info & OWNER_SECURITY_INFORMATION) - ? xacl.info.sd_hs->sd->owner_sid : NULL, + ? xacl.info.sd_hs2->sd->owner_sid : NULL, (security_info & GROUP_SECURITY_INFORMATION) - ? xacl.info.sd_hs->sd->group_sid : NULL, + ? xacl.info.sd_hs2->sd->group_sid : NULL, (security_info & SACL_SECURITY_INFORMATION) - ? xacl.info.sd_hs->sd->sacl : NULL, + ? xacl.info.sd_hs2->sd->sacl : NULL, (security_info & DACL_SECURITY_INFORMATION) - ? xacl.info.sd_hs->sd->dacl : NULL, + ? xacl.info.sd_hs2->sd->dacl : NULL, &sd_size); TALLOC_FREE(xacl.info.sd); @@ -237,17 +237,17 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob) { struct xattr_NTACL xacl; - struct security_descriptor_hash sd_hs; + struct security_descriptor_hash_v2 sd_hs2; enum ndr_err_code ndr_err; TALLOC_CTX *ctx = talloc_tos(); ZERO_STRUCT(xacl); - ZERO_STRUCT(sd_hs); + ZERO_STRUCT(sd_hs2); xacl.version = 2; - xacl.info.sd_hs = &sd_hs; - xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd); - memset(&xacl.info.sd_hs->hash[0], '\0', 16); + xacl.info.sd_hs2 = &sd_hs2; + xacl.info.sd_hs2->sd = CONST_DISCARD(struct security_descriptor *, psd); + memset(&xacl.info.sd_hs2->hash[0], '\0', 16); ndr_err = ndr_push_struct_blob( pblob, ctx, NULL, &xacl, diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 3646b659dc..381c374dec 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -23,13 +23,15 @@ #include "includes.h" #include "librpc/gen_ndr/xattr.h" #include "librpc/gen_ndr/ndr_xattr.h" +#include "../lib/crypto/crypto.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob, - uint8_t hash[16]); + uint16_t hash_type, + uint8_t hash[XATTR_SD_HASH_SIZE]); #define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \ GROUP_SECURITY_INFORMATION | \ @@ -40,21 +42,23 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, Hash a security descriptor. *******************************************************************/ -static NTSTATUS hash_sd(struct security_descriptor *psd, - uint8_t hash[16]) +static NTSTATUS hash_sd_sha256(struct security_descriptor *psd, + uint8_t hash[XATTR_SD_HASH_SIZE]) { DATA_BLOB blob; - struct MD5Context tctx; + SHA256_CTX tctx; NTSTATUS status; - memset(hash, '\0', 16); - status = create_acl_blob(psd, &blob, hash); + memset(hash, '\0', XATTR_SD_HASH_SIZE); + status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash); if (!NT_STATUS_IS_OK(status)) { return status; } - MD5Init(&tctx); - MD5Update(&tctx, blob.data, blob.length); - MD5Final(hash, &tctx); + + SHA256_Init(&tctx); + SHA256_Update(&tctx, blob.data, blob.length); + SHA256_Final(hash, &tctx); + return NT_STATUS_OK; } @@ -63,9 +67,9 @@ static NTSTATUS hash_sd(struct security_descriptor *psd, *******************************************************************/ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, - uint32 security_info, struct security_descriptor **ppdesc, - uint8_t hash[16]) + uint16_t *p_hash_type, + uint8_t hash[XATTR_SD_HASH_SIZE]) { TALLOC_CTX *ctx = talloc_tos(); struct xattr_NTACL xacl; @@ -81,22 +85,35 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, return ndr_map_error2ntstatus(ndr_err);; } - if (xacl.version != 2) { - return NT_STATUS_REVISION_MISMATCH; + switch (xacl.version) { + case 2: + *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, + xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE, + xacl.info.sd_hs2->sd->owner_sid, + xacl.info.sd_hs2->sd->group_sid, + xacl.info.sd_hs2->sd->sacl, + xacl.info.sd_hs2->sd->dacl, + &sd_size); + /* No hash - null out. */ + *p_hash_type = XATTR_SD_HASH_TYPE_NONE; + memset(hash, '\0', XATTR_SD_HASH_SIZE); + break; + case 3: + *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, + xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE, + xacl.info.sd_hs3->sd->owner_sid, + xacl.info.sd_hs3->sd->group_sid, + xacl.info.sd_hs3->sd->sacl, + xacl.info.sd_hs3->sd->dacl, + &sd_size); + *p_hash_type = xacl.info.sd_hs3->hash_type; + /* Current version 3. */ + memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE); + break; + default: + return NT_STATUS_REVISION_MISMATCH; } - *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_hs->sd->type | SEC_DESC_SELF_RELATIVE, - (security_info & OWNER_SECURITY_INFORMATION) - ? xacl.info.sd_hs->sd->owner_sid : NULL, - (security_info & GROUP_SECURITY_INFORMATION) - ? xacl.info.sd_hs->sd->group_sid : NULL, - (security_info & SACL_SECURITY_INFORMATION) - ? xacl.info.sd_hs->sd->sacl : NULL, - (security_info & DACL_SECURITY_INFORMATION) - ? xacl.info.sd_hs->sd->dacl : NULL, - &sd_size); - - memcpy(hash, xacl.info.sd_hs->hash, 16); TALLOC_FREE(xacl.info.sd); return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; @@ -166,20 +183,22 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob, - uint8_t hash[16]) + uint16_t hash_type, + uint8_t hash[XATTR_SD_HASH_SIZE]) { struct xattr_NTACL xacl; - struct security_descriptor_hash sd_hs; + struct security_descriptor_hash_v3 sd_hs3; enum ndr_err_code ndr_err; TALLOC_CTX *ctx = talloc_tos(); ZERO_STRUCT(xacl); - ZERO_STRUCT(sd_hs); + ZERO_STRUCT(sd_hs3); - xacl.version = 2; - xacl.info.sd_hs = &sd_hs; - xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd); - memcpy(&xacl.info.sd_hs->hash[0], hash, 16); + xacl.version = 3; + xacl.info.sd_hs3 = &sd_hs3; + xacl.info.sd_hs3->sd = CONST_DISCARD(struct security_descriptor *, psd); + xacl.info.sd_hs3->hash_type = hash_type; + memcpy(&xacl.info.sd_hs3->hash[0], hash, XATTR_SD_HASH_SIZE); ndr_err = ndr_push_struct_blob( pblob, ctx, NULL, &xacl, @@ -274,13 +293,14 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, files_struct *fsp, const char *name, - uint32 security_info, + uint32_t security_info, struct security_descriptor **ppdesc) { DATA_BLOB blob; NTSTATUS status; - uint8_t hash[16]; - uint8_t hash_tmp[16]; + uint16_t hash_type; + uint8_t hash[XATTR_SD_HASH_SIZE]; + uint8_t hash_tmp[XATTR_SD_HASH_SIZE]; struct security_descriptor *pdesc_next = NULL; if (fsp && name == NULL) { @@ -295,18 +315,23 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, return status; } - status = parse_acl_blob(&blob, security_info, ppdesc, &hash[0]); + status = parse_acl_blob(&blob, ppdesc, + &hash_type, &hash[0]); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("parse_acl_blob returned %s\n", nt_errstr(status))); return status; } - /* If there was no stored hash, don't check. */ - memset(&hash_tmp[0], '\0', 16); - if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) { - /* No hash, goto return blob sd. */ - goto out; + /* Ensure the hash type is one we know. */ + switch (hash_type) { + case XATTR_SD_HASH_TYPE_NONE: + /* No hash, goto return blob sd. */ + goto out; + case XATTR_SD_HASH_TYPE_SHA256: + break; + default: + return NT_STATUS_REVISION_MISMATCH; } /* Get the full underlying sd, then hash. */ @@ -326,12 +351,12 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, goto out; } - status = hash_sd(pdesc_next, hash_tmp); + status = hash_sd_sha256(pdesc_next, hash_tmp); if (!NT_STATUS_IS_OK(status)) { goto out; } - if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) { + if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) { TALLOC_FREE(pdesc_next); /* Hash matches, return blob sd. */ goto out; @@ -357,6 +382,19 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, out: + if (!(security_info & OWNER_SECURITY_INFORMATION)) { + (*ppdesc)->owner_sid = NULL; + } + if (!(security_info & GROUP_SECURITY_INFORMATION)) { + (*ppdesc)->group_sid = NULL; + } + if (!(security_info & DACL_SECURITY_INFORMATION)) { + (*ppdesc)->dacl = NULL; + } + if (!(security_info & SACL_SECURITY_INFORMATION)) { + (*ppdesc)->sacl = NULL; + } + TALLOC_FREE(blob.data); return status; } @@ -420,7 +458,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, DATA_BLOB blob; size_t size; char *parent_name; - uint8_t hash[16]; + uint8_t hash[XATTR_SD_HASH_SIZE]; if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; @@ -511,11 +549,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, return status; } - status = hash_sd(pdesc_next, hash); + status = hash_sd_sha256(pdesc_next, hash); if (!NT_STATUS_IS_OK(status)) { return status; } - status = create_acl_blob(psd, &blob, hash); + status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -630,7 +668,7 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m *********************************************************************/ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info, struct security_descriptor **ppdesc) + uint32_t security_info, struct security_descriptor **ppdesc) { return get_nt_acl_xattr_internal(handle, fsp, NULL, security_info, ppdesc); @@ -641,7 +679,7 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, *********************************************************************/ static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle, - const char *name, uint32 security_info, struct security_descriptor **ppdesc) + const char *name, uint32_t security_info, struct security_descriptor **ppdesc) { return get_nt_acl_xattr_internal(handle, NULL, name, security_info, ppdesc); @@ -652,12 +690,12 @@ static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle, *********************************************************************/ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info_sent, const struct security_descriptor *psd) + uint32_t security_info_sent, const struct security_descriptor *psd) { NTSTATUS status; DATA_BLOB blob; struct security_descriptor *pdesc_next = NULL; - uint8_t hash[16]; + uint8_t hash[XATTR_SD_HASH_SIZE]; if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", @@ -712,7 +750,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, return status; } - status = hash_sd(pdesc_next, hash); + status = hash_sd_sha256(pdesc_next, hash); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -741,7 +779,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, NDR_PRINT_DEBUG(security_descriptor, CONST_DISCARD(struct security_descriptor *,psd)); } - create_acl_blob(psd, &blob, hash); + create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash); store_acl_blob_fsp(handle, fsp, &blob); return NT_STATUS_OK; |