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

📄 ntsec.c

📁 Netscape NSPR库源码
💻 C
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#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){    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;    HANDLE hToken = NULL; /* initialized to an arbitrary value to                           * silence a Purify UMR warning */    UCHAR infoBuffer[1024];    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);}/* * 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){    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);    }}/* * 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){    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;}/* * 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);    }}

⌨️ 快捷键说明

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