| Index: mozilla/nsprpub/pr/src/md/windows/ntsec.c
|
| ===================================================================
|
| --- mozilla/nsprpub/pr/src/md/windows/ntsec.c (revision 191424)
|
| +++ mozilla/nsprpub/pr/src/md/windows/ntsec.c (working copy)
|
| @@ -1,261 +0,0 @@
|
| -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
| -/* This Source Code Form is subject to the terms of the Mozilla Public
|
| - * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -
|
| -#include "primpl.h"
|
| -
|
| -/*
|
| - * ntsec.c
|
| - *
|
| - * Implement the POSIX-style mode bits (access permissions) for
|
| - * files and other securable objects in Windows NT using Windows
|
| - * NT's security descriptors with appropriate discretionary
|
| - * access-control lists.
|
| - */
|
| -
|
| -/*
|
| - * The security identifiers (SIDs) for owner, primary group,
|
| - * and the Everyone (World) group.
|
| - *
|
| - * These SIDs are looked up during NSPR initialization and
|
| - * saved in this global structure (see _PR_NT_InitSids) so
|
| - * that _PR_NT_MakeSecurityDescriptorACL doesn't need to
|
| - * look them up every time.
|
| - */
|
| -static struct {
|
| - PSID owner;
|
| - PSID group;
|
| - PSID everyone;
|
| -} _pr_nt_sids;
|
| -
|
| -/*
|
| - * Initialize the SIDs for owner, primary group, and the Everyone
|
| - * group in the _pr_nt_sids structure.
|
| - *
|
| - * This function needs to be called by NSPR initialization.
|
| - */
|
| -void _PR_NT_InitSids(void)
|
| -{
|
| -#ifdef WINCE /* not supported */
|
| - return;
|
| -#else
|
| - SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
|
| - HANDLE hToken = NULL; /* initialized to an arbitrary value to
|
| - * silence a Purify UMR warning */
|
| - PSID infoBuffer[1024/sizeof(PSID)]; /* defined as an array of PSIDs
|
| - * to force proper alignment */
|
| - PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer;
|
| - PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup
|
| - = (PTOKEN_PRIMARY_GROUP) infoBuffer;
|
| - DWORD dwLength;
|
| - BOOL rv;
|
| -
|
| - /*
|
| - * Look up and make a copy of the owner and primary group
|
| - * SIDs in the access token of the calling process.
|
| - */
|
| - rv = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
|
| - if (rv == 0) {
|
| - /*
|
| - * On non-NT systems, this function is not implemented
|
| - * (error code ERROR_CALL_NOT_IMPLEMENTED), and neither are
|
| - * the other security functions. There is no point in
|
| - * going further.
|
| - *
|
| - * A process with insufficient access permissions may fail
|
| - * with the error code ERROR_ACCESS_DENIED.
|
| - */
|
| - PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
|
| - ("_PR_NT_InitSids: OpenProcessToken() failed. Error: %d",
|
| - GetLastError()));
|
| - return;
|
| - }
|
| -
|
| - rv = GetTokenInformation(hToken, TokenOwner, infoBuffer,
|
| - sizeof(infoBuffer), &dwLength);
|
| - PR_ASSERT(rv != 0);
|
| - dwLength = GetLengthSid(pTokenOwner->Owner);
|
| - _pr_nt_sids.owner = (PSID) PR_Malloc(dwLength);
|
| - PR_ASSERT(_pr_nt_sids.owner != NULL);
|
| - rv = CopySid(dwLength, _pr_nt_sids.owner, pTokenOwner->Owner);
|
| - PR_ASSERT(rv != 0);
|
| -
|
| - rv = GetTokenInformation(hToken, TokenPrimaryGroup, infoBuffer,
|
| - sizeof(infoBuffer), &dwLength);
|
| - PR_ASSERT(rv != 0);
|
| - dwLength = GetLengthSid(pTokenPrimaryGroup->PrimaryGroup);
|
| - _pr_nt_sids.group = (PSID) PR_Malloc(dwLength);
|
| - PR_ASSERT(_pr_nt_sids.group != NULL);
|
| - rv = CopySid(dwLength, _pr_nt_sids.group,
|
| - pTokenPrimaryGroup->PrimaryGroup);
|
| - PR_ASSERT(rv != 0);
|
| -
|
| - rv = CloseHandle(hToken);
|
| - PR_ASSERT(rv != 0);
|
| -
|
| - /* Create a well-known SID for the Everyone group. */
|
| - rv = AllocateAndInitializeSid(&SIDAuthWorld, 1,
|
| - SECURITY_WORLD_RID,
|
| - 0, 0, 0, 0, 0, 0, 0,
|
| - &_pr_nt_sids.everyone);
|
| - PR_ASSERT(rv != 0);
|
| -#endif
|
| -}
|
| -
|
| -/*
|
| - * Free the SIDs for owner, primary group, and the Everyone group
|
| - * in the _pr_nt_sids structure.
|
| - *
|
| - * This function needs to be called by NSPR cleanup.
|
| - */
|
| -void
|
| -_PR_NT_FreeSids(void)
|
| -{
|
| -#ifdef WINCE
|
| - return;
|
| -#else
|
| - if (_pr_nt_sids.owner) {
|
| - PR_Free(_pr_nt_sids.owner);
|
| - }
|
| - if (_pr_nt_sids.group) {
|
| - PR_Free(_pr_nt_sids.group);
|
| - }
|
| - if (_pr_nt_sids.everyone) {
|
| - FreeSid(_pr_nt_sids.everyone);
|
| - }
|
| -#endif
|
| -}
|
| -
|
| -/*
|
| - * Construct a security descriptor whose discretionary access-control
|
| - * list implements the specified mode bits. The SIDs for owner, group,
|
| - * and everyone are obtained from the global _pr_nt_sids structure.
|
| - * Both the security descriptor and access-control list are returned
|
| - * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call.
|
| - *
|
| - * The accessTable array maps NSPR's read, write, and execute access
|
| - * rights to the corresponding NT access rights for the securable
|
| - * object.
|
| - */
|
| -PRStatus
|
| -_PR_NT_MakeSecurityDescriptorACL(
|
| - PRIntn mode,
|
| - DWORD accessTable[],
|
| - PSECURITY_DESCRIPTOR *resultSD,
|
| - PACL *resultACL)
|
| -{
|
| -#ifdef WINCE
|
| - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
| - return PR_FAILURE;
|
| -#else
|
| - PSECURITY_DESCRIPTOR pSD = NULL;
|
| - PACL pACL = NULL;
|
| - DWORD cbACL; /* size of ACL */
|
| - DWORD accessMask;
|
| -
|
| - if (_pr_nt_sids.owner == NULL) {
|
| - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
|
| - return PR_FAILURE;
|
| - }
|
| -
|
| - pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
|
| - if (pSD == NULL) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| - if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| - if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| - if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| -
|
| - /*
|
| - * Construct a discretionary access-control list with three
|
| - * access-control entries, one each for owner, primary group,
|
| - * and Everyone.
|
| - */
|
| -
|
| - cbACL = sizeof(ACL)
|
| - + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))
|
| - + GetLengthSid(_pr_nt_sids.owner)
|
| - + GetLengthSid(_pr_nt_sids.group)
|
| - + GetLengthSid(_pr_nt_sids.everyone);
|
| - pACL = (PACL) PR_Malloc(cbACL);
|
| - if (pACL == NULL) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| - if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| - accessMask = 0;
|
| - if (mode & 00400) accessMask |= accessTable[0];
|
| - if (mode & 00200) accessMask |= accessTable[1];
|
| - if (mode & 00100) accessMask |= accessTable[2];
|
| - if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
|
| - _pr_nt_sids.owner)) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| - accessMask = 0;
|
| - if (mode & 00040) accessMask |= accessTable[0];
|
| - if (mode & 00020) accessMask |= accessTable[1];
|
| - if (mode & 00010) accessMask |= accessTable[2];
|
| - if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
|
| - _pr_nt_sids.group)) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| - accessMask = 0;
|
| - if (mode & 00004) accessMask |= accessTable[0];
|
| - if (mode & 00002) accessMask |= accessTable[1];
|
| - if (mode & 00001) accessMask |= accessTable[2];
|
| - if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
|
| - _pr_nt_sids.everyone)) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| -
|
| - if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
|
| - _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
|
| - goto failed;
|
| - }
|
| -
|
| - *resultSD = pSD;
|
| - *resultACL = pACL;
|
| - return PR_SUCCESS;
|
| -
|
| -failed:
|
| - if (pSD) {
|
| - PR_Free(pSD);
|
| - }
|
| - if (pACL) {
|
| - PR_Free(pACL);
|
| - }
|
| - return PR_FAILURE;
|
| -#endif
|
| -}
|
| -
|
| -/*
|
| - * Free the specified security descriptor and access-control list
|
| - * previously created by _PR_NT_MakeSecurityDescriptorACL.
|
| - */
|
| -void
|
| -_PR_NT_FreeSecurityDescriptorACL(PSECURITY_DESCRIPTOR pSD, PACL pACL)
|
| -{
|
| - if (pSD) {
|
| - PR_Free(pSD);
|
| - }
|
| - if (pACL) {
|
| - PR_Free(pACL);
|
| - }
|
| -}
|
|
|