From 2d137b69008ffb74504f60ac96f7ce6dbde50a13 Mon Sep 17 00:00:00 2001 From: yura Date: Thu, 13 Jul 2006 16:01:52 +0000 Subject: [PATCH] create SD in __ntfs_create --- ChangeLog | 9 ++++-- libntfs/dir.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 907dd932..0d3175fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +xx/xx/xxxx - x.xx.x - + + - ntfsmount now creates files and directories with security descriptor + that grant full access to everyone. (Yura) + 21/06/2006 - 1.13.1 - Various fixes. - Fix bug in ntfs_attr_pwrite() when we sometimes lose current run in @@ -18,13 +23,13 @@ compressed metadata image size by 10-25% and more importantly it eliminates non-interesting ntfscmp differences. (Szaka) - Change utils_parse_size() to use a base of 0 instead of 10 when - calling strtoll(). This automagically allows specification of + calling strtoll(). This automatically allows specification of numbers in hex (and octal if anyone is crazy enough to use that) in addition to decimal numbers on the command line options to most if not all utilities. (Anton) - Fix comparison of $MFT and $MFTMirr to not bail out when there are unused, invalid mft records which are the same in both $MFT and - $MFTMirr. Ported from kernel driver 2.1.27 release and aplied both + $MFTMirr. Ported from kernel driver 2.1.27 release and applied both to libntfs/volume.c mount related code and to ntfsprogs/ntfsfix.c's fixup code. (Anton) - Change ntfsinfo to dump the key data as well as the keys themselves diff --git a/libntfs/dir.c b/libntfs/dir.c index 95a47574..e9cd1e03 100644 --- a/libntfs/dir.c +++ b/libntfs/dir.c @@ -1082,7 +1082,7 @@ err_out: * @type: type of the object to create * @dev: major and minor device numbers (obtained from makedev()) * @target: target in unicode (only for symlinks) - * @target_len: length of target in unicode charcters + * @target_len: length of target in unicode characters * * Internal, use ntfs_create{,_device,_symlink} wrappers instead. * @@ -1110,10 +1110,14 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, ntfschar *target, u8 target_len) { ntfs_inode *ni; - int rollback_data = 0; + int rollback_data = 0, rollback_sd = 0; FILE_NAME_ATTR *fn = NULL; STANDARD_INFORMATION *si = NULL; - int err, fn_len, si_len; + SECURITY_DESCRIPTOR_ATTR *sd = NULL; + ACL *acl; + ACCESS_ALLOWED_ACE *ace; + SID *sid; + int err, fn_len, si_len, sd_len; ntfs_log_trace("Entering.\n"); /* Sanity checks. */ @@ -1158,6 +1162,60 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, "attribute.\n"); goto err_out; } + /* 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 = calloc(1, sd_len); + if (!sd) { + err = errno; + ntfs_log_error("Not enough memory.\n"); + goto err_out; + } + sd->revision = 1; + sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE; + sid = (SID*)((u8*)sd + sizeof(SECURITY_DESCRIPTOR_ATTR)); + sd->owner = cpu_to_le32((u8*)sid - (u8*)sd); + sid->revision = 1; + sid->sub_authority_count = 2; + sid->sub_authority[0] = cpu_to_le32(32); + sid->sub_authority[1] = cpu_to_le32(544); + sid->identifier_authority.value[5] = 5; + sid = (SID*)((u8*)sid + sizeof(SID) + 4); + sd->group = cpu_to_le32((u8*)sid - (u8*)sd); + sid->revision = 1; + sid->sub_authority_count = 2; + sid->sub_authority[0] = cpu_to_le32(32); + sid->sub_authority[1] = cpu_to_le32(544); + sid->identifier_authority.value[5] = 5; + acl = (ACL*)((u8*)sid + sizeof(SID) + 4); + sd->dacl = cpu_to_le32((u8*)acl - (u8*)sd); + acl->revision = 2; + acl->size = cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)); + acl->ace_count = cpu_to_le16(1); + 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; + /* Add SECURITY_DESCRIPTOR attribute to inode. */ + if (ntfs_attr_add(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0, + (u8*)sd, sd_len)) { + err = errno; + ntfs_log_error("Failed to add SECURITY_DESCRIPTOR " + "attribute.\n"); + goto err_out; + } + rollback_sd = 1; + /* Add DATA/INDEX_ROOT attribute. */ if (S_ISDIR(type)) { INDEX_ROOT *ir = NULL; INDEX_ENTRY *ie; @@ -1297,10 +1355,24 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, /* Done! */ free(fn); free(si); + free(sd); ntfs_log_trace("Done.\n"); return ni; err_out: ntfs_log_trace("Failed.\n"); + if (rollback_sd) { + ntfs_attr *na; + + na = ntfs_attr_open(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0); + if (!na) + ntfs_log_perror("Failed to open SD (0x50) attribute of " + " inode 0x%llx. Run chkdsk.\n", + (unsigned long long)ni->mft_no); + else if (ntfs_attr_rm(na)) + ntfs_log_perror("Failed to remove SD (0x50) attribute " + "of inode 0x%llx. Run chkdsk.\n", + (unsigned long long)ni->mft_no); + } if (rollback_data) { ntfs_attr *na; @@ -1330,6 +1402,7 @@ err_out: "Leaving inconsistent metadata. Run chkdsk.\n"); free(fn); free(si); + free(sd); errno = err; return NULL; }