Can't compile mkacls.cpp as suggested in BUG #: 374329 (SQLBUDT)

from cl.exe I get a bunch of linker errors:
/out:mkacls.exe
mkacls.obj
mkacls.obj : error LNK2019: unresolved external symbol __imp__CryptGetProvParam@
20 referenced in function "struct _SECURITY_DESCRIPTOR * __cdecl GetSecurityDesc
Dacl(unsigned long)" (?GetSecurityDescDacl@@YAPAU_SECURITY_DESCRIPTOR@@K@Z)
mkacls.obj : error LNK2019: unresolved external symbol __imp__GetSecurityDescrip
torDacl@16 referenced in function "struct _ACL * __cdecl GetDacl(struct _SECURIT
Y_DESCRIPTOR *)" (?GetDacl@@YAPAU_ACL@@PAU_SECURITY_DESCRIPTOR@@@Z)
mkacls.obj : error LNK2019: unresolved external symbol__imp__SetEntriesInAclA@1
6 referenced in function "struct _ACL * __cdecl AddSidToAcl(struct _ACL const *,
void *)" (?AddSidToAcl@@YAPAU_ACL@@PBU1@PAX@Z)
mkacls.obj : error LNK2019: unresolved external symbol __imp__CryptSetProvParam@
16 referenced in function "int __cdecl SetSecurityDescDacl(unsigned long,struct
_ACL const *)" (?SetSecurityDescDacl@@YAHKPBU_ACL@@@Z)
mkacls.obj : error LNK2019: unresolved external symbol __imp__SetSecurityDescrip
torDacl@16 referenced in function "int __cdecl SetSecurityDescDacl(unsigned long
,struct _ACL const *)" (?SetSecurityDescDacl@@YAHKPBU_ACL@@@Z)
mkacls.obj : error LNK2019: unresolved external symbol __imp__InitializeSecurity
Descriptor@8 referenced in function "int __cdecl SetSecurityDescDacl(unsigned lo
ng,struct _ACL const *)" (?SetSecurityDescDacl@@YAHKPBU_ACL@@@Z)
mkacls.obj : error LNK2019: unresolved external symbol __imp__LookupAccountNameA
@28 referenced in function "void * __cdecl GetSIDForAccount(char const *)" (?GetSIDForAccount@@YAPAXPBD@Z)
mkacls.obj : error LNK2019: unresolved external symbol __imp__CryptReleaseContext@8 referenced in function "int __cdecl ChangeContainerACL(char const *)" (?ChangeContainerACL@@YAHPBD@Z)
mkacls.obj : error LNK2019: unresolved external symbol __imp__CryptAcquireContextA@20 referenced in function "int __cdecl ChangeContainerACL(char const *)" (?Ch
angeContainerACL@@YAHPBD@Z)
mkacls.exe : fatal error LNK1120: 9 unresolved externals

from the IDE multiple errors after the #includes i.e. ; expected

[3907 byte] By [davidwj] at [2008-2-15]
# 1

/*

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

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <sddl.h>
#include <aclapi.h>
#include <lm.h>
#include <Wincrypt.h>
// Fixed one error Wincrypt.h was also needed.

//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)

{

PSID pSID = NULL;

DWORD cbSID = 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;

}

// mkacls.cpp : Defines the entry point for the console application.

//

int _tmain(int argc, _TCHAR* argv[])
{
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;
}

// Now I have to fix a bunch more bugs in the source..
// would be nice if it would work as posted in a support area

davidwj at 2007-9-8 > top of Msdn Tech,SQL Server,SQL Server Setup & Upgrade...
# 2

Is this still an issue for you? I'm trying to clean up really old posts, and ran across this one. I'll mark the issue as answered; if you are still looking for help on this problem feel free to respond and I'll try to redirect to someone who can answer.

Paul

PaulNicholson-MSFT at 2007-9-8 > top of Msdn Tech,SQL Server,SQL Server Setup & Upgrade...

SQL Server

Site Classified