666 lines
19 KiB
C++
666 lines
19 KiB
C++
#include "schema.h"
|
|
#pragma hdrstop
|
|
|
|
#include "initguid.h"
|
|
#include "iadmw.h"
|
|
#include "schemini.hxx"
|
|
|
|
#if _IIS_6_0
|
|
#include "..\adsiis\globdata.cxx"
|
|
#elif _IIS_5_1
|
|
#include "..\adsiis\iis51\globdata.cxx"
|
|
#else
|
|
#error "Neither _IIS_6_0 nor _IIS_5_1 is defined"
|
|
#endif
|
|
|
|
#define DEFAULT_TIMEOUT_VALUE 30000
|
|
|
|
HRESULT SetAdminACL(IMSAdminBase * pAdminBase);
|
|
DWORD
|
|
GetPrincipalSID (
|
|
LPTSTR Principal,
|
|
PSID *Sid,
|
|
BOOL *pbWellKnownSID
|
|
);
|
|
|
|
MetaHandle::MetaHandle(IMSAdminBasePtr _pmb) : pmb(_pmb) {
|
|
if (pmb)
|
|
pmb->AddRef();
|
|
h = 0;
|
|
}
|
|
MetaHandle::~MetaHandle() {
|
|
if (pmb) {
|
|
if (h)
|
|
pmb->CloseKey(h);
|
|
pmb->Release();
|
|
}
|
|
}
|
|
|
|
struct WideStrMapEntry {
|
|
LPWSTR m_str;
|
|
void *m_data;
|
|
};
|
|
|
|
class WideStrMap {
|
|
WideStrMapEntry *map;
|
|
int count;
|
|
int mapSize;
|
|
public:
|
|
WideStrMap();
|
|
~WideStrMap();
|
|
BOOL CheckSpace();
|
|
BOOL Add(LPWSTR str, void *data);
|
|
void *Find(LPWSTR str);
|
|
void *operator[] (LPWSTR str);
|
|
};
|
|
|
|
WideStrMap::WideStrMap() {
|
|
count = 0;
|
|
mapSize = 64;
|
|
map = (WideStrMapEntry *)malloc(sizeof(WideStrMapEntry) * mapSize);
|
|
}
|
|
|
|
WideStrMap::~WideStrMap() {
|
|
free(map);
|
|
}
|
|
|
|
BOOL WideStrMap::CheckSpace() {
|
|
if (count < mapSize)
|
|
return TRUE;
|
|
mapSize += 32;
|
|
if ((map = (WideStrMapEntry *)realloc(map, sizeof(WideStrMapEntry)*mapSize)) == NULL)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WideStrMap::Add(LPWSTR str, void *data) {
|
|
if (!CheckSpace())
|
|
return FALSE;
|
|
map[count].m_str = str;
|
|
map[count].m_data = data;
|
|
count++;
|
|
return TRUE;
|
|
}
|
|
|
|
void *WideStrMap::Find(LPWSTR str) {
|
|
for (int i=0; i < count; i++) {
|
|
if (!_wcsicmp(str, map[i].m_str))
|
|
return map[i].m_data;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *WideStrMap::operator[] (LPWSTR str) {
|
|
return Find(str);
|
|
}
|
|
|
|
#if 0
|
|
struct PropValue {
|
|
DWORD dwMetaID;
|
|
DWORD dwSynID;
|
|
DWORD dwMetaType;
|
|
DWORD dwFlags;
|
|
BOOL fMultiValued;
|
|
DWORD dwMask;
|
|
DWORD dwMetaFlags;
|
|
DWORD dwUserGroup;
|
|
};
|
|
#endif
|
|
|
|
void InitPropValue(PropValue *pv, PROPERTYINFO *pi) {
|
|
pv->dwSynID = pi->dwSyntaxId;
|
|
pv->dwMetaID = pi->dwMetaID;
|
|
pv->dwPropID = pi->dwPropID;
|
|
pv->dwMaxRange = (DWORD)pi->lMaxRange;
|
|
pv->dwMinRange = (DWORD)pi->lMinRange;
|
|
|
|
switch(pi->dwSyntaxId) {
|
|
case IIS_SYNTAX_ID_DWORD:
|
|
case IIS_SYNTAX_ID_BOOL:
|
|
case IIS_SYNTAX_ID_BOOL_BITMASK:
|
|
pv->dwMetaType = DWORD_METADATA;
|
|
break;
|
|
case IIS_SYNTAX_ID_STRING:
|
|
pv->dwMetaType = STRING_METADATA;
|
|
break;
|
|
case IIS_SYNTAX_ID_EXPANDSZ:
|
|
pv->dwMetaType = EXPANDSZ_METADATA;
|
|
break;
|
|
case IIS_SYNTAX_ID_MIMEMAP:
|
|
case IIS_SYNTAX_ID_MULTISZ:
|
|
pv->dwMetaType = MULTISZ_METADATA;
|
|
break;
|
|
case IIS_SYNTAX_ID_NTACL:
|
|
case IIS_SYNTAX_ID_IPSECLIST:
|
|
pv->dwMetaType = BINARY_METADATA;
|
|
break;
|
|
|
|
}
|
|
pv->dwFlags = pi->dwFlags;
|
|
pv->fMultiValued = pi->fMultiValued;
|
|
pv->dwMask = pi->dwMask;
|
|
pv->dwMetaFlags = pi->dwMetaFlags;
|
|
pv->dwUserGroup = pi->dwUserGroup;
|
|
}
|
|
|
|
// struct __declspec(__uuid()
|
|
static char asciiBuf[2048];
|
|
|
|
BOOL DataForSyntaxID(PROPERTYINFO *pp, METADATA_RECORD *mdr) {
|
|
static DWORD value=0;
|
|
WCHAR *ptr;
|
|
int i;
|
|
|
|
switch(pp->dwSyntaxId) {
|
|
case IIS_SYNTAX_ID_BOOL:
|
|
case IIS_SYNTAX_ID_BOOL_BITMASK:
|
|
case IIS_SYNTAX_ID_DWORD:
|
|
mdr->dwMDDataType = DWORD_METADATA;
|
|
mdr->dwMDDataLen = sizeof(DWORD);
|
|
mdr->pbMDData = (unsigned char *)&(pp->dwDefault);
|
|
break;
|
|
case IIS_SYNTAX_ID_STRING:
|
|
mdr->dwMDDataType = STRING_METADATA;
|
|
mdr->dwMDDataLen = (wcslen(pp->szDefault)+1)*2;
|
|
mdr->pbMDData = (unsigned char *)pp->szDefault;
|
|
break;
|
|
case IIS_SYNTAX_ID_EXPANDSZ:
|
|
mdr->dwMDDataType = EXPANDSZ_METADATA;
|
|
mdr->dwMDDataLen = (wcslen(pp->szDefault)+1)*2;
|
|
mdr->pbMDData = (unsigned char *)pp->szDefault;
|
|
break;
|
|
case IIS_SYNTAX_ID_MIMEMAP:
|
|
case IIS_SYNTAX_ID_MULTISZ:
|
|
//
|
|
// Note, ALL multisz types must have an extra \0 in the table.
|
|
//
|
|
mdr->dwMDDataType = MULTISZ_METADATA;
|
|
ptr = pp->szDefault;
|
|
do {
|
|
ptr += wcslen(ptr)+1;
|
|
} while (*ptr != 0);
|
|
mdr->dwMDDataLen = DIFF((char *)ptr - (char *)pp->szDefault)+2;
|
|
mdr->pbMDData = (unsigned char *)pp->szDefault;
|
|
break;
|
|
case IIS_SYNTAX_ID_IPSECLIST:
|
|
case IIS_SYNTAX_ID_NTACL:
|
|
case IIS_SYNTAX_ID_BINARY:
|
|
mdr->dwMDDataType = BINARY_METADATA;
|
|
mdr->dwMDDataLen = 0;
|
|
mdr->pbMDData = NULL;
|
|
break;
|
|
default:
|
|
mdr->dwMDDataType = DWORD_METADATA;
|
|
mdr->dwMDDataLen = sizeof(DWORD);
|
|
mdr->pbMDData = (unsigned char *)&value;
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
const DWORD getAllBufSize = 4096;
|
|
|
|
wchar_t *grabProp(wchar_t *out, wchar_t *in) {
|
|
if (!in || *in == L'\0') {
|
|
*out = L'\0';
|
|
return NULL;
|
|
}
|
|
while (*in != L',' && *in != L'\0') {
|
|
*out++ = *in++;
|
|
}
|
|
*out = L'\0';
|
|
if (*in == L',')
|
|
return ++in;
|
|
return in;
|
|
}
|
|
|
|
|
|
HRESULT StoreSchema() {
|
|
DWORD bufSize = getAllBufSize;
|
|
BYTE *buf = new BYTE[bufSize];
|
|
HRESULT hr;
|
|
COSERVERINFO csiName;
|
|
COSERVERINFO *pcsiParam = &csiName;
|
|
IClassFactory * pcsfFactory = NULL;
|
|
IMSAdminBase * pAdminBase = NULL;
|
|
METADATA_RECORD mdr;
|
|
wchar_t mandProps[MAX_PATH];
|
|
wchar_t optProps[MAX_PATH];
|
|
wchar_t prop[MAX_PATH], *propList;
|
|
MetaHandle root(NULL);
|
|
DWORD value = 0;
|
|
DWORD i;
|
|
//
|
|
// nameToProp is used for mapping properties by name to the property structures
|
|
// that define the properties. Since we first run through the list of props,
|
|
// and write out the names, we add the prop to the map. Then, when we encounter
|
|
// the properties by name, which is how the classes maintain them, we can access
|
|
// the corresponding property structure.
|
|
//
|
|
WideStrMap nameToProp;
|
|
|
|
memset(pcsiParam, 0, sizeof(COSERVERINFO));
|
|
pcsiParam->pwszName = NULL;
|
|
csiName.pAuthInfo = NULL;
|
|
pcsiParam = &csiName;
|
|
|
|
hr = CoGetClassObject(
|
|
CLSID_MSAdminBase,
|
|
CLSCTX_SERVER,
|
|
pcsiParam,
|
|
IID_IClassFactory,
|
|
(void**) &pcsfFactory
|
|
);
|
|
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pcsfFactory->CreateInstance(
|
|
NULL,
|
|
IID_IMSAdminBase,
|
|
(void **) &pAdminBase
|
|
);
|
|
pcsfFactory->Release();
|
|
BAIL_ON_FAILURE(hr);
|
|
root.setpointer(pAdminBase);
|
|
hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
L"",
|
|
METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
|
|
DEFAULT_TIMEOUT_VALUE,
|
|
root);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pAdminBase->AddKey(root, L"Schema");
|
|
if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
hr = pAdminBase->AddKey(root, L"Schema/Properties");
|
|
if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = pAdminBase->AddKey(root, L"Schema/Classes");
|
|
if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = pAdminBase->AddKey(root, L"Schema/Properties/Names");
|
|
if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = pAdminBase->AddKey(root, L"Schema/Properties/Types");
|
|
if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
hr = pAdminBase->AddKey(root, L"Schema/Properties/Defaults");
|
|
if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
root.close();
|
|
|
|
//
|
|
// Now, let's initialize the property dictionary.
|
|
//
|
|
hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
L"/Schema/Properties",
|
|
METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
|
|
DEFAULT_TIMEOUT_VALUE,
|
|
root);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
mdr.dwMDDataTag = 0;
|
|
DWORD propData[2];
|
|
PropValue pv;
|
|
for (i=0; i < g_cIISProperties; i++) {
|
|
//
|
|
// First, we set the name prop to the string value of the properties name.
|
|
//
|
|
mdr.dwMDIdentifier = g_aIISProperties[i].dwPropID;
|
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdr.dwMDDataType = STRING_METADATA;
|
|
mdr.dwMDDataLen = (wcslen(g_aIISProperties[i].szPropertyName)+1)*2;
|
|
mdr.pbMDData = (unsigned char *)g_aIISProperties[i].szPropertyName;
|
|
hr = pAdminBase->SetData(root, L"Names", &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// Next, we need to update the type field.
|
|
//
|
|
InitPropValue(&pv, &g_aIISProperties[i]);
|
|
mdr.dwMDDataType = BINARY_METADATA;
|
|
mdr.dwMDDataLen = sizeof(PropValue);
|
|
mdr.pbMDData = (unsigned char *)&pv;
|
|
hr = pAdminBase->SetData(root, L"Types", &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// update default values
|
|
//
|
|
|
|
mdr.dwMDIdentifier = g_aIISProperties[i].dwPropID;
|
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
DataForSyntaxID(&(g_aIISProperties[i]), &mdr);
|
|
hr = pAdminBase->SetData(root, L"Defaults", &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}
|
|
|
|
root.close();
|
|
hr = pAdminBase->SaveData();
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
L"/Schema/Classes",
|
|
METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
|
|
DEFAULT_TIMEOUT_VALUE,
|
|
root);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
|
|
for (i=0; i < g_cIISClasses; i++) {
|
|
hr = pAdminBase->AddKey(root, g_aIISClasses[i].bstrName);
|
|
if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
//
|
|
// setting Containment and Container property for classes
|
|
//
|
|
|
|
mdr.dwMDIdentifier = MD_SCHEMA_CLASS_CONTAINMENT;
|
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdr.dwMDDataType = STRING_METADATA;
|
|
if (g_aIISClasses[i].bstrContainment) {
|
|
mdr.dwMDDataLen = (wcslen((LPWSTR)g_aIISClasses[i].bstrContainment)+1)*2;
|
|
}
|
|
else {
|
|
mdr.dwMDDataLen = 0;
|
|
}
|
|
|
|
mdr.pbMDData = (unsigned char *)g_aIISClasses[i].bstrContainment;
|
|
hr = pAdminBase->SetData(root, g_aIISClasses[i].bstrName, &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
mdr.dwMDIdentifier = MD_SCHEMA_CLASS_CONTAINER;
|
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdr.dwMDDataType = DWORD_METADATA;
|
|
mdr.dwMDDataLen = sizeof(DWORD);
|
|
mdr.pbMDData = (unsigned char *)&(g_aIISClasses[i].fContainer);
|
|
hr = pAdminBase->SetData(root, g_aIISClasses[i].bstrName, &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
|
|
//
|
|
// setting Optional and Mandatory Properties
|
|
//
|
|
|
|
mdr.dwMDIdentifier = MD_SCHEMA_CLASS_MAND_PROPERTIES;
|
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdr.dwMDDataType = STRING_METADATA;
|
|
if (g_aIISClasses[i].bstrMandatoryProperties) {
|
|
mdr.dwMDDataLen = (wcslen((LPWSTR)g_aIISClasses[i].bstrMandatoryProperties)+1)*2;
|
|
}
|
|
else {
|
|
mdr.dwMDDataLen = 0;
|
|
}
|
|
|
|
mdr.pbMDData = (unsigned char *)g_aIISClasses[i].bstrMandatoryProperties;
|
|
hr = pAdminBase->SetData(root, g_aIISClasses[i].bstrName, &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
mdr.dwMDIdentifier = MD_SCHEMA_CLASS_OPT_PROPERTIES;
|
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdr.dwMDDataType = STRING_METADATA;
|
|
if (g_aIISClasses[i].bstrOptionalProperties) {
|
|
mdr.dwMDDataLen = (wcslen((LPWSTR)g_aIISClasses[i].bstrOptionalProperties)+1)*2;
|
|
}
|
|
else {
|
|
mdr.dwMDDataLen = 0;
|
|
}
|
|
|
|
mdr.pbMDData = (unsigned char *)g_aIISClasses[i].bstrOptionalProperties;
|
|
hr = pAdminBase->SetData(root, g_aIISClasses[i].bstrName, &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
}
|
|
root.close();
|
|
hr = pAdminBase->SaveData();
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
hr = SetAdminACL(pAdminBase);
|
|
|
|
error:
|
|
root.close();
|
|
if (pAdminBase)
|
|
pAdminBase->Release();
|
|
return hr;
|
|
}
|
|
|
|
HRESULT SetAdminACL(
|
|
IMSAdminBase * pAdminBase
|
|
)
|
|
{
|
|
BOOL b = FALSE;
|
|
DWORD dwLength = 0;
|
|
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
PSECURITY_DESCRIPTOR outpSD = NULL;
|
|
DWORD cboutpSD = 0;
|
|
PACL pACLNew = NULL;
|
|
DWORD cbACL = 0;
|
|
PSID pAdminsSID = NULL, pEveryoneSID = NULL;
|
|
BOOL bWellKnownSID = FALSE;
|
|
MetaHandle root(NULL);
|
|
METADATA_RECORD mdr;
|
|
HRESULT hr = NO_ERROR;
|
|
DWORD dwStartMetaId = IIS_MD_ADSI_METAID_BEGIN;
|
|
|
|
// Initialize a new security descriptor
|
|
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
if (!pSD) {hr = E_OUTOFMEMORY;}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
// Get Local Admins Sid
|
|
GetPrincipalSID (_T("Administrators"), &pAdminsSID, &bWellKnownSID);
|
|
|
|
// Get everyone Sid
|
|
GetPrincipalSID (_T("Everyone"), &pEveryoneSID, &bWellKnownSID);
|
|
|
|
// Initialize a new ACL, which only contains 2 aaace
|
|
cbACL = sizeof(ACL) +
|
|
(sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pAdminsSID) - sizeof(DWORD)) +
|
|
(sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pEveryoneSID) - sizeof(DWORD)) ;
|
|
pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
|
|
if (!pACLNew) {hr = E_OUTOFMEMORY;}
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
InitializeAcl(pACLNew, cbACL, ACL_REVISION);
|
|
|
|
AddAccessAllowedAce(
|
|
pACLNew,
|
|
ACL_REVISION,
|
|
FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE,
|
|
pAdminsSID);
|
|
|
|
AddAccessAllowedAce(
|
|
pACLNew,
|
|
ACL_REVISION,
|
|
FILE_GENERIC_READ,
|
|
pEveryoneSID);
|
|
|
|
// Add the ACL to the security descriptor
|
|
b = SetSecurityDescriptorDacl(pSD, TRUE, pACLNew, FALSE);
|
|
b = SetSecurityDescriptorOwner(pSD, pAdminsSID, TRUE);
|
|
b = SetSecurityDescriptorGroup(pSD, pAdminsSID, TRUE);
|
|
|
|
// Security descriptor blob must be self relative
|
|
b = MakeSelfRelativeSD(pSD, outpSD, &cboutpSD);
|
|
outpSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GPTR, cboutpSD);
|
|
if (!outpSD) {hr = E_OUTOFMEMORY;}
|
|
BAIL_ON_FAILURE(hr);
|
|
b = MakeSelfRelativeSD( pSD, outpSD, &cboutpSD );
|
|
|
|
// below this modify pSD to outpSD
|
|
|
|
// Apply the new security descriptor to the file
|
|
dwLength = GetSecurityDescriptorLength(outpSD);
|
|
|
|
// Apply the new security descriptor to the file
|
|
hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
L"/Schema",
|
|
METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
|
|
DEFAULT_TIMEOUT_VALUE,
|
|
root);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
mdr.dwMDIdentifier = MD_ADMIN_ACL;
|
|
mdr.dwMDAttributes = METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE;
|
|
mdr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdr.dwMDDataType = BINARY_METADATA;
|
|
mdr.dwMDDataLen = dwLength;
|
|
mdr.pbMDData = (LPBYTE)outpSD;
|
|
|
|
hr = pAdminBase->SetData(root, L"", &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
//
|
|
// set the start count for meta id
|
|
//
|
|
|
|
mdr.dwMDIdentifier = MD_SCHEMA_METAID;
|
|
mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdr.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdr.dwMDDataType = DWORD_METADATA;
|
|
mdr.dwMDDataLen = sizeof(DWORD);
|
|
mdr.pbMDData = (LPBYTE)&dwStartMetaId;
|
|
|
|
hr = pAdminBase->SetData(root, L"", &mdr);
|
|
BAIL_ON_FAILURE(hr);
|
|
|
|
root.close();
|
|
|
|
error :
|
|
|
|
//Cleanup:
|
|
// both of Administrators and Everyone are well-known SIDs, use FreeSid() to free them.
|
|
if (outpSD)
|
|
GlobalFree(outpSD);
|
|
|
|
if (pAdminsSID)
|
|
FreeSid(pAdminsSID);
|
|
if (pEveryoneSID)
|
|
FreeSid(pEveryoneSID);
|
|
if (pSD)
|
|
LocalFree((HLOCAL) pSD);
|
|
if (pACLNew)
|
|
LocalFree((HLOCAL) pACLNew);
|
|
|
|
return (hr);
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetPrincipalSID (
|
|
LPTSTR Principal,
|
|
PSID *Sid,
|
|
BOOL *pbWellKnownSID
|
|
)
|
|
{
|
|
SID_IDENTIFIER_AUTHORITY SidIdentifierNTAuthority = SECURITY_NT_AUTHORITY;
|
|
SID_IDENTIFIER_AUTHORITY SidIdentifierWORLDAuthority = SECURITY_WORLD_SID_AUTHORITY;
|
|
PSID_IDENTIFIER_AUTHORITY pSidIdentifierAuthority;
|
|
BYTE Count;
|
|
DWORD dwRID[8];
|
|
|
|
*pbWellKnownSID = TRUE;
|
|
memset(&(dwRID[0]), 0, 8 * sizeof(DWORD));
|
|
if ( wcscmp(Principal,_T("Administrators")) == 0 ) {
|
|
// Administrators group
|
|
pSidIdentifierAuthority = &SidIdentifierNTAuthority;
|
|
Count = 2;
|
|
dwRID[0] = SECURITY_BUILTIN_DOMAIN_RID;
|
|
dwRID[1] = DOMAIN_ALIAS_RID_ADMINS;
|
|
} else if ( wcscmp(Principal,_T("System")) == 0) {
|
|
// SYSTEM
|
|
pSidIdentifierAuthority = &SidIdentifierNTAuthority;
|
|
Count = 1;
|
|
dwRID[0] = SECURITY_LOCAL_SYSTEM_RID;
|
|
} else if ( wcscmp(Principal,_T("Interactive")) == 0) {
|
|
// INTERACTIVE
|
|
pSidIdentifierAuthority = &SidIdentifierNTAuthority;
|
|
Count = 1;
|
|
dwRID[0] = SECURITY_INTERACTIVE_RID;
|
|
} else if ( wcscmp(Principal,_T("Everyone")) == 0) {
|
|
// Everyone
|
|
pSidIdentifierAuthority = &SidIdentifierWORLDAuthority;
|
|
Count = 1;
|
|
dwRID[0] = SECURITY_WORLD_RID;
|
|
} else {
|
|
*pbWellKnownSID = FALSE;
|
|
}
|
|
|
|
if (*pbWellKnownSID) {
|
|
if ( !AllocateAndInitializeSid(pSidIdentifierAuthority,
|
|
(BYTE)Count,
|
|
dwRID[0],
|
|
dwRID[1],
|
|
dwRID[2],
|
|
dwRID[3],
|
|
dwRID[4],
|
|
dwRID[5],
|
|
dwRID[6],
|
|
dwRID[7],
|
|
Sid) )
|
|
return GetLastError();
|
|
} else {
|
|
// get regular account sid
|
|
DWORD sidSize;
|
|
TCHAR refDomain [256];
|
|
DWORD refDomainSize;
|
|
DWORD returnValue;
|
|
SID_NAME_USE snu;
|
|
|
|
sidSize = 0;
|
|
refDomainSize = 255;
|
|
|
|
LookupAccountName (NULL,
|
|
Principal,
|
|
*Sid,
|
|
&sidSize,
|
|
refDomain,
|
|
&refDomainSize,
|
|
&snu);
|
|
|
|
returnValue = GetLastError();
|
|
if (returnValue != ERROR_INSUFFICIENT_BUFFER)
|
|
return returnValue;
|
|
|
|
*Sid = (PSID) malloc (sidSize);
|
|
refDomainSize = 255;
|
|
|
|
if (!LookupAccountName (NULL,
|
|
Principal,
|
|
*Sid,
|
|
&sidSize,
|
|
refDomain,
|
|
&refDomainSize,
|
|
&snu))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|