*** empty log message ***
							parent
							
								
									e859b1b109
								
							
						
					
					
						commit
						99b4aba970
					
				|  | @ -68,11 +68,11 @@ extern u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, | |||
| extern ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent, | ||||
| 		const char *pathname); | ||||
| 
 | ||||
| extern ntfs_inode *ntfs_create(ntfs_inode *dir_ni, ntfschar *name, u8 name_len, | ||||
| 		dev_t type); | ||||
| extern ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, | ||||
| extern ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid, | ||||
| 		ntfschar *name,	u8 name_len, dev_t type); | ||||
| extern ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid, | ||||
| 		ntfschar *name, u8 name_len, dev_t type, dev_t dev); | ||||
| extern ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, | ||||
| extern ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid, | ||||
| 		ntfschar *name, u8 name_len, ntfschar *target, u8 target_len); | ||||
| extern int ntfs_check_empty_dir(ntfs_inode *ni); | ||||
| extern int ntfs_delete(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, | ||||
|  |  | |||
|  | @ -127,5 +127,7 @@ extern char *ntfs_ie_filename_get(INDEX_ENTRY *ie); | |||
| extern void ntfs_ie_filename_dump(INDEX_ENTRY *ie); | ||||
| extern void ntfs_ih_filename_dump(INDEX_HEADER *ih); | ||||
| 
 | ||||
| extern int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie); | ||||
| 
 | ||||
| #endif /* _NTFS_INDEX_H */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ typedef enum { | |||
| 				      in the index. */ | ||||
| 	NI_NoMtimeUpdate,	/* 1: Don't update modifiction time. */ | ||||
| 	NI_NoParentMtimeUpdate,	/* 1: Don't update parent dir's mtime. */ | ||||
| 	NI_v3_Extensions,	/* 1: JPA v3.x extensions present. */ | ||||
| } ntfs_inode_state_bits; | ||||
| 
 | ||||
| #define  test_nino_flag(ni, flag)	   test_bit(NI_##flag, (ni)->state) | ||||
|  | @ -159,6 +160,12 @@ struct _ntfs_inode { | |||
| 	time_t last_data_change_time; | ||||
| 	time_t last_mft_change_time; | ||||
| 	time_t last_access_time; | ||||
| 				/* NTFS 3.x extensions added by JPA */ | ||||
| 				/* only if NI_v3_Extensions is set in state */ | ||||
|  	le32 owner_id; | ||||
| 	le32 security_id; | ||||
| 	le32 quota_charged; | ||||
| 	le32 usn; | ||||
| }; | ||||
| 
 | ||||
| extern ntfs_inode *ntfs_inode_base(ntfs_inode *ni); | ||||
|  |  | |||
|  | @ -28,6 +28,50 @@ | |||
| #include "layout.h" | ||||
| #include "inode.h" | ||||
| 
 | ||||
| /*
 | ||||
|  *          item in the mapping list | ||||
|  */ | ||||
| 
 | ||||
| struct MAPPING { | ||||
| 	struct MAPPING *next; | ||||
| 	int xid;		/* linux id : uid or gid */ | ||||
| 	SID *sid;		/* Windows id : usid or gsid */ | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  *           Security context, needed by most security functions | ||||
|  */ | ||||
| 
 | ||||
| struct SECURITY_ENTRY { | ||||
| 	uid_t uid; | ||||
| 	gid_t gid; | ||||
| 	unsigned int mode:9; | ||||
| 	unsigned int valid:1; | ||||
| } ; | ||||
| 
 | ||||
| struct SECURITY_HEAD { | ||||
| 	int first; | ||||
| 	int last; | ||||
| 			/* statistics */ | ||||
| 	unsigned long attempts; | ||||
| 	unsigned long reads; | ||||
| 	unsigned long writes; | ||||
| } ; | ||||
| 
 | ||||
| struct SECURITY_CACHE { | ||||
| 	struct SECURITY_HEAD head; | ||||
| 	struct SECURITY_ENTRY cachetable[1]; | ||||
| } ; | ||||
| 
 | ||||
| struct SECURITY_CONTEXT { | ||||
| 	ntfs_volume *vol; | ||||
| 	struct MAPPING *usermapping; | ||||
| 	struct MAPPING *groupmapping; | ||||
| 	struct SECURITY_CACHE **pseccache; | ||||
| 	uid_t uid; /* uid of user requesting (not the mounter) */ | ||||
| 	gid_t gid; /* gid of user requesting (not the mounter) */ | ||||
| 	} ; | ||||
| 
 | ||||
| extern const GUID *const zero_guid; | ||||
| 
 | ||||
| extern BOOL ntfs_guid_is_zero(const GUID *guid); | ||||
|  | @ -58,4 +102,21 @@ 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); | ||||
| int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx, | ||||
| 		const char *path, ntfs_inode *ni, struct stat*); | ||||
| int ntfs_set_mode(struct SECURITY_CONTEXT *scx, | ||||
| 		const char *path, ntfs_inode *ni, mode_t mode); | ||||
| BOOL ntfs_allowed_access(struct SECURITY_CONTEXT *scx, const char *path, | ||||
| 		ntfs_inode *ni, int accesstype); | ||||
| BOOL ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx, | ||||
| 		const char *path, int accesstype); | ||||
| 
 | ||||
| int ntfs_set_owner(struct SECURITY_CONTEXT *scx, | ||||
| 		const char *path, ntfs_inode *ni, uid_t uid, gid_t gid); | ||||
| int ntfs_set_owner_mode(struct SECURITY_CONTEXT *scx, | ||||
| 		const char *path, ntfs_inode *ni, | ||||
| 		uid_t uid, gid_t gid, mode_t mode); | ||||
| 
 | ||||
| 
 | ||||
