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