示例#1
0
文件: sec.c 项目: NVIDIA/winex_lgpl
/******************************************************************************
 *  RtlEqualSid		[NTDLL.@]
 *
 */
BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
{
    if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
        return FALSE;

    if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
        return FALSE;

    if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
        return FALSE;

    return TRUE;
}
示例#2
0
static
BOOLEAN
TestValidateSamLogonInfo(
    NetrValidationInfo ***pppLogonInfo,
    DWORD                 dwNumUsers
)
{
    BOOLEAN bRet = TRUE;
    DWORD i = 0;

    for (i = 0; i < dwNumUsers; i++)
    {
        NetrValidationInfo **ppLogonInfo = pppLogonInfo[i];

        ASSERT_UNICODE_STRING_VALID_MSG(&ppLogonInfo[2]->sam2->base.account_name, ("(i = %u)\n", i));
        ASSERT_UNICODE_STRING_VALID_MSG(&ppLogonInfo[2]->sam2->base.full_name, ("(i = %u)\n", i));
        ASSERT_UNICODE_STRING_VALID_MSG(&ppLogonInfo[2]->sam2->base.logon_script, ("(i = %u)\n", i));
        ASSERT_UNICODE_STRING_VALID_MSG(&ppLogonInfo[2]->sam2->base.profile_path, ("(i = %u)\n", i));
        ASSERT_UNICODE_STRING_VALID_MSG(&ppLogonInfo[2]->sam2->base.home_directory, ("(i = %u)\n", i));
        ASSERT_UNICODE_STRING_VALID_MSG(&ppLogonInfo[2]->sam2->base.home_drive, ("(i = %u)\n", i));
        ASSERT_UNICODE_STRING_VALID_MSG(&ppLogonInfo[2]->sam2->base.logon_server, ("(i = %u)\n", i));
        ASSERT_UNICODE_STRING_VALID_MSG(&ppLogonInfo[2]->sam2->base.domain, ("(i = %u)\n", i));
        ASSERT_TEST_MSG((ppLogonInfo[2]->sam2->base.domain_sid != NULL &&
                         RtlValidSid(ppLogonInfo[2]->sam2->base.domain_sid)), ("(i = %u)\n", i));
        ASSERT_TEST_MSG(ppLogonInfo[2]->sam2->base.acct_flags & ACB_NORMAL, ("(i = %u)\n", i));
    }

    return bRet;
}
示例#3
0
BOOLEAN
RtlpIsValidLittleEndianSidBuffer(
    IN PVOID Buffer,
    IN ULONG BufferSize,
    OUT PULONG BufferUsed
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSID littleEndianSid = (PSID) Buffer;
    ULONG size = 0;

    if (BufferSize < SID_MIN_SIZE)
    {
        status = STATUS_INVALID_SID;
        GOTO_CLEANUP();
    }

    size = RtlLengthRequiredSid(LW_LTOH8(littleEndianSid->SubAuthorityCount));
    if (!RtlpIsBufferAvailable(BufferSize, 0, size))
    {
        status = STATUS_INVALID_SID;
        GOTO_CLEANUP();
    }

    // This is ok since it only looks at 1-byte fields:
    status = RtlValidSid(littleEndianSid) ? STATUS_SUCCESS : STATUS_INVALID_SID;

cleanup:
    *BufferUsed = NT_SUCCESS(status) ? size : 0;

    return NT_SUCCESS(status);
}
示例#4
0
static void
print_sid (const char *prefix, int idx, PISID sid)
{
  DWORD i;

  cyglsa_printf ("%s", prefix);
  if (idx >= 0)
    cyglsa_printf ("[%d] ", idx);
  cyglsa_printf ("(0x%08x) ", (INT_PTR) sid);
  if (!sid)
    cyglsa_printf ("NULL\n");
  else if (IsBadReadPtr (sid, 8))
    cyglsa_printf ("INVALID POINTER\n");
  else if (!RtlValidSid ((PSID) sid))
    cyglsa_printf ("INVALID SID\n");
  else if (IsBadReadPtr (sid, 8 + sizeof (DWORD) * sid->SubAuthorityCount))
    cyglsa_printf ("INVALID POINTER SPACE\n");
  else
    {
      cyglsa_printf ("S-%d-%d", sid->Revision, sid->IdentifierAuthority.Value[5]);
      for (i = 0; i < sid->SubAuthorityCount; ++i)
        cyglsa_printf ("-%lu", sid->SubAuthority[i]);
      cyglsa_printf ("\n");
    }
}
示例#5
0
文件: sec.c 项目: NVIDIA/winex_lgpl
/**************************************************************************
 *                 RtlCopySid				[NTDLL.@]
 */
DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
{
	if (!pSourceSid || !RtlValidSid(pSourceSid) ||
	    (nDestinationSidLength < RtlLengthSid(pSourceSid)))
          return FALSE;

	if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
	  return FALSE;

	memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
	return TRUE;
}
示例#6
0
/*
 * @implemented
 */