| #endif /* defined _NTFS_SECURITY_H */ | ||||
|  |  | |||
|  | @ -41,16 +41,21 @@ BOOL ntfs_is_collation_rule_supported(COLLATION_RULES cr) | |||
| 	 * FIXME:  At the moment we only support COLLATION_BINARY, | ||||
| 	 * COLLATION_NTOFS_ULONG and COLLATION_FILE_NAME so we return false | ||||
| 	 * for everything else. | ||||
| 	 * JPA added COLLATION_NTOFS_SECURITY_HASH | ||||
| 	 */ | ||||
| 	if (cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG && | ||||
| 			cr != COLLATION_FILE_NAME) | ||||
| 	if (cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG | ||||
| 			&& cr != COLLATION_FILE_NAME | ||||
| 			&& cr != COLLATION_NTOFS_SECURITY_HASH) | ||||
| 		return FALSE; | ||||
| /* JPA remove double checking
 | ||||
| 	i = le32_to_cpu(cr); | ||||
| 	if (((i >= 0) && (i <= 0x02)) || | ||||
| 			((i >= 0x10) && (i <= 0x13))) | ||||
| 		return TRUE; | ||||
| 	 | ||||
| 	return FALSE; | ||||
| */ | ||||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -121,6 +126,58 @@ static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)), | |||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ntfs_collate_ntofs_security_hash - Which of two security descriptors | ||||
|  *                    should be listed first | ||||
|  * @vol: unused | ||||
|  * @data1: | ||||
|  * @data1_len: | ||||
|  * @data2: | ||||
|  * @data2_len: | ||||
|  * | ||||
|  * JPA compare two security hash keys made of two unsigned le32 | ||||
|  * | ||||
|  * Returns: -1, 0 or 1 depending of how the keys compare | ||||
|  */ | ||||
| static int ntfs_collate_ntofs_security_hash(ntfs_volume *vol __attribute__((unused)), | ||||
| 		const void *data1, const int data1_len, | ||||
| 		const void *data2, const int data2_len) | ||||
| { | ||||
| 	int rc; | ||||
| 	u32 d1, d2; | ||||
| 	u32 *p1, *p2; | ||||
| 
 | ||||
| 	ntfs_log_trace("Entering.\n"); | ||||
| 	if (data1_len != data2_len || data1_len != 8) { | ||||
| 		ntfs_log_error("data1_len or/and data2_len not equal to 8.\n"); | ||||
| 		return NTFS_COLLATION_ERROR; | ||||
| 	} | ||||
| 	p1 = (u32*)data1; | ||||
| 	p2 = (u32*)data2; | ||||
| 	d1 = le32_to_cpup(p1); | ||||
| 	d2 = le32_to_cpup(p2); | ||||
| 	if (d1 < d2) | ||||
| 		rc = -1; | ||||
| 	else { | ||||
| 		if (d1 > d2) | ||||
| 			rc = 1; | ||||
| 		else { | ||||
| 			d1 = le32_to_cpup(++p1); | ||||
| 			d2 = le32_to_cpup(++p2); | ||||
| 			if (d1 < d2) | ||||
| 				rc = -1; | ||||
| 			else { | ||||
| 				if (d1 > d2) | ||||
| 					rc = 1; | ||||
| 				else | ||||
| 					rc = 0; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	ntfs_log_trace("Done, returning %i.\n", rc); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ntfs_collate_file_name - Which of two filenames should be listed first | ||||
|  * @vol: | ||||
|  | @ -162,7 +219,7 @@ static ntfs_collate_func_t ntfs_do_collate0x0[3] = { | |||
| static ntfs_collate_func_t ntfs_do_collate0x1[4] = { | ||||
| 	ntfs_collate_ntofs_ulong, | ||||
| 	NULL/*ntfs_collate_ntofs_sid*/, | ||||
| 	NULL/*ntfs_collate_ntofs_security_hash*/, | ||||
| 	ntfs_collate_ntofs_security_hash, | ||||
| 	NULL/*ntfs_collate_ntofs_ulongs*/, | ||||
| }; | ||||
| 
 | ||||
|  | @ -199,9 +256,11 @@ int ntfs_collate(ntfs_volume *vol, COLLATION_RULES cr, | |||
| 	 * FIXME:  At the moment we only support COLLATION_BINARY, | ||||
| 	 * COLLATION_NTOFS_ULONG and COLLATION_FILE_NAME so we return error | ||||
| 	 * for everything else. | ||||
| 	 * JPA added COLLATION_NTOFS_SECURITY_HASH | ||||
| 	 */ | ||||
| 	if (cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG && | ||||
| 			cr != COLLATION_FILE_NAME) | ||||
| 	if (cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG | ||||
| 			&& cr != COLLATION_FILE_NAME | ||||
| 			&& cr != COLLATION_NTOFS_SECURITY_HASH) | ||||
| 		goto err; | ||||
| 	i = le32_to_cpu(cr); | ||||
| 	if (i < 0) | ||||
|  |  | |||
|  | @ -1001,6 +1001,7 @@ err_out: | |||
| /**
 | ||||
|  * __ntfs_create - create object on ntfs volume | ||||
|  * @dir_ni:	ntfs inode for directory in which create new object | ||||
|  * @securid:	id of inheritable security descriptor, 0 if none | ||||
|  * @name:	unicode name of new object | ||||
|  * @name_len:	length of the name in unicode characters | ||||
|  * @type:	type of the object to create | ||||
|  | @ -1029,7 +1030,7 @@ err_out: | |||
|  * Return opened ntfs inode that describes created object on success or NULL | ||||
|  * on error with errno set to the error code. | ||||
|  */ | ||||
| static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, | ||||
| static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid, | ||||
| 		ntfschar *name, u8 name_len, dev_t type, dev_t dev, | ||||
| 		ntfschar *target, u8 target_len) | ||||
| { | ||||
|  | @ -1057,10 +1058,14 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, | |||
| 	if (!ni) | ||||
| 		return NULL; | ||||
| 	/*
 | ||||
| 	 * Create STANDARD_INFORMATION attribute. Write STANDARD_INFORMATION | ||||
| 	 * version 1.2, windows will upgrade it to version 3 if needed. | ||||
| 	 * Create STANDARD_INFORMATION attribute. | ||||
| 	 * JPA Depending on available inherited security descriptor, | ||||
| 	 * Write STANDARD_INFORMATION v1.2 (no inheritance) or v3 | ||||
| 	 */ | ||||
| 	si_len = offsetof(STANDARD_INFORMATION, v1_end); | ||||
| 	if (securid) | ||||
| 		si_len = sizeof(STANDARD_INFORMATION); | ||||
| 	else | ||||
| 		si_len = offsetof(STANDARD_INFORMATION, v1_end); | ||||
| 	si = ntfs_calloc(si_len); | ||||
| 	if (!si) { | ||||
| 		err = errno; | ||||
|  | @ -1070,6 +1075,14 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, | |||
| 	si->last_data_change_time = utc2ntfs(ni->last_data_change_time); | ||||
| 	si->last_mft_change_time = utc2ntfs(ni->last_mft_change_time); | ||||
| 	si->last_access_time = utc2ntfs(ni->last_access_time); | ||||
| 	if (securid) { | ||||
| 		set_nino_flag(ni, v3_Extensions); | ||||
| 		si->owner_id = 0; | ||||
| 		si->security_id = securid; | ||||
| 		si->quota_charged = 0; | ||||
| 		si->usn = 0; | ||||
| 	} else | ||||
| 		clear_nino_flag(ni, v3_Extensions); | ||||
| 	if (!S_ISREG(type) && !S_ISDIR(type)) { | ||||
| 		si->file_attributes = FILE_ATTR_SYSTEM; | ||||
| 		ni->flags = FILE_ATTR_SYSTEM; | ||||
|  | @ -1083,9 +1096,11 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, | |||
| 		goto err_out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ntfs_sd_add_everyone(ni)) { | ||||
| 		err = errno; | ||||
| 		goto err_out; | ||||
| 	if (securid) { | ||||
| 		if (ntfs_sd_add_everyone(ni)) { | ||||
| 			err = errno; | ||||
| 			goto err_out; | ||||
| 		} | ||||
| 	} | ||||
| 	rollback_sd = 1; | ||||
| 
 | ||||
|  | @ -1256,35 +1271,35 @@ err_out: | |||
|  * Some wrappers around __ntfs_create() ... | ||||
|  */ | ||||
| 
 | ||||
| ntfs_inode *ntfs_create(ntfs_inode *dir_ni, ntfschar *name, u8 name_len, | ||||
| 		dev_t type) | ||||
| ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid, ntfschar *name, | ||||
| 		u8 name_len, dev_t type) | ||||
| { | ||||
| 	if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO && | ||||
| 			type != S_IFSOCK) { | ||||
| 		ntfs_log_error("Invalid arguments.\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return __ntfs_create(dir_ni, name, name_len, type, 0, NULL, 0); | ||||
| 	return __ntfs_create(dir_ni, securid, name, name_len, type, 0, NULL, 0); | ||||
| } | ||||
| 
 | ||||
| ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, ntfschar *name, u8 name_len, | ||||
| 		dev_t type, dev_t dev) | ||||
| ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid, | ||||
| 		ntfschar *name,	u8 name_len, dev_t type, dev_t dev) | ||||
| { | ||||
| 	if (type != S_IFCHR && type != S_IFBLK) { | ||||
| 		ntfs_log_error("Invalid arguments.\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return __ntfs_create(dir_ni, name, name_len, type, dev, NULL, 0); | ||||
| 	return __ntfs_create(dir_ni, securid, name, name_len, type, dev, NULL, 0); | ||||
| } | ||||
| 
 | ||||
| ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, ntfschar *name, u8 name_len, | ||||
| 		ntfschar *target, u8 target_len) | ||||
| ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid, | ||||
| 		ntfschar *name,	u8 name_len, ntfschar *target, u8 target_len) | ||||
| { | ||||
| 	if (!target || !target_len) { | ||||
| 		ntfs_log_error("Invalid arguments.\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return __ntfs_create(dir_ni, name, name_len, S_IFLNK, 0, | ||||
| 	return __ntfs_create(dir_ni, securid, name, name_len, S_IFLNK, 0, | ||||
| 			target, target_len); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1429,16 +1429,20 @@ static int ntfs_ib_split(ntfs_index_context *icx, INDEX_BLOCK *ib) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie) | ||||
| /* JPA static */ | ||||
| int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie) | ||||
| { | ||||
| 	char *fn; | ||||
| 	INDEX_HEADER *ih; | ||||
| 	int allocated_size, new_size; | ||||
| 	int ret = STATUS_ERROR; | ||||
| 
 | ||||
| /* removed by JPA to make function usable for security indexes
 | ||||
| 	char *fn; | ||||
| 	 | ||||
| 	fn = ntfs_ie_filename_get(ie); | ||||
| 	ntfs_log_trace("file: '%s'\n", fn); | ||||
| 	ntfs_attr_name_free(&fn); | ||||
| */ | ||||
| 	 | ||||
| 	while (1) { | ||||
| 				 | ||||
|  |  | |||
|  | @ -190,6 +190,19 @@ ntfs_inode *ntfs_inode_open(ntfs_volume *vol, const MFT_REF mref) | |||
| 	ni->last_data_change_time = ntfs2utc(std_info->last_data_change_time); | ||||
| 	ni->last_mft_change_time = ntfs2utc(std_info->last_mft_change_time); | ||||
| 	ni->last_access_time = ntfs2utc(std_info->last_access_time); | ||||
|   		/* JPA insert v3 extensions if present */ | ||||
|                 /* length may be seen as 72 (v1.x) or 96 (v3.x) */ | ||||
|         if (ctx->attr->length > sizeof(STANDARD_INFORMATION)) { | ||||
|   		set_nino_flag(ni, v3_Extensions); | ||||
| 		ni->owner_id = std_info->owner_id; | ||||
| 		ni->security_id = std_info->security_id; | ||||
| 		ni->quota_charged = std_info->quota_charged; | ||||
| 		ni->usn = std_info->usn; | ||||
| 	} else { | ||||
| 		clear_nino_flag(ni, v3_Extensions); | ||||
| 		ni->owner_id = 0; | ||||
| 		ni->security_id = 0; | ||||
| 	} | ||||
| 	/* Set attribute list information. */ | ||||
| 	if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, AT_UNNAMED, 0, 0, 0, NULL, 0, | ||||
| 			ctx)) { | ||||
|  | @ -531,6 +544,13 @@ static int ntfs_inode_sync_standard_information(ntfs_inode *ni) | |||
| 	std_info->last_data_change_time = utc2ntfs(ni->last_data_change_time); | ||||
| 	std_info->last_mft_change_time = utc2ntfs(ni->last_mft_change_time); | ||||
| 	std_info->last_access_time = utc2ntfs(ni->last_access_time); | ||||
| 		/* JPA update v3.x extensions */ | ||||
| 	if (test_nino_flag(ni, v3_Extensions)) { | ||||
| 		std_info->owner_id = ni->owner_id; | ||||
| 		std_info->security_id = ni->security_id; | ||||
| 		std_info->quota_charged = ni->quota_charged; | ||||
| 		std_info->usn = ni->usn; | ||||
| 	} | ||||
| 	ntfs_inode_mark_dirty(ctx->ntfs_ino); | ||||
| 	ntfs_attr_put_search_ctx(ctx); | ||||
| 	return 0; | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue