diff --git a/include/ntfs-3g/acls.h b/include/ntfs-3g/acls.h index 8a83d32d..4b083886 100644 --- a/include/ntfs-3g/acls.h +++ b/include/ntfs-3g/acls.h @@ -185,7 +185,8 @@ char *ntfs_build_descr_posix(struct MAPPING* const mapping[], #endif /* POSIXACLS */ int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, - const SID *usid, const SID *gsid, BOOL fordir); + const SID *usid, const SID *gsid, + BOOL fordir, le16 inherited); int ntfs_build_permissions(const char *securattr, const SID *usid, const SID *gsid, BOOL isdir); char *ntfs_build_descr(mode_t mode, diff --git a/libntfs-3g/acls.c b/libntfs-3g/acls.c index fdfa4fd3..a43552d2 100644 --- a/libntfs-3g/acls.c +++ b/libntfs-3g/acls.c @@ -136,6 +136,19 @@ static const char worldsidbytes[] = { 0, 0, 0, 0 /* 1st level */ } ; +/* + * SID for authenticated user (S-1-5-11) + */ + +static const char authsidbytes[] = { + 1, /* revision */ + 1, /* auth count */ + 0, 0, 0, 0, 0, 5, /* base */ + 11, 0, 0, 0 /* 1st level */ +}; + +static const SID *authsid = (const SID*)authsidbytes; + const SID *worldsid = (const SID*)worldsidbytes; /* @@ -670,7 +683,8 @@ BOOL ntfs_valid_descr(const char *securattr, unsigned int attrsz) */ int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, - const SID *usid, const SID *gsid, BOOL fordir) + const SID *usid, const SID *gsid, BOOL fordir, + le16 inherited) { unsigned int src; unsigned int dst; @@ -683,7 +697,9 @@ int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, int gsidsz; const ACCESS_ALLOWED_ACE *poldace; ACCESS_ALLOWED_ACE *pnewace; + ACCESS_ALLOWED_ACE *pauthace; + pauthace = (ACCESS_ALLOWED_ACE*)NULL; usidsz = ntfs_sid_size(usid); gsidsz = ntfs_sid_size(gsid); @@ -700,8 +716,12 @@ int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, for (nace = 0; nace < oldcnt; nace++) { poldace = (const ACCESS_ALLOWED_ACE*)((const char*)oldacl + src); acesz = le16_to_cpu(poldace->size); - /* inheritance for access */ - if (poldace->flags & selection) { + /* + * Inheritance for access, unless this is inheriting + * an inherited ACL to a directory. + */ + if ((poldace->flags & selection) + && !(fordir && inherited)) { pnewace = (ACCESS_ALLOWED_ACE*) ((char*)newacl + dst); memcpy(pnewace,poldace,acesz); @@ -772,9 +792,27 @@ int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, pnewace->flags &= ~(OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); - dst += acesz; - newcnt++; + /* + * Group similar ACE for authenticated users + * (should probably be done for other SIDs) + */ + if (!fordir + && (poldace->type == ACCESS_ALLOWED_ACE_TYPE) + && ntfs_same_sid(&poldace->sid, authsid)) { + if (pauthace) { + pauthace->flags |= pnewace->flags; + pauthace->mask |= pnewace->mask; + } else { + pauthace = pnewace; + dst += acesz; + newcnt++; + } + } else { + dst += acesz; + newcnt++; + } } + /* inheritance for further inheritance */ if (fordir && (poldace->flags @@ -794,6 +832,8 @@ int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, memcpy(&pnewace->sid, gsid, gsidsz); acesz = gsidsz + 8; } + if (inherited) + pnewace->flags |= INHERITED_ACE; dst += acesz; newcnt++; } diff --git a/libntfs-3g/security.c b/libntfs-3g/security.c index 4f2865b7..57e7331e 100644 --- a/libntfs-3g/security.c +++ b/libntfs-3g/security.c @@ -3810,7 +3810,9 @@ static le32 build_inherited_id(struct SECURITY_CONTEXT *scx, pnhead = (SECURITY_DESCRIPTOR_RELATIVE*)newattr; pnhead->revision = SECURITY_DESCRIPTOR_REVISION; pnhead->alignment = 0; - pnhead->control = SE_SELF_RELATIVE; + pnhead->control = (pphead->control + & (SE_DACL_AUTO_INHERITED | SE_SACL_AUTO_INHERITED)) + | SE_SELF_RELATIVE; pos = sizeof(SECURITY_DESCRIPTOR_RELATIVE); /* * locate and inherit DACL @@ -3821,7 +3823,9 @@ static le32 build_inherited_id(struct SECURITY_CONTEXT *scx, offpacl = le32_to_cpu(pphead->dacl); ppacl = (const ACL*)&parentattr[offpacl]; pnacl = (ACL*)&newattr[pos]; - aclsz = ntfs_inherit_acl(ppacl, pnacl, usid, gsid, fordir); + aclsz = ntfs_inherit_acl(ppacl, pnacl, usid, gsid, + fordir, pphead->control + & SE_DACL_AUTO_INHERITED); if (aclsz) { pnhead->dacl = cpu_to_le32(pos); pos += aclsz; @@ -3836,7 +3840,9 @@ static le32 build_inherited_id(struct SECURITY_CONTEXT *scx, offpacl = le32_to_cpu(pphead->sacl); ppacl = (const ACL*)&parentattr[offpacl]; pnacl = (ACL*)&newattr[pos]; - aclsz = ntfs_inherit_acl(ppacl, pnacl, usid, gsid, fordir); + aclsz = ntfs_inherit_acl(ppacl, pnacl, usid, gsid, + fordir, pphead->control + & SE_SACL_AUTO_INHERITED); if (aclsz) { pnhead->sacl = cpu_to_le32(pos); pos += aclsz; diff --git a/src/secaudit.c b/src/secaudit.c index 1ee222d4..95867add 100644 --- a/src/secaudit.c +++ b/src/secaudit.c @@ -194,6 +194,10 @@ * * Jun 2012, version 1.3.23 * - added support for SACL (nickgarvey) + * + * Jul 2012, version 1.3.24 + * - added self-tests for authenticated users + * - added display of ace-inherited flag */ /* @@ -217,7 +221,7 @@ * General parameters which may have to be adapted to needs */ -#define AUDT_VERSION "1.3.23" +#define AUDT_VERSION "1.3.24" #define GET_FILE_SECURITY "ntfs_get_file_security" #define SET_FILE_SECURITY "ntfs_set_file_security" @@ -1630,6 +1634,8 @@ void showace(const char *attr, int off, int isdir, int level) printf("%*cDon\'t propagate inherits ACE\n",-level-4,marker); if (flags & 8) printf("%*cInherit only ACE\n",-level-4,marker); + if (flags & 0x10) + printf("%*cACE was inherited\n",-level-4,marker); if (flags & 0x40) printf("%*cAudit on success\n",-level-4,marker); if (flags & 0x80) diff --git a/src/secaudit.h b/src/secaudit.h index 1255478f..38a24ad6 100644 --- a/src/secaudit.h +++ b/src/secaudit.h @@ -516,7 +516,8 @@ enum { #define CONTAINER_INHERIT_ACE (0x2) #define NO_PROPAGATE_INHERIT_ACE (0x4) #define INHERIT_ONLY_ACE (0x8) -#define VALID_INHERIT_FLAGS (0xF) +#define INHERITED_ACE (0x10) +#define VALID_INHERIT_FLAGS (0x1F) /* * Other useful definitions @@ -533,6 +534,12 @@ enum { #define ACL_REVISION_DS 4 #endif +#ifndef INHERITED_ACE /* not always defined in */ +#define INHERITED_ACE (0x10) +#undef VALID_INHERIT_FLAGS +#define VALID_INHERIT_FLAGS (0x1F) +#endif + /* * Matching of ntfs permissions to Linux permissions * these constants are adapted to endianness