BOOLEAN
NTAPI
RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
    PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor;
    PSID Owner, Group;
    PACL Sacl, Dacl;
    PAGED_CODE_RTL();

    _SEH2_TRY
    {
        /* Fail on bad revisions */
        if (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) return FALSE;

        /* Owner SID must be valid if present */
        Owner = SepGetOwnerFromDescriptor(Sd);
        if ((Owner) && (!RtlValidSid(Owner))) return FALSE;

        /* Group SID must be valid if present */
        Group = SepGetGroupFromDescriptor(Sd);
        if ((Owner) && (!RtlValidSid(Group))) return FALSE;

        /* DACL must be valid if present */
        Dacl = SepGetDaclFromDescriptor(Sd);
        if ((Dacl) && (!RtlValidAcl(Dacl))) return FALSE;

        /* SACL must be valid if present */
        Sacl = SepGetSaclFromDescriptor(Sd);
        if ((Sacl) && (!RtlValidAcl(Sacl))) return FALSE;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Access fault, bail out */
        return FALSE;
    }
    _SEH2_END;

    /* All good */
    return TRUE;
}
示例#7
0
文件: cache.c 项目: vmware/lightwave
DWORD
VmDirRESTCacheGetBuiltInAdminsGroupSid(
    PVDIR_REST_HEAD_CACHE   pRestCache,
    PSID*                   ppBuiltInAdminsGroupSid
    )
{
    DWORD   dwError = 0;
    ULONG   ulSidLen = 0;
    BOOLEAN bInLock = FALSE;
    PSID    pSid = NULL;

    if (!pRestCache || !ppBuiltInAdminsGroupSid)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    VMDIR_RWLOCK_READLOCK(bInLock, gpVdirRestCache->pRWLock, 0);

    if (!RtlValidSid(pRestCache->pBuiltInAdminsGroupSid))
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_NOT_FOUND);
    }

    ulSidLen = RtlLengthSid(pRestCache->pBuiltInAdminsGroupSid);

    dwError = VmDirAllocateMemory(ulSidLen, (PVOID*)&pSid);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = RtlCopySid(ulSidLen, pSid, pRestCache->pBuiltInAdminsGroupSid);
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppBuiltInAdminsGroupSid = pSid;

cleanup:
    VMDIR_RWLOCK_UNLOCK(bInLock, gpVdirRestCache->pRWLock);
    return dwError;

error:
    VMDIR_LOG_ERROR(
            VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)",
            __FUNCTION__,
            dwError);

    VMDIR_SAFE_FREE_MEMORY(pSid);
    goto cleanup;
}
示例#8
0
文件: sec.c 项目: NVIDIA/winex_lgpl
/******************************************************************************
 *  RtlAddAccessDeniedAce		[NTDLL.@]
 */
NTSTATUS WINAPI RtlAddAccessDeniedAce(
	IN OUT PACL pAcl,
	IN DWORD dwAceRevision,
	IN DWORD AccessMask,
	IN PSID pSid)
{
	DWORD dwSidLength;
	ACCESS_DENIED_ACE* lpADA;

	TRACE("(%p,0x%08lx,0x%08lx,%p)!\n", pAcl, dwAceRevision, AccessMask, pSid);

	if( !RtlValidSid( pSid ) )
	{
		return STATUS_INVALID_SID;
	}

	dwSidLength = RtlLengthSid( pSid ) - sizeof( DWORD );

	if( !RtlFirstFreeAce( pAcl, (PACE_HEADER*)&lpADA) )
	{
		if( lpADA == NULL ) return STATUS_INVALID_ACL;
		else return STATUS_ALLOTTED_SPACE_EXCEEDED;
	}

	if( ((BYTE*)lpADA + sizeof( *lpADA ) + dwSidLength ) > ((BYTE*)pAcl + pAcl->AclSize) )
	{
		return STATUS_ALLOTTED_SPACE_EXCEEDED;
	}

	lpADA->Header.AceType = ACCESS_DENIED_ACE_TYPE;
	lpADA->Header.AceFlags = 0; /* Not set with RtlAddAccessDeniedAce. */
	lpADA->Header.AceSize = sizeof( *lpADA );
	lpADA->Mask = AccessMask;
	memcpy( &lpADA->SidStart, pSid, dwSidLength );

	pAcl->AceCount++;

	return STATUS_SUCCESS;
}
示例#9
0
static
DWORD
ValidateParameters(
    PCSTR pszSid
    )
{
    DWORD dwError = 0;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSID pSid = NULL;

    BAIL_ON_INVALID_STRING(pszSid);

    ntStatus = RtlAllocateSidFromCString(&pSid,
                                         pszSid);
    if (ntStatus != STATUS_SUCCESS)
    {
        dwError = LW_ERROR_INVALID_PARAMETER;
        BAIL_ON_LSA_ERROR(dwError);
    }

    if (RtlValidSid(pSid) &&
        pSid->SubAuthorityCount != 4)
    {
        dwError = LW_ERROR_INVALID_PARAMETER;
        BAIL_ON_LSA_ERROR(dwError);
    }

cleanup:
    if (pSid)
    {
        RTL_FREE(&pSid);
    }

    return dwError;

error:
    goto cleanup;
}
示例#10
0
static
BOOLEAN
TestValidateDomainTrusts(
    NetrDomainTrust      *pTrusts,
    DWORD                 dwNumTrusts
)
{
    BOOLEAN bRet = TRUE;
    DWORD i = 0;

    for (i = 0; i < dwNumTrusts; i++)
    {
        NetrDomainTrust *pTrust = &(pTrusts[i]);

        ASSERT_TEST_MSG(pTrust->netbios_name != NULL, ("(i = %u)\n", i));
        ASSERT_TEST_MSG(pTrust->dns_name != NULL, ("(i = %u)\n", i));
        ASSERT_TEST_MSG((pTrust->trust_type >= 1 &&
                         pTrust->trust_type <= 4), ("(i = %u)\n", i));
        ASSERT_TEST_MSG((pTrust->sid != NULL &&
                         RtlValidSid(pTrust->sid)), ("(i = %u)\n", i));
    }

    return bRet;
}
示例#11
0
/*
 * @implemented
 */
