193 files changed, 80411 insertions, 44563 deletions
diff --git a/libntfs-3g/acls.c b/libntfs-3g/acls.c index 11054ba..e762310 100755 --- a/libntfs-3g/acls.c +++ b/libntfs-3g/acls.c @@ -4,7 +4,7 @@ * This module is part of ntfs-3g library, but may also be * integrated in tools running over Linux or Windows * - * Copyright (c) 2007-2009 Jean-Pierre Andre + * Copyright (c) 2007-2012 Jean-Pierre Andre * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -76,10 +76,7 @@ #include <string.h> #include <stdlib.h> #include <stdarg.h> -#ifdef HAVE_SYS_TYPES_H #include <sys/types.h> -#endif - #include <errno.h> /* @@ -108,7 +105,7 @@ #include <dlfcn.h> #endif /* STSC */ #endif /* WIN32 */ -//#include "secaudit.h" +#include "secaudit.h" #endif /* HAVE_CONFIG_H */ /* @@ -139,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; /* @@ -238,6 +248,12 @@ static int is_world_sid(const SID * usid) && (usid->identifier_authority.low_part == const_cpu_to_be32(5)) && (usid->sub_authority[0] == const_cpu_to_le32(32)) && (usid->sub_authority[1] == const_cpu_to_le32(545))) + + /* check whether S-1-5-11 : authenticated user */ + || ((usid->sub_authority_count == 1) + && (usid->identifier_authority.high_part == const_cpu_to_be16(0)) + && (usid->identifier_authority.low_part == const_cpu_to_be32(5)) + && (usid->sub_authority[0] == const_cpu_to_le32(11))) ); } @@ -525,9 +541,7 @@ gid_t ntfs_find_group(const struct MAPPING* groupmapping, const SID * gsid) { gid_t gid; const struct MAPPING *p; - int gsidsz; - gsidsz = ntfs_sid_size(gsid); p = groupmapping; while (p && p->xid && !ntfs_same_sid(gsid, p->sid)) p = p->next; @@ -618,7 +632,6 @@ BOOL ntfs_valid_descr(const char *securattr, unsigned int attrsz) * old revision and no DACL though SE_DACL_PRESENT is set */ if ((attrsz >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) - && (ntfs_attr_size(securattr) <= attrsz) && (phead->revision == SECURITY_DESCRIPTOR_REVISION) && (offowner >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) && ((offowner + 2) < attrsz) @@ -626,14 +639,15 @@ BOOL ntfs_valid_descr(const char *securattr, unsigned int attrsz) && ((offgroup + 2) < attrsz) && (!offdacl || ((offdacl >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) - && (offdacl < attrsz))) + && (offdacl+sizeof(ACL) <= attrsz))) && (!offsacl || ((offsacl >= sizeof(SECURITY_DESCRIPTOR_RELATIVE)) - && (offsacl < attrsz))) + && (offsacl+sizeof(ACL) <= attrsz))) && !(phead->owner & const_cpu_to_le32(3)) && !(phead->group & const_cpu_to_le32(3)) && !(phead->dacl & const_cpu_to_le32(3)) && !(phead->sacl & const_cpu_to_le32(3)) + && (ntfs_attr_size(securattr) <= attrsz) && ntfs_valid_sid((const SID*)&securattr[offowner]) && ntfs_valid_sid((const SID*)&securattr[offgroup]) /* @@ -669,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; @@ -682,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); @@ -699,25 +716,19 @@ 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) { + src += acesz; + /* + * Inheritance for access, unless this is inheriting + * an inherited ACL to a directory. + */ + if ((poldace->flags & selection) + && !(fordir && inherited) + && !ntfs_same_sid(&poldace->sid, ownersid) + && !ntfs_same_sid(&poldace->sid, groupsid)) { pnewace = (ACCESS_ALLOWED_ACE*) ((char*)newacl + dst); memcpy(pnewace,poldace,acesz); - /* - * Replace generic creator-owner and - * creator-group by owner and group - */ - if (ntfs_same_sid(&pnewace->sid, ownersid)) { - memcpy(&pnewace->sid, usid, usidsz); - acesz = usidsz + 8; - pnewace->size = cpu_to_le16(acesz); - } - if (ntfs_same_sid(&pnewace->sid, groupsid)) { - memcpy(&pnewace->sid, gsid, gsidsz); - acesz = gsidsz + 8; - pnewace->size = cpu_to_le16(acesz); - } + /* reencode GENERIC_ALL */ if (pnewace->mask & GENERIC_ALL) { pnewace->mask &= ~GENERIC_ALL; if (fordir) @@ -736,16 +747,70 @@ int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, | FILE_EXEC | cpu_to_le32(0x40); } + /* reencode GENERIC_READ (+ EXECUTE) */ + if (pnewace->mask & GENERIC_READ) { + if (fordir) + pnewace->mask |= OWNER_RIGHTS + | DIR_READ + | DIR_EXEC; + else + pnewace->mask |= OWNER_RIGHTS + | FILE_READ + | FILE_EXEC; + pnewace->mask &= ~(GENERIC_READ + | GENERIC_EXECUTE + | WRITE_DAC + | WRITE_OWNER + | DELETE | FILE_WRITE_EA + | FILE_WRITE_ATTRIBUTES); + } + /* reencode GENERIC_WRITE */ + if (pnewace->mask & GENERIC_WRITE) { + if (fordir) + pnewace->mask |= OWNER_RIGHTS + | DIR_WRITE; + else + pnewace->mask |= OWNER_RIGHTS + | FILE_WRITE; + pnewace->mask &= ~(GENERIC_WRITE + | WRITE_DAC + | WRITE_OWNER + | FILE_DELETE_CHILD); + } /* remove inheritance flags */ 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; + if (inherited) + pnewace->flags |= INHERITED_ACE; + dst += acesz; + newcnt++; + } + } else { + if (inherited) + pnewace->flags |= INHERITED_ACE; + dst += acesz; + newcnt++; + } } - /* inheritance for further inheritance */ - if (fordir - && (poldace->flags + /* + * Inheritance for access, specific to + * creator-owner (and creator-group) + */ + if (fordir || !inherited + || (poldace->flags & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE))) { pnewace = (ACCESS_ALLOWED_ACE*) ((char*)newacl + dst); @@ -753,19 +818,46 @@ int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, /* * Replace generic creator-owner and * creator-group by owner and group + * (but keep for further inheritance) */ if (ntfs_same_sid(&pnewace->sid, ownersid)) { memcpy(&pnewace->sid, usid, usidsz); - acesz = usidsz + 8; + pnewace->size = cpu_to_le16(usidsz + 8); + /* remove inheritance flags */ + pnewace->flags &= ~(OBJECT_INHERIT_ACE + | CONTAINER_INHERIT_ACE + | INHERIT_ONLY_ACE); + if (inherited) + pnewace->flags |= INHERITED_ACE; + dst += usidsz + 8; + newcnt++; } if (ntfs_same_sid(&pnewace->sid, groupsid)) { memcpy(&pnewace->sid, gsid, gsidsz); - acesz = gsidsz + 8; + pnewace->size = cpu_to_le16(gsidsz + 8); + /* remove inheritance flags */ + pnewace->flags &= ~(OBJECT_INHERIT_ACE + | CONTAINER_INHERIT_ACE + | INHERIT_ONLY_ACE); + if (inherited) + pnewace->flags |= INHERITED_ACE; + dst += gsidsz + 8; + newcnt++; } + } + + /* inheritance for further inheritance */ + if (fordir + && (poldace->flags + & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE))) { + pnewace = (ACCESS_ALLOWED_ACE*) + ((char*)newacl + dst); + memcpy(pnewace,poldace,acesz); + if (inherited) + pnewace->flags |= INHERITED_ACE; dst += acesz; newcnt++; } - src += acesz; } /* * Adjust header if something was inherited @@ -1904,7 +1996,6 @@ static int buildacls_posix(struct MAPPING* const mapping[], const SID *sid; int acecnt; int usidsz; - int gsidsz; int wsidsz; int asidsz; int ssidsz; @@ -1912,7 +2003,6 @@ static int buildacls_posix(struct MAPPING* const mapping[], le32 grants; usidsz = ntfs_sid_size(usid); - gsidsz = ntfs_sid_size(gsid); wsidsz = ntfs_sid_size(worldsid); asidsz = ntfs_sid_size(adminsid); ssidsz = ntfs_sid_size(systemsid); @@ -3066,6 +3156,7 @@ static int build_owngrp_permissions(const char *securattr, int nace; le32 special; BOOL grppresent; + BOOL ownpresent; le32 allowown, allowgrp, allowall; le32 denyown, denygrp, denyall; @@ -3075,21 +3166,26 @@ static int build_owngrp_permissions(const char *securattr, special = const_cpu_to_le32(0); allowown = allowgrp = allowall = const_cpu_to_le32(0); denyown = denygrp = denyall = const_cpu_to_le32(0); + ownpresent = FALSE; grppresent = FALSE; if (offdacl) { acecnt = le16_to_cpu(pacl->ace_count); offace = offdacl + sizeof(ACL); - } else + } else { acecnt = 0; + offace = 0; + } for (nace = 0; nace < acecnt; nace++) { pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace]; if (!(pace->flags & INHERIT_ONLY_ACE)) { if ((ntfs_same_sid(usid, &pace->sid) || ntfs_same_sid(ownersid, &pace->sid)) && (pace->mask & WRITE_OWNER)) { - if (pace->type == ACCESS_ALLOWED_ACE_TYPE) + if (pace->type == ACCESS_ALLOWED_ACE_TYPE) { allowown |= pace->mask; - } else + ownpresent = TRUE; + } + } else if (ntfs_same_sid(usid, &pace->sid) && (!(pace->mask & WRITE_OWNER))) { if (pace->type == ACCESS_ALLOWED_ACE_TYPE) { @@ -3110,6 +3206,8 @@ static int build_owngrp_permissions(const char *securattr, } offace += le16_to_cpu(pace->size); } + if (!ownpresent) + allowown = allowall; if (!grppresent) allowgrp = allowall; return (merge_permissions(isdir, @@ -3135,7 +3233,6 @@ static int norm_ownadmin_permissions_posix(struct POSIX_SECURITY *posix_desc, u16 tag; u16 tagsset; struct POSIX_ACE *pxace; - int acccnt; mode_t denywrld; mode_t allow; mode_t deny; @@ -3144,7 +3241,6 @@ static int norm_ownadmin_permissions_posix(struct POSIX_SECURITY *posix_desc, mode = 0; pxace = posix_desc->acl.ace; - acccnt = posix_desc->acccnt; tagsset = 0; denywrld = 0; /* @@ -3714,7 +3810,7 @@ struct POSIX_SECURITY *ntfs_build_permissions_posix( pxace->perms |= POSIX_PERM_DENIAL; else if (pxace->tag == POSIX_ACL_OTHER) - pctx->permswrld = pxace->perms; + pctx->permswrld |= pxace->perms; pctx->tagsset |= pxace->tag; if (pace->flags & INHERIT_ONLY_ACE) { l--; @@ -3884,12 +3980,10 @@ struct POSIX_SECURITY *ntfs_build_permissions_posix( int ntfs_build_permissions(const char *securattr, const SID *usid, const SID *gsid, BOOL isdir) { - const SECURITY_DESCRIPTOR_RELATIVE *phead; int perm; BOOL adminowns; BOOL groupowns; - phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; adminowns = ntfs_same_sid(usid,adminsid) || ntfs_same_sid(gsid,adminsid); groupowns = !adminowns && ntfs_same_sid(gsid,usid); @@ -3960,33 +4054,6 @@ static SID *encodesid(const char *sidstr) } /* - * Early logging before the logs are redirected - * - * (not quite satisfactory : this appears before the ntfs-g banner, - * and with a different pid) - */ - -static void log_early_error(const char *format, ...) - __attribute__((format(printf, 1, 2))); - -static void log_early_error(const char *format, ...) -{ - va_list args; - - va_start(args, format); -#ifdef HAVE_SYSLOG_H - openlog("ntfs-3g", LOG_PID, LOG_USER); - ntfs_log_handler_syslog(NULL, NULL, 0, - NTFS_LOG_LEVEL_ERROR, NULL, - format, args); -#else - vfprintf(stderr,format,args); -#endif - va_end(args); -} - - -/* * Get a single mapping item from buffer * * Always reads a full line, truncating long lines @@ -3999,7 +4066,6 @@ static struct MAPLIST *getmappingitem(FILEREADER reader, void *fileid, { int src; int dst; - char *p; char *q; char *pu; char *pg; @@ -4033,7 +4099,6 @@ static struct MAPLIST *getmappingitem(FILEREADER reader, void *fileid, if (gotend) { pu = pg = (char*)NULL; /* decompose into uid, gid and sid */ - p = item->maptext; item->uidstr = item->maptext; item->gidstr = strchr(item->uidstr, ':'); if (item->gidstr) { @@ -4048,7 +4113,7 @@ static struct MAPLIST *getmappingitem(FILEREADER reader, void *fileid, if (pu && pg) *pu = *pg = '\0'; else { - log_early_error("Bad mapping item \"%s\"\n", + ntfs_log_early_error("Bad mapping item \"%s\"\n", item->maptext); free(item); item = (struct MAPLIST*)NULL; @@ -4177,7 +4242,7 @@ struct MAPPING *ntfs_do_user_mapping(struct MAPLIST *firstitem) if (pwd) uid = pwd->pw_uid; else - log_early_error("Invalid user \"%s\"\n", + ntfs_log_early_error("Invalid user \"%s\"\n", item->uidstr); } } @@ -4257,7 +4322,7 @@ struct MAPPING *ntfs_do_group_mapping(struct MAPLIST *firstitem) if (grp) gid = grp->gr_gid; else - log_early_error("Invalid group \"%s\"\n", + ntfs_log_early_error("Invalid group \"%s\"\n", item->gidstr); } } |