Jeremy.
stored in "security.NTACL"
Version 1. raw SD stored as Samba4 does it.
- Version 2. raw SD + last changed timestamp so we
- can discard if this doesn't match the POSIX st_ctime.
+ Version 2. raw SD + last changed hash so we
+ can discard if this doesn't match the underlying ACL hash.
*/
const char *XATTR_NTACL_NAME = "security.NTACL";
typedef [public] struct {
security_descriptor *sd;
- NTTIME last_changed;
- } security_descriptor_timestamp;
+ uint8 hash[16];
+ } security_descriptor_hash;
typedef [switch_type(uint16)] union {
[case(1)] security_descriptor *sd;
- [case(2)] security_descriptor_timestamp *sd_ts;
+ [case(2)] security_descriptor_hash *sd_hs;
} xattr_NTACL_Info;
typedef [public] struct {
ndr->depth--;
}
-_PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_timestamp(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_timestamp *r)
+_PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_hash(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash *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_NTTIME(ndr, NDR_SCALARS, r->last_changed));
+ NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->hash, 16));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->sd) {
return NDR_ERR_SUCCESS;
}
-_PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_timestamp(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_timestamp *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_hash(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash *r)
{
uint32_t _ptr_sd;
TALLOC_CTX *_mem_save_sd_0;
} else {
r->sd = NULL;
}
- NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->last_changed));
+ NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->hash, 16));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->sd) {
return NDR_ERR_SUCCESS;
}
-_PUBLIC_ void ndr_print_security_descriptor_timestamp(struct ndr_print *ndr, const char *name, const struct security_descriptor_timestamp *r)
+_PUBLIC_ void ndr_print_security_descriptor_hash(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash *r)
{
- ndr_print_struct(ndr, name, "security_descriptor_timestamp");
+ ndr_print_struct(ndr, name, "security_descriptor_hash");
ndr->depth++;
ndr_print_ptr(ndr, "sd", r->sd);
ndr->depth++;
ndr_print_security_descriptor(ndr, "sd", r->sd);
}
ndr->depth--;
- ndr_print_NTTIME(ndr, "last_changed", r->last_changed);
+ ndr_print_array_uint8(ndr, "hash", r->hash, 16);
ndr->depth--;
}
break; }
case 2: {
- NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd_ts));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd_hs));
break; }
default:
break;
case 2:
- if (r->sd_ts) {
- NDR_CHECK(ndr_push_security_descriptor_timestamp(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_ts));
+ if (r->sd_hs) {
+ NDR_CHECK(ndr_push_security_descriptor_hash(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs));
}
break;
int level;
uint16_t _level;
TALLOC_CTX *_mem_save_sd_0;
- TALLOC_CTX *_mem_save_sd_ts_0;
+ TALLOC_CTX *_mem_save_sd_hs_0;
level = ndr_pull_get_switch_value(ndr, r);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &_level));
break; }
case 2: {
- uint32_t _ptr_sd_ts;
- NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd_ts));
- if (_ptr_sd_ts) {
- NDR_PULL_ALLOC(ndr, r->sd_ts);
+ 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);
} else {
- r->sd_ts = NULL;
+ r->sd_hs = NULL;
}
break; }
break;
case 2:
- if (r->sd_ts) {
- _mem_save_sd_ts_0 = NDR_PULL_GET_MEM_CTX(ndr);
- NDR_PULL_SET_MEM_CTX(ndr, r->sd_ts, 0);
- NDR_CHECK(ndr_pull_security_descriptor_timestamp(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_ts));
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sd_ts_0, 0);
+ 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);
}
break;
break;
case 2:
- ndr_print_ptr(ndr, "sd_ts", r->sd_ts);
+ ndr_print_ptr(ndr, "sd_hs", r->sd_hs);
ndr->depth++;
- if (r->sd_ts) {
- ndr_print_security_descriptor_timestamp(ndr, "sd_ts", r->sd_ts);
+ if (r->sd_hs) {
+ ndr_print_security_descriptor_hash(ndr, "sd_hs", r->sd_hs);
}
ndr->depth--;
break;
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_timestamp(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_timestamp *r);
-enum ndr_err_code ndr_pull_security_descriptor_timestamp(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_timestamp *r);
-void ndr_print_security_descriptor_timestamp(struct ndr_print *ndr, const char *name, const struct security_descriptor_timestamp *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);
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);
struct xattr_DosStream *streams;/* [unique,size_is(num_streams)] */
}/* [public] */;
-struct security_descriptor_timestamp {
+struct security_descriptor_hash {
struct security_descriptor *sd;/* [unique] */
- NTTIME last_changed;
+ uint8_t hash[16];
}/* [public] */;
union xattr_NTACL_Info {
struct security_descriptor *sd;/* [unique,case] */
- struct security_descriptor_timestamp *sd_ts;/* [unique,case(2)] */
+ struct security_descriptor_hash *sd_hs;/* [unique,case(2)] */
}/* [switch_type(uint16)] */;
struct xattr_NTACL {
return NT_STATUS_REVISION_MISMATCH;
}
- *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_ts->sd->type | SEC_DESC_SELF_RELATIVE,
+ *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_ts->sd->owner_sid : NULL,
+ ? xacl.info.sd_hs->sd->owner_sid : NULL,
(security_info & GROUP_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->group_sid : NULL,
+ ? xacl.info.sd_hs->sd->group_sid : NULL,
(security_info & SACL_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->sacl : NULL,
+ ? xacl.info.sd_hs->sd->sacl : NULL,
(security_info & DACL_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->dacl : NULL,
+ ? xacl.info.sd_hs->sd->dacl : NULL,
&sd_size);
TALLOC_FREE(xacl.info.sd);
static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
{
struct xattr_NTACL xacl;
- struct security_descriptor_timestamp sd_ts;
+ struct security_descriptor_hash sd_hs;
enum ndr_err_code ndr_err;
TALLOC_CTX *ctx = talloc_tos();
- struct timespec curr = timespec_current();
ZERO_STRUCT(xacl);
- ZERO_STRUCT(sd_ts);
-
- /* Horrid hack as setting an xattr changes the ctime
- * on Linux. This gives a race of 1 second during
- * which we would not see a POSIX ACL set.
- */
- curr.tv_sec += 1;
+ ZERO_STRUCT(sd_hs);
xacl.version = 2;
- xacl.info.sd_ts = &sd_ts;
- xacl.info.sd_ts->sd = CONST_DISCARD(struct security_descriptor *, psd);
- unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr);
-
- DEBUG(10, ("create_acl_blob: timestamp stored as %s\n",
- timestring(ctx, curr.tv_sec) ));
+ 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);
ndr_err = ndr_push_struct_blob(
pblob, ctx, NULL, &xacl,
return NT_STATUS_REVISION_MISMATCH;
}
- *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_ts->sd->type | SEC_DESC_SELF_RELATIVE,
+ *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_ts->sd->owner_sid : NULL,
+ ? xacl.info.sd_hs->sd->owner_sid : NULL,
(security_info & GROUP_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->group_sid : NULL,
+ ? xacl.info.sd_hs->sd->group_sid : NULL,
(security_info & SACL_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->sacl : NULL,
+ ? xacl.info.sd_hs->sd->sacl : NULL,
(security_info & DACL_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->dacl : NULL,
+ ? xacl.info.sd_hs->sd->dacl : NULL,
&sd_size);
TALLOC_FREE(xacl.info.sd);
static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
{
struct xattr_NTACL xacl;
- struct security_descriptor_timestamp sd_ts;
+ struct security_descriptor_hash sd_hs;
enum ndr_err_code ndr_err;
TALLOC_CTX *ctx = talloc_tos();
- struct timespec curr = timespec_current();
ZERO_STRUCT(xacl);
- ZERO_STRUCT(sd_ts);
-
- /* Horrid hack as setting an xattr changes the ctime
- * on Linux. This gives a race of 1 second during
- * which we would not see a POSIX ACL set.
- */
- curr.tv_sec += 1;
+ ZERO_STRUCT(sd_hs);
xacl.version = 2;
- xacl.info.sd_ts = &sd_ts;
- xacl.info.sd_ts->sd = CONST_DISCARD(struct security_descriptor *, psd);
- unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr);
-
- DEBUG(10, ("create_acl_blob: timestamp stored as %s\n",
- timestring(ctx, curr.tv_sec) ));
+ 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);
ndr_err = ndr_push_struct_blob(
pblob, ctx, NULL, &xacl,