00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "includes.h"
00027 #include "smbldap.h"
00028
00029 #ifndef LDAP_OPT_SUCCESS
00030 #define LDAP_OPT_SUCCESS 0
00031 #endif
00032
00033
00034
00035 #define SMBLDAP_DONT_PING_TIME 10
00036 #define SMBLDAP_NUM_RETRIES 8
00037
00038 #define SMBLDAP_IDLE_TIME 150
00039
00040
00041
00042
00043 ATTRIB_MAP_ENTRY attrib_map_v22[] = {
00044 { LDAP_ATTR_UID, "uid" },
00045 { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
00046 { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
00047 { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
00048 { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" },
00049 { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" },
00050 { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" },
00051 { LDAP_ATTR_LOGON_TIME, "logonTime" },
00052 { LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
00053 { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
00054 { LDAP_ATTR_CN, "cn" },
00055 { LDAP_ATTR_SN, "sn" },
00056 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
00057 { LDAP_ATTR_HOME_PATH, "smbHome" },
00058 { LDAP_ATTR_HOME_DRIVE, "homeDrive" },
00059 { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" },
00060 { LDAP_ATTR_PROFILE_PATH, "profilePath" },
00061 { LDAP_ATTR_DESC, "description" },
00062 { LDAP_ATTR_USER_WKS, "userWorkstations"},
00063 { LDAP_ATTR_USER_RID, "rid" },
00064 { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"},
00065 { LDAP_ATTR_LMPW, "lmPassword" },
00066 { LDAP_ATTR_NTPW, "ntPassword" },
00067 { LDAP_ATTR_DOMAIN, "domain" },
00068 { LDAP_ATTR_OBJCLASS, "objectClass" },
00069 { LDAP_ATTR_ACB_INFO, "acctFlags" },
00070 { LDAP_ATTR_MOD_TIMESTAMP, "modifyTimestamp" },
00071 { LDAP_ATTR_LIST_END, NULL }
00072 };
00073
00074 ATTRIB_MAP_ENTRY attrib_map_to_delete_v22[] = {
00075 { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" },
00076 { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" },
00077 { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" },
00078 { LDAP_ATTR_LOGON_TIME, "logonTime" },
00079 { LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
00080 { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
00081 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
00082 { LDAP_ATTR_HOME_PATH, "smbHome" },
00083 { LDAP_ATTR_HOME_DRIVE, "homeDrives" },
00084 { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" },
00085 { LDAP_ATTR_PROFILE_PATH, "profilePath" },
00086 { LDAP_ATTR_USER_WKS, "userWorkstations"},
00087 { LDAP_ATTR_USER_RID, "rid" },
00088 { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"},
00089 { LDAP_ATTR_LMPW, "lmPassword" },
00090 { LDAP_ATTR_NTPW, "ntPassword" },
00091 { LDAP_ATTR_DOMAIN, "domain" },
00092 { LDAP_ATTR_ACB_INFO, "acctFlags" },
00093 { LDAP_ATTR_LIST_END, NULL }
00094 };
00095
00096
00097
00098 ATTRIB_MAP_ENTRY attrib_map_v30[] = {
00099 { LDAP_ATTR_UID, "uid" },
00100 { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
00101 { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
00102 { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
00103 { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" },
00104 { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" },
00105 { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" },
00106 { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
00107 { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
00108 { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
00109 { LDAP_ATTR_CN, "cn" },
00110 { LDAP_ATTR_SN, "sn" },
00111 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
00112 { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
00113 { LDAP_ATTR_HOME_PATH, "sambaHomePath" },
00114 { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
00115 { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" },
00116 { LDAP_ATTR_DESC, "description" },
00117 { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" },
00118 { LDAP_ATTR_USER_SID, LDAP_ATTRIBUTE_SID },
00119 { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" },
00120 { LDAP_ATTR_LMPW, "sambaLMPassword" },
00121 { LDAP_ATTR_NTPW, "sambaNTPassword" },
00122 { LDAP_ATTR_DOMAIN, "sambaDomainName" },
00123 { LDAP_ATTR_OBJCLASS, "objectClass" },
00124 { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
00125 { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" },
00126 { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
00127 { LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" },
00128 { LDAP_ATTR_PWD_HISTORY, "sambaPasswordHistory" },
00129 { LDAP_ATTR_MOD_TIMESTAMP, "modifyTimestamp" },
00130 { LDAP_ATTR_LOGON_HOURS, "sambaLogonHours" },
00131 { LDAP_ATTR_LIST_END, NULL }
00132 };
00133
00134 ATTRIB_MAP_ENTRY attrib_map_to_delete_v30[] = {
00135 { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" },
00136 { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" },
00137 { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" },
00138 { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
00139 { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
00140 { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
00141 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
00142 { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
00143 { LDAP_ATTR_HOME_PATH, "sambaHomePath" },
00144 { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
00145 { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" },
00146 { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" },
00147 { LDAP_ATTR_USER_SID, LDAP_ATTRIBUTE_SID },
00148 { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" },
00149 { LDAP_ATTR_LMPW, "sambaLMPassword" },
00150 { LDAP_ATTR_NTPW, "sambaNTPassword" },
00151 { LDAP_ATTR_DOMAIN, "sambaDomainName" },
00152 { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
00153 { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" },
00154 { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
00155 { LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" },
00156 { LDAP_ATTR_PWD_HISTORY, "sambaPasswordHistory" },
00157 { LDAP_ATTR_LOGON_HOURS, "sambaLogonHours" },
00158 { LDAP_ATTR_LIST_END, NULL }
00159 };
00160
00161
00162
00163 ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
00164 { LDAP_ATTR_DOMAIN, "sambaDomainName" },
00165 { LDAP_ATTR_NEXT_RID, "sambaNextRid" },
00166 { LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" },
00167 { LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" },
00168 { LDAP_ATTR_DOM_SID, LDAP_ATTRIBUTE_SID },
00169 { LDAP_ATTR_ALGORITHMIC_RID_BASE,"sambaAlgorithmicRidBase"},
00170 { LDAP_ATTR_OBJCLASS, "objectClass" },
00171 { LDAP_ATTR_LIST_END, NULL },
00172 };
00173
00174
00175
00176 ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
00177 { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
00178 { LDAP_ATTR_GROUP_SID, LDAP_ATTRIBUTE_SID },
00179 { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
00180 { LDAP_ATTR_SID_LIST, "sambaSIDList" },
00181 { LDAP_ATTR_DESC, "description" },
00182 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
00183 { LDAP_ATTR_CN, "cn" },
00184 { LDAP_ATTR_OBJCLASS, "objectClass" },
00185 { LDAP_ATTR_LIST_END, NULL }
00186 };
00187
00188 ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
00189 { LDAP_ATTR_GROUP_SID, LDAP_ATTRIBUTE_SID },
00190 { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
00191 { LDAP_ATTR_DESC, "description" },
00192 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
00193 { LDAP_ATTR_SID_LIST, "sambaSIDList" },
00194 { LDAP_ATTR_LIST_END, NULL }
00195 };
00196
00197
00198
00199 ATTRIB_MAP_ENTRY idpool_attr_list[] = {
00200 { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
00201 { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
00202 { LDAP_ATTR_OBJCLASS, "objectClass" },
00203 { LDAP_ATTR_LIST_END, NULL }
00204 };
00205
00206 ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
00207 { LDAP_ATTR_SID, LDAP_ATTRIBUTE_SID },
00208 { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER},
00209 { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER},
00210 { LDAP_ATTR_OBJCLASS, "objectClass" },
00211 { LDAP_ATTR_LIST_END, NULL }
00212 };
00213
00214
00215
00216
00217
00218 const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
00219 {
00220 int i = 0;
00221
00222 while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
00223 if ( table[i].attrib == key )
00224 return table[i].name;
00225 i++;
00226 }
00227
00228 return NULL;
00229 }
00230
00231
00232
00233
00234
00235
00236 const char** get_attr_list( TALLOC_CTX *mem_ctx, ATTRIB_MAP_ENTRY table[] )
00237 {
00238 const char **names;
00239 int i = 0;
00240
00241 while ( table[i].attrib != LDAP_ATTR_LIST_END )
00242 i++;
00243 i++;
00244
00245 names = TALLOC_ARRAY( mem_ctx, const char*, i );
00246 if ( !names ) {
00247 DEBUG(0,("get_attr_list: out of memory\n"));
00248 return NULL;
00249 }
00250
00251 i = 0;
00252 while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
00253 names[i] = talloc_strdup( names, table[i].name );
00254 i++;
00255 }
00256 names[i] = NULL;
00257
00258 return names;
00259 }
00260
00261
00262
00263
00264
00265 BOOL smbldap_get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
00266 const char *attribute, char *value,
00267 int max_len)
00268 {
00269 char **values;
00270
00271 if ( !attribute )
00272 return False;
00273
00274 value[0] = '\0';
00275
00276 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
00277 DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute));
00278
00279 return False;
00280 }
00281
00282 if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, False) == (size_t)-1) {
00283 DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
00284 attribute, values[0]));
00285 ldap_value_free(values);
00286 return False;
00287 }
00288
00289 ldap_value_free(values);
00290 #ifdef DEBUG_PASSWORDS
00291 DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value));
00292 #endif
00293 return True;
00294 }
00295
00296 BOOL smbldap_get_single_pstring (LDAP * ldap_struct, LDAPMessage * entry,
00297 const char *attribute, pstring value)
00298 {
00299 return smbldap_get_single_attribute(ldap_struct, entry,
00300 attribute, value,
00301 sizeof(pstring));
00302 }
00303
00304 char * smbldap_talloc_single_attribute(LDAP *ldap_struct, LDAPMessage *entry,
00305 const char *attribute,
00306 TALLOC_CTX *mem_ctx)
00307 {
00308 char **values;
00309 char *result;
00310
00311 if (attribute == NULL) {
00312 return NULL;
00313 }
00314
00315 values = ldap_get_values(ldap_struct, entry, attribute);
00316
00317 if (values == NULL) {
00318 DEBUG(10, ("attribute %s does not exist\n", attribute));
00319 return NULL;
00320 }
00321
00322 if (ldap_count_values(values) != 1) {
00323 DEBUG(10, ("attribute %s has %d values, expected only one\n",
00324 attribute, ldap_count_values(values)));
00325 ldap_value_free(values);
00326 return NULL;
00327 }
00328
00329 if (pull_utf8_talloc(mem_ctx, &result, values[0]) == (size_t)-1) {
00330 DEBUG(10, ("pull_utf8_talloc failed\n"));
00331 ldap_value_free(values);
00332 return NULL;
00333 }
00334
00335 ldap_value_free(values);
00336
00337 #ifdef DEBUG_PASSWORDS
00338 DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n",
00339 attribute, result));
00340 #endif
00341 return result;
00342 }
00343
00344 static int ldapmsg_destructor(LDAPMessage **result) {
00345 ldap_msgfree(*result);
00346 return 0;
00347 }
00348
00349 void talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result)
00350 {
00351 LDAPMessage **handle;
00352
00353 if (result == NULL) {
00354 return;
00355 }
00356
00357 handle = TALLOC_P(mem_ctx, LDAPMessage *);
00358 SMB_ASSERT(handle != NULL);
00359
00360 *handle = result;
00361 talloc_set_destructor(handle, ldapmsg_destructor);
00362 }
00363
00364 static int ldapmod_destructor(LDAPMod ***mod) {
00365 ldap_mods_free(*mod, True);
00366 return 0;
00367 }
00368
00369 void talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod)
00370 {
00371 LDAPMod ***handle;
00372
00373 if (mod == NULL) {
00374 return;
00375 }
00376
00377 handle = TALLOC_P(mem_ctx, LDAPMod **);
00378 SMB_ASSERT(handle != NULL);
00379
00380 *handle = mod;
00381 talloc_set_destructor(handle, ldapmod_destructor);
00382 }
00383
00384
00385
00386
00387
00388
00389 void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
00390 {
00391 LDAPMod **mods;
00392 int i;
00393 int j;
00394
00395 mods = *modlist;
00396
00397
00398
00399 if (attribute == NULL || *attribute == '\0') {
00400 return;
00401 }
00402
00403 #if 0
00404
00405 if (value == NULL || *value == '\0')
00406 return;
00407 #endif
00408
00409 if (mods == NULL) {
00410 mods = SMB_MALLOC_P(LDAPMod *);
00411 if (mods == NULL) {
00412 smb_panic("smbldap_set_mod: out of memory!\n");
00413
00414 abort();
00415 }
00416 mods[0] = NULL;
00417 }
00418
00419 for (i = 0; mods[i] != NULL; ++i) {
00420 if (mods[i]->mod_op == modop && strequal(mods[i]->mod_type, attribute))
00421 break;
00422 }
00423
00424 if (mods[i] == NULL) {
00425 mods = SMB_REALLOC_ARRAY (mods, LDAPMod *, i + 2);
00426 if (mods == NULL) {
00427 smb_panic("smbldap_set_mod: out of memory!\n");
00428
00429 abort();
00430 }
00431 mods[i] = SMB_MALLOC_P(LDAPMod);
00432 if (mods[i] == NULL) {
00433 smb_panic("smbldap_set_mod: out of memory!\n");
00434
00435 abort();
00436 }
00437 mods[i]->mod_op = modop;
00438 mods[i]->mod_values = NULL;
00439 mods[i]->mod_type = SMB_STRDUP(attribute);
00440 mods[i + 1] = NULL;
00441 }
00442
00443 if (value != NULL) {
00444 char *utf8_value = NULL;
00445
00446 j = 0;
00447 if (mods[i]->mod_values != NULL) {
00448 for (; mods[i]->mod_values[j] != NULL; j++);
00449 }
00450 mods[i]->mod_values = SMB_REALLOC_ARRAY(mods[i]->mod_values, char *, j + 2);
00451
00452 if (mods[i]->mod_values == NULL) {
00453 smb_panic("smbldap_set_mod: out of memory!\n");
00454
00455 abort();
00456 }
00457
00458 if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) {
00459 smb_panic("smbldap_set_mod: String conversion failure!\n");
00460
00461 abort();
00462 }
00463
00464 mods[i]->mod_values[j] = utf8_value;
00465
00466 mods[i]->mod_values[j + 1] = NULL;
00467 }
00468 *modlist = mods;
00469 }
00470
00471
00472
00473
00474
00475
00476 void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
00477 LDAPMod ***mods,
00478 const char *attribute, const char *newval)
00479 {
00480 char oldval[2048];
00481 BOOL existed;
00482
00483 if (attribute == NULL) {
00484
00485
00486 return;
00487 }
00488
00489 if (existing != NULL) {
00490 existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval));
00491 } else {
00492 existed = False;
00493 *oldval = '\0';
00494 }
00495
00496
00497
00498 if (existed && newval && (StrCaseCmp(oldval, newval) == 0)) {
00499
00500
00501
00502
00503 DEBUG(10,("smbldap_make_mod: attribute |%s| not changed.\n", attribute));
00504 return;
00505 }
00506
00507 if (existed) {
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute, oldval));
00520 smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
00521 }
00522
00523
00524
00525
00526
00527 if ((newval != NULL) && (strlen(newval) > 0)) {
00528 DEBUG(10,("smbldap_make_mod: adding attribute |%s| value |%s|\n", attribute, newval));
00529 smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
00530 }
00531 }
00532
00533
00534
00535
00536
00537
00538
00539 struct smbldap_state_lookup {
00540 LDAP *ld;
00541 struct smbldap_state *smbldap_state;
00542 struct smbldap_state_lookup *prev, *next;
00543 };
00544
00545 static struct smbldap_state_lookup *smbldap_state_lookup_list;
00546
00547 static struct smbldap_state *smbldap_find_state(LDAP *ld)
00548 {
00549 struct smbldap_state_lookup *t;
00550
00551 for (t = smbldap_state_lookup_list; t; t = t->next) {
00552 if (t->ld == ld) {
00553 return t->smbldap_state;
00554 }
00555 }
00556 return NULL;
00557 }
00558
00559 static void smbldap_delete_state(struct smbldap_state *smbldap_state)
00560 {
00561 struct smbldap_state_lookup *t;
00562
00563 for (t = smbldap_state_lookup_list; t; t = t->next) {
00564 if (t->smbldap_state == smbldap_state) {
00565 DLIST_REMOVE(smbldap_state_lookup_list, t);
00566 SAFE_FREE(t);
00567 return;
00568 }
00569 }
00570 }
00571
00572 static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
00573 {
00574 struct smbldap_state *tmp_ldap_state;
00575 struct smbldap_state_lookup *t;
00576
00577 if ((tmp_ldap_state = smbldap_find_state(ld))) {
00578 SMB_ASSERT(tmp_ldap_state == smbldap_state);
00579 return;
00580 }
00581
00582 t = SMB_XMALLOC_P(struct smbldap_state_lookup);
00583 ZERO_STRUCTP(t);
00584
00585 DLIST_ADD_END(smbldap_state_lookup_list, t, struct smbldap_state_lookup *);
00586 t->ld = ld;
00587 t->smbldap_state = smbldap_state;
00588 }
00589
00590
00591
00592
00593
00594 int smb_ldap_start_tls(LDAP *ldap_struct, int version)
00595 {
00596 int rc;
00597
00598 if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
00599 return LDAP_SUCCESS;
00600 }
00601
00602 #ifdef LDAP_OPT_X_TLS
00603 if (version != LDAP_VERSION3) {
00604 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
00605 return LDAP_OPERATIONS_ERROR;
00606 }
00607
00608 if ((rc = ldap_start_tls_s (ldap_struct, NULL, NULL)) != LDAP_SUCCESS) {
00609 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
00610 ldap_err2string(rc)));
00611 return rc;
00612 }
00613
00614 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
00615 return LDAP_SUCCESS;
00616 #else
00617 DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));
00618 return LDAP_OPERATIONS_ERROR;
00619 #endif
00620 }
00621
00622
00623
00624
00625
00626 int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
00627 {
00628 int rc;
00629
00630 DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri));
00631
00632 #ifdef HAVE_LDAP_INITIALIZE
00633
00634 rc = ldap_initialize(ldap_struct, uri);
00635 if (rc) {
00636 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
00637 }
00638
00639 return rc;
00640 #else
00641
00642
00643
00644 {
00645 int port = 0;
00646 fstring protocol;
00647 fstring host;
00648 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
00649
00650
00651
00652 if ( strnequal( uri, "URL:", 4 ) ) {
00653 uri += 4;
00654 }
00655
00656 sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
00657
00658 if (port == 0) {
00659 if (strequal(protocol, "ldap")) {
00660 port = LDAP_PORT;
00661 } else if (strequal(protocol, "ldaps")) {
00662 port = LDAPS_PORT;
00663 } else {
00664 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
00665 }
00666 }
00667
00668 if ((*ldap_struct = ldap_init(host, port)) == NULL) {
00669 DEBUG(0, ("ldap_init failed !\n"));
00670 return LDAP_OPERATIONS_ERROR;
00671 }
00672
00673 if (strequal(protocol, "ldaps")) {
00674 #ifdef LDAP_OPT_X_TLS
00675 int tls = LDAP_OPT_X_TLS_HARD;
00676 if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
00677 {
00678 DEBUG(0, ("Failed to setup a TLS session\n"));
00679 }
00680
00681 DEBUG(3,("LDAPS option set...!\n"));
00682 #else
00683 DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
00684 return LDAP_OPERATIONS_ERROR;
00685 #endif
00686 }
00687
00688 }
00689 #endif
00690 return LDAP_SUCCESS;
00691 }
00692
00693
00694
00695
00696
00697
00698 int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version)
00699 {
00700 int version;
00701 int rc;
00702
00703
00704 *new_version = LDAP_VERSION2;
00705
00706 rc = ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
00707 if (rc) {
00708 return rc;
00709 }
00710
00711 if (version == LDAP_VERSION3) {
00712 *new_version = LDAP_VERSION3;
00713 return LDAP_SUCCESS;
00714 }
00715
00716
00717 version = LDAP_VERSION3;
00718 rc = ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
00719 if (rc) {
00720 return rc;
00721 }
00722
00723 *new_version = LDAP_VERSION3;
00724 return LDAP_SUCCESS;
00725 }
00726
00727
00728
00729
00730
00731 int smb_ldap_setup_full_conn(LDAP **ldap_struct, const char *uri)
00732 {
00733 int rc, version;
00734
00735 rc = smb_ldap_setup_conn(ldap_struct, uri);
00736 if (rc) {
00737 return rc;
00738 }
00739
00740 rc = smb_ldap_upgrade_conn(*ldap_struct, &version);
00741 if (rc) {
00742 return rc;
00743 }
00744
00745 rc = smb_ldap_start_tls(*ldap_struct, version);
00746 if (rc) {
00747 return rc;
00748 }
00749
00750 return LDAP_SUCCESS;
00751 }
00752
00753
00754
00755
00756 static int smbldap_open_connection (struct smbldap_state *ldap_state)
00757
00758 {
00759 int rc = LDAP_SUCCESS;
00760 int version;
00761 LDAP **ldap_struct = &ldap_state->ldap_struct;
00762
00763 rc = smb_ldap_setup_conn(ldap_struct, ldap_state->uri);
00764 if (rc) {
00765 return rc;
00766 }
00767
00768
00769
00770 smbldap_store_state(*ldap_struct, ldap_state);
00771
00772
00773
00774 rc = smb_ldap_upgrade_conn(*ldap_struct, &version);
00775 if (rc) {
00776 return rc;
00777 }
00778
00779
00780
00781 rc = smb_ldap_start_tls(*ldap_struct, version);
00782 if (rc) {
00783 return rc;
00784 }
00785
00786 DEBUG(2, ("smbldap_open_connection: connection opened\n"));
00787 return rc;
00788 }
00789
00790
00791
00792
00793
00794 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
00795 #else
00796 static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
00797 int *methodp, int freeit, void *arg)
00798 {
00799 struct smbldap_state *ldap_state = arg;
00800
00801
00802
00803
00804
00805 if (freeit) {
00806 SAFE_FREE(*whop);
00807 if (*credp) {
00808 memset(*credp, '\0', strlen(*credp));
00809 }
00810 SAFE_FREE(*credp);
00811 } else {
00812 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
00813 ldap_state->bind_dn?ldap_state->bind_dn:"[Anonymous bind]"));
00814
00815 if (ldap_state->anonymous) {
00816 *whop = NULL;
00817 *credp = NULL;
00818 } else {
00819 *whop = SMB_STRDUP(ldap_state->bind_dn);
00820 if (!*whop) {
00821 return LDAP_NO_MEMORY;
00822 }
00823 *credp = SMB_STRDUP(ldap_state->bind_secret);
00824 if (!*credp) {
00825 SAFE_FREE(*whop);
00826 return LDAP_NO_MEMORY;
00827 }
00828 }
00829 *methodp = LDAP_AUTH_SIMPLE;
00830 }
00831
00832 GetTimeOfDay(&ldap_state->last_rebind);
00833
00834 return 0;
00835 }
00836 #endif
00837
00838
00839
00840
00841
00842
00843 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
00844 static int rebindproc_connect_with_state (LDAP *ldap_struct,
00845 LDAP_CONST char *url,
00846 ber_tag_t request,
00847 ber_int_t msgid, void *arg)
00848 {
00849 struct smbldap_state *ldap_state =
00850 (struct smbldap_state *)arg;
00851 int rc;
00852 int version;
00853
00854 DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n",
00855 url, ldap_state->bind_dn?ldap_state->bind_dn:"[Anonymous bind]"));
00856
00857
00858
00859
00860
00861 smb_ldap_upgrade_conn(ldap_struct, &version);
00862 smb_ldap_start_tls(ldap_struct, version);
00863
00864
00865
00866
00867
00868 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
00869
00870
00871
00872
00873
00874 switch (request) {
00875
00876 case LDAP_REQ_MODIFY:
00877 case LDAP_REQ_ADD:
00878 case LDAP_REQ_DELETE:
00879 case LDAP_REQ_MODDN:
00880 case LDAP_REQ_EXTENDED:
00881 DEBUG(10,("rebindproc_connect_with_state: "
00882 "setting last_rebind timestamp "
00883 "(req: 0x%02x)\n", (unsigned int)request));
00884 GetTimeOfDay(&ldap_state->last_rebind);
00885 break;
00886 default:
00887 ZERO_STRUCT(ldap_state->last_rebind);
00888 break;
00889 }
00890
00891 return rc;
00892 }
00893 #endif
00894
00895
00896
00897
00898 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
00899 #else
00900 # if LDAP_SET_REBIND_PROC_ARGS == 2
00901 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
00902 int *method, int freeit )
00903 {
00904 struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
00905
00906 return rebindproc_with_state(ldap_struct, whop, credp,
00907 method, freeit, ldap_state);
00908
00909 }
00910 # endif
00911 #endif
00912
00913
00914
00915
00916
00917 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
00918 # if LDAP_SET_REBIND_PROC_ARGS == 2
00919 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
00920 ber_int_t msgid)
00921 {
00922 struct smbldap_state *ldap_state = smbldap_find_state(ld);
00923
00924 return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
00925 ldap_state);
00926 }
00927 # endif
00928 #endif
00929
00930
00931
00932
00933 static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
00934 {
00935 int rc;
00936 int version;
00937
00938 if (!ldap_state->anonymous && !ldap_state->bind_dn) {
00939
00940
00941 if (!fetch_ldap_pw(&ldap_state->bind_dn, &ldap_state->bind_secret)) {
00942 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
00943 return LDAP_INVALID_CREDENTIALS;
00944 }
00945 }
00946
00947
00948
00949
00950 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
00951 ldap_state->uri, ldap_state->bind_dn));
00952
00953 #ifdef HAVE_LDAP_SET_REBIND_PROC
00954 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
00955 # if LDAP_SET_REBIND_PROC_ARGS == 2
00956 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
00957 # endif
00958 # if LDAP_SET_REBIND_PROC_ARGS == 3
00959 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
00960 # endif
00961 #else
00962 # if LDAP_SET_REBIND_PROC_ARGS == 2
00963 ldap_set_rebind_proc(ldap_struct, &rebindproc);
00964 # endif
00965 # if LDAP_SET_REBIND_PROC_ARGS == 3
00966 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
00967 # endif
00968 #endif
00969 #endif
00970
00971 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
00972
00973 if (rc != LDAP_SUCCESS) {
00974 char *ld_error = NULL;
00975 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
00976 &ld_error);
00977 DEBUG(ldap_state->num_failures ? 2 : 0,
00978 ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
00979 ldap_state->uri,
00980 ldap_state->bind_dn ? ldap_state->bind_dn : "[Anonymous bind]",
00981 ldap_err2string(rc),
00982 ld_error ? ld_error : "(unknown)"));
00983 SAFE_FREE(ld_error);
00984 ldap_state->num_failures++;
00985 return rc;
00986 }
00987
00988 ldap_state->num_failures = 0;
00989 ldap_state->paged_results = False;
00990
00991 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
00992
00993 if (smbldap_has_control(ldap_state->ldap_struct, ADS_PAGE_CTL_OID) && version == 3) {
00994 ldap_state->paged_results = True;
00995 }
00996
00997 DEBUG(3, ("ldap_connect_system: successful connection to the LDAP server\n"));
00998 DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n",
00999 ldap_state->paged_results ? "does" : "does not"));
01000 return rc;
01001 }
01002
01003
01004
01005
01006 static int smbldap_open(struct smbldap_state *ldap_state)
01007 {
01008 int rc, opt_rc;
01009 BOOL reopen = False;
01010 SMB_ASSERT(ldap_state);
01011
01012 #ifndef NO_LDAP_SECURITY
01013 if (geteuid() != 0) {
01014 DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));
01015 return LDAP_INSUFFICIENT_ACCESS;
01016 }
01017 #endif
01018
01019 if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
01020
01021 #ifdef HAVE_UNIXSOCKET
01022 struct sockaddr_un addr;
01023 #else
01024 struct sockaddr addr;
01025 #endif
01026 socklen_t len = sizeof(addr);
01027 int sd;
01028
01029 opt_rc = ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd);
01030 if (opt_rc == 0 && (getpeername(sd, (struct sockaddr *) &addr, &len)) < 0 )
01031 reopen = True;
01032
01033 #ifdef HAVE_UNIXSOCKET
01034 if (opt_rc == 0 && addr.sun_family == AF_UNIX)
01035 reopen = True;
01036 #endif
01037 if (reopen) {
01038
01039 ldap_unbind(ldap_state->ldap_struct);
01040 ldap_state->ldap_struct = NULL;
01041 ldap_state->last_ping = (time_t)0;
01042 } else {
01043 ldap_state->last_ping = time(NULL);
01044 }
01045 }
01046
01047 if (ldap_state->ldap_struct != NULL) {
01048 DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));
01049 return LDAP_SUCCESS;
01050 }
01051
01052 if ((rc = smbldap_open_connection(ldap_state))) {
01053 return rc;
01054 }
01055
01056 if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
01057 ldap_unbind(ldap_state->ldap_struct);
01058 ldap_state->ldap_struct = NULL;
01059 return rc;
01060 }
01061
01062
01063 ldap_state->last_ping = time(NULL);
01064 ldap_state->pid = sys_getpid();
01065 DEBUG(4,("The LDAP server is successfully connected\n"));
01066
01067 return LDAP_SUCCESS;
01068 }
01069
01070
01071
01072
01073 static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
01074 {
01075 if (!ldap_state)
01076 return NT_STATUS_INVALID_PARAMETER;
01077
01078 if (ldap_state->ldap_struct != NULL) {
01079 ldap_unbind(ldap_state->ldap_struct);
01080 ldap_state->ldap_struct = NULL;
01081 }
01082
01083 smbldap_delete_state(ldap_state);
01084
01085 DEBUG(5,("The connection to the LDAP server was closed\n"));
01086
01087
01088 return NT_STATUS_OK;
01089 }
01090
01091 static BOOL got_alarm;
01092
01093 static void (*old_handler)(int);
01094
01095 static void gotalarm_sig(int dummy)
01096 {
01097 got_alarm = True;
01098 }
01099
01100 static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
01101 int *attempts, time_t endtime)
01102 {
01103 time_t now = time(NULL);
01104 int open_rc = LDAP_SERVER_DOWN;
01105
01106 if (*rc != LDAP_SERVER_DOWN)
01107 goto no_next;
01108
01109 if (now >= endtime) {
01110 smbldap_close(ldap_state);
01111 *rc = LDAP_TIMEOUT;
01112 goto no_next;
01113 }
01114
01115 if (*attempts == 0) {
01116 got_alarm = False;
01117 old_handler = CatchSignal(SIGALRM, gotalarm_sig);
01118 alarm(endtime - now);
01119
01120 if (ldap_state->pid != sys_getpid())
01121 smbldap_close(ldap_state);
01122 }
01123
01124 while (1) {
01125
01126 if (*attempts != 0)
01127 smb_msleep(1000);
01128
01129 *attempts += 1;
01130
01131 open_rc = smbldap_open(ldap_state);
01132
01133 if (open_rc == LDAP_SUCCESS) {
01134 ldap_state->last_use = now;
01135 return True;
01136 }
01137
01138 if (open_rc == LDAP_INSUFFICIENT_ACCESS) {
01139
01140
01141
01142 *rc = open_rc;
01143 break;
01144 }
01145
01146 if (got_alarm) {
01147 *rc = LDAP_TIMEOUT;
01148 break;
01149 }
01150
01151 if (open_rc != LDAP_SUCCESS) {
01152 DEBUG(1, ("Connection to LDAP server failed for the "
01153 "%d try!\n", *attempts));
01154 }
01155 }
01156
01157 no_next:
01158 CatchSignal(SIGALRM, old_handler);
01159 alarm(0);
01160 ldap_state->last_use = now;
01161 return False;
01162 }
01163
01164
01165
01166
01167 static int smbldap_search_ext(struct smbldap_state *ldap_state,
01168 const char *base, int scope, const char *filter,
01169 const char *attrs[], int attrsonly,
01170 LDAPControl **sctrls, LDAPControl **cctrls,
01171 int sizelimit, LDAPMessage **res)
01172 {
01173 int rc = LDAP_SERVER_DOWN;
01174 int attempts = 0;
01175 char *utf8_filter;
01176 time_t endtime = time(NULL)+lp_ldap_timeout();
01177 struct timeval timeout;
01178
01179 SMB_ASSERT(ldap_state);
01180
01181 DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
01182 "scope => [%d]\n", base, filter, scope));
01183
01184 if (ldap_state->last_rebind.tv_sec > 0) {
01185 struct timeval tval;
01186 SMB_BIG_INT tdiff = 0;
01187 int sleep_time = 0;
01188
01189 ZERO_STRUCT(tval);
01190 GetTimeOfDay(&tval);
01191
01192 tdiff = usec_time_diff(&tval, &ldap_state->last_rebind);
01193 tdiff /= 1000;
01194
01195 sleep_time = lp_ldap_replication_sleep()-(int)tdiff;
01196 sleep_time = MIN(sleep_time, MAX_LDAP_REPLICATION_SLEEP_TIME);
01197
01198 if (sleep_time > 0) {
01199
01200 DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
01201 "for LDAP replication.\n",sleep_time));
01202 smb_msleep(sleep_time);
01203 DEBUG(5,("smbldap_search_ext: go on!\n"));
01204 }
01205 ZERO_STRUCT(ldap_state->last_rebind);
01206 }
01207
01208 if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
01209 return LDAP_NO_MEMORY;
01210 }
01211
01212
01213 timeout.tv_sec = lp_ldap_timeout();
01214 timeout.tv_usec = 0;
01215
01216
01217
01218
01219
01220
01221
01222
01223 got_alarm = 0;
01224 CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
01225 alarm(lp_ldap_timeout());
01226
01227
01228 while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
01229 rc = ldap_search_ext_s(ldap_state->ldap_struct, base, scope,
01230 utf8_filter,
01231 CONST_DISCARD(char **, attrs),
01232 attrsonly, sctrls, cctrls, &timeout,
01233 sizelimit, res);
01234 if (rc != LDAP_SUCCESS) {
01235 char *ld_error = NULL;
01236 int ld_errno;
01237
01238 ldap_get_option(ldap_state->ldap_struct,
01239 LDAP_OPT_ERROR_NUMBER, &ld_errno);
01240
01241 ldap_get_option(ldap_state->ldap_struct,
01242 LDAP_OPT_ERROR_STRING, &ld_error);
01243 DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
01244 "(%s)\n", base, ld_errno,
01245 ldap_err2string(rc),
01246 ld_error ? ld_error : "unknown"));
01247 SAFE_FREE(ld_error);
01248
01249 if (ld_errno == LDAP_SERVER_DOWN) {
01250 ldap_unbind(ldap_state->ldap_struct);
01251 ldap_state->ldap_struct = NULL;
01252 }
01253 }
01254 }
01255
01256 SAFE_FREE(utf8_filter);
01257
01258
01259 CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
01260 alarm(0);
01261
01262 if (got_alarm != 0)
01263 return LDAP_TIMELIMIT_EXCEEDED;
01264
01265 return rc;
01266 }
01267
01268 int smbldap_search(struct smbldap_state *ldap_state,
01269 const char *base, int scope, const char *filter,
01270 const char *attrs[], int attrsonly,
01271 LDAPMessage **res)
01272 {
01273 return smbldap_search_ext(ldap_state, base, scope, filter, attrs,
01274 attrsonly, NULL, NULL, LDAP_NO_LIMIT, res);
01275 }
01276
01277 int smbldap_search_paged(struct smbldap_state *ldap_state,
01278 const char *base, int scope, const char *filter,
01279 const char **attrs, int attrsonly, int pagesize,
01280 LDAPMessage **res, void **cookie)
01281 {
01282 LDAPControl pr;
01283 LDAPControl **rcontrols;
01284 LDAPControl *controls[2] = { NULL, NULL};
01285 BerElement *cookie_be = NULL;
01286 struct berval *cookie_bv = NULL;
01287 int tmp = 0, i, rc;
01288 BOOL critical = True;
01289
01290 *res = NULL;
01291
01292 DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
01293 "scope => [%d], pagesize => [%d]\n",
01294 base, filter, scope, pagesize));
01295
01296 cookie_be = ber_alloc_t(LBER_USE_DER);
01297 if (cookie_be == NULL) {
01298 DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
01299 "NULL\n"));
01300 return LDAP_NO_MEMORY;
01301 }
01302
01303
01304 if (*cookie != NULL) {
01305 ber_printf(cookie_be, "{iO}", (ber_int_t) pagesize, *cookie);
01306 ber_bvfree((struct berval *)*cookie);
01307 *cookie = NULL;
01308 } else {
01309 ber_printf(cookie_be, "{io}", (ber_int_t) pagesize, "", 0);
01310 }
01311 ber_flatten(cookie_be, &cookie_bv);
01312
01313 pr.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
01314 pr.ldctl_iscritical = (char) critical;
01315 pr.ldctl_value.bv_len = cookie_bv->bv_len;
01316 pr.ldctl_value.bv_val = cookie_bv->bv_val;
01317
01318 controls[0] = ≺
01319 controls[1] = NULL;
01320
01321 rc = smbldap_search_ext(ldap_state, base, scope, filter, attrs,
01322 0, controls, NULL, LDAP_NO_LIMIT, res);
01323
01324 ber_free(cookie_be, 1);
01325 ber_bvfree(cookie_bv);
01326
01327 if (rc != 0) {
01328 DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
01329 "failed with [%s]\n", filter, ldap_err2string(rc)));
01330 goto done;
01331 }
01332
01333 DEBUG(3,("smbldap_search_paged: search was successfull\n"));
01334
01335 rc = ldap_parse_result(ldap_state->ldap_struct, *res, NULL, NULL,
01336 NULL, NULL, &rcontrols, 0);
01337 if (rc != 0) {
01338 DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
01339 "with [%s]\n", ldap_err2string(rc)));
01340 goto done;
01341 }
01342
01343 if (rcontrols == NULL)
01344 goto done;
01345
01346 for (i=0; rcontrols[i]; i++) {
01347
01348 if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) != 0)
01349 continue;
01350
01351 cookie_be = ber_init(&rcontrols[i]->ldctl_value);
01352 ber_scanf(cookie_be,"{iO}", &tmp, &cookie_bv);
01353
01354
01355 if (cookie_bv->bv_len)
01356 *cookie=ber_bvdup(cookie_bv);
01357 else
01358 *cookie=NULL;
01359 ber_bvfree(cookie_bv);
01360 ber_free(cookie_be, 1);
01361 break;
01362 }
01363 ldap_controls_free(rcontrols);
01364 done:
01365 return rc;
01366 }
01367
01368 int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
01369 {
01370 int rc = LDAP_SERVER_DOWN;
01371 int attempts = 0;
01372 char *utf8_dn;
01373 time_t endtime = time(NULL)+lp_ldap_timeout();
01374
01375 SMB_ASSERT(ldap_state);
01376
01377 DEBUG(5,("smbldap_modify: dn => [%s]\n", dn ));
01378
01379 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
01380 return LDAP_NO_MEMORY;
01381 }
01382
01383 while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
01384 rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
01385 if (rc != LDAP_SUCCESS) {
01386 char *ld_error = NULL;
01387 int ld_errno;
01388
01389 ldap_get_option(ldap_state->ldap_struct,
01390 LDAP_OPT_ERROR_NUMBER, &ld_errno);
01391
01392 ldap_get_option(ldap_state->ldap_struct,
01393 LDAP_OPT_ERROR_STRING, &ld_error);
01394 DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
01395 "(%s)\n", dn, ld_errno,
01396 ldap_err2string(rc),
01397 ld_error ? ld_error : "unknown"));
01398 SAFE_FREE(ld_error);
01399
01400 if (ld_errno == LDAP_SERVER_DOWN) {
01401 ldap_unbind(ldap_state->ldap_struct);
01402 ldap_state->ldap_struct = NULL;
01403 }
01404 }
01405 }
01406
01407 SAFE_FREE(utf8_dn);
01408 return rc;
01409 }
01410
01411 int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
01412 {
01413 int rc = LDAP_SERVER_DOWN;
01414 int attempts = 0;
01415 char *utf8_dn;
01416 time_t endtime = time(NULL)+lp_ldap_timeout();
01417
01418 SMB_ASSERT(ldap_state);
01419
01420 DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
01421
01422 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
01423 return LDAP_NO_MEMORY;
01424 }
01425
01426 while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
01427 rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
01428 if (rc != LDAP_SUCCESS) {
01429 char *ld_error = NULL;
01430 int ld_errno;
01431
01432 ldap_get_option(ldap_state->ldap_struct,
01433 LDAP_OPT_ERROR_NUMBER, &ld_errno);
01434
01435 ldap_get_option(ldap_state->ldap_struct,
01436 LDAP_OPT_ERROR_STRING, &ld_error);
01437 DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
01438 "(%s)\n", dn, ld_errno,
01439 ldap_err2string(rc),
01440 ld_error ? ld_error : "unknown"));
01441 SAFE_FREE(ld_error);
01442
01443 if (ld_errno == LDAP_SERVER_DOWN) {
01444 ldap_unbind(ldap_state->ldap_struct);
01445 ldap_state->ldap_struct = NULL;
01446 }
01447 }
01448 }
01449
01450 SAFE_FREE(utf8_dn);
01451 return rc;
01452 }
01453
01454 int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
01455 {
01456 int rc = LDAP_SERVER_DOWN;
01457 int attempts = 0;
01458 char *utf8_dn;
01459 time_t endtime = time(NULL)+lp_ldap_timeout();
01460
01461 SMB_ASSERT(ldap_state);
01462
01463 DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
01464
01465 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
01466 return LDAP_NO_MEMORY;
01467 }
01468
01469 while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
01470 rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
01471 if (rc != LDAP_SUCCESS) {
01472 char *ld_error = NULL;
01473 int ld_errno;
01474
01475 ldap_get_option(ldap_state->ldap_struct,
01476 LDAP_OPT_ERROR_NUMBER, &ld_errno);
01477
01478 ldap_get_option(ldap_state->ldap_struct,
01479 LDAP_OPT_ERROR_STRING, &ld_error);
01480 DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
01481 "(%s)\n", dn, ld_errno,
01482 ldap_err2string(rc),
01483 ld_error ? ld_error : "unknown"));
01484 SAFE_FREE(ld_error);
01485
01486 if (ld_errno == LDAP_SERVER_DOWN) {
01487 ldap_unbind(ldap_state->ldap_struct);
01488 ldap_state->ldap_struct = NULL;
01489 }
01490 }
01491 }
01492
01493 SAFE_FREE(utf8_dn);
01494 return rc;
01495 }
01496
01497 int smbldap_extended_operation(struct smbldap_state *ldap_state,
01498 LDAP_CONST char *reqoid, struct berval *reqdata,
01499 LDAPControl **serverctrls, LDAPControl **clientctrls,
01500 char **retoidp, struct berval **retdatap)
01501 {
01502 int rc = LDAP_SERVER_DOWN;
01503 int attempts = 0;
01504 time_t endtime = time(NULL)+lp_ldap_timeout();
01505
01506 if (!ldap_state)
01507 return (-1);
01508
01509 while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
01510 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid,
01511 reqdata, serverctrls,
01512 clientctrls, retoidp, retdatap);
01513 if (rc != LDAP_SUCCESS) {
01514 char *ld_error = NULL;
01515 int ld_errno;
01516
01517 ldap_get_option(ldap_state->ldap_struct,
01518 LDAP_OPT_ERROR_NUMBER, &ld_errno);
01519
01520 ldap_get_option(ldap_state->ldap_struct,
01521 LDAP_OPT_ERROR_STRING, &ld_error);
01522 DEBUG(10, ("Extended operation failed with error: "
01523 "%d (%s) (%s)\n", ld_errno,
01524 ldap_err2string(rc),
01525 ld_error ? ld_error : "unknown"));
01526 SAFE_FREE(ld_error);
01527
01528 if (ld_errno == LDAP_SERVER_DOWN) {
01529 ldap_unbind(ldap_state->ldap_struct);
01530 ldap_state->ldap_struct = NULL;
01531 }
01532 }
01533 }
01534
01535 return rc;
01536 }
01537
01538
01539
01540
01541 int smbldap_search_suffix (struct smbldap_state *ldap_state,
01542 const char *filter, const char **search_attr,
01543 LDAPMessage ** result)
01544 {
01545 return smbldap_search(ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE,
01546 filter, search_attr, 0, result);
01547 }
01548
01549 static void smbldap_idle_fn(void **data, time_t *interval, time_t now)
01550 {
01551 struct smbldap_state *state = (struct smbldap_state *)(*data);
01552
01553 if (state->ldap_struct == NULL) {
01554 DEBUG(10,("ldap connection not connected...\n"));
01555 return;
01556 }
01557
01558 if ((state->last_use+SMBLDAP_IDLE_TIME) > now) {
01559 DEBUG(10,("ldap connection not idle...\n"));
01560 return;
01561 }
01562
01563 DEBUG(7,("ldap connection idle...closing connection\n"));
01564 smbldap_close(state);
01565 }
01566
01567
01568
01569
01570
01571 void smbldap_free_struct(struct smbldap_state **ldap_state)
01572 {
01573 smbldap_close(*ldap_state);
01574
01575 if ((*ldap_state)->bind_secret) {
01576 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
01577 }
01578
01579 SAFE_FREE((*ldap_state)->bind_dn);
01580 SAFE_FREE((*ldap_state)->bind_secret);
01581
01582 smb_unregister_idle_event((*ldap_state)->event_id);
01583
01584 *ldap_state = NULL;
01585
01586
01587 }
01588
01589
01590
01591
01592
01593
01594 NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state)
01595 {
01596 *smbldap_state = TALLOC_ZERO_P(mem_ctx, struct smbldap_state);
01597 if (!*smbldap_state) {
01598 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
01599 return NT_STATUS_NO_MEMORY;
01600 }
01601
01602 if (location) {
01603 (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
01604 } else {
01605 (*smbldap_state)->uri = "ldap://localhost";
01606 }
01607
01608 (*smbldap_state)->event_id =
01609 smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state),
01610 SMBLDAP_IDLE_TIME);
01611
01612 if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) {
01613 DEBUG(0,("Failed to register LDAP idle event!\n"));
01614 return NT_STATUS_INVALID_HANDLE;
01615 }
01616
01617 return NT_STATUS_OK;
01618 }
01619
01620
01621
01622
01623 char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry)
01624 {
01625 char *utf8_dn, *unix_dn;
01626
01627 utf8_dn = ldap_get_dn(ld, entry);
01628 if (!utf8_dn) {
01629 DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
01630 return NULL;
01631 }
01632 if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) {
01633 DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 [%s]\n", utf8_dn));
01634 return NULL;
01635 }
01636 ldap_memfree(utf8_dn);
01637 return unix_dn;
01638 }
01639
01640 const char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld,
01641 LDAPMessage *entry)
01642 {
01643 char *utf8_dn, *unix_dn;
01644
01645 utf8_dn = ldap_get_dn(ld, entry);
01646 if (!utf8_dn) {
01647 DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n"));
01648 return NULL;
01649 }
01650 if (pull_utf8_talloc(mem_ctx, &unix_dn, utf8_dn) == (size_t)-1) {
01651 DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 "
01652 "[%s]\n", utf8_dn));
01653 return NULL;
01654 }
01655 ldap_memfree(utf8_dn);
01656 return unix_dn;
01657 }
01658
01659
01660
01661
01662
01663 static BOOL smbldap_check_root_dse(LDAP *ld, const char **attrs, const char *value)
01664 {
01665 LDAPMessage *msg = NULL;
01666 LDAPMessage *entry = NULL;
01667 char **values = NULL;
01668 int rc, num_result, num_values, i;
01669 BOOL result = False;
01670
01671 if (!attrs[0]) {
01672 DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
01673 return False;
01674 }
01675
01676 if (!strequal(attrs[0], "supportedExtension") &&
01677 !strequal(attrs[0], "supportedControl") &&
01678 !strequal(attrs[0], "namingContexts")) {
01679 DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs[0]));
01680 return False;
01681 }
01682
01683 rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE,
01684 "(objectclass=*)", CONST_DISCARD(char **, attrs), 0 , &msg);
01685
01686 if (rc != LDAP_SUCCESS) {
01687 DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
01688 return False;
01689 }
01690
01691 num_result = ldap_count_entries(ld, msg);
01692
01693 if (num_result != 1) {
01694 DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result));
01695 goto done;
01696 }
01697
01698 entry = ldap_first_entry(ld, msg);
01699
01700 if (entry == NULL) {
01701 DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
01702 goto done;
01703 }
01704
01705 values = ldap_get_values(ld, entry, attrs[0]);
01706
01707 if (values == NULL) {
01708 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs[0]));
01709 goto done;
01710 }
01711
01712 num_values = ldap_count_values(values);
01713
01714 if (num_values == 0) {
01715 DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs[0]));
01716 goto done;
01717 }
01718
01719 for (i=0; i<num_values; i++) {
01720 if (strcmp(values[i], value) == 0)
01721 result = True;
01722 }
01723
01724
01725 done:
01726 if (values != NULL)
01727 ldap_value_free(values);
01728 if (msg != NULL)
01729 ldap_msgfree(msg);
01730
01731 return result;
01732
01733 }
01734
01735
01736
01737
01738
01739 BOOL smbldap_has_control(LDAP *ld, const char *control)
01740 {
01741 const char *attrs[] = { "supportedControl", NULL };
01742 return smbldap_check_root_dse(ld, attrs, control);
01743 }
01744
01745
01746
01747
01748
01749 BOOL smbldap_has_extension(LDAP *ld, const char *extension)
01750 {
01751 const char *attrs[] = { "supportedExtension", NULL };
01752 return smbldap_check_root_dse(ld, attrs, extension);
01753 }
01754
01755
01756
01757
01758
01759 BOOL smbldap_has_naming_context(LDAP *ld, const char *naming_context)
01760 {
01761 const char *attrs[] = { "namingContexts", NULL };
01762 return smbldap_check_root_dse(ld, attrs, naming_context);
01763 }
01764
01765 BOOL smbldap_set_creds(struct smbldap_state *ldap_state, BOOL anon, const char *dn, const char *secret)
01766 {
01767 ldap_state->anonymous = anon;
01768
01769
01770
01771 SAFE_FREE(ldap_state->bind_dn);
01772 if (ldap_state->bind_secret) {
01773
01774 memset(ldap_state->bind_secret, '\0', strlen(ldap_state->bind_secret));
01775 SAFE_FREE(ldap_state->bind_secret);
01776 }
01777
01778 if ( ! anon) {
01779 ldap_state->bind_dn = SMB_STRDUP(dn);
01780 ldap_state->bind_secret = SMB_STRDUP(secret);
01781 }
01782
01783 return True;
01784 }