Merge from 3.0. Fix munged dial in pdb_ldap
[samba.git] / source / lib / smbldap.c
1 /* 
2    Unix SMB/CIFS mplementation.
3    LDAP protocol helper functions for SAMBA
4    Copyright (C) Jean François Micouleau        1998
5    Copyright (C) Gerald Carter                  2001-2003
6    Copyright (C) Shahms King                    2001
7    Copyright (C) Andrew Bartlett                2002-2003
8    Copyright (C) Stefan (metze) Metzmacher      2002-2003
9     
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23    
24 */
25
26 #include "includes.h"
27 #include "smbldap.h"
28
29 #ifndef LDAP_OPT_SUCCESS
30 #define LDAP_OPT_SUCCESS 0
31 #endif
32
33 /* Try not to hit the up or down server forever */
34
35 #define SMBLDAP_DONT_PING_TIME 10       /* ping only all 10 seconds */
36 #define SMBLDAP_NUM_RETRIES 8           /* retry only 8 times */
37
38 #define SMBLDAP_IDLE_TIME 150           /* After 2.5 minutes disconnect */
39
40
41 /* attributes used by Samba 2.2 */
42
43 ATTRIB_MAP_ENTRY attrib_map_v22[] = {
44         { LDAP_ATTR_UID,                "uid"           },
45         { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
46         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
47         { LDAP_ATTR_UNIX_HOME,          "homeDirectory" },
48         { LDAP_ATTR_PWD_LAST_SET,       "pwdLastSet"    },
49         { LDAP_ATTR_PWD_CAN_CHANGE,     "pwdCanChange"  },
50         { LDAP_ATTR_PWD_MUST_CHANGE,    "pwdMustChange" },
51         { LDAP_ATTR_LOGON_TIME,         "logonTime"     },
52         { LDAP_ATTR_LOGOFF_TIME,        "logoffTime"    },
53         { LDAP_ATTR_KICKOFF_TIME,       "kickoffTime"   },
54         { LDAP_ATTR_CN,                 "cn"            },
55         { LDAP_ATTR_DISPLAY_NAME,       "displayName"   },
56         { LDAP_ATTR_HOME_PATH,          "smbHome"       },
57         { LDAP_ATTR_HOME_DRIVE,         "homeDrives"    },
58         { LDAP_ATTR_LOGON_SCRIPT,       "scriptPath"    },
59         { LDAP_ATTR_PROFILE_PATH,       "profilePath"   },
60         { LDAP_ATTR_DESC,               "description"   },
61         { LDAP_ATTR_USER_WKS,           "userWorkstations"},
62         { LDAP_ATTR_USER_RID,           "rid"           },
63         { LDAP_ATTR_PRIMARY_GROUP_RID,  "primaryGroupID"},
64         { LDAP_ATTR_LMPW,               "lmPassword"    },
65         { LDAP_ATTR_NTPW,               "ntPassword"    },
66         { LDAP_ATTR_DOMAIN,             "domain"        },
67         { LDAP_ATTR_OBJCLASS,           "objectClass"   },
68         { LDAP_ATTR_ACB_INFO,           "acctFlags"     },
69         { LDAP_ATTR_LIST_END,           NULL            }
70 };
71
72 /* attributes used by Samba 3.0's sambaSamAccount */
73
74 ATTRIB_MAP_ENTRY attrib_map_v30[] = {
75         { LDAP_ATTR_UID,                "uid"                   },
76         { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
77         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
78         { LDAP_ATTR_UNIX_HOME,          "homeDirectory"         },
79         { LDAP_ATTR_PWD_LAST_SET,       "sambaPwdLastSet"       },
80         { LDAP_ATTR_PWD_CAN_CHANGE,     "sambaPwdCanChange"     },
81         { LDAP_ATTR_PWD_MUST_CHANGE,    "sambaPwdMustChange"    },
82         { LDAP_ATTR_LOGON_TIME,         "sambaLogonTime"        },
83         { LDAP_ATTR_LOGOFF_TIME,        "sambaLogoffTime"       },
84         { LDAP_ATTR_KICKOFF_TIME,       "sambaKickoffTime"      },
85         { LDAP_ATTR_CN,                 "cn"                    },
86         { LDAP_ATTR_DISPLAY_NAME,       "displayName"           },
87         { LDAP_ATTR_HOME_DRIVE,         "sambaHomeDrive"        },
88         { LDAP_ATTR_HOME_PATH,          "sambaHomePath"         },
89         { LDAP_ATTR_LOGON_SCRIPT,       "sambaLogonScript"      },
90         { LDAP_ATTR_PROFILE_PATH,       "sambaProfilePath"      },
91         { LDAP_ATTR_DESC,               "description"           },
92         { LDAP_ATTR_USER_WKS,           "sambaUserWorkstations" },
93         { LDAP_ATTR_USER_SID,           LDAP_ATTRIBUTE_SID      },
94         { LDAP_ATTR_PRIMARY_GROUP_SID,  "sambaPrimaryGroupSID"  },
95         { LDAP_ATTR_LMPW,               "sambaLMPassword"       },
96         { LDAP_ATTR_NTPW,               "sambaNTPassword"       },
97         { LDAP_ATTR_DOMAIN,             "sambaDomainName"       },
98         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
99         { LDAP_ATTR_ACB_INFO,           "sambaAcctFlags"        },
100         { LDAP_ATTR_MUNGED_DIAL,        "sambaMungedDial"       },
101         { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
102         { LDAP_ATTR_BAD_PASSWORD_TIME,  "sambaBadPasswordTime"  },
103         { LDAP_ATTR_LIST_END,           NULL                    }
104 };
105
106 /* attributes used for allocating RIDs */
107
108 ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
109         { LDAP_ATTR_DOMAIN,             "sambaDomainName"       },
110         { LDAP_ATTR_NEXT_RID,           "sambaNextRid"          },
111         { LDAP_ATTR_NEXT_USERRID,       "sambaNextUserRid"      },
112         { LDAP_ATTR_NEXT_GROUPRID,      "sambaNextGroupRid"     },
113         { LDAP_ATTR_DOM_SID,            LDAP_ATTRIBUTE_SID      },
114         { LDAP_ATTR_ALGORITHMIC_RID_BASE,"sambaAlgorithmicRidBase"},
115         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
116         { LDAP_ATTR_LIST_END,           NULL                    },
117 };
118
119 /* Samba 3.0 group mapping attributes */
120
121 ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
122         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
123         { LDAP_ATTR_GROUP_SID,          LDAP_ATTRIBUTE_SID      },
124         { LDAP_ATTR_GROUP_TYPE,         "sambaGroupType"        },
125         { LDAP_ATTR_DESC,               "description"           },
126         { LDAP_ATTR_DISPLAY_NAME,       "displayName"           },
127         { LDAP_ATTR_CN,                 "cn"                    },
128         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
129         { LDAP_ATTR_LIST_END,           NULL                    }       
130 };
131
132 ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
133         { LDAP_ATTR_GROUP_SID,          LDAP_ATTRIBUTE_SID      },
134         { LDAP_ATTR_GROUP_TYPE,         "sambaGroupType"        },
135         { LDAP_ATTR_DESC,               "description"           },
136         { LDAP_ATTR_DISPLAY_NAME,       "displayName"           },
137         { LDAP_ATTR_LIST_END,           NULL                    }       
138 };
139
140 /* idmap_ldap sambaUnixIdPool */
141
142 ATTRIB_MAP_ENTRY idpool_attr_list[] = {
143         { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
144         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
145         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
146         { LDAP_ATTR_LIST_END,           NULL                    }       
147 };
148
149 ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
150         { LDAP_ATTR_SID,                LDAP_ATTRIBUTE_SID      },
151         { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
152         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
153         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
154         { LDAP_ATTR_LIST_END,           NULL                    }       
155 };
156
157 /**********************************************************************
158  perform a simple table lookup and return the attribute name 
159  **********************************************************************/
160  
161  const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
162 {
163         int i = 0;
164         
165         while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
166                 if ( table[i].attrib == key )
167                         return table[i].name;
168                 i++;
169         }
170         
171         return NULL;
172 }
173
174
175 /**********************************************************************
176  Return the list of attribute names from a mapping table
177  **********************************************************************/
178
179  char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
180 {
181         char **names;
182         int i = 0;
183         
184         while ( table[i].attrib != LDAP_ATTR_LIST_END )
185                 i++;
186         i++;
187
188         names = (char**)malloc( sizeof(char*)*i );
189         if ( !names ) {
190                 DEBUG(0,("get_attr_list: out of memory\n"));
191                 return NULL;
192         }
193
194         i = 0;
195         while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
196                 names[i] = strdup( table[i].name );
197                 i++;
198         }
199         names[i] = NULL;
200         
201         return names;
202 }
203
204 /*********************************************************************
205  Cleanup 
206  ********************************************************************/
207
208  void free_attr_list( char **list )
209 {
210         int i = 0;
211
212         if ( !list )
213                 return; 
214
215         while ( list[i] ) {
216                 SAFE_FREE( list[i] );
217                 i+=1;
218         }
219
220         SAFE_FREE( list );
221 }
222
223 /*******************************************************************
224  find the ldap password
225 ******************************************************************/
226 static BOOL fetch_ldap_pw(char **dn, char** pw)
227 {
228         char *key = NULL;
229         size_t size;
230         
231         *dn = smb_xstrdup(lp_ldap_admin_dn());
232         
233         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
234                 SAFE_FREE(*dn);
235                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
236         }
237         
238         *pw=secrets_fetch(key, &size);
239         SAFE_FREE(key);
240
241         if (!size) {
242                 /* Upgrade 2.2 style entry */
243                 char *p;
244                 char* old_style_key = strdup(*dn);
245                 char *data;
246                 fstring old_style_pw;
247                 
248                 if (!old_style_key) {
249                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
250                         return False;
251                 }
252
253                 for (p=old_style_key; *p; p++)
254                         if (*p == ',') *p = '/';
255         
256                 data=secrets_fetch(old_style_key, &size);
257                 if (!size && size < sizeof(old_style_pw)) {
258                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
259                         SAFE_FREE(old_style_key);
260                         SAFE_FREE(*dn);
261                         return False;
262                 }
263
264                 size = MIN(size, sizeof(fstring)-1);
265                 strncpy(old_style_pw, data, size);
266                 old_style_pw[size] = 0;
267
268                 SAFE_FREE(data);
269
270                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
271                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
272                         SAFE_FREE(old_style_key);
273                         SAFE_FREE(*dn);
274                         return False;                   
275                 }
276                 if (!secrets_delete(old_style_key)) {
277                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
278                 }
279
280                 SAFE_FREE(old_style_key);
281
282                 *pw = smb_xstrdup(old_style_pw);                
283         }
284         
285         return True;
286 }
287
288 /*******************************************************************
289  Search an attribute and return the first value found.
290 ******************************************************************/
291
292  BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
293                                     const char *attribute, char *value,
294                                     int max_len)
295 {
296         char **values;
297         
298         if ( !attribute )
299                 return False;
300                 
301         value[0] = '\0';
302
303         if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
304                 DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute));
305                 
306                 return False;
307         }
308         
309         if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len) == (size_t)-1) {
310                 DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n", 
311                           attribute, values[0]));
312                 ldap_value_free(values);
313                 return False;
314         }
315         
316         ldap_value_free(values);
317 #ifdef DEBUG_PASSWORDS
318         DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value));
319 #endif  
320         return True;
321 }
322
323  BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry,
324                                   const char *attribute, pstring value)
325 {
326         return smbldap_get_single_attribute(ldap_struct, entry,
327                                             attribute, value, 
328                                             sizeof(pstring));
329 }
330
331 /************************************************************************
332  Routine to manage the LDAPMod structure array
333  manage memory used by the array, by each struct, and values
334  ***********************************************************************/
335
336  void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
337 {
338         LDAPMod **mods;
339         int i;
340         int j;
341
342         mods = *modlist;
343
344         /* sanity checks on the mod values */
345
346         if (attribute == NULL || *attribute == '\0')
347                 return; 
348 #if 0   /* commented out after discussion with abartlet.  Do not reenable.
349            left here so other so re-add similar code   --jerry */
350         if (value == NULL || *value == '\0')
351                 return;
352 #endif
353
354         if (mods == NULL) 
355         {
356                 mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
357                 if (mods == NULL)
358                 {
359                         DEBUG(0, ("make_a_mod: out of memory!\n"));
360                         return;
361                 }
362                 mods[0] = NULL;
363         }
364
365         for (i = 0; mods[i] != NULL; ++i) {
366                 if (mods[i]->mod_op == modop && strequal(mods[i]->mod_type, attribute))
367                         break;
368         }
369
370         if (mods[i] == NULL)
371         {
372                 mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
373                 if (mods == NULL)
374                 {
375                         DEBUG(0, ("make_a_mod: out of memory!\n"));
376                         return;
377                 }
378                 mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
379                 if (mods[i] == NULL)
380                 {
381                         DEBUG(0, ("make_a_mod: out of memory!\n"));
382                         return;
383                 }
384                 mods[i]->mod_op = modop;
385                 mods[i]->mod_values = NULL;
386                 mods[i]->mod_type = strdup(attribute);
387                 mods[i + 1] = NULL;
388         }
389
390         if (value != NULL)
391         {
392                 char *utf8_value = NULL;
393
394                 j = 0;
395                 if (mods[i]->mod_values != NULL) {
396                         for (; mods[i]->mod_values[j] != NULL; j++);
397                 }
398                 mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
399                                                (j + 2) * sizeof (char *));
400                                                
401                 if (mods[i]->mod_values == NULL) {
402                         DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
403                         return;
404                 }
405
406                 if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) {
407                         DEBUG (0, ("make_a_mod: String conversion failure!\n"));
408                         return;
409                 }
410
411                 mods[i]->mod_values[j] = utf8_value;
412
413                 mods[i]->mod_values[j + 1] = NULL;
414         }
415         *modlist = mods;
416 }
417
418 /**********************************************************************
419   Set attribute to newval in LDAP, regardless of what value the
420   attribute had in LDAP before.
421 *********************************************************************/
422
423  void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
424                       LDAPMod ***mods,
425                       const char *attribute, const char *newval)
426 {
427         char oldval[2048]; /* current largest allowed value is mungeddial */
428         BOOL existed;
429
430         if (existing != NULL) {
431                 existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval));
432         } else {
433                 existed = False;
434                 *oldval = '\0';
435         }
436
437         /* all of our string attributes are case insensitive */
438         
439         if (existed && newval && (StrCaseCmp(oldval, newval) == 0)) {
440                 
441                 /* Believe it or not, but LDAP will deny a delete and
442                    an add at the same time if the values are the
443                    same... */
444                 return;
445         }
446
447         if (existed) {
448                 /* There has been no value before, so don't delete it.
449                  * Here's a possible race: We might end up with
450                  * duplicate attributes */
451                 /* By deleting exactly the value we found in the entry this
452                  * should be race-free in the sense that the LDAP-Server will
453                  * deny the complete operation if somebody changed the
454                  * attribute behind our back. */
455                 /* This will also allow modifying single valued attributes 
456                  * in Novell NDS. In NDS you have to first remove attribute and then
457                  * you could add new value */
458                 
459                 smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
460         }
461
462         /* Regardless of the real operation (add or modify)
463            we add the new value here. We rely on deleting
464            the old value, should it exist. */
465
466         if ((newval != NULL) && (strlen(newval) > 0)) {
467                 smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
468         }
469 }
470
471 /**********************************************************************
472  Some varients of the LDAP rebind code do not pass in the third 'arg' 
473  pointer to a void*, so we try and work around it by assuming that the 
474  value of the 'LDAP *' pointer is the same as the one we had passed in
475  **********************************************************************/
476
477 struct smbldap_state_lookup {
478         LDAP *ld;
479         struct smbldap_state *smbldap_state;
480         struct smbldap_state_lookup *prev, *next;
481 };
482
483 static struct smbldap_state_lookup *smbldap_state_lookup_list;
484
485 static struct smbldap_state *smbldap_find_state(LDAP *ld) 
486 {
487         struct smbldap_state_lookup *t;
488
489         for (t = smbldap_state_lookup_list; t; t = t->next) {
490                 if (t->ld == ld) {
491                         return t->smbldap_state;
492                 }
493         }
494         return NULL;
495 }
496
497 static void smbldap_delete_state(struct smbldap_state *smbldap_state) 
498 {
499         struct smbldap_state_lookup *t;
500
501         for (t = smbldap_state_lookup_list; t; t = t->next) {
502                 if (t->smbldap_state == smbldap_state) {
503                         DLIST_REMOVE(smbldap_state_lookup_list, t);
504                         SAFE_FREE(t);
505                         return;
506                 }
507         }
508 }
509
510 static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) 
511 {
512         struct smbldap_state *tmp_ldap_state;
513         struct smbldap_state_lookup *t;
514         struct smbldap_state_lookup *tmp;
515         
516         if ((tmp_ldap_state = smbldap_find_state(ld))) {
517                 SMB_ASSERT(tmp_ldap_state == smbldap_state);
518                 return;
519         }
520
521         t = smb_xmalloc(sizeof(*t));
522         ZERO_STRUCTP(t);
523         
524         DLIST_ADD_END(smbldap_state_lookup_list, t, tmp);
525         t->ld = ld;
526         t->smbldap_state = smbldap_state;
527 }
528
529 /*******************************************************************
530  open a connection to the ldap server.
531 ******************************************************************/
532 static int smbldap_open_connection (struct smbldap_state *ldap_state)
533
534 {
535         int rc = LDAP_SUCCESS;
536         int version;
537         BOOL ldap_v3 = False;
538         LDAP **ldap_struct = &ldap_state->ldap_struct;
539
540 #ifdef HAVE_LDAP_INITIALIZE
541         DEBUG(10, ("smbldap_open_connection: %s\n", ldap_state->uri));
542         
543         if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
544                 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
545                 return rc;
546         }
547 #else 
548
549         /* Parse the string manually */
550
551         {
552                 int port = 0;
553                 fstring protocol;
554                 fstring host;
555                 const char *p = ldap_state->uri; 
556                 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
557                 
558                 /* skip leading "URL:" (if any) */
559                 if ( strnequal( p, "URL:", 4 ) ) {
560                         p += 4;
561                 }
562                 
563                 sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
564                 
565                 if (port == 0) {
566                         if (strequal(protocol, "ldap")) {
567                                 port = LDAP_PORT;
568                         } else if (strequal(protocol, "ldaps")) {
569                                 port = LDAPS_PORT;
570                         } else {
571                                 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
572                         }
573                 }
574                 
575                 if ((*ldap_struct = ldap_init(host, port)) == NULL)     {
576                         DEBUG(0, ("ldap_init failed !\n"));
577                         return LDAP_OPERATIONS_ERROR;
578                 }
579                 
580                 if (strequal(protocol, "ldaps")) {
581 #ifdef LDAP_OPT_X_TLS
582                         int tls = LDAP_OPT_X_TLS_HARD;
583                         if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
584                         {
585                                 DEBUG(0, ("Failed to setup a TLS session\n"));
586                         }
587                         
588                         DEBUG(3,("LDAPS option set...!\n"));
589 #else
590                         DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
591                         return LDAP_OPERATIONS_ERROR;
592 #endif
593                 }
594         }
595 #endif
596
597         /* Store the LDAP pointer in a lookup list */
598
599         smbldap_store_state(*ldap_struct, ldap_state);
600
601         /* Upgrade to LDAPv3 if possible */
602
603         if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
604         {
605                 if (version != LDAP_VERSION3)
606                 {
607                         version = LDAP_VERSION3;
608                         if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
609                                 ldap_v3 = True;
610                         }
611                 } else {
612                         ldap_v3 = True;
613                 }
614         }
615
616         if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
617 #ifdef LDAP_OPT_X_TLS
618                 if (ldap_v3) {
619                         if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
620                         {
621                                 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
622                                          ldap_err2string(rc)));
623                                 return rc;
624                         }
625                         DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
626                 } else {
627                         
628                         DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
629                         return LDAP_OPERATIONS_ERROR;
630                 }
631 #else
632                 DEBUG(0,("smbldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
633                 return LDAP_OPERATIONS_ERROR;
634 #endif
635         }
636
637         DEBUG(2, ("smbldap_open_connection: connection opened\n"));
638         return rc;
639 }
640
641
642 /*******************************************************************
643  a rebind function for authenticated referrals
644  This version takes a void* that we can shove useful stuff in :-)
645 ******************************************************************/
646 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
647 #else
648 static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp, 
649                                    int *methodp, int freeit, void *arg)
650 {
651         struct smbldap_state *ldap_state = arg;
652         
653         /** @TODO Should we be doing something to check what servers we rebind to?
654             Could we get a referral to a machine that we don't want to give our
655             username and password to? */
656         
657         if (freeit) {
658                 SAFE_FREE(*whop);
659                 memset(*credp, '\0', strlen(*credp));
660                 SAFE_FREE(*credp);
661         } else {
662                 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n", 
663                           ldap_state->bind_dn));
664
665                 *whop = strdup(ldap_state->bind_dn);
666                 if (!*whop) {
667                         return LDAP_NO_MEMORY;
668                 }
669                 *credp = strdup(ldap_state->bind_secret);
670                 if (!*credp) {
671                         SAFE_FREE(*whop);
672                         return LDAP_NO_MEMORY;
673                 }
674                 *methodp = LDAP_AUTH_SIMPLE;
675         }
676
677         gettimeofday(&(ldap_state->last_rebind),NULL);
678                 
679         return 0;
680 }
681 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
682
683 /*******************************************************************
684  a rebind function for authenticated referrals
685  This version takes a void* that we can shove useful stuff in :-)
686  and actually does the connection.
687 ******************************************************************/
688 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
689 static int rebindproc_connect_with_state (LDAP *ldap_struct, 
690                                           LDAP_CONST char *url, 
691                                           ber_tag_t request,
692                                           ber_int_t msgid, void *arg)
693 {
694         struct smbldap_state *ldap_state = arg;
695         int rc;
696         DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n", 
697                  ldap_state->bind_dn));
698         
699         /** @TODO Should we be doing something to check what servers we rebind to?
700             Could we get a referral to a machine that we don't want to give our
701             username and password to? */
702
703         rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
704         
705         gettimeofday(&(ldap_state->last_rebind),NULL);
706
707         return rc;
708 }
709 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
710
711 /*******************************************************************
712  Add a rebind function for authenticated referrals
713 ******************************************************************/
714 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
715 #else
716 # if LDAP_SET_REBIND_PROC_ARGS == 2
717 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
718                        int *method, int freeit )
719 {
720         struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
721
722         return rebindproc_with_state(ldap_struct, whop, credp,
723                                      method, freeit, ldap_state);
724         
725 }
726 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
727 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
728
729 /*******************************************************************
730  a rebind function for authenticated referrals
731  this also does the connection, but no void*.
732 ******************************************************************/
733 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
734 # if LDAP_SET_REBIND_PROC_ARGS == 2
735 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
736                                ber_int_t msgid)
737 {
738         struct smbldap_state *ldap_state = smbldap_find_state(ld);
739
740         return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, 
741                                              ldap_state);
742 }
743 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
744 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
745
746 /*******************************************************************
747  connect to the ldap server under system privilege.
748 ******************************************************************/
749 static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
750 {
751         int rc;
752         char *ldap_dn;
753         char *ldap_secret;
754
755         /* get the password */
756         if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
757         {
758                 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
759                 return LDAP_INVALID_CREDENTIALS;
760         }
761
762         ldap_state->bind_dn = ldap_dn;
763         ldap_state->bind_secret = ldap_secret;
764
765         /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite 
766            (OpenLDAP) doesnt' seem to support it */
767            
768         DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
769                   ldap_state->uri, ldap_dn));
770
771 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
772 # if LDAP_SET_REBIND_PROC_ARGS == 2     
773         ldap_set_rebind_proc(ldap_struct, &rebindproc_connect); 
774 # endif
775 # if LDAP_SET_REBIND_PROC_ARGS == 3     
776         ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);  
777 # endif
778 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
779 # if LDAP_SET_REBIND_PROC_ARGS == 2     
780         ldap_set_rebind_proc(ldap_struct, &rebindproc); 
781 # endif
782 # if LDAP_SET_REBIND_PROC_ARGS == 3     
783         ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);  
784 # endif
785 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
786
787         rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
788
789         if (rc != LDAP_SUCCESS) {
790                 char *ld_error = NULL;
791                 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
792                                 &ld_error);
793                 DEBUG(ldap_state->num_failures ? 2 : 0,
794                       ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
795                                ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),
796                                ld_error ? ld_error : "(unknown)"));
797                 SAFE_FREE(ld_error);
798                 ldap_state->num_failures++;
799                 return rc;
800         }
801
802         ldap_state->num_failures = 0;
803
804         DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
805         return rc;
806 }
807
808 /**********************************************************************
809 Connect to LDAP server (called before every ldap operation)
810 *********************************************************************/
811 static int smbldap_open(struct smbldap_state *ldap_state)
812 {
813         int rc;
814         SMB_ASSERT(ldap_state);
815                 
816 #ifndef NO_LDAP_SECURITY
817         if (geteuid() != 0) {
818                 DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));
819                 return  LDAP_INSUFFICIENT_ACCESS;
820         }
821 #endif
822
823         if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
824                 struct sockaddr_un addr;
825                 socklen_t len = sizeof(addr);
826                 int sd;
827                 if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
828                     getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
829                         /* the other end has died. reopen. */
830                         ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
831                         ldap_state->ldap_struct = NULL;
832                         ldap_state->last_ping = (time_t)0;
833                 } else {
834                         ldap_state->last_ping = time(NULL);
835                 } 
836         }
837
838         if (ldap_state->ldap_struct != NULL) {
839                 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
840                 return LDAP_SUCCESS;
841         }
842
843         if ((rc = smbldap_open_connection(ldap_state))) {
844                 return rc;
845         }
846
847         if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
848                 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
849                 ldap_state->ldap_struct = NULL;
850                 return rc;
851         }
852
853
854         ldap_state->last_ping = time(NULL);
855         DEBUG(4,("The LDAP server is succesful connected\n"));
856
857         return LDAP_SUCCESS;
858 }
859
860 /**********************************************************************
861 Disconnect from LDAP server 
862 *********************************************************************/
863 static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
864 {
865         if (!ldap_state)
866                 return NT_STATUS_INVALID_PARAMETER;
867                 
868         if (ldap_state->ldap_struct != NULL) {
869                 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
870                 ldap_state->ldap_struct = NULL;
871         }
872
873         smbldap_delete_state(ldap_state);
874         
875         DEBUG(5,("The connection to the LDAP server was closed\n"));
876         /* maybe free the results here --metze */
877         
878         
879
880         return NT_STATUS_OK;
881 }
882
883 int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
884 {
885         int rc;
886
887         SMB_ASSERT(ldap_state && attempts);
888                 
889         if (*attempts != 0) {
890                 unsigned int sleep_time;
891                 uint8 rand_byte;
892
893                 /* Sleep for a random timeout */
894                 rand_byte = (char)(sys_random());
895
896                 sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2; 
897                 /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
898                    on average.  
899                  */
900                 DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n", 
901                           sleep_time));
902                 smb_msleep(sleep_time);
903         }
904         (*attempts)++;
905
906         if ((rc = smbldap_open(ldap_state))) {
907                 DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
908                 return rc;
909         } 
910         
911         return LDAP_SUCCESS;            
912 }
913
914
915 /*********************************************************************
916  ********************************************************************/
917
918 int smbldap_search(struct smbldap_state *ldap_state, 
919                    const char *base, int scope, const char *filter, 
920                    char *attrs[], int attrsonly, 
921                    LDAPMessage **res)
922 {
923         int             rc = LDAP_SERVER_DOWN;
924         int             attempts = 0;
925         char           *utf8_filter;
926
927         SMB_ASSERT(ldap_state);
928         
929         DEBUG(5,("smbldap_search: base => [%s], filter => [%s], scope => [%d]\n",
930                 base, filter, scope));
931
932         if (ldap_state->last_rebind.tv_sec > 0) {
933                 struct timeval  tval;
934                 int             tdiff = 0;
935                 int             sleep_time = 0;
936
937                 ZERO_STRUCT(tval);
938
939                 gettimeofday(&tval,NULL);
940
941                 tdiff = 1000000 *(tval.tv_sec - ldap_state->last_rebind.tv_sec) + 
942                         (tval.tv_usec - ldap_state->last_rebind.tv_usec);
943
944                 sleep_time = ((1000*lp_ldap_replication_sleep())-tdiff)/1000;
945
946                 if (sleep_time > 0) {
947                         /* we wait for the LDAP replication */
948                         DEBUG(5,("smbldap_search: waiting %d milliseconds for LDAP replication.\n",sleep_time));
949                         smb_msleep(sleep_time);
950                         DEBUG(5,("smbldap_search: go on!\n"));
951                         ZERO_STRUCT(ldap_state->last_rebind);
952                 }
953         }
954
955         if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
956                 return LDAP_NO_MEMORY;
957         }
958
959         while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
960                 
961                 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
962                         continue;
963                 
964                 rc = ldap_search_s(ldap_state->ldap_struct, base, scope, 
965                                    utf8_filter, attrs, attrsonly, res);
966         }
967         
968         if (rc == LDAP_SERVER_DOWN) {
969                 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
970                 smbldap_close(ldap_state);      
971         }
972
973         ldap_state->last_use = time(NULL);
974
975         SAFE_FREE(utf8_filter);
976         return rc;
977 }
978
979 int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
980 {
981         int             rc = LDAP_SERVER_DOWN;
982         int             attempts = 0;
983         char           *utf8_dn;
984
985         SMB_ASSERT(ldap_state);
986
987         DEBUG(5,("smbldap_modify: dn => [%s]\n", dn ));
988
989         if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
990                 return LDAP_NO_MEMORY;
991         }
992
993         while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
994                 
995                 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
996                         continue;
997                 
998                 rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
999         }
1000         
1001         if (rc == LDAP_SERVER_DOWN) {
1002                 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
1003                 smbldap_close(ldap_state);      
1004         }
1005         
1006         ldap_state->last_use = time(NULL);
1007
1008         SAFE_FREE(utf8_dn);
1009         return rc;
1010 }
1011
1012 int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
1013 {
1014         int             rc = LDAP_SERVER_DOWN;
1015         int             attempts = 0;
1016         char           *utf8_dn;
1017         
1018         SMB_ASSERT(ldap_state);
1019
1020         DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
1021
1022         if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
1023                 return LDAP_NO_MEMORY;
1024         }
1025
1026         while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
1027                 
1028                 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
1029                         continue;
1030                 
1031                 rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
1032         }
1033         
1034         if (rc == LDAP_SERVER_DOWN) {
1035                 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
1036                 smbldap_close(ldap_state);      
1037         }
1038                 
1039         ldap_state->last_use = time(NULL);
1040
1041         SAFE_FREE(utf8_dn);
1042         return rc;
1043 }
1044
1045 int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
1046 {
1047         int             rc = LDAP_SERVER_DOWN;
1048         int             attempts = 0;
1049         char           *utf8_dn;
1050         
1051         SMB_ASSERT(ldap_state);
1052
1053         DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
1054
1055         if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
1056                 return LDAP_NO_MEMORY;
1057         }
1058
1059         while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
1060                 
1061                 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
1062                         continue;
1063                 
1064                 rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
1065         }
1066         
1067         if (rc == LDAP_SERVER_DOWN) {
1068                 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
1069                 smbldap_close(ldap_state);      
1070         }
1071                 
1072         ldap_state->last_use = time(NULL);
1073
1074         SAFE_FREE(utf8_dn);
1075         return rc;
1076 }
1077
1078 int smbldap_extended_operation(struct smbldap_state *ldap_state, 
1079                                LDAP_CONST char *reqoid, struct berval *reqdata, 
1080                                LDAPControl **serverctrls, LDAPControl **clientctrls, 
1081                                char **retoidp, struct berval **retdatap)
1082 {
1083         int             rc = LDAP_SERVER_DOWN;
1084         int             attempts = 0;
1085         
1086         if (!ldap_state)
1087                 return (-1);
1088
1089         while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
1090                 
1091                 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
1092                         continue;
1093                 
1094                 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, 
1095                                                serverctrls, clientctrls, retoidp, retdatap);
1096         }
1097         
1098         if (rc == LDAP_SERVER_DOWN) {
1099                 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
1100                 smbldap_close(ldap_state);      
1101         }
1102                 
1103         ldap_state->last_use = time(NULL);
1104
1105         return rc;
1106 }
1107
1108 /*******************************************************************
1109  run the search by name.
1110 ******************************************************************/
1111 int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter, 
1112                            char **search_attr, LDAPMessage ** result)
1113 {
1114         int scope = LDAP_SCOPE_SUBTREE;
1115         int rc;
1116
1117         rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
1118
1119         if (rc != LDAP_SUCCESS) {
1120                 char *ld_error = NULL;
1121                 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1122                                 &ld_error);
1123                 DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n", 
1124                         ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
1125                 SAFE_FREE(ld_error);
1126         }
1127         
1128         return rc;
1129 }
1130
1131 static void smbldap_idle_fn(void **data, time_t *interval, time_t now)
1132 {
1133         struct smbldap_state *state = (struct smbldap_state *)(*data);
1134
1135         if (state->ldap_struct == NULL) {
1136                 DEBUG(10,("ldap connection not connected...\n"));
1137                 return;
1138         }
1139                 
1140         if ((state->last_use+SMBLDAP_IDLE_TIME) > now) {
1141                 DEBUG(10,("ldap connection not idle...\n"));
1142                 return;
1143         }
1144                 
1145         DEBUG(7,("ldap connection idle...closing connection\n"));
1146         smbldap_close(state);
1147 }
1148
1149 /**********************************************************************
1150  Housekeeping
1151  *********************************************************************/
1152
1153 void smbldap_free_struct(struct smbldap_state **ldap_state) 
1154 {
1155         smbldap_close(*ldap_state);
1156         
1157         if ((*ldap_state)->bind_secret) {
1158                 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
1159         }
1160
1161         SAFE_FREE((*ldap_state)->bind_dn);
1162         SAFE_FREE((*ldap_state)->bind_secret);
1163
1164         smb_unregister_idle_event((*ldap_state)->event_id);
1165
1166         *ldap_state = NULL;
1167
1168         /* No need to free any further, as it is talloc()ed */
1169 }
1170
1171
1172 /**********************************************************************
1173  Intitalise the 'general' ldap structures, on which ldap operations may be conducted
1174  *********************************************************************/
1175
1176 NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state) 
1177 {
1178         *smbldap_state = talloc_zero(mem_ctx, sizeof(**smbldap_state));
1179         if (!*smbldap_state) {
1180                 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1181                 return NT_STATUS_NO_MEMORY;
1182         }
1183
1184         if (location) {
1185                 (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
1186         } else {
1187                 (*smbldap_state)->uri = "ldap://localhost";
1188         }
1189
1190         (*smbldap_state)->event_id =
1191                 smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state),
1192                                         SMBLDAP_IDLE_TIME);
1193
1194         if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) {
1195                 DEBUG(0,("Failed to register LDAP idle event!\n"));
1196                 return NT_STATUS_INVALID_HANDLE;
1197         }
1198
1199         return NT_STATUS_OK;
1200 }
1201
1202 /*******************************************************************
1203  Return a copy of the DN for a LDAPMessage. Convert from utf8 to CH_UNIX.
1204 ********************************************************************/
1205
1206 char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry)
1207 {
1208         char *utf8_dn, *unix_dn;
1209
1210         utf8_dn = ldap_get_dn(ld, entry);
1211         if (!utf8_dn) {
1212                 DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
1213                 return NULL;
1214         }
1215         if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) {
1216                 DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 [%s]\n", utf8_dn));
1217                 return NULL;
1218         }
1219         ldap_memfree(utf8_dn);
1220         return unix_dn;
1221 }