mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-02-28 06:13:03 +01:00
Refactor into generic query
Querying is now generic so that more flexibility is made available to the attacker.
This commit is contained in:
parent
3ba9b0549b
commit
4e01c9ef98
@ -6,21 +6,58 @@
|
||||
#include "adsi.h"
|
||||
#include "adsi_interface.h"
|
||||
|
||||
/*!
|
||||
* @brief Helper function that converts an ASCII string to a wide char string.
|
||||
* @param lpValue ASCII string to convert.
|
||||
* @param lpwValue Target memory for the converted string.
|
||||
* @remark lpwValue must already have enough memory allocated to hold all the characters.
|
||||
* @returns Indication of success or failure.
|
||||
*/
|
||||
DWORD to_wide_string(LPSTR lpValue, LPWSTR* lpwValue)
|
||||
{
|
||||
size_t charsCopied = 0;
|
||||
DWORD valueLength;
|
||||
DWORD dwResult;
|
||||
|
||||
do
|
||||
{
|
||||
if (lpValue == NULL)
|
||||
{
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Value parameter missing", ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
valueLength = lstrlenA(lpValue);
|
||||
*lpwValue = (LPWSTR)malloc(sizeof(WCHAR)* (lstrlenA(lpValue) + 1));
|
||||
if (*lpwValue == NULL)
|
||||
{
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to allocate memory", ERROR_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
mbstowcs_s(&charsCopied, *lpwValue, valueLength + 1, lpValue, valueLength);
|
||||
dwResult = ERROR_SUCCESS;
|
||||
} while (0);
|
||||
|
||||
return dwResult;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enumerate all the users in AD.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @param packet Pointer to the incoming \c Packet instance.
|
||||
* @returns The ERROR_SUCCESS constant.
|
||||
* @returns Indication of success or failure.
|
||||
* @remark Real error codes are returned to the caller via a response packet.
|
||||
*/
|
||||
DWORD request_adsi_user_enum(Remote *remote, Packet *packet)
|
||||
DWORD request_adsi_domain_query(Remote *remote, Packet *packet)
|
||||
{
|
||||
DWORD dwResult = ERROR_SUCCESS;
|
||||
LPSTR lpDomain = NULL;
|
||||
LPSTR lpValue = NULL;
|
||||
LPWSTR lpwDomain = NULL;
|
||||
size_t charsCopied = 0;
|
||||
size_t domainLength = 0;
|
||||
LPWSTR lpwFilter = NULL;
|
||||
LPWSTR* lpwFields = NULL;
|
||||
DWORD fieldCount = 0;
|
||||
DWORD fieldIndex = 0;
|
||||
Packet * response = packet_create_response(packet);
|
||||
Tlv fieldTlv;
|
||||
|
||||
do
|
||||
{
|
||||
@ -29,28 +66,70 @@ DWORD request_adsi_user_enum(Remote *remote, Packet *packet)
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to create response packet", ERROR_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
// Get the domain that we're doing the query against
|
||||
lpDomain = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_DOMAIN);
|
||||
|
||||
if (lpDomain == NULL)
|
||||
lpValue = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_DOMAIN);
|
||||
dprintf("[EXTAPI ADSI] Domain: %s", lpValue);
|
||||
dwResult = to_wide_string(lpValue, &lpwDomain);
|
||||
if (dwResult != ERROR_SUCCESS)
|
||||
{
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Domain parameter missing", ERROR_INVALID_PARAMETER);
|
||||
dprintf("[EXTAPI ADSI] Failed to get Domain");
|
||||
break;
|
||||
}
|
||||
|
||||
dprintf("[EXTAPI ADSI] Request to enumerate users in domain %s", lpDomain);
|
||||
|
||||
domainLength = lstrlenA(lpDomain);
|
||||
lpwDomain = (LPWSTR)malloc(sizeof(WCHAR)* (lstrlenA(lpDomain) + 1));
|
||||
if (lpwDomain == NULL)
|
||||
lpValue = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_FILTER);
|
||||
dprintf("[EXTAPI ADSI] Filter: %s", lpValue);
|
||||
dwResult = to_wide_string(lpValue, &lpwFilter);
|
||||
if (dwResult != ERROR_SUCCESS)
|
||||
{
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to allocate memory", ERROR_OUTOFMEMORY);
|
||||
dprintf("[EXTAPI ADSI] Failed to get Filter");
|
||||
break;
|
||||
}
|
||||
mbstowcs_s(&charsCopied, lpwDomain, domainLength + 1, lpDomain, domainLength);
|
||||
|
||||
dprintf("[EXTAPI ADSI] Beginning user enumeration");
|
||||
dwResult = domain_user_enum(lpwDomain, response);
|
||||
while (packet_enum_tlv(packet, fieldCount, TLV_TYPE_EXT_ADSI_FIELD, &fieldTlv) == ERROR_SUCCESS)
|
||||
{
|
||||
lpValue = (char*)fieldTlv.buffer;
|
||||
dprintf("[EXTAPI ADSI] Field %u: %s", fieldCount, lpValue);
|
||||
lpwFields = (LPWSTR*)realloc(lpwFields, sizeof(LPWSTR) * (fieldCount + 1));
|
||||
|
||||
if (lpwFields == NULL)
|
||||
{
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to allocate memory", ERROR_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
dwResult = to_wide_string(lpValue, &lpwFields[fieldCount]);
|
||||
if (dwResult != ERROR_SUCCESS)
|
||||
{
|
||||
dprintf("[EXTAPI ADSI] Failed to get field as wide string");
|
||||
break;
|
||||
}
|
||||
++fieldCount;
|
||||
}
|
||||
|
||||
dprintf("[EXTAPI ADSI] Field count: %u", fieldCount, lpValue);
|
||||
|
||||
if (dwResult == ERROR_SUCCESS)
|
||||
{
|
||||
dprintf("[EXTAPI ADSI] Beginning user enumeration");
|
||||
dwResult = domain_query(lpwDomain, lpwFilter, lpwFields, fieldCount, response);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (lpwFields)
|
||||
{
|
||||
for (fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
|
||||
{
|
||||
if (lpwFields[fieldIndex])
|
||||
{
|
||||
free(lpwFields[fieldIndex]);
|
||||
}
|
||||
}
|
||||
free(lpwFields);
|
||||
}
|
||||
|
||||
if (lpwFilter)
|
||||
{
|
||||
free(lpwFilter);
|
||||
}
|
||||
|
||||
if (lpwDomain)
|
||||
{
|
||||
free(lpwDomain);
|
||||
@ -64,62 +143,3 @@ DWORD request_adsi_user_enum(Remote *remote, Packet *packet)
|
||||
|
||||
return dwResult;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enumerate all the computers in AD.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @param packet Pointer to the incoming \c Packet instance.
|
||||
* @returns The ERROR_SUCCESS constant.
|
||||
* @remark Real error codes are returned to the caller via a response packet.
|
||||
*/
|
||||
DWORD request_adsi_computer_enum(Remote *remote, Packet *packet)
|
||||
{
|
||||
DWORD dwResult = ERROR_SUCCESS;
|
||||
LPSTR lpDomain = NULL;
|
||||
LPWSTR lpwDomain = NULL;
|
||||
size_t charsCopied = 0;
|
||||
size_t domainLength = 0;
|
||||
Packet * response = packet_create_response(packet);
|
||||
|
||||
do
|
||||
{
|
||||
if (!response)
|
||||
{
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to create response packet", ERROR_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
// Get the domain that we're doing the query against
|
||||
lpDomain = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_DOMAIN);
|
||||
|
||||
if (lpDomain == NULL)
|
||||
{
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Domain parameter missing", ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
dprintf("[EXTAPI ADSI] Request to enumerate computers in domain %s", lpDomain);
|
||||
|
||||
domainLength = lstrlenA(lpDomain);
|
||||
lpwDomain = (LPWSTR)malloc(sizeof(WCHAR)* (lstrlenA(lpDomain) + 1));
|
||||
if (lpwDomain == NULL)
|
||||
{
|
||||
BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to allocate memory", ERROR_OUTOFMEMORY);
|
||||
}
|
||||
mbstowcs_s(&charsCopied, lpwDomain, domainLength + 1, lpDomain, domainLength);
|
||||
|
||||
dprintf("[EXTAPI ADSI] Beginning computer enumeration");
|
||||
dwResult = domain_computer_enum(lpwDomain, response);
|
||||
} while (0);
|
||||
|
||||
if (lpwDomain)
|
||||
{
|
||||
free(lpwDomain);
|
||||
}
|
||||
|
||||
dprintf("[EXTAPI ADSI] Transmitting response back to caller.");
|
||||
if (response)
|
||||
{
|
||||
packet_transmit_response(dwResult, remote, response);
|
||||
}
|
||||
|
||||
return dwResult;
|
||||
}
|
@ -5,7 +5,8 @@
|
||||
#ifndef _METERPRETER_SOURCE_EXTENSION_EXTAPI_ADSI_H
|
||||
#define _METERPRETER_SOURCE_EXTENSION_EXTAPI_ADSI_H
|
||||
|
||||
DWORD request_adsi_user_enum(Remote *remote, Packet *packet);
|
||||
DWORD request_adsi_computer_enum(Remote *remote, Packet *packet);
|
||||
//DWORD request_adsi_user_enum(Remote *remote, Packet *packet);
|
||||
//DWORD request_adsi_computer_enum(Remote *remote, Packet *packet);
|
||||
DWORD request_adsi_domain_query(Remote *remote, Packet *packet);
|
||||
|
||||
#endif
|
||||
|
@ -16,9 +16,19 @@ extern "C" {
|
||||
#define VALUE_SIZE 512
|
||||
#define PATH_SIZE 256
|
||||
|
||||
/*! @brief The GUID of the Directory Search COM object. */
|
||||
static const IID IID_IDirectorySearch = { 0x109BA8EC, 0x92F0, 0x11D0, { 0xA7, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8 } };
|
||||
|
||||
DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols, TlvType* tlvIds, UINT queryColCount, TlvType groupTlvId, Packet* response)
|
||||
/*!
|
||||
* @brief Perform a domain query via ADSI.
|
||||
* @param lpwDomain Name of the domain that is to be queried.
|
||||
* @param lpwFilter The filter to use when reading objects (LDAP style).
|
||||
* @param lpwQueryCols Array of column names representing fields to extract.
|
||||
* @param queryColCount Number of columns in \c lpwQueryCols.
|
||||
* @param response The response \c Packet to add the results to.
|
||||
*/
|
||||
DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
|
||||
UINT queryColCount, Packet* response)
|
||||
{
|
||||
HRESULT hResult;
|
||||
WCHAR cbPath[PATH_SIZE];
|
||||
@ -39,8 +49,10 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols, Tl
|
||||
dprintf("[ADSI] Unable to open domain: %x", hResult);
|
||||
break;
|
||||
}
|
||||
dprintf("[ADSI] Domain opened");
|
||||
|
||||
// run the search for the values listed above
|
||||
OutputDebugStringW(lpwFilter);
|
||||
hResult = pDirSearch->ExecuteSearch(lpwFilter, lpwQueryCols, queryColCount, &hSearch);
|
||||
if (hResult != S_OK)
|
||||
{
|
||||
@ -48,9 +60,9 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols, Tl
|
||||
break;
|
||||
}
|
||||
|
||||
ADS_SEARCH_COLUMN col;
|
||||
// These buffers are used to store the values that we're reading out of AD
|
||||
Tlv* entries = (Tlv*)malloc(queryColCount * sizeof(Tlv));
|
||||
char* values = (char*)malloc(VALUE_SIZE * queryColCount);
|
||||
char* values = (char*)malloc(queryColCount * VALUE_SIZE);
|
||||
|
||||
// now we iterate through the search results
|
||||
while (SUCCEEDED((hResult = pDirSearch->GetNextRow(hSearch))))
|
||||
@ -66,29 +78,35 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols, Tl
|
||||
DWORD dwIndex = 0;
|
||||
size_t charsConverted;
|
||||
QWORD qwValue;
|
||||
UINT uiValue;
|
||||
ADS_SEARCH_COLUMN col;
|
||||
|
||||
// iterate through the columns, adding Tlv entries as we go, but only
|
||||
// if we can get the values out.
|
||||
for (DWORD colIndex = 0; colIndex < queryColCount; ++colIndex)
|
||||
{
|
||||
char* valueTarget = values + dwIndex * VALUE_SIZE;
|
||||
|
||||
entries[dwIndex].buffer = (PUCHAR)valueTarget;
|
||||
entries[dwIndex].header.type = TLV_TYPE_EXT_ADSI_VALUE;
|
||||
|
||||
// try to do something sane based on the type that's being used to store
|
||||
// the value.
|
||||
HRESULT hr = pDirSearch->GetColumn(hSearch, lpwQueryCols[dwIndex], &col);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
char* valueTarget = values + (dwIndex * VALUE_SIZE);
|
||||
entries[dwIndex].buffer = (PUCHAR)valueTarget;
|
||||
entries[dwIndex].header.type = tlvIds[dwIndex];
|
||||
|
||||
switch (col.dwADsType)
|
||||
{
|
||||
case ADSTYPE_LARGE_INTEGER:
|
||||
qwValue = col.pADsValues->LargeInteger.QuadPart;
|
||||
*((QWORD*)valueTarget) = htonq(qwValue);
|
||||
entries[dwIndex].header.length = sizeof(QWORD);
|
||||
dprintf("[ADSI] Adding large int value %ul", (QWORD)qwValue);
|
||||
qwValue = htonq((QWORD)col.pADsValues->LargeInteger.QuadPart);
|
||||
_i64toa_s(qwValue, valueTarget, VALUE_SIZE, 10);
|
||||
entries[dwIndex].header.length = lstrlenA(valueTarget) + 1;
|
||||
dprintf("[ADSI] Adding large int value %ul", (UINT)col.pADsValues->Integer);
|
||||
break;
|
||||
case ADSTYPE_INTEGER:
|
||||
*((UINT*)valueTarget) = htonl((UINT)col.pADsValues->Integer);
|
||||
entries[dwIndex].header.length = sizeof(UINT);
|
||||
uiValue = htonl((UINT)col.pADsValues->Integer);
|
||||
_itoa_s(uiValue, valueTarget, VALUE_SIZE, 10);
|
||||
entries[dwIndex].header.length = lstrlenA(valueTarget) + 1;
|
||||
dprintf("[ADSI] Adding int value %u", (UINT)col.pADsValues->Integer);
|
||||
break;
|
||||
default:
|
||||
@ -97,30 +115,33 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols, Tl
|
||||
: col.pADsValues->CaseExactString;
|
||||
|
||||
wcstombs_s(&charsConverted, valueTarget, VALUE_SIZE, source, VALUE_SIZE - 1);
|
||||
dprintf("[ADSI] Adding %s", valueTarget);
|
||||
dprintf("[ADSI] Adding string %s", valueTarget);
|
||||
entries[dwIndex].header.length = lstrlenA(valueTarget) + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
dwIndex++;
|
||||
pDirSearch->FreeColumn(&col);
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("[ADSI] Col read failed: %x", hr);
|
||||
valueTarget[0] = 0;
|
||||
entries[dwIndex].header.length = 1;
|
||||
}
|
||||
|
||||
dwIndex++;
|
||||
}
|
||||
|
||||
if (dwIndex > 0)
|
||||
{
|
||||
dprintf("[ADSI] Adding group packet of %u values", dwIndex);
|
||||
// Throw the user details together in a group, ready to return.
|
||||
packet_add_tlv_group(response, groupTlvId, entries, dwIndex);
|
||||
packet_add_tlv_group(response, TLV_TYPE_EXT_ADSI_RESULT, entries, dwIndex);
|
||||
dprintf("[ADSI] Added group packet of %u values", dwIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("[ADSI] User found, but no fields extracted.");
|
||||
dprintf("[ADSI] Item found, but no fields extracted.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,26 +161,10 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols, Tl
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf("[ADSI] Failed to initialize COM");
|
||||
}
|
||||
|
||||
return (DWORD)hResult;
|
||||
}
|
||||
|
||||
DWORD domain_user_enum(LPCWSTR lpwDomain, Packet* response)
|
||||
{
|
||||
LPWSTR lpwFields[] = { L"samAccountName", L"description", L"Name", L"distinguishedname", L"comment" };
|
||||
TlvType tlvIds[] = { TLV_TYPE_EXT_ADSI_USER_SAM, TLV_TYPE_EXT_ADSI_USER_DESC,
|
||||
TLV_TYPE_EXT_ADSI_USER_NAME, TLV_TYPE_EXT_ADSI_USER_DN, TLV_TYPE_EXT_ADSI_USER_COMMENT };
|
||||
DWORD dwCols = sizeof(lpwFields) / sizeof(LPWSTR);
|
||||
|
||||
return domain_query(lpwDomain, L"(objectClass=user)", lpwFields, tlvIds, dwCols, TLV_TYPE_EXT_ADSI_USER, response);
|
||||
}
|
||||
|
||||
DWORD domain_computer_enum(LPCWSTR lpwDomain, Packet* response)
|
||||
{
|
||||
LPWSTR lpwFields[] = { L"description", L"Name", L"distinguishedname", L"comment" };
|
||||
TlvType tlvIds[] = { TLV_TYPE_EXT_ADSI_COMP_DESC, TLV_TYPE_EXT_ADSI_COMP_NAME,
|
||||
TLV_TYPE_EXT_ADSI_COMP_DN, TLV_TYPE_EXT_ADSI_COMP_COMMENT };
|
||||
DWORD dwCols = sizeof(lpwFields) / sizeof(LPWSTR);
|
||||
|
||||
return domain_query(lpwDomain, L"(objectClass=computer)", lpwFields, tlvIds, dwCols, TLV_TYPE_EXT_ADSI_COMP, response);
|
||||
}
|
@ -6,7 +6,6 @@
|
||||
#ifndef _METERPRETER_SOURCE_EXTENSION_EXTAPI_ADSI_INTERFACE_H
|
||||
#define _METERPRETER_SOURCE_EXTENSION_EXTAPI_ADSI_INTERFACE_H
|
||||
|
||||
DWORD domain_user_enum(LPCWSTR lpDomain, Packet* response);
|
||||
DWORD domain_computer_enum(LPCWSTR lpDomain, Packet* response);
|
||||
DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols, UINT queryColCount, Packet* response);
|
||||
|
||||
#endif
|
||||
|
@ -26,8 +26,7 @@ Command customCommands[] =
|
||||
COMMAND_REQ("extapi_service_query", request_service_query),
|
||||
COMMAND_REQ("extapi_clipboard_get_data", request_clipboard_get_data),
|
||||
COMMAND_REQ("extapi_clipboard_set_data", request_clipboard_set_data),
|
||||
COMMAND_REQ("extapi_adsi_user_enum", request_adsi_user_enum),
|
||||
COMMAND_REQ("extapi_adsi_computer_enum", request_adsi_computer_enum),
|
||||
COMMAND_REQ("extapi_adsi_domain_query", request_adsi_domain_query),
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
|
||||
|
@ -43,17 +43,9 @@
|
||||
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 48)
|
||||
|
||||
#define TLV_TYPE_EXT_ADSI_DOMAIN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 55)
|
||||
#define TLV_TYPE_EXT_ADSI_COMP MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 56)
|
||||
#define TLV_TYPE_EXT_ADSI_COMP_DESC MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 57)
|
||||
#define TLV_TYPE_EXT_ADSI_COMP_NAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 58)
|
||||
#define TLV_TYPE_EXT_ADSI_COMP_DN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 59)
|
||||
#define TLV_TYPE_EXT_ADSI_COMP_COMMENT MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 60)
|
||||
#define TLV_TYPE_EXT_ADSI_USER MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 61)
|
||||
#define TLV_TYPE_EXT_ADSI_USER_DESC MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 62)
|
||||
#define TLV_TYPE_EXT_ADSI_USER_NAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 63)
|
||||
#define TLV_TYPE_EXT_ADSI_USER_DN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 64)
|
||||
#define TLV_TYPE_EXT_ADSI_USER_COMMENT MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 65)
|
||||
#define TLV_TYPE_EXT_ADSI_USER_SAM MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 66)
|
||||
#define TLV_TYPE_EXT_ADSI_USER_ATTRIB MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 67)
|
||||
#define TLV_TYPE_EXT_ADSI_FILTER MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 56)
|
||||
#define TLV_TYPE_EXT_ADSI_FIELD MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 57)
|
||||
#define TLV_TYPE_EXT_ADSI_VALUE MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 58)
|
||||
#define TLV_TYPE_EXT_ADSI_RESULT MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 59)
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user