-
Notifications
You must be signed in to change notification settings - Fork 15
/
LDAPQuery.cpp
178 lines (141 loc) · 6.23 KB
/
LDAPQuery.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "LDAPQuery.h"
#pragma comment(lib, "wldap32.lib")
// 构造函数,初始化 LDAP 查询对象
LDAPQuery::LDAPQuery(const std::wstring& dc_wstr) : ldap(nullptr), version(LDAP_VERSION3), errorCode(0), dc_wstr(dc_wstr), searchResult(nullptr) {}
// 析构函数,释放资源
LDAPQuery::~LDAPQuery() {
if (searchResult) {
ldap_msgfree(searchResult);
}
if (ldap) {
ldap_unbind_s(ldap);
}
}
// 初始化 LDAP 查询对象
bool LDAPQuery::Initialize() {
// 初始化 LDAP 连接
//ldap = ldap_initW(const_cast<wchar_t*>(dc_wstr.c_str()), LDAP_PORT); // 这样更简洁, 但是进行了类型转换
// 动态分配 wchar_t 数组来存储 std::wstring 字符串的宽字符, 这样可以避免使用 const_cast 来去除 const 属性
wchar_t* dcW = new wchar_t[dc_wstr.length() + 1];
wcscpy_s(dcW, dc_wstr.length() + 1, dc_wstr.c_str());
ldap = ldap_initW(dcW, LDAP_PORT);
// 释放内存
delete[] dcW;
if (!ldap) {
std::cerr << "Failed to initialize LDAP." << std::endl;
return false;
}
// 设置 LDAP 协议版本
errorCode = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
if (errorCode != LDAP_SUCCESS) {
std::cerr << "Failed to set LDAP option." << std::endl;
ldap_unbind_s(ldap);
return false;
}
return true;
}
// 绑定 LDAP 连接
bool LDAPQuery::Bind() {
errorCode = ldap_bind_sW(ldap, nullptr, nullptr, LDAP_AUTH_NEGOTIATE);
if (errorCode != LDAP_SUCCESS) {
std::cerr << "Failed to bind LDAP." << std::endl;
ldap_unbind_s(ldap);
return false;
}
return true;
}
//执行 LDAP 查询, 接受三个参数, 分别是 LDAP 目录名称 (dn), 查询过滤器 (filter), 和要返回的属性 (attribute)
//bool LDAPQuery::Search(const std::wstring& dn, const std::wstring& filter, const std::wstring& attribute) {
// std::wcout << dn << std::endl;
// //PWSTR attributes[] = { const_cast<wchar_t*>(attribute.c_str()), nullptr };
// PWCHAR attributes[] = { (PWCHAR)L"dNSHostName", NULL };
// //PWSTR attributes[] = { attribute.data(), nullptr };
// PWSTR filterPtr = const_cast<wchar_t*>(filter.c_str());
// PWSTR dnPtr = const_cast<wchar_t*>(dn.c_str());
//
// //errorCode = ldap_search_sW(ldap, dnPtr, LDAP_SCOPE_SUBTREE, filterPtr, attributes, 0, &searchResult);
// errorCode = ldap_search_s(ldap, const_cast<PWCHAR>(dn.c_str()), LDAP_SCOPE_SUBTREE, const_cast<PWCHAR>(filter.c_str()), attributes, 0, &searchResult);
// std::wcout << errorCode << std::endl;
// if (errorCode != LDAP_SUCCESS) {
// std::cerr << "Failed to search LDAP." << std::endl;
// ldap_unbind_s(ldap);
// return false;
// }
//
// return true;
//}
// 执行 LDAP 查询, 接受三个参数, 分别是 LDAP 目录名称 (dn_wstr), 查询过滤器 (filter_wstr), 和要返回的属性 (attribute_wstr)
bool LDAPQuery::Search(const std::wstring& dn_wstr, const std::wstring& filter_wstr, const std::wstring& attribute_wstr) {
// 动态分配 wchar_t 数组来存储 std::wstring 字符串的宽字符, 这样可以避免使用 const_cast 来去除 const 属性
wchar_t* dnPtr = new wchar_t[dn_wstr.length() + 1];
wcscpy_s(dnPtr, dn_wstr.length() + 1, dn_wstr.c_str());
wchar_t* filterPtr = new wchar_t[filter_wstr.length() + 1];
wcscpy_s(filterPtr, filter_wstr.length() + 1, filter_wstr.c_str());
wchar_t* attributePtr = new wchar_t[attribute_wstr.length() + 1];
wcscpy_s(attributePtr, attribute_wstr.length() + 1, attribute_wstr.c_str());
// Set search parameters
PWSTR attributes[] = { attributePtr, nullptr };
// Perform LDAP search
errorCode = ldap_search_sW(ldap, dnPtr, LDAP_SCOPE_SUBTREE, filterPtr, attributes, 0, &searchResult);
if (errorCode != LDAP_SUCCESS) {
std::wcerr << errorCode << std::endl;
std::wcerr << L"Failed to search LDAP." << std::endl;
ldap_unbind_s(ldap);
// Free dynamically allocated memory
delete[] dnPtr;
delete[] filterPtr;
delete[] attributePtr;
return false;
}
// Free dynamically allocated memory
delete[] dnPtr;
delete[] filterPtr;
delete[] attributePtr;
return true;
}
// 在 LDAP 查询结果中提取 "dNSHostName" 属性的值
std::wstring LDAPQuery::GetdNSHostName() {
std::wstringstream output_wstringStream;
// 将输出重定向到字符串流
std::wstreambuf* outputBuffer = std::wcout.rdbuf();
std::wcout.rdbuf(output_wstringStream.rdbuf());
// 遍历 LDAP 查询结果并输出到字符串流
for (LDAPMessage* entry = ldap_first_entry(ldap, searchResult); entry != nullptr; entry = ldap_next_entry(ldap, entry))
{
//PWSTR* values = ldap_get_valuesW(ldap, entry, const_cast<wchar_t*>(L"dNSHostName"));
std::wstring attrName_wstr = L"dNSHostName";
wchar_t* attrNameW = new wchar_t[attrName_wstr.length() + 1];
wcscpy_s(attrNameW, attrName_wstr.length() + 1, attrName_wstr.c_str());
PWSTR* values = ldap_get_valuesW(ldap, entry, attrNameW);
delete[] attrNameW;
if (values != nullptr)
{
std::wcout << values[0] << std::endl;
ldap_value_freeW(values);
}
}
std::wcout.rdbuf(outputBuffer);
return output_wstringStream.str();
}
// 在 LDAP 查询结果中提取 "operatingSystem" 属性的值
std::wstring LDAPQuery::GetOperatingSystem() {
std::wostringstream output_wostringstream;
std::wstreambuf* outputBuffer = std::wcout.rdbuf();
std::wcout.rdbuf(output_wostringstream.rdbuf());
for (LDAPMessage* entry = ldap_first_entry(ldap, searchResult); entry != nullptr; entry = ldap_next_entry(ldap, entry))
{
//PWSTR* values = ldap_get_valuesW(ldap, entry, const_cast<wchar_t*>(L"operatingSystem"));
std::wstring attrName_wstr = L"operatingSystem";
wchar_t* attrNameW = new wchar_t[attrName_wstr.length() + 1];
wcscpy_s(attrNameW, attrName_wstr.length() + 1, attrName_wstr.c_str());
PWSTR* values = ldap_get_valuesW(ldap, entry, attrNameW);
delete[] attrNameW;
if (values != nullptr)
{
output_wostringstream << values[0] << std::endl;
ldap_value_freeW(values);
}
}
std::wcout.rdbuf(outputBuffer);
return output_wostringstream.str();
}