/*
* 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
* 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
*
* 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
*/
/*
* General parameters which may have to be adapted to needs
*/
-#define AUDT_VERSION "1.4.6"
-
-#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 AUDT_VERSION "1.5.0"
+
+#define SELFTESTS 0
+#define NOREVBOM 0 /* still unclear what this should be */
/*
* External declarations
*/
+#include "config.h"
+
+#ifdef HAVE_STDIO_H
#include <stdio.h>
-#include <time.h>
-#include <string.h>
+#endif /* HAVE_STDIO_H */
+#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
+#endif /* HAVE_STDLIB_H */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif /* HAVE_TIME_H */
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+#ifdef HAVE_ERRNO_H
#include <errno.h>
-#include <stdarg.h>
+#endif /* HAVE_ERRNO_H */
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+#ifdef HAVE_SETXATTR
+#include <sys/xattr.h>
+#else /* HAVE_SETXATTR */
+#warning "The extended attribute package is not available"
+#endif /* HAVE_SETXATTR */
- /*
- * integration into secaudit, check whether Win32,
- * may have to be adapted to compiler or something else
- */
+#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"
-#ifndef WIN32
-#if defined(__WIN32) | defined(__WIN32__) | defined(WNSC)
-#define WIN32 1
-#endif
-#endif
+struct CALLBACK;
- /*
- * integration into secaudit/Win32
- */
-#ifdef WIN32
-#include <windows.h>
-#define __LITTLE_ENDIAN 1234
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#else
- /*
- * integration into secaudit/STSC
- */
-#ifdef STSC
-#include <stat.h>
-#undef __BYTE_ORDER
-#define __BYTE_ORDER __BIG_ENDIAN
-#else
- /*
- * integration into secaudit/Linux
- */
+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);
-#include <sys/stat.h>
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#endif
-#ifdef HAVE_MACHINE_ENDIAN_H
-#include <machine/endian.h>
-#endif
-#include <unistd.h>
-#include <dlfcn.h>
-#endif /* STSC */
-#endif /* WIN32 */
-#include "secaudit.h"
+#if POSIXACLS
-#ifndef WIN32
+static BOOL same_posix(struct POSIX_SECURITY *pxdesc1,
+ struct POSIX_SECURITY *pxdesc2);
-#ifndef STSC
+#endif /* POSIXACLS */
-#if !defined(HAVE_CONFIG_H) && POSIXACLS && !defined(__SVR4)
- /* require <sys/xattr.h> if not integrated into ntfs-3g package */
-#define HAVE_SETXATTR 1
-#endif
+#ifndef HAVE_SYSLOG_H
+void ntfs_log_early_error(const char *format, ...)
+ __attribute__((format(printf, 1, 2)));
+#endif /* HAVE_SYSLOG_H */
-#ifdef HAVE_CONFIG_H
-#ifdef _FILE_OFFSET_BITS
-#undef _FILE_OFFSET_BITS /* work around "_FILE_OFFSET_BITS" possibly already defined */
-#endif
- /* <sys/xattr.h> 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 */
+#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 */
-#ifdef HAVE_SETXATTR
-#include <sys/xattr.h>
+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
-#warning "The extended attribute package is not available"
-#endif /* HAVE_SETXATTR */
+#define DIRSEP "/"
+#endif
-#endif /* STSC */
+ /* standard owner (and administrator) rights */
-#define NTFS_MNT_NONE 0 /* no flag for mounting the device */
-#define NTFS_MNT_RDONLY 1 /* flag for mounting the device read-only */
+#define OWNER_RIGHTS (DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER \
+ | SYNCHRONIZE \
+ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES \
+ | FILE_READ_EA | FILE_WRITE_EA)
-struct CALLBACK;
+ /* standard world rights */
-typedef int (*dircallback)(struct CALLBACK *context, char *ntfsname,
- int length, int type, long long pos, u64 mft_ref,
- unsigned int dt_type);
+#define WORLD_RIGHTS (READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_EA \
+ | SYNCHRONIZE)
-#ifndef HAVE_SYSLOG_H
-void ntfs_log_early_error(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-#endif
+ /* inheritance flags for files and directories */
-#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);
+#define FILE_INHERITANCE NO_PROPAGATE_INHERIT_ACE
+#define DIR_INHERITANCE (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE)
-#else
+/*
+ * 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.
+ */
-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 */
+#define ROOT_OWNER_UNMARK SYNCHRONIZE /* ACL granted to root as owner */
+#define ROOT_GROUP_UNMARK FILE_READ_EA /* ACL granted to root as group */
+
+#define INSDS1 1
+#define INSDS2 2
+#define INSII 4
+#define INSDH 8
+
+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;
+} ;
-#define ACCOUNTSIZE 256 /* maximum size of an account name */
+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
/*
- * Prototypes for local functions
+ * Including <windows.h> 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 */
-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*);
-
-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*[]);
-
-#ifndef WIN32
+#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 {
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)
"::" 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;
+static const SID *authsid = (const SID*)authsidbytes;
/*
* SID for local users (S-1-5-32-545)
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;
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;
return (v);
}
-unsigned long get4l(const char *attr, int p)
+static unsigned long get4l(const char *attr, int p)
{
int i;
unsigned long v;
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;
return (v);
}
-u64 get8l(const char *attr, int p)
+static u64 get8l(const char *attr, int p)
{
int i;
u64 v;
* 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;
p[i] = ((v >> 8*i) & 255);
}
-void set4l(char *p, unsigned long v)
+static void set4l(char *p, unsigned long v)
{
int i;
* 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;
}
}
-u32 hash(const le32 *buf, int size /* bytes */)
+static u32 hash(const le32 *buf, int size /* bytes */)
{
u32 h;
int i;
* 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;
-
- 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
+ int count = 0;
+ BOOL surrog;
+ BOOL fail;
+
+ 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);
}
/*
* 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;
-
- 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);
+ int size;
+
+ size = ntfs_ucstombs(utf16, length, &utf8, MAXFILENAME);
+ return (size < 0 ? 0 : size);
}
-#ifdef WIN32
+/*
+ * Print a file name
+ * on Windows it prints UTF-16LE names as UTF-8
+ */
+
+static void printname(FILE *file, const char *name)
+{
+#ifdef HAVE_WINDOWS_H
+ char *wname;
+ char *p;
+
+ 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 /* HAVE_WINDOWS_H */
+}
/*
- * Evaluate the size of UTF-16LE conversion of a UTF-8 text
- * (basic conversions only)
- * trailing '\0' not accounted for
+ * Print the last error code
*/
-unsigned int utf16size(const char *utf8)
+static void printerror(FILE *file)
{
- 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 (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 EBUSY :
+ fprintf(file,"You probably try to write to a mounted device\n");
+ break;
+ default :
+ break;
}
- if (state != BASE) size = 0;
- return (size);
}
+#ifndef HAVE_SYSLOG_H
+
/*
- * 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
+ * Redefine early error messages in stand-alone situations
*/
-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)
-{
-#ifdef WIN32
- char utf8name[MAXFILENAME];
-
- makeutf8(utf8name,name,utf16len(name));
- fprintf(file,"%s",utf8name);
-#else
- fprintf(file,"%s",name);
-#endif
-}
-
-/*
- * Print the last error code
- */
-
-void printerror(FILE *file)
-{
-#ifdef WIN32
- int err;
- const char *txt;
-
- err = GetLastError();
- switch (err) {
- case 5 :
- txt = "Access to security descriptor was denied";
- 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";
- 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
-
-/*
- * 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;
va_end(args);
}
-#endif
+#endif /* HAVE_SYSLOG_H */
/*
* Guess whether a security attribute is intended for a directory
* (not 100% reliable)
*/
-BOOL guess_dir(const char *attr)
+static BOOL guess_dir(const char *attr)
{
int off;
int isdir;
* 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;
unsigned long last;
char marker;
- if (opt_b)
+ if (cmd == CMD_BACKUP)
marker = '#';
else
marker = ' ';
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; i<cnt; i++)
printf("-%lx",get4l(attr,off+8+4*i));
printf("\n");
printf("%*c%sdec S-%d-",-level,marker,prefix,attr[off] & 255);
- printf("%llu",auth);
+ printf("%llu",(long long)auth);
for (i=0; i<cnt; i++)
printf("-%lu",get4l(attr,off+8+4*i));
printf("\n");
}
-void showusid(const char *attr, int level)
+static void showusid(const char *attr, int level)
{
int off;
char marker;
- if (opt_b)
+ if (cmd == CMD_BACKUP)
marker = '#';
else
marker = ' ';
showsid(attr,off,"O:",level+4);
}
-void showgsid(const char *attr, int level)
+static void showgsid(const char *attr, int level)
{
int off;
char marker;
- if (opt_b)
+ if (cmd == CMD_BACKUP)
marker = '#';
else
marker = ' ';
showsid(attr,off,"G:",level+4);
}
-void showownership(const char *attr)
+static void showownership(const char *attr)
{
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
char account[ACCOUNTSIZE];
BIGSID sidcopy;
- SID_NAME_USE use;
- unsigned long accountsz;
- unsigned long domainsz;
-#endif
- enum { SHOWOWN, SHOWGRP, SHOWINT } shown;
+ s32 use;
+ u32 accountsz;
+ u32 domainsz;
+#endif /* HAVE_WINDOWS_H */
+ enum { SHOWOWN, SHOWGRP, SHOWINT, SHOWDONE } shown;
const char *sid;
const char *prefix;
u64 auth;
int off;
int i;
- for (shown=SHOWOWN; shown<=SHOWINT; shown++) {
+ for (shown=SHOWOWN; shown<SHOWDONE; ) {
switch (shown) {
case SHOWOWN :
off = get4l(attr,4);
sid = &attr[off];
prefix = "Windows owner";
+ shown = SHOWGRP;
break;
case SHOWGRP :
off = get4l(attr,8);
sid = &attr[off];
prefix = "Windows group";
+ shown = SHOWINT;
break;
#if OWNERFROMACL
case SHOWINT :
if (ntfs_same_sid((const SID*)sid,
(const SID*)&attr[off]))
sid = (const char*)NULL;
+ shown = SHOWDONE;
break;
-#endif
+#endif /* OWNERFROMACL */
default :
sid = (const char*)NULL;
prefix = (const char*)NULL;
+ shown = SHOWDONE;
break;
}
if (sid) {
cnt = sid[1] & 255;
auth = get6h(sid,2);
- if (opt_b)
+ if (cmd == CMD_BACKUP)
printf("# %s S-%d-",prefix,sid[0] & 255);
else
printf("%s S-%d-",prefix,sid[0] & 255);
- printf("%llu",auth);
+ printf("%llu",(long long)auth);
for (i=0; i<cnt; i++)
printf("-%lu",get4l(sid,8+4*i));
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
memcpy(sidcopy,sid,ntfs_sid_size((const SID*)sid));
accountsz = ACCOUNTSIZE;
domainsz = ACCOUNTSIZE;
account, &accountsz,
(char*)NULL, &domainsz, &use))
printf(" (%s)", account);
-#endif
+#endif /* HAVE_WINDOWS_H */
printf("\n");
}
}
}
-void showheader(const char *attr, int level)
+static void showheader(const char *attr, int level)
{
int flags;
char marker;
- if (opt_b)
+ if (cmd == CMD_BACKUP)
marker = '#';
else
marker = ' ';
printf("%*cOff DACL 0x%x\n",-level-4,marker,(int)get4l(attr,16));
}
-void showace(const char *attr, int off, int isdir, int level)
+static void showace(const char *attr, int off, int isdir, int level)
{
int flags;
u32 rights;
char marker;
- if (opt_b)
+ if (cmd == CMD_BACKUP)
marker = '#';
else
marker = ' ';
}
-void showacl(const char *attr, int off, int isdir, int level)
+static void showacl(const char *attr, int off, int isdir, int level)
{
int i;
int cnt;
int x;
char marker;
- if (opt_b)
+ if (cmd == CMD_BACKUP)
marker = '#';
else
marker = ' ';
}
}
-void showdacl(const char *attr, int isdir, int level)
+static void showdacl(const char *attr, int isdir, int level)
{
int off;
char marker;
- if (opt_b)
+ if (cmd == CMD_BACKUP)
marker = '#';
else
marker = ' ';
}
}
-void showsacl(const char *attr, int isdir, int level)
+static void showsacl(const char *attr, int isdir, int level)
{
int off;
char marker;
- if (opt_b)
+ if (cmd == CMD_BACKUP)
marker = '#';
else
marker = ' ';
}
}
-void showall(const char *attr, int level)
+static void showall(const char *attr, int level)
{
BOOL isdir;
* Display a Posix descriptor
*/
-void showposix(const struct POSIX_SECURITY *pxdesc)
+static void showposix(const struct POSIX_SECURITY *pxdesc)
{
char txperm[4];
const char *txtag;
#endif /* POSIXACLS */
-#if defined(WIN32) | defined(STSC)
-
-#else
-
-/*
- * Relay to get usid as defined during mounting
- */
-
-const SID *relay_find_usid(const struct MAPPING *usermapping __attribute__((unused)),
- uid_t uid, SID *defusid)
-{
- return (ntfs_get_usid(ntfs_context,uid,(char*)defusid) ?
- defusid : (SID*)NULL);
-}
-
-/*
- * Relay to get gsid as defined during mounting
- */
-
-const SID *relay_find_gsid(const struct MAPPING *groupmapping __attribute__((unused)),
- uid_t gid, SID *defgsid)
-{
- return (ntfs_get_usid(ntfs_context,gid,(char*)defgsid) ?
- defgsid : (SID*)NULL);
-}
-
/*
* Relay to get uid as defined during mounting
*/
-uid_t relay_find_user(const struct MAPPING *mapping __attribute__((unused)),
+static uid_t relay_find_user(const struct MAPPING *mapping __attribute__((unused)),
const SID *usid)
{
int uid;
- uid = ntfs_get_user(ntfs_context,(const char*)usid);
+ uid = ntfs_get_user(ntfs_context, usid);
return (uid < 0 ? 0 : uid);
}
* Relay to get gid as defined during mounting
*/
-gid_t relay_find_group(const struct MAPPING *mapping __attribute__((unused)),
+static gid_t relay_find_group(const struct MAPPING *mapping __attribute__((unused)),
const SID *gsid)
{
int gid;
- gid = ntfs_get_group(ntfs_context,(const char*)gsid);
+ gid = ntfs_get_group(ntfs_context, gsid);
return (gid < 0 ? 0 : gid);
}
-#endif
-
-#if defined(WIN32) | defined(STSC)
-
-/*
- * Dummy get uid from user name, out of a Linux environment
- */
-
-struct passwd *getpwnam(const char *user)
-{
- ntfs_log_error("Cannot interpret id \"%s\"", user);
- ntfs_log_error("please use numeric uids in UserMapping file\n");
- return ((struct passwd*)NULL);
-}
-
-/*
- * Dummy get gid from group name, out of a Linux environment
- */
-
-struct group *getgrnam(const char *group)
-{
- ntfs_log_error("Cannot interpret id \"%s\"", group);
- ntfs_log_error("please use numeric gids in UserMapping file\n");
- return ((struct group*)NULL);
-}
-
-#endif /* defined(WIN32) | defined(STSC) */
-
#if POSIXACLS
-struct POSIX_SECURITY *linux_permissions_posix(const char *attr, BOOL isdir)
+static struct POSIX_SECURITY *linux_permissions_posix(const char *attr, BOOL isdir)
{
const SECURITY_DESCRIPTOR_RELATIVE *phead;
#if OWNERFROMACL
const SID *osid;
-#endif
+#endif /* OWNERFROMACL */
const SID *usid;
const SID *gsid;
struct POSIX_SECURITY *posix_desc;
#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
- 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++;
#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;
#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");
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;
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;
}
}
-void freeblocks(void)
+static void freeblocks(void)
{
int i,j;
struct SECURITY_DATA *psecurdata;
* 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;
return (sz);
}
-#endif /* POSIXACLS & SELFTESTS & !USESTUBS */
+#endif /* SELFTESTS */
/*
* Apply default single user 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;
* (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;
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);
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) {
/* and rely on internal representation */
while (firstitem) {
item = firstitem->next;
-#if USESTUBS
- stdfree(firstitem); /* allocated within library */
-#else
free(firstitem);
-#endif
firstitem = item;
}
} else {
* Get an hexadecimal number (source with MSB first)
*/
-u32 getmsbhex(const char *text)
+static u32 getmsbhex(const char *text)
{
u32 v;
int b;
* 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;
* 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;
* 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;
free(pxdesc);
}
}
-#endif
+#endif /* POSIXACLS */
pos = 0;
}
if (isdump && !off)
} 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;
BOOL bad;
BOOL badattrib;
BOOL err;
-#ifdef WIN32
- HANDLE htoken;
- TOKEN_PRIVILEGES tkp;
-#endif
err = FALSE;
psecurdata = (struct SECURITY_DATA*)NULL;
/* 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);
*/
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);
* Restore security descriptors from a file
*/
-BOOL restore(FILE *fd)
+static BOOL restore(FILE *fd)
{
static char attr[MAXATTRSZ];
char line[MAXFILENAME+25];
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);
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;
}
return (err);
}
-#endif /* WIN32 */
-#if POSIXACLS & SELFTESTS & !USESTUBS
+#if POSIXACLS
/*
* Merge Posix ACL rights into an u32 (self test only)
*
* 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;
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;
}
}
-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 & SELFTESTS & !USESTUBS */
+#endif /* POSIXACLS & SELFTESTS */
-#if SELFTESTS & !USESTUBS
+#ifdef SELFTESTS
/*
* Build a dummy security descriptor
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 */
...)
{
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 */
/* 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);
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);
* Check a few samples with special conditions
*/
-void check_samples()
+static void check_samples(void)
{
char *descr = (char*)NULL;
BOOL isdir = FALSE;
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
struct POSIX_ACE ace[4];
} sampletry1 =
{
- { 0645, 4, 0, 4, 0x35,
+ { 0645, 4, 0, 4, 0x35, 0,
{ POSIX_VERSION, 0, 0 }
},
{
struct POSIX_ACE ace[6];
} sampletry3 =
{
- { 0100, 6, 0, 6, 0x3f,
+ { 0100, 6, 0, 6, 0x3f, 0,
{ POSIX_VERSION, 0, 0 }
},
{
struct POSIX_ACE ace[8];
} sampletry4 =
{
- { 0140, 8, 0, 8, 0x3f,
+ { 0140, 8, 0, 8, 0x3f, 0,
{ POSIX_VERSION, 0, 0 }
},
{
struct POSIX_ACE ace[6];
} sampletry5 =
{
- { 0454, 6, 0, 6, 0x3f,
+ { 0454, 6, 0, 6, 0x3f, 0,
{ POSIX_VERSION, 0, 0 }
},
{
struct POSIX_ACE ace[8];
} sampletry6 =
{
- { 0332, 8, 0, 8, 0x3f,
+ { 0332, 8, 0, 8, 0x3f, 0,
{ POSIX_VERSION, 0, 0 }
},
{
struct POSIX_ACE ace[4];
} sampletry8 =
{
- { 0677, 4, 0, 4, 0x35,
+ { 0677, 4, 0, 4, 0x35, 0,
{ POSIX_VERSION, 0, 0 }
},
{
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);
(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 */
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),
(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;
(long)defrights,(long)expectdef);
showall(descr,0);
showposix(pxdesc);
-exit(1);
}
free(pxdesc);
}
-#endif
+#endif /* POSIXACLS */
}
free(descr);
}
* 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;
u32 pxcount;
u32 pxacecount;
u32 pxglobhash;
-#endif
+#endif /* POSIXACLS */
count = 0;
acecount = 0;
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 */
free(attr);
}
free(pxdesc);
-#else
+#else /* POSIXACLS */
gotback = linux_permissions(attr, isdir);
if (gotback != perm)
err = ERRAM;
break;
case ERRAP :
/* continued */
-#else
+#else /* POSIXACLS */
case ERRAM :
case ERRAP :
#endif /* POSIXACLS */
* 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;
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,
165888, 186624,
165888, 186624,
168480, 189216,
-#endif
0, 0,
0, 0,
0, 0,
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,
0xf9685700, 0x44d16700,
0x587ebe90, 0xf7c51480,
0x2cb1b518, 0x52408df6,
-#endif
0, 0,
0, 0,
0, 0,
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++)
pxdesc->acl.ace[5].perms = wrld;
}
- err = ERRNO;
gotback = (struct POSIX_SECURITY*)NULL;
pxattr = ntfs_build_descr_posix(context.mapping,
pxdesc,isdir,owner,group);
printf("gotback ACL\n");
showposix(gotback);
errors++;
-exit(1);
}
} else {
printf("Got back an invalid Posix ACL\n");
#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;
#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
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
-
-/*
- * Get the security descriptor of a file (Windows version)
- */
-
-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
+#endif /* SELFTESTS */
/*
- * Get the security descriptor of a file (Linux version)
+ * Get the security descriptor of a file
*/
-unsigned int getfull(char *attr, const char *fullname)
+static unsigned int getfull(char *attr, const char *fullname)
{
static char part[MAXATTRSZ];
BIGSID ownsid;
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");
} 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];
const SID *gsid;
#if OWNERFROMACL
const SID *osid;
-#endif
+#endif /* OWNERFROMACL */
printf("%s ",(isdir ? "Directory" : "File"));
printname(stdout,fullname);
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;
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;
/*
{
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;
const SID *gsid;
#if OWNERFROMACL
const SID *osid;
-#endif
+#endif /* OWNERFROMACL */
printf("%s ",(isdir ? "Directory" : "File"));
printname(stdout,fullname);
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);
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;
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;
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<ucnt; i++)
printf("-%lu",get4l(attr,uoff+8+4*i));
printf("\n");
printf(":%d:",gid);
else
printf(":group:");
- printf("S-%d-%llu",attr[goff] & 255,gauth);
+ printf("S-%d-%llu",attr[goff] & 255,(long long)gauth);
for (i=0; i<gcnt; i++)
printf("-%lu",get4l(attr,goff+8+4*i));
printf("\n");
/* generic rule, based on group */
- printf("::S-%d-%llu",attr[goff] & 255,gauth);
+ printf("::S-%d-%llu",attr[goff] & 255,(long long)gauth);
for (i=0; i<gcnt-1; i++)
printf("-%lu",get4l(attr,goff+8+4*i));
printf("-10000\n");
printf("# insert the modified lines into .NTFS-3G/UserMapping, with .NTFS-3G\n");
} else
printf("# Insert the above lines into .NTFS-3G/UserMapping, with .NTFS-3G\n");
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
printf("# being a directory of the root of the NTFS file system.\n");
/* Get the drive letter to the file system */
&& (name[1] == ':'))
driveletter = name[0];
else {
- if (GetCurrentDirectoryA(MAXFILENAME, fullname)
+ if (getcwd(fullname, MAXFILENAME)
&& (fullname[1] == ':'))
driveletter = fullname[0];
}
printf("# Example : %c:\\.NTFS-3G\\UserMapping\n",
driveletter);
}
-#else
+#else /* HAVE_WINDOWS_H */
printf("# being a hidden subdirectory of the root of the NTFS file system.\n");
/* Get the path to the root of the file system */
+/*
if (name[0] != '/') {
p = getcwd(fullname,MAXFILENAME);
if (p) {
strcpy(fullname,name);
p = fullname;
}
+*/
+ p = ntfs_realpath(name, fullname);
if (p) {
- /* go down the path to inode 5 (fails on symlinks) */
+ /* go down the path to inode 5 */
do {
lstat(fullname,&st);
q = strrchr(p,'/');
printname(stdout,p);
printf("/.NTFS-3G/UserMapping\n");
}
-#endif
+#endif /* HAVE_WINDOWS_H */
} else {
printf("** Not possible : ");
printname(stdout,name);
return (err);
}
-#ifdef WIN32
-
-/*
- * Check whether a directory with reparse data is a junction
- * or a symbolic link
- */
-
-BOOL islink(const char *filename)
-{
- WIN32_FIND_DATAW found;
- HANDLE search;
- BOOL link;
-
- link = FALSE;
- search = FindFirstFileW((LPCWSTR)filename, &found);
- if (search != INVALID_HANDLE_VALUE) {
- link = (found.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)
- || (found.dwReserved0 == IO_REPARSE_TAG_SYMLINK);
- FindClose(search);
- }
- return (link);
-}
-
-#if POSIXACLS
-BOOL iterate(RECURSE call, const char *fullname, const struct POSIX_SECURITY *pxdesc)
-#else
-BOOL iterate(RECURSE call, const char *fullname, mode_t mode)
-#endif
-{
- WIN32_FIND_DATAW found;
- HANDLE search;
- BOOL err;
- unsigned int len;
- char *filter;
- char *inner;
-
- err = FALSE;
- filter = (char*)malloc(MAXFILENAME);
- inner = (char*)malloc(MAXFILENAME);
- if (filter && inner) {
- len = utf16len(fullname);
- memcpy(filter, fullname, 2*len);
- makeutf16(&filter[2*len],"\\*.*");
- search = FindFirstFileW((LPCWSTR)filter, &found);
- if (search != INVALID_HANDLE_VALUE) {
- do {
- if (found.cFileName[0] != UNICODE('.')) {
- memcpy(inner, fullname, 2*len);
- inner[2*len] = '\\';
- inner[2*len+1] = 0;
- memcpy(&inner[2*len+2],found.cFileName,
- 2*utf16len((char*)found.cFileName)+2);
- if (opt_v)
- if (opt_b)
- printf("#\n#\n");
- else
- printf("\n\n");
- switch (call) {
- case RECSHOW :
- if (recurseshow(inner))
- err = TRUE;
- break;
-#if POSIXACLS
- case RECSETPOSIX :
- if (recurseset_posix(inner,pxdesc))
- err = TRUE;
- break;
-#else
- case RECSET :
- if (recurseset(inner,mode))
- err = TRUE;
- break;
-#endif
- default :
- err = TRUE;
- }
- }
- } while (FindNextFileW(search, &found));
- FindClose(search);
- }
- free(filter);
- free(inner);
- } else {
- printf("** Cannot process deeper : not enough memory\n");
- errors++;
- err = TRUE;
- }
- return (err);
-}
-
-
-
/*
- * Display all the parameters associated to a file (Windows version)
+ * Display all the parameters associated to a file
*/
-void showfull(const char *fullname, BOOL isdir)
+static void showfull(const char *fullname, BOOL isdir)
{
static char attr[MAXATTRSZ];
+ static char part[MAXATTRSZ];
#if POSIXACLS
struct POSIX_SECURITY *pxdesc;
-#endif
- ULONG attrsz;
+#endif /* POSIXACLS */
+ struct SECURITY_DATA *psecurdata;
+ char *newattr;
+ int securindex;
int mode;
+ int level;
+ int attrib;
+ u32 attrsz;
+ u32 partsz;
uid_t uid;
gid_t gid;
- int attrib;
- int level;
- printf("%s ",(isdir ? "Directory" : "File"));
- printname(stdout,fullname);
- printf("\n");
+ if (opt_v || (cmd == CMD_BACKUP)) {
+ printf("%s ",(isdir ? "Directory" : "File"));
+ printname(stdout, fullname);
+ printf("\n");
+ }
/* get individual parameters, as when trying to get them */
- /* all, and one (typically SACL) is missing, we get none, */
- /* and concatenate them, to be able to compute the hash code */
-
- attrsz = getfull(attr, fullname);
- if (attrsz) {
- if (opt_v || opt_b) {
- hexdump(attr,attrsz,8);
- printf("Computed hash : 0x%08lx\n",
- (unsigned long)hash((le32*)attr,attrsz));
- }
- if (opt_v && opt_b) {
- printf("# %s ",(isdir ? "Directory" : "File"));
- printname(stdout,fullname);
- printf(" hash 0x%lx\n",
- (unsigned long)hash((le32*)attr,attrsz));
- }
- attrib = GetFileAttributesW((LPCWSTR)fullname);
- if (attrib == INVALID_FILE_ATTRIBUTES) {
- printf("** Could not get file attrib\n");
- errors++;
- } else
- printf("Windows attrib : 0x%x\n",attrib);
- if (ntfs_valid_descr(attr,attrsz)) {
-#if POSIXACLS
- pxdesc = linux_permissions_posix(attr,isdir);
- if (pxdesc)
- mode = pxdesc->mode;
- else
- mode = 0;
-#else
- mode = linux_permissions(attr,isdir);
-#endif
- if (opt_v >= 2) {
- level = (opt_b ? 4 : 0);
- showheader(attr,level);
- showusid(attr,level);
- showgsid(attr,level);
- showdacl(attr,isdir,level);
- showsacl(attr,isdir,level);
- }
- uid = linux_owner(attr);
- gid = linux_group(attr);
- if (opt_b) {
- showownership(attr);
- printf("# Interpreted Unix owner %d, group %d, mode 0%03o\n",
- (int)uid,(int)gid,mode);
- } else {
- showownership(attr);
- printf("Interpreted Unix owner %d, group %d, mode 0%03o\n",
- (int)uid,(int)gid,mode);
- }
-#if POSIXACLS
- if (pxdesc) {
- if (!opt_b
- && (pxdesc->defcnt
- || (pxdesc->tagsset
- & (POSIX_ACL_USER
- | POSIX_ACL_GROUP
- | POSIX_ACL_MASK))))
- showposix(pxdesc);
- free(pxdesc);
- }
-#endif
- } else
- if (opt_b)
- printf("# Descriptor fails sanity check\n");
- else
- printf("Descriptor fails sanity check\n");
- }
-}
-
-BOOL recurseshow(const char *fullname)
-{
- int attrib;
- int err;
- BOOL isdir;
-
- err = FALSE;
- attrib = GetFileAttributesW((LPCWSTR)fullname);
- if (attrib != INVALID_FILE_ATTRIBUTES) {
- isdir = (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
- showfull(fullname,isdir);
- if (isdir
- && !((attrib & FILE_ATTRIBUTE_REPARSE_POINT)
- && islink(fullname))) {
-#if POSIXACLS
- err = iterate(RECSHOW, fullname, (struct POSIX_SECURITY*)NULL);
-#else
- err = iterate(RECSHOW, fullname, 0);
-#endif
- }
- } else {
- printf("** Could not access ");
- printname(stdout,fullname);
- printf("\n");
- printerror(stdout);
- errors++;
- err = TRUE;
- }
- return (err);
-}
-
-
-BOOL singleshow(const char *fullname)
-{
- int attrib;
- int err;
- BOOL isdir;
-
- err = FALSE;
- attrib = GetFileAttributesW((LPCWSTR)fullname);
- if (attrib != INVALID_FILE_ATTRIBUTES) {
- isdir = (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
- showfull(fullname,isdir);
- } else {
- printf("** Could not access ");
- printname(stdout,fullname);
- printf("\n");
- printerror(stdout);
- errors++;
- err = TRUE;
- }
- return (err);
-}
-
-BOOL mapproposal(const char *fullname)
-{
- char attr[256];
- ULONG attrsz;
- int attrib;
- int err;
-
- err = FALSE;
- attrsz = 0;
- attrib = GetFileAttributesW((LPCWSTR)fullname);
- if ((attrib != INVALID_FILE_ATTRIBUTES)
- && GetFileSecurityW((LPCWSTR)fullname,
- OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION,
- (char*)attr,256,&attrsz)) {
- err = proposal(fullname,attr);
- } else {
- printf("** Could not access ");
- printname(stdout,fullname);
- printf("\n");
- printerror(stdout);
- err = TRUE;
- }
- return (err);
-}
-
-#if POSIXACLS
-
-BOOL recurseset_posix(const char *fullname, const struct POSIX_SECURITY *pxdesc)
-{
- int attrib;
- int err;
- BOOL isdir;
-
- err = FALSE;
- attrib = GetFileAttributesW((LPCWSTR)fullname);
- if (attrib != INVALID_FILE_ATTRIBUTES) {
- isdir = (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
- err = !setfull_posix(fullname,pxdesc,isdir);
- if (err) {
- printf("** Failed to update ");
- printname(stdout,fullname);
- printf("\n");
- errors++;
- } else
- if (isdir
- && !((attrib & FILE_ATTRIBUTE_REPARSE_POINT)
- && islink(fullname)))
- iterate(RECSETPOSIX, fullname, pxdesc);
- } else {
- err = GetLastError();
- printf("** Could not access ");
- printname(stdout,fullname);
- printf("\n");
- printerror(stdout);
- err = TRUE;
- errors++;
- }
- return (err);
-}
-
-#else
-
-BOOL recurseset(const char *fullname, int mode)
-{
- int attrib;
- int err;
- BOOL isdir;
-
- err = FALSE;
- attrib = GetFileAttributesW((LPCWSTR)fullname);
- if (attrib != INVALID_FILE_ATTRIBUTES) {
- isdir = (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
- setfull(fullname,mode,isdir);
- if (isdir
- && !((attrib & FILE_ATTRIBUTE_REPARSE_POINT)
- && islink(fullname)))
- iterate(RECSETPOSIX, fullname, mode);
- } else {
- err = GetLastError();
- printf("** Could not access ");
- printname(stdout,fullname);
- printf("\n");
- printerror(stdout);
- err = TRUE;
- errors++;
- }
- return (err);
-}
-
-#endif
-
-#if POSIXACLS
-
-BOOL singleset_posix(const char *path, const struct POSIX_SECURITY *pxdesc)
-{
- BOOL isdir;
- BOOL err;
- int attrib;
-
- err = FALSE;
- attrib = GetFileAttributesW((LPCWSTR)path);
- if (attrib != INVALID_FILE_ATTRIBUTES) {
- isdir = (attrib & FILE_ATTRIBUTE_DIRECTORY);
- err = !setfull_posix(path,pxdesc,isdir);
- if (err) {
- printf("** Failed to update ");
- printname(stdout,path);
- printf("\n");
- errors++;
- }
- } else {
- printf("** Could not access ");
- printname(stdout,path);
- printf("\n");
- printerror(stdout);
- errors++;
- err = TRUE;
- }
- return (!err);
-}
-
-#endif
-
-BOOL singleset(const char *path, int mode)
-{
- BOOL isdir;
- BOOL err;
- int attrib;
-
- err = FALSE;
- attrib = GetFileAttributesW((LPCWSTR)path);
- if (attrib != INVALID_FILE_ATTRIBUTES) {
- isdir = (attrib & FILE_ATTRIBUTE_DIRECTORY);
- setfull(path,mode,isdir);
- } else {
- printf("** Could not access ");
- printname(stdout,path);
- printf("\n");
- printerror(stdout);
- errors++;
- err = TRUE;
- }
- return (!err);
-}
-
-#else
-
-/*
- * Display all the parameters associated to a file (Linux version)
- */
-
-void showfull(const char *fullname, BOOL isdir)
-{
- static char attr[MAXATTRSZ];
- static char part[MAXATTRSZ];
-#if POSIXACLS
- struct POSIX_SECURITY *pxdesc;
-#endif
- struct SECURITY_DATA *psecurdata;
- char *newattr;
- int securindex;
- int mode;
- int level;
- int attrib;
- u32 attrsz;
- u32 partsz;
- uid_t uid;
- gid_t gid;
-
- if (opt_v || opt_b)
- printf("%s %s\n",(isdir ? "Directory" : "File"),fullname);
-
- /* get individual parameters, as when trying to get them */
- /* all, and one (typically SACL) is missing, we get none */
- /* and concatenate them, to be able to compute the checksum */
+ /* all, and one (typically SACL) is missing, we get none */
+ /* and concatenate them, to be able to compute the checksum */
partsz = 0;
securindex = ntfs_get_file_security(ntfs_context,fullname,
if ((securindex < 0)
|| (securindex >= MAXSECURID)
|| ((securindex > 0)
- && ((!opt_r && !opt_b)
+ && ((!opt_r && (cmd != CMD_BACKUP))
|| !securdata[securindex >> SECBLKSZ]
|| !securdata[securindex >> SECBLKSZ][securindex & ((1 << SECBLKSZ) - 1)].filecount)))
{
- if (opt_v || opt_b) {
+ if (opt_v || (cmd == CMD_BACKUP)) {
if ((securindex < -1) || (securindex >= MAXSECURID))
printf("Security key : 0x%x out of range\n",securindex);
else
else
printf("Security key : 0x%x\n",securindex);
} else {
- printf("%s %s",(isdir ? "Directory" : "File"),fullname);
+ printf("%s ",(isdir ? "Directory" : "File"));
+ printname(stdout, fullname);
if ((securindex < -1) || (securindex >= MAXSECURID))
- printf(" : key 0x%x out of range\n",securindex);
+ printf(" : key 0x%x out of range\n",securindex);
else
if (securindex == -1)
printf(" : no key\n");
psecurdata = &securdata[securindex >> SECBLKSZ]
[securindex & ((1 << SECBLKSZ) - 1)];
}
- if (opt_v && (opt_a || opt_b) && psecurdata) {
+ if (((cmd == CMD_AUDIT) || (cmd == CMD_BACKUP))
+ && opt_v && psecurdata) {
newattr = (char*)malloc(attrsz);
- printf("# %s %s hash 0x%lx\n",(isdir ? "Directory" : "File"),
- fullname,
+ printf("# %s ",(isdir ? "Directory" : "File"));
+ printname(stdout, fullname);
+ printf(" hash 0x%lx\n",
(unsigned long)hash((le32*)attr,attrsz));
if (newattr) {
memcpy(newattr,attr,attrsz);
psecurdata->attr = newattr;
}
}
- if ((opt_v || opt_b)
+ if ((opt_v || (cmd == CMD_BACKUP))
&& ((securindex >= MAXSECURID)
|| (securindex <= 0)
|| !psecurdata
mode = pxdesc->mode;
else
mode = 0;
-#else
+#else /* POSIXACLS */
mode = linux_permissions(attr,isdir);
-#endif
+#endif /* POSIXACLS */
attrib = ntfs_get_file_attributes(ntfs_context,fullname);
if (opt_v >= 2) {
- level = (opt_b ? 4 : 0);
+ level = (cmd == CMD_BACKUP ? 4 : 0);
showheader(attr,level);
showusid(attr,level);
showgsid(attr,level);
printf("Windows attrib : 0x%x\n",attrib);
uid = linux_owner(attr);
gid = linux_group(attr);
- if (opt_b) {
+ if (cmd == CMD_BACKUP) {
showownership(attr);
printf("# Interpreted Unix owner %d, group %d, mode 0%03o\n",
(int)uid,(int)gid,mode);
}
#if POSIXACLS
if (pxdesc) {
- if (!opt_b
+ if ((cmd != CMD_BACKUP)
&& (pxdesc->defcnt
|| (pxdesc->tagsset
& (POSIX_ACL_USER
| POSIX_ACL_GROUP
| POSIX_ACL_MASK))))
showposix(pxdesc);
-#if USESTUBS
- stdfree(pxdesc); /* allocated within library */
-#else
free(pxdesc);
-#endif
}
-#endif
- if ((opt_r || opt_b) && (securindex < MAXSECURID)
+#endif /* POSIXACLS */
+ if ((opt_r || (cmd == CMD_BACKUP))
+ && (securindex < MAXSECURID)
&& (securindex > 0) && psecurdata) {
psecurdata->filecount++;
psecurdata->mode = mode;
psecurdata = &securdata[securindex >> SECBLKSZ]
[securindex & ((1 << SECBLKSZ) - 1)];
psecurdata->filecount++;
- if (opt_b || opt_r) {
- if (!opt_b && !opt_v)
- printf("%s %s\n",(isdir ? "Directory" : "File"),fullname);
+ if ((cmd == CMD_BACKUP) || opt_r) {
+ if ((cmd != CMD_BACKUP) && !opt_v) {
+ printf("%s ",(isdir ? "Directory" : "File"));
+ printname(stdout,fullname);
+ printf("\n");
+ }
printf("Security key : 0x%x mode %03o (already displayed)\n",
securindex,psecurdata->mode);
if (attrib != INVALID_FILE_ATTRIBUTES)
printf("Windows attrib : 0x%x\n",attrib);
} else {
- printf("%s %s",(isdir ? "Directory" : "File"),fullname);
+ printf("%s ",(isdir ? "Directory" : "File"));
+ printname(stdout,fullname);
printf(" : key 0x%x\n",securindex);
}
- if ((opt_a || opt_b) && opt_v
- && psecurdata && psecurdata->attr) {
- printf("# %s %s hash 0x%lx\n",(isdir ? "Directory" : "File"),
- fullname,
+ if (((cmd == CMD_AUDIT) || (cmd == CMD_BACKUP))
+ && opt_v
+ && psecurdata
+ && psecurdata->attr) {
+ printf("# %s ",(isdir ? "Directory" : "File"));
+ printname(stdout,fullname);
+ printf(" hash 0x%lx\n",
(unsigned long)hash((le32*)psecurdata->attr,
ntfs_attr_size(psecurdata->attr)));
}
}
} else {
- if (!opt_v && !opt_b)
- printf("%s %s",(isdir ? "Directory" : "File"),fullname);
+ if (!opt_v && (cmd != CMD_BACKUP)) {
+ printf("%s ",(isdir ? "Directory" : "File"));
+ printname(stdout, fullname);
+ }
printf(" (Failed)\n");
- printf("** Could not get security data of %s, partsz %d\n",
- fullname,partsz);
+ printf("** Could not get security data of ");
+ printname(stdout, fullname);
+ printf(", partsz %d\n", partsz);
printerror(stdout);
errors++;
}
}
-BOOL recurseshow(const char *path)
+static BOOL recurseshow(const char *path)
{
struct CALLBACK dircontext;
struct LINK *current;
if (isdir) {
showfull(path,TRUE);
if (opt_v) {
- if (opt_b)
+ if (cmd == CMD_BACKUP)
printf("#\n#\n");
else
printf("\n\n");
if (errno == ENOTDIR) {
showfull(path,FALSE);
if (opt_v) {
- if (opt_b)
+ if (cmd == CMD_BACKUP)
printf("#\n#\n");
else
printf("\n\n");
}
-BOOL singleshow(const char *path)
+static BOOL singleshow(const char *path)
{
BOOL isdir;
BOOL err;
return (err);
}
+#ifndef HAVE_WINDOWS_H
+
#ifdef HAVE_SETXATTR
static ssize_t ntfs_getxattr(const char *path, const char *name, void *value, size_t size)
{
#if defined(__APPLE__) || defined(__DARWIN__)
return getxattr(path, name, value, size, 0, 0);
-#else
+#else /* defined(__APPLE__) || defined(__DARWIN__) */
return getxattr(path, name, value, size);
-#endif
+#endif /* defined(__APPLE__) || defined(__DARWIN__) */
}
/*
* Display all the parameters associated to a mounted file
+ *
+ * (Unix only)
*/
-BOOL showmounted(const char *fullname)
+static BOOL showmounted(const char *fullname)
{
static char attr[MAXATTRSZ];
struct stat st;
#if POSIXACLS
struct POSIX_SECURITY *pxdesc;
-#endif
+#endif /* POSIXACLS */
BOOL mapped;
int attrsz;
int mode;
printf("No user mapping : "
"cannot display the Posix ACL\n");
}
-#else
+#else /* POSIXACLS */
mode = linux_permissions(attr,isdir);
-#endif
+#endif /* POSIXACLS */
if (opt_v >= 2) {
- level = (opt_b ? 4 : 0);
+ level = (cmd == CMD_BACKUP ? 4 : 0);
showheader(attr,level);
showusid(attr,level);
showgsid(attr,level);
| POSIX_ACL_GROUP
| POSIX_ACL_MASK))))
showposix(pxdesc);
-#if USESTUBS
- stdfree(pxdesc); /* allocated within library */
-#else
free(pxdesc);
-#endif
}
if (mapped)
ntfs_free_mapping(context.mapping);
-#endif
+#endif /* POSIXACLS */
} else {
printf("Descriptor fails sanity check\n");
errors++;
return (err);
}
-BOOL processmounted(const char *fullname)
+static BOOL processmounted(const char *fullname)
{
static char attr[MAXATTRSZ];
BOOL err;
err = FALSE;
- if (!opt_u)
+ if (cmd != CMD_USERMAP)
err = showmounted(fullname);
else
if (!stat(fullname,&st)) {
#else /* HAVE_SETXATTR */
-BOOL processmounted(const char *fullname __attribute__((unused)))
+static BOOL processmounted(const char *fullname __attribute__((unused)))
{
fprintf(stderr,"Not possible on this configuration,\n");
fprintf(stderr,"you have to use an unmounted partition\n");
#endif /* HAVE_SETXATTR */
+#endif /* HAVE_WINDOWS_H */
+
#if POSIXACLS
-BOOL recurseset_posix(const char *path, const struct POSIX_SECURITY *pxdesc)
+static BOOL recurseset_posix(const char *path, const struct POSIX_SECURITY *pxdesc)
{
struct CALLBACK dircontext;
struct LINK *current;
printerror(stdout);
errors++;
} else {
- if (opt_b)
+ if (cmd == CMD_BACKUP)
printf("#\n#\n");
else
printf("\n\n");
return (!err);
}
-#else
+#else /* POSIXACLS */
-BOOL recurseset(const char *path, int mode)
+static BOOL recurseset(const char *path, int mode)
{
struct CALLBACK dircontext;
struct LINK *current;
callback, &dircontext);
if (isdir) {
setfull(path,mode,TRUE);
- if (opt_b)
+ if (cmd == CMD_BACKUP)
printf("#\n#\n");
else
printf("\n\n");
return (!err);
}
-#endif
+#endif /* POSIXACLS */
#if POSIXACLS
-BOOL singleset_posix(const char *path, const struct POSIX_SECURITY *pxdesc)
+static BOOL singleset_posix(const char *path, const struct POSIX_SECURITY *pxdesc)
{
BOOL isdir;
BOOL err;
return (!err);
}
-#endif
+#else /* POSIXACLS */
-BOOL singleset(const char *path, int mode)
+static BOOL singleset(const char *path, int mode)
{
BOOL isdir;
BOOL err;
return (!err);
}
-int callback(struct CALLBACK *dircontext, char *ntfsname,
- int length, int type,
- long long pos __attribute__((unused)), u64 mft_ref __attribute__((unused)),
- unsigned int dt_type __attribute__((unused)))
+#endif /* POSIXACLS */
+
+static int callback(void *ctx, const ntfschar *ntfsname,
+ const int length, const int type,
+ const s64 pos __attribute__((unused)),
+ const MFT_REF mft_ref __attribute__((unused)),
+ const unsigned int dt_type __attribute__((unused)))
{
struct LINK *linkage;
+ struct CALLBACK *dircontext;
char *name;
int newlth;
int size;
+ dircontext = (struct CALLBACK*)ctx;
size = utf8size(ntfsname,length);
if (dircontext
&& (type != 2) /* 2 : dos name (8+3) */
&& (size > 0) /* chars convertible to utf8 */
&& ((length > 2)
- || (ntfsname[0] != '.')
- || (ntfsname[1] != '\0')
- || ((ntfsname[2] || ntfsname[3])
- && ((ntfsname[2] != '.') || (ntfsname[3] != '\0'))))) {
- linkage = (struct LINK*)malloc(sizeof(struct LINK)
+ || (ntfsname[0] != const_cpu_to_le16('.'))
+ || ((length > 1)
+ && (ntfsname[1] != const_cpu_to_le16('.'))))) {
+ linkage = (struct LINK*)malloc(sizeof(struct LINK)
+ strlen(dircontext->dir)
+ size + 2);
if (linkage) {
return (0);
}
-#endif
-
-#ifdef WIN32
-
-/*
- * Backup security descriptors in a directory tree (Windows mode)
- */
-
-BOOL backup(const char *root)
-{
- BOOL err;
- time_t now;
- const char *txtime;
-
- now = time((time_t*)NULL);
- txtime = ctime(&now);
- printf("#\n# Recursive ACL collection on %s#\n",txtime);
- err = recurseshow(root);
- return (err);
-}
-
-#else
-
/*
- * Backup security descriptors in a directory tree (Linux mode)
+ * Backup security descriptors in a directory tree
*/
-BOOL backup(const char *volume, const char *root)
+static BOOL backup(const char *volume, const char *root)
{
BOOL err;
int count;
return (err);
}
-#endif
-
-#ifdef WIN32
-
/*
- * List security descriptors in a directory tree (Windows mode)
+ * List security descriptors in a directory tree
*/
-BOOL listfiles(const char *root)
-{
- BOOL err;
-
- if (opt_r) {
- printf("\nRecursive file check\n");
- err = recurseshow(root);
- } else
- err = singleshow(root);
- return (err);
-}
-
-#else
-
-/*
- * List security descriptors in a directory tree (Linux mode)
- */
-
-BOOL listfiles(const char *volume, const char *root)
+static BOOL listfiles(const char *volume, const char *root)
{
BOOL err;
int i,j;
err = singleshow(root);
close_volume(volume);
} else {
- fprintf(stderr,"Could not open volume %s\n",volume);
- printerror(stdout);
err = TRUE;
}
close_security_api();
return (err);
}
-BOOL mapproposal(const char *volume, const char *name)
+#ifdef HAVE_WINDOWS_H
+
+static BOOL mapproposal(const char *volume, const char *name)
{
BOOL err;
u32 attrsz;
int securindex;
- char attr[256]; /* header (20) and a couple of SIDs (max 40 each) */
+ char attr[256]; /* header (20) and a couple of SIDs (max 68 each) */
err = FALSE;
if (!getuid() && open_security_api()) {
if (securindex)
err = proposal(name,attr);
else {
- fprintf(stderr,"*** Could not get the ACL of %s\n",
- name);
- printerror(stdout);
+ fprintf(stderr,"*** Could not get the ACL of ");
+ printname(stderr, name);
+ fprintf(stderr,"\n");
+ printerror(stderr);
errors++;
}
close_volume(volume);
#endif
-#ifndef WIN32
-
/*
* Check whether a SDS entry is valid
*/
-BOOL valid_sds(const char *attr, unsigned int offset,
+static BOOL valid_sds(const char *attr, unsigned int offset,
unsigned int entrysz, unsigned int size, u32 prevkey,
BOOL second)
{
* and store current data for subsequent checks
*/
-int consist_sds(const char *attr, unsigned int offset,
+static int consist_sds(const char *attr, unsigned int offset,
unsigned int entrysz, BOOL second)
{
int errcnt;
/*
- * Auditing of $SDS (Linux only)
+ * Auditing of $SDS
*/
-int audit_sds(BOOL second)
+static int audit_sds(BOOL second)
{
static char attr[MAXATTRSZ + 20];
BOOL isdir;
* Check whether a SII entry is sane
*/
-BOOL valid_sii(const char *entry, u32 prevkey)
+static BOOL valid_sii(const char *entry, u32 prevkey)
{
BOOL valid;
u32 key;
* Check whether a SII entry is consistent with other known data
*/
-int consist_sii(const char *entry)
+static int consist_sii(const char *entry)
{
int errcnt;
u32 key;
/*
- * Auditing of $SII (Linux only)
+ * Auditing of $SII
*/
-int audit_sii()
+static int audit_sii(void)
{
char *entry;
int errcnt;
prevkey = 0;
done = FALSE;
do {
- entry = (char*)ntfs_read_sii(ntfs_context,(void*)entry);
+ entry = (char*)ntfs_read_sii(ntfs_context,(INDEX_ENTRY*)entry);
if (entry) {
valid = valid_sii(entry,prevkey);
if (valid) {
* Check whether a SII entry is sane
*/
-BOOL valid_sdh(const char *entry, u32 prevkey, u32 prevhash)
+static BOOL valid_sdh(const char *entry, u32 prevkey, u32 prevhash)
{
BOOL valid;
u32 key;
* Check whether a SDH entry is consistent with other known data
*/
-int consist_sdh(const char *entry)
+static int consist_sdh(const char *entry)
{
int errcnt;
u32 key;
}
/*
- * Auditing of $SDH (Linux only)
+ * Auditing of $SDH
*/
-int audit_sdh()
+static int audit_sdh(void)
{
char *entry;
int errcnt;
entry = (char*)NULL;
done = FALSE;
do {
- entry = (char*)ntfs_read_sdh(ntfs_context,(void*)entry);
+ entry = (char*)ntfs_read_sdh(ntfs_context,(INDEX_ENTRY*)entry);
if (entry) {
valid = valid_sdh(entry,prevkey,prevhash);
if (valid) {
* Audit summary
*/
-void audit_summary()
+static void audit_summary(void)
{
int count;
int flags;
}
/*
- * Auditing (Linux only)
+ * Auditing
*/
-BOOL audit(const char *volume)
+static BOOL audit(const char *volume)
{
BOOL err;
return (err);
}
-#endif
-
#if POSIXACLS
/*
* [d:]{ugmo}:uid[:perms],...
*/
-struct POSIX_SECURITY *encode_posix_acl(const char *str)
+static struct POSIX_SECURITY *encode_posix_acl(const char *str)
{
int acccnt;
int defcnt;
}
/* compute the mode and tagsset */
tagsset = 0;
- for (i=0; i<acccnt; i++)
+ for (i=0; i<acccnt; i++) {
tagsset |= acl->ace[i].tag;
switch (acl->ace[i].tag) {
case POSIX_ACL_USER_OBJ :
mode |= acl->ace[i].perms << 6;
break;
case POSIX_ACL_GROUP_OBJ :
- mode |= acl->ace[i].perms << 3;
+ /* unless mask seen first */
+ if (!(tagsset & POSIX_ACL_MASK))
+ mode |= acl->ace[i].perms << 3;
break;
case POSIX_ACL_OTHER :
mode |= acl->ace[i].perms;
break;
+ case POSIX_ACL_MASK :
+ /* overrides group */
+ mode = (mode & 07707)
+ | (acl->ace[i].perms << 3);
+ break;
default :
break;
}
+ }
pxdesc->mode = mode;
pxdesc->tagsset = tagsset;
pxdesc->acl.version = POSIX_VERSION;
#endif /* POSIXACLS */
-
-int getoptions(int argc, char *argv[])
+static BOOL setperms(const char *volume, const char *perms, const char *base)
{
- int xarg;
- int narg;
- const char *parg;
- BOOL err;
+ const char *p;
+ BOOL cmderr;
+ int i;
+#if POSIXACLS
+ struct POSIX_SECURITY *pxdesc;
+#else /* POSIXACLS */
+ int mode;
+#endif /* POSIXACLS */
- opt_a = FALSE;
- opt_b = FALSE;
- opt_e = FALSE;
- opt_h = FALSE;
-#if FORCEMASK
- opt_m = FALSE;
-#endif
- opt_r = FALSE;
- opt_s = FALSE;
-#if SELFTESTS & !USESTUBS
- opt_t = FALSE;
-#endif
- opt_u = FALSE;
- opt_v = 0;
- xarg = 1;
- err = FALSE;
- while ((xarg < argc) && (argv[xarg][0] == '-')) {
- parg = argv[xarg++];
- while (*++parg)
- switch (*parg)
- {
-#ifndef WIN32
- case 'a' :
- opt_a = TRUE;
- break;
-#endif
- case 'b' :
- opt_b = TRUE;
- break;
- case 'e' :
- opt_e = TRUE;
- break;
- case 'h' :
- opt_h = TRUE;
- break;
-#if FORCEMASK
- case 'm' :
- opt_m = TRUE;
- break;
-#endif
- case 'r' :
- case 'R' :
- opt_r = TRUE;
- break;
- case 's' :
- opt_s = TRUE;
- break;
-#if SELFTESTS & !USESTUBS
- case 't' :
- opt_t = TRUE;
- break;
-#endif
- case 'u' :
- opt_u = TRUE;
- break;
- case 'v' :
- opt_v++;
- break;
- default :
- fprintf(stderr,"Invalid option -%c\n",*parg);
- err = TRUE;
+ cmderr = FALSE;
+ p = perms;
+#if POSIXACLS
+ pxdesc = encode_posix_acl(p);
+ if (pxdesc) {
+ if (!getuid() && open_security_api()) {
+ if (open_volume(volume,NTFS_MNT_NONE)) {
+ if (opt_r) {
+ for (i=0; i<(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ); i++)
+ securdata[i] = (struct SECURITY_DATA*)NULL;
+ recurseset_posix(base,pxdesc);
+ } else
+ singleset_posix(base,pxdesc);
+ close_volume(volume);
+ } else {
+ fprintf(stderr,"Could not open volume %s\n",volume);
+ printerror(stderr);
+ cmderr = TRUE;
+ }
+ close_security_api();
+ } else {
+ if (getuid())
+ fprintf(stderr,"This is only possible as root\n");
+ else
+ fprintf(stderr,"Could not open security API\n");
+ cmderr = TRUE;
+ }
+ free(pxdesc);
+ } else
+ cmderr = TRUE;
+#else /* POSIXACLS */
+ mode = 0;
+ while ((*p >= '0') && (*p <= '7'))
+ mode = (mode << 3) + (*p++) - '0';
+ if (*p) {
+ fprintf(stderr,"New mode should be given in octal\n");
+ cmderr = TRUE;
+ } else {
+ if (!getuid() && open_security_api()) {
+ if (open_volume(volume,NTFS_MNT_NONE)) {
+ if (opt_r) {
+ for (i=0; i<(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ); i++)
+ securdata[i] = (struct SECURITY_DATA*)NULL;
+ recurseset(base,mode);
+ } else
+ singleset(base,mode);
+ close_volume(volume);
+ } else {
+ fprintf(stderr,"Could not open volume %s\n",volume);
+ printerror(stderr);
+ cmderr = TRUE;
}
+ close_security_api();
+ } else {
+ if (getuid())
+ fprintf(stderr,"This is only possible as root\n");
+ else
+ fprintf(stderr,"Could not open security API\n");
+ cmderr = TRUE;
+ }
}
- narg = argc - xarg;
-#ifdef WIN32
- if ( ((opt_h || opt_s) && (narg > 1))
- || ((opt_r || opt_b || opt_u) && ((narg < 1) || (narg > 2)))
-#if SELFTESTS & !USESTUBS
- || (opt_t && (narg > 0))
-#endif
- || (opt_e && !opt_s)
- || (!opt_h && !opt_r && !opt_b && !opt_s
-#if SELFTESTS & !USESTUBS
- && !opt_t
-#endif
- && ((narg < 1) || (narg > 2))))
+#endif /* POSIXACLS */
+ return (cmderr);
+}
- err = TRUE;
- if (err) {
- xarg = 0;
- fprintf(stderr,"Usage:\n");
-#if SELFTESTS & !USESTUBS
- fprintf(stderr," secaudit -t\n");
- fprintf(stderr," run self-tests\n");
-#endif
- fprintf(stderr," secaudit -h [file]\n");
- fprintf(stderr," display security descriptors within file\n");
- fprintf(stderr," secaudit [-v] file\n");
- fprintf(stderr," display the security parameters of file\n");
- fprintf(stderr," secaudit -r[v] directory\n");
- fprintf(stderr," display the security parameters of files in directory\n");
- fprintf(stderr," secaudit -b[v] directory\n");
- fprintf(stderr," backup the security parameters of files in directory\n");
- fprintf(stderr," secaudit -s[ev] [backupfile]\n");
- fprintf(stderr," set the security parameters as indicated in backup file\n");
- fprintf(stderr," with -e also set extra parameters (Windows attrib)\n");
- fprintf(stderr," secaudit perms file\n");
- fprintf(stderr," set the security parameters of file to perms\n");
- fprintf(stderr," secaudit -r[v] perms directory\n");
- fprintf(stderr," set the security parameters of files in directory to perms\n");
- fprintf(stderr," secaudit -u file\n");
- fprintf(stderr," get a user mapping proposal applicable to file\n");
+static void usage(void)
+{
+#ifdef HAVE_WINDOWS_H
+ fprintf(stderr,"Usage:\n");
+#ifdef SELFTESTS
+ fprintf(stderr," secaudit -t\n");
+ fprintf(stderr," run self-tests\n");
+#endif /* SELFTESTS */
+ fprintf(stderr," secaudit -h [file]\n");
+ fprintf(stderr," display security descriptors within file\n");
+ fprintf(stderr," secaudit -a[rv] volume\n");
+ fprintf(stderr," audit the volume\n");
+ fprintf(stderr," secaudit [-v] file\n");
+ fprintf(stderr," display the security parameters of file\n");
+ fprintf(stderr," secaudit -r[v] directory\n");
+ fprintf(stderr," display the security parameters of files in directory\n");
+ fprintf(stderr," secaudit -b[v] directory\n");
+ fprintf(stderr," backup the security parameters of files in directory\n");
+ fprintf(stderr," secaudit -s[ev] volume [backupfile]\n");
+ fprintf(stderr," set the security parameters as indicated in backup file\n");
+ fprintf(stderr," with -e also set extra parameters (Windows attrib)\n");
+ fprintf(stderr," secaudit perms file\n");
+ fprintf(stderr," set the security parameters of file to perms\n");
+ fprintf(stderr," secaudit -r[v] perms directory\n");
+ fprintf(stderr," set the security parameters of files in directory to perms\n");
+ fprintf(stderr," secaudit -u file\n");
+ fprintf(stderr," get a user mapping proposal applicable to file\n");
#if POSIXACLS
- fprintf(stderr," Note: perms can be an octal mode or a Posix ACL description\n");
-#else
- fprintf(stderr," Note: perms is an octal mode\n");
-#endif
- fprintf(stderr," -v is for verbose, -vv for very verbose\n");
- }
-#else
- if ( (opt_h && (narg > 1))
- || (opt_a && (narg != 1))
- || ((opt_r || opt_b || opt_s || opt_u)
- && ((narg < 1) || (narg > 3)))
-#if SELFTESTS & !USESTUBS
- || (opt_t && (narg > 0))
-#endif
- || (opt_e && !opt_s)
- || (!opt_h && !opt_a && !opt_r && !opt_b && !opt_s && !opt_u
-#if SELFTESTS & !USESTUBS
- && !opt_t
-#endif
-#ifdef HAVE_SETXATTR
- && ((narg < 1) || (narg > 3))))
-#else
- && ((narg < 2) || (narg > 3))))
-#endif
- err = TRUE;
- if (err) {
- xarg = 0;
- fprintf(stderr,"Usage:\n");
-#if SELFTESTS & !USESTUBS
- fprintf(stderr," secaudit -t\n");
- fprintf(stderr," run self-tests\n");
-#endif
- fprintf(stderr," secaudit -h [file]\n");
- fprintf(stderr," display security descriptors within file\n");
- fprintf(stderr," secaudit -a[rv] volume\n");
- fprintf(stderr," audit the volume\n");
- fprintf(stderr," secaudit [-v] volume file\n");
- fprintf(stderr," display the security parameters of file\n");
- fprintf(stderr," secaudit -r[v] volume directory\n");
- fprintf(stderr," display the security parameters of files in directory\n");
- fprintf(stderr," secaudit -b[v] volume directory\n");
- fprintf(stderr," backup the security parameters of files in directory\n");
- fprintf(stderr," secaudit -s[ev] volume [backupfile]\n");
- fprintf(stderr," set the security parameters as indicated in backup file\n");
- fprintf(stderr," with -e also set extra parameters (Windows attrib)\n");
- fprintf(stderr," secaudit volume perms file\n");
- fprintf(stderr," set the security parameters of file to perms\n");
- fprintf(stderr," secaudit -r[v] volume perms directory\n");
- fprintf(stderr," set the security parameters of files in directory to perms\n");
- fprintf(stderr," secaudit -u volume file\n");
- fprintf(stderr," get a user mapping proposal applicable to file\n");
+ fprintf(stderr," Notes: perms can be an octal mode or a Posix ACL description\n");
+#else /* POSIXACLS */
+ fprintf(stderr," Notes: perms is an octal mode\n");
+#endif /* POSIXACLS */
+ fprintf(stderr," volume is a drive letter and colon (eg. D:)\n");
+ fprintf(stderr," -v is for verbose, -vv for very verbose\n");
+#else /* HAVE_WINDOWS_H */
+ fprintf(stderr,"Usage:\n");
+#ifdef SELFTESTS
+ fprintf(stderr," secaudit -t\n");
+ fprintf(stderr," run self-tests\n");
+#endif /* SELFTESTS */
+ fprintf(stderr," secaudit -h [file]\n");
+ fprintf(stderr," display security descriptors within file\n");
+ fprintf(stderr," secaudit -a[rv] volume\n");
+ fprintf(stderr," audit the volume\n");
+ fprintf(stderr," secaudit [-v] volume file\n");
+ fprintf(stderr," display the security parameters of file\n");
+ fprintf(stderr," secaudit -r[v] volume directory\n");
+ fprintf(stderr," display the security parameters of files in directory\n");
+ fprintf(stderr," secaudit -b[v] volume directory\n");
+ fprintf(stderr," backup the security parameters of files in directory\n");
+ fprintf(stderr," secaudit -s[ev] volume [backupfile]\n");
+ fprintf(stderr," set the security parameters as indicated in backup file\n");
+ fprintf(stderr," with -e also set extra parameters (Windows attrib)\n");
+ fprintf(stderr," secaudit volume perms file\n");
+ fprintf(stderr," set the security parameters of file to perms\n");
+ fprintf(stderr," secaudit -r[v] volume perms directory\n");
+ fprintf(stderr," set the security parameters of files in directory to perms\n");
#ifdef HAVE_SETXATTR
- fprintf(stderr," special cases, do not require being root :\n");
- fprintf(stderr," secaudit -u mounted-file\n");
- fprintf(stderr," get a user mapping proposal applicable to mounted file\n");
- fprintf(stderr," secaudit [-v] mounted-file\n");
- fprintf(stderr," display the security parameters of a mounted file\n");
-#endif
+ fprintf(stderr," special cases, do not require being root :\n");
+ fprintf(stderr," secaudit -u mounted-file\n");
+ fprintf(stderr," get a user mapping proposal applicable to mounted file\n");
+ fprintf(stderr," secaudit [-v] mounted-file\n");
+ fprintf(stderr," display the security parameters of a mounted file\n");
+#endif /* HAVE_SETXATTR */
#if POSIXACLS
- fprintf(stderr," Note: perms can be an octal mode or a Posix ACL description\n");
-#else
- fprintf(stderr," Note: perms is an octal mode\n");
-#endif
- fprintf(stderr," -v is for verbose, -vv for very verbose\n");
- }
-#endif
- if ((sizeof(SID) != 12) && !err) {
- fprintf(stderr,"Possible alignment problem, check your compiler options\n");
- err = TRUE;
- xarg = 0;
- }
- return (xarg);
+ fprintf(stderr," Notes: perms can be an octal mode or a Posix ACL description\n");
+#else /* POSIXACLS */
+ fprintf(stderr," Notes: perms is an octal mode\n");
+#endif /* POSIXACLS */
+#if defined(__sun) && defined (__SVR4)
+ fprintf(stderr," volume is a partition designator (eg. /dev/dsk/c5t0d0p1)\n");
+#else /* defined(__sun) && defined (__SVR4) */
+ fprintf(stderr," volume is a partition designator (eg. /dev/sdb2)\n");
+#endif /* defined(__sun) && defined (__SVR4) */
+ fprintf(stderr," -v is for verbose, -vv for very verbose\n");
+#endif /* HAVE_WINDOWS_H */
}
-/*
- * Memory allocation with checks
- */
-
-#undef malloc
-#undef calloc
-#undef free
-#undef isalloc
-
-void dumpalloc(const char *txt)
+static void version(void)
{
- struct CHKALLOC *q;
-
- if (firstalloc) {
- printf("alloc table at %s\n",txt);
- for (q=firstalloc; q; q=q->next)
-#ifdef __x86_64__
- printf("%08llx : %u bytes at %08llx allocated at %s line %d\n",
- (long long)q,(unsigned int)q->size,
- (long long)q->alloc,q->file,q->line);
-#else
- printf("%08lx : %u bytes at %08lx allocated at %s line %d\n",
- (long)q,(unsigned int)q->size,
- (long)q->alloc,q->file,q->line);
-#endif
- }
-}
+ static const char *EXEC_NAME = "ntfssecaudit";
-void *chkmalloc(size_t size, const char *file, int line)
-{
- void *p;
- struct CHKALLOC *q;
-
- p = (void*)malloc(size+1);
- if (p) {
- ((unsigned char*)p)[size] = 0xaa;
- q = (struct CHKALLOC*)malloc(sizeof(struct CHKALLOC));
- if (q) {
- q->next = firstalloc;
- q->alloc = p;
- q->size = size;
- q->file = file;
- q->line = line;
- firstalloc = q;
- }
- }
- return (p);
+// confusing (see banner)
+ printf("\n%s v%s (libntfs-3g) - Audit security data on a NTFS "
+ "Volume.\n\n", EXEC_NAME, VERSION);
+ printf(" Copyright (c) 2007-2016 Jean-Pierre Andre\n");
+ printf("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home);
}
-void *chkcalloc(size_t cnt, size_t size, const char *file, int line)
-{
- return (chkmalloc(cnt*size,file,line));
-}
+#ifdef HAVE_WINDOWS_H
+
+/*
+ * Split a Windows file designator into volume and fullpath
+ */
-void chkfree(void *p, const char *file, int line)
+static BOOL splitarg(char **split, const char *arg)
{
- struct CHKALLOC *q;
- struct CHKALLOC *r;
+ char curdir[MAXFILENAME];
+ BOOL err;
+ BOOL withvol;
+ BOOL withfullpath;
+ int lthd;
+ char *volume;
+ char *filename;
- if (p) {
- if (firstalloc && (firstalloc->alloc == p)) {
- r = firstalloc;
- firstalloc = firstalloc->next;
- } else {
- q = firstalloc;
- if (q)
- while (q->next && (q->next->alloc != p))
- q = q->next;
- if (q && q->next) {
- r = q->next;
- q->next = r->next;
- } else {
- r = (struct CHKALLOC*)NULL;
- printf("** freeing unallocated memory in %s line %d\n",file,line);
- if (!isatty(1))
- fprintf(stderr,"** freeing unallocated memory in %s line %d\n",file,line);
- }
+ err = TRUE;
+ withvol = arg[0] && (arg[1] == ':');
+ if (withvol)
+ withfullpath = (arg[2] == '/') || (arg[2] == '\\');
+ else
+ withfullpath = (arg[0] == '/') || (arg[0] == '\\');
+ lthd = 0;
+ if (!withvol || !withfullpath) {
+ if (getcwd(curdir, sizeof(curdir)))
+ lthd = strlen(curdir);
+ }
+ if (withvol && !withfullpath && arg[2]
+ && ((arg[0] ^ curdir[0]) & 0x3f)) {
+ fprintf(stderr,"%c: is not the current drive,\n",arg[0]);
+ fprintf(stderr,"please use the full path\n");
+ } else {
+ if (withvol && !withfullpath && !arg[2]
+ && ((arg[0] ^ curdir[0]) & 0x3f)) {
+ curdir[2] = '\\';
+ curdir[3] = 0;
+ lthd = 3;
}
- if (r) {
- if (((unsigned char*)p)[r->size] != 0xaa) {
- printf("** memory corruption, alloc in %s line %d release in %s %d\n",
- r->file,r->line,file,line);
- if (!isatty(1))
- fprintf(stderr,"** memory corruption, alloc in %s line %d release in %s %d\n",
- r->file,r->line,file,line);
- }
- memset(p,0xaa,r->size);
- free(r);
- free(p);
+ volume = (char*)malloc(4);
+ if (volume) {
+ if (withvol)
+ volume[0] = arg[0];
+ else
+ volume[0] = curdir[0];
+ volume[1] = ':';
+ volume[2] = 0;
+ filename = (char*)malloc(strlen(arg) + lthd + 2);
+ if (filename) {
+ if (withfullpath) {
+ if (withvol)
+ strcpy(filename, &arg[2]);
+ else
+ strcpy(filename, arg);
+ } else {
+ strcpy(filename, &curdir[2]);
+ if (curdir[lthd - 1] != '\\')
+ strcat(filename, "\\");
+ if (withvol)
+ strcat(filename, &arg[2]);
+ else
+ strcat(filename, arg);
+ }
+ if (!cleanpath(filename)) {
+ split[0] = volume;
+ split[1] = filename;
+ err = FALSE;
+ } else {
+ fprintf(stderr,"Bad path %s\n", arg);
+ }
+ } else
+ free(volume);
}
}
+ return (err);
}
-void *stdmalloc(size_t size)
-{
- return (malloc(size));
-}
+#endif /* HAVE_WINDOWS_H */
-void stdfree(void *p)
-{
- free(p);
-}
+/*
+ * Parse the command-line options
+ */
-BOOL chkisalloc(void *p, const char *file, int line)
+static int parse_options(int argc, char *argv[])
{
- struct CHKALLOC *q;
+ static const char *sopt = "-abehHrstuvV";
+ static const struct option lopt[] = {
+ { "audit", no_argument, NULL, 'a' },
+ { "backup", no_argument, NULL, 'b' },
+ { "extra", no_argument, NULL, 'e' },
+ { "help", no_argument, NULL, 'H' },
+ { "hexdecode", no_argument, NULL, 'h' },
+ { "recurse", no_argument, NULL, 'r' },
+ { "set", no_argument, NULL, 's' },
+ { "test", no_argument, NULL, 't' },
+ { "user-mapping",no_argument, NULL, 'u' },
+ { "verbose", no_argument, NULL, 'v' },
+ { "version", no_argument, NULL, 'V' },
+ { NULL, 0, NULL, 0 }
+ };
- if (p) {
- q = firstalloc;
- while (q && (q->alloc != p))
- q = q->next;
- } else
- q = (struct CHKALLOC*)NULL;
- if (!p || !q) {
-#ifdef __x86_64__
- printf("error in %s %d : 0x%llx not allocated\n",file,line,
- (long long)p);
-#else
- printf("error in %s %d : 0x%lx not allocated\n",file,line,
- (long)p);
-#endif
- }
- return (p && q);
-}
+ int c = -1;
+ int err = 0;
+ int ver = 0;
+ int help = 0;
+ int xarg = 0;
+ CMDS prevcmd;
+ opterr = 0; /* We'll handle the errors, thank you. */
+ opt_e = FALSE;
+ opt_r = FALSE;
+ opt_v = 0;
+ cmd = CMD_NONE;
+ prevcmd = CMD_NONE;
+
+ while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
+ switch (c) {
+ case 1:
+ if (!xarg)
+ xarg = optind - 1;
+ break;
+ case 'a':
+ prevcmd = cmd;
+ cmd = CMD_AUDIT;
+ break;
+ case 'b':
+ prevcmd = cmd;
+ cmd = CMD_BACKUP;
+ break;
+ case 'e':
+ opt_e = TRUE;
+ break;
+ case 'h':
+ prevcmd = cmd;
+ cmd = CMD_HEX;
+ break;
+ case 'H':
+ help++;
+ break;
+ case 'r':
+ opt_r = TRUE;
+ break;
+ case 's':
+ prevcmd = cmd;
+ cmd = CMD_SET;
+ break;
+#ifdef SELFTESTS
+ case 't':
+ prevcmd = cmd;
+ cmd = CMD_TEST;
+ break;
+#endif
+ case 'u':
+ prevcmd = cmd;
+ cmd = CMD_USERMAP;
+ break;
+ case 'v':
+ opt_v++;
+ break;
+ case 'V':
+ ver++;
+ break;
+ default:
+ if ((c < 'a') || (c > 'z'))
+ fprintf(stderr,"Unhandled option case: %d.\n", c);
+ else
+ fprintf(stderr,"Invalid option -%c\n",c);
+ err++;
+ break;
+ }
+ if ((cmd != CMD_NONE)
+ && (prevcmd != CMD_NONE)
+ && (prevcmd != cmd)) {
+ fprintf(stderr,"Incompatible commands\n");
+ err++;
+ }
+ }
+ if (!xarg)
+ xarg = argc;
-#ifdef WIN32
+ if (help || err)
+ cmd = CMD_HELP;
+ else
+ if (ver)
+ cmd = CMD_VERSION;
-/*
- * Windows version
- */
+ return (err ? 0 : xarg);
+}
-main(argc,argv)
-int argc;
-char *argv[];
+int main(int argc, char *argv[])
{
+ char *split[2];
+ char *uname;
FILE *fd;
int xarg;
- int mode;
- unsigned int size;
BOOL cmderr;
- char *filename;
- const char *p;
+ BOOL fail;
int i;
-#if POSIXACLS
- struct POSIX_SECURITY *pxdesc;
-#endif
printf("%s\n",BANNER);
cmderr = FALSE;
+ fail = FALSE;
errors = 0;
warnings = 0;
- xarg = getoptions(argc,argv);
+ split[0] = split[1] = (char*)NULL;
+ uname = (char*)NULL;
+ xarg = parse_options(argc,argv);
if (xarg) {
for (i=0; i<(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ); i++)
securdata[i] = (struct SECURITY_DATA*)NULL;
#if POSIXACLS
context.mapping[MAPUSERS] = (struct MAPPING*)NULL;
context.mapping[MAPGROUPS] = (struct MAPPING*)NULL;
-#endif
- firstalloc = (struct CHKALLOC*)NULL;
+#endif /* POSIXACLS */
mappingtype = MAPNONE;
- switch (argc - xarg) {
- case 0 :
- if (opt_h)
- showhex(stdin);
+
+ switch (cmd) {
+ case CMD_AUDIT :
+ if (xarg == (argc - 1))
+ fail = audit(argv[xarg]);
else
- if (opt_s)
- restore(stdin);
-#if SELFTESTS & !USESTUBS
- if (opt_t)
- selftests();
+ cmderr = TRUE;
+ break;
+ case CMD_BACKUP :
+ switch (argc - xarg) {
+ case 1 :
+#ifdef HAVE_WINDOWS_H
+ if (!splitarg(split, argv[xarg]))
+ fail = backup(split[0], split[1]);
+ else
+ cmderr = TRUE;
+#else
+ fail = backup(argv[xarg],"/");
#endif
+ break;
+ case 2 :
+ cmderr = backup(argv[xarg],argv[xarg+1]);
+ break;
+ default :
+ cmderr = TRUE;
+ break;
+ }
break;
- case 1 :
- if (opt_h || opt_s) {
- fd = fopen(argv[xarg],"r");
+ case CMD_HEX :
+ switch (argc - xarg) {
+ case 0 :
+ showhex(stdin);
+ break;
+ case 1 :
+ fd = fopen(argv[xarg],"rb");
if (fd) {
- if (opt_h)
- showhex(fd);
- else
- restore(fd);
+ showhex(fd);
fclose(fd);
- } else {
- fprintf(stderr,"Could not open %s\n",argv[xarg]);
- cmderr = TRUE;
- }
- } else {
- size = utf16size(argv[xarg]);
- if (size) {
- filename = (char*)malloc(2*size + 2);
- if (filename) {
- makeutf16(filename,argv[xarg]);
- if (opt_u) {
- cmderr = mapproposal(filename);
- } else {
-#if POSIXACLS
- if (local_build_mapping(context.mapping,filename)) {
- printf("*** Could not get user mapping data\n");
- warnings++;
- }
-#endif
- if (opt_b)
- cmderr = backup(filename);
- else {
- if (opt_r)
- cmderr = listfiles(filename);
- else
- cmderr = singleshow(filename);
- }
-#if POSIXACLS
- ntfs_free_mapping(context.mapping);
-#endif
- }
- free(filename);
- } else {
- fprintf(stderr,"No more memory\n");
- cmderr = TRUE;
- }
} else {
- fprintf(stderr,"Bad UTF-8 name \"%s\"\n",argv[xarg]);
+ fprintf(stderr,"Could not open %s\n",
+ argv[xarg]);
cmderr = TRUE;
}
+ break;
+ default :
+ cmderr = TRUE;
+ break;
}
break;
- case 2 :
- mode = 0;
- p = argv[xarg];
-#if POSIXACLS
- pxdesc = encode_posix_acl(p);
- if (pxdesc) {
- size = utf16size(argv[xarg + 1]);
- if (size) {
- filename = (char*)malloc(2*size + 2);
- if (filename) {
- makeutf16(filename,argv[xarg + 1]);
- if (local_build_mapping(context.mapping,filename)) {
- printf("*** Could not get user mapping data\n");
- warnings++;
- }
- if (opt_r) {
- for (i=0; i<(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ); i++)
- securdata[i] = (struct SECURITY_DATA*)NULL;
- recurseset_posix(filename,pxdesc);
- } else
- singleset_posix(filename,pxdesc);
- ntfs_free_mapping(context.mapping);
- free(filename);
- } else {
- fprintf(stderr,"No more memory\n");
- cmderr = TRUE;
- }
- chkfree(pxdesc,__FILE__,__LINE__);
- } else {
- fprintf(stderr,"Bad UTF-8 name \"%s\"\n",argv[xarg + 1]);
+ case CMD_NONE :
+ switch (argc - xarg) {
+ case 1 :
+#ifdef HAVE_WINDOWS_H
+ if (!splitarg(split, argv[xarg]))
+ fail = listfiles(split[0], split[1]);
+ else
cmderr = TRUE;
- }
- }
#else
- while ((*p >= '0') && (*p <= '7'))
- mode = (mode << 3) + (*p++) - '0';
- if (*p) {
- fprintf(stderr,"New mode should be given in octal\n");
- cmderr = TRUE;
- } else {
- size = utf16size(argv[xarg + 1]);
- if (size) {
- filename = (char*)malloc(2*size + 2);
- if (filename) {
- makeutf16(filename,argv[xarg + 1]);
-#if POSIXACLS
- if (local_build_mapping(&context,filename)) {
- printf("*** Could not get user mapping data\n");
- warnings++;
- }
+ if (opt_r)
+ cmderr = listfiles(argv[xarg],"/");
+ else
+ cmderr = processmounted(argv[xarg]);
#endif
- if (opt_r) {
- for (i=0; i<(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ); i++)
- securdata[i] = (struct SECURITY_DATA*)NULL;
- recurseset(filename,mode);
- } else
- singleset(filename,mode);
- free(filename);
- } else {
- fprintf(stderr,"No more memory\n");
+ break;
+ case 2 :
+#ifdef HAVE_WINDOWS_H
+ if (!splitarg(split, argv[xarg + 1]))
+ fail = setperms(split[0],
+ argv[xarg], split[1]);
+ else
+ cmderr = TRUE;
+#else /* HAVE_WINDOWS_H */
+ fail = listfiles(argv[xarg],argv[xarg+1]);
+#endif /* HAVE_WINDOWS_H */
+ break;
+ case 3 :
+#ifdef HAVE_WINDOWS_H
+ uname = unixname(argv[xarg+2]);
+ if (uname)
+ fail = setperms(argv[xarg],
+ argv[xarg+1], uname);
+ else
+ cmderr = TRUE;
+#else /* HAVE_WINDOWS_H */
+ cmderr = setperms(argv[xarg], argv[xarg+1],
+ argv[xarg+2]);
+#endif
+ break;
+ default :
+ cmderr = TRUE;
+ break;
+ }
+ break;
+ case CMD_SET :
+ switch (argc - xarg) {
+ case 1 :
+ cmderr = dorestore(argv[xarg],stdin);
+ break;
+ case 2 :
+ fd = fopen(argv[xarg+1],"rb");
+ if (fd) {
+ if (dorestore(argv[xarg],fd))
cmderr = TRUE;
- }
+ fclose(fd);
} else {
- fprintf(stderr,"Bad UTF-8 name \"%s\"\n",argv[xarg + 1]);
+ fprintf(stderr,"Could not open %s\n",
+ argv[xarg]);
cmderr = TRUE;
}
- }
-#endif
- break;
-#if FORCEMASK
- case 3 :
- mode = 0;
- forcemsk = 0;
- p = argv[xarg];
- while (*p) {
- if ((*p >= '0') && (*p <= '9'))
- forcemsk = (forcemsk << 4) + *p - '0';
- else forcemsk = (forcemsk << 4) + (*p & 7) + 9;
- p++;
- }
- p = argv[xarg + 1];
- while ((*p >= '0') && (*p <= '7'))
- mode = (mode << 3) + (*p++) - '0';
- if (*p) {
- fprintf(stderr,"New mode should be given in octal\n");
+ break;
+ default :
cmderr = TRUE;
- } else {
- if (opt_r) {
- recurseset(argv[xarg + 2],mode);
- }
- else singleset(argv[xarg + 2],mode);
}
break;
-#endif
- }
- if (warnings)
- printf("** %u %s signalled\n",warnings,
- (warnings > 1 ? "warnings were" : "warning was"));
- if (errors)
- printf("** %u %s found\n",errors,
- (errors > 1 ? "errors were" : "error was"));
- else
- if (!cmderr)
- printf("No errors were found\n");
- if (!isatty(1)) {
- fflush(stdout);
- if (warnings)
- fprintf(stderr,"** %u %s signalled\n",warnings,
- (warnings > 1 ? "warnings were" : "warning was"));
- if (errors)
- fprintf(stderr,"** %u %s found\n",errors,
- (errors > 1 ? "errors were" : "error was"));
+#ifdef SELFTESTS
+ case CMD_TEST :
+ if (xarg != argc)
+ cmderr = TRUE;
else
- fprintf(stderr,"No errors were found\n");
- freeblocks();
- }
- }
- dumpalloc("termination");
- if (cmderr || errors)
- exit(1);
- return (0);
-}
-
-#else
-
-/*
- * Linux version
- */
-
-int main(int argc, char *argv[])
-{
- FILE *fd;
- const char *p;
- int xarg;
- BOOL cmderr;
- int i;
-#if POSIXACLS
- struct POSIX_SECURITY *pxdesc;
-#else
- unsigned int mode;
-#endif
-
- printf("%s\n",BANNER);
- cmderr = FALSE;
- errors = 0;
- warnings = 0;
- xarg = getoptions(argc,argv);
- if (xarg) {
- for (i=0; i<(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ); i++)
- securdata[i] = (struct SECURITY_DATA*)NULL;
-#if POSIXACLS
- context.mapping[MAPUSERS] = (struct MAPPING*)NULL;
- context.mapping[MAPGROUPS] = (struct MAPPING*)NULL;
-#endif
- firstalloc = (struct CHKALLOC*)NULL;
- mappingtype = MAPNONE;
- switch (argc - xarg) {
- case 0 :
- if (opt_h)
- showhex(stdin);
-#if SELFTESTS & !USESTUBS
- if (opt_t)
selftests();
-#endif
break;
- case 1 :
- if (opt_a)
- cmderr = audit(argv[xarg]);
- else
- if (opt_h) {
- fd = fopen(argv[xarg],"rb");
- if (fd) {
- showhex(fd);
- fclose(fd);
- } else {
- fprintf(stderr,"Could not open %s\n",argv[xarg]);
- cmderr = TRUE;
- }
- } else
- if (opt_b)
- cmderr = backup(argv[xarg],"/");
- else
- if (opt_r)
- cmderr = listfiles(argv[xarg],"/");
- else
- if (opt_s)
- cmderr = dorestore(argv[xarg],stdin);
- else
- cmderr = processmounted(argv[xarg]);
- break;
- case 2 :
- if (opt_b)
- cmderr = backup(argv[xarg],argv[xarg+1]);
- else
- if (opt_s) {
- fd = fopen(argv[xarg+1],"rb");
- if (fd) {
- if (dorestore(argv[xarg],fd))
- cmderr = TRUE;
- fclose(fd);
- } else {
- fprintf(stderr,"Could not open %s\n",argv[xarg]);
- cmderr = TRUE;
- }
- } else
- if (opt_u)
- cmderr = mapproposal(argv[xarg],argv[xarg+1]);
- else
- cmderr = listfiles(argv[xarg],argv[xarg+1]);
- break;
- case 3 :
- p = argv[xarg+1];
-#if POSIXACLS
- pxdesc = encode_posix_acl(p);
- if (pxdesc) {
- if (!getuid() && open_security_api()) {
- if (open_volume(argv[xarg],NTFS_MNT_NONE)) {
- if (opt_r) {
- for (i=0; i<(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ); i++)
- securdata[i] = (struct SECURITY_DATA*)NULL;
- recurseset_posix(argv[xarg + 2],pxdesc);
- } else
- singleset_posix(argv[xarg + 2],pxdesc);
- close_volume(argv[xarg]);
- } else {
- fprintf(stderr,"Could not open volume %s\n",argv[xarg]);
- printerror(stderr);
- cmderr = TRUE;
- }
- close_security_api();
- } else {
- if (getuid())
- fprintf(stderr,"This is only possible as root\n");
- else
- fprintf(stderr,"Could not open security API\n");
+#endif
+ case CMD_USERMAP :
+ switch (argc - xarg) {
+ case 1 :
+#ifdef HAVE_WINDOWS_H
+ if (!splitarg(split, argv[xarg]))
+ fail = mapproposal(split[0],
+ split[1]);
+ else
cmderr = TRUE;
- }
- chkfree(pxdesc,__FILE__,__LINE__);
- } else
+#else /* HAVE_WINDOWS_H */
+ processmounted(argv[xarg]);
+#endif /* HAVE_WINDOWS_H */
+ break;
+ case 2 :
+#ifdef HAVE_WINDOWS_H
+ uname = unixname(argv[xarg+1]);
+ if (uname)
+ cmderr = mapproposal(argv[xarg],
+ uname);
+ else
+ cmderr = TRUE;
+#else /* HAVE_WINDOWS_H */
cmderr = TRUE;
-#else
- mode = 0;
- while ((*p >= '0') && (*p <= '7'))
- mode = (mode << 3) + (*p++) - '0';
- if (*p) {
- fprintf(stderr,"New mode should be given in octal\n");
+#endif /* HAVE_WINDOWS_H */
+ break;
+ default :
cmderr = TRUE;
- } else
- if (!getuid() && open_security_api()) {
- if (open_volume(argv[xarg],NTFS_MNT_NONE)) {
- if (opt_r) {
- for (i=0; i<(MAXSECURID + (1 << SECBLKSZ) - 1)/(1 << SECBLKSZ); i++)
- securdata[i] = (struct SECURITY_DATA*)NULL;
- recurseset(argv[xarg + 2],mode);
- } else
- singleset(argv[xarg + 2],mode);
- close_volume(argv[xarg]);
- } else {
- fprintf(stderr,"Could not open volume %s\n",argv[xarg]);
- printerror(stderr);
- cmderr = TRUE;
- }
- close_security_api();
- } else {
- if (getuid())
- fprintf(stderr,"This is only possible as root\n");
- else
- fprintf(stderr,"Could not open security API\n");
- cmderr = TRUE;
- }
-#endif
+ }
+ break;
+ case CMD_HELP :
+ default :
+ usage();
+ break;
+ case CMD_VERSION :
+ version();
break;
}
+
if (warnings)
printf("** %u %s signalled\n",warnings,
- (warnings > 1 ? "warnings were" : "warning was"));
+ (warnings > 1 ? "warnings were"
+ : "warning was"));
if (errors)
printf("** %u %s found\n",errors,
(errors > 1 ? "errors were" : "error was"));
else
- if (!cmderr)
- printf("No errors were found\n");
+ if (fail)
+ printf("Command failed\n");
+ else
+ if (cmderr)
+ usage();
+ else
+ printf("No errors were found\n");
if (!isatty(1)) {
fflush(stdout);
if (warnings)
fprintf(stderr,"** %u %s signalled\n",warnings,
- (warnings > 1 ? "warnings were" : "warning was"));
+ (warnings > 1 ? "warnings were"
+ : "warning was"));
if (errors)
fprintf(stderr,"** %u %s found\n",errors,
- (errors > 1 ? "errors were" : "error was"));
+ (errors > 1 ? "errors were"
+ : "error was"));
else
- if (!cmderr)
- fprintf(stderr,"No errors were found\n");
+ fprintf(stderr,"No errors were found\n");
}
+ if (split[0])
+ free(split[0]);
+ if (split[1])
+ free(split[1]);
+ if (uname)
+ free(uname);
freeblocks();
} else
- cmderr = TRUE;
- dumpalloc("termination");
+ usage();
if (cmderr || errors)
exit(1);
return (0);
}
-
-#endif
* Windows to Linux user mapping for ntfs-3g
*
*
- * Copyright (c) 2007-2014 Jean-Pierre Andre
+ * Copyright (c) 2007-2016 Jean-Pierre Andre
*
* A quick'n dirty program scanning owners of files in
* "c:\Documents and Settings" (and "c:\Users")
- * and asking user to map them to Linux accounts
+ * and asking user to map them to Linux accounts
*
* History
*
*
* May 2014 Version 1.1.6
* - fixed a wrong function header
+ *
+ * Mar 2016 Version 1.2.0
+ * - reorganized to rely on libntfs-3g even on Windows
*/
/*
* General parameters which may have to be adapted to needs
*/
-#ifdef HAVE_CONFIG_H
-#define USESTUBS 1 /* API stubs generated at link time */
-#else
-#define USESTUBS 0 /* direct calls to API, based on following definitions */
-#define ENVNTFS3G "NTFS3G"
-#define LIBFILE64 "/lib64/libntfs-3g.so.491"
-#define LIBFILE "/lib/libntfs-3g.so.491"
-#endif
-
-#define GET_FILE_SECURITY "ntfs_get_file_security"
-#define SET_FILE_SECURITY "ntfs_set_file_security"
-#define READ_DIRECTORY "ntfs_read_directory"
-#define INIT_FILE_SECURITY "ntfs_initialize_file_security"
-#define LEAVE_FILE_SECURITY "ntfs_leave_file_security"
-
-#define VERSION "1.1.6"
+#define USERMAPVERSION "1.2.0"
#define MAPDIR ".NTFS-3G"
#define MAPFILE "UserMapping"
#define MAXATTRSZ 2048
#define OWNERS1 "Documents and Settings"
#define OWNERS2 "Users"
-/*
- * Define WIN32 for a Windows execution
- * may have to be adapted to compiler or something else
- */
+#include "config.h"
-#ifndef WIN32
-#if defined(__WIN32) | defined(__WIN32__) | defined(WNSC)
-#define WIN32 1
-#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
#endif
-
-#ifdef WIN32
-#define BANNER "Generated by usermap for Windows, v " VERSION
-#else
-#define BANNER "Generated by usermap for Linux, v " VERSION
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
#endif
-
-
-#include <stdio.h>
+#ifdef HAVE_STRING_H
#include <string.h>
-#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
-#include <errno.h>
+#endif
+#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 "utils.h"
+#include "misc.h"
+
+#ifdef HAVE_WINDOWS_H
/*
- * Define the security API according to platform
+ * Including <windows.h> leads to numerous conflicts with layout.h
+ * so define a few needed Windows calls unrelated to ntfs-3g
*/
+BOOL WINAPI LookupAccountNameA(const char*, const char*, void*,
+ u32*, char*, u32*, s32*);
+BOOL WINAPI GetUserNameA(char*, u32*);
+#endif
-#ifdef WIN32
-
-#include <fcntl.h>
-#include <windows.h>
-
-#define STATIC
-
-typedef enum { DENIED, AGREED } boolean;
-
+#ifdef HAVE_WINDOWS_H
+#define DIRSEP "\\"
#else
+#define DIRSEP "/"
+#endif
-#include <unistd.h>
-#include <dlfcn.h>
+#ifdef HAVE_WINDOWS_H
+#define BANNER "Generated by ntfsusermap for Windows, v " USERMAPVERSION
+#else
+#define BANNER "Generated by ntfsusermap for Linux, v " USERMAPVERSION
+#endif
-typedef enum { DENIED, AGREED } boolean, BOOL;
-typedef unsigned int DWORD; /* must be 32 bits whatever the platform */
-typedef DWORD *LPDWORD;
+typedef enum { DENIED, AGREED } boolean;
-enum { OWNER_SECURITY_INFORMATION = 1,
- GROUP_SECURITY_INFORMATION = 2,
- DACL_SECURITY_INFORMATION = 4,
- SACL_SECURITY_INFORMATION = 8
-} ;
+enum STATES { STATE_USERS, STATE_HOMES, STATE_BASE } ;
struct CALLBACK {
const char *accname;
const char *dir;
int levels;
- int docset;
+ enum STATES docset;
} ;
typedef int (*dircallback)(struct CALLBACK *context, char *ntfsname,
int length, int type, long long pos, unsigned long long mft_ref,
unsigned int dt_type);
-#if USESTUBS
-
-#define STATIC static
-
-BOOL 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);
-BOOL ntfs_read_directory(void *scapi,
- const char *path, dircallback callback, void *context);
-void *ntfs_initialize_file_security(const char *device,
- unsigned long flags);
-BOOL ntfs_leave_file_security(void *scapi);
-#else
-
-#define STATIC
-
-BOOL (*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);
-BOOL (*ntfs_read_directory)(void *scapi,
- const char *path, dircallback callback, void *context);
-void *(*ntfs_initialize_file_security)(const char *device,
- unsigned long flags);
-BOOL (*ntfs_leave_file_security)(void *scapi);
-
-#endif
-
-STATIC boolean open_security_api(void);
-STATIC boolean close_security_api(void);
-STATIC boolean open_volume(const char *volume);
-STATIC boolean close_volume(const char *volume);
-
-#endif
-
-struct MAPPING {
- struct MAPPING *next;
+struct USERMAPPING {
+ struct USERMAPPING *next;
const char *uidstr;
const char *gidstr;
const char *sidstr;
boolean defined;
};
-struct MAPPING *firstmapping;
-struct MAPPING *lastmapping;
+struct USERMAPPING *firstmapping;
+struct USERMAPPING *lastmapping;
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
char *currentwinname;
char *currentdomain;
unsigned char *currentsid;
#endif
-#ifndef WIN32
-
void *ntfs_handle;
void *ntfs_context = (void*)NULL;
/*
- * Shut down compiler warnings for unused parameters
- */
-
-static long unused(const void *p)
-{
-return ((long)p);
-}
-
-/*
- * Open and close the security API (platform dependent)
- */
-
-STATIC boolean open_security_api(void)
-{
-#if USESTUBS
- return (AGREED);
-#else
- char *error;
- boolean err;
- const char *libfile;
-
- err = AGREED;
- libfile = getenv(ENVNTFS3G);
- if (!libfile)
- libfile = (sizeof(char*) == 8 ? LIBFILE64 : LIBFILE);
- ntfs_handle = dlopen(libfile,RTLD_LAZY);
- if (ntfs_handle) {
- ntfs_initialize_file_security =
- dlsym(ntfs_handle,INIT_FILE_SECURITY);
- error = dlerror();
- if (error)
- fprintf(stderr," %s\n",error);
- else {
- ntfs_leave_file_security =
- dlsym(ntfs_handle,LEAVE_FILE_SECURITY);
- ntfs_get_file_security =
- dlsym(ntfs_handle,GET_FILE_SECURITY);
- ntfs_set_file_security =
- dlsym(ntfs_handle,SET_FILE_SECURITY);
- ntfs_read_directory =
- dlsym(ntfs_handle,READ_DIRECTORY);
- err = !ntfs_initialize_file_security
- || !ntfs_leave_file_security
- || !ntfs_get_file_security
- || !ntfs_set_file_security
- || !ntfs_read_directory;
- 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
-}
-
-STATIC boolean close_security_api(void)
-{
-#if USESTUBS
- return (0);
-#else
- return (!dlclose(ntfs_handle));
-#endif
-}
-
-/*
- * Open and close a volume (platform dependent)
+ * Open and close a volume in read-only mode
* assuming a single volume needs to be opened at any time
*/
-STATIC boolean open_volume(const char *volume)
+static boolean open_volume(const char *volume)
{
boolean ok;
ok = DENIED;
if (!ntfs_context) {
- ntfs_context = ntfs_initialize_file_security(volume,0);
+ ntfs_context = ntfs_initialize_file_security(volume,
+ NTFS_MNT_RDONLY);
if (ntfs_context) {
fprintf(stderr,"\"%s\" opened\n",volume);
ok = AGREED;
} else {
fprintf(stderr,"Could not open \"%s\"\n",volume);
- fprintf(stderr,"Make sure \"%s\" is not mounted\n",volume);
+#ifdef HAVE_WINDOWS_H
+ if (errno == EACCES)
+ fprintf(stderr,"Make sure you have"
+ " Administrator rights\n");
+#else
+ fprintf(stderr,"Make sure \"%s\" is not mounted\n",
+ volume);
+#endif
}
} else
fprintf(stderr,"A volume is already open\n");
return (ok);
}
-STATIC boolean close_volume(const char *volume)
+static boolean close_volume(const char *volume)
{
boolean r;
* We are assuming outputs to terminal expect UTF8
*/
-STATIC void to_utf8(char *dst, const char *src, unsigned int cnt)
+static void to_utf8(char *dst, const char *src, unsigned int cnt)
{
unsigned int ch;
unsigned int i;
*dst = 0;
}
-STATIC int utf8_size(const char *src, unsigned int cnt)
+static int utf8_size(const char *src, unsigned int cnt)
{
unsigned int ch;
unsigned int i;
return (size);
}
-#endif
-
-
-STATIC void welcome(void)
+static void welcome(void)
{
- printf("\nThis tool will help you to build a mapping of Windows users\n");
+ printf("\nThis tool will help you to build a mapping of"
+ " Windows users\n");
printf("to Linux users.\n");
printf("Be prepared to give Linux user id (uid) and group id (gid)\n");
printf("for owners of files which will be selected.\n");
}
-STATIC unsigned int get2l(const unsigned char *attr, int p)
+static unsigned int get2l(const unsigned char *attr, int p)
{
int i;
unsigned int v;
return (v);
}
-STATIC unsigned long get4l(const unsigned char *attr, int p)
+static unsigned long get4l(const unsigned char *attr, int p)
{
int i;
unsigned long v;
return (v);
}
-STATIC unsigned long long get6h(const unsigned char *attr, int p)
+static unsigned long long get6h(const unsigned char *attr, int p)
{
int i;
unsigned long long v;
return (v);
}
-STATIC char *decodesid(const unsigned char *sid)
+static char *decodesid(const unsigned char *sid)
{
char *str;
int i;
str = (char *)malloc(MAXSIDSZ);
if (str) {
strcpy(str, "S");
- sprintf(&str[strlen(str)], "-%d", sid[0]); /* revision */
+ /* revision */
+ sprintf(&str[strlen(str)], "-%d", sid[0]);
+ /* main authority */
auth = get6h(sid, 2);
-#ifdef WIN32
- sprintf(&str[strlen(str)], "-%I64u", auth); /* main authority */
+#ifdef HAVE_WINDOWS_H
+ sprintf(&str[strlen(str)], "-%I64u", auth);
#else
- sprintf(&str[strlen(str)], "-%llu", auth); /* main authority */
+ sprintf(&str[strlen(str)], "-%llu", auth);
#endif
for (i = 0; (i < 8) && (i < sid[1]); i++) {
+ /* sub-authority */
subauth = get4l(sid, 8 + 4 * i);
- sprintf(&str[strlen(str)], "-%lu", subauth); /* sub-authority */
+ sprintf(&str[strlen(str)], "-%lu", subauth);
}
}
return (str);
* Test whether a generic group (S-1-5-21- ... -513)
*/
-STATIC boolean isgenericgroup(const char *sid)
+static boolean isgenericgroup(const char *sid)
{
boolean yes;
return (yes);
}
-STATIC unsigned char *makegroupsid(const unsigned char *sid)
+static unsigned char *makegroupsid(const unsigned char *sid)
{
static unsigned char groupsid[MAXSIDSZ];
int size;
return (groupsid);
}
-STATIC void domapping(const char *accname, const char *filename,
- const char *dir, const unsigned char *sid, int type)
+static void askmapping(const char *accname, const char *filename,
+ const char *dir, const unsigned char *sid, int type,
+ struct USERMAPPING *mapping, char *sidstr)
{
char buf[81];
- char *sidstr;
char *idstr;
+ char *login;
int sidsz;
boolean reject;
- struct MAPPING *mapping;
- char *login;
char *p;
+ do {
+ reject = DENIED;
+ printf("\n");
+ if (accname)
+ printf("Under Windows login \"%s\"\n", accname);
+ if (dir) {
+#ifdef HAVE_WINDOWS_H
+ char *wdir;
+
+ wdir = strdup(dir);
+ if (wdir) {
+ for (p=wdir; *p; p++)
+ if (*p == '/')
+ *p = '\\';
+ printf(" in directory \"%s\"\n",wdir);
+ free(wdir);
+ }
+#else
+ printf(" in directory \"%s\"\n",dir);
+#endif
+ }
+ printf(" file \"%s\" has no mapped %s\n",
+ filename,(type ? "group" : "owner"));
+ printf("By which Linux login should this file be owned ?\n");
+ printf("Enter %s of login, or just press \"enter\" if"
+ " this file\n", (type ? "gid" : "uid"));
+ printf("does not belong to a user, or you do not know"
+ " to whom\n");
+ printf("\n");
+ if (type)
+ printf("Group : ");
+ else
+ printf("User : ");
+ p = fgets(buf, 80, stdin);
+ if (p && p[0] && (p[strlen(p) - 1] == '\n'))
+ p[strlen(p) - 1] = '\0';
+
+ if (p && p[0]
+ && ((p[0] == '0') || !strcmp(p, "root"))) {
+ printf("Please do not map users to root\n");
+ printf("Administrators will be mapped automatically\n");
+ reject = AGREED;
+ }
+ if (reject)
+ printf("Please retry\n");
+ } while (reject);
+ if (!mapping) {
+ mapping =
+ (struct USERMAPPING *)
+ malloc(sizeof(struct USERMAPPING));
+ mapping->next = (struct USERMAPPING *)NULL;
+ mapping->defined = DENIED;
+ if (lastmapping)
+ lastmapping->next = mapping;
+ else
+ firstmapping = mapping;
+ lastmapping = mapping;
+ }
+ if (mapping) {
+ if (p && p[0]) {
+ idstr = (char *)malloc(strlen(p) + 1);
+ if (idstr) {
+ strcpy(idstr, p);
+ if (type) {
+ mapping->uidstr = "";
+ mapping->gidstr = idstr;
+ } else {
+ mapping->uidstr = idstr;
+ mapping->gidstr = idstr;
+ }
+ mapping->defined = AGREED;
+ }
+ }
+ mapping->sidstr = sidstr;
+ if (accname) {
+ login = (char*)malloc(strlen(accname) + 1);
+ if (login)
+ strcpy(login,accname);
+ mapping->login = login;
+ } else
+ mapping->login = (char*)NULL;
+ sidsz = 8 + sid[1]*4;
+ p = (char*)malloc(sidsz);
+ if (p) {
+ memcpy(p, sid, sidsz);
+ }
+ mapping->sid = (unsigned char*)p;
+ }
+}
+
+static void domapping(const char *accname, const char *filename,
+ const char *dir, const unsigned char *sid, int type)
+{
+ char *sidstr;
+ struct USERMAPPING *mapping;
+
if ((get6h(sid, 2) == 5) && (get4l(sid, 8) == 21)) {
sidstr = decodesid(sid);
mapping = firstmapping;
|| !strcmp(mapping->login, accname)))
free(sidstr); /* decision already known */
else {
- do {
- reject = DENIED;
- printf("\n");
- if (accname)
- printf("Under Windows login \"%s\"\n", accname);
- if (dir)
- printf(" in directory \"%s\"\n",dir);
- printf(" file \"%s\" has no mapped %s\n",
- filename,(type ? "group" : "owner"));
- printf("By which Linux login should this file be owned ?\n");
- printf("Enter %s of login, or just press \"enter\" if this file\n",
- (type ? "gid" : "uid"));
- printf("does not belong to a user, or you do not known to whom\n");
- printf("\n");
- if (type)
- printf("Group : ");
- else
- printf("User : ");
- p = fgets(buf, 80, stdin);
- if (p && p[0] && (p[strlen(p) - 1] == '\n'))
- p[strlen(p) - 1] = '\0';
-
- if (p && p[0]
- && ((p[0] == '0') || !strcmp(p, "root"))) {
- printf("Please do not map users to root\n");
- printf("Administrators will be mapped automatically\n");
- reject = AGREED;
- }
- if (reject)
- printf("Please retry\n");
- } while (reject);
- if (!mapping) {
- mapping =
- (struct MAPPING *)
- malloc(sizeof(struct MAPPING));
- mapping->next = (struct MAPPING *)NULL;
- mapping->defined = DENIED;
- if (lastmapping)
- lastmapping->next = mapping;
- else
- firstmapping = mapping;
- lastmapping = mapping;
- }
- if (mapping) {
- if (p && p[0]) {
- idstr = (char *)malloc(strlen(p) + 1);
- if (idstr) {
- strcpy(idstr, p);
- if (type) {
- mapping->uidstr = "";
- mapping->gidstr = idstr;
- } else {
- mapping->uidstr = idstr;
- mapping->gidstr = idstr;
- }
- mapping->defined = AGREED;
- }
- }
- mapping->sidstr = sidstr;
- if (accname) {
- login = (char*)malloc(strlen(accname) + 1);
- if (login)
- strcpy(login,accname);
- mapping->login = login;
- } else
- mapping->login = (char*)NULL;
- sidsz = 8 + sid[1]*4;
- p = (char*)malloc(sidsz);
- if (p) {
- memcpy(p, sid, sidsz);
- }
- mapping->sid = (unsigned char*)p;
- }
+ askmapping(accname, filename, dir, sid, type,
+ mapping, sidstr);
}
}
}
-STATIC void listaclusers(const char *accname, const unsigned char *attr, int off)
+static void listaclusers(const char *accname, const unsigned char *attr,
+ int off)
{
int i;
int cnt;
}
}
-#ifdef WIN32
-
-STATIC void account(const char *accname, const char *dir, const char *name, int type)
-{
- unsigned char attr[MAXATTRSZ];
- unsigned long attrsz;
- char *fullname;
- int attrib;
-
- fullname = (char *)malloc(strlen(dir) + strlen(name) + 2);
- if (fullname) {
- strcpy(fullname, dir);
- strcat(fullname, "\\");
- strcat(fullname, name);
- attrib = GetFileAttributes(fullname);
- if (attrib & 0x10) { /* only directories processed */
- if (GetFileSecurity
- (fullname, OWNER_SECURITY_INFORMATION, attr, MAXATTRSZ,
- &attrsz)) {
- domapping(accname, name, dir, &attr[20], 0);
- attrsz = 0;
- if (GetFileSecurity
- (fullname, GROUP_SECURITY_INFORMATION, attr,
- MAXATTRSZ, &attrsz))
- domapping(accname, name, dir, &attr[20], 1);
- else
- printf(" No group SID\n");
- attrsz = 0;
- if (GetFileSecurityA
- (fullname, DACL_SECURITY_INFORMATION, attr,
- MAXATTRSZ, &attrsz)) {
- if (type == 0)
- listaclusers(accname, attr, 20);
- } else
- printf
- (" No discretionary access control list\n");
- }
- }
- free(fullname);
- }
-}
-
-#else
-
-STATIC void account(const char *accname, const char *dir, const char *name, int type)
+static void account(const char *accname, const char *dir,
+ const char *name, int type)
{
unsigned char attr[MAXATTRSZ];
- DWORD attrsz;
+ u32 attrsz;
char *fullname;
fullname = (char *)malloc(strlen(dir) + strlen(name) + 2);
strcat(fullname, "/");
strcat(fullname, name);
if (ntfs_get_file_security(ntfs_context,
- fullname, OWNER_SECURITY_INFORMATION,
- (char*)attr, MAXATTRSZ, &attrsz)) {
+ fullname, OWNER_SECURITY_INFORMATION,
+ (char*)attr, MAXATTRSZ, &attrsz)) {
domapping(accname, name, dir, &attr[20], 0);
attrsz = 0;
if (ntfs_get_file_security(ntfs_context,
if (type == 0)
listaclusers(accname, attr, 20);
} else
- printf(" No discretionary access control list for %s !\n",
- dir);
+ printf(" No discretionary access control"
+ " list for %s !\n", dir);
}
free(fullname);
}
}
-#endif
-
-
/*
* recursive search of file owners and groups in a directory
*/
-#ifdef WIN32
+static boolean recurse(const char *accname, const char *dir,
+ int levels, enum STATES docset);
-STATIC boolean recurse(const char *accname, const char *dir, int levels)
-{
- WIN32_FIND_DATA found;
- HANDLE search;
- char *filter;
- char *fullname;
- boolean err;
-
- err = DENIED;
- filter = (char *)malloc(strlen(dir) + 5);
- if (filter) {
- strcpy(filter, dir);
- strcat(filter, "\\*.*");
- search = FindFirstFile(filter, &found);
- if (search != INVALID_HANDLE_VALUE) {
- do {
- if (found.cFileName[0] != '.') {
- account(accname, dir, found.cFileName,1);
- if (levels > 0) {
- fullname =
- (char *)malloc(strlen(dir) +
- strlen(found.cFileName)
- + 2);
- if (fullname) {
- strcpy(fullname, dir);
- strcat(fullname, "\\");
- strcat(fullname,
- found.cFileName);
- recurse(accname,
- fullname,
- levels - 1);
- free(fullname);
- }
- }
- }
- } while (FindNextFile(search, &found));
- FindClose(search);
- }
- free(filter);
- } else {
- printf("Directory %s not found\n",dir);
- err = AGREED;
- }
- return (!err);
-}
-
-#else
-
-STATIC boolean recurse(const char *accname, const char *dir, int levels, int docset);
-
-STATIC int callback(struct CALLBACK *context, char *ntfsname,
- int length, int type, long long pos, unsigned long long mft_ref,
- unsigned int dt_type)
+static int callback(void *ctx, const ntfschar *ntfsname,
+ const int length, const int type,
+ const s64 pos __attribute__((unused)),
+ const MFT_REF mft_ref __attribute__((unused)),
+ const unsigned int dt_type __attribute__((unused)))
{
+ struct CALLBACK *context;
char *fullname;
char *accname;
char *name;
- unused((void*)&pos);
- unused((void*)&mft_ref);
- unused((void*)&dt_type);
+ context = (struct CALLBACK*)ctx;
fullname = (char *)malloc(strlen(context->dir)
- + utf8_size(ntfsname, length) + 2);
+ + utf8_size((const char*)ntfsname, length) + 2);
if (fullname) {
+ /* No "\\" when interfacing libntfs-3g */
if (strcmp(context->dir,"/")) {
strcpy(fullname, context->dir);
strcat(fullname, "/");
strcpy(fullname,"/");
/* Unicode to ascii conversion by a lazy man */
name = &fullname[strlen(fullname)];
- to_utf8(name, ntfsname, length);
+ to_utf8(name, (const char*)ntfsname, length);
/* ignore special files and DOS names */
if ((type != 2)
&& strcmp(name,".")
&& strcmp(name,"..")
&& (name[0] != '$')) {
switch (context->docset) {
- case 2 :
+ case STATE_USERS :
/*
* only "Documents and Settings"
* or "Users"
*/
if (!strcmp(name,OWNERS1)
|| !strcmp(name,OWNERS2)) {
- recurse((char*)NULL, fullname, 2, 1);
+ recurse((char*)NULL, fullname, 2,
+ STATE_HOMES);
}
break;
/*
* within "Documents and Settings"
* or "Users"
*/
- case 1 :
+ case STATE_HOMES :
accname = (char*)malloc(strlen(name) + 1);
if (accname) {
strcpy(accname, name);
if (context->levels > 0)
recurse(name, fullname,
- context->levels - 1, 0);
+ context->levels - 1,
+ STATE_BASE);
}
break;
/*
- * not related to "Documents and Settings"
- * or "Users"
+ * not related to "Documents and
+ * Settings" or "Users"
*/
- case 0 :
+ case STATE_BASE :
account(context->accname, context->dir,
name, 1);
if (context->levels > 0)
recurse(context->accname, fullname,
- context->levels - 1, 0);
+ context->levels - 1,
+ STATE_BASE);
break;
}
}
return (0);
}
-STATIC boolean recurse(const char *accname, const char *dir, int levels, int docset)
+static boolean recurse(const char *accname, const char *dir,
+ int levels, enum STATES docset)
{
struct CALLBACK context;
boolean err;
ntfs_read_directory(ntfs_context,dir,callback,&context);
return (!err);
}
-#endif
/*
* Search directory "Documents and Settings" for user accounts
*/
-#ifdef WIN32
-
-STATIC boolean getusers(const char *dir, int levels)
-{
- WIN32_FIND_DATA found;
- HANDLE search;
- char *filter;
- char *fullname;
- char *accname;
- boolean err;
- const char *docset;
-
- /* first get files from "Documents and Settings" */
- err = DENIED;
- if (sizeof(OWNERS1) > sizeof(OWNERS2))
- filter = (char *)malloc(strlen(dir) + strlen(OWNERS1) + 6);
- else
- filter = (char *)malloc(strlen(dir) + strlen(OWNERS2) + 6);
- if (filter) {
- docset = OWNERS1;
- strcpy(filter, dir);
- strcat(filter, "\\");
- strcat(filter, docset);
- strcat(filter, "\\*.*");
- search = FindFirstFile(filter, &found);
- /* if failed, retry with "Users" */
- if (search == INVALID_HANDLE_VALUE) {
- docset = OWNERS2;
- strcpy(filter, dir);
- strcat(filter, "\\");
- strcat(filter, docset);
- strcat(filter, "\\*.*");
- search = FindFirstFile(filter, &found);
- }
- if (search != INVALID_HANDLE_VALUE) {
- do {
- if (found.cFileName[0] != '.') {
- fullname =
- (char *)malloc(strlen(dir)
- + strlen(docset)
- + strlen(found.cFileName) + 3);
- accname = (char *)
- malloc(strlen(found.cFileName) + 1);
- if (fullname && accname) {
- strcpy(accname,
- found.cFileName);
-
- strcpy(fullname, dir);
- strcat(fullname, "\\");
- strcat(fullname, docset);
- strcat(fullname, "\\");
- strcat(fullname,
- found.cFileName);
- recurse(accname, fullname, 2);
-
- free(fullname);
- }
- }
- } while (FindNextFile(search, &found));
- FindClose(search);
- } else {
- printf("No subdirectory found in %s\\%s\n",dir,docset);
- }
- /* now search in other directories */
- strcpy(filter, dir);
- strcat(filter, "\\*.*");
- search = FindFirstFile(filter, &found);
- if (search != INVALID_HANDLE_VALUE) {
- do {
- if ((found.cFileName[0] != '.')
- && strcmp(found.cFileName,OWNERS1)
- && strcmp(found.cFileName,OWNERS2)) {
- fullname =
- (char *)malloc(strlen(dir)
- + strlen(found.cFileName) + 2);
- if (fullname) {
- strcpy(fullname, dir);
- strcat(fullname, "\\");
- strcat(fullname,
- found.cFileName);
- recurse((char*)NULL, fullname, 2);
- free(fullname);
- }
- }
- } while (FindNextFile(search, &found));
- FindClose(search);
- } else {
- printf("No directory found in %s\n",dir);
- err = AGREED;
- }
- }
- return (!err);
-}
-
-#else
-
-STATIC boolean getusers(const char *dir, int levels)
+static boolean getusers(const char *dir, int levels)
{
boolean err;
struct CALLBACK context;
context.dir = dir;
context.accname = (const char*)NULL;
context.levels = levels;
- context.docset = 2;
+ context.docset = STATE_USERS;
ntfs_read_directory(ntfs_context,dir,callback,&context);
printf("* Search for other directories %s\n",dir);
- context.docset = 0;
+ context.docset = STATE_BASE;
ntfs_read_directory(ntfs_context,dir,callback,&context);
-
return (!err);
}
-#endif
-
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
/*
* Get the current login name (Win32 only)
*/
-STATIC void loginname(boolean silent)
+static void loginname(boolean silent)
{
char *winname;
char *domain;
unsigned char *sid;
- unsigned long namesz;
- unsigned long sidsz;
- unsigned long domainsz;
- int nametype;
+ u32 namesz;
+ u32 sidsz;
+ u32 domainsz;
+ s32 nametype;
boolean ok;
int r;
if (winname
&& domain
&& sid
- && GetUserName(winname,&namesz)) {
+ && GetUserNameA(winname,&namesz)) {
winname[namesz] = '\0';
if (!silent)
printf("Your current user name is %s\n",winname);
nametype = 1;
- r = LookupAccountName((char*)NULL,winname,sid,&sidsz,
+ r = LookupAccountNameA((char*)NULL,winname,sid,&sidsz,
domain,&domainsz,&nametype);
if (r) {
domain[domainsz] = '\0';
* Minimal output on stdout
*/
-boolean minimal(unsigned char *sid)
+static boolean minimal(unsigned char *sid)
{
const unsigned char *groupsid;
boolean ok;
printf("# %s\n",BANNER);
printf("# For Windows account \"%s\" in domain \"%s\"\n",
currentwinname, currentdomain);
- printf("# Replace \"user\" and \"group\" hereafter by matching Linux login\n");
+ printf("# Replace \"user\" and \"group\" hereafter by"
+ " matching Linux login\n");
printf("user::%s\n",decodesid(sid));
printf(":group:%s\n",decodesid(groupsid));
ok = AGREED;
#endif
-STATIC boolean outputmap(const char *volume, const char *dir)
+/*
+ * Create a user mapping file
+ *
+ * From now on, partitions which were opened through ntfs-3g
+ * are closed, and we use the system drivers to create the file.
+ * On Windows, we can write on a partition which was analyzed.
+ */
+
+static boolean outputmap(const char *volume, const char *dir)
{
char buf[256];
int fn;
char *fullname;
char *backup;
- struct MAPPING *mapping;
+ struct USERMAPPING *mapping;
boolean done;
boolean err;
boolean undecided;
-#ifdef WIN32
-#else
struct stat st;
int s;
-#endif
done = DENIED;
fullname = (char *)malloc(strlen(MAPFILE) + 1
+ strlen(volume) + 1
+ (dir ? strlen(dir) + 1 : 0));
if (fullname) {
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
strcpy(fullname, volume);
if (dir && dir[0]) {
- strcat(fullname, "\\");
+ strcat(fullname, DIRSEP);
strcat(fullname,dir);
}
/* build directory, if not present */
- if (GetFileAttributes(fullname) & 0x80000000) {
+ if (stat(fullname,&st) && (errno == ENOENT)) {
printf("* Creating directory %s\n", fullname);
mkdir(fullname);
}
- strcat(fullname, "\\");
+ strcat(fullname, DIRSEP);
strcat(fullname, MAPFILE);
printf("\n");
-
- if (!(GetFileAttributes(fullname) & 0x80000000)) {
- backup = (char*)malloc(strlen(fullname) + 5);
- strcpy(backup,fullname);
- strcat(backup,".bak");
- unlink(backup);
- if (!rename(fullname,backup))
- printf("* Old mapping file moved to %s\n",backup);
- }
#else
strcpy(fullname, MAPFILE);
printf("\n");
+#endif
s = stat(fullname,&st);
if (!s) {
backup = (char*)malloc(strlen(fullname + 5));
strcpy(backup,fullname);
strcat(backup,".bak");
+#ifdef HAVE_WINDOWS_H
+ unlink(backup);
+#endif
if (rename(fullname,backup))
- printf("* Old mapping file moved to %s\n",backup);
+ printf("* Old mapping file moved to %s\n",
+ backup);
}
-#endif
printf("* Creating file %s\n", fullname);
err = DENIED;
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
fn = open(fullname,O_CREAT + O_TRUNC + O_WRONLY + O_BINARY,
S_IREAD + S_IWRITE);
#else
for (mapping = firstmapping; mapping && !err;
mapping = mapping->next)
if (mapping->defined
- && (!mapping->uidstr[0] || !mapping->gidstr[0])) {
+ && (!mapping->uidstr[0]
+ || !mapping->gidstr[0])) {
sprintf(buf,"%s:%s:%s\n",
mapping->uidstr,
mapping->gidstr,
for (mapping = firstmapping; mapping && !err;
mapping = mapping->next)
if (mapping->defined
- && mapping->uidstr[0] && mapping->gidstr[0]) {
+ && mapping->uidstr[0]
+ && mapping->gidstr[0]) {
sprintf(buf,"%s:%s:%s\n",
mapping->uidstr,
mapping->gidstr,
for (mapping = firstmapping; mapping;
mapping = mapping->next)
if (!mapping->defined) {
- printf(" %s\n", mapping->sidstr);
+ printf(" %s\n",
+ mapping->sidstr);
}
}
-#ifndef WIN32
- printf("\n* You will have to move the file \"" MAPFILE "\"\n");
- printf(" to directory \"" MAPDIR "\" after mounting\n");
+#ifndef HAVE_WINDOWS_H
+ printf("\n* You will have to move the file \""
+ MAPFILE "\"\n");
+ printf(" to directory \"" MAPDIR "\" after"
+ " mounting\n");
#endif
}
}
if (!done)
- fprintf(stderr, "* Could not create mapping file \"%s\"\n", fullname);
+ fprintf(stderr, "* Could not create mapping file \"%s\"\n",
+ fullname);
return (done);
}
-STATIC boolean sanitize(void)
+static boolean sanitize(void)
{
char buf[81];
boolean ok;
int ownercnt;
int groupcnt;
- struct MAPPING *mapping;
- struct MAPPING *firstowner;
- struct MAPPING *genericgroup;
- struct MAPPING *group;
+ struct USERMAPPING *mapping;
+ struct USERMAPPING *firstowner;
+ struct USERMAPPING *genericgroup;
+ struct USERMAPPING *group;
char *sidstr;
/* count owners and groups */
/* and find first user, and a generic group */
ownercnt = 0;
groupcnt = 0;
- firstowner = (struct MAPPING*)NULL;
- genericgroup = (struct MAPPING*)NULL;
+ firstowner = (struct USERMAPPING*)NULL;
+ genericgroup = (struct USERMAPPING*)NULL;
for (mapping=firstmapping; mapping; mapping=mapping->next) {
if (mapping->defined && mapping->uidstr[0]) {
if (!ownercnt)
firstowner = mapping;
ownercnt++;
}
- if (mapping->defined && mapping->gidstr[0] && !mapping->uidstr[0]) {
+ if (mapping->defined && mapping->gidstr[0]
+ && !mapping->uidstr[0]) {
groupcnt++;
}
if (!mapping->defined && isgenericgroup(mapping->sidstr)) {
genericgroup = mapping;
}
}
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
/* no user defined, on Windows, suggest a mapping */
/* based on account currently used */
if (!ownercnt && currentwinname && currentsid) {
char *p;
printf("\nYou have defined no file owner,\n");
- printf(" please enter the Linux login which should be mapped\n");
+ printf(" please enter the Linux login which should"
+ " be mapped\n");
printf(" to account you are currently using\n");
printf(" Linux user ? ");
p = fgets(buf, 80, stdin);
if (p && p[0] && (p[strlen(p) - 1] == '\n'))
p[strlen(p) - 1] = '\0';
if (p && p[0]) {
- firstowner = (struct MAPPING*)malloc(sizeof(struct MAPPING));
+ firstowner = (struct USERMAPPING*)malloc(
+ sizeof(struct USERMAPPING));
owner = (char*)malloc(strlen(p) + 1);
if (firstowner && owner) {
strcpy(owner, p);
firstowner->sid = currentsid;
firstmapping = firstowner;
ownercnt++;
- /* prefer a generic group with the same authorities */
+ /* prefer a generic group with the same
+ * authorities */
for (mapping=firstmapping; mapping;
mapping=mapping->next)
if (!mapping->defined
&& isgenericgroup(mapping->sidstr)
&& !memcmp(firstowner->sidstr,
mapping->sidstr,
- strlen(mapping->sidstr)-3))
+ strlen(mapping
+ ->sidstr)-3))
genericgroup = mapping;
}
}
#endif
if (ownercnt) {
/*
- * No group was selected, but there were a generic group
- * insist in using it, associated to the first user
+ * No group was selected, but there were a generic
+ * group, insist in using it, associated to the
+ * first user
*/
if (!groupcnt) {
- printf("\nYou have defined no group, this can cause problems\n");
+ printf("\nYou have defined no group,"
+ " this can cause problems\n");
printf("Do you accept defining a standard group ?\n");
if (!fgets(buf,80,stdin)
|| ((buf[0] != 'n')
&& (buf[0] != 'N'))) {
if (genericgroup) {
genericgroup->uidstr = "";
- genericgroup->gidstr = firstowner->uidstr;
+ genericgroup->gidstr =
+ firstowner->uidstr;
genericgroup->defined = AGREED;
} else {
- group = (struct MAPPING*)
- malloc(sizeof(struct MAPPING));
+ group = (struct USERMAPPING*)
+ malloc(sizeof(
+ struct USERMAPPING));
sidstr = decodesid(
makegroupsid(firstowner->sid));
if (group && sidstr) {
return (ok);
}
-STATIC boolean checkoptions(int argc, char *argv[], boolean silent)
+static boolean checkoptions(int argc, char *argv[] __attribute__((unused)),
+ boolean silent __attribute__((unused)))
{
boolean err;
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
int xarg;
const char *pvol;
- if (silent)
+ if (silent) {
err = (argc != 1);
- else {
+ } else {
err = (argc < 2);
for (xarg=1; (xarg<argc) && !err; xarg++) {
pvol = argv[xarg];
if (pvol[0] && (pvol[1] == ':') && !pvol[2]) {
err = !(((pvol[0] >= 'A') && (pvol[0] <= 'Z'))
- || ((pvol[0] >= 'a') && (pvol[0] <= 'z')));
+ || ((pvol[0] >= 'a')
+ && (pvol[0] <= 'z')));
}
}
}
if (err) {
- fprintf(stderr, "Usage : usermap [vol1: [vol2: ...]]\n");
- fprintf(stderr, " \"voln\" are the letters of the partition to share with Linux\n");
+ fprintf(stderr, "Usage : ntfsusermap [vol1: [vol2: ...]]\n");
+ fprintf(stderr, " \"voln\" are the letters of the partition"
+ " to share with Linux\n");
fprintf(stderr, " eg C:\n");
- fprintf(stderr, " the Windows system partition should be named first\n");
+ fprintf(stderr, " the Windows system partition should be"
+ " named first\n");
+ if (silent) {
+ fprintf(stderr, "When outputting to file, a minimal"
+ " user mapping proposal\n");
+ fprintf(stderr, "is written to the file, and no"
+ " partition should be mentioned\n");
+ }
}
#else
- unused((void*)argv);
- unused((void*)&silent);
err = (argc < 2);
if (err) {
- fprintf(stderr, "Usage : usermap dev1 [dev2 ...]\n");
- fprintf(stderr, " \"dev.\" are the devices to share with Windows\n");
+ fprintf(stderr, "Usage : ntfsusermap dev1 [dev2 ...]\n");
+ fprintf(stderr, " \"dev.\" are the devices to share"
+ " with Windows\n");
fprintf(stderr, " eg /dev/sdb1\n");
- fprintf(stderr, " the devices should not be mounted\n");
- fprintf(stderr, " the Windows system partition should be named first\n");
+ fprintf(stderr, " the devices should not be mounted, and\n");
+ fprintf(stderr, " the Windows system partition should"
+ " be named first\n");
} else
if (getuid()) {
- fprintf(stderr, "\nSorry, only root can start usermap\n");
+ fprintf(stderr, "\nSorry, only root can start"
+ " ntfsusermap\n");
err = AGREED;
}
#endif
return (!err);
}
-STATIC boolean process(int argc, char *argv[])
+static boolean process(int argc, char *argv[])
{
boolean ok;
int xarg;
int targ;
- firstmapping = (struct MAPPING *)NULL;
- lastmapping = (struct MAPPING *)NULL;
+ firstmapping = (struct USERMAPPING *)NULL;
+ lastmapping = (struct USERMAPPING *)NULL;
ok = AGREED;
-#ifdef WIN32
- for (xarg=1; (xarg<argc) && ok; xarg++) {
- printf("\n* Scanning \"%s\" (two levels)\n",argv[xarg]);
- ok = getusers(argv[xarg],2);
- }
-#else
for (xarg=1; (xarg<argc) && ok; xarg++)
if (open_volume(argv[xarg])) {
printf("\n* Scanning \"%s\" (two levels)\n",argv[xarg]);
close_volume(argv[xarg]);
} else
ok = DENIED;
-#endif
if (ok && sanitize()) {
targ = (argc > 2 ? 2 : 1);
if (!outputmap(argv[targ],MAPDIR)) {
printf("Trying to write file on root directory\n");
if (outputmap(argv[targ],(const char*)NULL)) {
- printf("\nNote : you will have to move the file to directory \"%s\" on Linux\n",
+ printf("\nNote : you will have to move the"
+ " file to directory \"%s\" on Linux\n",
MAPDIR);
} else
ok = DENIED;
if (!silent)
welcome();
if (checkoptions(argc, argv, silent)) {
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
loginname(silent);
if (silent)
ok = minimal(currentsid);
else
- ok = process(argc, argv);
-#else
- if (open_security_api()) {
ok = process(argc,argv);
- if (!close_security_api()) ok = DENIED;
- }
- else {
- ok = DENIED;
- }
+#else
+ ok = process(argc,argv);
#endif
} else
ok = DENIED;