Logg på med Microsoft
Logg på eller opprett en konto.
Hei,
Velg en annen konto.
Du har flere kontoer
Velg kontoen du vil logge på med.

FEIL #: 374329 (SQLBUDT)

Symptomer

Når Microsoft SQL Server 2005 kjører under nettverkstjenestekontoen, kan du ikke aktivere kryptering med sertifikat. Hvis du klargjør et sertifikat for bruk i kryptering, starter ikke SQL Server. I tillegg kan det hende følgende melding i SQL Server-feilloggen:


Dato Tid Serveren serveren kan ikke laste inn sertifikat som trengs for å opprette en SSL-tilkobling. Den returnerte følgende feil: 0x8009030d. Kontrollere sertifikater for å kontrollere at de er gyldige.
DatoTid Serverfeil: 26014, alvorlighetsgrad: 16 tilstand: 1.

DatoTid Serveren kan ikke laste inn sertifikat som angis av brukeren. Serveren godtar ikke en tilkobling. Du bør kontrollere at sertifikatet er riktig installert. Se "Konfigurere sertifikatet for bruk av SSL" i bøker på Internett.

DatoTid Serverfeil: 17195, alvorlighetsgrad: 16 tilstand: 1.

DatoTid Server-Server kan ikke oppstart fordi serveren er konfigurert til å kreve kryptering, men nettverket biblioteker støtter ikke kryptering.
DatoTid Serverfeil: 17182, alvorlighetsgrad: 16 tilstand: 1.

Årsak

Dette problemet oppstår fordi nettverkstjenestekontoen ikke har tillatelse til å lese de private nøkkelen beholderne.

Løsning

Hvis du vil løse dette problemet, Kompiler og Kjør .cpp koden nedenfor.

Obs! Denne koden gir alle tjenester som kjører under Network Service-kontotilgang til maskinlageret for. Denne koden brukes med forsiktighet.

/*
MKACLS - This utility will list the machine key containers present and allow
the user to change the key container DACL.
*/

#include <stdio.h>
#include <windows.h>
#include <sddl.h>
#include <aclapi.h>
#include <lm.h>

//Get SD for retrieving DACL.
SECURITY_DESCRIPTOR* GetSecurityDescDacl(HCRYPTPROV hProv) {

SECURITY_DESCRIPTOR *sd;
unsigned long size = 0;

CryptGetProvParam(
hProv,
PP_KEYSET_SEC_DESCR,
0,
&size,
DACL_SECURITY_INFORMATION);

int ret = GetLastError();
if (ret != ERROR_INSUFFICIENT_BUFFER) {
fprintf(stderr, "Error getting file security DACL: %d\n", ret);
return 0;
}

sd = (SECURITY_DESCRIPTOR *) malloc(size);
if (! sd) {
fprintf(stderr, "Out of memory for security descriptor!\n");
return 0;
}

CryptGetProvParam(
hProv,
PP_KEYSET_SEC_DESCR,
(BYTE*)sd,
&size,
DACL_SECURITY_INFORMATION);

return sd;
}

//Get DACL from SD.
ACL* GetDacl(SECURITY_DESCRIPTOR *sd) {

ACL *acl;
int defaulted, present;

if (! sd) return 0;

if (! GetSecurityDescriptorDacl(
sd,
&present,
&acl,
&defaulted))
{
fprintf(stderr, "Error getting DACL from security descriptor: %d\n", GetLastError());
return 0;
}

if (! present) {
fprintf(stderr, "Security descriptor has no DACL present\n");
free(acl);
return 0;
}

return acl;
}


ACL *AddSidToAcl(const ACL *pOldACL, PSID pSID)
{
EXPLICIT_ACCESS ea[1] ={{0}};

// Initialize an EXPLICIT_ACCESS structure for an access control entry.
ea[0].grfAccessPermissions = FILE_READ_DATA;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
ea[0].Trustee.ptstrName = (LPTSTR) pSID;

// Create a new DACL that contains the new access control entries and the old ones.

ACL *pNewACL = NULL;
DWORD dwRes = SetEntriesInAcl(1, ea, (ACL*)pOldACL, &pNewACL);
if (ERROR_SUCCESS == dwRes)
return pNewACL;

return NULL;
}


BOOL SetSecurityDescDacl(HCRYPTPROV hProv, const ACL *pACL)
{
PSECURITY_DESCRIPTOR pSD = NULL;
BOOL bRetVal = FALSE;

// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
printf("LocalAlloc Error %u\n", GetLastError());
goto CommonReturn;
}

if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{
printf("InitializeSecurityDescriptor Error %u\n",GetLastError());
goto CommonReturn;
}

// Add the DACL to the security descriptor.
if (!SetSecurityDescriptorDacl(pSD,
TRUE,
(ACL*)pACL,
FALSE))
{
printf("SetSecurityDescriptorDacl Error %u\n", GetLastError());
goto CommonReturn;
}

if(!CryptSetProvParam(
hProv,
PP_KEYSET_SEC_DESCR,
(BYTE*)pSD,
DACL_SECURITY_INFORMATION))
{
printf("CryptSetProvParam failed, lasterror = 0x%08x\n", GetLastError());
goto CommonReturn;
}

bRetVal = TRUE;

CommonReturn:
if (pSD)
LocalFree(pSD);

return bRetVal;
}




PSID GetSIDForAccount(LPCSTR pszAcct)
{
PSIDpSID = NULL;
DWORDcbSID = 0;
DWORD cbDomain = 0;
LPTSTR pszDomain = NULL;
SID_NAME_USE snu;


LookupAccountName(NULL, pszAcct, NULL, &cbSID, NULL, &cbDomain, &snu);

if ( cbSID )
{
pSID = (PSID)malloc(cbSID);
pszDomain = (LPTSTR)malloc(cbDomain);

if ( pSID && pszDomain)
{
if ( LookupAccountName(NULL, pszAcct, pSID, &cbSID, pszDomain, &cbDomain, &snu) )
{
// Success. Therefore, kill the domain buffer that we do not need.
free(pszDomain);
pszDomain = NULL;
}
else
{
// Failed. Therefore, kill both buffers.
free(pszDomain);
pszDomain = NULL;
free(pSID);
pSID = NULL;
}
}
}

return pSID;
}

BOOL ChangeContainerACL(LPCSTR pszContainer)
{
HCRYPTPROV hProv = 0;
BOOL bRetVal = FALSE;

if(CryptAcquireContext(&hProv,
pszContainer,
MS_DEF_PROV,
PROV_RSA_FULL,
CRYPT_MACHINE_KEYSET))
{

SECURITY_DESCRIPTOR *pSD = GetSecurityDescDacl(hProv);
if (pSD)
{
ACL *pCurACL = GetDacl(pSD);
if (pCurACL)
{
//TODO: This should be replaced with a call to RtlCreateServiceSid for LH.
PSID pSID = GetSIDForAccount("NetworkService");

if ( pSID)
{
ACL *pNewACL = AddSidToAcl(pCurACL, pSID);
if ( pNewACL )
{
bRetVal = SetSecurityDescDacl(hProv, pNewACL);
LocalFree(pNewACL);
}

free(pSID);
}

LocalFree(pCurACL);
}
free(pSD);
}

CryptReleaseContext(hProv, 0);
}
else
printf("Error opening key container %s\n", pszContainer);

return bRetVal;
}

int __cdecl main()
{
HCRYPTPROV hProv= 0;

printf("Looking for CAPI machine key containers...\n");

if(CryptAcquireContext(&hProv,
NULL,
MS_DEF_PROV,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
{

for (int i=0 ; ; i++)
{
DWORD dwFlags = i ? 0 : CRYPT_FIRST;
const DWORD BUFLEN = 4096;
DWORD dwBufLen = BUFLEN;
BYTE szBuf[BUFLEN];

if(!CryptGetProvParam(hProv, PP_ENUMCONTAINERS, szBuf, &dwBufLen, dwFlags))
{
DWORD dwError = GetLastError();
if( dwError != ERROR_NO_MORE_ITEMS && dwError != ERROR_FILE_NOT_FOUND)
printf("Error reading container name - %08x\n", GetLastError());
break;
}
else
{
if ( !ChangeContainerACL((LPCSTR)szBuf) )
printf("Error changing ACL on container %s\n", szBuf);
else
printf("Changed ACL on container %s\n", szBuf);
}

}

CryptReleaseContext(hProv,0);
}
else
printf("Error opening CSP - %08x\n", GetLastError());

printf("Done\n");

return 0;
}

Denne koden gir tillatelser for Network Service-kontoen til å lese de private nøkkelen beholderne. Når du har kjørt denne koden, kan det hende følgende melding i feilloggen for SQL Server når du starter SQL Server:


Dato Tid Server sertifikatet lastet er for kryptering.

Status

Microsoft har bekreftet at dette er en feil i Microsoft-produktene som er oppført i delen "Gjelder for".

Trenger du mer hjelp?

Utvid ferdighetene dine
Utforsk opplæring
Vær først ute med de nye funksjonene
Bli med i Microsoft Insiders

Var denne informasjonen nyttig?

Hvor fornøyd er du med språkkvaliteten?
Hva påvirket opplevelsen din?

Takk for tilbakemeldingen!

×