/*
 *		General declarations for secaudit
 *
 *	These declarations are organized to enable code sharing with ntfs-3g
 *	library, but should only be used to build tools runnable both
 *	on Linux (dynamic linking) and Windows (static linking)
 *
 * Copyright (c) 2007-2009 Jean-Pierre Andre
 *
 */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (in the main directory of the NTFS-3G
 * distribution in the file COPYING); if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 *		General parameters which may have to be adapted to needs
 */

#define SELFTESTS 1 /* include code for self-testing */
#define POSIXACLS 0 /* include code for processing Posix ACLs */
#define NOREVBOM 0 /* temporary */

#define OWNERFROMACL 1 /* must match option in security.c */

#define MAXATTRSZ 65536 /* Max sec attr size (16448 met for WinXP) */
#define MAXSECURID 262144
#define SECBLKSZ 8
#define MAXFILENAME 4096
#define FORCEMASK 0 /* Special (dangerous) option -m to force a mask */
#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 */

/*
 *		     Definitions for Linux
 *	Use explicit or implicit dynamic linking
 */

#ifdef HAVE_CONFIG_H
#undef POSIXACLS   /* override default by configure option */
#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.838"
#define LIBFILE "/lib/libntfs-3g.so.838"
#endif

#define MAPDIR ".NTFS-3G"
#define MAPFILE "UserMapping"
#define MAGIC_API 0x09042009

#ifndef _NTFS_ENDIANS_H

typedef char s8;
typedef short s16;
typedef long long s64;
typedef unsigned char u8;
typedef unsigned short le16, be16, u16;
typedef unsigned long long u64;
#ifdef STSC
typedef long s32;
typedef unsigned long le32, be32, u32;
#else
typedef int s32;
typedef unsigned int le32, be32, u32;
#endif

#ifdef STSC
#define endian_rev16(x) ((((x) & 255L) << 8) + (((x) >> 8) & 255L))
#define endian_rev32(x) ((((x) & 255L) << 24) + (((x) & 0xff00L) << 8) \
		       + (((x) >> 8) & 0xff00L) + (((x) >> 24) & 255L))
#else
#define endian_rev16(x) ((((x) & 255) << 8) + (((x) >> 8) & 255))
#define endian_rev32(x) ((((x) & 255) << 24) + (((x) & 0xff00) << 8) \
		       + (((x) >> 8) & 0xff00) + (((x) >> 24) & 255))
#endif
#define endian_rev64(x) ((((x) & 255LL) << 56) + (((x) & 0xff00LL) << 40) \
		       + (((x) & 0xff0000LL) << 24) + (((x) & 0xff000000LL) << 8) \
		       + (((x) >> 8) & 0xff000000LL) + (((x) >> 24) & 0xff0000LL) \
		       + (((x) >> 40) & 0xff00LL) + (((x) >> 56) & 255LL))

#if __BYTE_ORDER == __LITTLE_ENDIAN

#define cpu_to_be16(x) endian_rev16(x)
#define cpu_to_be32(x) endian_rev32(x)
#define cpu_to_le16(x) (x)
#define cpu_to_le32(x) (x)
#define cpu_to_le64(x) (x)
#define le16_to_cpu(x) (x)
#define le32_to_cpu(x) (x)
#define le64_to_cpu(x) (x)

#else

#define cpu_to_be16(x) (x)
#define cpu_to_be32(x) (x)
#define cpu_to_le16(x) endian_rev16(x)
#define cpu_to_le32(x) endian_rev32(x)
#define cpu_to_le64(x) endian_rev64(x)
#define le16_to_cpu(x) endian_rev16(x)
#define le32_to_cpu(x) endian_rev32(x)
#define le64_to_cpu(x) endian_rev64(x)

#endif

#define const_le16_to_cpu(x) le16_to_cpu(x)
#define const_cpu_to_le16(x) cpu_to_le16(x)
#define const_cpu_to_le32(x) cpu_to_le32(x)
#define const_cpu_to_be16(x) cpu_to_be16(x)
#define const_cpu_to_be32(x) cpu_to_be32(x)

#endif /* _NTFS_ENDIANS_H */

