// This file is the metadata version of the key storage serverice object for the w3 server. // it knows nothing about the LSA storage and only interacts with the metabase. Likewise, // it does not convert old keyset.exe keys into a newer format. Any old LSA keys should have // automatically converted to the new metabase format by the setup utility. // file created 4/1/1997 by BoydM #include "stdafx.h" #include "KeyObjs.h" #include "iiscnfg.h" #include "wrapmb.h" #include "cmnkey.h" #include "mdkey.h" #include "mdserv.h" #include "resource.h" // the service image index extern int g_iServiceImage; extern HINSTANCE g_hInstance; BOOL g_fUsingMetabase = FALSE; #define MAX_LEN (METADATA_MAX_NAME_LEN * sizeof(WCHAR)) //-------------------------------------------------------- CMDKeyService::CMDKeyService(): m_pszwMachineName(NULL) { // specify the resources to use HINSTANCE hOldRes = AfxGetResourceHandle(); AfxSetResourceHandle( g_hInstance ); // set the icon id m_iImage = (WORD)g_iServiceImage; // load the service name m_szItemName.LoadString( IDS_SERV_NAME ); // yes, we are using the metabase g_fUsingMetabase = TRUE; // restore the resources AfxSetResourceHandle( hOldRes ); } //-------------------------------------------------------- CMDKeyService::~CMDKeyService() { if ( m_pszwMachineName ) delete m_pszwMachineName; } //-------------------------------------------------------- void CMDKeyService::SetMachineName( WCHAR* pszw ) { if ( pszw ) { m_pszwMachineName = new WCHAR[wcslen(pszw)+1]; wcscpy( m_pszwMachineName, pszw ); } else { m_pszwMachineName = NULL; } } //-------------------------------------------------------- void CMDKeyService::LoadKeys( CMachine* pMachine ) { CString szKeyObject; DWORD index = 0; CString szKeyBase; CString sz; // keep a local list of the added keys in some attempt to keep this simpler CTypedPtrArray rgbKeys; CString szIdent; BOOL fLoadTheKey; DWORD iKey; DWORD nKey; // create the metabase wrapper object CWrapMetaBase mbWrap; if ( !mbWrap.FInit() ) { ASSERT( FALSE ); goto cleanup; // can't get to metabase - no keys } // build the key name szKeyBase = SZ_META_BASE; szKeyBase += SZ_META_KEYBASE; // open the base metabase object that contains all the keys // if we were unable to open the object - then there aren't any keys if ( !mbWrap.Open( szKeyBase, METADATA_PERMISSION_READ ) ) goto cleanup; // can't open metabase // read in all the keys and add them to the main list while ( mbWrap.EnumObjects("", sz.GetBuffer(MAX_LEN), MAX_LEN, index) ) { sz.ReleaseBuffer(); // make a new key object CMDKey* pKey = new CMDKey(this); if ( !pKey ) continue; // here's the deal. If this key is a member of a group of IP addresses that actually // use the same key, then we need to figure out the groups. We don't want to actually // load all the keys. - Just the first from each group. First we get the unique // identifier string for the key (the serial number), which should be cached in the // metabase for us. fLoadTheKey = FALSE; if ( pKey->FGetIdentString(&mbWrap, sz.GetBuffer(MAX_LEN), szIdent) ) { sz.ReleaseBuffer(); // we did get an ident string. Now we need to look through the list of keys we // have already loaded and see if there is a parental match for this one. If there // is, we add this key's metaname to the list of metanames for the parent and do NOT // load the rest of the data for the key - because it is already there for the parent. nKey = rgbKeys.GetSize(); for ( iKey = 0; iKey < nKey; iKey++ ) { CString szTest = rgbKeys[iKey]->m_szIdent; if ( szIdent == szTest ) { // we found a sub-member! - add it to the parent's list rgbKeys[iKey]->AddBinding( sz ); // get out of this sub-loop goto loadkey; } } // we did not find a parent for the key. Load it fLoadTheKey = TRUE; } else { sz.ReleaseBuffer(); // if we did not get the ident string, then this is an incomplete key and // won't have multiple bindings anyway. Load it fLoadTheKey = TRUE; } // fill in the parts of the key by reading in the relevant info from the metabase // add the key to the tree - if we successfully read it in loadkey: if ( fLoadTheKey && pKey->FLoadKey(&mbWrap, (LPSTR)(LPCSTR)sz) ) { // add it to visible tree view pKey->FAddToTree( this ); // add it to the cached list for easier access as we load the keys rgbKeys.Add(pKey); } else delete pKey; // increment to the next object index++; } sz.ReleaseBuffer(); // close the metabase on the target machine mbWrap.Close(); // cleanup the metabase connection cleanup: ; } //-------------------------------------------------------- BOOL CMDKeyService::FCommitChangesNow( ) { BOOL fAnswer = FALSE; DWORD iKey = 1; CMDKey* pKey; CString szKeyBase; CStringArray rgbSZ; CString szEnum; DWORD iObject = 0; DWORD iString; DWORD nStrings; rgbSZ.SetSize( 0, 8 ); BOOL f; // get the metabase going if ( !FInitMetabaseWrapper(m_pszwMachineName) ) return FALSE; // create the metabase wrapper object CWrapMetaBase mbWrap; if ( !mbWrap.FInit() ) { ASSERT( FALSE ); goto cleanup; // can't get to metabase - no keys } // build the key name szKeyBase = SZ_META_BASE; szKeyBase += SZ_META_KEYBASE; // open the base metabase object that contains all the keys // if we were unable to open the object - then there aren't any keys if ( !mbWrap.Open( szKeyBase, METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ ) ) { // the base object for the keys doesn't exist. This means // we have to create it first, then try to open it // open up the w3svc base, which is where the key base lives if ( !mbWrap.Open( SZ_META_BASE, METADATA_PERMISSION_WRITE ) ) goto cleanup; // whoa! this shouldn't happen // create the key - if it doesn't work, croak if ( !mbWrap.AddObject(SZ_META_KEYBASE) ) { mbWrap.Close(); goto cleanup; } mbWrap.Close(); // NOW try to open the base key - and it better work this time if ( !mbWrap.Open( szKeyBase, METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ ) ) goto cleanup; } // update each of the keys pKey = GetFirstMDKey(); while( pKey ) { // tell the key to write itself out pKey->FWriteKey( &mbWrap, iKey, &rgbSZ ); // get the next key pKey = GetNextMDKey( pKey ); iKey++; } // scan the metabase looking for objects there were not just saved. If it hasn't // been just saved, or marked saved, we get rid of it. // read in all the keys and add them to the main list nStrings = rgbSZ.GetSize(); while ( mbWrap.EnumObjects("", szEnum.GetBuffer(MAX_LEN), MAX_LEN, iObject) ) { szEnum.ReleaseBuffer(); // is it in the saved list? for ( iString = 0; iString < nStrings; iString++ ) { if ( rgbSZ[iString] == szEnum ) { // increment to the next object iObject++; goto nextObject; } } // if it is not in the list, delete the object f = mbWrap.DeleteObject( szEnum ); nextObject: ; } szEnum.ReleaseBuffer(); // close the metabase on the target machine mbWrap.Close(); // write out the changes we made to the metabase mbWrap.Save(); // string memory in a CStringArray object is automatically cleanup up // when the main object is deleted. // clear the dirty flag SetDirty( FALSE ); fAnswer = TRUE; // cleanup the metabase connection cleanup: // now close the metabase again. We will open it when we need it FCloseMetabaseWrapper(); // return the answer return fAnswer; } //-------------------------------------------------------- BOOL CMDKeyService::FIsBindingInUse( CString szBinding ) { CMDKey* pKey; // get the first key in the service list pKey = GetFirstMDKey(); // loop the keys, testing each in turn while ( pKey ) { // test it if ( pKey->FContainsBinding( szBinding ) ) return TRUE; // get the next key in the list pKey = GetNextMDKey( pKey ); } // nope. Didn't find it. return FALSE; }