From 454284f1eae31da23440f6b6606c76ebbeb8ccfe Mon Sep 17 00:00:00 2001 From: Mark Valence Date: Thu, 9 Dec 1999 22:33:22 +0000 Subject: [PATCH] Adds for Start TLS functionality on slapd and LDAP C API. --- include/ldap.h | 12 ++++++++ include/ldap_pvt.h | 2 ++ libraries/libldap/open.c | 54 +++++++++++++++++++++++---------- libraries/libldap/tls.c | 26 ++++++++++++++++ libraries/libldap/url.c | 5 ++- servers/slapd/Makefile.in | 4 +-- servers/slapd/extended.c | 41 +++++++++++++++++++++++++ servers/slapd/main.c | 4 +++ servers/slapd/module.c | 24 +++++++++++++-- servers/slapd/proto-slap.h | 13 ++++++++ servers/slapd/tools/Makefile.in | 2 +- 11 files changed, 162 insertions(+), 25 deletions(-) diff --git a/include/ldap.h b/include/ldap.h index 28dbea9bd6..072c0a5809 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -984,6 +984,18 @@ ldap_init LDAP_P(( LDAP_CONST char *host, int port )); +LIBLDAP_F( int ) +ldap_create LDAP_P(( + LDAP **ldp )); + +LIBLDAP_F( int ) +ldap_initialize LDAP_P(( + LDAP **ldp, + LDAP_CONST char *url )); + +LIBLDAP_F( int ) +ldap_start_tls LDAP_P(( + LDAP *ld )); /* * in messages.c: diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h index 95b0c98b6c..632652cd64 100644 --- a/include/ldap_pvt.h +++ b/include/ldap_pvt.h @@ -123,6 +123,8 @@ LIBLDAP_F (int) ldap_pvt_tls_connect LDAP_P(( Sockbuf *sb, void *ctx_arg )); LIBLDAP_F (int) ldap_pvt_tls_accept LDAP_P(( Sockbuf *sb, void *ctx_arg )); LIBLDAP_F (int) ldap_pvt_tls_get_option LDAP_P(( struct ldapoptions *lo, int option, void *arg )); LIBLDAP_F (int) ldap_pvt_tls_set_option LDAP_P(( struct ldapoptions *lo, int option, void *arg )); +LIBLDAP_F (int) ldap_pvt_tls_inplace LDAP_P(( Sockbuf *sb )); +LIBLDAP_F (int) ldap_pvt_tls_start LDAP_P(( Sockbuf *sb, void *ctx_arg )); LDAP_END_DECL diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c index fb2a140d5d..2d11f59f98 100644 --- a/libraries/libldap/open.c +++ b/libraries/libldap/open.c @@ -227,12 +227,40 @@ ldap_initialize( LDAP **ldp, LDAP_CONST char *url ) return LDAP_SUCCESS; } +int +ldap_start_tls ( LDAP *ld ) +{ + LDAPConn *lc; + int rc; + char *rspoid; + struct berval *rspdata; + + if (ld->ld_conns == NULL) { + rc = ldap_open_defconn( ld ); + if (rc != LDAP_SUCCESS) + return(rc); + } + + for (lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next) { + if (ldap_pvt_tls_inplace(lc->lconn_sb) != 0) + return LDAP_OPERATIONS_ERROR; + rc = ldap_extended_operation_s(ld, LDAP_EXOP_START_TLS, + NULL, NULL, NULL, &rspoid, &rspdata); + if (rc != LDAP_SUCCESS) + return rc; + rc = ldap_pvt_tls_start( lc->lconn_sb, ld->ld_options.ldo_tls_ctx ); + if (rc != LDAP_SUCCESS) + return rc; + } + return LDAP_SUCCESS; +} + int open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv, char **krbinstancep, int async ) { - int rc = -1; - int port; + int rc = -1; + int port, tls; long addr; Debug( LDAP_DEBUG_TRACE, "open_ldap_connection\n", 0, 0, 0 ); @@ -254,19 +282,13 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv, ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL ); #ifdef HAVE_TLS - if ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD - || srv->lud_ldaps != 0 ) - { - /* - * Fortunately, the lib uses blocking io... - */ - if ( ldap_pvt_tls_connect( sb, ld->ld_options.ldo_tls_ctx ) < - 0 ) { - return -1; - } - /* FIXME: hostname of server must be compared with name in - * certificate.... - */ + tls = srv->lud_ldaps; + if (tls == -1) + tls = ld->ld_options.ldo_tls_mode; + if ( tls != 0 ) { + rc = ldap_pvt_tls_start( sb, ld->ld_options.ldo_tls_ctx ); + if (rc != LDAP_SUCCESS) + return rc; } #endif if ( krbinstancep != NULL ) { @@ -277,7 +299,7 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv, *c = '\0'; } #else /* HAVE_KERBEROS */ - krbinstancep = NULL; + *krbinstancep = NULL; #endif /* HAVE_KERBEROS */ } diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c index a00ad4525f..bad5312c5c 100644 --- a/libraries/libldap/tls.c +++ b/libraries/libldap/tls.c @@ -355,6 +355,14 @@ ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg ) return 0; } +int +ldap_pvt_tls_inplace ( Sockbuf *sb ) +{ + if ( HAS_TLS( sb ) ) + return(1); + return(0); +} + const char * ldap_pvt_tls_get_peer( LDAP *ld ) { @@ -496,6 +504,24 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg ) return 0; } +int +ldap_pvt_tls_start ( Sockbuf *sb, void *ctx_arg ) +{ + /* + * Fortunately, the lib uses blocking io... + */ + if ( ldap_pvt_tls_connect( sb, ctx_arg ) < 0 ) { + return LDAP_CONNECT_ERROR; + } + + /* FIXME: hostname of server must be compared with name in + * certificate.... + */ + + return LDAP_SUCCESS; +} + + static int tls_setup( Sockbuf *sb, void *arg ) { diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c index 551892f009..3a4dcbd503 100644 --- a/libraries/libldap/url.c +++ b/libraries/libldap/url.c @@ -565,8 +565,7 @@ ldap_url_parsehosts (LDAPURLDesc **ludlist, const char *hosts ) *p++ = 0; ludp->lud_port = atoi(p); } - if (ludp->lud_port == LDAPS_PORT) - ludp->lud_ldaps = 1; /* cheat */ + ludp->lud_ldaps = -1; /* unknown (use TLS default) */ ludp->lud_next = *ludlist; *ludlist = ludp; } @@ -634,7 +633,7 @@ ldap_url_list2urls (LDAPURLDesc *ludlist) p = s; for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) { - p += sprintf(p, "ldap%s://%s", ludp->lud_ldaps ? "s" : "", ludp->lud_host); + p += sprintf(p, "ldap%s://%s", (ludp->lud_ldaps == 1) ? "s" : "", ludp->lud_host); if (ludp->lud_port != 0) p += sprintf(p, ":%d", ludp->lud_port); *p++ = '/'; diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in index bd89976e58..c2deb526bf 100644 --- a/servers/slapd/Makefile.in +++ b/servers/slapd/Makefile.in @@ -15,7 +15,7 @@ SRCS = main.c daemon.c connection.c search.c filter.c add.c charray.c \ value.c ava.c bind.c unbind.c abandon.c filterentry.c \ phonetic.c acl.c str2filter.c aclparse.c init.c user.c \ repl.c lock.c controls.c extended.c kerberos.c passwd.c \ - schema.c schemaparse.c monitor.c configinfo.c \ + schema.c schemaparse.c monitor.c configinfo.c starttls.c \ root_dse.c sasl.c module.c suffixalias.c $(@PLAT@_SRCS) OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \ @@ -24,7 +24,7 @@ OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \ value.o ava.o bind.o unbind.o abandon.o filterentry.o \ phonetic.o acl.o str2filter.o aclparse.o init.o user.o \ repl.o lock.o controls.o extended.o kerberos.o passwd.o \ - schema.o schemaparse.o monitor.o configinfo.o \ + schema.o schemaparse.o monitor.o configinfo.o starttls.o \ root_dse.o sasl.o module.o suffixalias.o $(@PLAT@_OBJS) LDAP_INCDIR= ../../include diff --git a/servers/slapd/extended.c b/servers/slapd/extended.c index dd48d4bee2..9aa6f11201 100644 --- a/servers/slapd/extended.c +++ b/servers/slapd/extended.c @@ -42,6 +42,22 @@ typedef struct extop_list_t { extop_list_t *supp_ext_list = NULL; +/* this list of built-in extops is for extops that are not part + * of backends or in external modules. essentially, this is + * just a way to get built-in extops onto the extop list without + * having a separate init routine for each built-in extop. + */ +struct { + char *oid; + SLAP_EXTOP_MAIN_FN ext_main; +} builtin_extops[] = { +#ifdef HAVE_TLS + { LDAP_EXOP_START_TLS, starttls_extop }, +#endif + { NULL, NULL } + }; + + static extop_list_t *find_extop( extop_list_t *list, char *oid ); static int extop_callback( @@ -182,6 +198,31 @@ load_extop( return(0); } +int +extops_init (void) +{ + int i; + + for (i = 0; builtin_extops[i].oid != NULL; i++) { + load_extop(builtin_extops[i].oid, builtin_extops[i].ext_main); + } + return(0); +} + +int +extops_kill (void) +{ + extop_list_t *ext; + + /* we allocated the memory, so we have to free it, too. */ + while ((ext = supp_ext_list) != NULL) { + supp_ext_list = ext->next; + if (ext->oid != NULL) + ch_free(ext->oid); + ch_free(ext); + } + return(0); +} static extop_list_t * find_extop( extop_list_t *list, char *oid ) diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 877949ed0d..6d271d7438 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -359,6 +359,8 @@ int main( int argc, char **argv ) } #endif + extops_init(); + #ifdef SLAPD_MODULES if ( module_init() != 0 ) { rc = 1; @@ -464,6 +466,8 @@ destroy: module_kill(); #endif + extops_kill(); + stop: #ifdef HAVE_NT_EVENT_LOG LogSlapdStoppedEvent( NTservice ); diff --git a/servers/slapd/module.c b/servers/slapd/module.c index 984f904948..4559be0e0c 100644 --- a/servers/slapd/module.c +++ b/servers/slapd/module.c @@ -189,7 +189,7 @@ static int module_unload (module_loaded_t *module) return 0; } -int load_null (const void *module, const char *file_name) +int load_null_module (const void *module, const char *file_name) { return 0; } @@ -201,7 +201,12 @@ load_extop_module ( const char *file_name ) { - ext_main = module_resolve(module, "ext_main"); + SLAP_EXTOP_MAIN_FN ext_main; + int (*ext_getoid)(int index, char *oid, int blen); + char *oid; + int rc; + + ext_main = (SLAP_EXTOP_MAIN_FN)module_resolve(module, "ext_main"); if (ext_main == NULL) { return(-1); } @@ -211,7 +216,20 @@ load_extop_module ( return(-1); } - return load_extop( ext_main, ext_getoid ); + oid = ch_malloc(256); + rc = (ext_getoid)(0, oid, 256); + if (rc != 0) { + ch_free(oid); + return(rc); + } + if (*oid == 0) { + free(oid); + return(-1); + } + + rc = load_extop( oid, ext_main ); + free(oid); + return rc; } #endif /* SLAPD_EXTERNAL_EXTENSIONS */ #endif /* SLAPD_MODULES */ diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 07ea38c315..3f3723fcb5 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -268,6 +268,10 @@ LIBSLAPD_F (int) load_extop LDAP_P(( const char *ext_oid, SLAP_EXTOP_MAIN_FN ext_main )); +LIBSLAPD_F (int) extops_init LDAP_P(( void )); + +LIBSLAPD_F (int) extops_kill LDAP_P(( void )); + LIBSLAPD_F (char *) get_supported_extop LDAP_P((int index)); /* @@ -449,6 +453,15 @@ LIBSLAPD_F (void) parse_at LDAP_P(( const char *fname, int lineno, char *line, c LIBSLAPD_F (void) parse_oidm LDAP_P(( const char *fname, int lineno, int argc, char **argv )); LIBSLAPD_F (char *) scherr2str LDAP_P((int code)) LDAP_GCCATTR((const)); LIBSLAPD_F (int) dscompare LDAP_P(( const char *s1, const char *s2del, char delim )); + + +/* + * starttls.c + */ + +LIBSLAPD_F (int) starttls_extop LDAP_P(( SLAP_EXTOP_CALLBACK_FN, Connection *conn, Operation *op, char * oid, struct berval * reqdata, struct berval ** rspdata, char ** text )); + + /* * str2filter.c */ diff --git a/servers/slapd/tools/Makefile.in b/servers/slapd/tools/Makefile.in index 49baf569b9..a624cafa9b 100644 --- a/servers/slapd/tools/Makefile.in +++ b/servers/slapd/tools/Makefile.in @@ -54,7 +54,7 @@ SLAPD_OBJS = ../config.o ../ch_malloc.o ../backend.o ../charray.o \ ../acl.o ../phonetic.o ../attr.o ../value.o ../entry.o \ ../dn.o ../filter.o ../str2filter.o ../ava.o ../init.o \ ../controls.o ../schemaparse.o ../kerberos.o ../passwd.o \ - ../extended.o + ../extended.o ../starttls.o SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o -- 2.39.5