#ifndef FALSE
enum { FALSE, TRUE } ;
#endif /* FALSE */

#ifdef WIN32

typedef unsigned short uid_t;
typedef unsigned short gid_t;

#define UNICODE(c) ((unsigned short)(c))

#define __attribute__(x)

#else

#ifndef BOOL
typedef int BOOL;   /* Already defined in windows.h */
#endif /* BOOL */

#ifdef STSC

#define ENOTSUP 95

#endif /* STSC */

typedef u32 DWORD; /* must be 32 bits whatever the platform */
typedef DWORD *LPDWORD;

#define MS_NONE 0    /* no flag for mounting the device */
#define MS_RDONLY 1  /* flag for mounting the device read-only */

#endif /* WIN32 */

#if defined(WIN32) | defined(STSC)

/*
 *	On non-Linux computers, there is no mount and the user mapping
 *	if fetched from a real file (or a dummy one for self tests)
 */

#define NTFS_FIND_USID(map,uid,buf) ntfs_find_usid(map,uid,buf)
#define NTFS_FIND_GSID(map,gid,buf) ntfs_find_gsid(map,gid,buf)
#define NTFS_FIND_USER(map,usid) ntfs_find_user(map,usid)
#define NTFS_FIND_GROUP(map,gsid) ntfs_find_group(map,gsid)

#else

/*
 *	On Linux computers, there is a mount and the user mapping
 *	if either obtained through the mount process or fetched
 *	from a dummy file for self-tests
 */

#define NTFS_FIND_USID(map,uid,buf) (mappingtype != MAPEXTERN ? \
		ntfs_find_usid(map,uid,buf) : relay_find_usid(map,uid,buf))
#define NTFS_FIND_GSID(map,gid,buf) (mappingtype != MAPEXTERN ? \
		ntfs_find_gsid(map,gid,buf) : relay_find_gsid(map,gid,buf))
#define NTFS_FIND_USER(map,usid) (mappingtype != MAPEXTERN ? \
		ntfs_find_user(map,usid) : relay_find_user(map,usid))
#define NTFS_FIND_GROUP(map,gsid) (mappingtype != MAPEXTERN ? \
		ntfs_find_group(map,gsid) : relay_find_group(map,gsid))

#endif

/*
 *		A few name hijackings or definitions
 *	needed for using code from ntfs-3g
 */

#ifdef WIN32
#define ACL MY_ACL
#define SID MY_SID
#define ACCESS_ALLOWED_ACE MY_ACCESS_ALLOWED_ACE
#define ACCESS_DENIED_ACE MY_ACCESS_DENIED_ACE
#define FILE_ATTRIBUTE_REPARSE_POINT 0x400
#define IO_REPARSE_TAG_MOUNT_POINT 0xa0000003
#define IO_REPARSE_TAG_SYMLINK     0xa000000c
#else
#define SE_OWNER_DEFAULTED  const_cpu_to_le16(1)
#define SE_GROUP_DEFAULTED  const_cpu_to_le16(2)
#define SE_DACL_PRESENT     const_cpu_to_le16(4)
#define SE_SACL_PRESENT     const_cpu_to_le16(0x10)
#define SE_DACL_DEFAULTED   const_cpu_to_le16(8)
#define SE_SELF_RELATIVE    const_cpu_to_le16(0x8000)
#define SID_REVISION 1
#endif /* WIN32 */
#define SE_DACL_PROTECTED   const_cpu_to_le16(0x1000)
#define SE_SACL_PROTECTED   const_cpu_to_le16(0x2000)
#define SE_DACL_AUTO_INHERITED   const_cpu_to_le16(0x400)
#define SE_SACL_AUTO_INHERITED   const_cpu_to_le16(0x800)
#define SE_DACL_AUTO_INHERIT_REQ   cpu_to_le16(0x100)
#define SE_SACL_AUTO_INHERIT_REQ   cpu_to_le16(0x200)

typedef le16 ntfschar;

#define ntfs_log_error(args...) do { printf("** " args); if (!isatty(1)) fprintf(stderr,args); } while(0)

/*
 *		Struct to hold the input mapping file
 *	(private to this module)
 */

struct MAPLIST {
	struct MAPLIST *next;
	char *uidstr;		/* uid text from the same record */
	char *gidstr;		/* gid text from the same record */
	char *sidstr;		/* sid text from the same record */
	char maptext[LINESZ + 1];
};

/*
 *		A few dummy declarations needed for using code from security.c
 */

#define MFT_RECORD_IS_DIRECTORY const_cpu_to_le16(1)

struct SECURITY_DATA {
	u64 offset;
	char *attr;
	u32 hash;
	u32 length;
	unsigned int filecount:16;
	unsigned int mode:12;
	unsigned int flags:4;
} ;

		/* default security sub-authorities */
enum {
	DEFSECAUTH1 = -1153374643, /* 3141592653 */
	DEFSECAUTH2 = 589793238,
	DEFSECAUTH3 = 462843383,
	DEFSECBASE = 10000
};

#define OWNERID 1016
#define GROUPID 513


#define INSDS1 1
#define INSDS2 2
#define INSII 4
#define INSDH 8

#ifdef WIN32

typedef enum { RECSHOW, RECSET, RECSETPOSIX } RECURSE; 

#endif

/*
 *		A type large enough to hold any SID
 */

typedef char BIGSID[40];

/*
 *		Declarations for memory allocation checks
 */

struct CHKALLOC
   {
   struct CHKALLOC *next;
   void *alloc;
   const char *file;
   int line;
   size_t size;
   } ;

#if defined(WIN32) | defined(STSC)

#define S_ISVTX 01000
#define S_ISGID 02000
#define S_ISUID 04000
#define S_IXUSR 0100
#define S_IWUSR 0200
#define S_IRUSR 0400
#define S_IXGRP 010
#define S_IWGRP 020
#define S_IRGRP 040
#define S_IXOTH 001
#define S_IWOTH 002
#define S_IROTH 004

#endif

#ifdef WIN32
#else
/*
 *
 *   See http://msdn2.microsoft.com/en-us/library/aa379649.aspx
 */

typedef enum {
	DACL_SECURITY_INFORMATION = 4, // The DACL of the object is being referenced.
	SACL_SECURITY_INFORMATION = 8, // The SACL of the object is being referenced.
	LABEL_SECURITY_INFORMATION = 8, // The mandatory integrity label is being referenced.
	GROUP_SECURITY_INFORMATION = 2, // The primary group identifier of the object is being referenced.
	OWNER_SECURITY_INFORMATION = 1, // The owner identifier of the object is being referenced.
} SECURITY_INFORMATION;

#define STANDARD_RIGHTS_READ	  cpu_to_le32(0x20000)
#define STANDARD_RIGHTS_WRITE	  cpu_to_le32(0x20000)
#define STANDARD_RIGHTS_EXECUTE   cpu_to_le32(0x20000)
#define STANDARD_RIGHTS_REQUIRED  cpu_to_le32(0xf0000)

#endif

typedef struct SECHEAD {
	s8 revision;
	s8 alignment;
	le16 control;
	le32 owner;
	le32 group;
	le32 sacl;
	le32 dacl;
} SECURITY_DESCRIPTOR_RELATIVE;

typedef struct ACL {
	s8 revision;
	s8 alignment1;
	le16 size;
	le16 ace_count;
	le16 alignment2;
} ACL;

typedef struct {
	union {
		struct {
			unsigned char revision;
			unsigned char sub_authority_count;
		} ;
		struct {
			/* evade an alignment problem when a 4 byte field  */
			/* in a struct implies alignment of the struct */
			le16 dummy;
			be16 high_part;
			be32 low_part;
		} identifier_authority;
	} ;
	le32 sub_authority[1];
} SID;

typedef u8 ACE_FLAGS;

typedef struct ACE {
	u8 type;
	u8 flags;
	le16 size;
	le32 mask;
	SID sid;
} ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE;


/*
 *          item in the mapping list
 */

struct MAPPING {
	struct MAPPING *next;
	int xid;		/* linux id : uid or gid */
	SID *sid;		/* Windows id : usid or gsid */
	int grcnt;		/* group count (for users only) */
	gid_t *groups;		/* groups which the user is member of */
};

/*
 *		       Posix ACL structures
 */

struct POSIX_ACE {
	u16 tag;
	u16 perms;
	s32 id;
} ;

struct POSIX_ACL {
	u8 version;
	u8 flags;
	u16 filler;
	struct POSIX_ACE ace[0];
} ;

struct POSIX_SECURITY {
	mode_t mode;
	int acccnt;
	int defcnt;
	int firstdef;
	u16 tagsset;
	struct POSIX_ACL acl;
} ;

/*
 *		Posix tags, cpu-endian 16 bits
 */

enum {
	POSIX_ACL_USER_OBJ =	1,
	POSIX_ACL_USER =	2,
	POSIX_ACL_GROUP_OBJ =	4,
	POSIX_ACL_GROUP =	8,
	POSIX_ACL_MASK =	16,
	POSIX_ACL_OTHER =	32,
	POSIX_ACL_SPECIAL =	64  /* internal use only */
} ;

/*
 *		Posix permissions, cpu-endian 16 bits
 */

enum {
	POSIX_PERM_X =		1,
	POSIX_PERM_W =		2,
	POSIX_PERM_R =		4,
	POSIX_PERM_DENIAL =	64 /* internal use only */
} ;

#define POSIX_VERSION 2

/*
 *		 A few definitions adapted from winnt.h
 *	    (Windows version uses actual definitions from winnt.h, which are
 *	     not compatible with code from security.c on a big-endian computer)
 */

#ifndef WIN32

#define DELETE				 cpu_to_le32(0x00010000L)
#define READ_CONTROL			 cpu_to_le32(0x00020000L)
#define WRITE_DAC			 cpu_to_le32(0x00040000L)
#define WRITE_OWNER			 cpu_to_le32(0x00080000L)
#define SYNCHRONIZE			 cpu_to_le32(0x00100000L)


#define FILE_READ_DATA		  cpu_to_le32( 0x0001 )    // file & pipe
#define FILE_LIST_DIRECTORY	  cpu_to_le32( 0x0001 )    // directory

#define FILE_WRITE_DATA 	  cpu_to_le32( 0x0002 )    // file & pipe
#define FILE_ADD_FILE		  cpu_to_le32( 0x0002 )    // directory

#define FILE_APPEND_DATA	  cpu_to_le32( 0x0004 )    // file
#define FILE_ADD_SUBDIRECTORY	  cpu_to_le32( 0x0004 )    // directory
#define FILE_CREATE_PIPE_INSTANCE cpu_to_le32( 0x0004 )    // named pipe


#define FILE_READ_EA		  cpu_to_le32( 0x0008 )    // file & directory

#define FILE_WRITE_EA		  cpu_to_le32( 0x0010 )    // file & directory

#define FILE_EXECUTE		  cpu_to_le32( 0x0020 )    // file
#define FILE_TRAVERSE		  cpu_to_le32( 0x0020 )    // directory

#define FILE_DELETE_CHILD	  cpu_to_le32( 0x0040 )    // directory

#define FILE_READ_ATTRIBUTES	  cpu_to_le32( 0x0080 )    // all

#define FILE_WRITE_ATTRIBUTES	  cpu_to_le32( 0x0100 )    // all

#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
				 cpu_to_le32(0x1FF))

#define FILE_GENERIC_READ	  (STANDARD_RIGHTS_READ     |\
				   FILE_READ_DATA	    |\
				   FILE_READ_ATTRIBUTES     |\
				   FILE_READ_EA 	    |\
				   SYNCHRONIZE)


#define FILE_GENERIC_WRITE	  (STANDARD_RIGHTS_WRITE    |\
				   FILE_WRITE_DATA	    |\
				   FILE_WRITE_ATTRIBUTES    |\
				   FILE_WRITE_EA	    |\
				   FILE_APPEND_DATA	    |\
				   SYNCHRONIZE)


#define FILE_GENERIC_EXECUTE	  (STANDARD_RIGHTS_EXECUTE  |\
				   FILE_READ_ATTRIBUTES     |\
				   FILE_EXECUTE 	    |\
				   SYNCHRONIZE)

#define GENERIC_READ			 cpu_to_le32(0x80000000L)
#define GENERIC_WRITE			 cpu_to_le32(0x40000000L)
#define GENERIC_EXECUTE 		 cpu_to_le32(0x20000000L)
#define GENERIC_ALL	 		 cpu_to_le32(0x10000000L)


#define OBJECT_INHERIT_ACE		  (0x1)
#define CONTAINER_INHERIT_ACE		  (0x2)
#define NO_PROPAGATE_INHERIT_ACE	  (0x4)
#define INHERIT_ONLY_ACE		  (0x8)
#define INHERITED_ACE			  (0x10)
#define VALID_INHERIT_FLAGS		  (0x1F)

/*
 *	     Other useful definitions
 */

#define ACL_REVISION 2
#define ACCESS_ALLOWED_ACE_TYPE 0
#define ACCESS_DENIED_ACE_TYPE 1
#define SECURITY_DESCRIPTOR_REVISION 1

#endif /* !WIN32 */

#ifndef ACL_REVISION_DS	/* not always defined in <windows.h> */
#define ACL_REVISION_DS 4
#endif

#ifndef INHERITED_ACE /* not always defined in <windows.h> */
#define INHERITED_ACE			  (0x10)
#undef VALID_INHERIT_FLAGS
#define VALID_INHERIT_FLAGS		  (0x1F)
#endif

/*
 *		Matching of ntfs permissions to Linux permissions
 *	these constants are adapted to endianness
 *	when setting, set them all
 *	when checking, check one is present
 */

          /* flags which are set to mean exec, write or read */

#define FILE_READ (FILE_READ_DATA)
#define FILE_WRITE (FILE_WRITE_DATA | FILE_APPEND_DATA \
		| READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA)
#define FILE_EXEC (FILE_EXECUTE)
#define DIR_READ FILE_LIST_DIRECTORY
#define DIR_WRITE (FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD \
	 	| READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA)
#define DIR_EXEC (FILE_TRAVERSE)

          /* flags tested for meaning exec, write or read */
	  /* tests for write allow for interpretation of a sticky bit */

#define FILE_GREAD (FILE_READ_DATA | GENERIC_READ)
#define FILE_GWRITE (FILE_WRITE_DATA | FILE_APPEND_DATA | GENERIC_WRITE)
#define FILE_GEXEC (FILE_EXECUTE | GENERIC_EXECUTE)
#define DIR_GREAD (FILE_LIST_DIRECTORY | GENERIC_READ)
#define DIR_GWRITE (FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | GENERIC_WRITE)
#define DIR_GEXEC (FILE_TRAVERSE | GENERIC_EXECUTE)

	/* standard owner (and administrator) rights */

#define OWNER_RIGHTS (DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER \
			| SYNCHRONIZE \
			| FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES \
			| FILE_READ_EA | FILE_WRITE_EA)

	/* standard world rights */

#define WORLD_RIGHTS (READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_EA \
			| SYNCHRONIZE)

          /* inheritance flags for files and directories */

#define FILE_INHERITANCE NO_PROPAGATE_INHERIT_ACE
#define DIR_INHERITANCE (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE)

/*
 *		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.
 */

#define ROOT_OWNER_UNMARK SYNCHRONIZE	/* ACL granted to root as owner */
#define ROOT_GROUP_UNMARK FILE_READ_EA	/* ACL granted to root as group */


struct SII {		/* this is an image of an $SII index entry */
	le16 offs;
	le16 size;
	le32 fill1;
	le16 indexsz;
	le16 indexksz;
	le16 flags;
	le16 fill2;
	le32 keysecurid;

	/* did not find official description for the following */
	le32 hash;
	le32 securid;
	le32 dataoffsl;	/* documented as badly aligned */
	le32 dataoffsh;
	le32 datasize;
} ;

struct SDH {		/* this is an image of an $SDH index entry */
	le16 offs;
	le16 size;
	le32 fill1;
	le16 indexsz;
	le16 indexksz;
	le16 flags;
	le16 fill2;
	le32 keyhash;
	le32 keysecurid;

	/* did not find official description for the following */
	le32 hash;
	le32 securid;
	le32 dataoffsl;
	le32 dataoffsh;
	le32 datasize;
	le32 fill3;
	} ;

#ifndef INVALID_FILE_ATTRIBUTES     /* not defined in old windows.h */
#define INVALID_FILE_ATTRIBUTES (-1)
#endif

enum { MAPUSERS, MAPGROUPS, MAPCOUNT } ;

struct SECURITY_CONTEXT {
	struct MAPPING *mapping[MAPCOUNT];
} ;

typedef enum { MAPNONE, MAPEXTERN, MAPLOCAL, MAPDUMMY } MAPTYPE;



struct passwd {
	uid_t pw_uid;
} ;

struct group {
	gid_t gr_gid;
} ;

typedef int (*FILEREADER)(void *fileid, char *buf, size_t size, off_t pos);

/*
 *		Data defined in secaudit.c
 */

extern MAPTYPE mappingtype;

/*
 *		Functions defined in acls.c
 */

BOOL ntfs_valid_descr(const char *securattr, unsigned int attrsz);
BOOL ntfs_valid_posix(const struct POSIX_SECURITY *pxdesc);
BOOL ntfs_valid_pattern(const SID *sid);
BOOL ntfs_same_sid(const SID *first, const SID *second);


int ntfs_sid_size(const SID * sid);
unsigned int ntfs_attr_size(const char *attr);

const SID *ntfs_find_usid(const struct MAPPING *usermapping,
			uid_t uid, SID *pdefsid);
const SID *ntfs_find_gsid(const struct MAPPING *groupmapping,
			gid_t gid, SID *pdefsid);
uid_t ntfs_find_user(const struct MAPPING *usermapping, const SID *usid);
gid_t ntfs_find_group(const struct MAPPING *groupmapping, const SID * gsid);
const SID *ntfs_acl_owner(const char *secattr);

void ntfs_sort_posix(struct POSIX_SECURITY *pxdesc);
int ntfs_merge_mode_posix(struct POSIX_SECURITY *pxdesc, mode_t mode);


struct POSIX_SECURITY *ntfs_build_permissions_posix(
			struct MAPPING* const mapping[],
			const char *securattr,
			const SID *usid, const SID *gsid, BOOL isdir);
int ntfs_build_permissions(const char *securattr,
			const SID *usid, const SID *gsid, BOOL isdir);
struct MAPLIST *ntfs_read_mapping(FILEREADER reader, void *fileid);
struct MAPPING *ntfs_do_user_mapping(struct MAPLIST *firstitem);
struct MAPPING *ntfs_do_group_mapping(struct MAPLIST *firstitem);
void ntfs_free_mapping(struct MAPPING *mapping[]);

struct POSIX_SECURITY *ntfs_merge_descr_posix(const struct POSIX_SECURITY *first,
			const struct POSIX_SECURITY *second);
char *ntfs_build_descr_posix(struct MAPPING* const mapping[],
			struct POSIX_SECURITY *pxdesc,
			int isdir, const SID *usid, const SID *gsid);
char *ntfs_build_descr(mode_t mode,
			int isdir, const SID * usid, const SID * gsid);

/*
 *		Functions defined in secaudit.c
 */

void *chkmalloc(size_t, const char*, int);
void *chkcalloc(size_t, size_t, const char *, int);
void chkfree(void*, const char*, int);
BOOL chkisalloc(void*, const char*, int);
void dumpalloc(const char*);

#define malloc(sz) chkmalloc(sz, __FILE__, __LINE__)
#define calloc(cnt,sz) chkcalloc(cnt, sz, __FILE__, __LINE__)
#define free(ptr) chkfree(ptr, __FILE__, __LINE__)
#define isalloc(ptr) chkisalloc(ptr, __FILE__, __LINE__)
#define ntfs_malloc(sz) chkmalloc(sz, __FILE__, __LINE__)

struct passwd *getpwnam(const char *user);
struct group *getgrnam(const char *group);

const SID *relay_find_usid(const struct MAPPING *usermapping,
			uid_t uid, SID *pdefsid);
const SID *relay_find_gsid(const struct MAPPING *groupmapping,
			gid_t gid, SID *pdefsid);
uid_t relay_find_user(const struct MAPPING *usermapping, const SID *usid);
gid_t relay_find_group(const struct MAPPING *groupmapping, const SID * gsid);

