diff options
Diffstat (limited to 'winpr/libwinpr/dsparse')
-rw-r--r-- | winpr/libwinpr/dsparse/CMakeLists.txt | 26 | ||||
-rw-r--r-- | winpr/libwinpr/dsparse/ModuleOptions.cmake | 9 | ||||
-rw-r--r-- | winpr/libwinpr/dsparse/dsparse.c | 142 | ||||
-rw-r--r-- | winpr/libwinpr/dsparse/test/CMakeLists.txt | 25 | ||||
-rw-r--r-- | winpr/libwinpr/dsparse/test/TestDsMakeSpn.c | 151 |
5 files changed, 353 insertions, 0 deletions
diff --git a/winpr/libwinpr/dsparse/CMakeLists.txt b/winpr/libwinpr/dsparse/CMakeLists.txt new file mode 100644 index 0000000..e455ccc --- /dev/null +++ b/winpr/libwinpr/dsparse/CMakeLists.txt @@ -0,0 +1,26 @@ +# WinPR: Windows Portable Runtime +# libwinpr-dsparse cmake build script +# +# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +winpr_module_add(dsparse.c) + +if(WIN32) + winpr_library_add_public(ntdsapi) +endif() + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/dsparse/ModuleOptions.cmake b/winpr/libwinpr/dsparse/ModuleOptions.cmake new file mode 100644 index 0000000..647de1b --- /dev/null +++ b/winpr/libwinpr/dsparse/ModuleOptions.cmake @@ -0,0 +1,9 @@ + +set(MINWIN_LAYER "0") +set(MINWIN_GROUP "none") +set(MINWIN_MAJOR_VERSION "0") +set(MINWIN_MINOR_VERSION "0") +set(MINWIN_SHORT_NAME "dsparse") +set(MINWIN_LONG_NAME "Domain Controller and Replication Management Functions") +set(MODULE_LIBRARY_NAME "${MINWIN_SHORT_NAME}") + diff --git a/winpr/libwinpr/dsparse/dsparse.c b/winpr/libwinpr/dsparse/dsparse.c new file mode 100644 index 0000000..e1e4132 --- /dev/null +++ b/winpr/libwinpr/dsparse/dsparse.c @@ -0,0 +1,142 @@ +/** + * WinPR: Windows Portable Runtime + * Active Directory Domain Services Parsing Functions + * + * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <winpr/config.h> + +#include <winpr/dsparse.h> +#include <winpr/assert.h> + +/** + * dsparse.dll: + * + * DsCrackSpnA + * DsCrackSpnW + * DsCrackUnquotedMangledRdnA + * DsCrackUnquotedMangledRdnW + * DsGetRdnW + * DsIsMangledDnA + * DsIsMangledDnW + * DsIsMangledRdnValueA + * DsIsMangledRdnValueW + * DsMakeSpnA + * DsMakeSpnW + * DsQuoteRdnValueA + * DsQuoteRdnValueW + * DsUnquoteRdnValueA + * DsUnquoteRdnValueW + */ + +#if !defined(_WIN32) || defined(_UWP) + +DWORD DsMakeSpnW(LPCWSTR ServiceClass, LPCWSTR ServiceName, LPCWSTR InstanceName, + USHORT InstancePort, LPCWSTR Referrer, DWORD* pcSpnLength, LPWSTR pszSpn) +{ + DWORD res = ERROR_OUTOFMEMORY; + char* ServiceClassA = NULL; + char* ServiceNameA = NULL; + char* InstanceNameA = NULL; + char* ReferrerA = NULL; + char* pszSpnA = NULL; + size_t length = 0; + + WINPR_ASSERT(ServiceClass); + WINPR_ASSERT(ServiceName); + WINPR_ASSERT(pcSpnLength); + + length = *pcSpnLength; + if ((length > 0) && pszSpn) + pszSpnA = calloc(length + 1, sizeof(char)); + + if (ServiceClass) + { + ServiceClassA = ConvertWCharToUtf8Alloc(ServiceClass, NULL); + if (!ServiceClassA) + goto fail; + } + if (ServiceName) + { + ServiceNameA = ConvertWCharToUtf8Alloc(ServiceName, NULL); + if (!ServiceNameA) + goto fail; + } + if (InstanceName) + { + InstanceNameA = ConvertWCharToUtf8Alloc(InstanceName, NULL); + if (!InstanceNameA) + goto fail; + } + if (Referrer) + { + ReferrerA = ConvertWCharToUtf8Alloc(Referrer, NULL); + if (!ReferrerA) + goto fail; + } + res = DsMakeSpnA(ServiceClassA, ServiceNameA, InstanceNameA, InstancePort, ReferrerA, + pcSpnLength, pszSpnA); + + if (res == ERROR_SUCCESS) + { + if (ConvertUtf8NToWChar(pszSpnA, *pcSpnLength, pszSpn, length) < 0) + res = ERROR_OUTOFMEMORY; + } + +fail: + free(ServiceClassA); + free(ServiceNameA); + free(InstanceNameA); + free(ReferrerA); + free(pszSpnA); + return res; +} + +DWORD DsMakeSpnA(LPCSTR ServiceClass, LPCSTR ServiceName, LPCSTR InstanceName, USHORT InstancePort, + LPCSTR Referrer, DWORD* pcSpnLength, LPSTR pszSpn) +{ + DWORD SpnLength = 0; + DWORD ServiceClassLength = 0; + DWORD ServiceNameLength = 0; + + WINPR_ASSERT(ServiceClass); + WINPR_ASSERT(ServiceName); + WINPR_ASSERT(pcSpnLength); + + WINPR_UNUSED(InstanceName); + WINPR_UNUSED(InstancePort); + WINPR_UNUSED(Referrer); + + if ((*pcSpnLength != 0) && (pszSpn == NULL)) + return ERROR_INVALID_PARAMETER; + + ServiceClassLength = (DWORD)strlen(ServiceClass); + ServiceNameLength = (DWORD)strlen(ServiceName); + + SpnLength = ServiceClassLength + 1 + ServiceNameLength + 1; + + if ((*pcSpnLength == 0) || (*pcSpnLength < SpnLength)) + { + *pcSpnLength = SpnLength; + return ERROR_BUFFER_OVERFLOW; + } + + sprintf_s(pszSpn, *pcSpnLength, "%s/%s", ServiceClass, ServiceName); + + return ERROR_SUCCESS; +} + +#endif diff --git a/winpr/libwinpr/dsparse/test/CMakeLists.txt b/winpr/libwinpr/dsparse/test/CMakeLists.txt new file mode 100644 index 0000000..d2b5ea4 --- /dev/null +++ b/winpr/libwinpr/dsparse/test/CMakeLists.txt @@ -0,0 +1,25 @@ + +set(MODULE_NAME "TestDsParse") +set(MODULE_PREFIX "TEST_DSPARSE") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestDsMakeSpn.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +target_link_libraries(${MODULE_NAME} winpr) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") diff --git a/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c b/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c new file mode 100644 index 0000000..dcaf635 --- /dev/null +++ b/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c @@ -0,0 +1,151 @@ + +#include <stdio.h> +#include <winpr/crt.h> +#include <winpr/winpr.h> +#include <winpr/tchar.h> +#include <winpr/dsparse.h> + +static BOOL test_DsMakeSpnA(void) +{ + LPCSTR testServiceClass = "HTTP"; + LPCSTR testServiceName = "LAB1-W2K8R2-GW.lab1.awake.local"; + LPCSTR testSpn = "HTTP/LAB1-W2K8R2-GW.lab1.awake.local"; + BOOL rc = FALSE; + CHAR Spn[100] = { 0 }; + DWORD status = 0; + DWORD SpnLength = -1; + + status = DsMakeSpnA(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_INVALID_PARAMETER) + { + printf("DsMakeSpnA: expected ERROR_INVALID_PARAMETER\n"); + goto fail; + } + + SpnLength = 0; + status = DsMakeSpnA(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_BUFFER_OVERFLOW) + { + printf("DsMakeSpnA: expected ERROR_BUFFER_OVERFLOW\n"); + goto fail; + } + + if (SpnLength != 37) + { + printf("DsMakeSpnA: SpnLength mismatch: Actual: %" PRIu32 ", Expected: 37\n", SpnLength); + goto fail; + } + + status = DsMakeSpnA(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, Spn); + + if (status != ERROR_SUCCESS) + { + printf("DsMakeSpnA: expected ERROR_SUCCESS\n"); + goto fail; + } + + if (strcmp(Spn, testSpn) != 0) + { + printf("DsMakeSpnA: SPN mismatch: Actual: %s, Expected: %s\n", Spn, testSpn); + goto fail; + } + + printf("DsMakeSpnA: %s\n", Spn); + rc = TRUE; +fail: + return rc; +} + +static BOOL test_DsMakeSpnW(void) +{ + const CHAR ctestServiceClass[] = { 'H', 'T', 'T', 'P', '\0' }; + const CHAR ctestServiceName[] = { 'L', 'A', 'B', '1', '-', 'W', '2', 'K', '8', 'R', '2', + '-', 'G', 'W', '.', 'l', 'a', 'b', '1', '.', 'a', 'w', + 'a', 'k', 'e', '.', 'l', 'o', 'c', 'a', 'l', '\0' }; + const CHAR ctestSpn[] = { 'H', 'T', 'T', 'P', '/', 'L', 'A', 'B', '1', '-', 'W', '2', 'K', + '8', 'R', '2', '-', 'G', 'W', '.', 'l', 'a', 'b', '1', '.', 'a', + 'w', 'a', 'k', 'e', '.', 'l', 'o', 'c', 'a', 'l', '\0' }; + WCHAR testServiceClass[ARRAYSIZE(ctestServiceClass)] = { 0 }; + WCHAR testServiceName[ARRAYSIZE(ctestServiceName)] = { 0 }; + WCHAR testSpn[ARRAYSIZE(ctestSpn)] = { 0 }; + + BOOL rc = FALSE; + WCHAR Spn[100] = { 0 }; + DWORD status = 0; + DWORD SpnLength = -1; + + ConvertUtf8NToWChar(ctestServiceClass, ARRAYSIZE(ctestServiceClass), testServiceClass, + ARRAYSIZE(testServiceClass)); + ConvertUtf8NToWChar(ctestServiceName, ARRAYSIZE(ctestServiceName), testServiceName, + ARRAYSIZE(testServiceName)); + ConvertUtf8NToWChar(ctestSpn, ARRAYSIZE(ctestSpn), testSpn, ARRAYSIZE(testSpn)); + + status = DsMakeSpnW(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_INVALID_PARAMETER) + { + printf("DsMakeSpnW: expected ERROR_INVALID_PARAMETER\n"); + goto fail; + } + + SpnLength = 0; + status = DsMakeSpnW(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_BUFFER_OVERFLOW) + { + printf("DsMakeSpnW: expected ERROR_BUFFER_OVERFLOW\n"); + goto fail; + } + + if (SpnLength != 37) + { + printf("DsMakeSpnW: SpnLength mismatch: Actual: %" PRIu32 ", Expected: 37\n", SpnLength); + goto fail; + } + + status = DsMakeSpnW(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, Spn); + + if (status != ERROR_SUCCESS) + { + printf("DsMakeSpnW: expected ERROR_SUCCESS\n"); + goto fail; + } + + if (_wcscmp(Spn, testSpn) != 0) + { + char buffer1[8192] = { 0 }; + char buffer2[8192] = { 0 }; + char* SpnA = buffer1; + char* testSpnA = buffer2; + + ConvertWCharToUtf8(Spn, SpnA, ARRAYSIZE(buffer1)); + ConvertWCharToUtf8(testSpn, testSpnA, ARRAYSIZE(buffer2)); + printf("DsMakeSpnW: SPN mismatch: Actual: %s, Expected: %s\n", SpnA, testSpnA); + goto fail; + } + + { + char buffer[8192] = { 0 }; + char* SpnA = buffer; + + ConvertWCharToUtf8(Spn, SpnA, ARRAYSIZE(buffer)); + printf("DsMakeSpnW: %s\n", SpnA); + } + + rc = TRUE; +fail: + return rc; +} +int TestDsMakeSpn(int argc, char* argv[]) +{ + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!test_DsMakeSpnA()) + return -1; + if (!test_DsMakeSpnW()) + return -2; + return 0; +} |