From ce0995e4bb1641c2ebc5c89d6c350fedf0330064 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 19 Dec 2003 00:05:02 +0000 Subject: [PATCH] Sync with HEAD --- doc/man/man3/ldap.3 | 170 +++++++++++++---------------- doc/man/man5/slapd.conf.5 | 16 ++- servers/slapd/connection.c | 8 +- servers/slapd/daemon.c | 28 ++--- servers/slapd/overlays/Makefile.in | 8 +- servers/slapd/proto-slap.h | 7 +- servers/slapd/result.c | 5 +- servers/slapd/sasl.c | 125 +++++++++++++++++---- servers/slapd/saslauthz.c | 20 ++-- servers/slapd/sl_malloc.c | 8 +- servers/slapd/slap.h | 2 +- servers/slapd/slapd.conf | 7 +- tests/scripts/test020-proxycache | 4 +- 13 files changed, 243 insertions(+), 165 deletions(-) diff --git a/doc/man/man3/ldap.3 b/doc/man/man3/ldap.3 index 24b364f1f3..32b7a28730 100644 --- a/doc/man/man3/ldap.3 +++ b/doc/man/man3/ldap.3 @@ -14,13 +14,14 @@ OpenLDAP LDAP (libldap, -lldap) .fi .SH DESCRIPTION .LP -The Lightweight Directory Access Protocol provides access to X.500 -directory services. The services may be stand\-alone or part of -a distributed directory service. This API supports LDAP over TCP -(RFC2251), LDAP over SSL, and LDAP over IPC (UNIX domain sockets). -This API supports SASL (RFC2829) and Start TLS (RFC2830). This -API is based upon IETF C LDAP API draft specification, a work in -progress. +The Lightweight Directory Access Protocol (LDAP) (RFC 3377) provides +access to X.500 directory services. These services may be stand\-alone +or part of a distributed directory service. This client API supports +LDAP over TCP (RFC2251), LDAP over TLS/SSL, and LDAP over IPC (UNIX +domain sockets). This API supports SASL (RFC2829) and Start TLS +(RFC2830) as well as a number of protocol extensions. This API is +loosely based upon IETF/LDAPEXT C LDAP API draft specification, a (orphaned) +work in progress. .LP The OpenLDAP Software package includes a stand\-alone server in .BR slapd (8), @@ -34,17 +35,16 @@ These routines are found in the \-lldap library. .LP The basic interaction is as follows. A session handle is created using -.BR ldap_init (3) -or -.BR ldap_initialize (3). -(The .BR ldap_initialize (3) -routine is preferred, but is not part of the draft specification.) -The underlying session is established upon first use which is -commonly an LDAP bind operation. The LDAP bind operation is -performed by calling +and set the protocol version to 3 by calling +.BR ldap_set_option (3). +The underlying session is established first operation is +issued. This would generally be a Start TLS or Bind operation. +A Start TLS operation is performed by calling +.BR ldap_start_tls_s (3). +A LDAP bind operation is performed by calling .BR ldap_sasl_bind (3) -or one of its friends. Next, other operations are performed +or one of its friends. Subsequently, other operations are performed by calling one of the synchronous or asynchronous routines (e.g., .BR ldap_search_ext_s (3) or @@ -58,11 +58,38 @@ The LDAP association and underlying connection is terminated by calling .BR ldap_unbind_ext (3). Errors can be interpreted by calling .BR ldap_err2string (3). -.SH SEARCH FILTERS -Search filters to be passed to the ldap search routines are to be +.SH LDAP versions +This library supports version 3 of the Lightweight Directory Access +Protocol (LDAPv3) as defined in RFC 3377. It also supports a varient +of version 2 of LDAP as defined by U-Mich LDAP and, to some degree, +RFC 1777. Version 2 (all varients) should be viewed as obsolete. +Version 3 should be used instead. +.LP +For backwards compatibility reasons, the library defaults to version 2. +Hence, all new applications (and all actively maintained applications) +should use +.BR ldap_set_option (3) +to select version 3. The library manual pages assume version 3 +has been selected. +.SH INPUT and OUTPUT PARAMETERS +All character string input/output is expected to be/is UTF\-8 +encoded Unicode (version 3.2). +.LP +Distinguished names (DN) (and relative distinguished names (RDN) to +be passed to the LDAP routines should conform to RFC 2253. The +.BR ldap_explode_dn (3) +routines can be used to work with DNs. +.LP +Search filters to be passed to the search routines are to be constructed by hand and should conform to RFC 2254. +.LP +LDAP URL are to be passed to routines are expected to conform +to RFC 2255. +The +.BR ldap_url (3) +routines can be used to work with LDAP URLs. .SH DISPLAYING RESULTS -Results obtained from the ldap search routines can be output by hand, +Results obtained from the search routines can be output by hand, by calling .BR ldap_first_entry (3) and @@ -76,21 +103,6 @@ to step through an entry's attributes, and .BR ldap_get_values (3) to retrieve a given attribute's values. Attribute values may or may not be displayable. -.SH CONTROLS -This library supports both LDAP Version 2 and Version 3, with the Version 2 -protocol selected by default. -LDAP Version 3 operations can be extended through the use of controls. Controls -can be sent to a server or returned to the client with any LDAP message. -Extended versions of the standard routines are available for use with -controls. These routines are generally named by adding -.BR _ext -to the regular routine's name. -.SH UNIFORM RESOURCE LOCATORS (URLS) -The -.BR ldap_url (3) -routines can be used to test a URL to see if it is an LDAP URL, to parse LDAP -URLs into their component pieces, and to initiate searches directly using -an LDAP URL. .SH UTILITY ROUTINES Also provided are various utility routines. The .BR ldap_sort (3) @@ -112,71 +124,52 @@ and .BR lber\-types (3). .SH INDEX .TP 20 -.SM ldap_open(3) -open a connection to an LDAP server (deprecated, use -.BR ldap_init (3)) -.TP -.SM ldap_init(3) -initialize the LDAP library without opening a connection to a server -.TP .SM ldap_initialize(3) initialize the LDAP library without opening a connection to a server .TP .SM ldap_result(3) wait for the result from an asynchronous operation .TP -.SM ldap_abandon(3) +.SM ldap_abandon_ext(3) abandon (abort) an asynchronous operation .TP -.SM ldap_add(3) +.SM ldap_add_ext(3) asynchronously add an entry .TP -.SM ldap_add_s(3) +.SM ldap_add_ext_s(3) synchronously add an entry .TP -.SM ldap_bind(3) +.SM ldap_sasl_bind(3) asynchronously bind to the directory .TP -.SM ldap_bind_s(3) +.SM ldap_sasl_bind_s(3) synchronously bind to the directory .TP -.SM ldap_simple_bind(3) -asynchronously bind to the directory using simple authentication -.TP -.SM ldap_simple_bind_s(3) -synchronously bind to the directory using simple authentication -.TP -.SM ldap_unbind(3) +.SM ldap_unbind_ext(3) synchronously unbind from the LDAP server and close the connection .TP -.SM ldap_unbind_s(3) +.SM ldap_unbind_ext_s(3) equivalent to -.BR ldap_unbind (3) +.BR ldap_unbind_ext (3) .TP .SM ldap_memfree(3) dispose of memory allocated by LDAP routines. .TP -.SM ldap_compare(3) +.SM ldap_compare_ext(3) asynchronously compare to a directory entry .TP -.SM ldap_compare_s(3) +.SM ldap_compare_ext_s(3) synchronously compare to a directory entry .TP -.SM ldap_delete(3) +.SM ldap_delete_ext(3) asynchronously delete an entry .TP -.SM ldap_delete_s(3) +.SM ldap_delete_ext_s(3) synchronously delete an entry .TP -.SM ldap_perror(3) -print an LDAP error indication to standard error -.TP .SM ld_errno(3) LDAP error indication .TP -.SM ldap_result2error(3) -extract LDAP error indication from LDAP result -.TP .SM ldap_errlist(3) list of LDAP errors and their meanings .TP @@ -202,49 +195,34 @@ return number of entries in a search result extract the DN from an entry .TP .SM ldap_explode_dn(3) -convert a DN into its component parts +convert a DN into its component parts (deprecated) .TP .SM ldap_explode_rdn(3) -convert an RDN into its component parts -.TP -.SM ldap_get_values(3) -return an attribute's values +convert an RDN into its component parts (deprecated) .TP .SM ldap_get_values_len(3) return an attribute's values with lengths .TP -.SM ldap_value_free(3) -free memory allocated by ldap_get_values(3) -.TP .SM ldap_value_free_len(3) free memory allocated by ldap_get_values_len(3) .TP -.SM ldap_count_values(3) -return number of values -.TP .SM ldap_count_values_len(3) return number of values .TP -.SM ldap_modify(3) +.SM ldap_modify_ext(3) asynchronously modify an entry .TP -.SM ldap_modify_s(3) +.SM ldap_modify_ext_s(3) synchronously modify an entry .TP .SM ldap_mods_free(3) -free array of pointers to mod structures used by ldap_modify(3) -.TP -.SM ldap_modrdn2(3) -asynchronously modify the RDN of an entry +free array of pointers to mod structures used by ldap_modify_ext(3) .TP -.SM ldap_modrdn2_s(3) -synchronously modify the RDN of an entry +.SM ldap_rename(3) +asynchronously rename an entry .TP -.SM ldap_modrdn(3) -deprecated - use ldap_modrdn2(3) -.TP -.SM ldap_modrdn_s(3) -depreciated - use ldap_modrdn2_s(3) +.SM ldap_rename_s(3) +synchronously rename an entry .TP .SM ldap_msgfree(3) free results allocated by ldap_result(3) @@ -255,15 +233,12 @@ return the message type of a message from ldap_result(3) .SM ldap_msgid(3) return the message id of a message from ldap_result(3) .TP -.SM ldap_search(3) +.SM ldap_search_ext(3) asynchronously search the directory .TP -.SM ldap_search_s(3) +.SM ldap_search_ext_s(3) synchronously search the directory .TP -.SM ldap_search_st(3) -synchronously search the directory with timeout -.TP .SM ldap_is_ldap_url(3) check a URL string to see if it is an LDAP URL .TP @@ -288,6 +263,7 @@ is developed and maintained by The OpenLDAP Project (http://www.openldap.org/). .B OpenLDAP is derived from University of Michigan LDAP 3.3 Release. .LP -These API manual pages are based upon descriptions provided in the -IETF C LDAP API Internet Draft, a work in progress, edited by -Mark Smith. +These API manual pages are loosely based upon descriptions provided +in the IETF/LDAPEXT C LDAP API Internet Draft, a (orphaned) work +in progress. + diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index ba2c3981ab..81b99e7067 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -640,9 +640,19 @@ flag will use rules in the .I saslAuthzTo attribute of the authentication DN. The -.B both -flag will allow both of the above. The rules are simply regular expressions -specifying which DNs are allowed to perform proxy authorization. The +.B any +flag, an alias for the deprecated value of +.BR both , +will allow any of the above, whatever succeeds first (checked in +.BR to , +.B from +sequence. +The +.B all +flag requires both authorizations to succeed. +The rules are simply regular expressions specifying which DNs are allowed +to perform proxy authorization. +The .I saslAuthzFrom attribute in an entry specifies which other users are allowed to proxy login to this entry. The diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index dfd4852eb1..d2883e1fd4 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -362,7 +362,7 @@ long connection_init( const char* peername, int flags, slap_ssf_t ssf, - const char *authid ) + struct berval *authid ) { unsigned long id; Connection *c; @@ -1169,7 +1169,7 @@ int connection_client_setup( { Connection *c; - if ( connection_init( s, l, "", "", CONN_IS_CLIENT, 0, "" ) < 0 ) { + if ( connection_init( s, l, "", "", CONN_IS_CLIENT, 0, NULL ) < 0 ) { return -1; } @@ -1336,8 +1336,8 @@ int connection_read(ber_socket_t s) s, rc, c->c_connid ); #endif } - slap_sasl_external( c, c->c_tls_ssf, authid.bv_val ); - if ( authid.bv_val ) free( authid.bv_val ); + slap_sasl_external( c, c->c_tls_ssf, &authid ); + if ( authid.bv_val ) free( authid.bv_val ); } /* if success and data is ready, fall thru to data input loop */ diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index e8bab26736..b0db47f765 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -1493,7 +1493,7 @@ slapd_daemon_task( socklen_t len = sizeof(from); long id; slap_ssf_t ssf = 0; - char *authid = NULL; + struct berval authid = { 0, NULL }; #ifdef SLAPD_RLOOKUPS char hbuf[NI_MAXHOST]; #endif @@ -1501,11 +1501,12 @@ slapd_daemon_task( char *dnsname = NULL; char *peeraddr = NULL; #ifdef LDAP_PF_LOCAL - char peername[MAXPATHLEN + sizeof("PATH=")]; + char peername[MAXPATHLEN + sizeof("PATH=")]; #elif defined(LDAP_PF_INET6) - char peername[sizeof("IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")]; + char peername[sizeof( + "IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")]; #else - char peername[sizeof("IP=255.255.255.255:65336")]; + char peername[sizeof("IP=255.255.255.255:65336")]; #endif /* LDAP_PF_LOCAL */ peername[0] = '\0'; @@ -1523,10 +1524,10 @@ slapd_daemon_task( * of the slapd. */ if ( slap_listeners[l]->sl_is_udp < 2 ) { - id = connection_init( - slap_listeners[l]->sl_sd, - slap_listeners[l], "", "", - CONN_IS_UDP, ssf, authid ); + id = connection_init( + slap_listeners[l]->sl_sd, + slap_listeners[l], "", "", + CONN_IS_UDP, ssf, NULL ); slap_listeners[l]->sl_is_udp++; } continue; @@ -1669,10 +1670,11 @@ slapd_daemon_task( gid_t gid; if( getpeereid( s, &uid, &gid ) == 0 ) { - authid = ch_malloc( + authid.bv_val = ch_malloc( sizeof("uidnumber=4294967295+gidnumber=4294967295," - "cn=peercred,cn=external,cn=auth")); - sprintf(authid, "uidnumber=%d+gidnumber=%d," + "cn=peercred,cn=external,cn=auth")); + authid.bv_len = sprintf( authid.bv_val, + "uidnumber=%d+gidnumber=%d," "cn=peercred,cn=external,cn=auth", (int) uid, (int) gid); } @@ -1761,9 +1763,9 @@ slapd_daemon_task( 0, #endif ssf, - authid ); + authid.bv_val ? &authid : NULL ); - if( authid ) ch_free(authid); + if( authid.bv_val ) ch_free(authid.bv_val); if( id < 0 ) { #ifdef NEW_LOGGING diff --git a/servers/slapd/overlays/Makefile.in b/servers/slapd/overlays/Makefile.in index 1f0f1d63bd..146b67847e 100644 --- a/servers/slapd/overlays/Makefile.in +++ b/servers/slapd/overlays/Makefile.in @@ -38,10 +38,10 @@ pcache.la : pcache.lo $(@PLAT@_LINK_LIBS) $(LTLINK_MOD) -module -o $@ pcache.lo version.lo $(LINK_LIBS) install-local: $(PROGRAMS) - @-$(MKDIR) $(DESTDIR)$(moduledir) - @for i in $? ; do \ - $(LTINSTALL) $(INSTALLFLAGS) -m 755 $$i $(DESTDIR)$(moduledir);\ - done + @if test -n "$?" ; then \ + $(MKDIR) $(DESTDIR)$(moduledir); \ + $(LTINSTALL) $(INSTALLFLAGS) -m 755 $? $(DESTDIR)$(moduledir);\ + fi MKDEPFLAG = -l diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 86078658ae..4e8f412aab 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -353,7 +353,7 @@ LDAP_SLAPD_F (long) connection_init LDAP_P(( const char* peername, int use_tls, slap_ssf_t ssf, - const char *id )); + struct berval *id )); LDAP_SLAPD_F (void) connection_closing LDAP_P(( Connection *c )); LDAP_SLAPD_F (int) connection_state_closing LDAP_P(( Connection *c )); @@ -958,7 +958,7 @@ LDAP_SLAPD_F (char **) slap_sasl_mechs( Connection *c ); LDAP_SLAPD_F (int) slap_sasl_external( Connection *c, slap_ssf_t ssf, /* relative strength of external security */ - const char *authid ); /* asserted authenication id */ + struct berval *authid ); /* asserted authenication id */ LDAP_SLAPD_F (int) slap_sasl_reset( Connection *c ); LDAP_SLAPD_F (int) slap_sasl_close( Connection *c ); @@ -989,7 +989,8 @@ LDAP_SLAPD_F (int) slap_parse_user LDAP_P(( LDAP_SLAPD_F (void) slap_sasl2dn LDAP_P(( Operation *op, struct berval *saslname, - struct berval *dn )); + struct berval *dn, + int flags )); LDAP_SLAPD_F (int) slap_sasl_authorized LDAP_P(( Operation *op, struct berval *authcid, diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 2374d94b56..c8f96ec02d 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -294,6 +294,7 @@ send_ldap_response( if (op->o_callback) { slap_callback *sc = op->o_callback; + rc = SLAP_CB_CONTINUE; for ( ; op->o_callback; ) { if ( op->o_callback->sc_response ) { rc = op->o_callback->sc_response( op, rs ); @@ -304,7 +305,7 @@ send_ldap_response( op->o_callback = sc; if ( rc != SLAP_CB_CONTINUE ) goto cleanup; } - + #ifdef LDAP_CONNECTIONLESS if (op->o_conn && op->o_conn->c_is_udp) ber = op->o_res_ber; @@ -719,6 +720,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) rs->sr_type = REP_SEARCH; if (op->o_callback) { slap_callback *sc = op->o_callback; + rc = SLAP_CB_CONTINUE; for ( ; op->o_callback; ) { if ( op->o_callback->sc_response ) { rc = op->o_callback->sc_response( op, rs ); @@ -1327,6 +1329,7 @@ slap_send_search_reference( Operation *op, SlapReply *rs ) rs->sr_type = REP_SEARCHREF; if (op->o_callback) { slap_callback *sc = op->o_callback; + rc = SLAP_CB_CONTINUE; for ( ; op->o_callback; ) { if ( op->o_callback->sc_response ) { rc = op->o_callback->sc_response( op, rs ); diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index e2d91d2d22..60e9db716d 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -44,17 +44,28 @@ # define SASL_CONST # endif -static sasl_security_properties_t sasl_secprops; - #define SASL_VERSION_FULL ((SASL_VERSION_MAJOR << 16) |\ (SASL_VERSION_MINOR << 8) | SASL_VERSION_STEP) -#endif /* HAVE_CYRUS_SASL */ +static sasl_security_properties_t sasl_secprops; +#elif defined( SLAP_BUILTIN_SASL ) +/* + * built-in SASL implementation + * only supports EXTERNAL + */ +typedef struct sasl_ctx { + slap_ssf_t sc_external_ssf; + struct berval sc_external_id; +} SASL_CTX; + +#endif #include "ldap_pvt.h" #include "lber_pvt.h" #include +static struct berval ext_bv = BER_BVC( "EXTERNAL" ); + int slap_sasl_config( int cargc, char **cargv, char *line, const char *fname, int lineno ) { @@ -1098,7 +1109,8 @@ int slap_sasl_init( void ) sasl_version( NULL, &rc ); if ( ((rc >> 16) != ((SASL_VERSION_MAJOR << 8)|SASL_VERSION_MINOR)) || - (rc & 0xffff) < SASL_VERSION_STEP) { + (rc & 0xffff) < SASL_VERSION_STEP) + { char version[sizeof("xxx.xxx.xxxxx")]; sprintf( version, "%u.%d.%d", (unsigned)rc >> 24, (rc >> 16) & 0xff, rc & 0xffff ); @@ -1163,7 +1175,6 @@ int slap_sasl_init( void ) 0, 0, 0 ); #endif - /* default security properties */ memset( &sasl_secprops, '\0', sizeof(sasl_secprops) ); sasl_secprops.max_ssf = INT_MAX; @@ -1187,15 +1198,17 @@ int slap_sasl_destroy( void ) int slap_sasl_open( Connection *conn, int reopen ) { - int cb, sc = LDAP_SUCCESS; -#if SASL_VERSION_MAJOR >= 2 - char *ipremoteport = NULL, *iplocalport = NULL; -#endif - + int sc = LDAP_SUCCESS; #ifdef HAVE_CYRUS_SASL + int cb; + sasl_conn_t *ctx = NULL; sasl_callback_t *session_callbacks; +#if SASL_VERSION_MAJOR >= 2 + char *ipremoteport = NULL, *iplocalport = NULL; +#endif + assert( conn->c_sasl_authctx == NULL ); if ( !reopen ) { @@ -1325,14 +1338,26 @@ int slap_sasl_open( Connection *conn, int reopen ) } sc = slap_sasl_err2ldap( sc ); + +#elif defined(SLAP_BUILTIN_SASL) + /* built-in SASL implementation */ + SASL_CTX *ctx = (SASL_CTX *) SLAP_MALLOC(sizeof(SASL_CTX)); + if( ctx == NULL ) return -1; + + ctx->sc_external_ssf = 0; + ctx->sc_external_id.bv_len = 0; + ctx->sc_external_id.bv_val = NULL; + + conn->c_sasl_authctx = ctx; #endif + return sc; } int slap_sasl_external( Connection *conn, slap_ssf_t ssf, - const char *auth_id ) + struct berval *auth_id ) { #if SASL_VERSION_MAJOR >= 2 int sc; @@ -1348,7 +1373,8 @@ int slap_sasl_external( return LDAP_OTHER; } - sc = sasl_setprop( ctx, SASL_AUTH_EXTERNAL, auth_id ); + sc = sasl_setprop( ctx, SASL_AUTH_EXTERNAL, + auth_id ? auth_id->bv_val : NULL ); if ( sc != SASL_OK ) { return LDAP_OTHER; @@ -1365,7 +1391,7 @@ int slap_sasl_external( memset( &extprops, '\0', sizeof(extprops) ); extprops.ssf = ssf; - extprops.auth_id = (char *) auth_id; + extprops.auth_id = auth_id ? auth_id->bv_val : NULL; sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, (void *) &extprops ); @@ -1373,6 +1399,20 @@ int slap_sasl_external( if ( sc != SASL_OK ) { return LDAP_OTHER; } +#elif defined(SLAP_BUILTIN_SASL) + /* built-in SASL implementation */ + SASL_CTX *ctx = conn->c_sasl_authctx; + if ( ctx == NULL ) return LDAP_UNAVAILABLE; + + ctx->sc_external_ssf = ssf; + if( auth_id ) { + ctx->sc_external_id = *auth_id; + auth_id->bv_len = 0; + auth_id->bv_val = NULL; + } else { + ctx->sc_external_id.bv_len = 0; + ctx->sc_external_id.bv_val = NULL; + } #endif return LDAP_SUCCESS; @@ -1418,6 +1458,13 @@ char ** slap_sasl_mechs( Connection *conn ) ch_free( mechstr ); #endif } +#elif defined(SLAP_BUILTIN_SASL) + /* builtin SASL implementation */ + SASL_CTX *ctx = conn->c_sasl_authctx; + if ( ctx != NULL && ctx->sc_external_id.bv_val ) { + /* should check ssf */ + mechs = ldap_str2charray( "EXTERNAL", "," ); + } #endif return mechs; @@ -1431,7 +1478,9 @@ int slap_sasl_close( Connection *conn ) if( ctx != NULL ) { sasl_dispose( &ctx ); } - if ( conn->c_sasl_sockctx && conn->c_sasl_authctx != conn->c_sasl_sockctx ) { + if ( conn->c_sasl_sockctx && + conn->c_sasl_authctx != conn->c_sasl_sockctx ) + { ctx = conn->c_sasl_sockctx; sasl_dispose( &ctx ); } @@ -1442,6 +1491,17 @@ int slap_sasl_close( Connection *conn ) free( conn->c_sasl_extra ); conn->c_sasl_extra = NULL; + +#elif defined(SLAP_BUILTIN_SASL) + SASL_CTX *ctx = conn->c_sasl_authctx; + if( ctx ) { + if( ctx->sc_external_id.bv_val ) { + free( ctx->sc_external_id.bv_val ); + ctx->sc_external_id.bv_val = NULL; + } + free( ctx ); + conn->c_sasl_authctx = NULL; + } #endif return LDAP_SUCCESS; @@ -1471,7 +1531,6 @@ int slap_sasl_bind( Operation *op, SlapReply *rs ) op->orb_cred.bv_len ); #endif - if( ctx == NULL ) { send_ldap_error( op, rs, LDAP_UNAVAILABLE, "SASL unavailable on this session" ); @@ -1600,9 +1659,35 @@ int slap_sasl_bind( Operation *op, SlapReply *rs ) Debug(LDAP_DEBUG_TRACE, "<== slap_sasl_bind: rc=%d\n", rs->sr_err, 0, 0); #endif +#elif defined(SLAP_BUILTIN_SASL) + /* built-in SASL implementation */ + SASL_CTX *ctx = op->o_conn->c_sasl_authctx; + + if ( ctx == NULL ) { + send_ldap_error( op, rs, LDAP_OTHER, + "Internal SASL Error" ); + + } else if ( bvmatch( &ext_bv, &op->o_conn->c_sasl_bind_mech ) ) { + /* EXTERNAL */ + + if( op->orb_cred.bv_len ) { + rs->sr_text = "proxy authorization not support"; + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + send_ldap_result( op, rs ); + + } else { + op->orb_edn = ctx->sc_external_id; + rs->sr_err = LDAP_SUCCESS; + rs->sr_sasldata = NULL; + send_ldap_sasl( op, rs ); + } + } else { + send_ldap_error( op, rs, LDAP_AUTH_METHOD_NOT_SUPPORTED, + "requested SASL mechanism not supported" ); + } #else - send_ldap_error( op, rs, LDAP_UNAVAILABLE, + send_ldap_error( op, rs, LDAP_AUTH_METHOD_NOT_SUPPORTED, "SASL not supported" ); #endif @@ -1709,8 +1794,6 @@ done: #define SET_DN 1 #define SET_U 2 -static struct berval ext_bv = BER_BVC( "EXTERNAL" ); - int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len, char *user_realm, struct berval *dn, int flags ) { @@ -1759,9 +1842,7 @@ int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len, * is already normalized, so copy it and skip normalization. */ if( flags & SLAP_GETDN_AUTHCID ) { - if( mech->bv_len == ext_bv.bv_len && - strcasecmp( ext_bv.bv_val, mech->bv_val ) == 0 ) - { + if( bvmatch( mech, &ext_bv )) { /* EXTERNAL DNs are already normalized */ do_norm = 0; is_dn = SET_DN; @@ -1891,7 +1972,7 @@ int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len, } /* Run thru regexp */ - slap_sasl2dn( op, dn, &dn2 ); + slap_sasl2dn( op, dn, &dn2, flags ); if( dn2.bv_val ) { sl_free( dn->bv_val, op->o_tmpmemctx ); *dn = dn2; diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index a2f7fe0221..1c1e8d4f84 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -72,9 +72,10 @@ static int nSaslRegexp = 0; static SaslRegexp_t *SaslRegexp = NULL; /* What SASL proxy authorization policies are allowed? */ -#define SASL_AUTHZ_NONE 0 -#define SASL_AUTHZ_FROM 1 -#define SASL_AUTHZ_TO 2 +#define SASL_AUTHZ_NONE 0x00 +#define SASL_AUTHZ_FROM 0x01 +#define SASL_AUTHZ_TO 0x02 +#define SASL_AUTHZ_AND 0x10 static int authz_policy = SASL_AUTHZ_NONE; @@ -88,8 +89,10 @@ int slap_sasl_setpolicy( const char *arg ) authz_policy = SASL_AUTHZ_FROM; } else if ( strcasecmp( arg, "to" ) == 0 ) { authz_policy = SASL_AUTHZ_TO; - } else if ( strcasecmp( arg, "both" ) == 0 ) { + } else if ( strcasecmp( arg, "both" ) == 0 || strcasecmp( arg, "any" ) == 0 ) { authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO; + } else if ( strcasecmp( arg, "all" ) == 0 ) { + authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO | SASL_AUTHZ_AND; } else { rc = LDAP_OTHER; } @@ -487,7 +490,8 @@ static void slap_sasl_rx_exp( LDAP URI to find the matching LDAP entry, using the pattern matching strings given in the saslregexp config file directive(s) */ -static int slap_sasl_regexp( struct berval *in, struct berval *out, void *ctx ) +static int slap_sasl_regexp( struct berval *in, struct berval *out, + int flags, void *ctx ) { char *saslname = in->bv_val; SaslRegexp_t *reg; @@ -804,7 +808,7 @@ COMPLETE: * entry, return the DN of that one entry. */ void slap_sasl2dn( Operation *opx, - struct berval *saslname, struct berval *sasldn ) + struct berval *saslname, struct berval *sasldn, int flags ) { int rc; slap_callback cb = { NULL, sasl_sc_sasl2dn, NULL, NULL }; @@ -827,7 +831,7 @@ void slap_sasl2dn( Operation *opx, cb.sc_private = sasldn; /* Convert the SASL name into a minimal URI */ - if( !slap_sasl_regexp( saslname, ®out, opx->o_tmpmemctx ) ) { + if( !slap_sasl_regexp( saslname, ®out, flags, opx->o_tmpmemctx ) ) { goto FINISHED; } @@ -966,7 +970,7 @@ int slap_sasl_authorized( Operation *op, if( authz_policy & SASL_AUTHZ_TO ) { rc = slap_sasl_check_authz( op, authcDN, authzDN, slap_schema.si_ad_saslAuthzTo, authcDN ); - if( rc == LDAP_SUCCESS ) { + if( rc == LDAP_SUCCESS && !(authz_policy & SASL_AUTHZ_AND) ) { goto DONE; } } diff --git a/servers/slapd/sl_malloc.c b/servers/slapd/sl_malloc.c index 28ad962137..15c5b4da39 100644 --- a/servers/slapd/sl_malloc.c +++ b/servers/slapd/sl_malloc.c @@ -63,7 +63,7 @@ sl_mem_create( struct slab_heap *sh = NULL; int pad = 2*sizeof(int)-1; - ldap_pvt_thread_pool_getkey( ctx, sl_mem_init, (void **)&sh, NULL ); + ldap_pvt_thread_pool_getkey( ctx, (void *)sl_mem_init, (void **)&sh, NULL ); /* round up to doubleword boundary */ size += pad; @@ -72,7 +72,7 @@ sl_mem_create( if (!sh) { sh = ch_malloc( sizeof(struct slab_heap) ); sh->h_base = ch_malloc( size ); - ldap_pvt_thread_pool_setkey( ctx, sl_mem_init, (void *)sh, sl_mem_destroy ); + ldap_pvt_thread_pool_setkey( ctx, (void *)sl_mem_init, (void *)sh, sl_mem_destroy ); } else if ( size > (char *) sh->h_end - (char *) sh->h_base ) { sh->h_base = ch_realloc( sh->h_base, size ); } @@ -88,7 +88,7 @@ sl_mem_detach( ) { /* separate from context */ - ldap_pvt_thread_pool_setkey( ctx, sl_mem_init, NULL, NULL ); + ldap_pvt_thread_pool_setkey( ctx, (void *)sl_mem_init, NULL, NULL ); } void * @@ -214,7 +214,7 @@ sl_context( void *ptr ) ctx = ldap_pvt_thread_pool_context(); - ldap_pvt_thread_pool_getkey( ctx, sl_mem_init, (void **)&sh, NULL ); + ldap_pvt_thread_pool_getkey( ctx, (void *)sl_mem_init, (void **)&sh, NULL ); if ( sh && ptr >= sh->h_base && ptr <= sh->h_end ) { return sh; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 7dc3b219a7..48415e9322 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1083,7 +1083,7 @@ typedef enum slap_style_e { } slap_style_t; typedef struct slap_authz_info { - ber_tag_t sai_method; /* LDAP_AUTH_* from */ + ber_tag_t sai_method; /* LDAP_AUTH_* from */ struct berval sai_mech; /* SASL Mechanism */ struct berval sai_dn; /* DN for reporting purposes */ struct berval sai_ndn; /* Normalized DN */ diff --git a/servers/slapd/slapd.conf b/servers/slapd/slapd.conf index 0bdbe73065..6ea1eab79d 100644 --- a/servers/slapd/slapd.conf +++ b/servers/slapd/slapd.conf @@ -42,10 +42,11 @@ argsfile %LOCALSTATEDIR%/slapd.args # by users read # by anonymous auth # -# if no access controls are present, the default policy is: -# Allow read by all +# if no access controls are present, the default policy +# allows anyone and everyone to read anything but restricts +# updates to rootdn. (e.g., "access to * by * read") # -# rootdn can always write! +# rootdn can always read and write EVERYTHING! ####################################################################### # ldbm database definitions diff --git a/tests/scripts/test020-proxycache b/tests/scripts/test020-proxycache index ddd294e9a4..7ad5bcea2e 100755 --- a/tests/scripts/test020-proxycache +++ b/tests/scripts/test020-proxycache @@ -180,7 +180,7 @@ CACHED=`grep CACHEABLE $LOG2 | awk '{ printf "1" }'` -if test $CACHEABILITY = $CACHED ; then +if test "$CACHEABILITY" = "$CACHED" ; then echo "Successfully verified cacheability" else echo "Error in verifying cacheability" @@ -250,7 +250,7 @@ ANSWERED=`grep ANSWERABLE $LOG2 | awk '{ test $KILLSERVERS != no && kill -HUP $KILLPIDS -if test $ANSWERABILITY = $ANSWERED ; then +if test "$ANSWERABILITY" = "$ANSWERED" ; then echo "Successfully verified answerability" else echo "Error in verifying answerability" -- 2.39.5