Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/nsprpub/pr/src/md/windows/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quelle  ntsec.c   Sprache: C

 
/* -*- 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);
  }
}

Messung V0.5
C=96 H=99 G=97

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.