1 /**************************************************************************
2 * Copyright (C) 2005-2020 by Oleksandr Shneyder *
3 * <o.shneyder@phoca-gmbh.de> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18 #include "LDAPSession.h"
19 #include "x2goclientconfig.h"
20 #ifdef USELDAP
21 #include <stdlib.h>
22
23
ByteArray()24 ByteArray::ByteArray()
25 {
26 size=0;
27 data=0;
28 }
29
ByteArray(const ByteArray & src)30 ByteArray::ByteArray ( const ByteArray& src )
31 {
32 size=0;
33 data=0;
34 *this=src;
35 }
36
~ByteArray()37 ByteArray::~ByteArray()
38 {
39 _delete();
40 }
41
load(const char * buf,int len)42 void ByteArray::load ( const char* buf,int len )
43 {
44 _delete();
45 if ( len>0 )
46 {
47 size=len;
48 data=new char[size+1];
49 if ( !data )
50 throw string ( "Not enouth memory" );
51 memcpy ( data,buf,len );
52 data[size]=0;
53 }
54 }
55
fromStdStr(const string & src)56 void ByteArray::fromStdStr ( const string& src )
57 {
58 load ( src.c_str(),src.size() );
59 }
60
operator =(const ByteArray & src)61 void ByteArray::operator = ( const ByteArray& src )
62 {
63 load ( src.data,src.size );
64 }
65
_delete()66 void ByteArray::_delete()
67 {
68 if ( data )
69 {
70 delete []data;
71 size=0;
72 }
73 }
74
75 /////////////////////////////////////
76
77
LDAPSession(string server,int port,string bindDN,string pass,bool simple,bool start_tls)78 LDAPSession::LDAPSession ( string server,int port,string bindDN,
79 string pass, bool simple, bool start_tls )
80 {
81 ld=ldap_init ( server.c_str(),port );
82 if ( !ld )
83 throw LDAPExeption ( "ldap_init","Can't initialize LDAP library." );
84 int ver=3;
85 int errc=ldap_set_option ( ld,LDAP_OPT_PROTOCOL_VERSION,&ver );
86 if ( errc != LDAP_SUCCESS )
87 throw LDAPExeption ( "ldap_set_option",
88 ldap_err2string ( errc ) );
89 if ( start_tls )
90 {
91 errc=ldap_start_tls_s ( ld,NULL,NULL );
92 if ( errc != LDAP_SUCCESS )
93 throw LDAPExeption ( "ldap_start_tls_s",
94 ldap_err2string ( errc ) );
95 }
96 if ( !simple )
97 {
98 errc=ldap_bind_s ( ld,bindDN.c_str(),pass.c_str(),
99 LDAP_AUTH_SIMPLE );
100 if ( errc != LDAP_SUCCESS )
101 throw LDAPExeption ( "ldap_bind_s",
102 ldap_err2string ( errc ) );
103 }
104 else
105 {
106 errc=ldap_simple_bind_s ( ld,bindDN.c_str(),pass.c_str() );
107 if ( errc != LDAP_SUCCESS )
108 throw LDAPExeption ( "ldap_simple_bind_s",
109 ldap_err2string ( errc ) );
110 }
111 }
112
addStringValue(string dn,const list<LDAPStringValue> & values)113 void LDAPSession::addStringValue ( string dn,
114 const list<LDAPStringValue>& values )
115 {
116 list<LDAPStringValue>::const_iterator it=values.begin();
117 list<LDAPStringValue>::const_iterator end=values.end();
118 int i=0;
119 LDAPMod** mods= ( LDAPMod** ) malloc (
120 sizeof ( LDAPMod* ) *values.size() +1 );
121
122 for ( ;it!=end;++it )
123 {
124 mods[i]= ( LDAPMod* ) malloc ( sizeof ( LDAPMod ) );
125 mods[i]->mod_op=LDAP_MOD_ADD;
126 mods[i]->mod_type= ( char* ) malloc (
127 sizeof ( char ) *
128 ( *it ).attr.length() );
129
130 strcpy ( mods[i]->mod_type, ( *it ).attr.c_str() );
131
132 list<string>::const_iterator sit= ( *it ).value.begin();
133 list<string>::const_iterator send= ( *it ).value.end();
134 int j=0;
135 mods[i]->mod_vals.modv_strvals= ( char** ) malloc (
136 sizeof ( char* ) *
137 ( *it ).value.size() +1 );
138 for ( ;sit!=send;++sit )
139 {
140 mods[i]->mod_vals.modv_strvals[j]=
141 ( char* ) malloc (
142 sizeof ( char ) *
143 ( *sit ).length() );
144
145 strcpy ( mods[i]->mod_vals.modv_strvals[j],
146 ( *sit ).c_str() );
147 ++j;
148 }
149 mods[i]->mod_vals.modv_strvals[j]=0l;
150 ++i;
151 }
152 mods[i]=0l;
153
154 int errc= ldap_add_s ( ld,dn.c_str(),mods );
155 if ( errc != LDAP_SUCCESS )
156 throw LDAPExeption ( "ldap_add_s",ldap_err2string ( errc ) );
157
158 ldap_mods_free ( mods,1 );
159 }
160
161
modifyStringValue(string dn,const list<LDAPStringValue> & values)162 void LDAPSession::modifyStringValue ( string dn,
163 const list<LDAPStringValue>& values )
164 {
165 list<LDAPStringValue>::const_iterator it=values.begin();
166 list<LDAPStringValue>::const_iterator end=values.end();
167 int i=0;
168 LDAPMod** mods= ( LDAPMod** ) malloc (
169 sizeof ( LDAPMod* ) *values.size() +1 );
170
171 for ( ;it!=end;++it )
172 {
173 mods[i]= ( LDAPMod* ) malloc ( sizeof ( LDAPMod ) );
174 mods[i]->mod_op=LDAP_MOD_REPLACE;
175 mods[i]->mod_type= ( char* ) malloc (
176 sizeof ( char ) *
177 ( *it ).attr.length() );
178 strcpy ( mods[i]->mod_type, ( *it ).attr.c_str() );
179
180 list<string>::const_iterator sit= ( *it ).value.begin();
181 list<string>::const_iterator send= ( *it ).value.end();
182 int j=0;
183 mods[i]->mod_vals.modv_strvals= ( char** ) malloc (
184 sizeof ( char* ) *
185 ( *it ).value.size() +1 );
186 for ( ;sit!=send;++sit )
187 {
188 mods[i]->mod_vals.modv_strvals[j]=
189 ( char* ) malloc ( sizeof ( char ) *
190 ( *sit ).length() );
191 strcpy ( mods[i]->mod_vals.modv_strvals[j],
192 ( *sit ).c_str() );
193 ++j;
194 }
195 mods[i]->mod_vals.modv_strvals[j]=0l;
196 ++i;
197 }
198 mods[i]=0l;
199
200 int errc= ldap_modify_s ( ld,dn.c_str(),mods );
201 if ( errc != LDAP_SUCCESS )
202 throw LDAPExeption ( "ldap_modify_s",ldap_err2string ( errc ) );
203
204 ldap_mods_free ( mods,1 );
205 }
206
remove(string dn)207 void LDAPSession::remove ( string dn )
208 {
209 int errc= ldap_delete_s ( ld,dn.c_str() );
210 if ( errc != LDAP_SUCCESS )
211 throw LDAPExeption ( "ldap_delete_s",ldap_err2string ( errc ) );
212 }
213
binSearch(string dn,const list<string> & attributes,string searchParam,list<LDAPBinEntry> & result)214 void LDAPSession::binSearch ( string dn,const list<string> &attributes,
215 string searchParam,
216 list<LDAPBinEntry>& result )
217 {
218 char** attr;
219 attr= ( char** ) malloc ( sizeof ( char* ) *attributes.size() +1 );
220 int i=0;
221 list<string>::const_iterator it=attributes.begin();
222 list<string>::const_iterator end=attributes.end();
223 for ( ;it!=end;++it )
224 {
225 attr[i]= ( char* ) malloc ( sizeof ( char ) *
226 ( *it ).length() );
227 strcpy ( attr[i], ( *it ).c_str() );
228 ++i;
229 }
230 attr[i]=0l;
231 LDAPMessage* res;
232 int errc=ldap_search_s ( ld,dn.c_str(),LDAP_SCOPE_SUBTREE,
233 searchParam.c_str(),attr,0,&res );
234 if ( errc != LDAP_SUCCESS )
235 {
236 i=0;
237 it=attributes.begin();
238 for ( ;it!=end;++it )
239 {
240 free ( attr[i] );
241 ++i;
242 }
243 free ( attr );
244 throw LDAPExeption ( "ldap_search_s",ldap_err2string ( errc ) );
245 }
246 LDAPMessage *entry=ldap_first_entry ( ld,res );
247 while ( entry )
248 {
249 LDAPBinEntry binEntry;
250 it=attributes.begin();
251 for ( ;it!=end;++it )
252 {
253 LDAPBinValue val;
254 val.attr= ( *it );
255 berval **atr=ldap_get_values_len ( ld,entry,
256 ( *it ).c_str() );
257 int count=ldap_count_values_len ( atr );
258 for ( i=0;i<count;i++ )
259 {
260 ByteArray arr;
261 arr.load ( atr[i]->bv_val,atr[i]->bv_len );
262 val.value.push_back ( arr );
263 }
264 ldap_value_free_len ( atr );
265 binEntry.push_back ( val );
266 }
267 entry=ldap_next_entry ( ld,entry );
268 result.push_back ( binEntry );
269 }
270 free ( res );
271 i=0;
272 it=attributes.begin();
273 for ( ;it!=end;++it )
274 {
275 free ( attr[i] );
276 ++i;
277 }
278 free ( attr );
279 }
280
stringSearch(string dn,const list<string> & attributes,string searchParam,list<LDAPStringEntry> & result)281 void LDAPSession::stringSearch ( string dn,const list<string> &attributes,
282 string searchParam,
283 list<LDAPStringEntry>& result )
284 {
285 char** attr;
286 attr= ( char** ) malloc ( sizeof ( char* ) *attributes.size() +1 );
287 int i=0;
288 list<string>::const_iterator it=attributes.begin();
289 list<string>::const_iterator end=attributes.end();
290 for ( ;it!=end;++it )
291 {
292 attr[i]= ( char* ) malloc ( sizeof ( char ) *
293 ( *it ).length() +1 );
294 strcpy ( attr[i], ( *it ).c_str() );
295 ++i;
296 }
297 attr[i]=0l;
298 LDAPMessage* res;
299 int errc=ldap_search_s ( ld,dn.c_str(),LDAP_SCOPE_SUBTREE,
300 searchParam.c_str(),attr,0,&res );
301 if ( errc != LDAP_SUCCESS )
302 {
303 i=0;
304 it=attributes.begin();
305 for ( ;it!=end;++it )
306 {
307 free ( attr[i] );
308 ++i;
309 }
310 free ( attr );
311 throw LDAPExeption ( "ldap_search_s",ldap_err2string ( errc ) );
312 }
313 LDAPMessage *entry=ldap_first_entry ( ld,res );
314 while ( entry )
315 {
316 LDAPStringEntry stringEntry;
317 it=attributes.begin();
318 for ( ;it!=end;++it )
319 {
320 LDAPStringValue val;
321 val.attr= ( *it );
322 char **atr=ldap_get_values ( ld,entry,
323 ( *it ).c_str() );
324 int count=ldap_count_values ( atr );
325 for ( i=0;i<count;i++ )
326 {
327 val.value.push_back ( atr[i] );
328 }
329 ldap_value_free ( atr );
330 stringEntry.push_back ( val );
331 }
332 entry=ldap_next_entry ( ld,entry );
333 result.push_back ( stringEntry );
334 }
335 free ( res );
336 i=0;
337 it=attributes.begin();
338 for ( ;it!=end;++it )
339 {
340 free ( attr[i] );
341 ++i;
342 }
343 free ( attr );
344 }
345
getStringAttrValues(const LDAPStringEntry & entry,string attr)346 list<string> LDAPSession::getStringAttrValues ( const LDAPStringEntry& entry,
347 string attr )
348 {
349 list<LDAPStringValue>::const_iterator it=entry.begin();
350 list<LDAPStringValue>::const_iterator end=entry.end();
351 list<string> lst;
352 for ( ;it!=end;++it )
353 {
354 if ( ( *it ).attr==attr )
355 return ( *it ).value;
356 }
357 return lst;
358 }
359
getBinAttrValues(const LDAPBinEntry & entry,string attr)360 list<ByteArray> LDAPSession::getBinAttrValues ( const LDAPBinEntry& entry,
361 string attr )
362 {
363 list<LDAPBinValue>::const_iterator it=entry.begin();
364 list<LDAPBinValue>::const_iterator end=entry.end();
365 list<ByteArray> lst;
366 for ( ;it!=end;++it )
367 {
368 if ( ( *it ).attr==attr )
369 return ( *it ).value;
370 }
371 return lst;
372 }
373
~LDAPSession()374 LDAPSession::~LDAPSession()
375 {
376 ldap_unbind ( ld );
377 }
378 #endif
379