Silinen Nesneleri Geri Yükleme

Windows Server 2003,"silinen nesneleri geri yükleme" özelliğini içerir.

Silinen nesne geri yüklemeyi etkinleştirmek için, etki alanındaki en az bir etki alanı denetleyicisiNin Windows Server 2003'te veya Windows'un sonraki bir sürümünde çalışıyor olması gerekir. Varsayılan olarak, yalnızca etki alanı yöneticileri silinen nesneleri geri yükleyebilir, ancak bu başkalarına devredilebilir.

Silinen nesneleri geri yüklemek için aşağıdaki sınırlamalar geçerlidir:

  • Bir nesnenin yer işareti yaşam süresi dolduğunda geri yüklenemez, çünkü yer işareti yaşam süresi sona erdiğinde nesne kalıcı olarak silinir.
  • Bir etki alanı veya uygulama bölümü gibi adlandırma bağlamının kökünde bulunan nesneler geri yüklenemez.
  • Şema nesneleri geri yüklenemiyor. Şema nesneleri hiçbir zaman silinmemelidir.
  • Silinen kapsayıcıları geri yüklemek mümkündür, ancak kapsayıcının altındaki ağaç yapısının el ile yeniden yapılandırılması gerektiğinden, silme işleminden önce kapsayıcıda bulunan silinmiş nesnelerin geri yüklenmesi zordur.

Silinen Nesneyi Geri Yüklemek için Gereken İzinler

Bir nesne silindiğinde, nesne güvenlik tanımlayıcısı korunur. Sahip, güvenlik tanımlayıcısından tanımlanabilir olsa da, güvenlik nedeniyle yalnızca etki alanı yöneticilerinin silinen nesneleri geri yüklemesine izin verilir. Etki alanı yöneticileri, kullanıcıya veya gruba "Reanimate Tombstone" denetim erişimi hakkı vererek silinen nesneleri diğer kullanıcılara ve gruplara geri yükleme izni verebilir. Adlandırma Bağlamı kökünde "Mezartaşı Yeniden Canlandırma" denetim erişim hakkı verilir. Nesne silindikten sonra yalnızca nesne ve öznitelikleri üzerinde okuma erişimi izni olan kullanıcıların nesneyi ve erişilebilir öznitelikleri okumasına izin verilir.

Not

Kullanıcıya bu iznin verilmesi, kullanıcının normalde erişimi olmayan kaynaklara erişimi olan bir hesap nesnesini geri yüklemesine izin verdiğinden güvenlik riski oluşturabilir. Bir hesabı geri yükleyerek, hesap geri yüklendiğinde kullanıcının hesapta ilk parolayı ayarlaması gerektiğinden, kullanıcı temelde bu hesabın denetimini alır.

 

Silinen bir nesneyi tamamen geri yüklemek için kullanıcının şunları yapması gerekir:

  • "Reanimate Tombstone" denetim erişim hakkına sahip bir grubun üyesi olun veya böyle bir gruba sahip olun.

  • Güncelleştirme gerektiren her zorunlu öznitelik için yazma erişimine sahip olun.

  • Göreli Ayırt Edici Ad'a (RDN) yazma iznine sahip olmalısınız.

  • Güncelleştirilmesi gereken her isteğe bağlı özniteliğe yazma erişimine sahip olun.

  • Geri yüklenen nesnenin nesne sınıfı için hedef kapsayıcıda alt öğe oluşturma haklarına sahip olun.

    Dikkat

    isDeleted özniteliği geri yükleme işlemi sırasında doğrulanmaz. "Silinmiş Nesneler" kapsayıcısı üzerindeki delete-child izni de doğrulanamaz.

     

Silinen Nesneyi Geri Yükleme

Silinen bir nesneyi geri yüklemek için, nesnenin önce Silinmiş Nesneler kapsayıcısında bulunması gerekir. Silinen nesneleri alma hakkında daha fazla bilgi için bkz. Silinmiş Nesneleri Alma.

Nesne bulunduğunda, aşağıdaki işlemlerin tek bir LDAP işleminde tamamlanması gerekir. Bunun için ldap_modify_ext_s işlevinin LDAP_SERVER_SHOW_DELETED_OID denetimiyle kullanılması gerekir.

  • isDeleted öznitelik değerini kaldırın. isDeleted öznitelik değeri kaldırılmalı, FALSEolarak bırakılmamalıdır.
  • Nesnenin ayırt edici adını, Silinmiş Nesneler kapsayıcısı dışında bir kapsayıcıya taşınacak şekilde değiştirin. Bu, normalde nesnesini içerebilen herhangi bir kapsayıcı olabilir. Nesnenin önceki kapsayıcısının ayırt edici adı, silinen nesnenin lastKnownParent özniteliğinde bulunabilir. lastKnownParent özniteliği yalnızca nesne bir Windows Server 2003 etki alanı denetleyicisinde silinmişse ayarlanır. Bu nedenle, lastKnownParent özniteliğinin içeriği yanlış olabilir.
  • Silme sırasında temizlenen nesne için zorunlu öznitelikleri geri yükleyin.

Not

objectCategory özniteliği, nesne geri yüklendiğinde de ayarlanabilir, ancak gerekli değildir. objectCategory değeri belirtilmezse, nesnenin objectClass için varsayılan objectCategory kullanılır.

 

Nesne geri yüklendikten sonra, nesne silinmeden önceki gibi erişilebilir. Bu noktada, önemli olan tüm isteğe bağlı öznitelikler geri yüklenmelidir. Dizindeki diğer nesnelerden nesneye yapılan tüm başvurular da geri yüklenmelidir.

