X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Flib%2Fsmbldap.c;h=cdd350fffa1e23051594b7efbedc197456472085;hb=e18610a197aab80a32cae8c1e09b96496679bbad;hp=b333f3063d0a73c8c86afeb7cc862c56fecdaf11;hpb=e25345a7a68e93626066d83185ed1944f6bdd044;p=samba.git diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index b333f3063d0..cdd350fffa1 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -24,8 +24,9 @@ #include "includes.h" #include "smbldap.h" -#include "secrets.h" #include "../libcli/security/security.h" +#include +#include "lib/param/loadparm.h" /* Try not to hit the up or down server forever */ @@ -34,227 +35,54 @@ #define SMBLDAP_IDLE_TIME 150 /* After 2.5 minutes disconnect */ +struct smbldap_state { + LDAP *ldap_struct; + pid_t pid; + time_t last_ping; /* monotonic */ + /* retrieve-once info */ + const char *uri; -/* attributes used by Samba 2.2 */ - -ATTRIB_MAP_ENTRY attrib_map_v22[] = { - { LDAP_ATTR_UID, "uid" }, - { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER}, - { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER}, - { LDAP_ATTR_UNIX_HOME, "homeDirectory" }, - { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" }, - { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" }, - { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" }, - { LDAP_ATTR_LOGON_TIME, "logonTime" }, - { LDAP_ATTR_LOGOFF_TIME, "logoffTime" }, - { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" }, - { LDAP_ATTR_CN, "cn" }, - { LDAP_ATTR_SN, "sn" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_HOME_PATH, "smbHome" }, - { LDAP_ATTR_HOME_DRIVE, "homeDrive" }, - { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" }, - { LDAP_ATTR_PROFILE_PATH, "profilePath" }, - { LDAP_ATTR_DESC, "description" }, - { LDAP_ATTR_USER_WKS, "userWorkstations"}, - { LDAP_ATTR_USER_RID, "rid" }, - { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"}, - { LDAP_ATTR_LMPW, "lmPassword" }, - { LDAP_ATTR_NTPW, "ntPassword" }, - { LDAP_ATTR_DOMAIN, "domain" }, - { LDAP_ATTR_OBJCLASS, "objectClass" }, - { LDAP_ATTR_ACB_INFO, "acctFlags" }, - { LDAP_ATTR_MOD_TIMESTAMP, "modifyTimestamp" }, - { LDAP_ATTR_LIST_END, NULL } -}; - -ATTRIB_MAP_ENTRY attrib_map_to_delete_v22[] = { - { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" }, - { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" }, - { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" }, - { LDAP_ATTR_LOGON_TIME, "logonTime" }, - { LDAP_ATTR_LOGOFF_TIME, "logoffTime" }, - { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_HOME_PATH, "smbHome" }, - { LDAP_ATTR_HOME_DRIVE, "homeDrives" }, - { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" }, - { LDAP_ATTR_PROFILE_PATH, "profilePath" }, - { LDAP_ATTR_USER_WKS, "userWorkstations"}, - { LDAP_ATTR_USER_RID, "rid" }, - { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"}, - { LDAP_ATTR_LMPW, "lmPassword" }, - { LDAP_ATTR_NTPW, "ntPassword" }, - { LDAP_ATTR_DOMAIN, "domain" }, - { LDAP_ATTR_ACB_INFO, "acctFlags" }, - { LDAP_ATTR_LIST_END, NULL } -}; + /* credentials */ + bool anonymous; + char *bind_dn; + char *bind_secret; + smbldap_bind_callback_fn bind_callback; + void *bind_callback_data; -/* attributes used by Samba 3.0's sambaSamAccount */ - -ATTRIB_MAP_ENTRY attrib_map_v30[] = { - { LDAP_ATTR_UID, "uid" }, - { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER}, - { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER}, - { LDAP_ATTR_UNIX_HOME, "homeDirectory" }, - { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" }, - { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" }, - { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" }, - { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" }, - { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" }, - { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" }, - { LDAP_ATTR_CN, "cn" }, - { LDAP_ATTR_SN, "sn" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" }, - { LDAP_ATTR_HOME_PATH, "sambaHomePath" }, - { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" }, - { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" }, - { LDAP_ATTR_DESC, "description" }, - { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" }, - { LDAP_ATTR_USER_SID, LDAP_ATTRIBUTE_SID }, - { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" }, - { LDAP_ATTR_LMPW, "sambaLMPassword" }, - { LDAP_ATTR_NTPW, "sambaNTPassword" }, - { LDAP_ATTR_DOMAIN, "sambaDomainName" }, - { LDAP_ATTR_OBJCLASS, "objectClass" }, - { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" }, - { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" }, - { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" }, - { LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" }, - { LDAP_ATTR_PWD_HISTORY, "sambaPasswordHistory" }, - { LDAP_ATTR_MOD_TIMESTAMP, "modifyTimestamp" }, - { LDAP_ATTR_LOGON_HOURS, "sambaLogonHours" }, - { LDAP_ATTR_LIST_END, NULL } -}; + bool paged_results; -ATTRIB_MAP_ENTRY attrib_map_to_delete_v30[] = { - { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" }, - { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" }, - { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" }, - { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" }, - { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" }, - { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" }, - { LDAP_ATTR_HOME_PATH, "sambaHomePath" }, - { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" }, - { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" }, - { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" }, - { LDAP_ATTR_USER_SID, LDAP_ATTRIBUTE_SID }, - { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" }, - { LDAP_ATTR_LMPW, "sambaLMPassword" }, - { LDAP_ATTR_NTPW, "sambaNTPassword" }, - { LDAP_ATTR_DOMAIN, "sambaDomainName" }, - { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" }, - { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" }, - { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" }, - { LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" }, - { LDAP_ATTR_PWD_HISTORY, "sambaPasswordHistory" }, - { LDAP_ATTR_LOGON_HOURS, "sambaLogonHours" }, - { LDAP_ATTR_LIST_END, NULL } -}; - -/* attributes used for allocating RIDs */ - -ATTRIB_MAP_ENTRY dominfo_attr_list[] = { - { LDAP_ATTR_DOMAIN, "sambaDomainName" }, - { LDAP_ATTR_NEXT_RID, "sambaNextRid" }, - { LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" }, - { LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" }, - { LDAP_ATTR_DOM_SID, LDAP_ATTRIBUTE_SID }, - { LDAP_ATTR_ALGORITHMIC_RID_BASE,"sambaAlgorithmicRidBase"}, - { LDAP_ATTR_OBJCLASS, "objectClass" }, - { LDAP_ATTR_LIST_END, NULL }, -}; + unsigned int num_failures; -/* Samba 3.0 group mapping attributes */ - -ATTRIB_MAP_ENTRY groupmap_attr_list[] = { - { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER}, - { LDAP_ATTR_GROUP_SID, LDAP_ATTRIBUTE_SID }, - { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" }, - { LDAP_ATTR_SID_LIST, "sambaSIDList" }, - { LDAP_ATTR_DESC, "description" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_CN, "cn" }, - { LDAP_ATTR_OBJCLASS, "objectClass" }, - { LDAP_ATTR_LIST_END, NULL } -}; - -ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = { - { LDAP_ATTR_GROUP_SID, LDAP_ATTRIBUTE_SID }, - { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" }, - { LDAP_ATTR_DESC, "description" }, - { LDAP_ATTR_DISPLAY_NAME, "displayName" }, - { LDAP_ATTR_SID_LIST, "sambaSIDList" }, - { LDAP_ATTR_LIST_END, NULL } -}; - -/* idmap_ldap sambaUnixIdPool */ - -ATTRIB_MAP_ENTRY idpool_attr_list[] = { - { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER}, - { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER}, - { LDAP_ATTR_OBJCLASS, "objectClass" }, - { LDAP_ATTR_LIST_END, NULL } -}; + time_t last_use; /* monotonic */ + struct tevent_context *tevent_context; + struct tevent_timer *idle_event; -ATTRIB_MAP_ENTRY sidmap_attr_list[] = { - { LDAP_ATTR_SID, LDAP_ATTRIBUTE_SID }, - { LDAP_ATTR_UIDNUMBER, LDAP_ATTRIBUTE_UIDNUMBER}, - { LDAP_ATTR_GIDNUMBER, LDAP_ATTRIBUTE_GIDNUMBER}, - { LDAP_ATTR_OBJCLASS, "objectClass" }, - { LDAP_ATTR_LIST_END, NULL } + struct timeval last_rebind; /* monotonic */ }; -/********************************************************************** - perform a simple table lookup and return the attribute name - **********************************************************************/ - - const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key ) +LDAP *smbldap_get_ldap(struct smbldap_state *state) { - int i = 0; - - while ( table[i].attrib != LDAP_ATTR_LIST_END ) { - if ( table[i].attrib == key ) - return table[i].name; - i++; - } - - return NULL; + return state->ldap_struct; } - -/********************************************************************** - Return the list of attribute names from a mapping table - **********************************************************************/ - - const char** get_attr_list( TALLOC_CTX *mem_ctx, ATTRIB_MAP_ENTRY table[] ) +bool smbldap_get_paged_results(struct smbldap_state *state) { - const char **names; - int i = 0; - - while ( table[i].attrib != LDAP_ATTR_LIST_END ) - i++; - i++; - - names = talloc_array( mem_ctx, const char*, i ); - if ( !names ) { - DEBUG(0,("get_attr_list: out of memory\n")); - return NULL; - } - - i = 0; - while ( table[i].attrib != LDAP_ATTR_LIST_END ) { - names[i] = talloc_strdup( names, table[i].name ); - i++; - } - names[i] = NULL; + return state->paged_results; +} - return names; +void smbldap_set_paged_results(struct smbldap_state *state, + bool paged_results) +{ + state->paged_results = paged_results; } +void smbldap_set_bind_callback(struct smbldap_state *state, + smbldap_bind_callback_fn callback, + void *callback_data) +{ + state->bind_callback = callback; + state->bind_callback_data = callback_data; +} /******************************************************************* Search an attribute and return the first value found. ******************************************************************/ @@ -450,15 +278,15 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { struct dom_sid *sid) { DATA_BLOB blob; - bool ret; + struct sid_parse_ret ret; if (!smbldap_talloc_single_blob(talloc_tos(), ld, msg, attrib, &blob)) { return false; } - ret = sid_parse((char *)blob.data, blob.length, sid); + ret = sid_parse(blob.data, blob.length, sid); TALLOC_FREE(blob.data); - return ret; + return (ret.len != -1); } static int ldapmsg_destructor(LDAPMessage **result) { @@ -466,7 +294,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { return 0; } - void talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result) + void smbldap_talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result) { LDAPMessage **handle; @@ -486,7 +314,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { return 0; } - void talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod) + void smbldap_talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod) { LDAPMod ***handle; @@ -520,7 +348,7 @@ static void smbldap_set_mod_internal(LDAPMod *** modlist, int modop, const char return; } -#if 0 /* commented out after discussion with abartlet. Do not reenable. +#if 0 /* commented out after discussion with abartlet. Do not re-enable. left here so other do not re-add similar code --jerry */ if (value == NULL || *value == '\0') return; @@ -572,7 +400,7 @@ static void smbldap_set_mod_internal(LDAPMod *** modlist, int modop, const char mods[i]->mod_bvalues[j] = SMB_MALLOC_P(struct berval); SMB_ASSERT(mods[i]->mod_bvalues[j] != NULL); - mods[i]->mod_bvalues[j]->bv_val = (char *)memdup(blob->data, blob->length); + mods[i]->mod_bvalues[j]->bv_val = (char *)smb_memdup(blob->data, blob->length); SMB_ASSERT(mods[i]->mod_bvalues[j]->bv_val != NULL); mods[i]->mod_bvalues[j]->bv_len = blob->length; @@ -631,12 +459,6 @@ static void smbldap_make_mod_internal(LDAP *ldap_struct, LDAPMessage *existing, bool existed; DATA_BLOB oldblob = data_blob_null; - if (attribute == NULL) { - /* This can actually happen for ldapsam_compat where we for - * example don't have a password history */ - return; - } - if (existing != NULL) { if (op & LDAP_MOD_BVALUES) { existed = smbldap_talloc_single_blob(talloc_tos(), ldap_struct, existing, attribute, &oldblob); @@ -770,7 +592,7 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) t = SMB_XMALLOC_P(struct smbldap_state_lookup); ZERO_STRUCTP(t); - DLIST_ADD_END(smbldap_state_lookup_list, t, struct smbldap_state_lookup *); + DLIST_ADD_END(smbldap_state_lookup_list, t); t->ld = ld; t->smbldap_state = smbldap_state; } @@ -779,10 +601,10 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) start TLS on an existing LDAP connection *******************************************************************/ -int smb_ldap_start_tls(LDAP *ldap_struct, int version) +int smbldap_start_tls(LDAP *ldap_struct, int version) { #ifdef LDAP_OPT_X_TLS - int rc; + int rc,tls; #endif if (lp_ldap_ssl() != LDAP_SSL_START_TLS) { @@ -790,6 +612,12 @@ int smb_ldap_start_tls(LDAP *ldap_struct, int version) } #ifdef LDAP_OPT_X_TLS + /* check if we use ldaps already */ + ldap_get_option(ldap_struct, LDAP_OPT_X_TLS, &tls); + if (tls == LDAP_OPT_X_TLS_HARD) { + return LDAP_SUCCESS; + } + if (version != LDAP_VERSION3) { DEBUG(0, ("Need LDAPv3 for Start TLS\n")); return LDAP_OPERATIONS_ERROR; @@ -950,7 +778,7 @@ static int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version) open a connection to the ldap server (just until the bind) ******************************************************************/ -int smb_ldap_setup_full_conn(LDAP **ldap_struct, const char *uri) +int smbldap_setup_full_conn(LDAP **ldap_struct, const char *uri) { int rc, version; @@ -964,7 +792,7 @@ int smb_ldap_setup_full_conn(LDAP **ldap_struct, const char *uri) return rc; } - rc = smb_ldap_start_tls(*ldap_struct, version); + rc = smbldap_start_tls(*ldap_struct, version); if (rc) { return rc; } @@ -1001,7 +829,7 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state) /* Start TLS if required */ - rc = smb_ldap_start_tls(*ldap_struct, version); + rc = smbldap_start_tls(*ldap_struct, version); if (rc) { return rc; } @@ -1095,7 +923,7 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct, * our credentials. At least *try* to secure the connection - Guenther */ smb_ldap_upgrade_conn(ldap_struct, &version); - smb_ldap_start_tls(ldap_struct, version); + smbldap_start_tls(ldap_struct, version); /** @TODO Should we be doing something to check what servers we rebind to? Could we get a referral to a machine that we don't want to give our @@ -1168,28 +996,12 @@ static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request, ******************************************************************/ static int smbldap_connect_system(struct smbldap_state *ldap_state) { - LDAP *ldap_struct = ldap_state->ldap_struct; + LDAP *ldap_struct = smbldap_get_ldap(ldap_state); int rc; int version; - if (!ldap_state->anonymous && !ldap_state->bind_dn) { - char *bind_dn = NULL; - char *bind_secret = NULL; - - /* get the default dn and password only if they are not set already */ - if (!fetch_ldap_pw(&bind_dn, &bind_secret)) { - DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n")); - rc = LDAP_INVALID_CREDENTIALS; - goto done; - } - smbldap_set_creds(ldap_state, false, bind_dn, bind_secret); - SAFE_FREE(bind_dn); - memset(bind_secret, '\0', strlen(bind_secret)); - SAFE_FREE(bind_secret); - } - /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite - (OpenLDAP) doesnt' seem to support it */ + (OpenLDAP) doesn't seem to support it */ DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n", ldap_state->uri, ldap_state->bind_dn)); @@ -1212,11 +1024,25 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state) #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ #endif - rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret); + /* When there is an alternative bind callback is set, + attempt to use it to perform the bind */ + if (ldap_state->bind_callback != NULL) { + /* We have to allow bind callback to be run under become_root/unbecome_root + to make sure within smbd the callback has proper write access to its resources, + like credential cache. This is similar to passdb case where this callback is supposed + to be used. When used outside smbd, become_root()/unbecome_root() are no-op. + */ + become_root(); + rc = ldap_state->bind_callback(ldap_struct, ldap_state, ldap_state->bind_callback_data); + unbecome_root(); + } else { + rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret); + } if (rc != LDAP_SUCCESS) { char *ld_error = NULL; - ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, + ldap_get_option(smbldap_get_ldap(ldap_state), + LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(ldap_state->num_failures ? 2 : 0, ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n", @@ -1232,9 +1058,11 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state) ldap_state->num_failures = 0; ldap_state->paged_results = False; - ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); + ldap_get_option(smbldap_get_ldap(ldap_state), + LDAP_OPT_PROTOCOL_VERSION, &version); - if (smbldap_has_control(ldap_state->ldap_struct, ADS_PAGE_CTL_OID) && version == 3) { + if (smbldap_has_control(smbldap_get_ldap(ldap_state), ADS_PAGE_CTL_OID) + && version == 3) { ldap_state->paged_results = True; } @@ -1249,8 +1077,8 @@ done: return rc; } -static void smbldap_idle_fn(struct event_context *event_ctx, - struct timed_event *te, +static void smbldap_idle_fn(struct tevent_context *tevent_ctx, + struct tevent_timer *te, struct timeval now_abs, void *private_data); @@ -1263,17 +1091,20 @@ static int smbldap_open(struct smbldap_state *ldap_state) bool reopen = False; SMB_ASSERT(ldap_state); - if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time_mono(NULL))) { + if ((smbldap_get_ldap(ldap_state) != NULL) && + ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < + time_mono(NULL))) { #ifdef HAVE_UNIXSOCKET struct sockaddr_un addr; #else - struct sockaddr addr; + struct sockaddr_storage addr; #endif socklen_t len = sizeof(addr); int sd; - opt_rc = ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd); + opt_rc = ldap_get_option(smbldap_get_ldap(ldap_state), + LDAP_OPT_DESC, &sd); if (opt_rc == 0 && (getpeername(sd, (struct sockaddr *) &addr, &len)) < 0 ) reopen = True; @@ -1283,15 +1114,15 @@ static int smbldap_open(struct smbldap_state *ldap_state) #endif if (reopen) { /* the other end has died. reopen. */ - ldap_unbind(ldap_state->ldap_struct); - ldap_state->ldap_struct = NULL; + ldap_unbind(smbldap_get_ldap(ldap_state)); + ldap_state->ldap_struct = NULL; ldap_state->last_ping = (time_t)0; } else { ldap_state->last_ping = time_mono(NULL); } } - if (ldap_state->ldap_struct != NULL) { + if (smbldap_get_ldap(ldap_state) != NULL) { DEBUG(11,("smbldap_open: already connected to the LDAP server\n")); return LDAP_SUCCESS; } @@ -1306,13 +1137,13 @@ static int smbldap_open(struct smbldap_state *ldap_state) ldap_state->last_ping = time_mono(NULL); - ldap_state->pid = sys_getpid(); + ldap_state->pid = getpid(); TALLOC_FREE(ldap_state->idle_event); - if (ldap_state->event_context != NULL) { - ldap_state->idle_event = event_add_timed( - ldap_state->event_context, ldap_state, + if (ldap_state->tevent_context != NULL) { + ldap_state->idle_event = tevent_add_timer( + ldap_state->tevent_context, ldap_state, timeval_current_ofs(SMBLDAP_IDLE_TIME, 0), smbldap_idle_fn, ldap_state); } @@ -1330,8 +1161,8 @@ static NTSTATUS smbldap_close(struct smbldap_state *ldap_state) if (!ldap_state) return NT_STATUS_INVALID_PARAMETER; - if (ldap_state->ldap_struct != NULL) { - ldap_unbind(ldap_state->ldap_struct); + if (smbldap_get_ldap(ldap_state) != NULL) { + ldap_unbind(smbldap_get_ldap(ldap_state)); ldap_state->ldap_struct = NULL; } @@ -1393,17 +1224,17 @@ static void setup_ldap_local_alarm(struct smbldap_state *ldap_state, time_t abso alarm(absolute_endtime - now); } - if (ldap_state->pid != sys_getpid()) { + if (ldap_state->pid != getpid()) { smbldap_close(ldap_state); } } static void get_ldap_errs(struct smbldap_state *ldap_state, char **pp_ld_error, int *p_ld_errno) { - ldap_get_option(ldap_state->ldap_struct, + ldap_get_option(smbldap_get_ldap(ldap_state), LDAP_OPT_ERROR_NUMBER, p_ld_errno); - ldap_get_option(ldap_state->ldap_struct, + ldap_get_option(smbldap_get_ldap(ldap_state), LDAP_OPT_ERROR_STRING, pp_ld_error); } @@ -1523,7 +1354,8 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state, break; } - rc = ldap_search_ext_s(ldap_state->ldap_struct, base, scope, + rc = ldap_search_ext_s(smbldap_get_ldap(ldap_state), + base, scope, utf8_filter, discard_const_p(char *, attrs), attrsonly, sctrls, cctrls, timeout_ptr, @@ -1543,7 +1375,7 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state, if (ld_errno != LDAP_SERVER_DOWN) { break; } - ldap_unbind(ldap_state->ldap_struct); + ldap_unbind(smbldap_get_ldap(ldap_state)); ldap_state->ldap_struct = NULL; } @@ -1618,7 +1450,7 @@ int smbldap_search_paged(struct smbldap_state *ldap_state, DEBUG(3,("smbldap_search_paged: search was successful\n")); - rc = ldap_parse_result(ldap_state->ldap_struct, *res, NULL, NULL, + rc = ldap_parse_result(smbldap_get_ldap(ldap_state), *res, NULL, NULL, NULL, NULL, &rcontrols, 0); if (rc != 0) { DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \ @@ -1677,7 +1509,8 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at break; } - rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs); + rc = ldap_modify_s(smbldap_get_ldap(ldap_state), utf8_dn, + attrs); if (rc == LDAP_SUCCESS) { break; } @@ -1693,7 +1526,7 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at if (ld_errno != LDAP_SERVER_DOWN) { break; } - ldap_unbind(ldap_state->ldap_struct); + ldap_unbind(smbldap_get_ldap(ldap_state)); ldap_state->ldap_struct = NULL; } @@ -1727,7 +1560,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs break; } - rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs); + rc = ldap_add_s(smbldap_get_ldap(ldap_state), utf8_dn, attrs); if (rc == LDAP_SUCCESS) { break; } @@ -1743,7 +1576,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs if (ld_errno != LDAP_SERVER_DOWN) { break; } - ldap_unbind(ldap_state->ldap_struct); + ldap_unbind(smbldap_get_ldap(ldap_state)); ldap_state->ldap_struct = NULL; } @@ -1777,7 +1610,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn) break; } - rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn); + rc = ldap_delete_s(smbldap_get_ldap(ldap_state), utf8_dn); if (rc == LDAP_SUCCESS) { break; } @@ -1793,7 +1626,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn) if (ld_errno != LDAP_SERVER_DOWN) { break; } - ldap_unbind(ldap_state->ldap_struct); + ldap_unbind(smbldap_get_ldap(ldap_state)); ldap_state->ldap_struct = NULL; } @@ -1823,7 +1656,8 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state, break; } - rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, + rc = ldap_extended_operation_s(smbldap_get_ldap(ldap_state), + reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap); if (rc == LDAP_SUCCESS) { @@ -1841,7 +1675,7 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state, if (ld_errno != LDAP_SERVER_DOWN) { break; } - ldap_unbind(ldap_state->ldap_struct); + ldap_unbind(smbldap_get_ldap(ldap_state)); ldap_state->ldap_struct = NULL; } @@ -1855,12 +1689,13 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter, const char **search_attr, LDAPMessage ** result) { - return smbldap_search(ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE, + return smbldap_search(ldap_state, lp_ldap_suffix(talloc_tos()), + LDAP_SCOPE_SUBTREE, filter, search_attr, 0, result); } -static void smbldap_idle_fn(struct event_context *event_ctx, - struct timed_event *te, +static void smbldap_idle_fn(struct tevent_context *tevent_ctx, + struct tevent_timer *te, struct timeval now_abs, void *private_data) { @@ -1868,7 +1703,7 @@ static void smbldap_idle_fn(struct event_context *event_ctx, TALLOC_FREE(state->idle_event); - if (state->ldap_struct == NULL) { + if (smbldap_get_ldap(state) == NULL) { DEBUG(10,("ldap connection not connected...\n")); return; } @@ -1877,8 +1712,8 @@ static void smbldap_idle_fn(struct event_context *event_ctx, DEBUG(10,("ldap connection not idle...\n")); /* this needs to be made monotonic clock aware inside tevent: */ - state->idle_event = event_add_timed( - event_ctx, state, + state->idle_event = tevent_add_timer( + tevent_ctx, state, timeval_add(&now_abs, SMBLDAP_IDLE_TIME, 0), smbldap_idle_fn, private_data); @@ -1903,6 +1738,7 @@ void smbldap_free_struct(struct smbldap_state **ldap_state) SAFE_FREE((*ldap_state)->bind_dn); SAFE_FREE((*ldap_state)->bind_secret); + smbldap_set_bind_callback(*ldap_state, NULL, NULL); TALLOC_FREE(*ldap_state); @@ -1920,8 +1756,11 @@ static int smbldap_state_destructor(struct smbldap_state *state) Intitalise the 'general' ldap structures, on which ldap operations may be conducted *********************************************************************/ -NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, +NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct tevent_context *tevent_ctx, const char *location, + bool anon, + const char *bind_dn, + const char *bind_secret, struct smbldap_state **smbldap_state) { *smbldap_state = talloc_zero(mem_ctx, struct smbldap_state); @@ -1936,7 +1775,11 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, (*smbldap_state)->uri = "ldap://localhost"; } - (*smbldap_state)->event_context = event_ctx; + (*smbldap_state)->tevent_context = tevent_ctx; + + if (bind_dn && bind_secret) { + smbldap_set_creds(*smbldap_state, anon, bind_dn, bind_secret); + } talloc_set_destructor(*smbldap_state, smbldap_state_destructor); return NT_STATUS_OK; @@ -2075,6 +1918,8 @@ bool smbldap_set_creds(struct smbldap_state *ldap_state, bool anon, const char * /* free any previously set credential */ SAFE_FREE(ldap_state->bind_dn); + smbldap_set_bind_callback(ldap_state, NULL, NULL); + if (ldap_state->bind_secret) { /* make sure secrets are zeroed out of memory */ memset(ldap_state->bind_secret, '\0', strlen(ldap_state->bind_secret));