From 2e86428fc00f19363043603c415f9152b9a0a271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Tue, 25 May 2010 10:05:10 +0200 Subject: [PATCH] redefined a default user mapping (a few changes in mount options) --- include/ntfs-3g/param.h | 8 ++++ include/ntfs-3g/security.h | 6 ++- libntfs-3g/security.c | 43 ++++++++++++++------ src/lowntfs-3g.c | 4 +- src/ntfs-3g.8.in | 45 +++++++++++---------- src/ntfs-3g.c | 4 +- src/secaudit.c | 81 ++++++++++++++++++++++++++++++++------ src/secaudit.h | 11 ++++-- 8 files changed, 152 insertions(+), 50 deletions(-) diff --git a/include/ntfs-3g/param.h b/include/ntfs-3g/param.h index b309e300..e474ebf0 100644 --- a/include/ntfs-3g/param.h +++ b/include/ntfs-3g/param.h @@ -31,6 +31,14 @@ #define FORCE_FORMAT_v1x 0 /* Insert security data as in NTFS v1.x */ #define OWNERFROMACL 1 /* Get the owner from ACL (not Windows owner) */ + /* default security sub-authorities */ +enum { + DEFSECAUTH1 = -1153374643, /* 3141592653 */ + DEFSECAUTH2 = 589793238, + DEFSECAUTH3 = 462843383, + DEFSECBASE = 10000 +}; + /* * Permission checking modes for high level and low level * diff --git a/include/ntfs-3g/security.h b/include/ntfs-3g/security.h index f95c3314..4f3b5c54 100644 --- a/include/ntfs-3g/security.h +++ b/include/ntfs-3g/security.h @@ -34,6 +34,9 @@ #define POSIXACLS 0 #endif +typedef u16 be16; +typedef u32 be32; + #if __BYTE_ORDER == __LITTLE_ENDIAN #define const_cpu_to_be16(x) ((((x) & 255L) << 8) + (((x) >> 8) & 255L)) #define const_cpu_to_be32(x) ((((x) & 255L) << 24) + (((x) & 0xff00L) << 8) \ @@ -240,7 +243,8 @@ extern int ntfs_sd_add_everyone(ntfs_inode *ni); extern le32 ntfs_security_hash(const SECURITY_DESCRIPTOR_RELATIVE *sd, const u32 len); -int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path); +int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path, + BOOL allowdef); int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, struct stat*); int ntfs_set_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, mode_t mode); diff --git a/libntfs-3g/security.c b/libntfs-3g/security.c index 55394adf..11df14e7 100644 --- a/libntfs-3g/security.c +++ b/libntfs-3g/security.c @@ -3970,14 +3970,13 @@ static int link_group_members(struct SECURITY_CONTEXT *scx) return (res); } - /* * Apply default single user mapping * returns zero if successful */ static int ntfs_do_default_mapping(struct SECURITY_CONTEXT *scx, - const SID *usid) + uid_t uid, gid_t gid, const SID *usid) { struct MAPPING *usermapping; struct MAPPING *groupmapping; @@ -3995,10 +3994,10 @@ static int ntfs_do_default_mapping(struct SECURITY_CONTEXT *scx, groupmapping = (struct MAPPING*)ntfs_malloc(sizeof(struct MAPPING)); if (groupmapping) { usermapping->sid = sid; - usermapping->xid = scx->uid; + usermapping->xid = uid; usermapping->next = (struct MAPPING*)NULL; groupmapping->sid = sid; - groupmapping->xid = scx->uid; + groupmapping->xid = gid; groupmapping->next = (struct MAPPING*)NULL; scx->mapping[MAPUSERS] = usermapping; scx->mapping[MAPGROUPS] = groupmapping; @@ -4007,7 +4006,6 @@ static int ntfs_do_default_mapping(struct SECURITY_CONTEXT *scx, } } return (res); - } /* @@ -4049,6 +4047,8 @@ static BOOL check_mapping(const struct MAPPING *usermapping, #endif +#if 0 /* not used any more */ + /* * Try and apply default single user mapping * returns zero if successful @@ -4070,7 +4070,8 @@ static int ntfs_default_mapping(struct SECURITY_CONTEXT *scx) phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr; usid = (SID*)&securattr[le32_to_cpu(phead->owner)]; if (ntfs_is_user_sid(usid)) - res = ntfs_do_default_mapping(scx,usid); + res = ntfs_do_default_mapping(scx, + scx->uid, scx->gid, usid); free(securattr); } ntfs_inode_close(ni); @@ -4078,6 +4079,8 @@ static int ntfs_default_mapping(struct SECURITY_CONTEXT *scx) return (res); } +#endif + /* * Basic read from a user mapping file on another volume */ @@ -4110,7 +4113,8 @@ static int localread(void *fileid, char *buf, size_t size, off_t offs) * (failure should not be interpreted as an error) */ -int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path) +int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path, + BOOL allowdef) { struct MAPLIST *item; struct MAPLIST *firstitem; @@ -4118,6 +4122,22 @@ int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path) struct MAPPING *groupmapping; ntfs_inode *ni; int fd; + static struct { + u8 revision; + u8 levels; + be16 highbase; + be32 lowbase; + le32 level1; + le32 level2; + le32 level3; + le32 level4; + le32 level5; + } defmap = { + 1, 5, const_cpu_to_be16(0), const_cpu_to_be32(5), + const_cpu_to_le32(21), + const_cpu_to_le32(DEFSECAUTH1), const_cpu_to_le32(DEFSECAUTH2), + const_cpu_to_le32(DEFSECAUTH3), const_cpu_to_le32(DEFSECBASE) + } ; /* be sure not to map anything until done */ scx->mapping[MAPUSERS] = (struct MAPPING*)NULL; @@ -4157,9 +4177,10 @@ int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path) firstitem = item; } } else { - /* no mapping file, try default mapping */ - if (scx->uid && scx->gid) { - if (!ntfs_default_mapping(scx)) + /* no mapping file, try a default mapping */ + if (allowdef) { + if (!ntfs_do_default_mapping(scx, + 0, 0, (const SID*)&defmap)) ntfs_log_info("Using default user mapping\n"); } } @@ -5120,7 +5141,7 @@ struct SECURITY_API *ntfs_initialize_file_security(const char *device, scx->pseccache = &scapi->seccache; scx->vol->secure_flags = 0; /* accept no mapping and no $Secure */ - ntfs_build_mapping(scx,(const char*)NULL); + ntfs_build_mapping(scx,(const char*)NULL,TRUE); ntfs_open_secure(vol); } else { if (scapi) diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index 96c0713b..5284ec02 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -4420,7 +4420,9 @@ int main(int argc, char *argv[]) /* to initialize security data */ if (ntfs_open_secure(ctx->vol) && (ctx->vol->major_ver >= 3)) failed_secure = "Could not open file $Secure"; - if (!ntfs_build_mapping(&ctx->security,ctx->usermap_path)) { + if (!ntfs_build_mapping(&ctx->security,ctx->usermap_path, + (ctx->vol->secure_flags & (1 << SECURITY_DEFAULT)) + && !(ctx->vol->secure_flags & (1 << SECURITY_WANTED)))) { #if POSIXACLS if (ctx->vol->secure_flags & (1 << SECURITY_DEFAULT)) permissions_mode = "User mapping built, Posix ACLs not used"; diff --git a/src/ntfs-3g.8.in b/src/ntfs-3g.8.in index a828c8b6..a99fd55c 100644 --- a/src/ntfs-3g.8.in +++ b/src/ntfs-3g.8.in @@ -38,7 +38,7 @@ The \fIvolume\fR to be mounted can be either a block device or an image file. .SS Access Handling and Security By default, files and directories are owned by the effective -user and group of the mounting process and everybody has +user and group of the mounting process, and everybody has full read, write, execution and directory browsing permissions. You can also assign permissions to a single user by using the .B uid @@ -55,10 +55,10 @@ options. Doing so, Windows users have full access to the files created by .B ntfs-3g. .PP -But, by defining a Windows-to-Linux user mapping in the file -\fB.NTFS-3G/UserMapping\fP, you can benefit from the full ownership and -permissions features as defined by Posix and those ownership and -permissions will be applied to Windows users and conversely. +But, by setting the default_permissions option, you can benefit from the full +ownership and permissions features as defined by POSIX. By defining a +Windows-to-Linux user mapping, the ownership and permissions will even be +applied to Windows users and conversely. .PP If .B ntfs-3g @@ -125,17 +125,15 @@ When a user mapping file is defined, the options \fBuid=\fP, \fBgid=\fP, .RE .TP .B default_permissions -Use standard access control. This option requires either a user mapping -file to be present, or the options \fIuid=\fP and \fIgid=\fP of a user -to be defined. This option is set by default when a user mapping file -or an ownership related option is present. +Set standard permissions on created files and use standard access control. +This option is set by default when a user mapping file or an ownership related +option is present. .TP .B inherit When creating a new file, set its initial ownership and protections according to inheritance rules defined in parent directory. These rules deviate from Posix specifications, but yield a better Windows -compatibility. A valid user mapping file is required for this option -to be effective. +compatibility. .TP .B ro Mount filesystem read\-only. Useful if Windows is hibernated or the @@ -259,9 +257,10 @@ the \fBuid\fP and \fBgid\fP used by Linux. As a consequence a mapping between the ids has to be defined for ownerships to be recorded into NTFS and recognized. .P -By default this mapping is fetched from the file \fB.NTFS-3G/UserMapping\fP +By default, this mapping is fetched from the file \fB.NTFS-3G/UserMapping\fP located in the NTFS partition. The option \fBusermapping=\fP may be used -to define another location. +to define another location. When the option default_permissions is set and +no mapping file is found, a default mapping is used. .P Each line in the user mapping file defines a mapping. It is organized in three fields separated by colons. The first field identifies a \fBuid\fP, @@ -270,18 +269,21 @@ corresponding NTFS id, known as a \fBSID\fP. The \fBuid\fP and the \fBgid\fP are optional and defining both of them for the same \fBSID\fP is not recommended. .P -If no interoperation with Windows is needed, a single default mapping -with no uid and gid can be used. Just copy the example below and replace -the 9 and 10-digit numbers by any number not greater than 4294967295. +If no strong interoperation with Windows is needed, a single default mapping +with no uid and gid can be used. Files created on Linux will appear to +Windows as owned by a foreign user, and files created on Windows will appear +to Linux as owned by root. Just copy the example below and replace the 9 and +10-digit numbers by any number not greater than 4294967295. The resulting +behavior is the same as the one with the option default_permission set with +no ownership option and no user mapping file available. .RS .sp .B ::S-1-5-21-3141592653-589793238-462643383-10000 .sp .RE -If interoperation with Windows is needed, the mapping has to be defined -for each user and group known in both system, and the \fBSID\fPs used -by Windows has to be collected. This will lead to a user mapping file -like : +If a strong interoperation with Windows is needed, the mapping has to be +defined for each user and group known in both system, and the \fBSID\fPs used +by Windows has to be collected. This will lead to a user mapping file like : .RS .sp .B john::S-1-5-21-3141592653-589793238-462643383-1008 @@ -291,7 +293,8 @@ like : .sp .RE .P -The utility \fBntfs-3g.usermap\fP may be used to create the user mapping file. +The utility \fBntfs-3g.usermap\fP may be used to create such a user +mapping file. .SH EXAMPLES Mount /dev/sda1 to /mnt/windows: .RS diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 5737c5eb..888edb99 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -4372,7 +4372,9 @@ int main(int argc, char *argv[]) /* to initialize security data */ if (ntfs_open_secure(ctx->vol) && (ctx->vol->major_ver >= 3)) failed_secure = "Could not open file $Secure"; - if (!ntfs_build_mapping(&ctx->security,ctx->usermap_path)) { + if (!ntfs_build_mapping(&ctx->security,ctx->usermap_path, + (ctx->vol->secure_flags & (1 << SECURITY_DEFAULT)) + && !(ctx->vol->secure_flags & (1 << SECURITY_WANTED)))) { #if POSIXACLS if (ctx->vol->secure_flags & (1 << SECURITY_DEFAULT)) permissions_mode = "User mapping built, Posix ACLs not used"; diff --git a/src/secaudit.c b/src/secaudit.c index 9ff517f2..a6fbf859 100644 --- a/src/secaudit.c +++ b/src/secaudit.c @@ -173,6 +173,7 @@ * - repeated the fix for return code of dorestore() * * Mar 2010, version 1.3.17 + * - adapted to new default user mapping * - fixed #ifdef'd code for selftest */ @@ -2101,6 +2102,44 @@ int dummyread(void *fileid __attribute__((unused)), #endif /* POSIXACLS & SELFTESTS & !USESTUBS */ +/* + * Apply default single user mapping + * returns zero if successful + */ + +static int do_default_mapping(struct MAPPING *mapping[], + const SID *usid) +{ + struct MAPPING *usermapping; + struct MAPPING *groupmapping; + SID *sid; + int sidsz; + int res; + + res = -1; + sidsz = ntfs_sid_size(usid); + sid = (SID*)ntfs_malloc(sidsz); + if (sid) { + memcpy(sid,usid,sidsz); + usermapping = (struct MAPPING*)ntfs_malloc(sizeof(struct MAPPING)); + if (usermapping) { + groupmapping = (struct MAPPING*)ntfs_malloc(sizeof(struct MAPPING)); + if (groupmapping) { + usermapping->sid = sid; + usermapping->xid = 0; + usermapping->next = (struct MAPPING*)NULL; + groupmapping->sid = sid; + groupmapping->xid = 0; + groupmapping->next = (struct MAPPING*)NULL; + mapping[MAPUSERS] = usermapping; + mapping[MAPGROUPS] = groupmapping; + res = 0; + } + } + } + return (res); +} + /* * Build the user mapping * - according to a mapping file if defined (or default present), @@ -2126,6 +2165,22 @@ int local_build_mapping(struct MAPPING *mapping[], const char *usermap_path) struct MAPLIST *firstitem = (struct MAPLIST*)NULL; struct MAPPING *usermapping; struct MAPPING *groupmapping; + static struct { + u8 revision; + u8 levels; + be16 highbase; + be32 lowbase; + le32 level1; + le32 level2; + le32 level3; + le32 level4; + le32 level5; + } defmap = { + 1, 5, const_cpu_to_be16(0), const_cpu_to_be32(5), + const_cpu_to_le32(21), + const_cpu_to_le32(DEFSECAUTH1), const_cpu_to_le32(DEFSECAUTH2), + const_cpu_to_le32(DEFSECAUTH3), const_cpu_to_le32(DEFSECBASE) + } ; /* be sure not to map anything until done */ mapping[MAPUSERS] = (struct MAPPING*)NULL; @@ -2201,6 +2256,8 @@ int local_build_mapping(struct MAPPING *mapping[], const char *usermap_path) #endif firstitem = item; } + } else { + do_default_mapping(mapping,(const SID*)&defmap); } if (mapping[MAPUSERS]) mappingtype = MAPLOCAL; @@ -2784,14 +2841,14 @@ void tryposix(struct POSIX_SECURITY *pxdesc) le32 owner_sid[] = /* S-1-5-21-3141592653-589793238-462843383-1016 */ { cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), - cpu_to_le32(AUTH1), cpu_to_le32(AUTH2), - cpu_to_le32(AUTH3), cpu_to_le32(1016) + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(1016) } ; le32 group_sid[] = /* S-1-5-21-3141592653-589793238-462843383-513 */ { cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), - cpu_to_le32(AUTH1), cpu_to_le32(AUTH2), - cpu_to_le32(AUTH3), cpu_to_le32(513) + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(513) } ; char *attr; @@ -3039,14 +3096,14 @@ void check_samples() le32 owner3[] = /* S-1-5-21-3141592653-589793238-462843383-1016 */ { cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), - cpu_to_le32(AUTH1), cpu_to_le32(AUTH2), - cpu_to_le32(AUTH3), cpu_to_le32(1016) + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(1016) } ; le32 group3[] = /* S-1-5-21-3141592653-589793238-462843383-513 */ { cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), - cpu_to_le32(AUTH1), cpu_to_le32(AUTH2), - cpu_to_le32(AUTH3), cpu_to_le32(513) + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(513) } ; #if POSIXACLS @@ -3855,14 +3912,14 @@ void selftests(void) le32 owner_sid[] = /* S-1-5-21-3141592653-589793238-462843383-1016 */ { cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), - cpu_to_le32(AUTH1), cpu_to_le32(AUTH2), - cpu_to_le32(AUTH3), cpu_to_le32(1016) + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(1016) } ; le32 group_sid[] = /* S-1-5-21-3141592653-589793238-462843383-513 */ { cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), - cpu_to_le32(AUTH1), cpu_to_le32(AUTH2), - cpu_to_le32(AUTH3), cpu_to_le32(513) + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(513) } ; #if POSIXACLS #ifdef STSC diff --git a/src/secaudit.h b/src/secaudit.h index 7f0d6da2..75c8ece1 100644 --- a/src/secaudit.h +++ b/src/secaudit.h @@ -260,9 +260,14 @@ struct SECURITY_DATA { unsigned int flags:4; } ; -#define AUTH1 3141592653U -#define AUTH2 589793238 -#define AUTH3 462843383 + /* default security sub-authorities */ +enum { + DEFSECAUTH1 = -1153374643, /* 3141592653 */ + DEFSECAUTH2 = 589793238, + DEFSECAUTH3 = 462843383, + DEFSECBASE = 10000 +}; + #define OWNERID 1016 #define GROUPID 513