|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 2000
//
// File: info.cpp
//
//--------------------------------------------------------------------------
#include <pch.cpp>
#pragma hdrstop
#include <certca.h>
#include <ntdsapi.h>
#include <dsgetdc.h>
#include <lmerr.h>
#include <lmaccess.h>
#include <lmapibuf.h>
#define __dwFILE__ __dwFILE_CERTUTIL_INFO_CPP__
#define DC_DELBAD 0x00000001
#define DC_DELALL 0x00000002
#define DC_VERIFY 0x00000004
// If you invoke DSSTORE with DC=mydc,DC=rd,DC=com DSSTORE calls
// DsGetDcName(NULL, L"mydc", NULL, NULL, DS_RETURN_DNS_NAME, &pDCInfo);
//
// I suspect changing the code to pass L"mydc.rd.com" instead of L"mydc" would
// solve the problem. I will look into this for the port of the code to
// certutil.exe.
//
// -----Original Message-----
// From: Christophe Lapeyre (Intl Vendor)
// Sent: Tuesday, January 09, 2001 3:30 AM
// To: Certificate Server Discussion Alias
// Subject: DSSTORE error 1355 (DsGetDCName failed)
//
//
// Hi all,
//
// I encountered the following problem with the DSSTORE tool:
//
// DSSTORE DC=mydc,DC=rd,DC=com -display
// DsGetDCName failed! - rc=1355 GLE - 3e5
// DsGetDCName failed! - rc=1355 GLE - 3e5
//
// Nltest /dsgetdc:mydc.rd.com just run ok.
//
// My Netbios domain name is different from my DNS domain name.
//
//
//
// There is a preview Kb article numbered Q280122, but I haven't been able to
// find a fix for this.
HRESULT ExtractCertSubject( IN CERT_CONTEXT const *pcc, IN DWORD dwType, IN DWORD dwFlags, OUT WCHAR **ppwszOut) { HRESULT hr; DWORD cwc; DWORD cwcBuf; WCHAR *pwszOut = NULL;
*ppwszOut = NULL; cwcBuf = 0; while (TRUE) { cwc = CertGetNameString( pcc, dwType, dwFlags, NULL, // pvTypePara
pwszOut, cwcBuf); if (1 == cwc) { hr = CRYPT_E_NOT_FOUND; _JumpError(hr, error, "CertGetNameString"); } if (NULL != pwszOut) { break; } pwszOut = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR)); if (NULL == pwszOut) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } cwcBuf = cwc; } *ppwszOut = pwszOut; pwszOut = NULL; hr = S_OK;
error: if (NULL != pwszOut) { LocalFree(pwszOut); } return(hr); }
static WCHAR *s_apwszKDCTemplates[] = { wszCERTTYPE_DC_AUTH, wszCERTTYPE_DS_EMAIL_REPLICATION, wszCERTTYPE_DC, };
HRESULT CheckForKDCCertificate( IN WCHAR const *pwszDC, IN DWORD dwFlags) { HRESULT hr; HCERTSTORE hStoreRemote = NULL; WCHAR wszStorePath[512]; WCHAR *apwszCertType[2] = { NULL, NULL }; DWORD cCert = 0; DWORD dwOpenFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE; CERT_CONTEXT const *pcc = NULL; CERT_CONTEXT const *pccPrev = NULL; BOOL fDelete; BOOL fNewLine; DWORD i; DWORD j; CERT_ENHKEY_USAGE *pUsage = NULL;
// If not doing delete operations, open "ReadOnly"
if (0 == ((DC_DELALL | DC_DELBAD) & dwFlags)) { dwOpenFlags |= CERT_STORE_READONLY_FLAG; }
swprintf(wszStorePath, L"\\\\%ws\\" wszMY_CERTSTORE, pwszDC); hStoreRemote = CertOpenStore( CERT_STORE_PROV_SYSTEM_W, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, dwOpenFlags, (VOID *) wszStorePath); if (NULL == hStoreRemote) { hr = myHLastError(); _JumpError2(hr, error, "CertOpenStore", E_ACCESSDENIED); }
wprintf( myLoadResourceString(IDS_FORMAT_KDCCERTS), // "** KDC Certificates for DC %ws"
pwszDC); wprintf(wszNewLine);
// Look for KDC certs
fNewLine = FALSE; while (TRUE) { BOOL fKDCCert;
for (i = 0; i < ARRAYSIZE(apwszCertType); i++) { if (NULL != apwszCertType[i]) { LocalFree(apwszCertType[i]); apwszCertType[i] = NULL; } }
pcc = CertEnumCertificatesInStore(hStoreRemote, pccPrev); if (NULL == pcc) { hr = myHLastError(); _PrintError2(hr, "CertEnumCertificatesInStore", CRYPT_E_NOT_FOUND); break; } pccPrev = pcc;
fKDCCert = FALSE; hr = cuGetCertType( pcc->pCertInfo, &apwszCertType[0], // ppwszCertTypeNameV1
NULL, // ppwszDisplayNameV1
NULL, // ppwszCertTypeObjId
&apwszCertType[1], // ppwszCertTypeName
NULL); // ppwszDisplayName
if (S_OK != hr) { _PrintError(hr, "cuGetCertType"); } else { for (i = 0; i < ARRAYSIZE(apwszCertType); i++) { if (NULL != apwszCertType[i]) { for (j = 0; j < ARRAYSIZE(s_apwszKDCTemplates); j++) { if (0 == mylstrcmpiS( apwszCertType[i], s_apwszKDCTemplates[j])) { fKDCCert = TRUE;
} } } } } if (!fKDCCert) { WCHAR const *pwsz = apwszCertType[0]; if (NULL == apwszCertType[0]) { pwsz = apwszCertType[1]; } if (g_fVerbose) { wprintf( myLoadResourceString(IDS_FORMAT_CERT_TYPE_NOT_DC), pwsz); wprintf(wszNewLine); } }
if (NULL != pUsage) { LocalFree(pUsage); pUsage = NULL; } hr = myCertGetEnhancedKeyUsage( pcc, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, &pUsage); if (S_OK != hr) { _PrintError2(hr, "myCertGetEnhancedKeyUsage", CRYPT_E_NOT_FOUND); } else { for (i = 0; i < pUsage->cUsageIdentifier; i++) { if (0 == strcmp( szOID_KP_SMARTCARD_LOGON, pUsage->rgpszUsageIdentifier[i])) { fKDCCert = TRUE; break; } } } if (!fKDCCert) { if (g_fVerbose) { wprintf( myLoadResourceString(IDS_FORMAT_CERT_USAGE_MISSING), L"szOID_KP_SMARTCARD_LOGON"); wprintf(wszNewLine); } if (!g_fForce || fDelete) { continue; } }
// Cert passed test, dump issuer and subject
wprintf(myLoadResourceString(IDS_FORMAT_CERT_COLON), cCert); wprintf(wszNewLine);
hr = cuDumpAsnBinaryQuiet( pcc->pbCertEncoded, pcc->cbCertEncoded, MAXDWORD); _PrintIfError(hr, "cuDumpAsnBinaryQuiet");
wprintf(wszNewLine); cCert++;
// perform operations on certificatess
fDelete = 0 != (DC_DELALL & dwFlags); if ((DC_VERIFY | DC_DELBAD) & dwFlags) { char *apszUsage[] = { szOID_PKIX_KP_SERVER_AUTH, szOID_KP_SMARTCARD_LOGON, }; DWORD VerifyState;
hr = cuVerifyCertContext( pcc, NULL, ARRAYSIZE(apszUsage), apszUsage, 0, // cIssuancePolicies
NULL, // apszIssuancePolicies
TRUE, // fNTAuth
&VerifyState); if (S_OK != hr) { _PrintError(hr, "cuVerifyCertContext"); if (CRYPT_E_REVOCATION_OFFLINE != hr) { fDelete = 0 != (DC_DELBAD & dwFlags); } } } if (fDelete) { CERT_CONTEXT const *pccDel;
pccDel = CertDuplicateCertificateContext(pcc); if (!CertDeleteCertificateFromStore(pccDel)) { hr = myHLastError(); wprintf(myLoadResourceString(IDS_FORMAT_DELETE_CERT_FROM_STORE_FAILED), hr); wprintf(wszNewLine); } else { wprintf(myLoadResourceString(IDS_FORMAT_DELETE_DC_CERT)); wprintf(wszNewLine); } } }
swprintf(wszStorePath, myLoadResourceString(IDS_FORMAT_KDC_PATH), cCert, pwszDC); wprintf(wszStorePath); wprintf(wszNewLine); if (0 == cCert) { wprintf(myLoadResourceString(IDS_NO_KDC_MY_STORE)); wprintf(wszNewLine); hr = CRYPT_E_NOT_FOUND; _JumpError(hr, error, "cCert"); } hr = S_OK;
error: if (NULL != pUsage) { LocalFree(pUsage); } for (i = 0; i < ARRAYSIZE(apwszCertType); i++) { if (NULL != apwszCertType[i]) { LocalFree(apwszCertType[i]); } } if (NULL != hStoreRemote) { CertCloseStore(hStoreRemote, 0); } return(hr); }
// This function queries the access token specified by the hToken parameter,
// and returns an allocated copy of the TokenUser information on success.
//
// The access token specified by hToken must be opened for TOKEN_QUERY access.
//
// On success, the return value is TRUE. The caller is responsible for freeing
// the resultant UserSid via LocalFree.
//
// On failure, the caller does not need to free any buffer.
HRESULT GetTokenUserSid( IN HANDLE hToken, // token to query
IN OUT PSID *ppUserSid) // resultant user sid
{ HRESULT hr; BYTE FastBuffer[256]; BYTE *SlowBuffer = NULL; TOKEN_USER *ptgUser; DWORD cbBuffer; DWORD cbSid;
*ppUserSid = NULL;
// try querying based on a fast stack based buffer first.
ptgUser = (TOKEN_USER *) FastBuffer; cbBuffer = sizeof(FastBuffer);
if (!GetTokenInformation( hToken, // identifies access token
TokenUser, // TokenUser info type
ptgUser, // retrieved info buffer
cbBuffer, // size of buffer passed-in
&cbBuffer)) // required buffer size
{ hr = myHLastError(); if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) != hr) { _JumpError(hr, error, "GetTokenInformation"); }
// try again with the specified buffer size
SlowBuffer = (BYTE *) LocalAlloc(LMEM_FIXED, cbBuffer); if (NULL == SlowBuffer) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } ptgUser = (TOKEN_USER *) SlowBuffer;
if (!GetTokenInformation( hToken, // identifies access token
TokenUser, // TokenUser info type
ptgUser, // retrieved info buffer
cbBuffer, // size of buffer passed-in
&cbBuffer)) // required buffer size
{ hr = myHLastError(); _JumpError(hr, error, "GetTokenInformation"); } }
// if we got the token info, copy the relevant element for the caller.
cbSid = GetLengthSid(ptgUser->User.Sid); *ppUserSid = LocalAlloc(LMEM_FIXED, cbSid); if (NULL == *ppUserSid) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); }
if (!CopySid(cbSid, *ppUserSid, ptgUser->User.Sid)) { hr = myHLastError(); _JumpError(hr, error, "CopySid"); } hr = S_OK;
error: if (S_OK != hr) { if (NULL != *ppUserSid) { LocalFree(*ppUserSid); *ppUserSid = NULL; } } if (NULL != SlowBuffer) { LocalFree(SlowBuffer); } return(hr); }
// This routine obtains a domain controller computer name associated with
// the account related to the hToken access token.
//
// hToken should be opened for TOKEN_QUERY access.
// pwszDomain should be of size (UNCLEN+1)
HRESULT GetDomainControllers( OPTIONAL IN WCHAR const *pwszDomain, IN HANDLE hToken, OUT DS_DOMAIN_CONTROLLER_INFO_1 **ppDCInfoOut, OUT DWORD *pcDC) { HRESULT hr; PSID pSidUser = NULL; // sid of client user.
WCHAR wszUserName[UNLEN + 1]; DWORD cwcUserName; WCHAR wszDomainName[DNLEN + 1]; // domain we want a controller for.
DWORD cwcDomainName; SID_NAME_USE snu; DOMAIN_CONTROLLER_INFO *pDomainInfo = NULL; DS_DOMAIN_CONTROLLER_INFO_1 *pDcInfo = NULL; HANDLE hDS = INVALID_HANDLE_VALUE; BOOL fSuccess = FALSE;
*ppDCInfoOut = NULL; if (NULL == pwszDomain) { // first, get the user sid associated with the specified access token.
hr = GetTokenUserSid(hToken, &pSidUser); _JumpIfError(hr, error, "GetTokenUserSid");
// next, lookup the domain name associated with the specified account.
cwcUserName = ARRAYSIZE(wszUserName); cwcDomainName = ARRAYSIZE(wszDomainName); if (!LookupAccountSid( NULL, pSidUser, wszUserName, &cwcUserName, wszDomainName, &cwcDomainName, &snu)) { hr = myHLastError(); _JumpError(hr, error, "LookupAccountSid"); } } else { wcscpy(wszDomainName, pwszDomain); }
hr = DsGetDcName( NULL, wszDomainName, NULL, NULL, DS_RETURN_DNS_NAME, &pDomainInfo); _JumpIfError(hr, error, "DsGetDcName");
// Get a handle to the DS on that machine
hr = DsBind(pDomainInfo->DomainControllerName, NULL, &hDS); _JumpIfError(hr, error, "DsBind");
// Use the handle to enumerate all of the DCs
hr = DsGetDomainControllerInfo( hDS, pDomainInfo->DomainName, 1, // info level
pcDC, (VOID **) ppDCInfoOut); _JumpIfError(hr, error, "DsGetDomainControllerInfo");
error: if (INVALID_HANDLE_VALUE != hDS) { DsUnBind(&hDS); } if (NULL != pDomainInfo) { NetApiBufferFree(pDomainInfo); } if (NULL != pSidUser) { LocalFree(pSidUser); } return(hr); }
HRESULT OpenRemoteEnterpriseRoot( IN WCHAR const *pwszDC) { HRESULT hr; HCERTSTORE hStoreRemote = NULL; WCHAR wszStorePath[512]; DWORD cCert = 0; CERT_CONTEXT const *pcc = NULL; CERT_CONTEXT const *pccPrev;
swprintf(wszStorePath, L"\\\\%ws\\" wszROOT_CERTSTORE, pwszDC); hStoreRemote = CertOpenStore( CERT_STORE_PROV_SYSTEM_W, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE | CERT_STORE_READONLY_FLAG, (VOID *) wszStorePath); if (NULL == hStoreRemote) { hr = myHLastError(); _JumpError2(hr, error, "CertOpenStore", E_ACCESSDENIED); }
wprintf( myLoadResourceString(IDS_FORMAT_DCROOTCERTS), // "** Enterprise Root Certificates for DC %ws"
pwszDC); wprintf(wszNewLine);
// Dump issuer of enterprise roots.
pccPrev = NULL; while (TRUE) { pcc = CertEnumCertificatesInStore(hStoreRemote, pccPrev); if (NULL == pcc) { hr = myHLastError(); _PrintError2(hr, "CertEnumCertificatesInStore", CRYPT_E_NOT_FOUND); break; }
wprintf(myLoadResourceString(IDS_FORMAT_CERT_COLON), cCert); wprintf(wszNewLine);
hr = cuDumpAsnBinaryQuiet( pcc->pbCertEncoded, pcc->cbCertEncoded, MAXDWORD); _PrintIfError(hr, "cuDumpAsnBinaryQuiet");
wprintf(wszNewLine); cCert++; pccPrev = pcc; } if (0 == cCert) { wprintf(myLoadResourceString(IDS_NO_KDC_ENT_STORE)); wprintf(wszNewLine); hr = CRYPT_E_NOT_FOUND; } hr = S_OK;
error: if (NULL != hStoreRemote) { CertCloseStore(hStoreRemote, 0); } return(hr); }
HRESULT verbDCInfo( IN WCHAR const *pwszOption, OPTIONAL IN WCHAR const *pwszFlags, IN WCHAR const *pwszArg2, IN WCHAR const *pwszArg3, IN WCHAR const *pwszArg4) { HRESULT hr; HRESULT hrSave; HANDLE hToken = NULL; DS_DOMAIN_CONTROLLER_INFO_1 *pDcInfo = NULL; DWORD cDC = 0; DWORD dwFlags; DWORD i; WCHAR *pwszDomain = NULL;
dwFlags = 0; if (NULL != pwszFlags) { if (0 == LSTRCMPIS(pwszFlags, L"DeleteAll")) { dwFlags = DC_DELALL; } else if (0 == LSTRCMPIS(pwszFlags, L"DeleteBad")) { dwFlags = DC_DELBAD | DC_VERIFY; } else if (0 == LSTRCMPIS(pwszFlags, L"Verify")) { dwFlags = DC_VERIFY; } else { hr = E_INVALIDARG; _JumpError(hr, error, "bad Flags"); } }
// Grovel the process token for user identity. Used in determining
// target domain
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) { hr = myHLastError(); _JumpError(hr, error, "OpenProcessToken"); }
// Use DS APIs to get all of the DCs in our domain
hr = GetDomainControllers(pwszDomain, hToken, &pDcInfo, &cDC); _JumpIfError(hr, error, "GetDomainControllers");
for (i = 0; i < cDC; i++) { wprintf(L"%u: %ws\n", i, pDcInfo[i].NetbiosName); } hrSave = S_OK; for (i = 0; i < cDC; i++) { WCHAR wszBuffer[512];
wprintf(wszNewLine); wprintf( myLoadResourceString(IDS_FORMAT_TESTINGDC), // "*** Testing DC[%u]: %ws"
i, pDcInfo[i].NetbiosName); wprintf(wszNewLine);
// Is DC available ?
wsprintf(wszBuffer, L"\\\\%ws\\netlogon", pDcInfo[i].NetbiosName);
if (MAXDWORD == GetFileAttributes(wszBuffer)) { hr = myHLastError(); _PrintError2(hr, "GetFileAttributes", hr); cuPrintError(IDS_DCUNAVAILABLE, hr); if (S_OK == hrSave) { hrSave = hr; } continue; }
// Open the enterprise root store, and make sure it's got the
// NTDEV ROOT CERTIFICATE (subject #defined above)
hr = OpenRemoteEnterpriseRoot(pDcInfo[i].NetbiosName); if (S_OK != hr) { _PrintError2(hr, "OpenRemoteEnterpriseRoot", hr); cuPrintError(IDS_REMOTEENTROOT, hr); if (S_OK == hrSave) { hrSave = hr; } }
// Make sure the machine has a *valid* KDC certificate
hr = CheckForKDCCertificate( pDcInfo[i].NetbiosName, dwFlags); if (S_OK != hr) { _PrintError2(hr, "CheckForKDCCertificate", hr); cuPrintError(IDS_REMOTEKDCCERT, hr); if (S_OK == hrSave) { hrSave = hr; } } } wprintf(wszNewLine); hr = hrSave; _JumpIfError2(hr, error, "verbDCInfo", hr);
error: if (NULL != pDcInfo) { DsFreeDomainControllerInfo(1, cDC, pDcInfo); } return(hr); }
BOOL IsAutoenrolledCert( IN CERT_CONTEXT const *pcc, OPTIONAL IN WCHAR const *pwszzTemplates) { HRESULT hr; BOOL fMatch = FALSE; WCHAR *pwszTemplate = NULL; WCHAR const *pwsz;
hr = cuGetCertType(pcc->pCertInfo, &pwszTemplate, NULL, NULL, NULL, NULL); if (S_OK != hr) { _PrintError(hr, "cuGetCertType"); if (CRYPT_E_NOT_FOUND == hr) { hr = S_OK; } goto error; }
pwsz = pwszzTemplates; if (NULL != pwsz) { for ( ; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1) { if (0 == mylstrcmpiL(pwsz, pwszTemplate)) { fMatch = TRUE; break; } } } if (!fMatch) { DWORD i; for (i = 0; i < ARRAYSIZE(s_apwszKDCTemplates); i++) { if (0 == mylstrcmpiS(pwszTemplate, s_apwszKDCTemplates[i])) { fMatch = TRUE; } } }
error: if (NULL != pwszTemplate) { LocalFree(pwszTemplate); } return(fMatch); }
//
// Check for autoenrolled certificate
//
HRESULT CheckForV1AutoenrolledCertificate( IN WCHAR const *pwszDC, OPTIONAL IN WCHAR const *pwszzTemplates) { HRESULT hr; HCERTSTORE hStoreRemote = NULL; WCHAR wszStorePath[512]; DWORD cCert; DWORD cCertArchived; DWORD dwArchiveBit; CERT_CONTEXT const *pcc;
swprintf(wszStorePath, L"\\\\%ws\\" wszMY_CERTSTORE, pwszDC);
hStoreRemote = CertOpenStore( CERT_STORE_PROV_SYSTEM_W, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_ENUM_ARCHIVED_FLAG, (VOID *) wszStorePath); if (NULL == hStoreRemote) { hr = myHLastError(); wprintf(myLoadResourceString(IDS_FORMAT_OPEN_REMOTE_MY_FAILED), hr); wprintf(wszNewLine); goto error; }
cCert = 0; cCertArchived = 0; pcc = NULL; while (TRUE) { pcc = CertEnumCertificatesInStore(hStoreRemote, pcc); if (NULL == pcc) { break; } if (!IsAutoenrolledCert(pcc, pwszzTemplates) && 1 >= g_fForce) { continue; }
// Cert passed test, dump issuer and subject
wprintf(myLoadResourceString(IDS_FORMAT_CERT_COLON), cCert); wprintf(wszNewLine);
if (!CertGetCertificateContextProperty( pcc, CERT_ARCHIVED_PROP_ID, NULL, &dwArchiveBit)) { hr = myHLastError(); if (hr != CRYPT_E_NOT_FOUND) { wprintf(myLoadResourceString(IDS_FORMAT_ERROR_GET_ARCHIVE_PROP), hr); wprintf(wszNewLine); } } else { wprintf(myLoadResourceString(IDS_LIST_ARCHIVED_CERT)); wprintf(wszNewLine); cCertArchived++; }
hr = cuDumpSerial(g_wszPad2, IDS_SERIAL, &pcc->pCertInfo->SerialNumber); _PrintIfError(hr, "cuDumpSerial");
hr = cuDisplayCertNames(FALSE, g_wszPad2, pcc->pCertInfo); _PrintIfError(hr, "cuDisplayCertNames");
hr = cuDumpCertType(g_wszPad2, pcc->pCertInfo); _PrintIfError2(hr, "cuDumpCertType", CRYPT_E_NOT_FOUND);
hr = cuDisplayHash( g_wszPad2, pcc, NULL, CERT_SHA1_HASH_PROP_ID, L"sha1"); _PrintIfError(hr, "cuDisplayHash");
wprintf(wszNewLine);
cCert++; } if (0 == cCert) { wprintf(myLoadResourceString(IDS_NO_AUTOENROLLED_CERT)); wprintf(wszNewLine); hr = CRYPT_E_NOT_FOUND; _JumpError(hr, error, "no AE certs"); } wprintf( myLoadResourceString(IDS_FORMAT_MACHINE_AND_ARCHIVED_CERTS), cCert, cCertArchived); wprintf(L" "); wprintf(myLoadResourceString(IDS_FORMAT_FOR_DC), pwszDC); wprintf(wszNewLine); hr = S_OK;
error: if (NULL != hStoreRemote) { CertCloseStore(hStoreRemote, 0); } return(hr); }
HRESULT CheckForV1AutoenrollmentObject( IN WCHAR const *pwszDC, OUT WCHAR **ppwszzTemplates) { HRESULT hr; HCERTSTORE hStoreRemote = NULL; WCHAR wszStorePath[512]; DWORD cAE; CTL_CONTEXT const *pCTL; DWORD cwc; WCHAR *pwsz;
*ppwszzTemplates = NULL; swprintf(wszStorePath, L"\\\\%ws\\" wszACRS_CERTSTORE, pwszDC);
hStoreRemote = CertOpenStore( CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG, (VOID *) wszStorePath); if (NULL == hStoreRemote) { hr = myHLastError(); wprintf(myLoadResourceString(IDS_FORMAT_OPEN_STORE_REMOTE_ENT_FAILED), hr); wprintf(wszNewLine); goto error; }
cwc = 1; cAE = 0; pCTL = NULL; while (TRUE) { pCTL = CertEnumCTLsInStore(hStoreRemote, pCTL); if (NULL == pCTL) { break; } cwc += wcslen((WCHAR const *) pCTL->pCtlInfo->ListIdentifier.pbData) + 1; cAE++; } if (0 == cAE) { wprintf(myLoadResourceString(IDS_NO_AUTOENROLL_OBJECT)); wprintf(wszNewLine); } else { pwsz = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR)); if (NULL == pwsz) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } *ppwszzTemplates = pwsz;
wprintf(myLoadResourceString(IDS_V1_AUTOENROLLMENT_OBJECTS_COLON)); while (TRUE) { pCTL = CertEnumCTLsInStore(hStoreRemote, pCTL); if (NULL == pCTL) { break; } wprintf(L" %ws\n", pCTL->pCtlInfo->ListIdentifier.pbData); wcscpy(pwsz, (WCHAR const *) pCTL->pCtlInfo->ListIdentifier.pbData); pwsz += wcslen(pwsz) + 1; cAE++; } *pwsz++ = L'\0'; CSASSERT(cwc == SAFE_SUBTRACT_POINTERS(pwsz, *ppwszzTemplates)); } wprintf(wszNewLine); hr = S_OK;
error: if (NULL != hStoreRemote) { CertCloseStore(hStoreRemote, 0); } return(hr); }
//
// This function takes a Marc Jacobs supplied text file (results from SSOLogon
// scripts) and runs through entmon for each machine in the list
//
HRESULT verbEntInfo( IN WCHAR const *pwszOption, IN WCHAR const *pwszSamMachine, IN WCHAR const *pwszArg2, IN WCHAR const *pwszArg3, IN WCHAR const *pwszArg4) { HRESULT hr; HRESULT hrSave; WCHAR *pwszDomain = NULL; WCHAR *pwszMachine = NULL; WCHAR *pwszMachineName = NULL; WCHAR *pwszzTemplates = NULL;
hr = mySplitConfigString(pwszSamMachine, &pwszDomain, &pwszMachine); _JumpIfError(hr, error, "mySplitConfigString");
if (NULL == pwszMachine || NULL == wcschr(pwszMachine, L'$')) { wprintf(myLoadResourceString(IDS_ERROR_CHECK_MACHINE_NAME)); wprintf(wszNewLine); hr = E_INVALIDARG; _JumpError(hr, error, "bad machine name"); }
// knock off trailing $
hr = myDupString(pwszMachine, &pwszMachineName); _JumpIfError(hr, error, "myDupString");
pwszMachineName[wcslen(pwszMachineName)-1] = L'\0';
// assume for now that we're only interested in opening remote root store
wprintf(myLoadResourceString(IDS_FORMAT_MACHINE_LIST), pwszMachine); wprintf(wszNewLine);
// Cert store functions, if first fails, bail.
hrSave = S_OK; hr = OpenRemoteEnterpriseRoot(pwszMachineName); if (S_OK != hr) { cuPrintError(IDS_REMOTEENTROOT, hr); _PrintError2(hr, "OpenRemoteEnterpriseRoot", hr); hrSave = hr; } else { hr = CheckForV1AutoenrollmentObject(pwszMachineName, &pwszzTemplates); _PrintIfError(hr, "CheckForV1AutoenrollmentObject"); hrSave = hr;
hr = CheckForV1AutoenrolledCertificate(pwszMachineName, pwszzTemplates); _PrintIfError(hr, "CheckForV1AutoenrolledCertificate"); if (S_OK == hrSave && CRYPT_E_NOT_FOUND != hr) { hrSave = hr; } } hr = cuGetGroupMembership(pwszSamMachine); _PrintIfError(hr, "cuGetGroupMembership");
hr = hrSave; _JumpIfError2(hr, error, "RunEntmon", hr);
wprintf(wszNewLine);
error: if (NULL != pwszzTemplates) { LocalFree(pwszzTemplates); } if (NULL != pwszDomain) { LocalFree(pwszDomain); } if (NULL != pwszMachine) { LocalFree(pwszMachine); } if (NULL != pwszMachineName) { LocalFree(pwszMachineName); } return(hr); }
|