static int do_uri_create( LDAPURLDesc *lud ) { char *uri; if ( lud->lud_scheme == NULL ) { lud->lud_scheme = "ldap"; } if ( lud->lud_port == -1 ) { if ( strcasecmp( lud->lud_scheme, "ldap" ) == 0 ) { lud->lud_port = LDAP_PORT; } else if ( strcasecmp( lud->lud_scheme, "ldaps" ) == 0 ) { lud->lud_port = LDAPS_PORT; } else if ( strcasecmp( lud->lud_scheme, "ldapi" ) == 0 ) { lud->lud_port = 0; } else { /* forgiving... */ lud->lud_port = 0; } } if ( lud->lud_scope == -1 ) { lud->lud_scope = LDAP_SCOPE_DEFAULT; } uri = ldap_url_desc2str( lud ); if ( lud->lud_attrs != NULL ) { ldap_charray_free( lud->lud_attrs ); lud->lud_attrs = NULL; } if ( lud->lud_exts != NULL ) { free( lud->lud_exts ); lud->lud_exts = NULL; } if ( uri == NULL ) { fprintf( stderr, "unable to generate URI\n" ); exit( EXIT_FAILURE ); } printf( "%s\n", uri ); free( uri ); return 0; }
static int _mu_conn_setup (LDAP **pld) { int rc; LDAPURLDesc *ludlist, **ludp; char **urls = NULL; int nurls = 0; char *ldapuri = NULL; LDAP *ld = NULL; int protocol = LDAP_VERSION3; /* FIXME: must be configurable */ if (ldap_param.debug) { if (ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &ldap_param.debug) != LBER_OPT_SUCCESS ) mu_error (_("cannot set LBER_OPT_DEBUG_LEVEL %d"), ldap_param.debug); if (ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &ldap_param.debug) != LDAP_OPT_SUCCESS ) mu_error (_("could not set LDAP_OPT_DEBUG_LEVEL %d"), ldap_param.debug); } if (ldap_param.url) { rc = ldap_url_parse (ldap_param.url, &ludlist); if (rc != LDAP_URL_SUCCESS) { mu_error (_("cannot parse LDAP URL(s)=%s (%d)"), ldap_param.url, rc); return 1; } for (ludp = &ludlist; *ludp; ) { LDAPURLDesc *lud = *ludp; char **tmp; if (lud->lud_dn && lud->lud_dn[0] && (lud->lud_host == NULL || lud->lud_host[0] == '\0')) { /* if no host but a DN is provided, try DNS SRV to gather the host list */ char *domain = NULL, *hostlist = NULL; size_t i; struct mu_wordsplit ws; if (ldap_dn2domain (lud->lud_dn, &domain) || !domain) { mu_error (_("DNS SRV: cannot convert DN=\"%s\" into a domain"), lud->lud_dn ); goto dnssrv_free; } rc = ldap_domain2hostlist (domain, &hostlist); if (rc) { mu_error (_("DNS SRV: cannot convert domain=%s into a hostlist"), domain); goto dnssrv_free; } if (mu_wordsplit (hostlist, &ws, MU_WRDSF_DEFFLAGS)) { mu_error (_("DNS SRV: could not parse hostlist=\"%s\": %s"), hostlist, mu_wordsplit_strerror (&ws)); goto dnssrv_free; } tmp = realloc (urls, sizeof(char *) * (nurls + ws.ws_wordc + 1)); if (!tmp) { mu_error ("DNS SRV %s", mu_strerror (errno)); goto dnssrv_free; } urls = tmp; urls[nurls] = NULL; for (i = 0; i < ws.ws_wordc; i++) { urls[nurls + i + 1] = NULL; rc = mu_asprintf (&urls[nurls + i], "%s://%s", lud->lud_scheme, ws.ws_wordv[i]); if (rc) { mu_error ("DNS SRV %s", mu_strerror (rc)); goto dnssrv_free; } } nurls += i; dnssrv_free: mu_wordsplit_free (&ws); ber_memfree (hostlist); ber_memfree (domain); } else { tmp = realloc (urls, sizeof(char *) * (nurls + 2)); if (!tmp) { mu_error ("DNS SRV %s", mu_strerror (errno)); break; } urls = tmp; urls[nurls + 1] = NULL; urls[nurls] = ldap_url_desc2str (lud); if (!urls[nurls]) { mu_error ("DNS SRV %s", mu_strerror (errno)); break; } nurls++; } *ludp = lud->lud_next; lud->lud_next = NULL; ldap_free_urldesc (lud); } if (ludlist) { ldap_free_urldesc (ludlist); return 1; } else if (!urls) return 1; rc = mu_argcv_string (nurls, urls, &ldapuri); if (rc) { mu_error ("%s", mu_strerror (rc)); return 1; } ber_memvfree ((void **)urls); } mu_diag_output (MU_DIAG_INFO, "constructed LDAP URI: %s", ldapuri ? ldapuri : "<DEFAULT>"); rc = ldap_initialize (&ld, ldapuri); if (rc != LDAP_SUCCESS) { mu_error (_("cannot create LDAP session handle for URI=%s (%d): %s"), ldapuri, rc, ldap_err2string (rc)); free (ldapuri); return 1; } free (ldapuri); ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol); if (ldap_param.tls) { rc = ldap_start_tls_s (ld, NULL, NULL); if (rc != LDAP_SUCCESS) { char *msg = NULL; ldap_get_option (ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg); mu_error (_("ldap_start_tls failed: %s"), ldap_err2string (rc)); mu_error (_("TLS diagnostics: %s"), msg); ldap_memfree (msg); ldap_unbind_ext (ld, NULL, NULL); return 1; } } /* FIXME: Timeouts, SASL, etc. */ *pld = ld; return 0; }
BerVarray referral_rewrite( BerVarray in, struct berval *base, struct berval *target, int scope ) { int i; BerVarray refs; struct berval *iv, *jv; if ( in == NULL ) { return NULL; } for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) { /* just count them */ } if ( i < 1 ) { return NULL; } refs = ch_malloc( ( i + 1 ) * sizeof( struct berval ) ); for ( iv = in, jv = refs; !BER_BVISNULL( iv ); iv++ ) { LDAPURLDesc *url; char *dn; int rc; rc = ldap_url_parse_ext( iv->bv_val, &url, LDAP_PVT_URL_PARSE_NONE ); if ( rc == LDAP_URL_ERR_BADSCHEME ) { ber_dupbv( jv++, iv ); continue; } else if ( rc != LDAP_URL_SUCCESS ) { continue; } dn = url->lud_dn; url->lud_dn = referral_dn_muck( ( dn && *dn ) ? dn : NULL, base, target ); ldap_memfree( dn ); if ( url->lud_scope == LDAP_SCOPE_DEFAULT ) { url->lud_scope = scope; } jv->bv_val = ldap_url_desc2str( url ); if ( jv->bv_val != NULL ) { jv->bv_len = strlen( jv->bv_val ); } else { ber_dupbv( jv, iv ); } jv++; ldap_free_urldesc( url ); } if ( jv == refs ) { ch_free( refs ); refs = NULL; } else { BER_BVZERO( jv ); } return refs; }
int main(int argc, char *argv[]) { const char *url, *scope = NULL; LDAPURLDesc *lud; enum { IS_LDAP = 0, IS_LDAPS, IS_LDAPI } type = IS_LDAP; int rc; if ( argc != 2 ) { fprintf( stderr, "usage: urltest <url>\n" ); exit( EXIT_FAILURE ); } url = argv[ 1 ]; if ( ldap_is_ldaps_url( url ) ) { fprintf( stdout, "LDAPS url\n" ); type = IS_LDAPS; } else if ( ldap_is_ldapi_url( url ) ) { fprintf( stdout, "LDAPI url\n" ); type = IS_LDAPI; } else if ( ldap_is_ldap_url( url ) ) { fprintf( stdout, "generic LDAP url\n" ); } else { fprintf( stderr, "Need a valid LDAP url\n" ); exit( EXIT_FAILURE ); } rc = ldap_url_parse( url, &lud ); if ( rc != LDAP_URL_SUCCESS ) { fprintf( stderr, "ldap_url_parse(%s) failed (%d)\n", url, rc ); exit( EXIT_FAILURE ); } fprintf( stdout, "PROTO: %s\n", lud->lud_scheme ); switch ( type ) { case IS_LDAPI: fprintf( stdout, "PATH: %s\n", lud->lud_host ); break; default: fprintf( stdout, "HOST: %s\n", lud->lud_host ); if ( lud->lud_port != 0 ) { fprintf( stdout, "PORT: %d\n", lud->lud_port ); } } if ( lud->lud_dn && lud->lud_dn[ 0 ] ) { fprintf( stdout, "DN: %s\n", lud->lud_dn ); } if ( lud->lud_attrs ) { int i; fprintf( stdout, "ATTRS:\n" ); for ( i = 0; lud->lud_attrs[ i ]; i++ ) { fprintf( stdout, "\t%s\n", lud->lud_attrs[ i ] ); } } scope = ldap_pvt_scope2str( lud->lud_scope ); if ( scope ) { fprintf( stdout, "SCOPE: %s\n", scope ); } if ( lud->lud_filter ) { fprintf( stdout, "FILTER: %s\n", lud->lud_filter ); } if ( lud->lud_exts ) { int i; fprintf( stdout, "EXTS:\n" ); for ( i = 0; lud->lud_exts[ i ]; i++ ) { fprintf( stdout, "\t%s\n", lud->lud_exts[ i ] ); } } fprintf( stdout, "URL: %s\n", ldap_url_desc2str( lud )); return EXIT_SUCCESS; }
OPENLDAP::Book::Book (Ekiga::ServiceCore &_core, boost::shared_ptr<xmlDoc> _doc, xmlNodePtr _node): saslform(NULL), core(_core), doc(_doc), node(_node), name_node(NULL), uri_node(NULL), authcID_node(NULL), password_node(NULL), ldap_context(NULL), patience(0) { xmlChar *xml_str; bool upgrade_config = false; /* for previous config */ std::string hostname="", port="", base="", scope="", call_attribute=""; xmlNodePtr hostname_node = NULL, port_node = NULL, base_node = NULL, scope_node = NULL, call_attribute_node = NULL; bookinfo.name = ""; bookinfo.uri = ""; bookinfo.authcID = ""; bookinfo.password = ""; bookinfo.saslMech = ""; bookinfo.sasl = false; bookinfo.starttls = false; for (xmlNodePtr child = node->children ; child != NULL; child = child->next) { if (child->type == XML_ELEMENT_NODE && child->name != NULL) { if (xmlStrEqual (BAD_CAST ("name"), child->name)) { xml_str = xmlNodeGetContent (child); bookinfo.name = (const char *)xml_str; xmlFree (xml_str); name_node = child; continue; } if (xmlStrEqual (BAD_CAST ("uri"), child->name)) { xml_str = xmlNodeGetContent (child); bookinfo.uri = (const char *)xml_str; xmlFree (xml_str); uri_node = child; continue; } if (xmlStrEqual (BAD_CAST ("hostname"), child->name)) { xml_str = xmlNodeGetContent (child); hostname = (const char *)xml_str; hostname_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("port"), child->name)) { xml_str = xmlNodeGetContent (child); port = (const char *)xml_str; port_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("base"), child->name)) { xml_str = xmlNodeGetContent (child); base = (const char *)xml_str; base_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("scope"), child->name)) { xml_str = xmlNodeGetContent (child); scope = (const char *)xml_str; scope_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("call_attribute"), child->name)) { xml_str = xmlNodeGetContent (child); call_attribute = (const char *)xml_str; call_attribute_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("authcID"), child->name)) { xml_str = xmlNodeGetContent (child); bookinfo.authcID = (const char *)xml_str; authcID_node = child; xmlFree (xml_str); continue; } if (xmlStrEqual (BAD_CAST ("password"), child->name)) { xml_str = xmlNodeGetContent (child); bookinfo.password = (const char *)xml_str; password_node = child; xmlFree (xml_str); continue; } } } if (upgrade_config) { if (!uri_node) { LDAPURLDesc *url_tmp = NULL; char *url_str; std::string new_uri; if (hostname.empty()) hostname="localhost"; new_uri = std::string("ldap://") + hostname; if (!port.empty()) new_uri += std::string(":") + port; new_uri += "/?cn," + call_attribute + "?" + scope; ldap_url_parse (new_uri.c_str(), &url_tmp); url_tmp->lud_dn = (char *)base.c_str(); url_str = ldap_url_desc2str (url_tmp); bookinfo.uri = std::string(url_str); ldap_memfree (url_str); robust_xmlNodeSetContent (node, &uri_node, "uri", bookinfo.uri); url_tmp->lud_dn = NULL; ldap_free_urldesc (url_tmp); } if (hostname_node) { xmlUnlinkNode (hostname_node); xmlFreeNode (hostname_node); } if (port_node) { xmlUnlinkNode (port_node); xmlFreeNode (port_node); } if (base_node) { xmlUnlinkNode (base_node); xmlFreeNode (base_node); } if (scope_node) { xmlUnlinkNode (scope_node); xmlFreeNode (scope_node); } if (call_attribute_node) { xmlUnlinkNode (call_attribute_node); xmlFreeNode (call_attribute_node); } trigger_saving (); } OPENLDAP::BookInfoParse (bookinfo); if (bookinfo.uri_host == EKIGA_NET_URI) I_am_an_ekiga_net_book = true; else I_am_an_ekiga_net_book = false; /* Actor stuff */ add_action (Ekiga::ActionPtr (new Ekiga::Action ("edit-book", _("_Edit"), boost::bind (&OPENLDAP::Book::edit, this)))); add_action (Ekiga::ActionPtr (new Ekiga::Action ("remove-book", _("_Remove"), boost::bind (&OPENLDAP::Book::remove, this)))); add_action (Ekiga::ActionPtr (new Ekiga::Action ("refresh-book", _("_Refresh"), boost::bind (&OPENLDAP::Book::refresh, this)))); }
/* * I don't like this much, but we need two different * functions because different heap managers may be * in use in back-ldap/meta to reduce the amount of * calls to malloc routines, and some of the free() * routines may be macros with args */ int rwm_referral_rewrite( Operation *op, SlapReply *rs, void *cookie, BerVarray a_vals, BerVarray *pa_nvals ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private; int i, last; dncookie dc; struct berval dn = BER_BVNULL, ndn = BER_BVNULL; assert( a_vals != NULL ); /* * Rewrite the dn if needed */ dc.rwmap = rwmap; dc.conn = op->o_conn; dc.rs = rs; dc.ctx = (char *)cookie; for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ ) ; last--; if ( pa_nvals != NULL ) { if ( *pa_nvals == NULL ) { *pa_nvals = ch_malloc( ( last + 2 ) * sizeof(struct berval) ); memset( *pa_nvals, 0, ( last + 2 ) * sizeof(struct berval) ); } } for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) { struct berval olddn = BER_BVNULL, oldval; int rc; LDAPURLDesc *ludp; oldval = a_vals[i]; rc = ldap_url_parse( oldval.bv_val, &ludp ); if ( rc != LDAP_URL_SUCCESS ) { /* leave attr untouched if massage failed */ if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) { ber_dupbv( &(*pa_nvals)[i], &oldval ); } continue; } /* FIXME: URLs like "ldap:///dc=suffix" if passed * thru ldap_url_parse() and ldap_url_desc2str() * get rewritten as "ldap:///dc=suffix??base"; * we don't want this to occur... */ if ( ludp->lud_scope == LDAP_SCOPE_BASE ) { ludp->lud_scope = LDAP_SCOPE_DEFAULT; } ber_str2bv( ludp->lud_dn, 0, 0, &olddn ); dn = olddn; if ( pa_nvals ) { ndn = olddn; rc = rwm_dn_massage_pretty_normalize( &dc, &olddn, &dn, &ndn ); } else { rc = rwm_dn_massage_pretty( &dc, &olddn, &dn ); } switch ( rc ) { case LDAP_UNWILLING_TO_PERFORM: /* * FIXME: need to check if it may be considered * legal to trim values when adding/modifying; * it should be when searching (e.g. ACLs). */ ch_free( a_vals[i].bv_val ); if (last > i ) { a_vals[i] = a_vals[last]; if ( pa_nvals ) { (*pa_nvals)[i] = (*pa_nvals)[last]; } } BER_BVZERO( &a_vals[last] ); if ( pa_nvals ) { BER_BVZERO( &(*pa_nvals)[last] ); } last--; break; case LDAP_SUCCESS: if ( !BER_BVISNULL( &dn ) && dn.bv_val != olddn.bv_val ) { char *newurl; ludp->lud_dn = dn.bv_val; newurl = ldap_url_desc2str( ludp ); ludp->lud_dn = olddn.bv_val; ch_free( dn.bv_val ); if ( newurl == NULL ) { /* FIXME: leave attr untouched * even if ldap_url_desc2str failed... */ break; } ber_str2bv( newurl, 0, 1, &a_vals[i] ); ber_memfree( newurl ); if ( pa_nvals ) { ludp->lud_dn = ndn.bv_val; newurl = ldap_url_desc2str( ludp ); ludp->lud_dn = olddn.bv_val; ch_free( ndn.bv_val ); if ( newurl == NULL ) { /* FIXME: leave attr untouched * even if ldap_url_desc2str failed... */ ch_free( a_vals[i].bv_val ); a_vals[i] = oldval; break; } if ( !BER_BVISNULL( &(*pa_nvals)[i] ) ) { ch_free( (*pa_nvals)[i].bv_val ); } ber_str2bv( newurl, 0, 1, &(*pa_nvals)[i] ); ber_memfree( newurl ); } ch_free( oldval.bv_val ); ludp->lud_dn = olddn.bv_val; } break; default: /* leave attr untouched if massage failed */ if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) { ber_dupbv( &(*pa_nvals)[i], &a_vals[i] ); } break; } ldap_free_urldesc( ludp ); } return 0; }
int OPENLDAP::BookFormInfo (Ekiga::Form &result, struct BookInfo &bookinfo, std::string &errmsg) { LDAPURLDesc *url_base = NULL, *url_host = NULL; char *url_str; std::string name = result.text ("name"); std::string uri = result.text ("uri"); std::string nameAttr = result.text ("nameAttr"); std::string callAttr = result.text ("callAttr"); std::string filter = result.text ("filter"); errmsg = ""; if (name.empty()) errmsg += _("Please provide a Book Name for this directory\n"); if (uri.empty()) errmsg += _("Please provide a Server URI\n"); if (nameAttr.empty()) errmsg += _("Please provide a DisplayName attribute\n"); if (callAttr.empty()) errmsg += _("Please provide a Call attribute\n"); if (ldap_url_parse (uri.c_str(), &url_host)) errmsg += _("Invalid Server URI\n"); if (!errmsg.empty()) { return -1; } if (filter.empty()) filter = "(cn=$)"; bookinfo.name = name; std::string base = result.text ("base"); std::string new_bits = "ldap:///?" + result.text ("nameAttr") + "," + result.text ("callAttr") + "?" + result.single_choice ("scope") + "?" + result.text ("filter"); bookinfo.authcID = result.text ("authcID"); bookinfo.password = result.text ("password"); bookinfo.starttls = result.boolean ("startTLS"); bookinfo.sasl = result.boolean ("sasl"); bookinfo.saslMech = result.single_choice ("saslMech"); if (bookinfo.sasl || bookinfo.starttls) { new_bits += "?"; if (bookinfo.starttls) new_bits += "StartTLS"; if (bookinfo.sasl) { if (bookinfo.starttls) new_bits += ","; new_bits += "SASL"; if (!bookinfo.saslMech.empty()) new_bits += "=" + bookinfo.saslMech; } } if (ldap_url_parse (new_bits.c_str(), &url_base)) errmsg += _("Invalid Server URI\n"); if (!errmsg.empty()) { return -1; } url_host->lud_dn = ldap_strdup (base.c_str()); url_host->lud_attrs = url_base->lud_attrs; url_host->lud_scope = url_base->lud_scope; url_host->lud_filter = url_base->lud_filter; if (!url_host->lud_exts) { url_host->lud_exts = url_base->lud_exts; url_base->lud_exts = NULL; } url_base->lud_attrs = NULL; url_base->lud_filter = NULL; ldap_free_urldesc (url_base); bookinfo.urld = boost::shared_ptr<LDAPURLDesc> (url_host, ldap_url_desc_deleter ()); url_str = ldap_url_desc2str (url_host); bookinfo.uri = std::string(url_str); ldap_memfree (url_str); { size_t pos; pos = bookinfo.uri.find ('/', strlen(url_host->lud_scheme) + 3); if (pos != std::string::npos) bookinfo.uri_host = bookinfo.uri.substr (0,pos); else bookinfo.uri_host = bookinfo.uri; } return 0; }
int rwm_referral_result_rewrite( dncookie *dc, BerVarray a_vals ) { int i, last; for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ ); last--; for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) { struct berval dn, olddn = BER_BVNULL; int rc; LDAPURLDesc *ludp; rc = ldap_url_parse( a_vals[i].bv_val, &ludp ); if ( rc != LDAP_URL_SUCCESS ) { /* leave attr untouched if massage failed */ continue; } /* FIXME: URLs like "ldap:///dc=suffix" if passed * thru ldap_url_parse() and ldap_url_desc2str() * get rewritten as "ldap:///dc=suffix??base"; * we don't want this to occur... */ if ( ludp->lud_scope == LDAP_SCOPE_BASE ) { ludp->lud_scope = LDAP_SCOPE_DEFAULT; } ber_str2bv( ludp->lud_dn, 0, 0, &olddn ); dn = olddn; rc = rwm_dn_massage_pretty( dc, &olddn, &dn ); switch ( rc ) { case LDAP_UNWILLING_TO_PERFORM: /* * FIXME: need to check if it may be considered * legal to trim values when adding/modifying; * it should be when searching (e.g. ACLs). */ ch_free( a_vals[i].bv_val ); if ( last > i ) { a_vals[i] = a_vals[last]; } BER_BVZERO( &a_vals[last] ); last--; i--; break; default: /* leave attr untouched if massage failed */ if ( !BER_BVISNULL( &dn ) && olddn.bv_val != dn.bv_val ) { char *newurl; ludp->lud_dn = dn.bv_val; newurl = ldap_url_desc2str( ludp ); if ( newurl == NULL ) { /* FIXME: leave attr untouched * even if ldap_url_desc2str failed... */ break; } ch_free( a_vals[i].bv_val ); ber_str2bv( newurl, 0, 1, &a_vals[i] ); ber_memfree( newurl ); ludp->lud_dn = olddn.bv_val; } break; } ldap_free_urldesc( ludp ); } return 0; }
/* * call from within ldap_back_db_open() */ int ldap_back_monitor_db_open( BackendDB *be ) { ldapinfo_t *li = (ldapinfo_t *) be->be_private; char buf[ BACKMONITOR_BUFSIZE ]; Entry *e = NULL; monitor_callback_t *cb = NULL; struct berval suffix, *filter, *base; char *ptr; time_t now; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; struct berval timestamp; int rc = 0; BackendInfo *mi; monitor_extra_t *mbe; if ( !SLAP_DBMONITORING( be ) ) { return 0; } /* check if monitor is configured and usable */ mi = backend_info( "monitor" ); if ( !mi || !mi->bi_extra ) { SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING; return 0; } mbe = mi->bi_extra; /* don't bother if monitor is not configured */ if ( !mbe->is_configured() ) { static int warning = 0; if ( warning++ == 0 ) { Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: " "monitoring disabled; " "configure monitor database to enable\n", 0, 0, 0 ); } return 0; } /* set up the fake subsystem that is used to create * the volatile connection entries */ li->li_monitor_info.lmi_mss.mss_name = "back-ldap"; li->li_monitor_info.lmi_mss.mss_flags = MONITOR_F_VOLATILE_CH; li->li_monitor_info.lmi_mss.mss_create = ldap_back_monitor_conn_create; li->li_monitor_info.lmi_li = li; li->li_monitor_info.lmi_scope = LDAP_SCOPE_SUBORDINATE; base = &li->li_monitor_info.lmi_base; BER_BVSTR( base, "cn=databases,cn=monitor" ); filter = &li->li_monitor_info.lmi_filter; BER_BVZERO( filter ); suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] ); if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) { suffix = be->be_nsuffix[ 0 ]; } else { ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix ); } filter->bv_len = STRLENOF( "(&" ) + li->li_monitor_info.lmi_more_filter.bv_len + STRLENOF( "(monitoredInfo=" ) + strlen( be->bd_info->bi_type ) + STRLENOF( ")(!(monitorOverlay=" ) + strlen( be->bd_info->bi_type ) + STRLENOF( "))(namingContexts:distinguishedNameMatch:=" ) + suffix.bv_len + STRLENOF( "))" ); ptr = filter->bv_val = ch_malloc( filter->bv_len + 1 ); ptr = lutil_strcopy( ptr, "(&" ); ptr = lutil_strncopy( ptr, li->li_monitor_info.lmi_more_filter.bv_val, li->li_monitor_info.lmi_more_filter.bv_len ); ptr = lutil_strcopy( ptr, "(monitoredInfo=" ); ptr = lutil_strcopy( ptr, be->bd_info->bi_type ); ptr = lutil_strcopy( ptr, ")(!(monitorOverlay=" ); ptr = lutil_strcopy( ptr, be->bd_info->bi_type ); ptr = lutil_strcopy( ptr, "))(namingContexts:distinguishedNameMatch:=" ); ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len ); ptr = lutil_strcopy( ptr, "))" ); ptr[ 0 ] = '\0'; assert( ptr == &filter->bv_val[ filter->bv_len ] ); if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) { ch_free( suffix.bv_val ); } now = slap_get_time(); timestamp.bv_val = timebuf; timestamp.bv_len = sizeof( timebuf ); slap_timestamp( &now, ×tamp ); /* caller (e.g. an overlay based on back-ldap) may want to use * a different RDN... */ if ( BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) ) { ber_str2bv( "cn=Connections", 0, 1, &li->li_monitor_info.lmi_rdn ); } ptr = ber_bvchr( &li->li_monitor_info.lmi_rdn, '=' ); assert( ptr != NULL ); ptr[ 0 ] = '\0'; ptr++; snprintf( buf, sizeof( buf ), "dn: %s=%s\n" "objectClass: monitorContainer\n" "%s: %s\n" "creatorsName: %s\n" "createTimestamp: %s\n" "modifiersName: %s\n" "modifyTimestamp: %s\n", li->li_monitor_info.lmi_rdn.bv_val, ptr, li->li_monitor_info.lmi_rdn.bv_val, ptr, BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val, timestamp.bv_val, BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val, timestamp.bv_val ); e = str2entry( buf ); if ( e == NULL ) { rc = -1; goto cleanup; } ptr[ -1 ] = '='; /* add labeledURI and special, modifiable URI value */ if ( li->li_uri != NULL ) { struct berval bv; LDAPURLDesc *ludlist = NULL; int rc; rc = ldap_url_parselist_ext( &ludlist, li->li_uri, NULL, LDAP_PVT_URL_PARSE_NOEMPTY_HOST | LDAP_PVT_URL_PARSE_DEF_PORT ); if ( rc != LDAP_URL_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: " "unable to parse URI list (ignored)\n", 0, 0, 0 ); } else { for ( ; ludlist != NULL; ) { LDAPURLDesc *next = ludlist->lud_next; bv.bv_val = ldap_url_desc2str( ludlist ); assert( bv.bv_val != NULL ); ldap_free_urldesc( ludlist ); bv.bv_len = strlen( bv.bv_val ); attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI, &bv, NULL ); ch_free( bv.bv_val ); ludlist = next; } } ber_str2bv( li->li_uri, 0, 0, &bv ); attr_merge_normalize_one( e, ad_olmDbURIList, &bv, NULL ); } ber_dupbv( &li->li_monitor_info.lmi_nrdn, &e->e_nname ); cb = ch_calloc( sizeof( monitor_callback_t ), 1 ); cb->mc_update = ldap_back_monitor_update; cb->mc_modify = ldap_back_monitor_modify; cb->mc_free = ldap_back_monitor_free; cb->mc_private = (void *)li; rc = mbe->register_entry_parent( e, cb, (monitor_subsys_t *)&li->li_monitor_info, MONITOR_F_VOLATILE_CH, base, LDAP_SCOPE_SUBORDINATE, filter ); cleanup:; if ( rc != 0 ) { if ( cb != NULL ) { ch_free( cb ); cb = NULL; } if ( e != NULL ) { entry_free( e ); e = NULL; } if ( !BER_BVISNULL( filter ) ) { ch_free( filter->bv_val ); BER_BVZERO( filter ); } } /* store for cleanup */ li->li_monitor_info.lmi_cb = (void *)cb; if ( e != NULL ) { entry_free( e ); } return rc; }
BerVarray referral_rewrite( BerVarray in, struct berval *base, struct berval *target, int scope ) { int i; BerVarray refs; struct berval *iv, *jv; if( in == NULL ) return NULL; for( i=0; in[i].bv_val != NULL ; i++ ) { /* just count them */ } if( i < 1 ) return NULL; refs = SLAP_MALLOC( (i+1) * sizeof( struct berval ) ); if( refs == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "referral_rewrite: SLAP_MALLOC failed\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "referral_rewrite: SLAP_MALLOC failed\n", 0, 0, 0 ); #endif return NULL; } for( iv=in,jv=refs; iv->bv_val != NULL ; iv++ ) { LDAPURLDesc *url; int rc = ldap_url_parse_ext( iv->bv_val, &url ); if( rc == LDAP_URL_ERR_BADSCHEME ) { ber_dupbv( jv++, iv ); continue; } else if( rc != LDAP_URL_SUCCESS ) { continue; } { char *dn = url->lud_dn; url->lud_dn = referral_dn_muck( ( dn && *dn ) ? dn : NULL, base, target ); ldap_memfree( dn ); } if( url->lud_scope == LDAP_SCOPE_DEFAULT ) { url->lud_scope = scope; } jv->bv_val = ldap_url_desc2str( url ); jv->bv_len = strlen( jv->bv_val ); ldap_free_urldesc( url ); jv++; } if( jv == refs ) { ch_free( refs ); refs = NULL; } else { jv->bv_val = NULL; } return refs; }
char* ldap_lookup(config_t agent_config, const char *username, char *external_uid) { LDAP *ld; LDAPMessage *result = (LDAPMessage *) 0; LDAPMessage *e; BerElement *ber; char *a, *dn; char *sane_username = malloc(strlen(username)*2); char *p = sane_username; char **vals = NULL; struct timeval ldaptimeout = {.tv_sec = BIND_TIMEOUT, .tv_usec = 0}; int i, rc=0, num_entries=0; char *transcoded_query = NULL; char *ldap_uri = NULL; char *end_ptr; char *ldap_host = _ds_read_attribute(agent_config, "ExtLookupServer"); char *port = _ds_read_attribute(agent_config, "ExtLookupPort"); long lldap_port; int ldap_port = 389; char *ldap_binddn = _ds_read_attribute(agent_config, "ExtLookupLogin"); char *ldap_passwd = _ds_read_attribute(agent_config, "ExtLookupPassword"); char *ldap_base = _ds_read_attribute(agent_config, "ExtLookupDB"); char *ldap_attrs[] = {_ds_read_attribute(agent_config, "ExtLookupLDAPAttribute"),0}; char *version = _ds_read_attribute(agent_config, "ExtLookupLDAPVersion"); long lldap_version; int ldap_version = 3; char *ldap_filter = _ds_read_attribute(agent_config, "ExtLookupQuery"); int ldap_scope; if (port != NULL) { errno=0; lldap_port = strtol(port, &end_ptr, 0); if ( (errno != 0) || (lldap_port < INT_MIN) || (lldap_port > INT_MAX) || (*end_ptr != '\0')) { LOG(LOG_ERR, "External Lookup: bad LDAP port number"); return NULL; } else ldap_port = (int)lldap_port; } /* set ldap protocol version */ if (version != NULL) { errno=0; lldap_version = strtol(version, &end_ptr, 0); if ((errno != 0) || (lldap_version < 1) || (lldap_version > 3) || (*end_ptr != '\0')) { LOG(LOG_ERR, "External Lookup: bad LDAP protocol version"); return NULL; } else ldap_version = (int)lldap_version; } if (_ds_match_attribute(agent_config, "ExtLookupLDAPScope", "one")) ldap_scope = LDAP_SCOPE_ONELEVEL; else /* defaults to sub */ ldap_scope = LDAP_SCOPE_SUBTREE; /* set alarm handler */ signal(SIGALRM, sig_alrm); /* sanitize username for filter integration */ for (; *username != '\0'; username++) { switch(*username) { case 0x2a: /* '*' */ case 0x28: /* '(' */ case 0x29: /* ')' */ case 0x5c: /* '\' */ case 0x00: /* NUL */ *p++ = 0x5c; /* '\' */ *p++ = *username; break; default: *p++ = *username; break; } } *p = '\0'; LOGDEBUG("External Lookup: sanitized username is %s\n", sane_username); /* build proper LDAP filter*/ transcoded_query = strdup(transcode_query(ldap_filter, sane_username, transcoded_query)); free(sane_username); if (transcoded_query == NULL) { LOG(LOG_ERR, "External Lookup: %s", ERR_EXT_LOOKUP_MISCONFIGURED); return NULL; } if( ldap_host != NULL || ldap_port ) { /* construct URL */ LDAPURLDesc url; memset( &url, 0, sizeof(url)); url.lud_scheme = "ldap"; url.lud_host = ldap_host; url.lud_port = ldap_port; url.lud_scope = LDAP_SCOPE_SUBTREE; ldap_uri = ldap_url_desc2str( &url ); } rc = ldap_initialize( &ld, ldap_uri ); if( rc != LDAP_SUCCESS ) { LOG(LOG_ERR, "External Lookup: Could not create LDAP session handle for URI=%s (%d): %s\n", ldap_uri, rc, ldap_err2string(rc)); return NULL; } if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version ) != LDAP_OPT_SUCCESS ) { LOG(LOG_ERR, "External Lookup: Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", ldap_version ); return NULL; } /* use TLS if configured */ if ( _ds_match_attribute(agent_config, "ExtLookupCrypto", "tls" )) { if (ldap_version != 3) { LOG(LOG_ERR, "External Lookup: TLS only supported with LDAP protocol version 3"); return NULL; } if ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { LOG(LOG_ERR, "External Lookup: %s: %s (%d)", ERR_EXT_LOOKUP_INIT_FAIL, strerror(errno), errno); return NULL; } } /* schedules alarm */ alarm(BIND_TIMEOUT); /* authenticate to the directory */ if ( (rc = ldap_simple_bind_s( ld, ldap_binddn, ldap_passwd )) != LDAP_SUCCESS ) { /* cancel alarms */ alarm(0); LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_INIT_FAIL, ldap_err2string(rc) ); ldap_unbind(ld); return NULL; } /* cancel alarms */ alarm(0); /* search for all entries matching the filter */ if ( (rc = ldap_search_st( ld, ldap_base, ldap_scope, transcoded_query, ldap_attrs, 0, &ldaptimeout, &result )) != LDAP_SUCCESS ) { free(transcoded_query); switch(rc) { case LDAP_TIMEOUT: case LDAP_BUSY: case LDAP_UNAVAILABLE: case LDAP_UNWILLING_TO_PERFORM: case LDAP_SERVER_DOWN: case LDAP_TIMELIMIT_EXCEEDED: LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) ); ldap_unbind( ld ); return NULL; break; case LDAP_FILTER_ERROR: LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) ); ldap_unbind( ld ); return NULL; break; case LDAP_SIZELIMIT_EXCEEDED: if ( result == NULL ) { LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) ); ldap_unbind( ld ); return NULL; } break; default: LOG(LOG_ERR, "External Lookup: %s: code=%d, %s", ERR_EXT_LOOKUP_SEARCH_FAIL, rc, ldap_err2string(ldap_result2error(ld, result, 1)) ); ldap_unbind( ld ); return NULL; } } num_entries=ldap_count_entries(ld,result); LOGDEBUG("External Lookup: found %d LDAP entries", num_entries); switch (num_entries) { case 1: /* only one entry, let's proceed */ break; case -1: /* an error occured */ LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1))); ldap_unbind( ld ); return NULL ; case 0: /* no entries found */ LOGDEBUG("External Lookup: %s: no entries found.", ERR_EXT_LOOKUP_SEARCH_FAIL); ldap_msgfree( result ); ldap_unbind( ld ); return NULL ; default: /* more than one entry returned */ LOG(LOG_ERR, "External Lookup: %s: more than one entry returned.", ERR_EXT_LOOKUP_SEARCH_FAIL); ldap_msgfree( result ); ldap_unbind( ld ); return NULL; } /* for each entry print out name + all attrs and values */ for ( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) { if ( (dn = ldap_get_dn( ld, e )) != NULL ) { ldap_memfree( dn ); } for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL; a = ldap_next_attribute( ld, e, ber ) ) { if ((vals = ldap_get_values( ld, e, a)) != NULL ) { for ( i = 0; vals[i] != NULL; i++ ) { external_uid = strdup(vals[i]); } ldap_value_free( vals ); } ldap_memfree( a ); } if ( ber != NULL ) { ber_free( ber, 0 ); } } ldap_msgfree( result ); ldap_unbind( ld ); return external_uid; } #endif char* program_lookup(config_t agent_config, const char *username, char *external_uid) { pid_t wstatus, pid; int i, status; int fd[2]; char *output = malloc (1024); char **args = malloc (1024); char *token; char *saveptr; char *str; char *command_line = 0; /* build proper command line*/ command_line = strdup(transcode_query(_ds_read_attribute(agent_config, "ExtLookupServer"), username, command_line)); if (command_line == NULL) { LOG(LOG_ERR, ERR_EXT_LOOKUP_MISCONFIGURED); free(output); free(args); return NULL; } LOGDEBUG("command line is %s", command_line); /* break the command line into arguments */ for (i = 0, str = command_line; ; i++, str = NULL) { token = strtok_r(str, " ", &saveptr); if (token == NULL) break; args[i] = token; LOGDEBUG("args[%d] = %s",i,token); } args[i] = (char *) 0; if (pipe(fd) == -1) { LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno)); free(output); free(args); return NULL; } switch(pid=fork()) { case -1: /* couldn't fork - something went wrong */ LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno)); free(output); free(args); return NULL; case 0: /* execute the command and write to fd */ close(fd[0]); dup2(fd[1], fileno(stdout)); execve(args[0], args, 0); exit(EXIT_FAILURE); default: /* read from fd the first output line */ do { wstatus = waitpid( pid, &status, WUNTRACED | WCONTINUED); if (wstatus == -1) { LOGDEBUG("waitpid() exited with an error: %s: errno=%i", strerror(errno), errno); free(output); free(args); return NULL; } if (WIFEXITED(status)) { LOGDEBUG("exited, status=%d\n", WEXITSTATUS(status)); if (WEXITSTATUS(status)) { LOGDEBUG("Error running %s. Check path and permissions.\n", args[0]); } } else if (WIFSIGNALED(status)) { LOGDEBUG("killed by signal %d\n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { LOGDEBUG("stopped by signal %d\n", WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { LOGDEBUG("continued\n"); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); close(fd[1]); /* just in case there's no line break at the end of the return... */ memset(output, 0, 1024); if (read(fd[0], output, 1024) == -1) { LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno)); free(output); free(args); return NULL; } close(fd[0]); } if (strlen(output) == 0) { free(output); free(args); return NULL; } /* terminate the output string at the first \n */ token = strchr(output, '\n'); if (token != NULL) *token = '\0'; external_uid = strdup(output); free(output); free(command_line); free(args); return external_uid; }
static ldaphost* ldaphost_new(const char *url) { ldaphost *p; int ret; p = OPENSSL_malloc(sizeof(ldaphost)); if (p == NULL) return(NULL); memset(p, 0, sizeof(ldaphost)); p->url = OPENSSL_malloc(strlen(url) + 1); if (p->url == NULL) goto error; strcpy(p->url, url); /*ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]] */ ret = ldap_is_ldap_url(url); if (ret < 0) { X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_NOT_LDAP_URL); goto error; } ret = ldap_url_parse(p->url, &p->ldapurl); if (ret != 0) { X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INVALID_URL); openssl_add_ldap_error(ret); goto error; } #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldap_url_desc2str=%s\n", ldap_url_desc2str(p->ldapurl)); fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldapurl->%s://%s:%d\n", p->ldapurl->lud_scheme, p->ldapurl->lud_host, p->ldapurl->lud_port); #endif /* open ldap connection */ #ifdef HAVE_LDAP_INITIALIZE ret = ldap_initialize(&p->ld, p->url); if (ret != LDAP_SUCCESS) { X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INITIALIZATION_ERROR); openssl_add_ldap_error(ret); goto error; } #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: ldap_initialize(..., url=%s)\n", p->url); #endif #else /*ndef HAVE_LDAP_INITIALIZE*/ p->ld = ldap_init(p->ldapurl->lud_host, p->ldapurl->lud_port); if(p->ld == NULL) { X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_INITIALIZATION_ERROR); goto error; } #endif /*ndef HAVE_LDAP_INITIALIZE*/ { int version = -1; ret = ldap_get_option(p->ld, LDAP_OPT_PROTOCOL_VERSION, &version); if (ret != LDAP_OPT_SUCCESS) { X509byLDAPerr(X509byLDAP_F_LDAPHOST_NEW, X509byLDAP_R_UNABLE_TO_GET_PROTOCOL_VERSION ); goto error; } #ifdef TRACE_BY_LDAP fprintf(stderr, "TRACE_BY_LDAP ldaphost_new: using ldap v%d protocol\n", version); #endif } return(p); error: ldaphost_free(p); return(NULL); }