From 3d7a28bfa5bcdf7669270f3afca5e672c46f7c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Thu, 7 Apr 2016 09:20:23 +0200 Subject: [PATCH] Adapted secaudit and usermap (now ntfssecaudit and ntfsusermap) to ntfsprogs These tools were originally developed for running on Windows and later ported to libntfs-3g. This patch makes them similar to other ntfsprogs tools, dropping the native Windows interfaces and using libntfs-3g on all platforms. There is no change in usage or supported features, only the command names have changed. --- configure.ac | 4 +- ntfsprogs/Makefile.am | 14 +- ntfsprogs/ntfssecaudit.8.in | 22 +- ntfsprogs/ntfssecaudit.c | 3934 ++++++++++++----------------------- ntfsprogs/ntfsusermap.8.in | 24 +- ntfsprogs/ntfsusermap.c | 957 ++++----- src/Makefile.am | 18 +- src/ntfs-3g.8.in | 2 +- 8 files changed, 1685 insertions(+), 3290 deletions(-) diff --git a/configure.ac b/configure.ac index b14b00af..644ae00a 100644 --- a/configure.ac +++ b/configure.ac @@ -668,11 +668,11 @@ AC_CONFIG_FILES([ ntfsprogs/ntfstruncate.8 ntfsprogs/ntfsfallocate.8 ntfsprogs/ntfsrecover.8 + ntfsprogs/ntfsusermap.8 + ntfsprogs/ntfssecaudit.8 src/Makefile src/ntfs-3g.8 src/ntfs-3g.probe.8 - src/ntfs-3g.usermap.8 - src/ntfs-3g.secaudit.8 ]) AC_OUTPUT diff --git a/ntfsprogs/Makefile.am b/ntfsprogs/Makefile.am index 0bbc70c5..f4f9d1b6 100644 --- a/ntfsprogs/Makefile.am +++ b/ntfsprogs/Makefile.am @@ -17,7 +17,8 @@ if ENABLE_NTFSPROGS bin_PROGRAMS = ntfsfix ntfsinfo ntfscluster ntfsls ntfscat ntfscmp sbin_PROGRAMS = mkntfs ntfslabel ntfsundelete ntfsresize ntfsclone \ ntfscp -EXTRA_PROGRAM_NAMES = ntfswipe ntfstruncate ntfsrecover +EXTRA_PROGRAM_NAMES = ntfswipe ntfstruncate ntfsrecover \ + ntfsusermap ntfssecaudit QUARANTINED_PROGRAM_NAMES = ntfsdump_logfile ntfsmftalloc ntfsmove ntfsck \ ntfsfallocate @@ -26,7 +27,8 @@ man_MANS = mkntfs.8 ntfsfix.8 ntfslabel.8 ntfsinfo.8 \ ntfsundelete.8 ntfsresize.8 ntfsprogs.8 ntfsls.8 \ ntfsclone.8 ntfscluster.8 ntfscat.8 ntfscp.8 \ ntfscmp.8 ntfswipe.8 ntfstruncate.8 \ - ntfsdecrypt.8 ntfsfallocate.8 ntfsrecover.8 + ntfsdecrypt.8 ntfsfallocate.8 ntfsrecover.8 \ + ntfsusermap.8 ntfssecaudit.8 EXTRA_MANS = CLEANFILES = $(EXTRA_PROGRAMS) @@ -106,6 +108,14 @@ ntfsrecover_SOURCES = playlog.c ntfsrecover.c utils.c utils.h ntfsrecover.h ntfsrecover_LDADD = $(AM_LIBS) $(NTFSRECOVER_LIBS) ntfsrecover_LDFLAGS = $(AM_LFLAGS) +ntfsusermap_SOURCES = ntfsusermap.c utils.c utils.h +ntfsusermap_LDADD = $(AM_LIBS) $(NTFSRECOVER_LIBS) +ntfsusermap_LDFLAGS = $(AM_LFLAGS) + +ntfssecaudit_SOURCES = ntfssecaudit.c utils.c utils.h +ntfssecaudit_LDADD = $(AM_LIBS) $(NTFSRECOVER_LIBS) +ntfssecaudit_LDFLAGS = $(AM_LFLAGS) + # We don't distribute these ntfstruncate_SOURCES = attrdef.c ntfstruncate.c utils.c utils.h diff --git a/ntfsprogs/ntfssecaudit.8.in b/ntfsprogs/ntfssecaudit.8.in index 669828e5..b715f4d9 100644 --- a/ntfsprogs/ntfssecaudit.8.in +++ b/ntfsprogs/ntfssecaudit.8.in @@ -1,11 +1,11 @@ -.\" Copyright (c) 2007-2009 Jean-Pierre André. +.\" Copyright (c) 2007-2016 Jean-Pierre André. .\" This file may be copied under the terms of the GNU Public License. .\" -.TH NTFS-3G.SECAUDIT 8 "February 2010" "ntfs-3g.secaudit 1.4.1" +.TH NTFSSECAUDIT 8 "February 2010" "ntfssecaudit 1.5.0" .SH NAME -ntfs-3g.secaudit \- NTFS Security Data Auditing +ntfssecaudit \- NTFS Security Data Auditing .SH SYNOPSIS -.B ntfs-3g.secaudit +.B ntfssecaudit \fB[\fIoptions\fP\fB]\fR .I args .PP @@ -39,7 +39,7 @@ and args define the parameters and the set of files acted upon. .PP Typing secaudit with no args will display a summary of available options. .SH DESCRIPTION -\fBntfs-3g.secaudit\fR +\fBntfssecaudit\fR displays the ownership and permissions of a set of files on an NTFS file system, and checks their consistency. It can be started in terminal mode only (no graphical user interface is available.) @@ -53,7 +53,7 @@ of information. It is therefore advisable to redirect the output to a file or pipe it to a text editor for examination. .SH OPTIONS Below are the valid combinations of options and arguments that -\fBntfs-3g.secaudit\fR accepts. All the indicated arguments are +\fBntfssecaudit\fR accepts. All the indicated arguments are mandatory and must be unique (if wildcards are used, they must resolve to a single name.) .TP @@ -135,25 +135,25 @@ Example : "\fBu::7,g::5,o:0,u:510:rwx,g:500:5,d:u:510:7\fP" Audit the global security data on /dev/sda1 .RS .sp -.B ntfs-3g.secaudit -ar /dev/sda1 +.B ntfssecaudit -ar /dev/sda1 .sp .RE Display the ownership and permissions parameters for files in directory /audio/music on device /dev/sda5, excluding sub-directories : .RS .sp -.B ntfs-3g.secaudit /dev/sda5 /audio/music +.B ntfssecaudit /dev/sda5 /audio/music .sp .RE Set all files in directory /audio/music on device /dev/sda5 as writeable by owner and read-only for everybody : .RS .sp -.B ntfs-3g.secaudit -r /dev/sda5 644 /audio/music +.B ntfssecaudit -r /dev/sda5 644 /audio/music .sp .RE .SH EXIT CODES -.B ntfs-3g.secaudit +.B ntfssecaudit exits with a value of 0 when no error was detected, and with a value of 1 when an error was detected. .SH KNOWN ISSUES @@ -170,7 +170,7 @@ in detail. You can contact the development team on the ntfs\-3g\-devel@lists.sf.net address. .SH AUTHORS -.B ntfs-3g.secaudit +.B ntfssecaudit has been developed by Jean-Pierre André. .SH THANKS Several people made heroic efforts, often over five or more diff --git a/ntfsprogs/ntfssecaudit.c b/ntfsprogs/ntfssecaudit.c index 29236c6d..abd5bfd5 100644 --- a/ntfsprogs/ntfssecaudit.c +++ b/ntfsprogs/ntfssecaudit.c @@ -1,8 +1,8 @@ /* * Display and audit security attributes in an NTFS volume * - * Copyright (c) 2007-2015 Jean-Pierre Andre - * + * Copyright (c) 2007-2016 Jean-Pierre Andre + * * Options : * -a auditing security data * -b backing up NTFS ACLs @@ -33,21 +33,25 @@ * set the security parameters of file to perms (mode or acl) * secaudit -r[v] volume perms directory * set the security parameters of files in directory to perms - * special case, does not require being root : + * special cases, do not require being root : * secaudit [-v] mounted-file * display the security parameters of mounted file + * secaudit -u[v] mounted-file + * display a user mapping proposal * * * On Windows (the volume being part of file name) * secaudit -h [file] * display the security descriptors found in file + * secaudit -a[rv] volume + * audit the volume * secaudit [-v] file * display the security parameters of file * secaudit -r[v] directory * display the security parameters of files in directory * secaudit -b[v] directory * backup the security parameters of files in directory - * secaudit -s[v] [backupfile] + * secaudit -s[v] volume [backupfile] * set the security parameters as indicated in backup * with -e set extra parameters (Windows attrib) * secaudit perms file @@ -221,6 +225,9 @@ * * May 2015, version 1.4.6 * - made to load shared library based on generic name + * + * Mar 2016, Version 1.5.0 + * - reorganized to rely on libntfs-3g even on Windows */ /* @@ -244,312 +251,202 @@ * General parameters which may have to be adapted to needs */ -#define AUDT_VERSION "1.4.6" +#define AUDT_VERSION "1.5.0" -#define GET_FILE_SECURITY "ntfs_get_file_security" -#define SET_FILE_SECURITY "ntfs_set_file_security" -#define GET_FILE_ATTRIBUTES "ntfs_get_file_attributes" -#define SET_FILE_ATTRIBUTES "ntfs_set_file_attributes" -#define READ_DIRECTORY "ntfs_read_directory" -#define READ_SDS "ntfs_read_sds" -#define READ_SII "ntfs_read_sii" -#define READ_SDH "ntfs_read_sdh" -#define GET_USER "ntfs_get_user" -#define GET_GROUP "ntfs_get_group" -#define GET_USID "ntfs_get_usid" -#define GET_GSID "ntfs_get_gsid" -#define INIT_FILE_SECURITY "ntfs_initialize_file_security" -#define LEAVE_FILE_SECURITY "ntfs_leave_file_security" +#define SELFTESTS 0 +#define NOREVBOM 0 /* still unclear what this should be */ /* * External declarations */ -#include -#include -#include -#include -#include -#include -#include -#include - - /* - * integration into secaudit, check whether Win32, - * may have to be adapted to compiler or something else - */ - -#ifndef WIN32 -#if defined(__WIN32) | defined(__WIN32__) | defined(WNSC) -#define WIN32 1 -#endif -#endif - - /* - * integration into secaudit/Win32 - */ -#ifdef WIN32 -#include -#define __LITTLE_ENDIAN 1234 -#define __BYTE_ORDER __LITTLE_ENDIAN -#else - /* - * integration into secaudit/STSC - */ -#ifdef STSC -#include -#undef __BYTE_ORDER -#define __BYTE_ORDER __BIG_ENDIAN -#else - /* - * integration into secaudit/Linux - */ - -#include -#ifdef HAVE_ENDIAN_H -#include -#endif -#ifdef HAVE_MACHINE_ENDIAN_H -#include -#endif -#include -#include -#endif /* STSC */ -#endif /* WIN32 */ -#include "secaudit.h" - -#ifndef WIN32 - -#ifndef STSC - -#if !defined(HAVE_CONFIG_H) && POSIXACLS && !defined(__SVR4) - /* require if not integrated into ntfs-3g package */ -#define HAVE_SETXATTR 1 -#endif - -#ifdef HAVE_CONFIG_H -#ifdef _FILE_OFFSET_BITS -#undef _FILE_OFFSET_BITS /* work around "_FILE_OFFSET_BITS" possibly already defined */ -#endif - /* according to config.h if integrated into ntfs-3g package */ #include "config.h" -#ifdef const /* work around "const" possibly redefined in config.h */ -#undef const -#endif -#ifndef POSIXACLS -#define POSIXACLS 0 -#endif -#endif /* HAVE_CONFIG_H */ +#ifdef HAVE_STDIO_H +#include +#endif /* HAVE_STDIO_H */ +#ifdef HAVE_STDLIB_H +#include +#endif /* HAVE_STDLIB_H */ +#ifdef HAVE_STRING_H +#include +#endif /* HAVE_STRING_H */ +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_TIME_H +#include +#endif /* HAVE_TIME_H */ +#ifdef HAVE_GETOPT_H +#include +#endif /* HAVE_GETOPT_H */ +#ifdef HAVE_ERRNO_H +#include +#endif /* HAVE_ERRNO_H */ +#ifdef HAVE_FCNTL_H +#include +#endif /* HAVE_FCNTL_H */ +#ifdef HAVE_SYS_TYPES_H +#include +#endif /* HAVE_SYS_TYPES_H */ +#ifdef HAVE_SYS_STAT_H +#include +#endif /* HAVE_SYS_STAT_H */ #ifdef HAVE_SETXATTR #include -#else +#else /* HAVE_SETXATTR */ #warning "The extended attribute package is not available" #endif /* HAVE_SETXATTR */ -#endif /* STSC */ - -#define NTFS_MNT_NONE 0 /* no flag for mounting the device */ -#define NTFS_MNT_RDONLY 1 /* flag for mounting the device read-only */ +#include "types.h" +#include "endians.h" +#include "support.h" +#include "layout.h" +#include "param.h" +#include "ntfstime.h" +#include "device_io.h" +#include "device.h" +#include "logging.h" +#include "runlist.h" +#include "mft.h" +#include "inode.h" +#include "attrib.h" +#include "bitmap.h" +#include "index.h" +#include "volume.h" +#include "unistr.h" +#include "mst.h" +#include "security.h" +#include "acls.h" +#include "realpath.h" +#include "utils.h" +#include "misc.h" struct CALLBACK; -typedef int (*dircallback)(struct CALLBACK *context, char *ntfsname, - int length, int type, long long pos, u64 mft_ref, - unsigned int dt_type); +typedef int (*dircallback)(void *context, const ntfschar *ntfsname, + const int length, const int type, const s64 pos, + const MFT_REF mft_ref, const unsigned int dt_type); + +#if POSIXACLS + +static BOOL same_posix(struct POSIX_SECURITY *pxdesc1, + struct POSIX_SECURITY *pxdesc2); + +#endif /* POSIXACLS */ #ifndef HAVE_SYSLOG_H void ntfs_log_early_error(const char *format, ...) __attribute__((format(printf, 1, 2))); -#endif - -#if USESTUBS | defined(STSC) - -int ntfs_get_file_security(void *scapi, - const char *path, DWORD selection, - char *buf, DWORD buflen, LPDWORD psize); -BOOL ntfs_set_file_security(void *scapi, - const char *path, DWORD selection, const char *attr); -int ntfs_get_file_attributes(void *scapi, - const char *path); -BOOL ntfs_set_file_attributes(void *scapi, - const char *path, DWORD attrib); -BOOL ntfs_read_directory(void *scapi, - const char *path, dircallback callback, void *context); -int ntfs_read_sds(void *scapi, - char *buf, DWORD buflen, DWORD offset); -void *ntfs_read_sii(void *scapi, void *entry); -void *ntfs_read_sdh(void *scapi, void *entry); - -int ntfs_get_usid(void *scapi, uid_t uid, char *buf); -int ntfs_get_gsid(void *scapi, gid_t gid, char *buf); -int ntfs_get_user(void *scapi, const char *usid); -int ntfs_get_group(void *scapi, const char *gsid); - -void *ntfs_initialize_file_security(const char *device, unsigned long flags); -BOOL ntfs_leave_file_security(void *scapi); - -#else - -typedef int (*type_get_file_security)(void *scapi, - const char *path, DWORD selection, - char *buf, DWORD buflen, LPDWORD psize); -typedef BOOL (*type_set_file_security)(void *scapi, - const char *path, DWORD selection, const char *attr); -typedef int (*type_get_file_attributes)(void *scapi, - const char *path); -typedef BOOL (*type_set_file_attributes)(void *scapi, - const char *path, DWORD attrib); -typedef BOOL (*type_read_directory)(void *scapi, - const char *path, dircallback callback, void *context); -typedef int (*type_read_sds)(void *scapi, - char *buf, DWORD buflen, DWORD offset); -typedef void *(*type_read_sii)(void *scapi, void *entry); -typedef void *(*type_read_sdh)(void *scapi, void *entry); - -typedef int (*type_get_usid)(void *scapi, uid_t uid, char *buf); -typedef int (*type_get_gsid)(void *scapi, gid_t gid, char *buf); -typedef int (*type_get_user)(void *scapi, const char *usid); -typedef int (*type_get_group)(void *scapi, const char *gsid); - -typedef void *(*type_initialize_file_security)(const char *device, - unsigned long flags); -typedef BOOL (*type_leave_file_security)(void *scapi); - -type_get_file_security ntfs_get_file_security; -type_set_file_security ntfs_set_file_security; -type_get_file_attributes ntfs_get_file_attributes; -type_set_file_attributes ntfs_set_file_attributes; -type_read_directory ntfs_read_directory; -type_read_sds ntfs_read_sds; -type_read_sii ntfs_read_sii; -type_read_sdh ntfs_read_sdh; - -type_get_usid ntfs_get_usid; -type_get_gsid ntfs_get_gsid; -type_get_user ntfs_get_user; -type_get_group ntfs_get_group; - -type_initialize_file_security ntfs_initialize_file_security; -type_leave_file_security ntfs_leave_file_security; - - -#endif /* USESTUBS | defined(STSC) */ -#endif /* WIN32 */ +#endif /* HAVE_SYSLOG_H */ #define ACCOUNTSIZE 256 /* maximum size of an account name */ +#define MAXFILENAME 4096 +#define MAXATTRSZ 65536 /* Max sec attr size (16448 met for WinXP) */ +#define MAXLINE 80 /* maximum processed size of a line */ +#define BUFSZ 1024 /* buffer size to read mapping file */ +#define LINESZ 120 /* maximum useful size of a mapping line */ + +typedef enum { RECSHOW, RECSET, RECSETPOSIX } RECURSE; +typedef enum { MAPNONE, MAPEXTERN, MAPLOCAL, MAPDUMMY } MAPTYPE; +typedef enum { CMD_AUDIT, CMD_BACKUP, CMD_HEX, CMD_HELP, CMD_SET, + CMD_TEST, CMD_USERMAP, CMD_VERSION, CMD_NONE } CMDS; + + +#define MAXSECURID 262144 +#define SECBLKSZ 8 +#define MAPDIR ".NTFS-3G" +#define MAPFILE "UserMapping" + +#ifdef HAVE_WINDOWS_H +#define DIRSEP "\\" +#else +#define DIRSEP "/" +#endif + + /* standard owner (and administrator) rights */ + +#define OWNER_RIGHTS (DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER \ + | SYNCHRONIZE \ + | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES \ + | FILE_READ_EA | FILE_WRITE_EA) + + /* standard world rights */ + +#define WORLD_RIGHTS (READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_EA \ + | SYNCHRONIZE) + + /* inheritance flags for files and directories */ + +#define FILE_INHERITANCE NO_PROPAGATE_INHERIT_ACE +#define DIR_INHERITANCE (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE) /* - * Prototypes for local functions + * To identify NTFS ACL meaning Posix ACL granted to root + * we use rights always granted to anybody, so they have no impact + * either on Windows or on Linux. */ -BOOL open_security_api(void); -BOOL close_security_api(void); -#ifndef WIN32 -BOOL open_volume(const char*, unsigned long flags); -BOOL close_volume(const char*); -#endif -unsigned int get2l(const char*, int); -unsigned long get4l(const char*, int); -u64 get6l(const char*, int); -u64 get6h(const char*, int); -u64 get8l(const char*, int); -void set2l(char*, unsigned int); -void set4l(char*, unsigned long); -void hexdump(const char*, int, int); -u32 hash(const le32*, int); -unsigned int utf8size(const char*, int); -unsigned int makeutf8(char*, const char*, int); -unsigned int utf16size(const char*); -unsigned int makeutf16(char*, const char*); -unsigned int utf16len(const char*); -void printname(FILE*, const char*); -void printerror(FILE*); -BOOL guess_dir(const char*); -void showsid(const char*, int, const char*, int); -void showusid(const char*, int); -void showgsid(const char*, int); -void showownership(const char*); -void showheader(const char*, int); -void showace(const char*, int, int, int); -void showacl(const char*, int, int, int); -void showdacl(const char*, int, int); -void showsacl(const char*, int, int); -void showall(const char*, int); -void showposix(const struct POSIX_SECURITY*); -int linux_permissions(const char*, BOOL); -uid_t linux_owner(const char*); -gid_t linux_group(const char*); -int basicread(void*, char*, size_t, off_t); -int dummyread(void*, char*, size_t, off_t); -int local_build_mapping(struct MAPPING *[], const char*); -void newblock(s32); -void freeblocks(void); -u32 getmsbhex(const char*); -u32 getlsbhex(const char*); -BOOL ishexdump(const char*, int, int); -void showhex(FILE*); -void showfull(const char*, BOOL); -BOOL applyattr(const char*, const char*, BOOL, int, s32); -BOOL restore(FILE*); -BOOL dorestore(const char*, FILE*); -u32 merge_rights(const struct POSIX_SECURITY*, BOOL); -void tryposix(struct POSIX_SECURITY*); -void check_samples(void); -void basictest(int, BOOL, const SID*, const SID*); -void posixtest(int, BOOL, const SID*, const SID*); -void selftests(void); -unsigned int getfull(char*, const char*); -BOOL updatefull(const char *name, DWORD flags, char *attr); -BOOL setfull(const char*, int, BOOL); -BOOL singleshow(const char*); -BOOL proposal(const char*, const char*); -BOOL showmounted(const char*); -BOOL processmounted(const char*); -BOOL recurseshow(const char*); -BOOL singleset(const char*, int); -BOOL recurseset(const char*, int); -#ifdef WIN32 -BOOL backup(const char*); -BOOL listfiles(const char*); -#if POSIXACLS -BOOL iterate(RECURSE, const char*, const struct POSIX_SECURITY*); -#else -BOOL iterate(RECURSE, const char*, mode_t); -#endif -#else -BOOL backup(const char*, const char*); -BOOL listfiles(const char*, const char*); -BOOL mapproposal(const char*, const char*); -#endif -#if POSIXACLS -BOOL setfull_posix(const char *, const struct POSIX_SECURITY*, BOOL); -struct POSIX_SECURITY *linux_permissions_posix(const char*, BOOL); -BOOL recurseset_posix(const char*, const struct POSIX_SECURITY*); -BOOL singleset_posix(const char*, const struct POSIX_SECURITY*); -struct POSIX_SECURITY *encode_posix_acl(const char*); -#endif -static void *stdmalloc(size_t); -static void stdfree(void*); +#define ROOT_OWNER_UNMARK SYNCHRONIZE /* ACL granted to root as owner */ +#define ROOT_GROUP_UNMARK FILE_READ_EA /* ACL granted to root as group */ -BOOL valid_sds(const char*, unsigned int, unsigned int, - unsigned int, u32, BOOL); -BOOL valid_sii(const char*, u32); -BOOL valid_sdh(const char*, u32, u32); -int consist_sds(const char*, unsigned int, unsigned int, BOOL); -int consist_sii(const char*); -int consist_sdh(const char*); -int audit_sds(BOOL); -int audit_sii(void); -int audit_sdh(void); -void audit_summary(void); -BOOL audit(const char*); -int getoptions(int, char*[]); +#define INSDS1 1 +#define INSDS2 2 +#define INSII 4 +#define INSDH 8 -#ifndef WIN32 +struct SII { /* this is an image of an $SII index entry */ + le16 offs; + le16 size; + le32 fill1; + le16 indexsz; + le16 indexksz; + le16 flags; + le16 fill2; + le32 keysecurid; + + /* did not find official description for the following */ + le32 hash; + le32 securid; + le32 dataoffsl; /* documented as badly aligned */ + le32 dataoffsh; + le32 datasize; +} ; + +struct SDH { /* this is an image of an $SDH index entry */ + le16 offs; + le16 size; + le32 fill1; + le16 indexsz; + le16 indexksz; + le16 flags; + le16 fill2; + le32 keyhash; + le32 keysecurid; + + /* did not find official description for the following */ + le32 hash; + le32 securid; + le32 dataoffsl; + le32 dataoffsh; + le32 datasize; + le32 fill3; + } ; + +#ifdef HAVE_WINDOWS_H +/* + * Including leads to numerous conflicts with layout.h + * so define a few needed Windows calls unrelated to ntfs-3g + */ +BOOL WINAPI LookupAccountSidA(const char*, void*, char*, u32*, + char*, u32*, s32*); +u32 WINAPI GetFileAttributesA(const char*); +#endif /* HAVE_WINDOWS_H */ + +#define INVALID_FILE_ATTRIBUTES (-1)/* error from ntfs_get_file_attributes() */ /* - * Structures for collecting directory contents (Linux only) + * Structures for collecting directory contents */ struct LINK { @@ -562,18 +459,27 @@ struct CALLBACK { const char *dir; } ; -int callback(struct CALLBACK *context, char *ntfsname, - int length, int type, long long pos, u64 mft_ref, - unsigned int dt_type); -#endif +static int callback(void *context, const ntfschar *ntfsname, + const int length, const int type, const s64 pos, + const MFT_REF mft_ref, const unsigned int dt_type); + +struct SECURITY_DATA { + u64 offset; + char *attr; + u32 hash; + u32 length; + unsigned int filecount:16; + unsigned int mode:12; + unsigned int flags:4; +} ; /* * Global constants */ -#define BANNER "secaudit " AUDT_VERSION " : NTFS security data auditing" +#define BANNER "ntfssecaudit " AUDT_VERSION " : NTFS security data auditing" -#if SELFTESTS & !USESTUBS +#ifdef SELFTESTS /* * Dummy mapping file (self tests only) @@ -591,44 +497,18 @@ char dummymapping[] = "500::" DUMMYAUTH "1000\n" "::" DUMMYAUTH "10000\n"; /* - * SID for world (S-1-1-0) - */ - -static const char worldsidbytes[] = { - 1, /* revision */ - 1, /* auth count */ - 0, 0, 0, 0, 0, 1, /* base */ - 0, 0, 0, 0 /* 1st level */ -} ; -static const SID *worldsid = (const SID*)worldsidbytes; - -/* * SID for authenticated user (S-1-5-11) */ - + static const char authsidbytes[] = { - 1, /* revision */ + 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; -/* - * SID for administrator (S-1-5-32-544) - */ - -static const char adminsidbytes[] = { - 1, /* revision */ - 2, /* auth count */ - 0, 0, 0, 0, 0, 5, /* base */ - 32, 0, 0, 0, /* 1st level */ - 32, 2, 0, 0 /* 2nd level */ -}; - -static const SID *adminsid = (const SID*)adminsidbytes; - /* * SID for local users (S-1-5-32-545) */ @@ -643,180 +523,101 @@ static const char localsidbytes[] = { static const SID *localsid = (const SID*)localsidbytes; -/* +/* * SID for system (S-1-5-18) */ - + static const char systemsidbytes[] = { - 1, /* revision */ + 1, /* revision */ 1, /* auth count */ 0, 0, 0, 0, 0, 5, /* base */ 18, 0, 0, 0 /* 1st level */ }; - + static const SID *systemsid = (const SID*)systemsidbytes; -#endif +#endif /* SELFTESTS */ /* * Global variables */ -BOOL opt_a; /* audit security data */ -BOOL opt_b; /* backup NTFS ACLs */ BOOL opt_e; /* restore extra (currently windows attribs) */ -BOOL opt_h; /* display an hexadecimal descriptor in a file */ BOOL opt_r; /* recursively apply to subdirectories */ -BOOL opt_s; /* restore NTFS ACLs */ BOOL opt_u; /* user mapping proposal */ -#if SELFTESTS & !USESTUBS -BOOL opt_t; /* run self-tests */ -#endif int opt_v; /* verbose or very verbose*/ +CMDS cmd; /* command to process */ struct SECURITY_DATA *securdata[(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ)]; -#if FORCEMASK -BOOL opt_m; /* force a mask - dangerous */ -u32 forcemsk /* mask to force */ -#endif unsigned int errors; /* number of severe errors */ unsigned int warnings; /* number of non-severe errors */ -struct CHKALLOC *firstalloc; struct SECURITY_CONTEXT context; MAPTYPE mappingtype; - -#ifdef STSC -#define static -#endif - -#ifndef WIN32 - -void *ntfs_handle; -void *ntfs_context = (void*)NULL; +struct SECURITY_API *ntfs_context = (struct SECURITY_API*)NULL; /* - * Open and close the security API (platform dependent) + * Open and close the security API (obsolete) */ -BOOL open_security_api(void) +static BOOL open_security_api(void) { -#if USESTUBS | defined(STSC) return (TRUE); -#else - char *error; - BOOL err; - const char *libfile; - - err = TRUE; - libfile = getenv(ENVNTFS3G); - if (!libfile) - libfile = (sizeof(char*) == 8 ? LIBFILE64 : LIBFILE); -#ifdef __SVR4 - /* do not override library functions by caller ones */ - ntfs_handle = dlopen(libfile,RTLD_LAZY | RTLD_GROUP); -#else - ntfs_handle = dlopen(libfile,RTLD_LAZY); -#endif - if (ntfs_handle) { - ntfs_initialize_file_security = (type_initialize_file_security) - dlsym(ntfs_handle,INIT_FILE_SECURITY); - error = dlerror(); - if (error) - fprintf(stderr," %s\n",error); - else { - ntfs_leave_file_security = (type_leave_file_security) - dlsym(ntfs_handle,LEAVE_FILE_SECURITY); - ntfs_get_file_security = (type_get_file_security) - dlsym(ntfs_handle,GET_FILE_SECURITY); - ntfs_set_file_security = (type_set_file_security) - dlsym(ntfs_handle,SET_FILE_SECURITY); - ntfs_get_file_attributes = (type_get_file_attributes) - dlsym(ntfs_handle,GET_FILE_ATTRIBUTES); - ntfs_set_file_attributes = (type_set_file_attributes) - dlsym(ntfs_handle,SET_FILE_ATTRIBUTES); - ntfs_read_directory = (type_read_directory) - dlsym(ntfs_handle,READ_DIRECTORY); - ntfs_read_sds = (type_read_sds) - dlsym(ntfs_handle,READ_SDS); - ntfs_read_sii = (type_read_sii) - dlsym(ntfs_handle,READ_SII); - ntfs_read_sdh = (type_read_sdh) - dlsym(ntfs_handle,READ_SDH); - ntfs_get_user = (type_get_user) - dlsym(ntfs_handle,GET_USER); - ntfs_get_group = (type_get_group) - dlsym(ntfs_handle,GET_GROUP); - ntfs_get_usid = (type_get_usid) - dlsym(ntfs_handle,GET_USID); - ntfs_get_gsid = (type_get_gsid) - dlsym(ntfs_handle,GET_GSID); - err = !ntfs_initialize_file_security - || !ntfs_leave_file_security - || !ntfs_get_file_security - || !ntfs_set_file_security - || !ntfs_get_file_attributes - || !ntfs_set_file_attributes - || !ntfs_read_directory - || !ntfs_read_sds - || !ntfs_read_sii - || !ntfs_read_sdh - || !ntfs_get_user - || !ntfs_get_group - || !ntfs_get_usid - || !ntfs_get_gsid; - - if (error) - fprintf(stderr,"ntfs-3g API not available\n"); - } - } else { - fprintf(stderr,"Could not open ntfs-3g library\n"); - fprintf(stderr,"\nPlease set environment variable \"" ENVNTFS3G "\"\n"); - fprintf(stderr,"to appropriate path and retry\n"); - } - return (!err); -#endif /* USESTUBS | defined(STSC) */ } -BOOL close_security_api(void) +static BOOL close_security_api(void) { -#if USESTUBS | defined(STSC) return (0); -#else - return (!dlclose(ntfs_handle)); -#endif /* USESTUBS | defined(STSC) */ } /* - * Open and close a volume (platform dependent) + * Open and close a volume * Assumes a single volume is opened */ -BOOL open_volume(const char *volume, unsigned long flags) +static BOOL open_volume(const char *volume, unsigned long flags) { BOOL ok; ok = FALSE; if (!ntfs_context) { - ntfs_context = ntfs_initialize_file_security(volume,flags); + ntfs_context = ntfs_initialize_file_security(volume, flags); if (ntfs_context) { if (*(u32*)ntfs_context != MAGIC_API) { fprintf(stderr,"Versions of ntfs-3g and secaudit" " are not compatible\n"); } else { - fprintf(stderr,"\"%s\" opened\n",volume); + fprintf(stderr,"\"%s\" opened %s\n",volume, + (flags & NTFS_MNT_RDONLY + ? "read-only" : "read-write")); mappingtype = MAPEXTERN; ok = TRUE; } } else { fprintf(stderr,"Could not open \"%s\"\n",volume); +#ifdef HAVE_WINDOWS_H + switch (errno) { + case EACCES : + fprintf(stderr,"You need Administrator rights to open \"%s\"\n", + volume); + break; + case EBUSY : + fprintf(stderr,"Looks like \"%s\" is mounted,\n",volume); + fprintf(stderr,"close all applications using it\n"); + break; + default : + fprintf(stderr,"Close all applications using %s\n", volume); + fprintf(stderr,"to make sure it is not mounted\n"); + } +#else fprintf(stderr,"Make sure \"%s\" is not mounted\n",volume); +#endif } } else fprintf(stderr,"A volume is already open\n"); return (ok); } -BOOL close_volume(const char *volume) +static BOOL close_volume(const char *volume) { BOOL r; @@ -825,17 +626,84 @@ BOOL close_volume(const char *volume) fprintf(stderr,"\"%s\" closed\n",volume); else fprintf(stderr,"Could not close \"%s\"\n",volume); - ntfs_context = (void*)NULL; + ntfs_context = (struct SECURITY_API*)NULL; return (r); } -#endif /* WIN32 */ +#ifdef HAVE_WINDOWS_H + +/* + * Make a path suitable for feeding to libntfs-3g + * + * Use '/' as a directory separator and remove /../ and /./ + */ + +static int cleanpath(char *path) +{ + int err; + char *p; + char *s, *d; + + err = 0; + for (p=path; *p; p++) + if (*p == '\\') + *p = '/'; + do { + s = (char*)NULL; + p = strstr(path, "/./"); + if (p) { + s = p + 3; + d = p + 1; + } else { + p = strstr(path, "/../"); + if (p) { + d = p; + while ((d != path) && (*--d != '/')) + d--; + if ((d != p) && (*d == '/')) { + s = p + 3; + } else + err = 1; + } + } + if (s) { + while (*s) + *d++ = *s++; + *d = 0; + } + } while (s && !err); + return (err); +} + +/* + * Build a path with Unix-type separators + * + * The path from the ntfs root is required for libntfs-3g calls + */ + +static char *unixname(const char *name) +{ + char *uname; + + uname = (char*)malloc(strlen(name) + 1); + if (uname) { + strcpy(uname, name); + if (cleanpath(uname)) { + fprintf(stderr,"Bad path %s\n",name); + free(uname); + uname = (char*)NULL; + } + } + return (uname); +} + +#endif /* HAVE_WINDOWS_H */ /* * Extract small or big endian data from an array of bytes */ -unsigned int get2l(const char *attr, int p) +static unsigned int get2l(const char *attr, int p) { int i; unsigned int v; @@ -846,7 +714,7 @@ unsigned int get2l(const char *attr, int p) return (v); } -unsigned long get4l(const char *attr, int p) +static unsigned long get4l(const char *attr, int p) { int i; unsigned long v; @@ -857,18 +725,7 @@ unsigned long get4l(const char *attr, int p) return (v); } -u64 get6l(const char *attr, int p) -{ - int i; - u64 v; - - v = 0; - for (i=0; i<6; i++) - v += ((long long)(attr[p+i] & 255)) << (8*i); - return (v); -} - -u64 get6h(const char *attr, int p) +static u64 get6h(const char *attr, int p) { int i; u64 v; @@ -879,7 +736,7 @@ u64 get6h(const char *attr, int p) return (v); } -u64 get8l(const char *attr, int p) +static u64 get8l(const char *attr, int p) { int i; u64 v; @@ -894,7 +751,7 @@ u64 get8l(const char *attr, int p) * Set small or big endian data into an array of bytes */ -void set2l(char *p, unsigned int v) +static void set2l(char *p, unsigned int v) { int i; @@ -902,7 +759,7 @@ void set2l(char *p, unsigned int v) p[i] = ((v >> 8*i) & 255); } -void set4l(char *p, unsigned long v) +static void set4l(char *p, unsigned long v) { int i; @@ -915,7 +772,7 @@ void set4l(char *p, unsigned long v) * hexadecimal dump of an array of bytes */ -void hexdump(const char *attr, int size, int level) +static void hexdump(const char *attr, int size, int level) { int i,j; @@ -929,7 +786,7 @@ void hexdump(const char *attr, int size, int level) } } -u32 hash(const le32 *buf, int size /* bytes */) +static u32 hash(const le32 *buf, int size /* bytes */) { u32 h; int i; @@ -946,50 +803,45 @@ u32 hash(const le32 *buf, int size /* bytes */) * Returns 0 for invalid input */ -unsigned int utf8size(const char *utf16, int length) +static unsigned int utf8size(const ntfschar *utf16, int length) { int i; - unsigned int size; - enum { BASE, SURR, ERR } state; + int count = 0; + BOOL surrog; + BOOL fail; - size = 0; - state = BASE; - for (i=0; i<2*length; i+=2) { - switch (state) { - case BASE : - if (utf16[i+1] & 0xf8) { - if ((utf16[i+1] & 0xf8) == 0xd8) - state = (utf16[i+1] & 4 ? ERR : SURR); - else + surrog = FALSE; + fail = FALSE; + for (i = 0; i < length && utf16[i] && !fail; i++) { + unsigned short c = le16_to_cpu(utf16[i]); + if (surrog) { + if ((c >= 0xdc00) && (c < 0xe000)) { + surrog = FALSE; + count += 4; + } else + fail = TRUE; + } else + if (c < 0x80) + count++; + else if (c < 0x800) + count += 2; + else if (c < 0xd800) + count += 3; + else if (c < 0xdc00) + surrog = TRUE; #if NOREVBOM - if (((utf16[i+1] & 0xff) == 0xff) - && ((utf16[i] & 0xfe) == 0xfe)) - state = ERR; - else - size += 3; + else if ((c >= 0xe000) && (c < 0xfffe)) #else - size += 3; + else if (c >= 0xe000) #endif - } else - if ((utf16[i] & 0x80) || utf16[i+1]) - size += 2; - else - size++; - break; - case SURR : - if ((utf16[i+1] & 0xfc) == 0xdc) { - state = BASE; - size += 4; - } else - state = ERR; - break; - case ERR : - break; - } + count += 3; + else + fail = TRUE; } - if (state != BASE) - size = 0; - return (size); + if (surrog) + fail = TRUE; + + return (fail ? 0 : count); } /* @@ -999,368 +851,57 @@ unsigned int utf8size(const char *utf16, int length) * Returns size or zero for invalid input */ -unsigned int makeutf8(char *utf8, const char *utf16, int length) +static unsigned int makeutf8(char *utf8, const ntfschar *utf16, int length) { - int i; - unsigned int size; - unsigned int rem; - enum { BASE, SURR, ERR } state; + int size; - size = 0; - rem = 0; - state = BASE; - for (i=0; i<2*length; i+=2) { - switch (state) { - case BASE : - if (utf16[i+1] & 0xf8) { - if ((utf16[i+1] & 0xf8) == 0xd8) { - if (utf16[i+1] & 4) - state = ERR; - else { - utf8[size++] = 0xf0 + (utf16[i+1] & 7) - + ((utf16[i] & 0xc0) == 0xc0); - utf8[size++] = 0x80 + (((utf16[i] + 64) >> 2) & 63); - rem = utf16[i] & 3; - state = SURR; - } - } else { -#if NOREVBOM - if (((utf16[i+1] & 0xff) == 0xff) - && ((utf16[i] & 0xfe) == 0xfe)) - state = ERR; - else { - utf8[size++] = 0xe0 + ((utf16[i+1] >> 4) & 15); - utf8[size++] = 0x80 - + ((utf16[i+1] & 15) << 2) - + ((utf16[i] >> 6) & 3); - utf8[size++] = 0x80 + (utf16[i] & 63); - } -#else - utf8[size++] = 0xe0 + ((utf16[i+1] >> 4) & 15); - utf8[size++] = 0x80 - + ((utf16[i+1] & 15) << 2) - + ((utf16[i] >> 6) & 3); - utf8[size++] = 0x80 + (utf16[i] & 63); -#endif - } - } else - if ((utf16[i] & 0x80) || utf16[i+1]) { - utf8[size++] = 0xc0 - + ((utf16[i+1] & 15) << 2) - + ((utf16[i] >> 6) & 3); - utf8[size++] = 0x80 + (utf16[i] & 63); - } else - utf8[size++] = utf16[i]; - break; - case SURR : - if ((utf16[i+1] & 0xfc) == 0xdc) { - utf8[size++] = 0x80 + (rem << 4) - + ((utf16[i+1] & 3) << 2) - + ((utf16[i] >> 6) & 3); - utf8[size++] = 0x80 + (utf16[i] & 63); - state = BASE; - } else - state = ERR; - break; - case ERR : - break; - } - } - utf8[size] = 0; - if (state != BASE) - state = ERR; - return (state == ERR ? 0 : size); + size = ntfs_ucstombs(utf16, length, &utf8, MAXFILENAME); + return (size < 0 ? 0 : size); } -#ifdef WIN32 - -/* - * Evaluate the size of UTF-16LE conversion of a UTF-8 text - * (basic conversions only) - * trailing '\0' not accounted for - */ - -unsigned int utf16size(const char *utf8) -{ - unsigned int size; - const char *p; - int c; - unsigned int code; - enum { BASE, TWO, THREE, THREE2, THREE3, FOUR, ERR } state; - - p = utf8; - size = 0; - state = BASE; - while (*p) { - c = *p++ & 255; - switch (state) { - case BASE : - if (!(c & 0x80)) - size++; - else - if (c < 0xc2) - state = ERR; - else - if (c < 0xe0) - state = TWO; - else - if (c < 0xf0) { - if (c == 0xe0) - state = THREE2; - else - if (c == 0xed) - state = THREE3; - else - state = THREE; - } else - if (c < 0xf8) { - state = FOUR; - code = c & 7; - } else - state = ERR; - break; - case TWO : - if ((c & 0xc0) != 0x80) - state = ERR; - else { - size++; - state = BASE; - } - break; - case THREE : - if ((c & 0xc0) != 0x80) - state = ERR; - else - state = TWO; - break; - case THREE2 : - if ((c & 0xe0) != 0xa0) - state = ERR; - else - state = TWO; - break; - case THREE3 : - if ((c & 0xe0) != 0x80) - state = ERR; - else - state = TWO; - break; - case FOUR : - if ((((code << 6) + (c & 63)) > 0x10f) - || (((code << 6) + (c & 63)) < 0x10)) - state = ERR; - else { - size++; - state = THREE; - } - break; - case ERR : - break; - } - } - if (state != BASE) size = 0; - return (size); -} - -/* - * Convert a UTF8 text to UTF-16LE - * (basic conversions only) - * Note : mbstowcs() not used because on Linux it fails for characters - * not present in current locale - */ - -unsigned int makeutf16(char *target, const char *utf8) -{ - unsigned int size; - unsigned int code; - const char *p; - int c; - enum { BASE, TWO, THREE, THREE2, THREE3, FOUR, FOUR2, FOUR3, ERR } state; - - p = utf8; - size = 0; - c = 0; - state = BASE; - while (*p) { - c = *p++ & 255; - switch (state) { - case BASE : - if (!(c & 0x80)) { - target[2*size] = c; - target[2*size + 1] = 0; - size++; - } else { - if (c < 0xc2) - state = ERR; - else - if (c < 0xe0) { - code = c & 31; - state = TWO; - } else - if (c < 0xf0) { - code = c & 15; - if (c == 0xe0) - state = THREE2; - else - if (c == 0xed) - state = THREE3; - else - state = THREE; - } else - if (c < 0xf8) { - code = c & 7; - state = FOUR; - } else - state = ERR; - } - break; - case TWO : -#if NOREVBOM - if (((c & 0xc0) != 0x80) - || ((code == 0x3ff) && (c >= 0xbe))) -#else - if ((c & 0xc0) != 0x80) -#endif - state = ERR; - else { - target[2*size] = ((code & 3) << 6) + (c & 63); - target[2*size + 1] = ((code >> 2) & 255); - size++; - state = BASE; - } - break; - case THREE : - if ((c & 0xc0) != 0x80) - state = ERR; - else { - code = ((code & 15) << 6) + (c & 63); - state = TWO; - } - break; - case THREE2 : - if ((c & 0xe0) != 0xa0) - state = ERR; - else { - code = ((code & 15) << 6) + (c & 63); - state = TWO; - } - break; - case THREE3 : - if ((c & 0xe0) != 0x80) - state = ERR; - else { - code = ((code & 15) << 6) + (c & 63); - state = TWO; - } - break; - case FOUR : - if ((c & 0xc0) != 0x80) - state = ERR; - else { - code = (code << 6) + (c & 63); - state = FOUR2; - } - break; - case FOUR2 : - if ((c & 0xc0) != 0x80) - state = ERR; - else { - code = (code << 6) + (c & 63); - state = FOUR3; - } - break; - case FOUR3 : - if ((code > 0x43ff) - || (code < 0x400) - || ((c & 0xc0) != 0x80)) - state = ERR; - else { - target[2*size] = ((code - 0x400) >> 4) & 255; - target[2*size+1] = 0xd8 + (((code - 0x400) >> 12) & 3); - target[2*size+2] = ((code & 3) << 6) + (c & 63); - target[2*size+3] = 0xdc + ((code >> 2) & 3); - size += 2; - state = BASE; - } - break; - case ERR : - break; - } - } - if (state != BASE) - size = 0; - target[2*size] = 0; - target[2*size + 1] = 0; - return (size); -} - -unsigned int utf16len(const char *str) -{ - unsigned int len; - - len = 0; - while (str[2*len] || str[2*len+1]) len++; - return (len); -} - -#endif - /* * Print a file name * on Windows it prints UTF-16LE names as UTF-8 */ -void printname(FILE *file, const char *name) +static void printname(FILE *file, const char *name) { -#ifdef WIN32 - char utf8name[MAXFILENAME]; +#ifdef HAVE_WINDOWS_H + char *wname; + char *p; - makeutf8(utf8name,name,utf16len(name)); - fprintf(file,"%s",utf8name); -#else + wname = (char*)malloc(strlen(name) + 1); + if (wname) { + strcpy(wname, name); + for (p=wname; *p; p++) + if (*p == '/') + *p = '\\'; + fprintf(file,"%s", wname); + free(wname); + } +#else /* HAVE_WINDOWS_H */ fprintf(file,"%s",name); -#endif +#endif /* HAVE_WINDOWS_H */ } /* * Print the last error code */ -void printerror(FILE *file) +static void printerror(FILE *file) { -#ifdef WIN32 - int err; - const char *txt; - - err = GetLastError(); - switch (err) { - case 5 : - txt = "Access to security descriptor was denied"; + if (errno) + fprintf(file,"Error code %d : %s\n",errno,strerror(errno)); + switch (errno) { + case EACCES : + fprintf(file,"You probably need Administrator rights\n"); break; - case 1307 : - txt = "This SID may not be assigned as the owner of this object"; - break; - case 1308 : - txt = "This SID may not be assigned as the group of this object"; - break; - case 1314 : - txt = "You do not have the privilege to change this SID"; + case EBUSY : + fprintf(file,"You probably try to write to a mounted device\n"); break; default : - txt = (const char*)NULL; break; } - if (txt) - fprintf(file,"Error %d : %s\n",err,txt); - else - fprintf(file,"Error %d\n",err); -#else -#ifdef STSC - if (errno) fprintf(file,"Error code %d\n",errno); -#else - if (errno) fprintf(file,"Error code %d : %s\n",errno,strerror(errno)); -#endif -#endif } #ifndef HAVE_SYSLOG_H @@ -1369,7 +910,7 @@ void printerror(FILE *file) * Redefine early error messages in stand-alone situations */ -void ntfs_log_early_error(const char *format, ...) +static void ntfs_log_early_error(const char *format, ...) { va_list args; @@ -1378,7 +919,7 @@ void ntfs_log_early_error(const char *format, ...) va_end(args); } -#endif +#endif /* HAVE_SYSLOG_H */ /* * Guess whether a security attribute is intended for a directory @@ -1386,7 +927,7 @@ void ntfs_log_early_error(const char *format, ...) * (not 100% reliable) */ -BOOL guess_dir(const char *attr) +static BOOL guess_dir(const char *attr) { int off; int isdir; @@ -1413,7 +954,7 @@ BOOL guess_dir(const char *attr) * See http://msdn2.microsoft.com/en-us/library/aa379649.aspx */ -void showsid(const char *attr, int off, const char *prefix, int level) +static void showsid(const char *attr, int off, const char *prefix, int level) { int cnt; int i; @@ -1424,7 +965,7 @@ void showsid(const char *attr, int off, const char *prefix, int level) unsigned long last; char marker; - if (opt_b) + if (cmd == CMD_BACKUP) marker = '#'; else marker = ' '; @@ -1566,23 +1107,23 @@ void showsid(const char *attr, int off, const char *prefix, int level) if (!known) printf("%*cUnknown SID\n",-level,marker); printf("%*c%shex S-%d-",-level,marker,prefix,attr[off] & 255); - printf("%llx",auth); + printf("%llx",(long long)auth); for (i=0; iowner)]; usid = ntfs_acl_owner((const char*)attr); -#if SELFTESTS & !USESTUBS - if (!opt_t && !ntfs_same_sid(usid,osid)) - printf("== Linux owner is different from Windows owner\n"); -#else +#ifdef SELFTESTS + if ((cmd != CMD_TEST) && !ntfs_same_sid(usid,osid)) + printf("== Linux owner is different from Windows owner\n"); +#else /* SELFTESTS */ if (!ntfs_same_sid(usid,osid)) - printf("== Linux owner is different from Windows owner\n"); -#endif -#else + printf("== Linux owner is different from Windows owner\n"); +#endif /* SELFTESTS */ +#else /* OWNERFROMACL */ usid = (const SID*)&attr[le32_to_cpu(phead->owner)]; -#endif - posix_desc = ntfs_build_permissions_posix(context.mapping, - (const char*)attr, usid, gsid, isdir); +#endif /* OWNERFROMACL */ + if (mappingtype == MAPEXTERN) + posix_desc = ntfs_build_permissions_posix( + ntfs_context->security.mapping, + (const char*)attr, usid, gsid, isdir); + else + posix_desc = ntfs_build_permissions_posix(context.mapping, + (const char*)attr, usid, gsid, isdir); if (!posix_desc) { printf("** Failed to build a Posix descriptor\n"); errors++; @@ -2161,12 +1657,12 @@ struct POSIX_SECURITY *linux_permissions_posix(const char *attr, BOOL isdir) #endif /* POSIXACLS */ -int linux_permissions(const char *attr, BOOL isdir) +static int linux_permissions(const char *attr, BOOL isdir) { const SECURITY_DESCRIPTOR_RELATIVE *phead; #if OWNERFROMACL const SID *osid; -#endif +#endif /* OWNERFROMACL */ const SID *usid; const SID *gsid; int perm; @@ -2176,16 +1672,16 @@ int linux_permissions(const char *attr, BOOL isdir) #if OWNERFROMACL osid = (const SID*)&attr[le32_to_cpu(phead->owner)]; usid = ntfs_acl_owner((const char*)attr); -#if SELFTESTS & !USESTUBS - if (!opt_t && !ntfs_same_sid(usid,osid)) - printf("== Linux owner is different from Windows owner\n"); -#else +#ifdef SELFTESTS + if ((cmd != CMD_TEST) && !ntfs_same_sid(usid,osid)) + printf("== Linux owner is different from Windows owner\n"); +#else /* SELFTESTS */ if (!ntfs_same_sid(usid,osid)) - printf("== Linux owner is different from Windows owner\n"); -#endif -#else + printf("== Linux owner is different from Windows owner\n"); +#endif /* SELFTESTS */ +#else /* OWNERFROMACL */ usid = (const SID*)&attr[le32_to_cpu(phead->owner)]; -#endif +#endif /* OWNERFROMACL */ perm = ntfs_build_permissions((const char*)attr, usid, gsid, isdir); if (perm < 0) { printf("** Failed to build permissions\n"); @@ -2194,31 +1690,31 @@ int linux_permissions(const char *attr, BOOL isdir) return (perm); } -uid_t linux_owner(const char *attr) +static uid_t linux_owner(const char *attr) { const SID *usid; uid_t uid; #if OWNERFROMACL usid = ntfs_acl_owner((const char*)attr); -#else +#else /* OWNERFROMACL */ const SECURITY_DESCRIPTOR_RELATIVE *phead; phead = (const SECURITY_DESCRIPTOR_RELATIVE*)attr; usid = (const SID*)&attr[le32_to_cpu(phead->owner)]; -#endif -#if defined(WIN32) | defined(STSC) +#endif /* OWNERFROMACL */ +#ifdef HAVE_WINDOWS_H uid = ntfs_find_user(context.mapping[MAPUSERS],usid); -#else +#else /* defined(HAVE_WINDOWS_H) */ if (mappingtype == MAPEXTERN) uid = relay_find_user(context.mapping[MAPUSERS],usid); else uid = ntfs_find_user(context.mapping[MAPUSERS],usid); -#endif +#endif /* defined(HAVE_WINDOWS_H) */ return (uid); } -gid_t linux_group(const char *attr) +static gid_t linux_group(const char *attr) { const SECURITY_DESCRIPTOR_RELATIVE *phead; const SID *gsid; @@ -2226,18 +1722,18 @@ gid_t linux_group(const char *attr) phead = (const SECURITY_DESCRIPTOR_RELATIVE*)attr; gsid = (const SID*)&attr[le32_to_cpu(phead->group)]; -#if defined(WIN32) | defined(STSC) +#ifdef HAVE_WINDOWS_H gid = ntfs_find_group(context.mapping[MAPGROUPS],gsid); -#else +#else /* defined(HAVE_WINDOWS_H) */ if (mappingtype == MAPEXTERN) gid = relay_find_group(context.mapping[MAPGROUPS],gsid); else gid = ntfs_find_group(context.mapping[MAPGROUPS],gsid); -#endif +#endif /* defined(HAVE_WINDOWS_H) */ return (gid); } -void newblock(s32 key) +static void newblock(s32 key) { struct SECURITY_DATA *psecurdata; int i; @@ -2256,7 +1752,7 @@ void newblock(s32 key) } } -void freeblocks(void) +static void freeblocks(void) { int i,j; struct SECURITY_DATA *psecurdata; @@ -2276,19 +1772,19 @@ void freeblocks(void) * Basic read from a user mapping file (Win32) */ -int basicread(void *fileid, char *buf, size_t size, +static int basicread(void *fileid, char *buf, size_t size, off_t pos __attribute__((unused))) { return (read(*(int*)fileid, buf, size)); } -#if SELFTESTS & !USESTUBS +#ifdef SELFTESTS /* * Read a dummy mapping file for tests */ -int dummyread(void *fileid __attribute__((unused)), +static int dummyread(void *fileid __attribute__((unused)), char *buf, size_t size, off_t pos) { size_t sz; @@ -2305,7 +1801,7 @@ int dummyread(void *fileid __attribute__((unused)), return (sz); } -#endif /* POSIXACLS & SELFTESTS & !USESTUBS */ +#endif /* SELFTESTS */ /* * Apply default single user mapping @@ -2323,24 +1819,12 @@ static int do_default_mapping(struct MAPPING *mapping[], res = -1; sidsz = ntfs_sid_size(usid); -#if USESTUBS - sid = (SID*)stdmalloc(sidsz); /* will be freed within the library */ -#else sid = (SID*)ntfs_malloc(sidsz); -#endif if (sid) { memcpy(sid,usid,sidsz); -#if USESTUBS - usermapping = (struct MAPPING*)stdmalloc(sizeof(struct MAPPING)); -#else usermapping = (struct MAPPING*)ntfs_malloc(sizeof(struct MAPPING)); -#endif if (usermapping) { -#if USESTUBS - groupmapping = (struct MAPPING*)stdmalloc(sizeof(struct MAPPING)); -#else groupmapping = (struct MAPPING*)ntfs_malloc(sizeof(struct MAPPING)); -#endif if (groupmapping) { usermapping->sid = sid; usermapping->xid = 0; @@ -2369,15 +1853,15 @@ static int do_default_mapping(struct MAPPING *mapping[], * (failure should not be interpreted as an error) */ -int local_build_mapping(struct MAPPING *mapping[], const char *usermap_path) +static int local_build_mapping(struct MAPPING *mapping[], const char *usermap_path) { -#ifdef WIN32 +#ifdef HAVE_WINDOWS_H char mapfile[sizeof(MAPDIR) + sizeof(MAPFILE) + 6]; - char currpath[261]; -#else + char currpath[MAXFILENAME]; +#else /* HAVE_WINDOWS_H */ char *mapfile; char *p; -#endif +#endif /* HAVE_WINDOWS_H */ int fd; struct MAPLIST *item; struct MAPLIST *firstitem = (struct MAPLIST*)NULL; @@ -2405,28 +1889,32 @@ int local_build_mapping(struct MAPPING *mapping[], const char *usermap_path) mapping[MAPGROUPS] = (struct MAPPING*)NULL; if (usermap_path) { -#ifdef WIN32 +#ifdef HAVE_WINDOWS_H /* TODO : check whether the device can store acls */ strcpy(mapfile,"x:\\" MAPDIR "\\" MAPFILE); if (((const le16*)usermap_path)[1] == ':') mapfile[0] = usermap_path[0]; else { - GetModuleFileName(NULL, currpath, 261); + getcwd(currpath,MAXFILENAME); mapfile[0] = currpath[0]; } fd = open(mapfile,O_RDONLY); -#else +#else /* HAVE_WINDOWS_H */ fd = 0; mapfile = (char*)malloc(MAXFILENAME); if (mapfile) { /* build a full path to locate the mapping file */ +/* if ((usermap_path[0] != '/') && getcwd(mapfile,MAXFILENAME)) { strcat(mapfile,"/"); strcat(mapfile,usermap_path); } else strcpy(mapfile,usermap_path); - p = strrchr(mapfile,'/'); +*/ + p = ntfs_realpath(usermap_path, mapfile); + if (p) + p = strrchr(mapfile,'/'); if (p) do { strcpy(p,"/" MAPDIR "/" MAPFILE); @@ -2446,15 +1934,15 @@ int local_build_mapping(struct MAPPING *mapping[], const char *usermap_path) errors++; } } -#endif +#endif /* HAVE_WINDOWS_H */ if (fd > 0) { firstitem = ntfs_read_mapping(basicread, (void*)&fd); close(fd); } } else { -#if SELFTESTS & !USESTUBS +#ifdef SELFTESTS firstitem = ntfs_read_mapping(dummyread, (void*)NULL); -#endif +#endif /* SELFTESTS */ } if (firstitem) { @@ -2469,11 +1957,7 @@ int local_build_mapping(struct MAPPING *mapping[], const char *usermap_path) /* and rely on internal representation */ while (firstitem) { item = firstitem->next; -#if USESTUBS - stdfree(firstitem); /* allocated within library */ -#else free(firstitem); -#endif firstitem = item; } } else { @@ -2488,7 +1972,7 @@ int local_build_mapping(struct MAPPING *mapping[], const char *usermap_path) * Get an hexadecimal number (source with MSB first) */ -u32 getmsbhex(const char *text) +static u32 getmsbhex(const char *text) { u32 v; int b; @@ -2517,7 +2001,7 @@ u32 getmsbhex(const char *text) * An odd number of digits might yield a strange result */ -u32 getlsbhex(const char *text) +static u32 getlsbhex(const char *text) { u32 v; int b; @@ -2548,7 +2032,7 @@ u32 getlsbhex(const char *text) * Check whether a line looks like an hex dump */ -BOOL ishexdump(const char *line, int first, int lth) +static BOOL ishexdump(const char *line, int first, int lth) { BOOL ok; int i; @@ -2578,13 +2062,13 @@ BOOL ishexdump(const char *line, int first, int lth) * This is typically to convert a verbose output to a very verbose one */ -void showhex(FILE *fd) +static void showhex(FILE *fd) { static char attr[MAXATTRSZ]; char line[MAXLINE+1]; #if POSIXACLS struct POSIX_SECURITY *pxdesc; -#endif +#endif /* POSIXACLS */ int lth; int first; unsigned int pos; @@ -2646,7 +2130,7 @@ void showhex(FILE *fd) free(pxdesc); } } -#endif +#endif /* POSIXACLS */ pos = 0; } if (isdump && !off) @@ -2677,7 +2161,7 @@ void showhex(FILE *fd) } while (!done); } -BOOL applyattr(const char *fullname, const char *attr, +static BOOL applyattr(const char *fullname, const char *attr, BOOL withattr, int attrib, s32 key) { struct SECURITY_DATA *psecurdata; @@ -2687,10 +2171,6 @@ BOOL applyattr(const char *fullname, const char *attr, BOOL bad; BOOL badattrib; BOOL err; -#ifdef WIN32 - HANDLE htoken; - TOKEN_PRIVILEGES tkp; -#endif err = FALSE; psecurdata = (struct SECURITY_DATA*)NULL; @@ -2708,11 +2188,7 @@ BOOL applyattr(const char *fullname, const char *attr, /* If we have a usable attrib value. Try applying */ badattrib = FALSE; if (opt_e && (attrib != INVALID_FILE_ATTRIBUTES)) { -#ifdef WIN32 - badattrib = !SetFileAttributesW((LPCWSTR)fullname, attrib); -#else badattrib = !ntfs_set_file_attributes(ntfs_context, fullname, attrib); -#endif if (badattrib) { printf("** Could not set Windows attrib of "); printname(stdout,fullname); @@ -2738,58 +2214,15 @@ BOOL applyattr(const char *fullname, const char *attr, */ if (psecurdata) curattr = psecurdata->attr; - + if (curattr) { -#ifdef WIN32 - selection = OWNER_SECURITY_INFORMATION - | GROUP_SECURITY_INFORMATION - | DACL_SECURITY_INFORMATION; - if (OpenProcessToken(GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &htoken)) { - if (LookupPrivilegeValue(NULL, SE_SECURITY_NAME, - &tkp.Privileges[0].Luid)) { - tkp.PrivilegeCount = 1; - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - if (AdjustTokenPrivileges(htoken, FALSE, &tkp, 0, NULL, 0)) { - selection |= SACL_SECURITY_INFORMATION; - } - } - } - /* const missing from stupid prototype */ - bad = !SetFileSecurityW((LPCWSTR)fullname, - selection, (PSECURITY_DESCRIPTOR)(LONG_PTR)curattr); - if (bad) - switch (GetLastError()) { - case 1307 : - case 1314 : - printf("** Could not set owner or SACL of "); - printname(stdout,fullname); - printf(", retrying with no owner or SACL setting\n"); - warnings++; - /* const missing from stupid prototype */ - bad = !SetFileSecurityW((LPCWSTR)fullname, - selection & ~OWNER_SECURITY_INFORMATION - & ~SACL_SECURITY_INFORMATION, - (PSECURITY_DESCRIPTOR) - (LONG_PTR)curattr); - break; - default : - break; - } - /* Release privileges once we are done*/ - if (selection ^ SACL_SECURITY_INFORMATION) { - tkp.Privileges[0].Attributes = 0; - AdjustTokenPrivileges(htoken, FALSE, &tkp, 0, NULL, 0); - } -#else selection = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION; bad = !ntfs_set_file_security(ntfs_context,fullname, selection, (const char*)curattr); -#endif if (bad) { printf("** Could not set the ACL of "); printname(stdout,fullname); @@ -2819,7 +2252,7 @@ BOOL applyattr(const char *fullname, const char *attr, * Restore security descriptors from a file */ -BOOL restore(FILE *fd) +static BOOL restore(FILE *fd) { static char attr[MAXATTRSZ]; char line[MAXFILENAME+25]; @@ -2962,17 +2395,13 @@ BOOL restore(FILE *fd) oldhash = 0; attrib = INVALID_FILE_ATTRIBUTES; if (!done) { -#ifdef WIN32 - if (!strncmp(line,"File ",5)) - makeutf16(fullname,&line[5]); - else - makeutf16(fullname,&line[10]); -#else if (!strncmp(line,"File ",5)) strcpy(fullname,&line[5]); else strcpy(fullname,&line[10]); -#endif +#ifdef HAVE_WINDOWS_H + cleanpath(fullname); +#endif /* HAVE_WINDOWS_H */ } } } while (!done); @@ -2980,13 +2409,7 @@ BOOL restore(FILE *fd) return (FALSE); } -/* - * Open the security API in rw mode for an ACL restoration - */ - -#ifdef WIN32 -#else -BOOL dorestore(const char *volume, FILE *fd) +static BOOL dorestore(const char *volume, FILE *fd) { BOOL err; @@ -3013,9 +2436,8 @@ BOOL dorestore(const char *volume, FILE *fd) } return (err); } -#endif /* WIN32 */ -#if POSIXACLS & SELFTESTS & !USESTUBS +#if POSIXACLS /* * Merge Posix ACL rights into an u32 (self test only) @@ -3025,7 +2447,7 @@ BOOL dorestore(const char *volume, FILE *fd) * * Only two users (U1, U2) and two groups (G1, G2) taken into account */ -u32 merge_rights(const struct POSIX_SECURITY *pxdesc, BOOL def) +static u32 merge_rights(const struct POSIX_SECURITY *pxdesc, BOOL def) { const struct POSIX_ACE *pxace; int i; @@ -3077,21 +2499,55 @@ u32 merge_rights(const struct POSIX_SECURITY *pxdesc, BOOL def) return (rights); } -void tryposix(struct POSIX_SECURITY *pxdesc) +static BOOL same_posix(struct POSIX_SECURITY *pxdesc1, + struct POSIX_SECURITY *pxdesc2) +{ + BOOL same; + int i; + + same = pxdesc1 + && pxdesc2 + && (pxdesc1->mode == pxdesc2->mode) + && (pxdesc1->acccnt == pxdesc2->acccnt) + && (pxdesc1->defcnt == pxdesc2->defcnt) + && (pxdesc1->firstdef == pxdesc2->firstdef) + && (pxdesc1->tagsset == pxdesc2->tagsset) + && (pxdesc1->acl.version == pxdesc2->acl.version) + && (pxdesc1->acl.flags == pxdesc2->acl.flags); + i = 0; + while (same && (i < pxdesc1->acccnt)) { + same = (pxdesc1->acl.ace[i].tag == pxdesc2->acl.ace[i].tag) + && (pxdesc1->acl.ace[i].perms == pxdesc2->acl.ace[i].perms) + && (pxdesc1->acl.ace[i].id == pxdesc2->acl.ace[i].id); + i++; + } + i = pxdesc1->firstdef; + while (same && (i < pxdesc1->firstdef + pxdesc1->defcnt)) { + same = (pxdesc1->acl.ace[i].tag == pxdesc2->acl.ace[i].tag) + && (pxdesc1->acl.ace[i].perms == pxdesc2->acl.ace[i].perms) + && (pxdesc1->acl.ace[i].id == pxdesc2->acl.ace[i].id); + i++; + } + return (same); +} + +#endif /* POSIXACLS */ + +#if POSIXACLS & SELFTESTS + +static void tryposix(struct POSIX_SECURITY *pxdesc) { le32 owner_sid[] = /* S-1-5-21-3141592653-589793238-462843383-1016 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(DEFSECAUTH1), - const_cpu_to_le32(DEFSECAUTH2), const_cpu_to_le32(DEFSECAUTH3), - const_cpu_to_le32(1016) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + 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 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(DEFSECAUTH1), - const_cpu_to_le32(DEFSECAUTH2), const_cpu_to_le32(DEFSECAUTH3), - const_cpu_to_le32(513) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(513) } ; char *attr; @@ -3137,41 +2593,9 @@ void tryposix(struct POSIX_SECURITY *pxdesc) } } -static BOOL same_posix(struct POSIX_SECURITY *pxdesc1, - struct POSIX_SECURITY *pxdesc2) -{ - BOOL same; - int i; +#endif /* POSIXACLS & SELFTESTS */ - same = pxdesc1 - && pxdesc2 - && (pxdesc1->mode == pxdesc2->mode) - && (pxdesc1->acccnt == pxdesc2->acccnt) - && (pxdesc1->defcnt == pxdesc2->defcnt) - && (pxdesc1->firstdef == pxdesc2->firstdef) - && (pxdesc1->tagsset == pxdesc2->tagsset) - && (pxdesc1->acl.version == pxdesc2->acl.version) - && (pxdesc1->acl.flags == pxdesc2->acl.flags); - i = 0; - while (same && (i < pxdesc1->acccnt)) { - same = (pxdesc1->acl.ace[i].tag == pxdesc2->acl.ace[i].tag) - && (pxdesc1->acl.ace[i].perms == pxdesc2->acl.ace[i].perms) - && (pxdesc1->acl.ace[i].id == pxdesc2->acl.ace[i].id); - i++; - } - i = pxdesc1->firstdef; - while (same && (i < pxdesc1->firstdef + pxdesc1->defcnt)) { - same = (pxdesc1->acl.ace[i].tag == pxdesc2->acl.ace[i].tag) - && (pxdesc1->acl.ace[i].perms == pxdesc2->acl.ace[i].perms) - && (pxdesc1->acl.ace[i].id == pxdesc2->acl.ace[i].id); - i++; - } - return (same); -} - -#endif /* POSIXACLS & SELFTESTS & !USESTUBS */ - -#if SELFTESTS & !USESTUBS +#ifdef SELFTESTS /* * Build a dummy security descriptor @@ -3180,7 +2604,7 @@ static BOOL same_posix(struct POSIX_SECURITY *pxdesc1, static char *build_dummy_descr(BOOL isdir __attribute__((unused)), const SID *usid, const SID *gsid, - int cnt, + int cnt, /* seq of int allow, SID *sid, int flags, u32 mask */ ...) { @@ -3239,9 +2663,9 @@ static char *build_dummy_descr(BOOL isdir __attribute__((unused)), pacl = (ACL*)&attr[pos]; pacl->revision = ACL_REVISION; pacl->alignment1 = 0; - pacl->size = const_cpu_to_le16(0); /* fixed later */ + pacl->size = cpu_to_le16(0); /* fixed later */ pacl->ace_count = cpu_to_le16(cnt); - pacl->alignment2 = const_cpu_to_le16(0); + pacl->alignment2 = cpu_to_le16(0); /* enter the ACEs */ @@ -3268,8 +2692,8 @@ static char *build_dummy_descr(BOOL isdir __attribute__((unused)), /* append usid and gsid if defined */ /* positions of ACL, USID and GSID into header */ - pnhead->owner = const_cpu_to_le32(0); - pnhead->group = const_cpu_to_le32(0); + pnhead->owner = cpu_to_le32(0); + pnhead->group = cpu_to_le32(0); if (usid) { memcpy(&attr[pos], usid, usidsz); pnhead->owner = cpu_to_le32(pos); @@ -3279,14 +2703,13 @@ static char *build_dummy_descr(BOOL isdir __attribute__((unused)), pnhead->group = cpu_to_le32(pos + usidsz); } /* positions of DACL and SACL into header */ - pnhead->sacl = const_cpu_to_le32(0); + pnhead->sacl = cpu_to_le32(0); if (cnt) { pacl->size = cpu_to_le16(aclsz); pnhead->dacl = - const_cpu_to_le32(sizeof( - SECURITY_DESCRIPTOR_RELATIVE)); + cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE)); } else - pnhead->dacl = const_cpu_to_le32(0); + pnhead->dacl = cpu_to_le32(0); if (!ntfs_valid_descr(attr,pos+usidsz+gsidsz)) { printf("** Bad sample descriptor\n"); free(attr); @@ -3302,7 +2725,7 @@ static char *build_dummy_descr(BOOL isdir __attribute__((unused)), * Check a few samples with special conditions */ -void check_samples() +static void check_samples(void) { char *descr = (char*)NULL; BOOL isdir = FALSE; @@ -3318,41 +2741,36 @@ void check_samples() struct POSIX_SECURITY *pxdesc; struct POSIX_SECURITY *pxsample; const char *txsample; -#endif +#endif /* POSIXACLS */ le32 owner1[] = /* S-1-5-21-1833069642-4243175381-1340018762-1003 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(1833069642), - const_cpu_to_le32(4243175381), const_cpu_to_le32(1340018762), - const_cpu_to_le32(1003) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + cpu_to_le32(1833069642), cpu_to_le32(4243175381U), + cpu_to_le32(1340018762), cpu_to_le32(1003) } ; le32 group1[] = /* S-1-5-21-1833069642-4243175381-1340018762-513 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(1833069642), - const_cpu_to_le32(4243175381), const_cpu_to_le32(1340018762), - const_cpu_to_le32(513) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + cpu_to_le32(1833069642), cpu_to_le32(4243175381U), + cpu_to_le32(1340018762), cpu_to_le32(513) } ; le32 group2[] = /* S-1-5-21-1607551490-981732888-1819828000-513 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(1607551490), - const_cpu_to_le32(981732888), const_cpu_to_le32(1819828000), - const_cpu_to_le32(513) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + cpu_to_le32(1607551490), cpu_to_le32(981732888), + cpu_to_le32(1819828000), cpu_to_le32(513) } ; le32 owner3[] = /* S-1-5-21-3141592653-589793238-462843383-1016 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(DEFSECAUTH1), - const_cpu_to_le32(DEFSECAUTH2), const_cpu_to_le32(DEFSECAUTH3), - const_cpu_to_le32(1016) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + 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 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(DEFSECAUTH1), - const_cpu_to_le32(DEFSECAUTH2), const_cpu_to_le32(DEFSECAUTH3), - const_cpu_to_le32(513) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(513) } ; #if POSIXACLS @@ -3361,7 +2779,7 @@ void check_samples() struct POSIX_ACE ace[4]; } sampletry1 = { - { 0645, 4, 0, 4, 0x35, + { 0645, 4, 0, 4, 0x35, 0, { POSIX_VERSION, 0, 0 } }, { @@ -3377,7 +2795,7 @@ void check_samples() struct POSIX_ACE ace[6]; } sampletry3 = { - { 0100, 6, 0, 6, 0x3f, + { 0100, 6, 0, 6, 0x3f, 0, { POSIX_VERSION, 0, 0 } }, { @@ -3395,7 +2813,7 @@ void check_samples() struct POSIX_ACE ace[8]; } sampletry4 = { - { 0140, 8, 0, 8, 0x3f, + { 0140, 8, 0, 8, 0x3f, 0, { POSIX_VERSION, 0, 0 } }, { @@ -3415,7 +2833,7 @@ void check_samples() struct POSIX_ACE ace[6]; } sampletry5 = { - { 0454, 6, 0, 6, 0x3f, + { 0454, 6, 0, 6, 0x3f, 0, { POSIX_VERSION, 0, 0 } }, { @@ -3433,7 +2851,7 @@ void check_samples() struct POSIX_ACE ace[8]; } sampletry6 = { - { 0332, 8, 0, 8, 0x3f, + { 0332, 8, 0, 8, 0x3f, 0, { POSIX_VERSION, 0, 0 } }, { @@ -3453,7 +2871,7 @@ void check_samples() struct POSIX_ACE ace[4]; } sampletry8 = { - { 0677, 4, 0, 4, 0x35, + { 0677, 4, 0, 4, 0x35, 0, { POSIX_VERSION, 0, 0 } }, { @@ -3536,10 +2954,12 @@ void check_samples() else pxdesc = (struct POSIX_SECURITY*)NULL; if (!descr || !pxdesc || !same_posix(pxsample,pxdesc)) { - printf("** Error in %s\n",txsample); + printf("** Error in %s (errno %d)\n",txsample,errno); showposix(pxsample); - showall(descr,0); - showposix(pxdesc); + if (descr) + showall(descr,0); + if (pxdesc) + showposix(pxdesc); errors++; } free(descr); @@ -3562,7 +2982,7 @@ void check_samples() (const SID*)owner1, (const SID*)group1, 1, (int)TRUE, worldsid, (int)0x3, (u32)0x1f01ff); - expectacc = expect = 0777; + expect = expectacc = 0777; expectdef = 0; break; case 2 : /* swsetup */ @@ -3586,7 +3006,7 @@ void check_samples() descr = build_dummy_descr(isdir, (const SID*)owner3, (const SID*)group3, 4, - (int)TRUE, (const SID*)owner3, 0, + (int)TRUE, (const SID*)owner3, 0, le32_to_cpu(FILE_READ_DATA | OWNER_RIGHTS), (int)TRUE, (const SID*)group3, 0, le32_to_cpu(FILE_WRITE_DATA), @@ -3623,8 +3043,7 @@ void check_samples() (int)TRUE, adminsid, (int)0xb, (u32)0x1f01ff, (int)TRUE, owner3, (int)0x3, (u32)0x1200a9); expectacc = 0500070700; - expectdef = 0700; - expect = 0700; + expectdef = expect = 0700; break; case 7 : /* WinXP/JP */ isdir = TRUE; @@ -3710,11 +3129,10 @@ void check_samples() (long)defrights,(long)expectdef); showall(descr,0); showposix(pxdesc); -exit(1); } free(pxdesc); } -#endif +#endif /* POSIXACLS */ } free(descr); } @@ -3727,7 +3145,7 @@ exit(1); * back exactly as set */ -void basictest(int kind, BOOL isdir, const SID *owner, const SID *group) +static void basictest(int kind, BOOL isdir, const SID *owner, const SID *group) { char *attr; mode_t perm; @@ -3761,7 +3179,7 @@ void basictest(int kind, BOOL isdir, const SID *owner, const SID *group) u32 pxcount; u32 pxacecount; u32 pxglobhash; -#endif +#endif /* POSIXACLS */ count = 0; acecount = 0; @@ -3770,7 +3188,7 @@ void basictest(int kind, BOOL isdir, const SID *owner, const SID *group) pxcount = 0; pxacecount = 0; pxglobhash = 0; -#endif +#endif /* POSIXACLS */ for (perm=0; (perm<=07777) && (errors < 10); perm++) { err = ERRNO; /* file owned by plain user and group */ @@ -3820,7 +3238,7 @@ void basictest(int kind, BOOL isdir, const SID *owner, const SID *group) free(attr); } free(pxdesc); -#else +#else /* POSIXACLS */ gotback = linux_permissions(attr, isdir); if (gotback != perm) err = ERRAM; @@ -3868,7 +3286,7 @@ void basictest(int kind, BOOL isdir, const SID *owner, const SID *group) break; case ERRAP : /* continued */ -#else +#else /* POSIXACLS */ case ERRAM : case ERRAP : #endif /* POSIXACLS */ @@ -3930,7 +3348,7 @@ void basictest(int kind, BOOL isdir, const SID *owner, const SID *group) * back exactly as set */ -void posixtest(int kind, BOOL isdir, +static void posixtest(int kind, BOOL isdir, const SID *owner, const SID *group) { struct POSIX_SECURITY *pxdesc; @@ -3956,23 +3374,8 @@ void posixtest(int kind, BOOL isdir, enum { ERRNO, ERRMA, ERRPA, /* error converting mode or Posix ACL to NTFS */ ERRAM, ERRAP, /* error converting NTFS to mode or Posix ACL */ - } err; + } ; u32 expectcnt[] = { -#ifdef STSC - 32400, 34992, - 25920, 28512, - 25920, 28512, - 25920, 28512, - 26460, 29052, - 0, 0, - 0, 0, - 0, 0, - 24516, 27108, - 20736, 23328, - 20736, 23328, - 20736, 23328, - 21060, 23652, -#else 252720, 273456, 199584, 220320, 199584, 220320, @@ -3986,7 +3389,6 @@ void posixtest(int kind, BOOL isdir, 165888, 186624, 165888, 186624, 168480, 189216, -#endif 0, 0, 0, 0, 0, 0, @@ -3997,21 +3399,6 @@ void posixtest(int kind, BOOL isdir, 14640, 0 } ; u32 expecthash[] = { -#ifdef STSC - 0xf9f82115, 0x40666647, - 0xde826d30, 0xa181b660, - 0x952d4500, 0x8ac49450, - 0xf80acee0, 0xbd9ec6c0, - 0xfe09b868, 0xde24e84d, - 0, 0, - 0, 0, - 0, 0, - 0x2381438d, 0x3ab42dc6, - 0x7cccf6f8, 0x108ad430, - 0x5e448840, 0x83ab6c40, - 0x9b037100, 0x8f7c3b40, - 0x04a359dc, 0xa4619609, -#else 0x1808a6cd, 0xd82f7c60, 0x5ad29e85, 0x518c7620, 0x188ce270, 0x7e44e590, @@ -4025,7 +3412,6 @@ void posixtest(int kind, BOOL isdir, 0xf9685700, 0x44d16700, 0x587ebe90, 0xf7c51480, 0x2cb1b518, 0x52408df6, -#endif 0, 0, 0, 0, 0, 0, @@ -4080,13 +3466,8 @@ void posixtest(int kind, BOOL isdir, mindes = 3; maxdes = (kind & 32 ? mindes : 6); -#ifdef STSC - minmsk = (kind & 32 ? 0 : 3); - maxmsk = (kind & 32 ? 7 : 3); -#else minmsk = 0; maxmsk = 7; -#endif for (mask=minmsk; mask<=maxmsk; mask++) for (ownobj=1; ownobj<7; ownobj++) for (grpobj=1; grpobj<7; grpobj++) @@ -4110,7 +3491,6 @@ void posixtest(int kind, BOOL isdir, pxdesc->acl.ace[5].perms = wrld; } - err = ERRNO; gotback = (struct POSIX_SECURITY*)NULL; pxattr = ntfs_build_descr_posix(context.mapping, pxdesc,isdir,owner,group); @@ -4136,7 +3516,6 @@ void posixtest(int kind, BOOL isdir, printf("gotback ACL\n"); showposix(gotback); errors++; -exit(1); } } else { printf("Got back an invalid Posix ACL\n"); @@ -4184,32 +3563,24 @@ exit(1); #endif /* POSIXACLS */ -void selftests(void) +static void selftests(void) { le32 owner_sid[] = /* S-1-5-21-3141592653-589793238-462843383-1016 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(DEFSECAUTH1), - const_cpu_to_le32(DEFSECAUTH2), const_cpu_to_le32(DEFSECAUTH3), - const_cpu_to_le32(1016) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + 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 */ { - const_cpu_to_le32(0x501), const_cpu_to_le32(0x05000000), - const_cpu_to_le32(21), const_cpu_to_le32(DEFSECAUTH1), - const_cpu_to_le32(DEFSECAUTH2), const_cpu_to_le32(DEFSECAUTH3), - const_cpu_to_le32(513) + cpu_to_le32(0x501), cpu_to_le32(0x05000000), cpu_to_le32(21), + cpu_to_le32(DEFSECAUTH1), cpu_to_le32(DEFSECAUTH2), + cpu_to_le32(DEFSECAUTH3), cpu_to_le32(513) } ; #if POSIXACLS -#ifdef STSC - unsigned char kindlist[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 16, 17, 18, 20, 22, 24, - 32, 33, 36, 40 } ; -#else unsigned char kindlist[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 20, 22, 24, 19, 21, 23, 25, 32, 33, 36, 40 } ; -#endif unsigned int k; #endif /* POSIXACLS */ int kind; @@ -4219,11 +3590,10 @@ void selftests(void) #if POSIXACLS local_build_mapping(context.mapping, (const char*)NULL); -#endif +#endif /* POSIXACLS */ /* first check samples */ mappingtype = MAPDUMMY; check_samples(); -if (errors) exit(1); /* * kind is oring of : * 1 : directory @@ -4254,202 +3624,17 @@ if (errors) exit(1); posixtest(kind, isdir, owner, group); } ntfs_free_mapping(context.mapping); -#endif +#endif /* POSIXACLS */ if (errors >= 10) printf("** too many errors, test aborted\n"); } -#endif /* SELFTESTS & !USESTUBS */ - -#ifdef WIN32 +#endif /* SELFTESTS */ /* - * Get the security descriptor of a file (Windows version) + * Get the security descriptor of a file */ -unsigned int getfull(char *attr, const char *fullname) -{ - static char part[MAXATTRSZ]; - BIGSID ownsid; - int xowner; - int ownersz; - u16 ownerfl; - ULONG attrsz; - ULONG partsz; - BOOL overflow; - HANDLE htoken; - TOKEN_PRIVILEGES tkp; - BOOL saclsuccess; - - attrsz = 0; - partsz = 0; - overflow = FALSE; - if (GetFileSecurityW((LPCWSTR)fullname,OWNER_SECURITY_INFORMATION, - (char*)part,MAXATTRSZ,&partsz)) { - xowner = get4l(part,4); - if (xowner) { - ownerfl = get2l(part,2); - ownersz = ntfs_sid_size((SID*)&part[xowner]); - if (ownersz <= (int)sizeof(BIGSID)) - memcpy(ownsid,&part[xowner],ownersz); - else - overflow = TRUE; - } else { - ownerfl = 0; - ownersz = 0; - } - /* - * SACL : just feed in or clean - * This requires the SE_SECURITY_NAME privilege - */ - saclsuccess = FALSE; - if (OpenProcessToken(GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &htoken)) { - if (LookupPrivilegeValue(NULL, SE_SECURITY_NAME, - &tkp.Privileges[0].Luid)) { - tkp.PrivilegeCount = 1; - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - if (AdjustTokenPrivileges(htoken, FALSE, &tkp, 0, NULL, 0)) { - if (GetFileSecurityW((LPCWSTR)fullname, - SACL_SECURITY_INFORMATION, - (char*)attr,MAXATTRSZ,&attrsz)) { - saclsuccess = TRUE; - } - tkp.Privileges[0].Attributes = 0; - AdjustTokenPrivileges(htoken, FALSE, &tkp, 0, NULL, 0); - } - } - } - if (!saclsuccess) { - attrsz = 20; - set4l(attr,0); - attr[0] = SECURITY_DESCRIPTOR_REVISION; - set4l(&attr[12],0); - if (opt_v >= 2) - printf(" No SACL\n"); - } - /* - * append DACL and merge its flags - */ - partsz = 0; - set4l(&attr[16],0); - if (GetFileSecurityW((LPCWSTR)fullname,DACL_SECURITY_INFORMATION, - (char*)part,MAXATTRSZ,&partsz)) { - if ((attrsz + partsz - 20) <= MAXATTRSZ) { - memcpy(&attr[attrsz],&part[20],partsz-20); - set4l(&attr[16],(partsz > 20 ? attrsz : 0)); - set2l(&attr[2],get2l(attr,2) | (get2l(part,2) - & const_le16_to_cpu(SE_DACL_PROTECTED - | SE_DACL_AUTO_INHERITED - | SE_DACL_PRESENT))); - attrsz += partsz - 20; - } else - overflow = TRUE; - } else - if (partsz > MAXATTRSZ) - overflow = TRUE; - else { - if (opt_b) - printf("# No discretionary access control list\n"); - else - printf(" No discretionary access control list\n"); - warnings++; - } - - /* - * append owner and merge its flag - */ - if (xowner && !overflow) { - memcpy(&attr[attrsz],ownsid,ownersz); - set4l(&attr[4],attrsz); - set2l(&attr[2],get2l(attr,2) - | (ownerfl & const_le16_to_cpu(SE_OWNER_DEFAULTED))); - attrsz += ownersz; - } else - set4l(&attr[4],0); - /* - * append group - */ - partsz = 0; - set4l(&attr[8],0); - if (GetFileSecurityW((LPCWSTR)fullname,GROUP_SECURITY_INFORMATION, - (char*)part,MAXATTRSZ,&partsz)) { - if ((attrsz + partsz - 20) <= MAXATTRSZ) { - memcpy(&attr[attrsz],&part[20],partsz-20); - set4l(&attr[8],(partsz > 20 ? attrsz : 0)); - set2l(&attr[2],get2l(attr,2) | (get2l(part,2) - & const_le16_to_cpu(SE_GROUP_DEFAULTED))); - attrsz += partsz - 20; - } else - overflow = TRUE; - } else - if (partsz > MAXATTRSZ) - overflow = TRUE; - else { - printf("** No group SID\n"); - warnings++; - } - set2l(&attr[2],get2l(attr,2) - | const_le16_to_cpu(SE_SELF_RELATIVE)); - if (overflow) { - printf("** Descriptor was too long (> %d)\n",MAXATTRSZ); - warnings++; - attrsz = 0; - } else - if (!ntfs_valid_descr((char*)attr,attrsz)) { - printf("** Descriptor for "); - printname(stdout,fullname); - printf(" is not valid\n"); - errors++; - attrsz = 0; - } - - } else { - printf("** Could not get owner of "); - printname(stdout,fullname); - printf(", partsz %d\n",partsz); - printerror(stdout); - warnings++; - attrsz = 0; - } - return (attrsz); -} - -/* - * Update a security descriptor (Windows version) - */ - -BOOL updatefull(const char *name, DWORD flags, char *attr) -{ - BOOL bad; - - bad = !SetFileSecurityW((LPCWSTR)name, flags, attr); - if (bad - && (flags & OWNER_SECURITY_INFORMATION) - && (GetLastError() == 1307)) { - printf("** Could not set owner of "); - printname(stdout,name); - printf(", retrying with no owner setting\n"); - warnings++; - bad = !SetFileSecurityW((LPCWSTR)name, - flags & ~OWNER_SECURITY_INFORMATION, (char*)attr); - } - if (bad) { - printf("** Could not change attributes of "); - printname(stdout,name); - printf("\n"); - printerror(stdout); - errors++; - } - return (!bad); -} - -#else - -/* - * Get the security descriptor of a file (Linux version) - */ - -unsigned int getfull(char *attr, const char *fullname) +static unsigned int getfull(char *attr, const char *fullname) { static char part[MAXATTRSZ]; BIGSID ownsid; @@ -4513,7 +3698,7 @@ unsigned int getfull(char *attr, const char *fullname) if (partsz > MAXATTRSZ) overflow = TRUE; else { - if (opt_b) + if (cmd == CMD_BACKUP) printf("# No discretionary access control list\n"); else printf(" No discretionary access control list\n"); @@ -4568,38 +3753,37 @@ unsigned int getfull(char *attr, const char *fullname) } else { printf("** Could not get owner of %s\n",fullname); warnings++; - attrsz = 0; + attrsz = 0; } return (attrsz); } /* - * Update a security descriptor (Linux version) + * Update a security descriptor */ -BOOL updatefull(const char *name, DWORD flags, char *attr) +static BOOL updatefull(const char *name, u32 flags, char *attr) { - BOOL ok; + BOOL err; - ok = !ntfs_set_file_security(ntfs_context, name, flags, attr); - if (ok) { +// Why was the error not seen before ? + err = !ntfs_set_file_security(ntfs_context, name, flags, attr); + if (err) { printf("** Could not change attributes of %s\n",name); printerror(stdout); errors++; } - return (ok); + return (!err); } -#endif - #if POSIXACLS /* * Set all the parameters associated to a file */ -BOOL setfull_posix(const char *fullname, const struct POSIX_SECURITY *pxdesc, +static BOOL setfull_posix(const char *fullname, const struct POSIX_SECURITY *pxdesc, BOOL isdir) { static char attr[MAXATTRSZ]; @@ -4614,7 +3798,7 @@ BOOL setfull_posix(const char *fullname, const struct POSIX_SECURITY *pxdesc, const SID *gsid; #if OWNERFROMACL const SID *osid; -#endif +#endif /* OWNERFROMACL */ printf("%s ",(isdir ? "Directory" : "File")); printname(stdout,fullname); @@ -4658,12 +3842,18 @@ BOOL setfull_posix(const char *fullname, const struct POSIX_SECURITY *pxdesc, osid = (const SID*)&attr[le32_to_cpu(phead->owner)]; usid = ntfs_acl_owner((const char*)attr); if (!ntfs_same_sid(usid,osid)) - printf("== Windows owner might change\n"); -#else + printf("== Windows owner might change\n"); +#else /* OWNERFROMACL */ usid = (const SID*)&attr[le32_to_cpu(phead->owner)]; -#endif - newattr = ntfs_build_descr_posix(context.mapping, - newpxdesc,isdir,usid,gsid); +#endif /* OWNERFROMACL */ + if (mappingtype == MAPEXTERN) + newattr = ntfs_build_descr_posix( + ntfs_context->security.mapping, + newpxdesc,isdir,usid,gsid); + else + newattr = ntfs_build_descr_posix( + context.mapping, + newpxdesc,isdir,usid,gsid); free(newpxdesc); } else newattr = (char*)NULL; @@ -4683,23 +3873,11 @@ BOOL setfull_posix(const char *fullname, const struct POSIX_SECURITY *pxdesc, showsacl(newattr,isdir,0); } -#ifdef WIN32 - /* - * avoid getting a set owner error on Windows - * owner should not be changed anyway - */ if (!updatefull(fullname, DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, newattr)) -#else - if (!updatefull(fullname, - DACL_SECURITY_INFORMATION - | GROUP_SECURITY_INFORMATION - | OWNER_SECURITY_INFORMATION, - newattr)) -#endif err = TRUE; /* { @@ -4718,9 +3896,9 @@ free(interp); return (!err); } -#endif +#else /* POSIXACLS */ -BOOL setfull(const char *fullname, int mode, BOOL isdir) +static BOOL setfull(const char *fullname, int mode, BOOL isdir) { static char attr[MAXATTRSZ]; const SECURITY_DESCRIPTOR_RELATIVE *phead; @@ -4732,7 +3910,7 @@ BOOL setfull(const char *fullname, int mode, BOOL isdir) const SID *gsid; #if OWNERFROMACL const SID *osid; -#endif +#endif /* OWNERFROMACL */ printf("%s ",(isdir ? "Directory" : "File")); printname(stdout,fullname); @@ -4746,10 +3924,10 @@ BOOL setfull(const char *fullname, int mode, BOOL isdir) osid = (const SID*)&attr[le32_to_cpu(phead->owner)]; usid = ntfs_acl_owner((const char*)attr); if (!ntfs_same_sid(usid,osid)) - printf("== Windows owner might change\n"); -#else + printf("== Windows owner might change\n"); +#else /* OWNERFROMACL */ usid = (const SID*)&attr[le32_to_cpu(phead->owner)]; -#endif +#endif /* OWNERFROMACL */ newattr = ntfs_build_descr(mode,isdir,usid,gsid); if (newattr) { newattrsz = ntfs_attr_size(newattr); @@ -4767,33 +3945,23 @@ BOOL setfull(const char *fullname, int mode, BOOL isdir) showsacl(newattr,isdir,0); } -#ifdef WIN32 - /* - * avoid getting a set owner error on Windows - * owner should not be changed anyway - */ if (!updatefull(fullname, DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, newattr)) -#else - if (!updatefull(fullname, - DACL_SECURITY_INFORMATION - | GROUP_SECURITY_INFORMATION - | OWNER_SECURITY_INFORMATION, - newattr)) -#endif err = TRUE; free(newattr); } - + } else err = TRUE; return (err); } -BOOL proposal(const char *name, const char *attr) +#endif /* POSIXACLS */ + +static BOOL proposal(const char *name, const char *attr) { char fullname[MAXFILENAME]; int uoff, goff; @@ -4802,20 +3970,20 @@ BOOL proposal(const char *name, const char *attr) int ucnt, gcnt; int uid, gid; BOOL err; -#ifdef WIN32 +#ifdef HAVE_WINDOWS_H char driveletter; -#else +#else /* HAVE_WINDOWS_H */ struct stat st; char *p,*q; -#endif +#endif /* HAVE_WINDOWS_H */ err = FALSE; -#ifdef WIN32 +#ifdef HAVE_WINDOWS_H uid = gid = 0; -#else +#else /* HAVE_WINDOWS_H */ uid = getuid(); gid = getgid(); -#endif +#endif /* HAVE_WINDOWS_H */ uoff = get4l(attr,4); uauth = get6h(attr,uoff+2); ucnt = attr[uoff+1] & 255; @@ -4832,7 +4000,7 @@ BOOL proposal(const char *name, const char *attr) printf("%d::",uid); else printf("user::"); - printf("S-%d-%llu",attr[uoff] & 255,uauth); + printf("S-%d-%llu",attr[uoff] & 255,(long long)uauth); for (i=0; i