/*********************************************************************** * ldap_modify_ext_sA (WLDAP32.@) * * See ldap_modify_ext_sW. */ ULONG CDECL ldap_modify_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[], PLDAPControlA *serverctrls, PLDAPControlA *clientctrls ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP WCHAR *dnW = NULL; LDAPModW **modsW = NULL; LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL; ret = WLDAP32_LDAP_NO_MEMORY; TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_a(dn), mods, serverctrls, clientctrls ); if (!ld) return WLDAP32_LDAP_PARAM_ERROR; if (dn) { dnW = strAtoW( dn ); if (!dnW) goto exit; } if (mods) { modsW = modarrayAtoW( mods ); if (!modsW) goto exit; } if (serverctrls) { serverctrlsW = controlarrayAtoW( serverctrls ); if (!serverctrlsW) goto exit; } if (clientctrls) { clientctrlsW = controlarrayAtoW( clientctrls ); if (!clientctrlsW) goto exit; } ret = ldap_modify_ext_sW( ld, dnW, modsW, serverctrlsW, clientctrlsW ); exit: strfreeW( dnW ); modarrayfreeW( modsW ); controlarrayfreeW( serverctrlsW ); controlarrayfreeW( clientctrlsW ); #endif return ret; }
//---------------------------------------------------------------------------- // // 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 delted 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) { lstrcpyW(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. lstrcatW(pwszNewDN, L","); lstrcatW(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; }