NTSTATUS NTAPI
RtlConvertSidToUnicodeString(PUNICODE_STRING String,
                             PSID Sid_,
                             BOOLEAN AllocateBuffer)
{
   WCHAR Buffer[256];
   PWSTR wcs;
   ULONG Length;
   ULONG i;
   PISID Sid =  Sid_;

   PAGED_CODE_RTL();

   if (RtlValidSid (Sid) == FALSE)
      return STATUS_INVALID_SID;

   wcs = Buffer;
   wcs += swprintf (wcs, L"S-%u-", Sid->Revision);
   if (Sid->IdentifierAuthority.Value[0] == 0 &&
       Sid->IdentifierAuthority.Value[1] == 0)
   {
      wcs += swprintf (wcs,
                       L"%lu",
                       (ULONG)Sid->IdentifierAuthority.Value[2] << 24 |
                       (ULONG)Sid->IdentifierAuthority.Value[3] << 16 |
                       (ULONG)Sid->IdentifierAuthority.Value[4] << 8 |
                       (ULONG)Sid->IdentifierAuthority.Value[5]);
   }
   else
   {
      wcs += swprintf (wcs,
                       L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
                       Sid->IdentifierAuthority.Value[0],
                       Sid->IdentifierAuthority.Value[1],
                       Sid->IdentifierAuthority.Value[2],
                       Sid->IdentifierAuthority.Value[3],
                       Sid->IdentifierAuthority.Value[4],
                       Sid->IdentifierAuthority.Value[5]);
   }

   for (i = 0; i < Sid->SubAuthorityCount; i++)
   {
      wcs += swprintf (wcs,
                       L"-%u",
                       Sid->SubAuthority[i]);
   }

   if (AllocateBuffer)
   {
      if (!RtlCreateUnicodeString(String,
                                  Buffer))
      {
         return STATUS_NO_MEMORY;
      }
   }
   else
   {
      Length = (wcs - Buffer) * sizeof(WCHAR);

      if (Length > String->MaximumLength)
         return STATUS_BUFFER_TOO_SMALL;

      String->Length = Length;
      RtlCopyMemory (String->Buffer,
                     Buffer,
                     Length);
      if (Length < String->MaximumLength)
         String->Buffer[Length / sizeof(WCHAR)] = 0;
   }

   return STATUS_SUCCESS;
}
示例#12
0
void TestsSeQueryInformationToken(PACCESS_TOKEN Token) 
{
    NTSTATUS Status;
    PVOID Buffer = NULL;
    PSID sid;
    PTOKEN_OWNER Towner;
    PTOKEN_DEFAULT_DACL TDefDacl;
    PTOKEN_GROUPS TGroups;
    ULONG GroupCount;
    PACL acl;
    PTOKEN_STATISTICS TStats;
    PTOKEN_TYPE TType;
    PTOKEN_USER TUser;
    BOOLEAN Flag;
    ULONG i;

    //----------------------------------------------------------------//
    // Testing SeQueryInformationToken with various args              //
    //----------------------------------------------------------------//

    ok(Token != NULL, "Token is not captured. Testing SQIT interrupted\n\n");

    if (Token == NULL) return;

    Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
    ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenOwner arg. But Buffer = NULL\n");

        if (Buffer)
        {
            Towner = (TOKEN_OWNER *)Buffer;
            sid = Towner->Owner;
            ok((RtlValidSid(sid) == TRUE), "TokenOwner's SID is not a valid SID\n");
            ExFreePool(Buffer);
        }
    }

    //----------------------------------------------------------------//
    
    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenDefaultDacl fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenDefaultDacl arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
            acl = TDefDacl->DefaultDacl;
            ok(((acl->AclRevision == ACL_REVISION || acl->AclRevision == ACL_REVISION_DS) == TRUE), "DACL is invalid\n");
            ExFreePool(Buffer);
        }
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenGroups, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenGroups fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenGroups arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TGroups = (PTOKEN_GROUPS)Buffer;
            GroupCount = TGroups->GroupCount;
            Flag = TRUE;
            for (i = 0; i < GroupCount; i++)
            {
                sid = TGroups->Groups[i].Sid;
                if (!RtlValidSid(sid))
                {
                    Flag = FALSE;
                    break;
                }
            }
            ok((Flag == TRUE), "TokenGroup's SIDs are not valid\n");
            ExFreePool(Buffer);
        }
    }

    //----------------------------------------------------------------//

    // Call SQIT with TokenImpersonationLevel argument
    //
    // What's up? Why SQIT fails with right arg?

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer);
    ok(Status == STATUS_SUCCESS, "and again: SQIT with TokenImpersonationLevel fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenImpersonationLevel arg. But Buffer = NULL\n");
    } else {
        ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenStatistics, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenStatistics fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenStatistics arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TStats = (PTOKEN_STATISTICS)Buffer;
            // just put 0 into 1st arg or use trace to print TokenStatistics f
            ok(1, "print statistics:\n\tTokenID = %u_%d\n\tSecurityImperLevel = %d\n\tPrivCount = %d\n\tGroupCount = %d\n\n", TStats->TokenId.LowPart, 
                TStats->TokenId.HighPart, 
                TStats->ImpersonationLevel,
                TStats->PrivilegeCount,
                TStats->GroupCount
                );
            ExFreePool(TStats);
        }
    } else {
        ok(Buffer == NULL, "Wrong. SQIT call is't success. But Buffer != NULL\n");
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenType, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenType fails with status 0x%X\n", Status);
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenType arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TType = (PTOKEN_TYPE)Buffer;
            ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in not a primary nor impersonation. FAILED\n");
            ExFreePool(TType);
        }
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenUser, &Buffer);
    ok(Status == STATUS_SUCCESS, "SQIT with TokenUser fails\n");
    if (Status == STATUS_SUCCESS)
    {
        ok(Buffer != NULL, "Wrong. SQIT call was successful with TokenUser arg. But Buffer = NULL\n");
        if (Buffer)
        {
            TUser = (PTOKEN_USER)Buffer;
            ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
            ExFreePool(TUser);
        }
    }

    //----------------------------------------------------------------//

    Buffer = NULL;
    Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
    ok(Status != STATUS_SUCCESS, "SQIT must fail with wrong TOKEN_INFORMATION_CLASS arg\n");
}
示例#13
0
NTSTATUS
RtlAllocateCStringFromSid(
    OUT PSTR* StringSid,
    IN PSID Sid
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSTR result = NULL;
    size_t size = 0;
    int count = 0;
    ULONG i = 0;

    if (!StringSid || !RtlValidSid(Sid))
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    size = RTLP_STRING_SID_MAX_CHARS(Sid->SubAuthorityCount);

    status = RTL_ALLOCATE(&result, CHAR, size);
    GOTO_CLEANUP_ON_STATUS(status);

    if (Sid->IdentifierAuthority.Value[0] || Sid->IdentifierAuthority.Value[1])
    {
        count += snprintf(result + count,
                          size - count,
                          "S-%u-0x%.2X%.2X%.2X%.2X%.2X%.2X",
                          Sid->Revision,
                          Sid->IdentifierAuthority.Value[0],
                          Sid->IdentifierAuthority.Value[1],
                          Sid->IdentifierAuthority.Value[2],
                          Sid->IdentifierAuthority.Value[3],
                          Sid->IdentifierAuthority.Value[4],
                          Sid->IdentifierAuthority.Value[5]);
    }
    else
    {
        ULONG value = 0;

        value |= (ULONG) Sid->IdentifierAuthority.Value[5];
        value |= (ULONG) Sid->IdentifierAuthority.Value[4] << 8;
        value |= (ULONG) Sid->IdentifierAuthority.Value[3] << 16;
        value |= (ULONG) Sid->IdentifierAuthority.Value[2] << 24;

        count += snprintf(result + count,
                          size - count,
                          "S-%u-%u",
                          Sid->Revision,
                          value);
    }

    for (i = 0; i < Sid->SubAuthorityCount; i++)
    {
        count += snprintf(result + count,
                          size - count,
                          "-%u", 
                          Sid->SubAuthority[i]);
    }

    status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(status))
    {
        RTL_FREE(&result);
    }

    if (StringSid)
    {
        *StringSid = result;
    }

    return status;
}
示例#14
0
NTSTATUS
RtlCreateAccessToken(
    OUT PACCESS_TOKEN* AccessToken,
    IN PTOKEN_USER User,
    IN PTOKEN_GROUPS Groups,
    IN PTOKEN_PRIVILEGES Privileges,
    IN PTOKEN_OWNER Owner,
    IN PTOKEN_PRIMARY_GROUP PrimaryGroup,
    IN PTOKEN_DEFAULT_DACL DefaultDacl,
    IN OPTIONAL PTOKEN_UNIX Unix
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int unixError = 0;
    ULONG requiredSize = 0;
    PACCESS_TOKEN token = NULL;
    ULONG i = 0;
    ULONG size = 0;
    PVOID location = NULL;

    if (!User || !User->User.Sid ||
        !Groups ||
        !Owner ||
        !PrimaryGroup ||
        !DefaultDacl)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    if (!RtlValidSid(User->User.Sid) ||
        (Owner->Owner && !RtlValidSid(Owner->Owner)) ||
        (PrimaryGroup->PrimaryGroup && !RtlValidSid(PrimaryGroup->PrimaryGroup)))
    {
        status = STATUS_INVALID_SID;
        GOTO_CLEANUP();
    }

    // No user attributes currently exist.
    if (User->User.Attributes != 0)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_CLEANUP();
    }

    for (i = 0; i < Groups->GroupCount; i++)
    {
        // TODO-Perhaps validate Group attributes
        if (!Groups->Groups[i].Sid)
        {
            status = STATUS_INVALID_PARAMETER;
            GOTO_CLEANUP();
        }
        if (!RtlValidSid(Groups->Groups[i].Sid))
        {
            status = STATUS_INVALID_SID;
            GOTO_CLEANUP();
        }
    }

    if (DefaultDacl->DefaultDacl &&
        !RtlValidAcl(DefaultDacl->DefaultDacl, NULL))
    {
        status = STATUS_INVALID_ACL;
        GOTO_CLEANUP();
    }

    // Compute size required

    requiredSize = sizeof(*token);

    size = RtlLengthSid(User->User.Sid);
    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    if (Owner->Owner)
    {
        size = RtlLengthSid(Owner->Owner);
        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    if (PrimaryGroup->PrimaryGroup)
    {
        size = RtlLengthSid(PrimaryGroup->PrimaryGroup);
        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    if (DefaultDacl->DefaultDacl)
    {
        status = RtlSafeAddULONG(&requiredSize, requiredSize,
                                 DefaultDacl->DefaultDacl->AclSize);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    status = RtlSafeMultiplyULONG(&size, sizeof(Groups->Groups[0]), Groups->GroupCount);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    for (i = 0; i < Groups->GroupCount; i++)
    {
        size = RtlLengthSid(Groups->Groups[i].Sid);

        status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
        GOTO_CLEANUP_ON_STATUS(status);
    }

    status = RtlSafeMultiplyULONG(&size,
                                  sizeof(Privileges->Privileges[0]),
                                  Privileges->PrivilegeCount);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RtlSafeAddULONG(&requiredSize, requiredSize, size);
    GOTO_CLEANUP_ON_STATUS(status);

    status = RTL_ALLOCATE(&token, ACCESS_TOKEN, requiredSize);
    GOTO_CLEANUP_ON_STATUS(status);

    location = LW_PTR_ADD(token, sizeof(*token));

    // Initialize

    token->ReferenceCount = 1;
    token->Flags = 0;
    unixError = pthread_rwlock_init(&token->RwLock, NULL);
    if (unixError)
    {
        LW_RTL_LOG_ERROR("Failed to init rwlock in access token "
                         "(error = %d).", unixError);
        status = LwErrnoToNtStatus(unixError);
        GOTO_CLEANUP();
    }
    token->pRwLock = &token->RwLock;

    token->User.Attributes = User->User.Attributes;
    token->User.Sid = (PSID) location;
    location = RtlpAppendData(location,
                              User->User.Sid,
                              RtlLengthSid(User->User.Sid));

    token->GroupCount = Groups->GroupCount;
    token->Groups = (PSID_AND_ATTRIBUTES) location;
    location = LwRtlOffsetToPointer(location, sizeof(Groups->Groups[0]) * Groups->GroupCount);
    for (i = 0; i < Groups->GroupCount; i++)
    {
        token->Groups[i].Attributes = Groups->Groups[i].Attributes;
        token->Groups[i].Sid = (PSID) location;
        location = RtlpAppendData(location,
                                  Groups->Groups[i].Sid,
                                  RtlLengthSid(Groups->Groups[i].Sid));
    }

    token->PrivilegeCount = Privileges->PrivilegeCount;
    token->Privileges = (PLUID_AND_ATTRIBUTES) location;
    location = LwRtlOffsetToPointer(
                location,
                sizeof(Privileges->Privileges[0]) * Privileges->PrivilegeCount);
    memcpy(token->Privileges,
           Privileges->Privileges,
           sizeof(token->Privileges[0]) * token->PrivilegeCount);

    if (Owner->Owner)
    {
        token->Owner = (PSID) location;
        location = RtlpAppendData(location,
                                  Owner->Owner,
                                  RtlLengthSid(Owner->Owner));
    }

    if (PrimaryGroup->PrimaryGroup)
    {
        token->PrimaryGroup = (PSID) location;
        location = RtlpAppendData(location,
                                  PrimaryGroup->PrimaryGroup,
                                  RtlLengthSid(PrimaryGroup->PrimaryGroup));
    }

    if (DefaultDacl->DefaultDacl)
    {
        token->DefaultDacl = (PACL) location;
        location = RtlpAppendData(location,
                                  DefaultDacl->DefaultDacl,
                                  DefaultDacl->DefaultDacl->AclSize);
    }

    if (Unix)
    {
        SetFlag(token->Flags, ACCESS_TOKEN_FLAG_UNIX_PRESENT);
        token->Uid = Unix->Uid;
        token->Gid = Unix->Gid;
        token->Umask = Unix->Umask;
    }

    if (location != LW_PTR_ADD(token, requiredSize))
    {
        status = STATUS_ASSERTION_FAILURE;
        GOTO_CLEANUP();
    }

    status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(status))
    {
        RtlReleaseAccessToken(&token);
    }

    *AccessToken = token;

    return status;
}
示例#15
0
FLT_POSTOP_CALLBACK_STATUS
claimsmanPostOperation(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_opt_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
)
/*++

Routine Description:

This routine is the post-operation completion routine for this
miniFilter.

This is non-pageable because it may be called at DPC level.

Arguments:

Data - Pointer to the filter callbackData that is passed to us.

FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance, its associated volume and
file object.

CompletionContext - The completion context set in the pre-operation routine.

Flags - Denotes whether the completion is successful or is being drained.

Return Value:

The return value is the status of the operation.

--*/
{
	UNREFERENCED_PARAMETER(Data);
	UNREFERENCED_PARAMETER(CompletionContext);
	UNREFERENCED_PARAMETER(Flags);
	NTSTATUS status;
	PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
	PUNICODE_STRING fileName = NULL;
	PTOKEN_USER pTokenUser = NULL;
	UNICODE_STRING sidString;
	
	LARGE_INTEGER Timeout;
	Timeout.QuadPart = (LONGLONG)1 * 10 * 1000 * 1000;
	
	// If there is no client registered, bail out immediately!
	// If the event is from kernel, bail out immediately!
	// If the event check for existence of file, bail out immediately!
	if (
		(ClaimsmanData.ClientPort == NULL) || 
		(Data->RequestorMode == KernelMode) ||
		(Data->IoStatus.Information == FILE_DOES_NOT_EXIST) ||
		(Data->IoStatus.Information == FILE_EXISTS)
		) {
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	//  We got a log record, if there is a file object, get its name.

	if (FltObjects->FileObject != NULL) {
		status = FltGetFileNameInformation(Data,
			FLT_FILE_NAME_NORMALIZED |
			FLT_FILE_NAME_QUERY_DEFAULT,
			&nameInfo);
	}
	else {
		//  Can't get a name when there's no file object
		status = STATUS_UNSUCCESSFUL;
	}

	if (NT_SUCCESS(status)) {
		FltParseFileNameInformation(nameInfo);
		fileName = &nameInfo->Name;
		// Produces way too much logging
		//PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
		//	("claimsman!claimsmanPostOperation: fileName=%wZ\n", fileName));
	}
	else
	{
		// No point continuing because we obviously did not get a filename anyways
		return FLT_POSTOP_FINISHED_PROCESSING;
	}

	//The only IRP you can trust for user information is IRP_MJ_CREATE. Things 
	//like write can be in arbitrary thread context, and even if the call works
	//you can get the wrong SID.

	status = SeQueryInformationToken(SeQuerySubjectContextToken(&(Data->Iopb->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext)), TokenUser, &pTokenUser);
	if (STATUS_SUCCESS == status && RtlValidSid(pTokenUser->User.Sid))
	{
		// Interesting extension?
		if (ClaimsmanCheckExtension(&nameInfo->Extension)) {
			CLAIMSMAN_MESSAGE msg;

			status = RtlConvertSidToUnicodeString(&sidString, pTokenUser->User.Sid, TRUE);

			if (NT_SUCCESS(status)) {
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: SID=%wZ\n", &sidString));
			}
			else {
				// No point continuing because we obviously did not get a valid SID
				FltReleaseFileNameInformation(nameInfo);
				ExFreePool(pTokenUser);
				return FLT_POSTOP_FINISHED_PROCESSING;
			}

			if (ClaimsmanCheckUserIgnore(&sidString)) {
				// Ignored user! Bail out!
				FltReleaseFileNameInformation(nameInfo);
				ExFreePool(pTokenUser);
				RtlFreeUnicodeString(&sidString);
				return FLT_POSTOP_FINISHED_PROCESSING;
			}

			LONGLONG size;
			LONGLONG modified;
			getSizeModified(FltObjects->Instance, fileName, &size, &modified);

			InitializeMessage(&msg, &sidString, fileName, FltObjects->FileObject->ReadAccess, FltObjects->FileObject->WriteAccess, FltObjects->FileObject->DeleteAccess, size, modified, Data->IoStatus.Status);

			// Ready, send the message!
			// But only if there's a client connected
			if (ClaimsmanData.ClientPort != NULL) {

				FltSendMessage(ClaimsmanData.Filter,
					&ClaimsmanData.ClientPort,
					&msg,
					sizeof(msg),
					NULL,
					0,
					&Timeout
					);
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: sent message=%d\n", status));
			}
			else {
				PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
					("claimsman!claimsmanPostOperation: no client connected!"));
			}
			RtlFreeUnicodeString(&sidString);
		}
	}

	FltReleaseFileNameInformation(nameInfo);
	if (pTokenUser != NULL) {
		ExFreePool(pTokenUser);
	}
	return FLT_POSTOP_FINISHED_PROCESSING;
}
示例#16
0
PSECURITY_DESCRIPTOR
NTAPI
INIT_FUNCTION
CmpHiveRootSecurityDescriptor(VOID)
{
    NTSTATUS Status;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    PACL Acl, AclCopy;
    PSID Sid[4];
    SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
    ULONG AceLength, AclLength, SidLength;
    PACE_HEADER AceHeader;
    ULONG i;
    PAGED_CODE();

    /* Phase 1: Allocate SIDs */
    SidLength = RtlLengthRequiredSid(1);
    Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
    SidLength = RtlLengthRequiredSid(2);
    Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);

    /* Make sure all SIDs were allocated */
    if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
    {
        /* Bugcheck */
        KeBugCheckEx(REGISTRY_ERROR, 11, 1, 0, 0);
    }

    /* Phase 2: Initialize all SIDs */
    Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
    Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
    Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
    Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 2, 0, 0);

    /* Phase 2: Setup SID Sub Authorities */
    *RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
    *RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
    *RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
    *RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
    *RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;

    /* Make sure all SIDs are valid */
    ASSERT(RtlValidSid(Sid[0]));
    ASSERT(RtlValidSid(Sid[1]));
    ASSERT(RtlValidSid(Sid[2]));
    ASSERT(RtlValidSid(Sid[3]));

    /* Phase 3: Calculate ACL Length */
    AclLength = sizeof(ACL);
    for (i = 0; i < 4; i++)
    {
        /* This is what MSDN says to do */
        AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
        AceLength += SeLengthSid(Sid[i]);
        AclLength += AceLength;
    }

    /* Phase 3: Allocate the ACL */
    Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
    if (!Acl) KeBugCheckEx(REGISTRY_ERROR, 11, 3, 0, 0);

    /* Phase 4: Create the ACL */
    Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 4, Status, 0);

    /* Phase 5: Build the ACL */
    Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
    Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 5, Status, 0);

    /* Phase 5: Make the ACEs inheritable */
    Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
    Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
    ASSERT(NT_SUCCESS(Status));
    AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;

    /* Phase 6: Allocate the security descriptor and make space for the ACL */
    SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
                                               sizeof(SECURITY_DESCRIPTOR) +
                                               AclLength,
                                               TAG_CM);
    if (!SecurityDescriptor) KeBugCheckEx(REGISTRY_ERROR, 11, 6, 0, 0);

    /* Phase 6: Make a copy of the ACL */
    AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
    RtlCopyMemory(AclCopy, Acl, AclLength);

    /* Phase 7: Create the security descriptor */
    Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 7, Status, 0);

    /* Phase 8: Set the ACL as a DACL */
    Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
                                          TRUE,
                                          AclCopy,
                                          FALSE);
    if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 8, Status, 0);

    /* Free the SIDs and original ACL */
    for (i = 0; i < 4; i++) ExFreePoolWithTag(Sid[i], TAG_CM);
    ExFreePoolWithTag(Acl, TAG_CM);

    /* Return the security descriptor */
    return SecurityDescriptor;
}
示例#17
0
/*
 * @implemented
 */
