📄 security.cc
字号:
else res = 0; /* symlinks are everything for everyone! */ if ((*attribute & S_IFLNK) == S_IFLNK) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; return res > 0 ? 0 : -1;}static intget_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribute, __uid32_t *uidret, __gid32_t *gidret){ if (!wincap.has_security ()) return 0; PSECURITY_DESCRIPTOR psd = NULL; PSID owner_sid; PSID group_sid; PACL acl; if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type, DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, &owner_sid, &group_sid, &acl, NULL, &psd)) { __seterrno (); debug_printf ("GetSecurityInfo %E"); return -1; } __uid32_t uid = cygsid (owner_sid).get_uid (); __gid32_t gid = cygsid (group_sid).get_gid (); if (uidret) *uidret = uid; if (gidret) *gidret = gid; if (!attribute) { syscall_printf ("uid %d, gid %d", uid, gid); LocalFree (psd); return 0; } BOOL grp_member = is_grp_member (uid, gid); if (!acl) { *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; syscall_printf ("No ACL = %x, uid %d, gid %d", *attribute, uid, gid); LocalFree (psd); return 0; } get_attribute_from_acl (attribute, acl, owner_sid, group_sid, grp_member); LocalFree (psd); syscall_printf ("%x, uid %d, gid %d", *attribute, uid, gid); return 0;}intget_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribute, __uid32_t *uidret, __gid32_t *gidret){ if (allow_ntsec) { int res = get_nt_object_attribute (handle, object_type, attribute, uidret, gidret); if (attribute && (*attribute & S_IFLNK) == S_IFLNK) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; return res; } if (uidret) *uidret = getuid32 (); if (gidret) *gidret = getgid32 (); if (!attribute) return 0; /* symlinks are everything for everyone! */ if ((*attribute & S_IFLNK) == S_IFLNK) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; return 0;}BOOLadd_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit){ if (!AddAccessAllowedAce (acl, ACL_REVISION, attributes, sid)) { __seterrno (); return FALSE; } ACCESS_ALLOWED_ACE *ace; if (inherit && GetAce (acl, offset, (PVOID *) &ace)) ace->Header.AceFlags |= inherit; len_add += sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) + GetLengthSid (sid); return TRUE;}BOOLadd_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit){ if (!AddAccessDeniedAce (acl, ACL_REVISION, attributes, sid)) { __seterrno (); return FALSE; } ACCESS_DENIED_ACE *ace; if (inherit && GetAce (acl, offset, (PVOID *) &ace)) ace->Header.AceFlags |= inherit; len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) + GetLengthSid (sid); return TRUE;}PSECURITY_DESCRIPTORalloc_sd (__uid32_t uid, __gid32_t gid, int attribute, PSECURITY_DESCRIPTOR sd_ret, DWORD *sd_size_ret){ BOOL dummy; debug_printf("uid %d, gid %d, attribute %x", uid, gid, attribute); if (!sd_ret || !sd_size_ret) { set_errno (EINVAL); return NULL; } /* Get owner and group from current security descriptor. */ PSID cur_owner_sid = NULL; PSID cur_group_sid = NULL; if (!GetSecurityDescriptorOwner (sd_ret, &cur_owner_sid, &dummy)) debug_printf ("GetSecurityDescriptorOwner %E"); if (!GetSecurityDescriptorGroup (sd_ret, &cur_group_sid, &dummy)) debug_printf ("GetSecurityDescriptorGroup %E"); /* Get SID of owner. */ cygsid owner_sid (NO_SID); /* Check for current user first */ if (uid == myself->uid) owner_sid = cygheap->user.sid (); else if (uid == ILLEGAL_UID) owner_sid = cur_owner_sid; else if (!owner_sid.getfrompw (getpwuid32 (uid))) { set_errno (EINVAL); return NULL; } owner_sid.debug_print ("alloc_sd: owner SID ="); /* Get SID of new group. */ cygsid group_sid (NO_SID); /* Check for current user first */ if (gid == myself->gid) group_sid = cygheap->user.groups.pgsid; else if (gid == ILLEGAL_GID) group_sid = cur_group_sid; else if (!group_sid.getfromgr (getgrgid32 (gid))) { set_errno (EINVAL); return NULL; } group_sid.debug_print ("alloc_sd: group SID ="); /* Initialize local security descriptor. */ SECURITY_DESCRIPTOR sd; PSECURITY_DESCRIPTOR psd = NULL; if (!InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION)) { __seterrno (); return NULL; } /* * We set the SE_DACL_PROTECTED flag here to prevent the DACL from being * modified by inheritable ACEs. * This flag as well as the SetSecurityDescriptorControl call are available * only since Win2K. */ if (wincap.has_security_descriptor_control ()) SetSecurityDescriptorControl (&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED); /* Create owner for local security descriptor. */ if (!SetSecurityDescriptorOwner (&sd, owner_sid, FALSE)) { __seterrno (); return NULL; } /* Create group for local security descriptor. */ if (!SetSecurityDescriptorGroup (&sd, group_sid, FALSE)) { __seterrno (); return NULL; } /* Initialize local access control list. */ char acl_buf[3072]; PACL acl = (PACL) acl_buf; if (!InitializeAcl (acl, 3072, ACL_REVISION)) { __seterrno (); return NULL; } /* From here fill ACL. */ size_t acl_len = sizeof (ACL); int ace_off = 0; /* Construct allow attribute for owner. */ DWORD owner_allow = (STANDARD_RIGHTS_ALL & ~DELETE) | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA; if (attribute & S_IRUSR) owner_allow |= FILE_GENERIC_READ; if (attribute & S_IWUSR) owner_allow |= FILE_GENERIC_WRITE | DELETE; if (attribute & S_IXUSR) owner_allow |= FILE_GENERIC_EXECUTE; if ((attribute & (S_IFDIR | S_IWUSR | S_IXUSR)) == (S_IFDIR | S_IWUSR | S_IXUSR)) owner_allow |= FILE_DELETE_CHILD; /* Construct allow attribute for group. */ DWORD group_allow = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | FILE_READ_EA; if (attribute & S_IRGRP) group_allow |= FILE_GENERIC_READ; if (attribute & S_IWGRP) group_allow |= STANDARD_RIGHTS_WRITE | FILE_GENERIC_WRITE; if (attribute & S_IXGRP) group_allow |= FILE_GENERIC_EXECUTE; if ((attribute & (S_IFDIR | S_IWGRP | S_IXGRP)) == (S_IFDIR | S_IWGRP | S_IXGRP) && !(attribute & S_ISVTX)) group_allow |= FILE_DELETE_CHILD; /* Construct allow attribute for everyone. */ DWORD other_allow = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | FILE_READ_EA; if (attribute & S_IROTH) other_allow |= FILE_GENERIC_READ; if (attribute & S_IWOTH) other_allow |= STANDARD_RIGHTS_WRITE | FILE_GENERIC_WRITE; if (attribute & S_IXOTH) other_allow |= FILE_GENERIC_EXECUTE; if ((attribute & (S_IFDIR | S_IWOTH | S_IXOTH)) == (S_IFDIR | S_IWOTH | S_IXOTH) && !(attribute & S_ISVTX)) other_allow |= FILE_DELETE_CHILD; /* Construct SUID, SGID and VTX bits in NULL ACE. */ DWORD null_allow = 0L; if (attribute & (S_ISUID | S_ISGID | S_ISVTX)) { if (attribute & S_ISUID) null_allow |= FILE_APPEND_DATA; if (attribute & S_ISGID) null_allow |= FILE_WRITE_DATA; if (attribute & S_ISVTX) null_allow |= FILE_READ_DATA; } /* Add owner and group permissions if SIDs are equal and construct deny attributes for group and owner. */ DWORD group_deny; if (owner_sid == group_sid) { owner_allow |= group_allow; group_allow = group_deny = 0L; } else { group_deny = ~group_allow & other_allow; group_deny &= ~(STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | FILE_READ_EA); } DWORD owner_deny = ~owner_allow & (group_allow | other_allow); owner_deny &= ~(STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA); /* Construct appropriate inherit attribute. */ DWORD inherit = (attribute & S_IFDIR) ? SUB_CONTAINERS_AND_OBJECTS_INHERIT : NO_INHERITANCE; /* Set deny ACE for owner. */ if (owner_deny && !add_access_denied_ace (acl, ace_off++, owner_deny, owner_sid, acl_len, inherit)) return NULL; /* Set deny ACE for group here to respect the canonical order, if this does not impact owner */ if (group_deny && !(owner_allow & group_deny)) { if (!add_access_denied_ace (acl, ace_off++, group_deny, group_sid, acl_len, inherit)) return NULL; group_deny = 0; } /* Set allow ACE for owner. */ if (!add_access_allowed_ace (acl, ace_off++, owner_allow, owner_sid, acl_len, inherit)) return NULL; /* Set deny ACE for group, if still needed. */ if (group_deny && !add_access_denied_ace (acl, ace_off++, group_deny, group_sid, acl_len, inherit)) return NULL; /* Set allow ACE for group. */ if (group_allow && !add_access_allowed_ace (acl, ace_off++, group_allow, group_sid, acl_len, inherit)) return NULL; /* Set allow ACE for everyone. */ if (!add_access_allowed_ace (acl, ace_off++, other_allow, well_known_world_sid, acl_len, inherit)) return NULL; /* Set null ACE for special bits. */ if (null_allow && !add_access_allowed_ace (acl, ace_off++, null_allow, well_known_null_sid, acl_len, NO_INHERITANCE)) return NULL; /* Fill ACL with unrelated ACEs from current security descriptor. */ PACL oacl; BOOL acl_exists; ACCESS_ALLOWED_ACE *ace; if (GetSecurityDescriptorDacl (sd_ret, &acl_exists, &oacl, &dummy) && acl_exists && oacl) for (DWORD i = 0; i < oacl->AceCount; ++i) if (GetAce (oacl, i, (PVOID *) &ace)) { cygsid ace_sid ((PSID) &ace->SidStart); /* Check for related ACEs. */ if ((ace_sid == cur_owner_sid) || (ace_sid == owner_sid) || (ace_sid == cur_group_sid) || (ace_sid == group_sid) || (ace_sid == well_known_world_sid) || (ace_sid == well_known_null_sid)) continue; /* * Add unrelated ACCESS_DENIED_ACE to the beginning but * behind the owner_deny, ACCESS_ALLOWED_ACE to the end. */ if (!AddAce (acl, ACL_REVISION, ace->Header.AceType == ACCESS_DENIED_ACE_TYPE ? (owner_deny ? 1 : 0) : MAXDWORD, (LPVOID) ace, ace->Header.AceSize)) { __seterrno (); return NULL; } acl_len += ace->Header.AceSize; } /* Set AclSize to computed value. */ acl->AclSize = acl_len; debug_printf ("ACL-Size: %d", acl_len); /* Create DACL for local security descriptor. */ if (!SetSecurityDescriptorDacl (&sd, TRUE, acl, FALSE)) { __seterrno (); return NULL; } /* Make self relative security descriptor. */ *sd_size_ret = 0; MakeSelfRelativeSD (&sd, sd_ret, sd_size_ret); if (*sd_size_ret <= 0) { __seterrno (); return NULL; } if (!MakeSelfRelativeSD (&sd, sd_ret, sd_size_ret)) { __seterrno (); return NULL; } psd = sd_ret; debug_printf ("Created SD-Size: %d", *sd_size_ret); return psd;}voidset_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa, void *sd_buf, DWORD sd_buf_size){ /* symlinks are anything for everyone! */ if ((attribute & S_IFLNK) == S_IFLNK) attribute |= S_IRWXU | S_IRWXG | S_IRWXO; psa->lpSecurityDescriptor = sd_buf; InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR) sd_buf, SECURITY_DESCRIPTOR_REVISION); psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (), attribute, (PSECURITY_DESCRIPTOR) sd_buf, &sd_buf_size);}static intset_nt_attribute (const char *file, __uid32_t uid, __gid32_t gid, int attribute){ if (!wincap.has_security ()) return 0; DWORD sd_size = 4096; char sd_buf[4096]; PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; int ret; if ((ret = read_sd (file, psd, &sd_size)) <= 0) { debug_printf ("read_sd %E"); return -1; } sd_size = 4096; if (!(psd = alloc_sd (uid, gid, attribute, psd, &sd_size))) return -1; return write_sd (file, psd, sd_size);}intset_file_attribute (int use_ntsec, const char *file, __uid32_t uid, __gid32_t gid, int attribute){ int ret = 0; if (use_ntsec && allow_ntsec) ret = set_nt_attribute (file, uid, gid, attribute); else if (allow_ntea && !NTWriteEA (file, ".UNIXATTR", (char *) &attribute, sizeof (attribute))) { __seterrno (); ret = -1; } syscall_printf ("%d = set_file_attribute (%s, %d, %d, %p)", ret, file, uid, gid, attribute); return ret;}intset_file_attribute (int use_ntsec, const char *file, int attribute){ return set_file_attribute (use_ntsec, file, myself->uid, myself->gid, attribute);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -