Exemplo n.º 1
0
static char *search_absolute(ntfs_volume *vol, ntfschar *path,
				int count, BOOL isdir)
{
	ntfs_inode *ni;
	u64 inum;
	char *target;
	int start;
	int len;

	target = (char*)NULL; /* default return */
	ni = ntfs_inode_open(vol, (MFT_REF)FILE_root);
	if (ni) {
		start = 0;
		/*
		 * Examine and translate the path, until we reach either
		 *  - the end,
		 *  - an unknown item
		 *  - a non-directory
		 *  - another reparse point,
		 * A reparse point is not dereferenced, it will be
		 * examined later when the translated path is dereferenced,
		 * however the final part of the path will not be adjusted
		 * to correct case.
		 */
		do {
			len = 0;
			while (((start + len) < count)
			    && (path[start + len] != const_cpu_to_le16('\\')))
				len++;
			inum = ntfs_fix_file_name(ni, &path[start], len);
			ntfs_inode_close(ni);
			ni = (ntfs_inode*)NULL;
			if (inum != (u64)-1) {
				inum = MREF(inum);
				ni = ntfs_inode_open(vol, inum);
				start += len;
				if (start < count)
					path[start++] = const_cpu_to_le16('/');
			}
		} while (ni
		    && (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
		    && !(ni->flags & FILE_ATTR_REPARSE_POINT)
		    && (start < count));
	if (ni
	    && ((ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ? isdir : !isdir)
		|| (ni->flags & FILE_ATTR_REPARSE_POINT)))
		if (ntfs_ucstombs(path, count, &target, 0) < 0) {
			if (target) {
				free(target);
				target = (char*)NULL;
			}
		}
	if (ni)
		ntfs_inode_close(ni);
	}
	return (target);
}
Exemplo n.º 2
0
/**
 * change_label - change the current label on a device
 * @dev:	device to change the label on
 * @mnt_flags:	mount flags of the device or 0 if not mounted
 * @mnt_point:	mount point of the device or NULL
 * @label:	the new label
 *
 * Change the label on the device @dev to @label.
 */
static int change_label(ntfs_volume *vol, char *label)
{
	ntfschar *new_label = NULL;
	int label_len;
	int result = 0;

	label_len = ntfs_mbstoucs(label, &new_label);
	if (label_len == -1) {
		ntfs_log_perror("Unable to convert label string to Unicode");
		return 1;
	}
	else if (label_len*sizeof(ntfschar) > 0x100) {
		ntfs_log_warning("New label is too long. Maximum %u characters "
				"allowed. Truncating %u excess characters.\n",
				(unsigned)(0x100 / sizeof(ntfschar)),
				(unsigned)(label_len -
				(0x100 / sizeof(ntfschar))));
		label_len = 0x100 / sizeof(ntfschar);
		label[label_len] = const_cpu_to_le16(0);
	}

	if(!opts.noaction)
		result = ntfs_volume_rename(vol, new_label, label_len) ? 1 : 0;

	free(new_label);
	return result;
}
Exemplo n.º 3
0
static char *search_absolute(ntfs_volume *vol, ntfschar *path,
				int count, BOOL isdir)
{
	ntfs_inode *ni;
	u64 inum;
	char *target;
	int start;
	int len;

	target = (char*)NULL; /* default return */
	ni = ntfs_inode_open(vol, (MFT_REF)FILE_root);
	if (ni) {
		start = 0;
		do {
			len = 0;
			while (((start + len) < count)
			    && (path[start + len] != const_cpu_to_le16('\\')))
				len++;
			inum = ntfs_fix_file_name(ni, &path[start], len);
			ntfs_inode_close(ni);
			ni = (ntfs_inode*)NULL;
			if (inum != (u64)-1) {
				inum = MREF(inum);
				ni = ntfs_inode_open(vol, inum);
				start += len;
				if (start < count)
					path[start++] = const_cpu_to_le16('/');
			}
		} while (ni
		    && (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
		    && (start < count));
	if (ni
	    && (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ? isdir : !isdir))
		if (ntfs_ucstombs(path, count, &target, 0) < 0) {
			if (target) {
				free(target);
				target = (char*)NULL;
			}
		}
	if (ni)
		ntfs_inode_close(ni);
	}
	return (target);
}
Exemplo n.º 4
0
static void erase_callback(struct erase_info *erase)
{
	struct partition *part;
	u16 magic;
	int i, rc;
	size_t retlen;

	part = (struct partition*)erase->priv;

	i = erase->addr / part->block_size;
	if (i >= part->total_blocks || part->blocks[i].offset != erase->addr) {
		printk(KERN_ERR PREFIX "erase callback for unknown offset %x "
				"on '%s'\n", erase->addr, part->mbd.mtd->name);
		return;
	}

	if (erase->state != MTD_ERASE_DONE) {
		printk(KERN_WARNING PREFIX "erase failed at 0x%x on '%s', "
				"state %d\n", erase->addr,
				part->mbd.mtd->name, erase->state);

		part->blocks[i].state = BLOCK_FAILED;
		part->blocks[i].free_sectors = 0;
		part->blocks[i].used_sectors = 0;

		kfree(erase);

		return;
	}

	magic = const_cpu_to_le16(RFD_MAGIC);

	part->blocks[i].state = BLOCK_ERASED;
	part->blocks[i].free_sectors = part->data_sectors_per_block;
	part->blocks[i].used_sectors = 0;
	part->blocks[i].erases++;

	rc = part->mbd.mtd->write(part->mbd.mtd,
		part->blocks[i].offset, sizeof(magic), &retlen,
		(u_char*)&magic);

	if (!rc && retlen != sizeof(magic))
		rc = -EIO;

	if (rc) {
		printk(KERN_NOTICE PREFIX "'%s': unable to write RFD "
				"header at 0x%lx\n",
				part->mbd.mtd->name,
				part->blocks[i].offset);
		part->blocks[i].state = BLOCK_FAILED;
	}
	else
		part->blocks[i].state = BLOCK_OK;

	kfree(erase);
}
Exemplo n.º 5
0
static int set_reparse_index(ntfs_inode *ni, ntfs_index_context *xr,
			le32 reparse_tag)
{
	struct REPARSE_INDEX indx;
	u64 file_id_cpu;
	le64 file_id;
	le16 seqn;

	seqn = ni->mrec->sequence_number;
	file_id_cpu = MK_MREF(ni->mft_no,le16_to_cpu(seqn));
	file_id = cpu_to_le64(file_id_cpu);
	indx.header.data_offset = const_cpu_to_le16(
					sizeof(INDEX_ENTRY_HEADER)
					+ sizeof(REPARSE_INDEX_KEY));
	indx.header.data_length = const_cpu_to_le16(0);
	indx.header.reservedV = const_cpu_to_le32(0);
	indx.header.length = const_cpu_to_le16(
					sizeof(struct REPARSE_INDEX));
	indx.header.key_length = const_cpu_to_le16(
					sizeof(REPARSE_INDEX_KEY));
	indx.header.flags = const_cpu_to_le16(0);
	indx.header.reserved = const_cpu_to_le16(0);
	indx.key.reparse_tag = reparse_tag;
		/* danger on processors which require proper alignment ! */
	memcpy(&indx.key.file_id, &file_id, 8);
	indx.filling = const_cpu_to_le32(0);
	ntfs_index_ctx_reinit(xr);
	return (ntfs_ie_add(xr,(INDEX_ENTRY*)&indx));
}
Exemplo n.º 6
0
int cpu_to_le_acl(const struct POSIX_ACL *acl, size_t size,
			struct LE_POSIX_ACL *le_acl)
{
	int i;
	int cnt;

	le_acl->version = acl->version;
	le_acl->flags = acl->flags;
	le_acl->filler = const_cpu_to_le16(0);
	cnt = (size - sizeof(struct POSIX_ACL)) / sizeof(struct POSIX_ACE);
	for (i=0; i<cnt; i++) {
		le_acl->ace[i].tag = cpu_to_le16(acl->ace[i].tag);
		le_acl->ace[i].perms = cpu_to_le16(acl->ace[i].perms);
		le_acl->ace[i].id = cpu_to_le32(acl->ace[i].id);
	}
	return (0);
}
Exemplo n.º 7
0
/**
 * change_label - change the current label on a device
 * @dev:	device to change the label on
 * @mnt_flags:	mount flags of the device or 0 if not mounted
 * @mnt_point:	mount point of the device or NULL
 * @label:	the new label
 *
 * Change the label on the device @dev to @label.
 */
static int change_label(ntfs_volume *vol, unsigned long mnt_flags, char *label, BOOL force)
{
	ntfschar *new_label = NULL;
	int label_len;
	int result = 0;

	//XXX significant?
	if (mnt_flags & NTFS_MF_MOUNTED) {
		/* If not the root fs or mounted read/write, refuse change. */
		if (!(mnt_flags & NTFS_MF_ISROOT) ||
				!(mnt_flags & NTFS_MF_READONLY)) {
			if (!force) {
				ntfs_log_error("Refusing to change label on "
						"read-%s mounted device %s.\n",
						mnt_flags & NTFS_MF_READONLY ?
						"only" : "write", opts.device);
				return 1;
			}
		}
	}

	label_len = ntfs_mbstoucs(label, &new_label);
	if (label_len == -1) {
		ntfs_log_perror("Unable to convert label string to Unicode");
		return 1;
	}
	else if (label_len*sizeof(ntfschar) > 0x100) {
		ntfs_log_warning("New label is too long. Maximum %u characters "
				"allowed. Truncating %u excess characters.\n",
				(unsigned)(0x100 / sizeof(ntfschar)),
				(unsigned)(label_len -
				(0x100 / sizeof(ntfschar))));
		label_len = 0x100 / sizeof(ntfschar);
		label[label_len] = const_cpu_to_le16(0);
	}

	if(!opts.noaction)
		result = ntfs_volume_rename(vol, new_label, label_len) ? 1 : 0;

	free(new_label);
	return result;
}
Exemplo n.º 8
0
static int mark_sector_deleted(struct partition *part, u_long old_addr)
{
	int block, offset, rc;
	u_long addr;
	size_t retlen;
	u16 del = const_cpu_to_le16(SECTOR_DELETED);

	block = old_addr / part->block_size;
	offset = (old_addr % part->block_size) / SECTOR_SIZE -
		part->header_sectors_per_block;

	addr = part->blocks[block].offset +
			(HEADER_MAP_OFFSET + offset) * sizeof(u16);
	rc = part->mbd.mtd->write(part->mbd.mtd, addr,
		sizeof(del), &retlen, (u_char*)&del);

	if (!rc && retlen != sizeof(del))
		rc = -EIO;

	if (rc) {
		printk(KERN_WARNING PREFIX "error writing '%s' at "
			"0x%lx\n", part->mbd.mtd->name, addr);
		if (rc)
			goto err;
	}
	if (block == part->current_block)
		part->header_cache[offset + HEADER_MAP_OFFSET] = del;

	part->blocks[block].used_sectors--;

	if (!part->blocks[block].used_sectors &&
	    !part->blocks[block].free_sectors)
		rc = erase_block(part, block);

err:
	return rc;
}
Exemplo n.º 9
0
static int set_object_id_index(ntfs_inode *ni, ntfs_index_context *xo,
			const OBJECT_ID_ATTR *object_id)
{
	struct OBJECT_ID_INDEX indx;
	u64 file_id_cpu;
	le64 file_id;
	le16 seqn;

	seqn = ni->mrec->sequence_number;
	file_id_cpu = MK_MREF(ni->mft_no,le16_to_cpu(seqn));
	file_id = cpu_to_le64(file_id_cpu);
	indx.header.data_offset = const_cpu_to_le16(
					sizeof(INDEX_ENTRY_HEADER)
					+ sizeof(OBJECT_ID_INDEX_KEY));
	indx.header.data_length = const_cpu_to_le16(
					sizeof(OBJECT_ID_INDEX_DATA));
	indx.header.reservedV = const_cpu_to_le32(0);
	indx.header.length = const_cpu_to_le16(
					sizeof(struct OBJECT_ID_INDEX));
	indx.header.key_length = const_cpu_to_le16(
					sizeof(OBJECT_ID_INDEX_KEY));
	indx.header.flags = const_cpu_to_le16(0);
	indx.header.reserved = const_cpu_to_le16(0);

	memcpy(&indx.key.object_id,object_id,sizeof(GUID));

	indx.data.file_id = file_id;
	memcpy(&indx.data.birth_volume_id,
			&object_id->birth_volume_id,sizeof(GUID));
	memcpy(&indx.data.birth_object_id,
			&object_id->birth_object_id,sizeof(GUID));
	memcpy(&indx.data.domain_id,
			&object_id->domain_id,sizeof(GUID));
	ntfs_index_ctx_reinit(xo);
	return (ntfs_ie_add(xo,(INDEX_ENTRY*)&indx));
}
Exemplo n.º 10
0
static char *ntfs_get_abslink(ntfs_volume *vol, ntfschar *junction,
			int count, const char *mnt_point, BOOL isdir)
{
	char *target;
	char *fulltarget;
	int sz;
	char *q;
	enum { FULL_PATH, ABS_PATH, REJECTED_PATH } kind;

	target = (char*)NULL;
	fulltarget = (char*)NULL;
			/*
			 * For a full valid path we want x:\
			 * where \ is an individual char and x a non-null char
			 */
	if ((count >= 3)
	    && junction[0]
	    && (junction[1] == const_cpu_to_le16(':'))
	    && (junction[2] == const_cpu_to_le16('\\')))
		kind = FULL_PATH;
	else
			/*
			 * For an absolute path we want an initial \
			 */
		if ((count >= 0)
		    && (junction[0] == const_cpu_to_le16('\\')))
			kind = ABS_PATH;
		else
			kind = REJECTED_PATH;
			/*
			 * Full path, with a drive letter and
			 * no specific definition for the drive letter :
			 * try to interpret as a target on the same volume.
			 * Do the same for an abs path with no drive letter.
			 */
	if (((kind == FULL_PATH)
	    && (count >= 3)
	    && junction[3]
	    && !ntfs_drive_letter(vol, junction[0]))
	    || (kind == ABS_PATH)) {
		if (kind == ABS_PATH)
			target = search_absolute(vol, &junction[1],
				count - 1, isdir);
		else
			target = search_absolute(vol, &junction[3],
				count - 3, isdir);
		if (target) {
			fulltarget = (char*)ntfs_malloc(strlen(mnt_point)
					+ strlen(target) + 2);
			if (fulltarget) {
				strcpy(fulltarget,mnt_point);
				strcat(fulltarget,"/");
				strcat(fulltarget,target);
			}
			free(target);
		}
	}
			/*
			 * full path with target not found on current volume :
			 * link to /.NTFS-3G/target which the user can
			 * define as a symbolic link to the real target
			 */
	if ((kind == FULL_PATH) && !fulltarget) {
		sz = ntfs_ucstombs(&junction[0],
			count,&target, 0);
		if ((sz > 0) && target) {
				/* reverse slashes */
			for (q=target; *q; q++)
				if (*q == '\\')
					*q = '/';
				/* force uppercase drive letter */
			if ((target[1] == ':')
			    && (target[0] >= 'a')
			    && (target[0] <= 'z'))
				target[0] += 'A' - 'a';
			fulltarget = (char*)ntfs_malloc(strlen(mnt_point)
				    + sizeof(mappingdir) + strlen(target) + 1);
			if (fulltarget) {
				strcpy(fulltarget,mnt_point);
				strcat(fulltarget,"/");
				strcat(fulltarget,mappingdir);
				strcat(fulltarget,target);
			}
		}
		if (target)
			free(target);
	}
	return (fulltarget);
}
Exemplo n.º 11
0
static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
{
	char *target = (char*)NULL;
	ntfs_inode *curni;
	ntfs_inode *newni;
	u64 inum;
	int pos;
	int lth;
	BOOL ok;
	int max = 32; /* safety */

	pos = 0;
	ok = TRUE;
	curni = ntfs_dir_parent_inode(ni);
	while (curni && ok && (pos < (count - 1)) && --max) {
		if ((count >= (pos + 2))
		    && (path[pos] == const_cpu_to_le16('.'))
		    && (path[pos+1] == const_cpu_to_le16('\\'))) {
			path[1] = const_cpu_to_le16('/');
			pos += 2;
		} else {
			if ((count >= (pos + 3))
			    && (path[pos] == const_cpu_to_le16('.'))
			    &&(path[pos+1] == const_cpu_to_le16('.'))
			    && (path[pos+2] == const_cpu_to_le16('\\'))) {
				path[2] = const_cpu_to_le16('/');
				pos += 3;
				newni = ntfs_dir_parent_inode(curni);
				if (curni != ni)
					ntfs_inode_close(curni);
				curni = newni;
				if (!curni)
					ok = FALSE;
			} else {
				lth = 0;
				while (((pos + lth) < count)
				    && (path[pos + lth] != const_cpu_to_le16('\\')))
					lth++;
				if (lth > 0)
					inum = ntfs_fix_file_name(curni,&path[pos],lth);
				else
					inum = (u64)-1;
				if (!lth
				    || ((curni != ni)
					&& ntfs_inode_close(curni))
				    || (inum == (u64)-1))
					ok = FALSE;
				else {
					curni = ntfs_inode_open(ni->vol, MREF(inum));
					if (!curni)
						ok = FALSE;
					else {
						if (ok && ((pos + lth) < count)) {
							path[pos + lth] = const_cpu_to_le16('/');
							pos += lth + 1;
						} else {
							pos += lth;
							if ((ni->mrec->flags ^ curni->mrec->flags)
							    & MFT_RECORD_IS_DIRECTORY)
								ok = FALSE;
							if (ntfs_inode_close(curni))
								ok = FALSE;
						}
					}
				}
			}
		}
	}

	if (ok && (ntfs_ucstombs(path, count, &target, 0) < 0)) {
		free(target); // needed ?
		target = (char*)NULL;
	}
	return (target);
}
Exemplo n.º 12
0
struct options {
    char *keyfile;	/* .pfx file containing the user's private key. */
    char *device;		/* Device/File to work with */
    char *file;		/* File to display */
    s64 inode;		/* Inode to work with */
    ATTR_TYPES attr;	/* Attribute type to display */
    int force;		/* Override common sense */
    int quiet;		/* Less output */
    int verbose;		/* Extra output */
};

static const char *EXEC_NAME = "ntfsdecrypt";
static struct options opts;

static ntfschar EFS[5] = {
    const_cpu_to_le16('$'), const_cpu_to_le16('E'), const_cpu_to_le16('F'),
    const_cpu_to_le16('S'), const_cpu_to_le16('\0')
};

/**
 * version - Print version information about the program
 *
 * Print a copyright statement and a brief description of the program.
 *
 * Return:  none
 */
static void version(void)
{
    ntfs_log_info("\n%s v%s (libntfs-3g) - Decrypt files and print on the "
                  "standard output.\n\n", EXEC_NAME, VERSION);
    ntfs_log_info("Copyright (c) 2005 Yuval Fledel\n");
Exemplo n.º 13
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "types.h"
#include "layout.h"
#include "attrib.h"
#include "security.h"
#include "misc.h"
#include "bitmap.h"

/*
 * The zero GUID.
 */
static const GUID __zero_guid = { const_cpu_to_le32(0), const_cpu_to_le16(0),
		const_cpu_to_le16(0), { 0, 0, 0, 0, 0, 0, 0, 0 } };
const GUID *const zero_guid = &__zero_guid;

/**
 * ntfs_guid_is_zero - check if a GUID is zero
 * @guid:	[IN] guid to check
 *
 * Return TRUE if @guid is a valid pointer to a GUID and it is the zero GUID
 * and FALSE otherwise.
 */
BOOL ntfs_guid_is_zero(const GUID *guid)
{
	return (memcmp(guid, zero_guid, sizeof(*zero_guid)));
}
Exemplo n.º 14
0
Arquivo: sd.c Projeto: AllardJ/Tomato
/**
 * init_system_file_sd -
 *
 * NTFS 3.1 - System files security decriptors
 * =====================================================
 *
 * Create the security descriptor for system file number @sys_file_no and
 * return a pointer to the descriptor.
 *
 * Note the root directory system file (".") is very different and handled by a
 * different function.
 *
 * The sd is returned in *@sd_val and has length *@sd_val_len.
 *
 * Do NOT free *@sd_val as it is static memory. This also means that you can
 * only use *@sd_val until the next call to this function.
 */
void init_system_file_sd(int sys_file_no, u8 **sd_val, int *sd_val_len)
{
	static u8 sd_array[0x68];
	SECURITY_DESCRIPTOR_RELATIVE *sd;
	ACL *acl;
	ACCESS_ALLOWED_ACE *aa_ace;
	SID *sid;
	le32 *sub_authorities;

	if (sys_file_no < 0) {
		*sd_val = NULL;
		*sd_val_len = 0;
		return;
	}
	*sd_val = sd_array;
	sd = (SECURITY_DESCRIPTOR_RELATIVE*)&sd_array;
	sd->revision = 1;
	sd->alignment = 0;
	sd->control = SE_SELF_RELATIVE | SE_DACL_PRESENT;
	*sd_val_len = 0x64;
	sd->owner = const_cpu_to_le32(0x48);
	sd->group = const_cpu_to_le32(0x54);
	sd->sacl = const_cpu_to_le32(0);
	sd->dacl = const_cpu_to_le32(0x14);
	/*
	 * Now at offset 0x14, as specified in the security descriptor, we have
	 * the DACL.
	 */
	acl = (ACL*)((char*)sd + le32_to_cpu(sd->dacl));
	acl->revision = 2;
	acl->alignment1 = 0;
	acl->size = const_cpu_to_le16(0x34);
	acl->ace_count = const_cpu_to_le16(2);
	acl->alignment2 = const_cpu_to_le16(0);
	/*
	 * Now at offset 0x1c, just after the DACL's ACL, we have the first
	 * ACE of the DACL. The type of the ACE is access allowed.
	 */
	aa_ace = (ACCESS_ALLOWED_ACE*)((char*)acl + sizeof(ACL));
	aa_ace->type = ACCESS_ALLOWED_ACE_TYPE;
	aa_ace->flags = 0;
	aa_ace->size = const_cpu_to_le16(0x14);
	switch (sys_file_no) {
	case FILE_AttrDef:
	case FILE_Boot:
		aa_ace->mask = SYNCHRONIZE | STANDARD_RIGHTS_READ |
			FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_READ_DATA;
		break;
	default:
		aa_ace->mask = SYNCHRONIZE | STANDARD_RIGHTS_WRITE |
			FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES |
			FILE_WRITE_EA | FILE_READ_EA | FILE_APPEND_DATA |
			FILE_WRITE_DATA | FILE_READ_DATA;
		break;
	}
	aa_ace->sid.revision = 1;
	aa_ace->sid.sub_authority_count = 1;
	aa_ace->sid.identifier_authority.value[0] = 0;
	aa_ace->sid.identifier_authority.value[1] = 0;
	aa_ace->sid.identifier_authority.value[2] = 0;
	aa_ace->sid.identifier_authority.value[3] = 0;
	aa_ace->sid.identifier_authority.value[4] = 0;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	aa_ace->sid.identifier_authority.value[5] = 5;
	aa_ace->sid.sub_authority[0] =
			const_cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);
	/*
	 * Now at offset 0x30 within security descriptor, just after the first
	 * ACE of the DACL. All system files, except the root directory, have
	 * a second ACE.
	 */
	/* The second ACE of the DACL. Type is access allowed. */
	aa_ace = (ACCESS_ALLOWED_ACE*)((char*)aa_ace +
			le16_to_cpu(aa_ace->size));
	aa_ace->type = ACCESS_ALLOWED_ACE_TYPE;
	aa_ace->flags = 0;
	aa_ace->size = const_cpu_to_le16(0x18);
	/* Only $AttrDef and $Boot behave differently to everything else. */
	switch (sys_file_no) {
	case FILE_AttrDef:
	case FILE_Boot:
		aa_ace->mask = SYNCHRONIZE | STANDARD_RIGHTS_READ |
				FILE_READ_ATTRIBUTES | FILE_READ_EA |
				FILE_READ_DATA;
		break;
	default:
		aa_ace->mask = SYNCHRONIZE | STANDARD_RIGHTS_READ |
				FILE_WRITE_ATTRIBUTES |
				FILE_READ_ATTRIBUTES | FILE_WRITE_EA |
				FILE_READ_EA | FILE_APPEND_DATA |
				FILE_WRITE_DATA | FILE_READ_DATA;
		break;
	}
	aa_ace->sid.revision = 1;
	aa_ace->sid.sub_authority_count = 2;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	aa_ace->sid.identifier_authority.value[0] = 0;
	aa_ace->sid.identifier_authority.value[1] = 0;
	aa_ace->sid.identifier_authority.value[2] = 0;
	aa_ace->sid.identifier_authority.value[3] = 0;
	aa_ace->sid.identifier_authority.value[4] = 0;
	aa_ace->sid.identifier_authority.value[5] = 5;
	sub_authorities = aa_ace->sid.sub_authority;
	*sub_authorities++ =
			const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	*sub_authorities =
			const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
	/*
	 * Now at offset 0x48 into the security descriptor, as specified in the
	 * security descriptor, we now have the owner SID.
	 */
	sid = (SID*)((char*)sd + le32_to_cpu(sd->owner));
	sid->revision = 1;
	sid->sub_authority_count = 1;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	sid->identifier_authority.value[0] = 0;
	sid->identifier_authority.value[1] = 0;
	sid->identifier_authority.value[2] = 0;
	sid->identifier_authority.value[3] = 0;
	sid->identifier_authority.value[4] = 0;
	sid->identifier_authority.value[5] = 5;
	sid->sub_authority[0] = const_cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);
	/*
	 * Now at offset 0x54 into the security descriptor, as specified in the
	 * security descriptor, we have the group SID.
	 */
	sid = (SID*)((char*)sd + le32_to_cpu(sd->group));
	sid->revision = 1;
	sid->sub_authority_count = 2;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	sid->identifier_authority.value[0] = 0;
	sid->identifier_authority.value[1] = 0;
	sid->identifier_authority.value[2] = 0;
	sid->identifier_authority.value[3] = 0;
	sid->identifier_authority.value[4] = 0;
	sid->identifier_authority.value[5] = 5;
	sub_authorities = sid->sub_authority;
	*sub_authorities++ = const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	*sub_authorities = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
}
Exemplo n.º 15
0
static char *ntfs_get_fulllink(ntfs_volume *vol, ntfschar *junction,
			int count, const char *mnt_point, BOOL isdir)
{
	char *target;
	char *fulltarget;
	int sz;
	char *q;
	enum { DIR_JUNCTION, VOL_JUNCTION, NO_JUNCTION } kind;

	target = (char*)NULL;
	fulltarget = (char*)NULL;
			/*
			 * For a valid directory junction we want \??\x:\
			 * where \ is an individual char and x a non-null char
			 */
	if ((count >= 7)
	    && !memcmp(junction,dir_junction_head,8)
	    && junction[4]
	    && (junction[5] == const_cpu_to_le16(':'))
	    && (junction[6] == const_cpu_to_le16('\\')))
		kind = DIR_JUNCTION;
	else
			/*
			 * For a valid volume junction we want \\?\Volume{
			 * and a final \ (where \ is an individual char)
			 */
		if ((count >= 12)
		    && !memcmp(junction,vol_junction_head,22)
		    && (junction[count-1] == const_cpu_to_le16('\\')))
			kind = VOL_JUNCTION;
		else
			kind = NO_JUNCTION;
			/*
			 * Directory junction with an explicit path and
			 * no specific definition for the drive letter :
			 * try to interpret as a target on the same volume
			 */
	if ((kind == DIR_JUNCTION)
	    && (count >= 7)
	    && junction[7]
	    && !ntfs_drive_letter(vol, junction[4])) {
		target = search_absolute(vol,&junction[7],count - 7, isdir);
		if (target) {
			fulltarget = (char*)ntfs_malloc(strlen(mnt_point)
					+ strlen(target) + 2);
			if (fulltarget) {
				strcpy(fulltarget,mnt_point);
				strcat(fulltarget,"/");
				strcat(fulltarget,target);
			}
			free(target);
		}
	}
			/*
			 * Volume junctions or directory junctions with
			 * target not found on current volume :
			 * link to /.NTFS-3G/target which the user can
			 * define as a symbolic link to the real target
			 */
	if (((kind == DIR_JUNCTION) && !fulltarget)
	    || (kind == VOL_JUNCTION)) {
		sz = ntfs_ucstombs(&junction[4],
			(kind == VOL_JUNCTION ? count - 5 : count - 4),
			&target, 0);
		if ((sz > 0) && target) {
				/* reverse slashes */
			for (q=target; *q; q++)
				if (*q == '\\')
					*q = '/';
				/* force uppercase drive letter */
			if ((target[1] == ':')
			    && (target[0] >= 'a')
			    && (target[0] <= 'z'))
				target[0] += 'A' - 'a';
			fulltarget = (char*)ntfs_malloc(strlen(mnt_point)
				    + sizeof(mappingdir) + strlen(target) + 1);
			if (fulltarget) {
				strcpy(fulltarget,mnt_point);
				strcat(fulltarget,"/");
				strcat(fulltarget,mappingdir);
				strcat(fulltarget,target);
			}
		}
		if (target)
			free(target);
	}
	return (fulltarget);
}
Exemplo n.º 16
0
static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
{
	char *target = (char*)NULL;
	ntfs_inode *curni;
	ntfs_inode *newni;
	u64 inum;
	int pos;
	int lth;
	BOOL ok;
	BOOL morelinks;
	int max = 32; /* safety */

	pos = 0;
	ok = TRUE;
	morelinks = FALSE;
	curni = ntfs_dir_parent_inode(ni);
		/*
		 * Examine and translate the path, until we reach either
		 *  - the end,
		 *  - an unknown item
		 *  - a non-directory
		 *  - another reparse point,
		 * A reparse point is not dereferenced, it will be
		 * examined later when the translated path is dereferenced,
		 * however the final part of the path will not be adjusted
		 * to correct case.
		 */
	while (curni && ok && !morelinks && (pos < (count - 1)) && --max) {
		if ((count >= (pos + 2))
		    && (path[pos] == const_cpu_to_le16('.'))
		    && (path[pos+1] == const_cpu_to_le16('\\'))) {
			path[1] = const_cpu_to_le16('/');
			pos += 2;
		} else {
			if ((count >= (pos + 3))
			    && (path[pos] == const_cpu_to_le16('.'))
			    &&(path[pos+1] == const_cpu_to_le16('.'))
			    && (path[pos+2] == const_cpu_to_le16('\\'))) {
				path[2] = const_cpu_to_le16('/');
				pos += 3;
				newni = ntfs_dir_parent_inode(curni);
				if (curni != ni)
					ntfs_inode_close(curni);
				curni = newni;
				if (!curni)
					ok = FALSE;
			} else {
				lth = 0;
				while (((pos + lth) < count)
				    && (path[pos + lth] != const_cpu_to_le16('\\')))
					lth++;
				if (lth > 0)
					inum = ntfs_fix_file_name(curni,&path[pos],lth);
				else
					inum = (u64)-1;
				if (!lth
				    || ((curni != ni)
					&& ntfs_inode_close(curni))
				    || (inum == (u64)-1))
					ok = FALSE;
				else {
					curni = ntfs_inode_open(ni->vol, MREF(inum));
					if (!curni)
						ok = FALSE;
					else {
						if (curni->flags & FILE_ATTR_REPARSE_POINT)
							morelinks = TRUE;
						if (ok && ((pos + lth) < count)) {
							path[pos + lth] = const_cpu_to_le16('/');
							pos += lth + 1;
							if (morelinks
							   && ntfs_inode_close(curni))
								ok = FALSE;
						} else {
							pos += lth;
							if (!morelinks
							  && (ni->mrec->flags ^ curni->mrec->flags)
							    & MFT_RECORD_IS_DIRECTORY)
								ok = FALSE;
							if (ntfs_inode_close(curni))
								ok = FALSE;
						}
					}
				}
			}
		}
	}

	if (ok && (ntfs_ucstombs(path, count, &target, 0) < 0)) {
		free(target); // needed ?
		target = (char*)NULL;
	}
	return (target);
}
Exemplo n.º 17
0
/**
 * @attr_rec: The attribute record to check
 * @mft_rec: The parent FILE record.
 * @buflen: The size of the FILE record.
 *
 * Return:
 *  NULL: Fatal error occured. Not sure where is the next record.
 *  otherwise: pointer to the next attribute record.
 *
 * The function only check fields that are inside this attr record.
 *
 * Assumes mft_rec is current_mft_record.
 */
static ATTR_REC *check_attr_record(ATTR_REC *attr_rec, MFT_RECORD *mft_rec,
			u16 buflen)
{
	u16 name_offset;
	u16 attrs_offset = le16_to_cpu(mft_rec->attrs_offset);
	u32 attr_type = le32_to_cpu(attr_rec->type);
	u32 length = le32_to_cpu(attr_rec->length);

	// Check that this attribute does not overflow the mft_record
	if ((u8*)attr_rec+length >= ((u8*)mft_rec)+buflen) {
		check_failed("Attribute (0x%x) is larger than FILE record (%lld).\n",
				(int)attr_type, (long long)current_mft_record);
		return NULL;
	}

	// Attr type must be a multiple of 0x10 and 0x10<=x<=0x100.
	if ((attr_type & ~0x0F0) && (attr_type != 0x100)) {
		check_failed("Unknown attribute type 0x%x.\n",
			(int)attr_type);
		goto check_attr_record_next_attr;
	}

	if (length<24) {
		check_failed("Attribute %lld:0x%x Length too short (%u).\n",
			(long long)current_mft_record, (int)attr_type,
			(int)length);
		goto check_attr_record_next_attr;
	}

	// If this is the first attribute:
	// todo: instance number must be smaller than next_instance.
	if ((u8*)attr_rec == ((u8*)mft_rec) + attrs_offset) {
		if (!mft_rec->base_mft_record)
			assert_u32_equal(attr_type, 0x10,
				"First attribute type");
		// The following not always holds.
		// attr 0x10 becomes instance 1 and attr 0x40 becomes 0.
		//assert_u32_equal(attr_rec->instance, 0,
		//	"First attribute instance number");
	} else {
		assert_u32_noteq(attr_type, 0x10,
			"Not-first attribute type");
		// The following not always holds.
		//assert_u32_noteq(attr_rec->instance, 0,
		//	"Not-first attribute instance number");
	}
	//if (current_mft_record==938 || current_mft_record==1683 || current_mft_record==3152 || current_mft_record==22410)
	//printf("Attribute %lld:0x%x instance: %u isbase:%d.\n",
	//		current_mft_record, (int)attr_type, (int)le16_to_cpu(attr_rec->instance), (int)mft_rec->base_mft_record);
	// todo: instance is unique.

	// Check flags.
	if (attr_rec->flags & ~(const_cpu_to_le16(0xc0ff))) {
		check_failed("Attribute %lld:0x%x Unknown flags (0x%x).\n",
			(long long)current_mft_record, (int)attr_type,
			(int)le16_to_cpu(attr_rec->flags));
	}

	if (attr_rec->non_resident>1) {
		check_failed("Attribute %lld:0x%x Unknown non-resident "
			"flag (0x%x).\n", (long long)current_mft_record,
			(int)attr_type, (int)attr_rec->non_resident);
		goto check_attr_record_next_attr;
	}

	name_offset = le16_to_cpu(attr_rec->name_offset);
	/*
	 * todo: name must be legal unicode.
	 * Not really, information below in urls is about filenames, but I
	 * believe it also applies to attribute names.  (Yura)
	 *  http://blogs.msdn.com/michkap/archive/2006/09/24/769540.aspx
	 *  http://blogs.msdn.com/michkap/archive/2006/09/10/748699.aspx
	 */

	if (attr_rec->non_resident) {
		// Non-Resident

		// Make sure all the fields exist.
		if (length<64) {
			check_failed("Non-resident attribute %lld:0x%x too short (%u).\n",
				(long long)current_mft_record, (int)attr_type,
				(int)length);
			goto check_attr_record_next_attr;
		}
		if (attr_rec->compression_unit && (length<72)) {
			check_failed("Compressed attribute %lld:0x%x too short (%u).\n",
				(long long)current_mft_record, (int)attr_type,
				(int)length);
			goto check_attr_record_next_attr;
		}

		// todo: name comes before mapping pairs, and after the header.
		// todo: length==mapping_pairs_offset+length of compressed mapping pairs.
		// todo: mapping_pairs_offset is 8-byte aligned.

		// todo: lowest vcn <= highest_vcn
		// todo: if base record -> lowest vcn==0
		// todo: lowest_vcn!=0 -> attribute list is used.
		// todo: lowest_vcn & highest_vcn are in the drive (0<=x<total clusters)
		// todo: mapping pairs agree with highest_vcn.
		// todo: compression unit == 0 or 4.
		// todo: reserved1 == 0.
		// todo: if not compressed nor sparse, initialized_size <= allocated_size and data_size <= allocated_size.
		// todo: if compressed or sparse, allocated_size <= initialized_size and allocated_size <= data_size
		// todo: if mft_no!=0 and not compressed/sparse, data_size==initialized_size.
		// todo: if mft_no!=0 and compressed/sparse, allocated_size==initialized_size.
		// todo: what about compressed_size if compressed?
		// todo: attribute must not be 0x10, 0x30, 0x40, 0x60, 0x70, 0x90, 0xd0 (not sure about 0xb0, 0xe0, 0xf0)
	} else {
		u16 value_offset = le16_to_cpu(attr_rec->value_offset);
		u32 value_length = le32_to_cpu(attr_rec->value_length);
		// Resident
		if (attr_rec->name_length) {
			if (name_offset < 24)
				check_failed("Resident attribute with "
					"name intersecting header.\n");
			if (value_offset < name_offset +
					attr_rec->name_length)
				check_failed("Named resident attribute "
					"with value before name.\n");
		}
		// if resident, length==value_length+value_offset
		//assert_u32_equal(le32_to_cpu(attr_rec->value_length)+
		//	value_offset, length,
		//	"length==value_length+value_offset");
		// if resident, length==value_length+value_offset
		if (value_length+value_offset > length) {
			check_failed("value_length(%d)+value_offset(%d)>length(%d) for attribute 0x%x.\n", (int)value_length, (int)value_offset, (int)length, (int)attr_type);
			return NULL;
		}

		// Check resident_flags.
		if (attr_rec->resident_flags>0x01) {
			check_failed("Unknown resident flags (0x%x) for attribute 0x%x.\n", (int)attr_rec->resident_flags, (int)attr_type);
		} else if (attr_rec->resident_flags && (attr_type!=0x30)) {
			check_failed("Resident flags mark attribute 0x%x as indexed.\n", (int)attr_type);
		}

		// reservedR is 0.
		assert_u32_equal(attr_rec->reservedR, 0, "Resident Reserved");

		// todo: attribute must not be 0xa0 (not sure about 0xb0, 0xe0, 0xf0)
		// todo: check content well-formness per attr_type.
	}
	return 0;
check_attr_record_next_attr:
	return (ATTR_REC *)(((u8 *)attr_rec) + length);
}
Exemplo n.º 18
0
	le16	subst_name_offset;
	le16	subst_name_length;
	le16	print_name_offset;
	le16	print_name_length;
	le32	flags;		     /* 1 for full target, otherwise 0 */
	char	path_buffer[0];      /* above data assume this is char array */
} ;