BOOLEAN
NTAPI
RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
                                   IN ULONG SecurityDescriptorLength,
                                   IN SECURITY_INFORMATION RequiredInformation)
{
    PISECURITY_DESCRIPTOR_RELATIVE Sd = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptorInput;
    PSID Owner, Group;
    PACL Dacl, Sacl;
    ULONG Length;
    PAGED_CODE_RTL();

    /* Note that Windows allows no DACL/SACL even if RequiredInfo wants it */

    /* Do we have enough space, is the revision vaild, and is this SD relative? */
    if ((SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) ||
        (Sd->Revision != SECURITY_DESCRIPTOR_REVISION) ||
        !(Sd->Control & SE_SELF_RELATIVE))
    {
        /* Nope, bail out */
        return FALSE;
    }

    /* Is there an owner? */
    if (Sd->Owner)
    {
        /* Try to access it */
        if (!RtlpValidateSDOffsetAndSize(Sd->Owner,
                                         SecurityDescriptorLength,
                                         sizeof(SID),
                                         &Length))
        {
            /* It's beyond the buffer, fail */
            return FALSE;
        }

        /* Read the owner, check if it's valid and if the buffer contains it */
        Owner = (PSID)((ULONG_PTR)Sd->Owner + (ULONG_PTR)Sd);
        if (!RtlValidSid(Owner) || (Length < RtlLengthSid(Owner))) return FALSE;
    }
    else if (RequiredInformation & OWNER_SECURITY_INFORMATION)
    {
        /* No owner but the caller expects one, fail */
        return FALSE;
    }

    /* Is there a group? */
    if (Sd->Group)
    {
        /* Try to access it */
        if (!RtlpValidateSDOffsetAndSize(Sd->Group,
                                         SecurityDescriptorLength,
                                         sizeof(SID),
                                         &Length))
        {
            /* It's beyond the buffer, fail */
            return FALSE;
        }

        /* Read the group, check if it's valid and if the buffer contains it */
        Group = (PSID)((ULONG_PTR)Sd->Group + (ULONG_PTR)Sd);
        if (!RtlValidSid(Group) || (Length < RtlLengthSid(Group))) return FALSE;
    }
    else if (RequiredInformation & GROUP_SECURITY_INFORMATION)
    {
        /* No group, but the caller expects one, fail */
        return FALSE;
    }

    /* Is there a DACL? */
    if ((Sd->Control & SE_DACL_PRESENT) == SE_DACL_PRESENT)
    {
        /* Try to access it */
        if (!RtlpValidateSDOffsetAndSize(Sd->Dacl,
                                         SecurityDescriptorLength,
                                         sizeof(ACL),
                                         &Length))
        {
            /* It's beyond the buffer, fail */
            return FALSE;
        }

        /* Read the DACL, check if it's valid and if the buffer contains it */
        Dacl = (PSID)((ULONG_PTR)Sd->Dacl + (ULONG_PTR)Sd);
        if (!(RtlValidAcl(Dacl)) || (Length < Dacl->AclSize)) return FALSE;
    }

    /* Is there a SACL? */
    if ((Sd->Control & SE_SACL_PRESENT) == SE_SACL_PRESENT)
    {
        /* Try to access it */
        if (!RtlpValidateSDOffsetAndSize(Sd->Sacl,
                                         SecurityDescriptorLength,
                                         sizeof(ACL),
                                         &Length))
        {
            /* It's beyond the buffer, fail */
            return FALSE;
        }

        /* Read the SACL, check if it's valid and if the buffer contains it */
        Sacl = (PSID)((ULONG_PTR)Sd->Sacl + (ULONG_PTR)Sd);
        if (!(RtlValidAcl(Sacl)) || (Length < Sacl->AclSize)) return FALSE;
    }

    /* All good */
    return TRUE;
}
示例#18
0
文件: acl.c 项目: Strongc/reactos
NTSTATUS
NTAPI
RtlpAddKnownAce(IN PACL Acl,
                IN ULONG Revision,
                IN ULONG Flags,
                IN ACCESS_MASK AccessMask,
                IN PSID Sid,
                IN UCHAR Type)
{
    PKNOWN_ACE Ace;
    ULONG AceSize, InvalidFlags;
    PAGED_CODE_RTL();

    /* Check the validity of the SID */
    if (!RtlValidSid(Sid)) return STATUS_INVALID_SID;

    /* Check the validity of the revision */
    if ((Acl->AclRevision > ACL_REVISION4) || (Revision > ACL_REVISION4))
    {
        return STATUS_REVISION_MISMATCH;
    }

    /* Pick the smallest of the revisions */
    if (Revision < Acl->AclRevision) Revision = Acl->AclRevision;

    /* Validate the flags */
    if (Type == SYSTEM_AUDIT_ACE_TYPE)
    {
        InvalidFlags = Flags & ~(VALID_INHERIT_FLAGS |
                                 SUCCESSFUL_ACCESS_ACE_FLAG |
                                 FAILED_ACCESS_ACE_FLAG);
    }
    else
    {
        InvalidFlags = Flags & ~VALID_INHERIT_FLAGS;
    }

    /* If flags are invalid, bail out */
    if (InvalidFlags != 0) return STATUS_INVALID_PARAMETER;

    /* If ACL is invalid, bail out */
    if (!RtlValidAcl(Acl)) return STATUS_INVALID_ACL;

    /* If there's no free ACE, bail out */
    if (!RtlFirstFreeAce(Acl, (PACE*)&Ace)) return STATUS_INVALID_ACL;

    /* Calculate the size of the ACE and bail out if it's too small */
    AceSize = RtlLengthSid(Sid) + sizeof(ACE);
    if (!(Ace) || ((ULONG_PTR)Ace + AceSize > (ULONG_PTR)Acl + Acl->AclSize))
    {
        return STATUS_ALLOTTED_SPACE_EXCEEDED;
    }

    /* Initialize the header and common fields */
    Ace->Header.AceFlags = (BYTE)Flags;
    Ace->Header.AceType = Type;
    Ace->Header.AceSize = (WORD)AceSize;
    Ace->Mask = AccessMask;

    /* Copy the SID */
    RtlCopySid(RtlLengthSid(Sid), &Ace->SidStart, Sid);

    /* Fill out the ACL header and return */
    Acl->AceCount++;
    Acl->AclRevision = (BYTE)Revision;
    return STATUS_SUCCESS;
}
示例#19
0
/******************************************************************************
 * IsValidSid [ADVAPI32.@]
 *
 * PARAMS
 *   pSid []
 */
BOOL WINAPI
IsValidSid( PSID pSid )
{
    return RtlValidSid( pSid );
}