From 693a81e1db572ee6480fa9b29d5fc095b8e49483 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 2 Oct 2001 01:02:23 +0000 Subject: [PATCH] More CLDAP tweaks, to differentiate between real LDAPv2 CLDAP and "other" LDAP/UDP messages. Slapd marks received CLDAP messages as LDAP_VERSION2. The client library can generate CLDAP queries if -Protocol 2 is chosen, otherwise not. LDAPv2 CLDAP cannot query the slapd rootDSE, gets no reply. --- libraries/libldap/abandon.c | 15 +++++++------- libraries/libldap/result.c | 2 +- libraries/libldap/sasl.c | 6 ++++++ libraries/libldap/search.c | 18 ++++++++-------- libraries/libldap/url.c | 4 ++++ servers/slapd/connection.c | 41 +++++++++++++++++++++---------------- servers/slapd/daemon.c | 3 +-- servers/slapd/result.c | 8 ++++++-- servers/slapd/search.c | 6 ++++++ 9 files changed, 64 insertions(+), 39 deletions(-) diff --git a/libraries/libldap/abandon.c b/libraries/libldap/abandon.c index 0bcae1ff95..80dadc325b 100644 --- a/libraries/libldap/abandon.c +++ b/libraries/libldap/abandon.c @@ -151,13 +151,14 @@ do_abandon( if ( LDAP_IS_UDP(ld) ) { err = ber_write( ber, ld->ld_options.ldo_peer, sizeof(struct sockaddr), 0); - if (err == sizeof(struct sockaddr)) { - char *dn = ld->ld_options.ldo_cldapdn; - if (!dn) dn = ""; - err = ber_printf( ber, "{isti", /* '}' */ - ++ld->ld_msgid, dn, - LDAP_REQ_ABANDON, msgid ); - } + } + if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == + LDAP_VERSION2) { + char *dn = ld->ld_options.ldo_cldapdn; + if (!dn) dn = ""; + err = ber_printf( ber, "{isti", /* '}' */ + ++ld->ld_msgid, dn, + LDAP_REQ_ABANDON, msgid ); } else #endif { diff --git a/libraries/libldap/result.c b/libraries/libldap/result.c index eb52071ae0..6dffb0b192 100644 --- a/libraries/libldap/result.c +++ b/libraries/libldap/result.c @@ -426,7 +426,7 @@ try_read1msg( return( -2 ); /* continue looking */ } #ifdef LDAP_CONNECTIONLESS - if (LDAP_IS_UDP(ld)) { + if (LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) { char *blank; ber_scanf(ber, "a{", &blank); if (blank) diff --git a/libraries/libldap/sasl.c b/libraries/libldap/sasl.c index a435b2b2d1..a3630e9781 100644 --- a/libraries/libldap/sasl.c +++ b/libraries/libldap/sasl.c @@ -186,6 +186,12 @@ ldap_sasl_bind_s( return( rc ); } +#ifdef LDAP_CONNECTIONLESS + if (LDAP_IS_UDP(ld)) { + return( rc ); + } +#endif + if ( ldap_result( ld, msgid, 1, NULL, &result ) == -1 ) { return( ld->ld_errno ); /* ldap_result sets ld_errno */ } diff --git a/libraries/libldap/search.c b/libraries/libldap/search.c index cfcfd8cf30..50f50067ff 100644 --- a/libraries/libldap/search.c +++ b/libraries/libldap/search.c @@ -301,15 +301,15 @@ ldap_build_search_req( if ( LDAP_IS_UDP(ld) ) { err = ber_write( ber, ld->ld_options.ldo_peer, sizeof(struct sockaddr), 0); - if (err == sizeof(struct sockaddr)) { - char *dn = ld->ld_options.ldo_cldapdn; - if (!dn) dn = ""; - err = ber_printf( ber, "{ist{seeiib", ++ld->ld_msgid, dn, - LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref, - (sizelimit < 0) ? ld->ld_sizelimit : sizelimit, - (timelimit < 0) ? ld->ld_timelimit : timelimit, - attrsonly ); - } + } + if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) { + char *dn = ld->ld_options.ldo_cldapdn; + if (!dn) dn = ""; + err = ber_printf( ber, "{ist{seeiib", ++ld->ld_msgid, dn, + LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref, + (sizelimit < 0) ? ld->ld_sizelimit : sizelimit, + (timelimit < 0) ? ld->ld_timelimit : timelimit, + attrsonly ); } else #endif { diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c index c58ba59f7f..48b8f7b30d 100644 --- a/libraries/libldap/url.c +++ b/libraries/libldap/url.c @@ -766,6 +766,10 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) if ((*ludpp)->lud_port == 0) { if( strcmp((*ludpp)->lud_scheme, "ldap") == 0 ) { (*ludpp)->lud_port = LDAP_PORT; +#ifdef LDAP_CONNECTIONLESS + } else if( strcmp((*ludpp)->lud_scheme, "cldap") == 0 ) { + (*ludpp)->lud_port = LDAP_PORT; +#endif } else if( strcmp((*ludpp)->lud_scheme, "ldaps") == 0 ) { (*ludpp)->lud_port = LDAPS_PORT; } diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 31c8b976fd..dd58fd82c3 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -479,7 +479,6 @@ long connection_init( if (tls_udp_option == 2) { c->c_is_udp = 1; - c->c_protocol = LDAP_VERSION2; #ifdef LDAP_DEBUG ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_PROVIDER, (void*)"udp_" ); @@ -1200,6 +1199,8 @@ connection_input( char peername[sizeof("IP=255.255.255.255:65336")]; len = ber_int_sb_read(conn->c_sb, &peeraddr, sizeof(struct sockaddr)); + if (len != sizeof(struct sockaddr)) + return 1; sprintf( peername, "IP=%s:%d", inet_ntoa( peeraddr.sa_in_addr.sin_addr ), (unsigned) ntohs( peeraddr.sa_in_addr.sin_port ) ); @@ -1251,11 +1252,6 @@ connection_input( ber_free( ber, 1 ); return -1; } -#ifdef LDAP_CONNECTIONLESS - if (conn->c_is_udp) { - tag = ber_get_stringa( ber, &cdn ); - } -#endif if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) { /* log, close and send error */ @@ -1273,19 +1269,23 @@ connection_input( } #ifdef LDAP_CONNECTIONLESS - if (conn->c_is_udp && (tag != LDAP_REQ_ABANDON && - tag != LDAP_REQ_SEARCH)) - { + if (conn->c_is_udp) { + if (tag == LBER_OCTETSTRING) { + ber_get_stringa( ber, &cdn ); + tag = ber_peek_tag(ber, &len); + } + if (tag != LDAP_REQ_ABANDON && tag != LDAP_REQ_SEARCH) { #ifdef NEW_LOGGING - LDAP_LOG(( "connection", LDAP_LEVEL_ERR, - "connection_input: conn %d invalid req for UDP 0x%lx.\n", - conn->c_connid, tag )); + LDAP_LOG(( "connection", LDAP_LEVEL_ERR, + "connection_input: conn %d invalid req for UDP 0x%lx.\n", + conn->c_connid, tag )); #else - Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, - 0 ); + Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, + 0 ); #endif - ber_free( ber, 1 ); - return 0; + ber_free( ber, 1 ); + return 0; + } } #endif if(tag == LDAP_REQ_BIND) { @@ -1297,7 +1297,10 @@ connection_input( #ifdef LDAP_CONNECTIONLESS op->o_peeraddr = peeraddr; - op->o_dn = cdn; + if (cdn) { + op->o_dn = cdn; + op->o_protocol = LDAP_VERSION2; + } #endif if ( conn->c_conn_state == SLAP_C_BINDING || conn->c_conn_state == SLAP_C_CLOSING ) @@ -1436,8 +1439,10 @@ static int connection_op_activate( Connection *conn, Operation *op ) arg->co_op->o_authmech = conn->c_authmech != NULL ? ch_strdup( conn->c_authmech ) : NULL; - arg->co_op->o_protocol = conn->c_protocol + if (!arg->co_op->o_protocol) { + arg->co_op->o_protocol = conn->c_protocol ? conn->c_protocol : LDAP_VERSION3; + } arg->co_op->o_connid = conn->c_connid; slap_op_add( &conn->c_ops, arg->co_op ); diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index f2455f7982..72fc0b2706 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -571,8 +571,7 @@ static Listener * slap_open_listener( #endif } else { #ifdef LDAP_CONNECTIONLESS - if ( tmp == LDAP_PROTO_UDP ) - l.sl_is_udp = 1; + l.sl_is_udp = ( tmp == LDAP_PROTO_UDP ); #endif if( lud->lud_host == NULL || lud->lud_host[0] == '\0' || strcmp(lud->lud_host, "*") == 0 ) diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 04ee590938..5d1f4c205c 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -323,6 +323,8 @@ send_ldap_response( ber_free(ber, 1); return; } + } + if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) { rc = ber_printf( ber, "{is{t{ess", msgid, "", tag, err, matched == NULL ? "" : matched, @@ -365,7 +367,7 @@ send_ldap_response( rc = ber_printf( ber, "N}N}" ); } #ifdef LDAP_CONNECTIONLESS - if( conn->c_is_udp && rc != -1 ) { + if( conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1 ) { rc = ber_printf( ber, "N}" ); } #endif @@ -772,6 +774,8 @@ send_search_entry( ber_free(ber, 1); return; } + } + if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) { rc = ber_printf( ber, "{is{t{s{", op->o_msgid, "", LDAP_RES_SEARCH_ENTRY, e->e_dn ); } else @@ -1022,7 +1026,7 @@ send_search_entry( rc = ber_printf( ber, /*{{{*/ "}N}N}" ); #ifdef LDAP_CONNECTIONLESS - if (conn->c_is_udp && rc != -1) + if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1) rc = ber_printf( ber, "}" ); #endif if ( rc == -1 ) { diff --git a/servers/slapd/search.c b/servers/slapd/search.c index d37d31653d..63379e60b6 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -202,6 +202,12 @@ do_search( Entry *entry = NULL; if ( strcasecmp( nbase, LDAP_ROOT_DSE ) == 0 ) { +#ifdef LDAP_CONNECTIONLESS + /* Ignore LDAPv2 CLDAP DSE queries */ + if (op->o_protocol==LDAP_VERSION2 && conn->c_is_udp) { + goto return_results; + } +#endif /* check restrictions */ rc = backend_check_restrictions( NULL, conn, op, NULL, &text ) ; if( rc != LDAP_SUCCESS ) { -- 2.39.5