struct REPARSE_INDEX {			/* index entry in $Extend/$Reparse */
	INDEX_ENTRY_HEADER header;
	REPARSE_INDEX_KEY key;
	le32 filling;
} ;

static const ntfschar dir_junction_head[] = {
	const_cpu_to_le16('\\'),
	const_cpu_to_le16('?'),
	const_cpu_to_le16('?'),
	const_cpu_to_le16('\\')
} ;

static const ntfschar vol_junction_head[] = {
	const_cpu_to_le16('\\'),
	const_cpu_to_le16('?'),
	const_cpu_to_le16('?'),
	const_cpu_to_le16('\\'),
	const_cpu_to_le16('V'),
	const_cpu_to_le16('o'),
	const_cpu_to_le16('l'),
	const_cpu_to_le16('u'),
	const_cpu_to_le16('m'),
Exemplo n.º 19
0
Arquivo: sd.c Projeto: AllardJ/Tomato
/**
 * init_root_sd -
 *
 * Creates the security_descriptor for the root folder on ntfs 3.1 as created
 * by Windows Vista (when the format is done from the disk management MMC
 * snap-in, note this is different from the format done from the disk
 * properties in Windows Explorer).
 */
void init_root_sd(u8 **sd_val, int *sd_val_len)
{
	SECURITY_DESCRIPTOR_RELATIVE *sd;
	ACL *acl;
	ACCESS_ALLOWED_ACE *ace;
	SID *sid;
	le32 *sub_authorities;

	static char sd_array[0x102c];
	*sd_val_len = 0x102c;
	*sd_val = (u8*)&sd_array;

	//security descriptor relative
	sd = (SECURITY_DESCRIPTOR_RELATIVE*)sd_array;
	sd->revision = SECURITY_DESCRIPTOR_REVISION;
	sd->alignment = 0;
	sd->control = SE_SELF_RELATIVE | SE_DACL_PRESENT;
	sd->owner = const_cpu_to_le32(0x1014);
	sd->group = const_cpu_to_le32(0x1020);
	sd->sacl = 0;
	sd->dacl = const_cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE));

	//acl
	acl = (ACL*)((u8*)sd + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
	acl->revision = ACL_REVISION;
	acl->alignment1 = 0;
	acl->size = const_cpu_to_le16(0x1000);
	acl->ace_count = const_cpu_to_le16(0x08);
	acl->alignment2 = 0;

	//ace1
	ace = (ACCESS_ALLOWED_ACE*)((u8*)acl + sizeof(ACL));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = 0;
	ace->size = const_cpu_to_le16(0x18);
	ace->mask = STANDARD_RIGHTS_ALL | FILE_WRITE_ATTRIBUTES |
			 FILE_LIST_DIRECTORY | FILE_WRITE_DATA |
			 FILE_ADD_SUBDIRECTORY | FILE_READ_EA | FILE_WRITE_EA |
			 FILE_TRAVERSE | FILE_DELETE_CHILD |
			 FILE_READ_ATTRIBUTES;
	ace->sid.revision = SID_REVISION;
	ace->sid.sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	sub_authorities = ace->sid.sub_authority;
	*sub_authorities++ =
			const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	*sub_authorities = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);

	//ace2
	ace = (ACCESS_ALLOWED_ACE*)((u8*)ace + le16_to_cpu(ace->size));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE |
			INHERIT_ONLY_ACE;
	ace->size = const_cpu_to_le16(0x18);
	ace->mask = GENERIC_ALL;
	ace->sid.revision = SID_REVISION;
	ace->sid.sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	sub_authorities = ace->sid.sub_authority;
	*sub_authorities++ =
			const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	*sub_authorities = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);

	//ace3
	ace = (ACCESS_ALLOWED_ACE*)((u8*)ace + le16_to_cpu(ace->size));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = 0;
	ace->size = const_cpu_to_le16(0x14);
	ace->mask = STANDARD_RIGHTS_ALL | FILE_WRITE_ATTRIBUTES |
			 FILE_LIST_DIRECTORY | FILE_WRITE_DATA |
			 FILE_ADD_SUBDIRECTORY | FILE_READ_EA | FILE_WRITE_EA |
			 FILE_TRAVERSE | FILE_DELETE_CHILD |
			 FILE_READ_ATTRIBUTES;
	ace->sid.revision = SID_REVISION;
	ace->sid.sub_authority_count = 0x01;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	ace->sid.sub_authority[0] =
			const_cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);

	//ace4
	ace = (ACCESS_ALLOWED_ACE*)((u8*)ace + le16_to_cpu(ace->size));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE |
			INHERIT_ONLY_ACE;
	ace->size = const_cpu_to_le16(0x14);
	ace->mask = GENERIC_ALL;
	ace->sid.revision = SID_REVISION;
	ace->sid.sub_authority_count = 0x01;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	ace->sid.sub_authority[0] =
			const_cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);

	//ace5
	ace = (ACCESS_ALLOWED_ACE*)((char*)ace + le16_to_cpu(ace->size));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = 0;
	ace->size = const_cpu_to_le16(0x14);
	ace->mask = SYNCHRONIZE | READ_CONTROL | DELETE |
			FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES |
			FILE_TRAVERSE | FILE_WRITE_EA | FILE_READ_EA |
			FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE |
			FILE_LIST_DIRECTORY;
	ace->sid.revision = SID_REVISION;
	ace->sid.sub_authority_count = 0x01;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	ace->sid.sub_authority[0] =
			const_cpu_to_le32(SECURITY_AUTHENTICATED_USER_RID);

	//ace6
	ace = (ACCESS_ALLOWED_ACE*)((u8*)ace + le16_to_cpu(ace->size));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE |
			INHERIT_ONLY_ACE;
	ace->size = const_cpu_to_le16(0x14);
	ace->mask = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
	ace->sid.revision = SID_REVISION;
	ace->sid.sub_authority_count = 0x01;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	ace->sid.sub_authority[0] =
			const_cpu_to_le32(SECURITY_AUTHENTICATED_USER_RID);

	//ace7
	ace = (ACCESS_ALLOWED_ACE*)((u8*)ace + le16_to_cpu(ace->size));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = 0;
	ace->size = const_cpu_to_le16(0x18);
	ace->mask = SYNCHRONIZE | READ_CONTROL | FILE_READ_ATTRIBUTES |
			FILE_TRAVERSE | FILE_READ_EA | FILE_LIST_DIRECTORY;
	ace->sid.revision = SID_REVISION;
	ace->sid.sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	sub_authorities = ace->sid.sub_authority;
	*sub_authorities++ =
			const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	*sub_authorities = const_cpu_to_le32(DOMAIN_ALIAS_RID_USERS);

	//ace8
	ace = (ACCESS_ALLOWED_ACE*)((u8*)ace + le16_to_cpu(ace->size));
	ace->type = ACCESS_ALLOWED_ACE_TYPE;
	ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE |
			INHERIT_ONLY_ACE;
	ace->size = const_cpu_to_le16(0x18);
	ace->mask = GENERIC_READ | GENERIC_EXECUTE;
	ace->sid.revision = SID_REVISION;
	ace->sid.sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	sub_authorities = ace->sid.sub_authority;
	*sub_authorities++ =
			const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	*sub_authorities = const_cpu_to_le32(DOMAIN_ALIAS_RID_USERS);

	//owner sid
	sid = (SID*)((char*)sd + le32_to_cpu(sd->owner));
	sid->revision = 0x01;
	sid->sub_authority_count = 0x01;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	sid->identifier_authority.value[0] = 0;
	sid->identifier_authority.value[1] = 0;
	sid->identifier_authority.value[2] = 0;
	sid->identifier_authority.value[3] = 0;
	sid->identifier_authority.value[4] = 0;
	sid->identifier_authority.value[5] = 5;
	sid->sub_authority[0] = const_cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);

	//group sid
	sid = (SID*)((char*)sd + le32_to_cpu(sd->group));
	sid->revision = 0x01;
	sid->sub_authority_count = 0x01;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	sid->identifier_authority.value[0] = 0;
	sid->identifier_authority.value[1] = 0;
	sid->identifier_authority.value[2] = 0;
	sid->identifier_authority.value[3] = 0;
	sid->identifier_authority.value[4] = 0;
	sid->identifier_authority.value[5] = 5;
	sid->sub_authority[0] = const_cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);
}
Exemplo n.º 20
0
char *ntfs_make_symlink(ntfs_inode *ni, const char *mnt_point,
			int *pattr_size)
{
	s64 attr_size = 0;
	char *target;
	unsigned int offs;
	unsigned int lth;
	ntfs_volume *vol;
	REPARSE_POINT *reparse_attr;
	struct MOUNT_POINT_REPARSE_DATA *mount_point_data;
	struct SYMLINK_REPARSE_DATA *symlink_data;
	enum { FULL_TARGET, ABS_TARGET, REL_TARGET } kind;
	ntfschar *p;
	BOOL bad;
	BOOL isdir;

	target = (char*)NULL;
	bad = TRUE;
	isdir = (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
			 != const_cpu_to_le16(0);
	vol = ni->vol;
	reparse_attr = (REPARSE_POINT*)ntfs_attr_readall(ni,
			AT_REPARSE_POINT,(ntfschar*)NULL, 0, &attr_size);
	if (reparse_attr && attr_size
			&& valid_reparse_data(ni, reparse_attr, attr_size)) {
		switch (reparse_attr->reparse_tag) {
		case IO_REPARSE_TAG_MOUNT_POINT :
			mount_point_data = (struct MOUNT_POINT_REPARSE_DATA*)
						reparse_attr->reparse_data;
			offs = le16_to_cpu(mount_point_data->subst_name_offset);
			lth = le16_to_cpu(mount_point_data->subst_name_length);
				/* reparse data consistency has been checked */
			target = ntfs_get_fulllink(vol,
				(ntfschar*)&mount_point_data->path_buffer[offs],
				lth/2, mnt_point, isdir);
			if (target)
				bad = FALSE;
			break;
		case IO_REPARSE_TAG_SYMLINK :
			symlink_data = (struct SYMLINK_REPARSE_DATA*)
						reparse_attr->reparse_data;
			offs = le16_to_cpu(symlink_data->subst_name_offset);
			lth = le16_to_cpu(symlink_data->subst_name_length);
			p = (ntfschar*)&symlink_data->path_buffer[offs];
				/*
				 * Predetermine the kind of target,
				 * the called function has to make a full check
				 */
			if (*p++ == const_cpu_to_le16('\\')) {
				if ((*p == const_cpu_to_le16('?'))
				    || (*p == const_cpu_to_le16('\\')))
					kind = FULL_TARGET;
				else
					kind = ABS_TARGET;
			} else
				if (*p == const_cpu_to_le16(':'))
					kind = ABS_TARGET;
				else
					kind = REL_TARGET;
			p--;
				/* reparse data consistency has been checked */
			switch (kind) {
			case FULL_TARGET :
				if (!(symlink_data->flags
				   & const_cpu_to_le32(1))) {
					target = ntfs_get_fulllink(vol,
						p, lth/2,
						mnt_point, isdir);
					if (target)
						bad = FALSE;
				}
				break;
			case ABS_TARGET :
				if (symlink_data->flags
				   & const_cpu_to_le32(1)) {
					target = ntfs_get_abslink(vol,
						p, lth/2,
						mnt_point, isdir);
					if (target)
						bad = FALSE;
				}
				break;
			case REL_TARGET :
				if (symlink_data->flags
				   & const_cpu_to_le32(1)) {
					target = ntfs_get_rellink(ni,
						p, lth/2);
					if (target)
						bad = FALSE;
				}
				break;
			}
			break;
		}
		free(reparse_attr);
	}
	*pattr_size = attr_size;
	if (bad)
		errno = EOPNOTSUPP;
	return (target);
}
Exemplo n.º 21
0
Arquivo: sd.c Projeto: AllardJ/Tomato
/**
 * init_secure_sds -
 *
 * NTFS 3.1 - System files security decriptors
 * ===========================================
 * Create the security descriptor entries in $SDS data stream like they
 * are in a partition, newly formatted with windows 2003
 */
void init_secure_sds(char *sd_val)
{
	SECURITY_DESCRIPTOR_HEADER *sds;
	SECURITY_DESCRIPTOR_RELATIVE *sd;
	ACL *acl;
	ACCESS_ALLOWED_ACE *ace;
	SID *sid;

/*
 * security descriptor #1
 */
	//header
	sds = (SECURITY_DESCRIPTOR_HEADER*)((char*)sd_val);
	sds->hash = const_cpu_to_le32(0xF80312F0);
	sds->security_id = const_cpu_to_le32(0x0100);
	sds->offset = const_cpu_to_le64(0x00);
	sds->length = const_cpu_to_le32(0x7C);
	//security descriptor relative
	sd = (SECURITY_DESCRIPTOR_RELATIVE*)((char*)sds +
			sizeof(SECURITY_DESCRIPTOR_HEADER));
	sd->revision = 0x01;
	sd->alignment = 0x00;
	sd->control = SE_SELF_RELATIVE | SE_DACL_PRESENT;
	sd->owner = const_cpu_to_le32(0x48);
	sd->group = const_cpu_to_le32(0x58);
	sd->sacl = const_cpu_to_le32(0x00);
	sd->dacl = const_cpu_to_le32(0x14);

	//acl
	acl = (ACL*)((char*)sd + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
	acl->revision = 0x02;
	acl->alignment1 = 0x00;
	acl->size = const_cpu_to_le16(0x34);
	acl->ace_count = const_cpu_to_le16(0x02);
	acl->alignment2 = 0x00;

	//ace1
	ace = (ACCESS_ALLOWED_ACE*)((char*)acl + sizeof(ACL));
	ace->type = 0x00;
	ace->flags = 0x00;
	ace->size = const_cpu_to_le16(0x14);
	ace->mask = const_cpu_to_le32(0x120089);
	ace->sid.revision = 0x01;
	ace->sid.sub_authority_count = 0x01;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	ace->sid.sub_authority[0] =
			const_cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);
	//ace2
	ace = (ACCESS_ALLOWED_ACE*)((char*)ace + le16_to_cpu(ace->size));
	ace->type = 0x00;
	ace->flags = 0x00;
	ace->size = const_cpu_to_le16(0x18);
	ace->mask = const_cpu_to_le32(0x120089);
	ace->sid.revision = 0x01;
	ace->sid.sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	ace->sid.sub_authority[0] =
		const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	ace->sid.sub_authority[1] =
		const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);

	//owner sid
	sid = (SID*)((char*)sd + le32_to_cpu(sd->owner));
	sid->revision = 0x01;
	sid->sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	sid->identifier_authority.value[0] = 0;
	sid->identifier_authority.value[1] = 0;
	sid->identifier_authority.value[2] = 0;
	sid->identifier_authority.value[3] = 0;
	sid->identifier_authority.value[4] = 0;
	sid->identifier_authority.value[5] = 5;
	sid->sub_authority[0] =
		const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	sid->sub_authority[1] =
		const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
	//group sid
	sid = (SID*)((char*)sd + le32_to_cpu(sd->group));
	sid->revision = 0x01;
	sid->sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	sid->identifier_authority.value[0] = 0;
	sid->identifier_authority.value[1] = 0;
	sid->identifier_authority.value[2] = 0;
	sid->identifier_authority.value[3] = 0;
	sid->identifier_authority.value[4] = 0;
	sid->identifier_authority.value[5] = 5;
	sid->sub_authority[0] =
		const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	sid->sub_authority[1] =
		const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
/*
 * security descriptor #2
 */
	//header
	sds = (SECURITY_DESCRIPTOR_HEADER*)((char*)sd_val + 0x80);
	sds->hash = const_cpu_to_le32(0xB32451);
	sds->security_id = const_cpu_to_le32(0x0101);
	sds->offset = const_cpu_to_le64(0x80);
	sds->length = const_cpu_to_le32(0x7C);

	//security descriptor relative
	sd = (SECURITY_DESCRIPTOR_RELATIVE*)((char*)sds +
		 sizeof(SECURITY_DESCRIPTOR_HEADER));
	sd->revision = 0x01;
	sd->alignment = 0x00;
	sd->control = SE_SELF_RELATIVE | SE_DACL_PRESENT;
	sd->owner = const_cpu_to_le32(0x48);
	sd->group = const_cpu_to_le32(0x58);
	sd->sacl = const_cpu_to_le32(0x00);
	sd->dacl = const_cpu_to_le32(0x14);

	//acl
	acl = (ACL*)((char*)sd + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
	acl->revision = 0x02;
	acl->alignment1 = 0x00;
	acl->size = const_cpu_to_le16(0x34);
	acl->ace_count = const_cpu_to_le16(0x02);
	acl->alignment2 = 0x00;

	//ace1
	ace = (ACCESS_ALLOWED_ACE*)((char*)acl + sizeof(ACL));
	ace->type = 0x00;
	ace->flags = 0x00;
	ace->size = const_cpu_to_le16(0x14);
	ace->mask = const_cpu_to_le32(0x12019F);
	ace->sid.revision = 0x01;
	ace->sid.sub_authority_count = 0x01;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	ace->sid.sub_authority[0] =
		const_cpu_to_le32(SECURITY_LOCAL_SYSTEM_RID);
	//ace2
	ace = (ACCESS_ALLOWED_ACE*)((char*)ace + le16_to_cpu(ace->size));
	ace->type = 0x00;
	ace->flags = 0x00;
	ace->size = const_cpu_to_le16(0x18);
	ace->mask = const_cpu_to_le32(0x12019F);
	ace->sid.revision = 0x01;
	ace->sid.sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	ace->sid.identifier_authority.value[0] = 0;
	ace->sid.identifier_authority.value[1] = 0;
	ace->sid.identifier_authority.value[2] = 0;
	ace->sid.identifier_authority.value[3] = 0;
	ace->sid.identifier_authority.value[4] = 0;
	ace->sid.identifier_authority.value[5] = 5;
	ace->sid.sub_authority[0] =
		const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	ace->sid.sub_authority[1] =
		const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);

	//owner sid
	sid = (SID*)((char*)sd + le32_to_cpu(sd->owner));
	sid->revision = 0x01;
	sid->sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	sid->identifier_authority.value[0] = 0;
	sid->identifier_authority.value[1] = 0;
	sid->identifier_authority.value[2] = 0;
	sid->identifier_authority.value[3] = 0;
	sid->identifier_authority.value[4] = 0;
	sid->identifier_authority.value[5] = 5;
	sid->sub_authority[0] =
		const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	sid->sub_authority[1] =
		const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);

	//group sid
	sid = (SID*)((char*)sd + le32_to_cpu(sd->group));
	sid->revision = 0x01;
	sid->sub_authority_count = 0x02;
	/* SECURITY_NT_SID_AUTHORITY (S-1-5) */
	sid->identifier_authority.value[0] = 0;
	sid->identifier_authority.value[1] = 0;
	sid->identifier_authority.value[2] = 0;
	sid->identifier_authority.value[3] = 0;
	sid->identifier_authority.value[4] = 0;
	sid->identifier_authority.value[5] = 5;
	sid->sub_authority[0] =
		const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
	sid->sub_authority[1] =
		const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);

	return;
}
Exemplo n.º 22
0
} OBJECT_ID_INDEX_KEY;

typedef struct {
	le64 file_id;
	GUID birth_volume_id;
	GUID birth_object_id;
	GUID domain_id;
} OBJECT_ID_INDEX_DATA; // known as OBJ_ID_INDEX_DATA

struct OBJECT_ID_INDEX {		/* index entry in $Extend/$ObjId */
	INDEX_ENTRY_HEADER header;
	OBJECT_ID_INDEX_KEY key;
	OBJECT_ID_INDEX_DATA data;
} ;

static ntfschar objid_index_name[] = { const_cpu_to_le16('$'),
					 const_cpu_to_le16('O') };
#ifdef HAVE_SETXATTR	/* extended attributes interface required */

/*
 *			Set the index for a new object id
 *
 *	Returns 0 if success
 *		-1 if failure, explained by errno
 */

static int set_object_id_index(ntfs_inode *ni, ntfs_index_context *xo,
			const OBJECT_ID_ATTR *object_id)
{
	struct OBJECT_ID_INDEX indx;
	u64 file_id_cpu;