COM Yükseltme Takma Adı
COM yükseltme takma adı, kullanıcı hesabı denetimi (UAC) altında çalışan uygulamaların yükseltilmiş ayrıcalıklarla COM sınıflarını etkinleştirmesine olanak tanır. Daha fazla bilgi için En Az Ayrıcalığa Odaklanmabakınız.
Yükselti Etiketi Ne Zaman Kullanılır?
Yükseltme takma adı, sistem tarih ve saatini değiştirme gibi yükseltilmiş ayrıcalıklar gerektiren belirli ve sınırlı bir işlevi gerçekleştirmek için COM sınıfını etkinleştirmek için kullanılır.
Yükseltme, hem COM sınıfından hem de istemcisinden katılım gerektirir. COM sınıfı, Gereksinimler bölümünde açıklandığı gibi kayıt defteri girdisine ek açıklama eklenerek yükseltmeyi destekleyecek şekilde yapılandırılmalıdır. COM istemcisi, yükseltme belirtecini kullanarak yükseltme isteğinde bulunmalıdır.
Yükseltme takma adı, uygulama uyumluluğu sağlamak için tasarlanmamıştır. Örneğin, yükseltilmiş sunucu olarak WinWord gibi eski bir COM uygulamasını çalıştırmak istiyorsanız, eski uygulamanın sınıfını yükseltme takma adıyla etkinleştirmek yerine COM istemci yürütülebilir dosyasını yükseltme gerektirecek şekilde yapılandırmanız gerekir. Yükseltilmiş COM istemcisi, eski uygulamanın CLSID'sini kullanarak CoCreateInstance çağırdığında, istemcinin yükseltilmiş durumu sunucu işlemine akar.
Tüm COM işlevleri yükseltmeyle uyumlu değildir. Çalışmayacak işlevsellik şunları içerir:
- Yükseltme, istemciden uzak COM sunucusuna aktarılmıyor. Bir istemci, yükseltme takma adıyla bir uzak COM sunucusunu etkinleştirirse, yükseltmeyi desteklese bile sunucu yükseltilmeyecektir.
- Yükseltilmiş bir COM sınıfı, COM çağrısı sırasında kimliğe bürünme kullanırsa, kimliğe bürünme sırasında yükseltilmiş ayrıcalıklarını kaybedebilir.
- Yükseltilmiş bir COM sunucusu çalışan nesne tablosuna (ROT) bir sınıf kaydederse, sınıfı yükseltilmiş olmayan istemciler tarafından kullanılamaz.
- UAC mekanizması kullanılarak yükseltilmiş bir işlem, COM etkinleştirmeleri sırasında kullanıcı başına sınıf yüklemez. COM uygulamaları için bu, uygulamanın hem ayrıcalıklı olmayan hem de ayrıcalıklı hesaplar tarafından kullanılacaksa, uygulamanın COM sınıflarının HKEY_LOCAL_MACHINE kayıt defteri kovanına yüklenmesi gerektiği anlamına gelir. Uygulamanın COM sınıflarının yalnızca uygulama ayrıcalıklı hesaplar tarafından hiçbir zaman kullanılmadıysa HKEY_USERS kovana yüklenmesi gerekir.
- Yükseltilmiş olmayan uygulamalardan yükseltilmiş uygulamalara sürükleyip bırakma işlemine izin verilmez.
Gereksinimler
COM sınıfını etkinleştirmek için yükseltme takma adını kullanmak için, sınıfın başlatan kullanıcı veya 'Etkinleştirici Olarak Etkinleştir' uygulama kimliği olarak çalışacak şekilde yapılandırılması gerekir. Sınıf başka bir kimlik altında çalışacak şekilde yapılandırılmışsa, etkinleştirme CO_E_RUNAS_VALUE_MUST_BE_AAA hatasını döndürür.
Sınıfa ayrıca çok dilli kullanıcı arabirimi (MUI) uyumlu bir “kullanıcı dostu” görünen adla etiket eklenmelidir. Bunun için aşağıdaki kayıt defteri girdisi gerekir:
HKEY_LOCAL_MACHINE\Software\Classes\CLSID
{CLSID}
LocalizedString = displayName
Bu giriş eksikse, etkinleştirme CO_E_MISSING_DISPLAYNAME hatasını döndürür. MUI dosyası eksikse, RegLoadMUIStringW işlevindeki hata kodu döndürülür.
İsteğe bağlı olarak, UAC kullanıcı arabirimi tarafından görüntülenecek bir uygulama simgesi belirtmek için aşağıdaki kayıt defteri anahtarını ekleyin:
HKEY_LOCAL_MACHINE\Software\Classes\CLSID
{CLSID}
Elevation
IconReference = applicationIcon
IconReference, LocalizedStringile aynı biçimi kullanır:
@ pathtobinary,-resourcenumber
Ayrıca, simgenin görüntülenmesi için COM bileşeni imzalanmalıdır.
COM sınıfı ayrıca LUA-Etkin olarak işaretlenmelidir. Bunun için aşağıdaki kayıt defteri girdisi gerekir:
HKEY_LOCAL_MACHINE\Software\Classes\CLSID
{CLSID}
Elevation
Enabled = 1
Bu girdi eksikse etkinleştirme CO_E_ELEVATION_DISABLED hatasını döndürür.
Bu girdilerin HKEY_CURRENT_USER veya HKEY_USERS kovanda değil HKEY_LOCAL_MACHINE kovanda bulunması gerektiğini unutmayın. Bu, kullanıcıların kaydolma ayrıcalıklarına sahip olmadığı COM sınıflarını yükseltmesini engeller.
Yükseltme Takma Adı ve Yükseltme Kullanıcı Arabirimi
İstemci zaten yükseltilmişse, yükseltme tanımlayıcısını kullanmak, Yükseltme UI'sinin görüntülenmesine neden olmaz.
Yükseltme Takma Adını Kullanma
Yükseltme lakabı, oturum isimlendirme, bölüm isimlendirme veya kuyruk isimlendirmelerine benzer, standart bir COM lakabıdır. Bir etkinleştirme isteğini belirtilen yükseltme düzeyine sahip belirli bir sunucuya yönlendirir. Etkinleştirilecek CLSID, takma ad dizesinde görünür.
Yükseltme takma adı aşağıdaki Çalıştırma düzeyi belirteçlerini destekler:
- Yönetici
- Yüksek
Bunun söz dizimi aşağıdaki gibidir:
Elevation:Administrator!new:{guid}
Elevation:Highest!new:{guid}
Yukarıdaki söz dizimi, guidtarafından belirtilen COM sınıfının bir örneğini döndürmek için "yeni" takma adını kullanır. Dikkat edin ki "yeni" takma adı, bir sınıf nesnesi almak için IClassFactory arabirimini dahili olarak kullanır ve ardından üzerinde IClassFactory::CreateInstance çağırır.
Yükseltme takma adı, IClassFactoryuygulayan bir sınıf nesnesi almak için de kullanılabilir. Ardından çağıran, nesne örneğini almak için createInstanceçağırır. Bunun söz dizimi aşağıdaki gibidir:
Elevation:Administrator!clsid:{guid}
Örnek kod
Aşağıdaki kod örneği, yükseltme takma adını nasıl kullanacağınızı gösterir. Geçerli iş parçacığında COM'yi halihazırda başlatmış olduğunuzu varsayar.
HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
BIND_OPTS3 bo;
WCHAR wszCLSID[50];
WCHAR wszMonikerName[300];
StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));
HRESULT hr = StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);
if (FAILED(hr))
return hr;
memset(&bo, 0, sizeof(bo));
bo.cbStruct = sizeof(bo);
bo.hwnd = hwnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
return CoGetObject(wszMonikerName, &bo, riid, ppv);
}
BIND_OPTS3 Windows Vista'da yenidir. BIND_OPTS2'ten türetilmiştir.
Tek ekleme bir hwnd ve bir HWND alanıdır. Bu kulp, uygulanabilir durumda Yükseltme kullanıcı arabiriminin sahibi olan bir pencereyi temsil eder.
hwnd NULL ise, COM geçerli iş parçacığıyla ilişkilendirilmiş bir pencere tutamacını bulmak için GetActiveWindow çağırır. Bu durum, istemci BIND_OPTS3 yapısını dolduramayan bir betik olduğunda ortaya çıkabilir. Bu durumda, COM betik iş parçacığıyla ilişkili pencereyi kullanmayı dener.
AşırıThe-Shoulder (OTS) Yükselme
Omuz üstü (OTS) yükseltme, istemcinin kendi kimlik bilgileri yerine yönetici kimlik bilgileriyle COM sunucusu çalıştırdığı senaryoyu ifade eder. ("Omuz üzerinden" terimi, istemci sunucuyu çalıştırırken yöneticinin istemcinin omzunu izlediği anlamına gelir.)
Bu senaryo, sunucu CoInitializeSecurity'ü açıkça (yani program aracılığıyla) veya dolaylı olarak (yani kayıt defterini kullanarak) çağırmazsa, sunucuya yapılan COM çağrılarında bir soruna neden olabilir. Bu tür sunucular için, COM yalnızca SELF, SYSTEM ve Builtin\Administrators'ın sunucuya COM çağrıları yapmasına izin veren bir güvenlik tanımlayıcısı hesaplar. Bu düzenleme OTS senaryolarında çalışmaz. Bunun yerine, sunucunun CoInitializeSecurityöğesini açıkça veya örtük olarak çağırması ve ETKILEŞIMLI grup SID ve SYSTEM içeren bir ACL belirtmesi gerekir.
Aşağıdaki kod örneği, ETKILEŞIMLI grup SID'siyle bir güvenlik tanımlayıcısının (SD) nasıl oluşturulacağını gösterir.
BOOL GetAccessPermissionsForLUAServer(SECURITY_DESCRIPTOR **ppSD)
{
// Local call permissions to IU, SY
LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)";
SECURITY_DESCRIPTOR *pSD;
*ppSD = NULL;
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))
{
*ppSD = pSD;
return TRUE;
}
return FALSE;
}
Aşağıdaki kod örneği, önceki kod örneğinden SD ile örtük olarakCoInitializeSecurity çağrısının nasıl yapılacağını gösterir:
// hKey is the HKCR\AppID\{GUID} key
BOOL SetAccessPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
{
BOOL bResult = FALSE;
DWORD dwLen = GetSecurityDescriptorLength(pSD);
LONG lResult;
lResult = RegSetValueExA(hkey,
"AccessPermission",
0,
REG_BINARY,
(BYTE*)pSD,
dwLen);
if (lResult != ERROR_SUCCESS) goto done;
bResult = TRUE;
done:
return bResult;
}
Aşağıdaki kod örneğinde, yukarıdaki SD ile açıkçaCoInitializeSecurity çağrısının nasıl yapılacağını gösterilmektedir:
// Absolute SD values
PSECURITY_DESCRIPTOR pAbsSD = NULL;
DWORD AbsSdSize = 0;
PACL pAbsAcl = NULL;
DWORD AbsAclSize = 0;
PACL pAbsSacl = NULL;
DWORD AbsSaclSize = 0;
PSID pAbsOwner = NULL;
DWORD AbsOwnerSize = 0;
PSID pAbsGroup = NULL;
DWORD AbsGroupSize = 0;
MakeAbsoluteSD (
pSD,
pAbsSD,
&AbsSdSize,
pAbsAcl,
&AbsAclSize,
pAbsSacl,
&AbsSaclSize,
pAbsOwner,
&AbsOwnerSize,
pAbsGroup,
&AbsGroupSize
);
if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
pAbsSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, AbsSdSize);
pAbsAcl = (PACL)LocalAlloc(LMEM_FIXED, AbsAclSize);
pAbsSacl = (PACL)LocalAlloc(LMEM_FIXED, AbsSaclSize);
pAbsOwner = (PSID)LocalAlloc(LMEM_FIXED, AbsOwnerSize);
pAbsGroup = (PSID)LocalAlloc(LMEM_FIXED, AbsGroupSize);
if ( ! (pAbsSD && pAbsAcl && pAbsSacl && pAbsOwner && pAbsGroup))
{
hr = E_OUTOFMEMORY;
goto Cleanup;
}
if ( ! MakeAbsoluteSD(
pSD,
pAbsSD,
&AbsSdSize,
pAbsAcl,
&AbsAclSize,
pAbsSacl,
&AbsSaclSize,
pAbsOwner,
&AbsOwnerSize,
pAbsGroup,
&AbsGroupSize
))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
// Call CoInitializeSecurity .
COM İzinleri ve Zorunlu Erişim Etiketleri
Windows Vista, güvenlik tanımlayıcılarında zorunlu erişim etiketlerine ilişkin bir kavrama sahiptir. Etiket, istemcilerin bir COM nesnesine yürütme erişimi alıp alamayacağını belirler. Etiket, güvenlik tanımlayıcısının sistem erişim denetimi listesi (SACL) bölümünde belirtilir. Windows Vista'da COM, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP etiketini destekler. COM izinlerindeki SACL'ler Windows Vista'dan önceki işletim sistemlerinde göz ardı edilir.
Windows Vista'da dcomcnfg.exe, COM izinlerinde bütünlük düzeyinin (IL) değiştirilmesini desteklemez. Program aracılığıyla ayarlanmalıdır.
Aşağıdaki kod örneği, tüm LOW IL istemcilerinden başlatma/etkinleştirme isteklerine izin veren bir etikete sahip bir COM güvenlik tanımlayıcısının nasıl oluşturulacağını gösterir. Etiketlerin Başlatma/Etkinleştirme ve Arama izinleri için geçerli olduğunu unutmayın. Bu nedenle, belirli bir IL'ye sahip istemcilerden başlatmaya, etkinleştirmeye veya çağrılara izin vermeyen bir COM sunucusu yazmak mümkündür. Bütünlük düzeyleri hakkında daha fazla bilgi için, Korumalı Modda Anlama ve Çalışma internet explorer "Windows Vista'nın Bütünlük Mekanizmasını Anlama" bölümüne bakın.
BOOL GetLaunchActPermissionsWithIL (SECURITY_DESCRIPTOR **ppSD)
{
// Allow World Local Launch/Activation permissions. Label the SD for LOW IL Execute UP
LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)";
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))
{
*ppSD = pSD;
return TRUE;
}
}
BOOL SetLaunchActPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
{
BOOL bResult = FALSE;
DWORD dwLen = GetSecurityDescriptorLength(pSD);
LONG lResult;
lResult = RegSetValueExA(hkey,
"LaunchPermission",
0,
REG_BINARY,
(BYTE*)pSD,
dwLen);
if (lResult != ERROR_SUCCESS) goto done;
bResult = TRUE;
done:
return bResult;
};
CoCreateInstance ve Bütünlük Düzeyleri
CoCreateInstance davranışı, Düşük IL istemcilerinin varsayılan olarak COM sunucularına bağlanmasını önlemek için Windows Vista'da değişmiştir. Sunucu, SACL'yi belirterek bu tür bağlamalara açıkça izin vermelidir. CoCreateInstance yapılan değişiklikler aşağıdaki gibidir:
- COM sunucu işlemi başlatılırken, sunucu işlem belirtecindeki IL, istemci veya sunucu belirteci IL'den hangisi daha düşükse ona göre ayarlanır.
- Varsayılan olarak, COM, Düşük IL istemcilerinin herhangi bir COM sunucularının çalışan örneklerine bağlanmasını engeller. Bağlama izin vermek için, COM sunucusunun Başlatma/Etkinleştirme güvenlik tanımlayıcısı Düşük IL etiketini belirten bir SACL içermelidir (bu tür bir güvenlik tanımlayıcısı oluşturmak için örnek kodun önceki bölümüne bakın).
Yükseltilmiş Sunucular ve ROT Kayıtları
BIR COM sunucusu çalışan nesne tablosuna (ROT) kaydolmak ve herhangi bir istemcinin kayda erişmesine izin vermek istiyorsa, ROTFLAGS_ALLOWANYCLIENT bayrağını kullanmalıdır. DCOM hizmet kontrol yöneticisi (DCOMSCM) bu bayrak için bir yanıltma kontrolü uyguladığı için, "Etkinleştirici Olarak Etkinleştir" COM sunucusu ROTFLAGS_ALLOWANYCLIENT belirtemiyor. Bu nedenle, Windows Vista'da COM, sunucunun ROT kayıtlarının herhangi bir istemci için kullanılabilir olmasını şart koşan yeni bir kayıt defteri girdisi için destek ekler:
HKEY_LOCAL_MACHINE\Software\Classes\AppID
{APPID}
ROTFlags
Bu REG_DWORD girdisi için tek geçerli değer:
ROTREGFLAGS_ALLOWANYCLIENT 0x1
Giriş HKEY_LOCAL_MACHINE kovanında bulunmalıdır.
Bu giriş, bir RunAs sunucusu için ROTFLAGS_ALLOWANYCLIENT tarafından sağlanan işlevsellikle aynı işlevselliğe sahip bir "Aktivatör Olarak Etkinleştir" sunucusu sağlar.
İlgili konular
-
COM 'da Güvenliği