Güvenlik önlemi olarak, kullanıcı nesneleri geri yüklendiklerinde devre dışı bırakılır. Kullanıcı nesnesinin kullanılmasına izin vermek için isteğe bağlı öznitelikler geri yüklendikten sonra kullanıcı nesnelerinin etkinleştirilmesi gerekir.

Daha fazla bilgi ve silinen bir nesnenin nasıl geri yüklendiğini gösteren bir kod örneği için aşağıdaki RestoreDeletedObject işlevine bakın.

SilinmişNesneyiGeriYükle

Aşağıdaki C++ kod örneği, silinen bir nesnenin nasıl geri yükleneceği gösterilmektedir.

//***************************************************************************
//
//  RestoreDeletedObject()
//
//  Restores a deleted object. 
//
//  pwszDeletedDN - Contains the fully qualified distinguished name of the 
//  deleted object.
//
//  pwszDestContainerDN - Contains the fully qualified distinguished name of 
//  the folder that the deleted object should be moved to.
//
//  Returns S_OK if successful or an HRESULT or LDAP error code otherwise.
//
//***************************************************************************

HRESULT RestoreDeletedObject(LPCWSTR pwszDeletedDN, LPCWSTR pwszDestContainerDN)
{
    if((NULL == pwszDeletedDN) || (NULL == pwszDestContainerDN))
    {
        return E_POINTER;
    }
    
    HRESULT hr = E_FAIL;

    // Build the new distinguished name.
    LPWSTR pwszNewDN = new WCHAR[lstrlenW(pwszDeletedDN) + lstrlenW(pwszDestContainerDN) + 1];
    if(pwszNewDN)
    {
        wcscpy_s(pwszNewDN, pwszDeletedDN);

        // Search for the first 0x0A character. This is the delimiter in the deleted object name.
        LPWSTR pwszChar;
        for(pwszChar = pwszNewDN; *pwszChar; pwszChar = CharNextW(pwszChar))
        {
            if(('\\' == *pwszChar) && ('0' == *(pwszChar + 1)) && ('A' == *(pwszChar + 2)))
            {
                break;
            }
            
        }

        if(0 != *pwszChar)
        {
            // Truncate the name string at the delimiter.
            *pwszChar = 0;

            // Add the last known parent DN to complete the DN.
            wcscat_s(pwszNewDN, L",");
            wcscat_s(pwszNewDN, pwszDestContainerDN);

            PLDAP ld;

            // Initialize LDAP.
            ld = ldap_init(NULL, LDAP_PORT);
            if(NULL != ld) 
            {
                ULONG ulRC;
                ULONG version = LDAP_VERSION3;

                // Set the LDAP version.
                ulRC = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, (void*)&version);
                if(LDAP_SUCCESS == ulRC)
                {
                    // Establish a connection with the server.
                    ulRC = ldap_connect(ld, NULL);
                    if(LDAP_SUCCESS == ulRC)
                    {                    
                        // Bind to the LDAP server.
                        ulRC = ldap_bind_s(ld, NULL, NULL, LDAP_AUTH_NEGOTIATE);
                        if(LDAP_SUCCESS == ulRC)
                        {
                            // Setup the new values.
                            LPWSTR rgNewVals[] = {pwszNewDN, NULL};

                            /*
                            Remove the isDeleted attribute. This cannot be set 
                            to FALSE or the restore operation will not work.
                            */
                            LDAPModW modIsDeleted = { LDAP_MOD_DELETE, L"isDeleted", NULL };

                            /*
                            Set the new DN, in effect, moving the deleted 
                            object to where it resided before the deletion.
                            */
                            LDAPModW modDN = { LDAP_MOD_REPLACE, L"distinguishedName", rgNewVals };
                            
                            // Initialize the LDAPMod structure.
                            PLDAPModW ldapMods[] = 
                            {
                                &modIsDeleted,
                                &modDN,
                                NULL
                            };

                            /*
                            Use the LDAP_SERVER_SHOW_DELETED_OID control to 
                            modify deleted objects.
                            */
                            LDAPControlW showDeletedControl;
                            showDeletedControl.ldctl_oid = LDAP_SERVER_SHOW_DELETED_OID_W;
                            showDeletedControl.ldctl_value.bv_len = 0;
                            showDeletedControl.ldctl_value.bv_val = NULL;
                            showDeletedControl.ldctl_iscritical = TRUE;

                            // Initialzie the LDAPControl structure
                            PLDAPControlW ldapControls[] = { &showDeletedControl, NULL };

                            /*
                            Modify the specified attributes. This must performed 
                            in one step, which is why the LDAP APIs must be used 
                            to restore a deleted object.
                            */
                            ulRC = ldap_modify_ext_sW(ld, (PWCHAR)pwszDeletedDN, ldapMods, ldapControls, NULL);
                            if(LDAP_SUCCESS == ulRC)
                            {
                                hr = S_OK;
                            }
                            else if(LDAP_ALREADY_EXISTS == ulRC)
                            {
                                /*
                                An object already exists with the specified name 
                                in the specified target container. At this point, 
                                a new name must be selected.
                                */
                            }
                        }
                    }
                }

                if(LDAP_SUCCESS != ulRC)
                {
                    hr = ulRC;
                    
                    OutputDebugString(ldap_err2string(ulRC));
                }

                // Release the LDAP session.
                ldap_unbind(ld);
            }
        }
        else
        {
            /*
            If the end of the string is reached before the delimiter is found, just 
            end and fail.
            */
            hr = E_INVALIDARG;
        }
    
        delete pwszNewDN;
    }
    else
    {
        hr = E_OUTOFMEMORY;
    }

    return hr;
}