⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 security.c

📁 添加linux下对NTFS格式文件系统访问支持的源代码ntfs-3g
💻 C
字号:
/** * security.c - Handling security/ACLs in NTFS.  Originated from the Linux-NTFS project. * * Copyright (c) 2004 Anton Altaparmakov * Copyright (c) 2005-2006 Szabolcs Szakacsits * Copyright (c) 2006 Yura Pakhuchiy * * 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 */#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef HAVE_STDIO_H#include <stdio.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif#include "types.h"#include "layout.h"#include "attrib.h"#include "security.h"#include "misc.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)));}/** * ntfs_guid_to_mbs - convert a GUID to a multi byte string * @guid:	[IN]  guid to convert * @guid_str:	[OUT] string in which to return the GUID (optional) * * Convert the GUID pointed to by @guid to a multi byte string of the form * "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX".  Therefore, @guid_str (if not NULL) * needs to be able to store at least 37 bytes. * * If @guid_str is not NULL it will contain the converted GUID on return.  If * it is NULL a string will be allocated and this will be returned.  The caller * is responsible for free()ing the string in that case. * * On success return the converted string and on failure return NULL with errno * set to the error code. */char *ntfs_guid_to_mbs(const GUID *guid, char *guid_str){	char *_guid_str;	int res;	if (!guid) {		errno = EINVAL;		return NULL;	}	_guid_str = guid_str;	if (!_guid_str) {		_guid_str = ntfs_malloc(37);		if (!_guid_str)			return _guid_str;	}	res = snprintf(_guid_str, 37,			"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",			(unsigned int)le32_to_cpu(guid->data1),			le16_to_cpu(guid->data2), le16_to_cpu(guid->data3),			guid->data4[0], guid->data4[1],			guid->data4[2], guid->data4[3], guid->data4[4],			guid->data4[5], guid->data4[6], guid->data4[7]);	if (res == 36)		return _guid_str;	if (!guid_str)		free(_guid_str);	errno = EINVAL;	return NULL;}/** * ntfs_sid_to_mbs_size - determine maximum size for the string of a SID * @sid:	[IN]  SID for which to determine the maximum string size * * Determine the maximum multi byte string size in bytes which is needed to * store the standard textual representation of the SID pointed to by @sid. * See ntfs_sid_to_mbs(), below. * * On success return the maximum number of bytes needed to store the multi byte * string and on failure return -1 with errno set to the error code. */int ntfs_sid_to_mbs_size(const SID *sid){	int size, i;	if (!ntfs_sid_is_valid(sid)) {		errno = EINVAL;		return -1;	}	/* Start with "S-". */	size = 2;	/*	 * Add the SID_REVISION.  Hopefully the compiler will optimize this	 * away as SID_REVISION is a constant.	 */	for (i = SID_REVISION; i > 0; i /= 10)		size++;	/* Add the "-". */	size++;	/*	 * Add the identifier authority.  If it needs to be in decimal, the	 * maximum is 2^32-1 = 4294967295 = 10 characters.  If it needs to be	 * in hexadecimal, then maximum is 0x665544332211 = 14 characters.	 */	if (!sid->identifier_authority.high_part)		size += 10;	else		size += 14;	/*	 * Finally, add the sub authorities.  For each we have a "-" followed	 * by a decimal which can be up to 2^32-1 = 4294967295 = 10 characters.	 */	size += (1 + 10) * sid->sub_authority_count;	/* We need the zero byte at the end, too. */	size++;	return size * sizeof(char);}/** * ntfs_sid_to_mbs - convert a SID to a multi byte string * @sid:		[IN]  SID to convert * @sid_str:		[OUT] string in which to return the SID (optional) * @sid_str_size:	[IN]  size in bytes of @sid_str * * Convert the SID pointed to by @sid to its standard textual representation. * @sid_str (if not NULL) needs to be able to store at least * ntfs_sid_to_mbs_size() bytes.  @sid_str_size is the size in bytes of * @sid_str if @sid_str is not NULL. * * The standard textual representation of the SID is of the form: *	S-R-I-S-S... * Where: *    - The first "S" is the literal character 'S' identifying the following *	digits as a SID. *    - R is the revision level of the SID expressed as a sequence of digits *	in decimal. *    - I is the 48-bit identifier_authority, expressed as digits in decimal, *	if I < 2^32, or hexadecimal prefixed by "0x", if I >= 2^32. *    - S... is one or more sub_authority values, expressed as digits in *	decimal. * * If @sid_str is not NULL it will contain the converted SUID on return.  If it * is NULL a string will be allocated and this will be returned.  The caller is * responsible for free()ing the string in that case. * * On success return the converted string and on failure return NULL with errno * set to the error code. */char *ntfs_sid_to_mbs(const SID *sid, char *sid_str, size_t sid_str_size){	u64 u;	char *s;	int i, j, cnt;	/*	 * No need to check @sid if !@sid_str since ntfs_sid_to_mbs_size() will	 * check @sid, too.  8 is the minimum SID string size.	 */	if (sid_str && (sid_str_size < 8 || !ntfs_sid_is_valid(sid))) {		errno = EINVAL;		return NULL;	}	/* Allocate string if not provided. */	if (!sid_str) {		cnt = ntfs_sid_to_mbs_size(sid);		if (cnt < 0)			return NULL;		s = ntfs_malloc(cnt);		if (!s)			return s;		sid_str = s;		/* So we know we allocated it. */		sid_str_size = 0;	} else {		s = sid_str;		cnt = sid_str_size;	}	/* Start with "S-R-". */	i = snprintf(s, cnt, "S-%hhu-", (unsigned char)sid->revision);	if (i < 0 || i >= cnt)		goto err_out;	s += i;	cnt -= i;	/* Add the identifier authority. */	for (u = i = 0, j = 40; i < 6; i++, j -= 8)		u += (u64)sid->identifier_authority.value[i] << j;	if (!sid->identifier_authority.high_part)		i = snprintf(s, cnt, "%lu", (unsigned long)u);	else		i = snprintf(s, cnt, "0x%llx", (unsigned long long)u);	if (i < 0 || i >= cnt)		goto err_out;	s += i;	cnt -= i;	/* Finally, add the sub authorities. */	for (j = 0; j < sid->sub_authority_count; j++) {		i = snprintf(s, cnt, "-%u", (unsigned int)				le32_to_cpu(sid->sub_authority[j]));		if (i < 0 || i >= cnt)			goto err_out;		s += i;		cnt -= i;	}	return sid_str;err_out:	if (i >= cnt)		i = EMSGSIZE;	else		i = errno;	if (!sid_str_size)		free(sid_str);	errno = i;	return NULL;}/** * ntfs_generate_guid - generatates a random current guid. * @guid:	[OUT]   pointer to a GUID struct to hold the generated guid. * * perhaps not a very good random number generator though... */void ntfs_generate_guid(GUID *guid){	unsigned int i;	u8 *p = (u8 *)guid;	for (i = 0; i < sizeof(GUID); i++) {		p[i] = (u8)(random() & 0xFF);		if (i == 7)			p[7] = (p[7] & 0x0F) | 0x40;		if (i == 8)			p[8] = (p[8] & 0x3F) | 0x80;	}}int ntfs_sd_add_everyone(ntfs_inode *ni){	SECURITY_DESCRIPTOR_ATTR *sd;	ACL *acl;	ACCESS_ALLOWED_ACE *ace;	SID *sid;	int ret, sd_len;		/* Create SECURITY_DESCRIPTOR attribute (everyone has full access). */	/*	 * Calculate security descriptor length. We have 2 sub-authorities in	 * owner and group SIDs, but structure SID contain only one, so add	 * 4 bytes to every SID.	 */	sd_len = sizeof(SECURITY_DESCRIPTOR_ATTR) + 2 * (sizeof(SID) + 4) +		sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); 	sd = ntfs_calloc(sd_len);	if (!sd)		return -1;		sd->revision = 1;	sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;		sid = (SID *)((u8 *)sd + sizeof(SECURITY_DESCRIPTOR_ATTR));	sid->revision = 1;	sid->sub_authority_count = 2;	sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);	sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);	sid->identifier_authority.value[5] = 5;	sd->owner = cpu_to_le32((u8 *)sid - (u8 *)sd);		sid = (SID *)((u8 *)sid + sizeof(SID) + 4); 	sid->revision = 1;	sid->sub_authority_count = 2;	sid->sub_authority[0] = cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);	sid->sub_authority[1] = cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);	sid->identifier_authority.value[5] = 5;	sd->group = cpu_to_le32((u8 *)sid - (u8 *)sd);		acl = (ACL *)((u8 *)sid + sizeof(SID) + 4);	acl->revision = 2;	acl->size = cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE));	acl->ace_count = cpu_to_le16(1);	sd->dacl = cpu_to_le32((u8 *)acl - (u8 *)sd);		ace = (ACCESS_ALLOWED_ACE *)((u8 *)acl + sizeof(ACL));	ace->type = ACCESS_ALLOWED_ACE_TYPE;	ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;	ace->size = cpu_to_le16(sizeof(ACCESS_ALLOWED_ACE));	ace->mask = cpu_to_le32(0x1f01ff); /* FIXME */	ace->sid.revision = 1;	ace->sid.sub_authority_count = 1;	ace->sid.sub_authority[0] = 0;	ace->sid.identifier_authority.value[5] = 1;		ret = ntfs_attr_add(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0, (u8 *)sd,			    sd_len);	if (ret)		ntfs_log_perror("Failed to add SECURITY_DESCRIPTOR\n");		free(sd);	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -