diff options
Diffstat (limited to 'winsup/cygwin/sec_helper.cc')
-rw-r--r-- | winsup/cygwin/sec_helper.cc | 673 |
1 files changed, 0 insertions, 673 deletions
diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc deleted file mode 100644 index 378a48135..000000000 --- a/winsup/cygwin/sec_helper.cc +++ /dev/null @@ -1,673 +0,0 @@ -/* sec_helper.cc: NT security helper functions - - Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, - 2010, 2011, 2012 Red Hat, Inc. - - Written by Corinna Vinschen <corinna@vinschen.de> - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include "winsup.h" -#include <stdlib.h> -#include <sys/acl.h> -#include <wchar.h> -#include "cygerrno.h" -#include "security.h" -#include "path.h" -#include "fhandler.h" -#include "dtable.h" -#include "pinfo.h" -#include "cygheap.h" -#include "pwdgrp.h" -#include "ntdll.h" - -/* General purpose security attribute objects for global use. */ -SECURITY_ATTRIBUTES NO_COPY sec_none; -SECURITY_ATTRIBUTES NO_COPY sec_none_nih; -SECURITY_ATTRIBUTES NO_COPY sec_all; -SECURITY_ATTRIBUTES NO_COPY sec_all_nih; - -MKSID (well_known_null_sid, "S-1-0-0", - SECURITY_NULL_SID_AUTHORITY, 1, SECURITY_NULL_RID); -MKSID (well_known_world_sid, "S-1-1-0", - SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID); -MKSID (well_known_local_sid, "S-1-2-0", - SECURITY_LOCAL_SID_AUTHORITY, 1, SECURITY_LOCAL_RID); -MKSID (well_known_console_logon_sid, "S-1-2-1", - SECURITY_LOCAL_SID_AUTHORITY, 1, 1); -MKSID (well_known_creator_owner_sid, "S-1-3-0", - SECURITY_CREATOR_SID_AUTHORITY, 1, SECURITY_CREATOR_OWNER_RID); -MKSID (well_known_creator_group_sid, "S-1-3-1", - SECURITY_CREATOR_SID_AUTHORITY, 1, SECURITY_CREATOR_GROUP_RID); -MKSID (well_known_dialup_sid, "S-1-5-1", - SECURITY_NT_AUTHORITY, 1, SECURITY_DIALUP_RID); -MKSID (well_known_network_sid, "S-1-5-2", - SECURITY_NT_AUTHORITY, 1, SECURITY_NETWORK_RID); -MKSID (well_known_batch_sid, "S-1-5-3", - SECURITY_NT_AUTHORITY, 1, SECURITY_BATCH_RID); -MKSID (well_known_interactive_sid, "S-1-5-4", - SECURITY_NT_AUTHORITY, 1, SECURITY_INTERACTIVE_RID); -MKSID (well_known_service_sid, "S-1-5-6", - SECURITY_NT_AUTHORITY, 1, SECURITY_SERVICE_RID); -MKSID (well_known_authenticated_users_sid, "S-1-5-11", - SECURITY_NT_AUTHORITY, 1, SECURITY_AUTHENTICATED_USER_RID); -MKSID (well_known_this_org_sid, "S-1-5-15", - SECURITY_NT_AUTHORITY, 1, 15); -MKSID (well_known_system_sid, "S-1-5-18", - SECURITY_NT_AUTHORITY, 1, SECURITY_LOCAL_SYSTEM_RID); -MKSID (well_known_builtin_sid, "S-1-5-32", - SECURITY_NT_AUTHORITY, 1, SECURITY_BUILTIN_DOMAIN_RID); -MKSID (well_known_admins_sid, "S-1-5-32-544", - SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS); -MKSID (well_known_users_sid, "S-1-5-32-545", - SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_USERS); -MKSID (fake_logon_sid, "S-1-5-5-0-0", - SECURITY_NT_AUTHORITY, 3, SECURITY_LOGON_IDS_RID, 0, 0); -MKSID (mandatory_medium_integrity_sid, "S-1-16-8192", - SECURITY_MANDATORY_LABEL_AUTHORITY, 1, SECURITY_MANDATORY_MEDIUM_RID); -MKSID (mandatory_high_integrity_sid, "S-1-16-12288", - SECURITY_MANDATORY_LABEL_AUTHORITY, 1, SECURITY_MANDATORY_HIGH_RID); -MKSID (mandatory_system_integrity_sid, "S-1-16-16384", - SECURITY_MANDATORY_LABEL_AUTHORITY, 1, SECURITY_MANDATORY_SYSTEM_RID); -/* UNIX accounts on a Samba server have the SID prefix "S-1-22-1" */ -#define SECURITY_SAMBA_UNIX_AUTHORITY {0,0,0,0,0,22} -MKSID (well_known_samba_unix_user_fake_sid, "S-1-22-1-0", - SECURITY_SAMBA_UNIX_AUTHORITY, 2, 1, 0); - -bool -cygpsid::operator== (const char *nsidstr) const -{ - cygsid nsid (nsidstr); - return psid == nsid; -} - -__uid32_t -cygpsid::get_id (BOOL search_grp, int *type) -{ - /* First try to get SID from group, then passwd */ - __uid32_t id = ILLEGAL_UID; - - if (search_grp) - { - struct __group32 *gr; - if (cygheap->user.groups.pgsid == psid) - id = myself->gid; - else if ((gr = internal_getgrsid (*this))) - id = gr->gr_gid; - if (id != ILLEGAL_UID) - { - if (type) - *type = GROUP; - return id; - } - } - if (!search_grp || type) - { - struct passwd *pw; - if (*this == cygheap->user.sid ()) - id = myself->uid; - else if ((pw = internal_getpwsid (*this))) - id = pw->pw_uid; - if (id != ILLEGAL_UID && type) - *type = USER; - } - return id; -} - -PWCHAR -cygpsid::string (PWCHAR nsidstr) const -{ - UNICODE_STRING sid; - - if (!psid || !nsidstr) - return NULL; - RtlInitEmptyUnicodeString (&sid, nsidstr, 256); - RtlConvertSidToUnicodeString (&sid, psid, FALSE); - return nsidstr; -} - -char * -cygpsid::string (char *nsidstr) const -{ - char *t; - DWORD i; - - if (!psid || !nsidstr) - return NULL; - strcpy (nsidstr, "S-1-"); - t = nsidstr + sizeof ("S-1-") - 1; - t += __small_sprintf (t, "%u", RtlIdentifierAuthoritySid (psid)->Value[5]); - for (i = 0; i < *RtlSubAuthorityCountSid (psid); ++i) - t += __small_sprintf (t, "-%lu", *RtlSubAuthoritySid (psid, i)); - return nsidstr; -} - -PSID -cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known) -{ - DWORD i; - SID_IDENTIFIER_AUTHORITY sid_auth = { SECURITY_NULL_SID_AUTHORITY }; -# define SECURITY_NT_AUTH 5 - - if (s > 255 || cnt < 1 || cnt > 8) - { - psid = NO_SID; - return NULL; - } - sid_auth.Value[5] = s; - set (); - RtlInitializeSid (psid, &sid_auth, cnt); - for (i = 0; i < cnt; ++i) - memcpy ((char *) psid + 8 + sizeof (DWORD) * i, &r[i], sizeof (DWORD)); - /* If the well_known flag isn't set explicitely, we check the SID - for being a well-known SID ourselves. That's necessary because this - cygsid is created from a SID string, usually from /etc/passwd or - /etc/group. The calling code just doesn't know if the SID is well-known - or not. All SIDs are well-known SIDs, except those in the non-unique NT - authority range. */ - if (well_known) - well_known_sid = well_known; - else - well_known_sid = (s != SECURITY_NT_AUTH - || r[0] != SECURITY_NT_NON_UNIQUE); - return psid; -} - -const PSID -cygsid::getfromstr (const char *nsidstr, bool well_known) -{ - char *lasts; - DWORD s, cnt = 0; - DWORD r[8]; - - if (nsidstr && !strncmp (nsidstr, "S-1-", 4)) - { - s = strtoul (nsidstr + 4, &lasts, 10); - while (cnt < 8 && *lasts == '-') - r[cnt++] = strtoul (lasts + 1, &lasts, 10); - if (!*lasts) - return get_sid (s, cnt, r, well_known); - } - return psid = NO_SID; -} - -BOOL -cygsid::getfrompw (const struct passwd *pw) -{ - char *sp = (pw && pw->pw_gecos) ? strrchr (pw->pw_gecos, ',') : NULL; - return (*this = sp ? sp + 1 : sp) != NULL; -} - -BOOL -cygsid::getfromgr (const struct __group32 *gr) -{ - char *sp = (gr && gr->gr_passwd) ? gr->gr_passwd : NULL; - return (*this = sp) != NULL; -} - -cygsid * -cygsidlist::alloc_sids (int n) -{ - if (n > 0) - return (cygsid *) cmalloc (HEAP_STR, n * sizeof (cygsid)); - else - return NULL; -} - -void -cygsidlist::free_sids () -{ - if (sids) - cfree (sids); - sids = NULL; - cnt = maxcnt = 0; - type = cygsidlist_empty; -} - -BOOL -cygsidlist::add (const PSID nsi, bool well_known) -{ - if (contains (nsi)) - return TRUE; - if (cnt >= maxcnt) - { - cygsid *tmp = new cygsid [2 * maxcnt]; - if (!tmp) - return FALSE; - maxcnt *= 2; - for (int i = 0; i < cnt; ++i) - tmp[i] = sids[i]; - delete [] sids; - sids = tmp; - } - if (well_known) - sids[cnt++] *= nsi; - else - sids[cnt++] = nsi; - return TRUE; -} - -bool -get_sids_info (cygpsid owner_sid, cygpsid group_sid, __uid32_t * uidret, __gid32_t * gidret) -{ - struct passwd *pw; - struct __group32 *gr = NULL; - bool ret = false; - - owner_sid.debug_print ("get_sids_info: owner SID ="); - group_sid.debug_print ("get_sids_info: group SID ="); - - if (group_sid == cygheap->user.groups.pgsid) - *gidret = myself->gid; - else if ((gr = internal_getgrsid (group_sid))) - *gidret = gr->gr_gid; - else - *gidret = ILLEGAL_GID; - - if (owner_sid == cygheap->user.sid ()) - { - *uidret = myself->uid; - if (*gidret == myself->gid) - ret = true; - else - ret = (internal_getgroups (0, NULL, &group_sid) > 0); - } - else if ((pw = internal_getpwsid (owner_sid))) - { - *uidret = pw->pw_uid; - if (gr || (*gidret != ILLEGAL_GID - && (gr = internal_getgrgid (*gidret)))) - for (int idx = 0; gr->gr_mem[idx]; ++idx) - if ((ret = strcasematch (pw->pw_name, gr->gr_mem[idx]))) - break; - } - else - *uidret = ILLEGAL_UID; - - return ret; -} - -PSECURITY_DESCRIPTOR -security_descriptor::malloc (size_t nsize) -{ - free (); - if ((psd = (PSECURITY_DESCRIPTOR) ::malloc (nsize))) - sd_size = nsize; - return psd; -} - -PSECURITY_DESCRIPTOR -security_descriptor::realloc (size_t nsize) -{ - PSECURITY_DESCRIPTOR tmp; - - /* Can't re-use buffer allocated by GetSecurityInfo. */ - if (psd && !sd_size) - free (); - if (!(tmp = (PSECURITY_DESCRIPTOR) ::realloc (psd, nsize))) - return NULL; - sd_size = nsize; - return psd = tmp; -} - -void -security_descriptor::free () -{ - if (psd) - { - if (!sd_size) - LocalFree (psd); - else - ::free (psd); - } - psd = NULL; - sd_size = 0; -} - -#undef TEXT -#define TEXT(q) L##q - -/* Index must match the corresponding foo_PRIVILEGE value, see security.h. */ -static const struct { - const wchar_t *name; - bool high_integrity; /* UAC: High Mandatory Label required to - be allowed to enable this privilege in - the user token. */ -} cygpriv[] = -{ - { L"", false }, - { L"", false }, - { SE_CREATE_TOKEN_NAME, true }, - { SE_ASSIGNPRIMARYTOKEN_NAME, true }, - { SE_LOCK_MEMORY_NAME, false }, - { SE_INCREASE_QUOTA_NAME, true }, - { SE_MACHINE_ACCOUNT_NAME, false }, - { SE_TCB_NAME, true }, - { SE_SECURITY_NAME, true }, - { SE_TAKE_OWNERSHIP_NAME, true }, - { SE_LOAD_DRIVER_NAME, true }, - { SE_SYSTEM_PROFILE_NAME, true }, - { SE_SYSTEMTIME_NAME, true }, - { SE_PROF_SINGLE_PROCESS_NAME, true }, - { SE_INC_BASE_PRIORITY_NAME, true }, - { SE_CREATE_PAGEFILE_NAME, true }, - { SE_CREATE_PERMANENT_NAME, false }, - { SE_BACKUP_NAME, true }, - { SE_RESTORE_NAME, true }, - { SE_SHUTDOWN_NAME, false }, - { SE_DEBUG_NAME, true }, - { SE_AUDIT_NAME, false }, - { SE_SYSTEM_ENVIRONMENT_NAME, true }, - { SE_CHANGE_NOTIFY_NAME, false }, - { SE_REMOTE_SHUTDOWN_NAME, true }, - { SE_UNDOCK_NAME, false }, - { SE_SYNC_AGENT_NAME, false }, - { SE_ENABLE_DELEGATION_NAME, false }, - { SE_MANAGE_VOLUME_NAME, true }, - { SE_IMPERSONATE_NAME, true }, - { SE_CREATE_GLOBAL_NAME, false }, - { SE_TRUSTED_CREDMAN_ACCESS_NAME, false }, - { SE_RELABEL_NAME, true }, - { SE_INC_WORKING_SET_NAME, false }, - { SE_TIME_ZONE_NAME, true }, - { SE_CREATE_SYMBOLIC_LINK_NAME, true } -}; - -bool -privilege_luid (const PWCHAR pname, LUID &luid, bool &high_integrity) -{ - ULONG idx; - for (idx = SE_CREATE_TOKEN_PRIVILEGE; - idx <= SE_MAX_WELL_KNOWN_PRIVILEGE; - ++idx) - if (!wcscmp (cygpriv[idx].name, pname)) - { - luid.HighPart = 0; - luid.LowPart = idx; - high_integrity = cygpriv[idx].high_integrity; - return true; - } - return false; -} - -static const wchar_t * -privilege_name (const LUID &priv_luid) -{ - if (priv_luid.HighPart || priv_luid.LowPart < SE_CREATE_TOKEN_PRIVILEGE - || priv_luid.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE) - return L"<unknown privilege>"; - return cygpriv[priv_luid.LowPart].name; -} - -int -set_privilege (HANDLE token, DWORD privilege, bool enable) -{ - int ret = -1; - TOKEN_PRIVILEGES new_priv, orig_priv; - ULONG size; - NTSTATUS status; - - new_priv.PrivilegeCount = 1; - new_priv.Privileges[0].Luid.HighPart = 0L; - new_priv.Privileges[0].Luid.LowPart = privilege; - new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0; - - status = NtAdjustPrivilegesToken (token, FALSE, &new_priv, sizeof orig_priv, - &orig_priv, &size); - if (!NT_SUCCESS (status)) - { - __seterrno_from_nt_status (status); - goto out; - } - - /* If orig_priv.PrivilegeCount is 0, the privilege hasn't been changed. */ - if (!orig_priv.PrivilegeCount) - ret = enable ? 1 : 0; - else - ret = (orig_priv.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) ? 1 : 0; - -out: - if (ret < 0) - debug_printf ("%d = set_privilege((token %x) %W, %d)", ret, token, - privilege_name (new_priv.Privileges[0].Luid), enable); - return ret; -} - -/* This is called very early in process initialization. The code must - not depend on anything. */ -void -set_cygwin_privileges (HANDLE token) -{ - /* Setting these rights at process startup allows processes running under - user tokens which are in the administrstors group to have root-like - permissions. */ - /* Allow to access all files, independent of their ACL settings. */ - set_privilege (token, SE_RESTORE_PRIVILEGE, true); - set_privilege (token, SE_BACKUP_PRIVILEGE, true); - /* Allow full access to other user's processes. */ - set_privilege (token, SE_DEBUG_PRIVILEGE, true); -#if 0 - /* Allow to create global shared memory. This isn't required anymore since - Cygwin 1.7. It uses its own subdirectories in the global NT namespace - which isn't affected by the SE_CREATE_GLOBAL_PRIVILEGE restriction. */ - if (wincap.has_create_global_privilege ()) - set_privilege (token, SE_CREATE_GLOBAL_PRIVILEGE, true); -#endif -} - -/* Function to return a common SECURITY_DESCRIPTOR that - allows all access. */ - -static inline PSECURITY_DESCRIPTOR -get_null_sd () -{ - static NO_COPY SECURITY_DESCRIPTOR sd; - static NO_COPY PSECURITY_DESCRIPTOR null_sdp; - - if (!null_sdp) - { - RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); - RtlSetDaclSecurityDescriptor (&sd, TRUE, NULL, FALSE); - null_sdp = &sd; - } - return null_sdp; -} - -/* Initialize global security attributes. - Called from dcrt0.cc (_dll_crt0). */ - -void -init_global_security () -{ - sec_none.nLength = sec_none_nih.nLength = - sec_all.nLength = sec_all_nih.nLength = sizeof (SECURITY_ATTRIBUTES); - sec_none.bInheritHandle = sec_all.bInheritHandle = TRUE; - sec_none_nih.bInheritHandle = sec_all_nih.bInheritHandle = FALSE; - sec_none.lpSecurityDescriptor = sec_none_nih.lpSecurityDescriptor = NULL; - sec_all.lpSecurityDescriptor = sec_all_nih.lpSecurityDescriptor = - get_null_sd (); -} - -bool -sec_acl (PACL acl, bool original, bool admins, PSID sid1, PSID sid2, DWORD access2) -{ - NTSTATUS status; - size_t acl_len = MAX_DACL_LEN (5); - LPVOID pAce; - cygpsid psid; - -#ifdef DEBUGGING - if ((unsigned long) acl % 4) - api_fatal ("Incorrectly aligned incoming ACL buffer!"); -#endif - status = RtlCreateAcl (acl, acl_len, ACL_REVISION); - if (!NT_SUCCESS (status)) - { - debug_printf ("RtlCreateAcl: %p", status); - return false; - } - if (sid1) - { - status = RtlAddAccessAllowedAce (acl, ACL_REVISION, GENERIC_ALL, sid1); - if (!NT_SUCCESS (status)) - debug_printf ("RtlAddAccessAllowedAce(sid1) %p", status); - } - if (original && (psid = cygheap->user.saved_sid ()) - && psid != sid1 && psid != well_known_system_sid) - { - status = RtlAddAccessAllowedAce (acl, ACL_REVISION, GENERIC_ALL, psid); - if (!NT_SUCCESS (status)) - debug_printf ("RtlAddAccessAllowedAce(original) %p", status); - } - if (sid2) - { - status = RtlAddAccessAllowedAce (acl, ACL_REVISION, access2, sid2); - if (!NT_SUCCESS (status)) - debug_printf ("RtlAddAccessAllowedAce(sid2) %p", status); - } - if (admins) - { - status = RtlAddAccessAllowedAce (acl, ACL_REVISION, GENERIC_ALL, - well_known_admins_sid); - if (!NT_SUCCESS (status)) - debug_printf ("RtlAddAccessAllowedAce(admin) %p", status); - } - status = RtlAddAccessAllowedAce (acl, ACL_REVISION, GENERIC_ALL, - well_known_system_sid); - if (!NT_SUCCESS (status)) - debug_printf ("RtlAddAccessAllowedAce(system) %p", status); - status = RtlFirstFreeAce (acl, &pAce); - if (NT_SUCCESS (status) && pAce) - acl->AclSize = (char *) pAce - (char *) acl; - else - debug_printf ("RtlFirstFreeAce: %p", status); - - return true; -} - -PSECURITY_ATTRIBUTES __stdcall -__sec_user (PVOID sa_buf, PSID sid1, PSID sid2, DWORD access2, BOOL inherit) -{ - PSECURITY_ATTRIBUTES psa = (PSECURITY_ATTRIBUTES) sa_buf; - PISECURITY_DESCRIPTOR psd = (PISECURITY_DESCRIPTOR) - ((char *) sa_buf + sizeof (*psa)); - PACL acl = (PACL) ((char *) sa_buf + sizeof (*psa) + sizeof (*psd)); - NTSTATUS status; - -#ifdef DEBUGGING - if ((unsigned long) sa_buf % 4) - api_fatal ("Incorrectly aligned incoming SA buffer!"); -#endif - if (!sec_acl (acl, true, true, sid1, sid2, access2)) - return inherit ? &sec_none : &sec_none_nih; - - RtlCreateSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION); - status = RtlSetDaclSecurityDescriptor (psd, TRUE, acl, FALSE); - if (!NT_SUCCESS (status)) - debug_printf ("RtlSetDaclSecurityDescriptor %p", status); - - psa->nLength = sizeof (SECURITY_ATTRIBUTES); - psa->lpSecurityDescriptor = psd; - psa->bInheritHandle = inherit; - return psa; -} - -/* Helper function to create a file security descriptor which allows - full access to admins, system, and the sid given as parameter. See - try_to_bin for how it's used. */ - -PSECURITY_DESCRIPTOR -_recycler_sd (void *buf, bool users, bool dir) -{ - NTSTATUS status; - PISECURITY_DESCRIPTOR psd = (PISECURITY_DESCRIPTOR) buf; - - if (!psd) - return NULL; - RtlCreateSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION); - PACL dacl = (PACL) (psd + 1); - /* Pre-Vista, the per-user recycler dir has a rather too complicated - ACL by default, which has distinct ACEs for inheritable and non-inheritable - permissions. However, this ACL is practically equivalent to the ACL - created since Vista. Therefore we simplify our job here and create the - pre-Vista permissions the same way as on Vista and later. */ - RtlCreateAcl (dacl, MAX_DACL_LEN (3), ACL_REVISION); - RtlAddAccessAllowedAceEx (dacl, ACL_REVISION, - dir ? CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE - : NO_INHERITANCE, - FILE_ALL_ACCESS, well_known_admins_sid); - RtlAddAccessAllowedAceEx (dacl, ACL_REVISION, - dir ? CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE - : NO_INHERITANCE, - FILE_ALL_ACCESS, well_known_system_sid); - if (users) - RtlAddAccessAllowedAceEx (dacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, - FILE_GENERIC_READ | FILE_GENERIC_EXECUTE - | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES, - well_known_users_sid); - else - RtlAddAccessAllowedAceEx (dacl, ACL_REVISION, - dir ? CONTAINER_INHERIT_ACE - | OBJECT_INHERIT_ACE - : NO_INHERITANCE, - FILE_ALL_ACCESS, cygheap->user.sid ()); - LPVOID ace; - status = RtlFirstFreeAce (dacl, &ace); - if (!NT_SUCCESS (status)) - { - debug_printf ("RtlFirstFreeAce: %p", status); - return NULL; - } - dacl->AclSize = (char *) ace - (char *) dacl; - RtlSetDaclSecurityDescriptor (psd, TRUE, dacl, FALSE); - /* If the directory DACL is not marked as protected, shell32 thinks - the recycle dir is corrupted. As soon as Explorer accesses the - Recycler, the user will get a GUI dialog "The Recycle Bin on X:\ - is corrupted. Do you want to empty the Recycle Bin for this drive?" - Of course we want to avoid that. */ - if (dir) - psd->Control |= SE_DACL_PROTECTED; - return psd; -} - -/* Helper function to create an event security descriptor which only allows - specific access to everyone. Only the creating process has all access - rights. */ - -PSECURITY_DESCRIPTOR -_everyone_sd (void *buf, ACCESS_MASK access) -{ - NTSTATUS status; - PISECURITY_DESCRIPTOR psd = (PISECURITY_DESCRIPTOR) buf; - - if (psd) - { - RtlCreateSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION); - PACL dacl = (PACL) (psd + 1); - RtlCreateAcl (dacl, MAX_DACL_LEN (1), ACL_REVISION); - status = RtlAddAccessAllowedAce (dacl, ACL_REVISION, access, - well_known_world_sid); - if (!NT_SUCCESS (status)) - { - debug_printf ("RtlAddAccessAllowedAce: %p", status); - return NULL; - } - LPVOID ace; - status = RtlFirstFreeAce (dacl, &ace); - if (!NT_SUCCESS (status)) - { - debug_printf ("RtlFirstFreeAce: %p", status); - return NULL; - } - dacl->AclSize = (char *) ace - (char *) dacl; - RtlSetDaclSecurityDescriptor (psd, TRUE, dacl, FALSE); - } - return psd; -} - |