root/src/add-ons/kernel/file_systems/ntfs/libntfs/security.h
/*
 * security.h - Exports for handling security/ACLs in NTFS.  
 *              Originated from the Linux-NTFS project.
 *
 * Copyright (c) 2004      Anton Altaparmakov
 * Copyright (c) 2005-2006 Szabolcs Szakacsits
 * Copyright (c) 2007-2010 Jean-Pierre Andre
 *
 * This program/include file is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program/include file 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
 */

#ifndef _NTFS_SECURITY_H
#define _NTFS_SECURITY_H

#include "types.h"
#include "layout.h"
#include "inode.h"
#include "dir.h"
#include "endians.h"

#ifndef POSIXACLS
#define POSIXACLS 0
#endif

/*
 *          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 */
};

/*
 *              Entry in the permissions cache
 *      Note : this cache is not organized as a generic cache
 */

struct CACHED_PERMISSIONS {
        uid_t uid;
        gid_t gid;
        le32 inh_fileid;
        le32 inh_dirid;
#if POSIXACLS
        struct POSIX_SECURITY *pxdesc;
        unsigned int pxdescsize:16;
#endif
        unsigned int mode:12;
        unsigned int valid:1;
} ;

/*
 *      Entry in the permissions cache for directories with no security_id
 */

struct CACHED_PERMISSIONS_LEGACY {
        struct CACHED_PERMISSIONS_LEGACY *next;
        struct CACHED_PERMISSIONS_LEGACY *previous;
        void *variable;
        size_t varsize;
        union ALIGNMENT payload[0];
                /* above fields must match "struct CACHED_GENERIC" */
        u64 mft_no;
        struct CACHED_PERMISSIONS perm;
} ;

/*
 *      Entry in the securid cache
 */

struct CACHED_SECURID {
        struct CACHED_SECURID *next;
        struct CACHED_SECURID *previous;
        void *variable;
        size_t varsize;
        union ALIGNMENT payload[0];
                /* above fields must match "struct CACHED_GENERIC" */
        uid_t uid;
        gid_t gid;
        unsigned int dmode;
        le32 securid;
} ;

/*
 *      Header of the security cache
 *      (has no cache structure by itself)
 */

struct CACHED_PERMISSIONS_HEADER {
        unsigned int last;
                        /* statistics for permissions */
        unsigned long p_writes;
        unsigned long p_reads;
        unsigned long p_hits;
} ;

/*
 *      The whole permissions cache
 */

struct PERMISSIONS_CACHE {
        struct CACHED_PERMISSIONS_HEADER head;
        struct CACHED_PERMISSIONS *cachetable[1]; /* array of variable size */
} ;

/*
 *      Security flags values
 */

enum {
        SECURITY_DEFAULT,       /* rely on fuse for permissions checking */
        SECURITY_RAW,           /* force same ownership/permissions on files */
        SECURITY_ACL,           /* enable Posix ACLs (when compiled in) */
        SECURITY_ADDSECURIDS,   /* upgrade old security descriptors */
        SECURITY_STATICGRPS,    /* use static groups for access control */
        SECURITY_WANTED         /* a security related option was present */
} ;

/*
 *      Security context, needed by most security functions
 */

enum { MAPUSERS, MAPGROUPS, MAPCOUNT } ;

struct SECURITY_CONTEXT {
        ntfs_volume *vol;
        struct MAPPING *mapping[MAPCOUNT];
        struct PERMISSIONS_CACHE **pseccache;
        uid_t uid; /* uid of user requesting (not the mounter) */
        gid_t gid; /* gid of user requesting (not the mounter) */
        pid_t tid; /* thread id of thread requesting */
        mode_t umask; /* umask of requesting thread */
        } ;

#if POSIXACLS

/*
 *                     Posix ACL structures
 */
  
struct POSIX_ACE {
        u16 tag;
        u16 perms;
        s32 id;   
} __attribute__((__packed__));
        
struct POSIX_ACL {
        u8 version;
        u8 flags;
        u16 filler;
        struct POSIX_ACE ace[0];
} __attribute__((__packed__));

struct POSIX_SECURITY {
        mode_t mode;
        int acccnt;
        int defcnt;
        int firstdef;
        u16 tagsset;
        u16 filler;
        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 */
} ;

#define POSIX_ACL_EXTENSIONS (POSIX_ACL_USER | POSIX_ACL_GROUP | POSIX_ACL_MASK)
        
/*
 *              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

#endif

extern BOOL ntfs_guid_is_zero(const GUID *guid);
extern char *ntfs_guid_to_mbs(const GUID *guid, char *guid_str);

extern int ntfs_sid_to_mbs_size(const SID *sid);
extern char *ntfs_sid_to_mbs(const SID *sid, char *sid_str,
                size_t sid_str_size);
extern void ntfs_generate_guid(GUID *guid);
extern int ntfs_sd_add_everyone(ntfs_inode *ni);

extern le32 ntfs_security_hash(const SECURITY_DESCRIPTOR_RELATIVE *sd, 
                               const u32 len);

int ntfs_build_mapping(struct SECURITY_CONTEXT *scx, const char *usermap_path,
                BOOL allowdef);
int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx,
                ntfs_inode *ni, struct stat*);
int ntfs_set_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, mode_t mode);
BOOL ntfs_allowed_as_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni);
int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
                ntfs_inode *ni, int accesstype);
int ntfs_allowed_create(struct SECURITY_CONTEXT *scx,
                ntfs_inode *ni, gid_t *pgid, mode_t *pdsetgid);
BOOL old_ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
                const char *path, int accesstype);

#if POSIXACLS
le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx,
                uid_t uid, gid_t gid, ntfs_inode *dir_ni,
                mode_t mode, BOOL isdir);
#else
le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx,
                uid_t uid, gid_t gid, mode_t mode, BOOL isdir);
#endif
int ntfs_set_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
                uid_t uid, gid_t gid);
int ntfs_set_ownmod(struct SECURITY_CONTEXT *scx,
                ntfs_inode *ni, uid_t uid, gid_t gid, mode_t mode);
#if POSIXACLS
int ntfs_set_owner_mode(struct SECURITY_CONTEXT *scx,
                ntfs_inode *ni, uid_t uid, gid_t gid,
                mode_t mode, struct POSIX_SECURITY *pxdesc);
#else
int ntfs_set_owner_mode(struct SECURITY_CONTEXT *scx,
                ntfs_inode *ni, uid_t uid, gid_t gid, mode_t mode);
#endif
le32 ntfs_inherited_id(struct SECURITY_CONTEXT *scx,
                ntfs_inode *dir_ni, BOOL fordir);
int ntfs_open_secure(ntfs_volume *vol);
int ntfs_close_secure(ntfs_volume *vol);

void ntfs_destroy_security_context(struct SECURITY_CONTEXT *scx);

#if POSIXACLS

int ntfs_set_inherited_posix(struct SECURITY_CONTEXT *scx,
                ntfs_inode *ni, uid_t uid, gid_t gid,
                ntfs_inode *dir_ni, mode_t mode);
int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
                        const char *name, char *value, size_t size);
int ntfs_set_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
                        const char *name, const char *value, size_t size,
                        int flags);
int ntfs_remove_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
                        const char *name);
#endif

int ntfs_get_ntfs_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
                        char *value, size_t size);
int ntfs_set_ntfs_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
                        const char *value, size_t size, int flags); 

int ntfs_get_ntfs_attrib(ntfs_inode *ni, char *value, size_t size);
int ntfs_set_ntfs_attrib(ntfs_inode *ni,
                        const char *value, size_t size, int flags);
                        

/*
 *              Security API for direct access to security descriptors
 *      based on Win32 API
 */

#define MAGIC_API 0x09042009

struct SECURITY_API {
        u32 magic;
        struct SECURITY_CONTEXT security;
        struct PERMISSIONS_CACHE *seccache;
} ;

/*
 *  The following constants are used in interfacing external programs.
 *  They are not to be stored on disk and must be defined in their
 *  native cpu representation.
 *  When disk representation (le) is needed, use SE_DACL_PRESENT, etc.
 */
enum {  OWNER_SECURITY_INFORMATION = 1,
        GROUP_SECURITY_INFORMATION = 2,
        DACL_SECURITY_INFORMATION = 4,
        SACL_SECURITY_INFORMATION = 8
} ;

int ntfs_get_file_security(struct SECURITY_API *scapi,
                const char *path, u32 selection,  
                char *buf, u32 buflen, u32 *psize);
int ntfs_set_file_security(struct SECURITY_API *scapi,
                const char *path, u32 selection, const char *attr);
int ntfs_get_file_attributes(struct SECURITY_API *scapi,
                const char *path);
BOOL ntfs_set_file_attributes(struct SECURITY_API *scapi,
                const char *path, s32 attrib);
BOOL ntfs_read_directory(struct SECURITY_API *scapi,
                const char *path, ntfs_filldir_t callback, void *context);
int ntfs_read_sds(struct SECURITY_API *scapi,
                char *buf, u32 size, u32 offset);
INDEX_ENTRY *ntfs_read_sii(struct SECURITY_API *scapi,
                INDEX_ENTRY *entry);
INDEX_ENTRY *ntfs_read_sdh(struct SECURITY_API *scapi,
                INDEX_ENTRY *entry);
struct SECURITY_API *ntfs_initialize_file_security(const char *device,
                                unsigned long flags);
BOOL ntfs_leave_file_security(struct SECURITY_API *scx);

int ntfs_get_usid(struct SECURITY_API *scapi, uid_t uid, char *buf);
int ntfs_get_gsid(struct SECURITY_API *scapi, gid_t gid, char *buf);
int ntfs_get_user(struct SECURITY_API *scapi, const SID *usid);
int ntfs_get_group(struct SECURITY_API *scapi, const SID *gsid);

#endif /* defined _NTFS_SECURITY_H */