[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: (ITS#4750) libldap initialization of ~/.ldaprc and setuid
Sorry for the late reply, I never saw this followup until now.
The idea of using multiple contexts is good. I'm thinking though that we can do
this simply by copying LDAP* session handles around, rather than introducing a
new LDAPContext structure. That will minimize the impact on application
writers, and allow us to continue using the current ldap_set_option() unchanged.
timo@physik.uni-potsdam.de wrote:
> Hi,
>
> OpenLDAP issue ITS#4750 is still unresolved (it affects current
> versions of nss_ldap and pam_ldap), and I consider it to be pretty
> serious:
> - Even security-conscious applications like pam_ldap still parse
> files from unsafe locations, including the current directory.
> - Attempting to read from a file in the current directory can
> cause problems on its own, e.g. when the directory is an autofs
> mountpoint (In fact, I became aware of this issue by investigating
> deadlocks occurring in such a situation)
> - If an application uses LDAP in more than one context, like a
> program using LDAP while also linking to nss_ldap and pam_ldap,
> the settings can interfere (unless very much care is taken, see
> below). This is bad, as the very purpose of nss and pam is to
> make the underlying mechanisms completely transparent to the
> application.
> - The existing LDAPNOINIT mechanism is only effective for the first
> call which initializes the global option structure. Thus, almost
> no one can reliably use it: the options may already have been
> initialized e.g. by nss_ldap which nearly every program might
> link to.
>
> The suggested workaround so far is to force nss_ldap, pam_ldap, and
> possibly others, to override all relevant options with safe values.
> To me, this seems to be quite error-prone and not a satisfactory
> solution:
> - it requires duplication of much of the configuration parsing code,
> which needs to be kept in sync with OpenLDAP's syntax and semantics
> (or worse, allow the syntax to diverge), and
> - it requires users to think of and nail down each and every potentially
> relevant option separately (note that current versions of libldap and
> pam_ldap silently ignore syntax errors in the config file, so one may
> very easily be in a false sense of security).
> - It does not stop libldap from opening files it shouldn't open in the
> first place.
> As Kurt Zeilenga already noted, a proper solution will require some
> redesign, so...
>
> I include 3 patches: one for libldap (against HEAD as of 20070216), and
> corresponding patches for nss_ldap-254 and pam_ldap-183.
>
> The first lines of the openldap patch (the changes to ldap.h) and
> the nss_ldap patch should tell you how it is supposed to work:
> libraries can obtain a private copy of the "globaloptions",
> in an opaque "LDAPContext" object, to be initialized in a safe way
> and independently from other copies of that structure.
> The existing struct globaloptions is used by default to stay compatible
> with existing programs.
>
> I'm willing to write more documentation too but I would like to get
> some some feedback on it first,
>
> Regards,
>
> Timo Felbinger
>
>
> --pf9I7BMVVzbSWLtt
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: attachment; filename="openldap.patch"
>
> This patch file is derived from OpenLDAP Software. All of the modifications to
> OpenLDAP Software represented in the following patch(es) were developed by
> Timo Felbinger <timo@physik.uni-potsdam.de>.
> These modifications are not subject to any license of University of Potsdam.
>
> I, Timo Felbinger, hereby place the following modifications to OpenLDAP Software
> (and only these modifications) into the public domain.
> Hence, these modifications may be freely used and/or redistributed for any purpose
> with or without attribution and/or other notice.
>
> diff -Nru openldap-src/include/ldap.h openldap-src-context/include/ldap.h
> --- openldap-src/include/ldap.h 2007-02-12 10:53:59.000000000 +0000
> +++ openldap-src-context/include/ldap.h 2007-02-17 13:22:45.000000000 +0000
> @@ -696,6 +696,8 @@
> */
> typedef struct ldap LDAP;
>
> +typedef struct ldapoptions LDAPContext;
> +
> #define LDAP_DEREF_NEVER 0x00
> #define LDAP_DEREF_SEARCHING 0x01
> #define LDAP_DEREF_FINDING 0x02
> @@ -890,6 +892,12 @@
> int option,
> LDAP_CONST void *invalue));
>
> +LDAP_F( int )
> +ldap_set_option_in_context LDAP_P((
> + LDAPContext *context,
> + int option,
> + LDAP_CONST void *invalue));
> +
> /* V3 REBIND Function Callback Prototype */
> typedef int (LDAP_REBIND_PROC) LDAP_P((
> LDAP *ld, LDAP_CONST char *url,
> @@ -1382,10 +1390,30 @@
> LDAP **ldp ));
>
> LDAP_F( int )
> +ldap_create_in_context LDAP_P((
> + LDAP **ldp,
> + LDAPContext *context ));
> +
> +LDAP_F( int )
> ldap_initialize LDAP_P((
> LDAP **ldp,
> LDAP_CONST char *url ));
>
> +LDAP_F( int )
> +ldap_initialize_in_context LDAP_P((
> + LDAP **ldp,
> + LDAP_CONST char *url,
> + LDAPContext *context ));
> +
> +LDAP_F( int )
> +ldap_create_context LDAP_P((
> + LDAPContext **context,
> + char **directives ));
> +
> +LDAP_F( int )
> +ldap_destroy_context LDAP_P((
> + LDAPContext *context ));
> +
> /*
> * in tls.c
> */
> diff -Nru openldap-src/include/ldap_pvt.h openldap-src-context/include/ldap_pvt.h
> --- openldap-src/include/ldap_pvt.h 2007-02-12 03:20:24.000000000 +0000
> +++ openldap-src-context/include/ldap_pvt.h 2007-02-17 13:22:45.000000000 +0000
> @@ -278,6 +278,8 @@
> int option, void *arg ));
> LDAP_F (int) ldap_pvt_tls_set_option LDAP_P(( struct ldap *ld,
> int option, void *arg ));
> +LDAP_F (int) ldap_pvt_tls_set_option_2 LDAP_P(( struct ldapoptions *lo, struct ldap *ld,
> + int option, void *arg ));
>
> LDAP_F (void) ldap_pvt_tls_destroy LDAP_P(( void ));
> LDAP_F (int) ldap_pvt_tls_init LDAP_P(( void ));
> diff -Nru openldap-src/libraries/libldap/init.c openldap-src-context/libraries/libldap/init.c
> --- openldap-src/libraries/libldap/init.c 2007-02-05 19:32:44.000000000 +0000
> +++ openldap-src-context/libraries/libldap/init.c 2007-02-17 13:22:45.000000000 +0000
> @@ -124,6 +124,7 @@
> #define MAX_LDAP_ENV_PREFIX_LEN 8
>
> static void openldap_ldap_init_w_conf(
> + struct ldapoptions *gopts,
> const char *file, int userconf )
> {
> char linebuf[ AC_LINE_MAX ];
> @@ -131,10 +132,11 @@
> int i;
> char *cmd, *opt;
> char *start, *end;
> - struct ldapoptions *gopts;
>
> - if ((gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
> - return; /* Could not allocate mem for global options */
> + if( ! gopts ) {
> + if ((gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
> + return; /* Could not allocate mem for global options */
> + }
> }
>
> if (file == NULL) {
> @@ -244,7 +246,7 @@
> * (char**) p = LDAP_STRDUP(opt);
> break;
> case ATTR_OPTION:
> - ldap_set_option( NULL, attrs[i].offset, opt );
> + ldap_set_option_in_context( gopts, attrs[i].offset, opt );
> break;
> case ATTR_SASL:
> #ifdef HAVE_CYRUS_SASL
> @@ -253,7 +255,7 @@
> break;
> case ATTR_TLS:
> #ifdef HAVE_TLS
> - ldap_int_tls_config( NULL, attrs[i].offset, opt );
> + ldap_int_tls_config_in_context( gopts, attrs[i].offset, opt );
> #endif
> break;
> case ATTR_OPT_TV: {
> @@ -285,7 +287,7 @@
>
> static void openldap_ldap_init_w_sysconf(const char *file)
> {
> - openldap_ldap_init_w_conf( file, 0 );
> + openldap_ldap_init_w_conf( NULL, file, 0 );
> }
>
> static void openldap_ldap_init_w_userconf(const char *file)
> @@ -314,11 +316,11 @@
>
> /* try ~/file */
> sprintf(path, "%s" LDAP_DIRSEP "%s", home, file);
> - openldap_ldap_init_w_conf(path, 1);
> + openldap_ldap_init_w_conf(NULL, path, 1);
>
> /* try ~/.file */
> sprintf(path, "%s" LDAP_DIRSEP ".%s", home, file);
> - openldap_ldap_init_w_conf(path, 1);
> + openldap_ldap_init_w_conf(NULL, path, 1);
> }
>
> if(path != NULL) {
> @@ -326,7 +328,7 @@
> }
>
> /* try file */
> - openldap_ldap_init_w_conf(file, 1);
> + openldap_ldap_init_w_conf(NULL, file, 1);
> }
>
> static void openldap_ldap_init_w_env(
> @@ -466,9 +468,10 @@
> void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl )
> {
> if (dbglvl)
> - gopts->ldo_debug = *dbglvl;
> + /* FIXME: currently ldo_debug is an always global option only, so we set both places: */
> + gopts->ldo_debug = LDAP_INT_GLOBAL_OPT()->ldo_debug = *dbglvl;
> else
> - gopts->ldo_debug = 0;
> + gopts->ldo_debug = LDAP_INT_GLOBAL_OPT()->ldo_debug = 0;
>
> gopts->ldo_version = LDAP_VERSION2;
> gopts->ldo_deref = LDAP_DEREF_NEVER;
> @@ -531,7 +534,10 @@
> char * ldap_int_hostname = NULL;
> #endif
>
> -void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
> +void ldap_int_initialize(
> + struct ldapoptions *gopts,
> + int *dbglvl,
> + char **directives )
> {
> if ( gopts->ldo_valid == LDAP_INITIALIZED ) {
> return;
> @@ -593,6 +599,19 @@
>
> ldap_int_initialize_global_options(gopts, NULL);
>
> + if( directives ) {
> + for( ; *directives; ++directives ) {
> + if( ! strncmp( *directives, "file=", 5 ) ) {
> + openldap_ldap_init_w_conf( gopts, *directives + 5, 1 );
> + continue;
> + }
> + /* add more directives here... */
> + gopts->ldo_valid = LDAP_TRASHED_SESSION;
> + return;
> + }
> + return;
> + }
> +
> if( getenv("LDAPNOINIT") != NULL ) {
> return;
> }
> diff -Nru openldap-src/libraries/libldap/ldap-int.h openldap-src-context/libraries/libldap/ldap-int.h
> --- openldap-src/libraries/libldap/ldap-int.h 2007-02-15 00:42:23.000000000 +0000
> +++ openldap-src-context/libraries/libldap/ldap-int.h 2007-02-17 13:22:45.000000000 +0000
> @@ -417,7 +417,7 @@
>
> LDAP_V ( struct ldapoptions ) ldap_int_global_options;
>
> -LDAP_F ( void ) ldap_int_initialize LDAP_P((struct ldapoptions *, int *));
> +LDAP_F ( void ) ldap_int_initialize LDAP_P((struct ldapoptions *, int *, char **directives ));
> LDAP_F ( void ) ldap_int_initialize_global_options LDAP_P((
> struct ldapoptions *, int *));
>
> @@ -652,6 +652,9 @@
> LDAP_F (int) ldap_int_tls_config LDAP_P(( LDAP *ld,
> int option, const char *arg ));
>
> +LDAP_F (int) ldap_int_tls_config_in_context LDAP_P(( struct ldapoptions *lo,
> + int option, const char *arg ));
> +
> LDAP_F (int) ldap_int_tls_start LDAP_P(( LDAP *ld,
> LDAPConn *conn, LDAPURLDesc *srv ));
>
> diff -Nru openldap-src/libraries/libldap/open.c openldap-src-context/libraries/libldap/open.c
> --- openldap-src/libraries/libldap/open.c 2007-02-12 03:20:24.000000000 +0000
> +++ openldap-src-context/libraries/libldap/open.c 2007-02-17 13:45:19.000000000 +0000
> @@ -87,27 +87,88 @@
> return ld;
> }
>
> +int
> +ldap_free_context_internals( LDAPContext *context )
> +{
> + ldap_free_urllist( context->ldo_defludp );
> +#ifdef HAVE_CYRUS_SASL
> + LDAP_FREE( context->ldo_def_sasl_authzid );
> + LDAP_FREE( context->ldo_def_sasl_authcid );
> + LDAP_FREE( context->ldo_def_sasl_realm );
> + LDAP_FREE( context->ldo_def_sasl_mech );
> +#endif
> + return LDAP_SUCCESS;
> +}
> +
> +/* public destructor of LDAPContext */
> +int
> +ldap_destroy_context( LDAPContext *context )
> +{
> + if( context ) {
> + ldap_free_context_internals( context );
> + free( context );
> + }
> + return LDAP_SUCCESS;
> +}
> +
> +/* public constructor of LDAPContext */
> +int
> +ldap_create_context(
> + LDAPContext **context,
> + /* directives: NULL-terminated list of initialization directives:
> + * - NULL: default initialization procedure (see ldap.conf(5))
> + * - { NULL }: equivalent to LDAPNOINIT
> + * - { ..., "file=path", ... }: parse path like user-config file
> + */
> + char **directives )
> +{
> + LDAPContext *lo;
> +
> + *context = NULL;
> + lo = ( LDAPContext * ) LDAP_CALLOC( 1, sizeof( LDAPContext ) );
> + if( ! lo )
> + return LDAP_NO_MEMORY;
> +
> + Debug( LDAP_DEBUG_TRACE, "ldap_create_context %p\n", lo, 0, 0 );
> +
> + lo->ldo_valid = LDAP_UNINITIALIZED;
> + ldap_int_initialize( lo, NULL, directives );
> + if( lo->ldo_valid != LDAP_INITIALIZED )
> + return LDAP_LOCAL_ERROR;
>
> + *context = lo;
> +
> + return LDAP_SUCCESS;
> +}
>
> int
> ldap_create( LDAP **ldp )
> {
> + return ldap_create_in_context( ldp, NULL );
> +}
> +
> +int
> +ldap_create_in_context( LDAP **ldp, LDAPContext *gopts )
> +{
> LDAP *ld;
> - struct ldapoptions *gopts;
>
> *ldp = NULL;
> - /* Get pointer to global option structure */
> - if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
> - return LDAP_NO_MEMORY;
> - }
>
> - /* Initialize the global options, if not already done. */
> - if( gopts->ldo_valid != LDAP_INITIALIZED ) {
> - ldap_int_initialize(gopts, NULL);
> - if ( gopts->ldo_valid != LDAP_INITIALIZED )
> - return LDAP_LOCAL_ERROR;
> + if( ! gopts ) {
> + /* default is the global context */
> + if ( (gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
> + return LDAP_NO_MEMORY;
> + }
> +
> + /* Initialize the global options, if not already done. */
> + if( gopts->ldo_valid != LDAP_INITIALIZED ) {
> + ldap_int_initialize(gopts, NULL, NULL);
> + }
> }
>
> + if( gopts->ldo_valid != LDAP_INITIALIZED )
> + return LDAP_LOCAL_ERROR;
> +
> Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 );
>
> if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
> @@ -167,13 +228,7 @@
>
> nomem:
> ldap_free_select_info( ld->ld_selectinfo );
> - ldap_free_urllist( ld->ld_options.ldo_defludp );
> -#ifdef HAVE_CYRUS_SASL
> - LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid );
> - LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid );
> - LDAP_FREE( ld->ld_options.ldo_def_sasl_realm );
> - LDAP_FREE( ld->ld_options.ldo_def_sasl_mech );
> -#endif
> + ldap_free_context_internals( &ld->ld_options );
> LDAP_FREE( (char *)ld );
> return LDAP_NO_MEMORY;
> }
> @@ -215,11 +270,17 @@
> int
> ldap_initialize( LDAP **ldp, LDAP_CONST char *url )
> {
> + return ldap_initialize_in_context( ldp, url, NULL );
> +}
> +
> +int
> +ldap_initialize_in_context( LDAP **ldp, LDAP_CONST char *url, LDAPContext *context )
> +{
> int rc;
> LDAP *ld;
>
> *ldp = NULL;
> - rc = ldap_create(&ld);
> + rc = ldap_create_in_context(&ld, context);
> if ( rc != LDAP_SUCCESS )
> return rc;
>
> diff -Nru openldap-src/libraries/libldap/options.c openldap-src-context/libraries/libldap/options.c
> --- openldap-src/libraries/libldap/options.c 2007-02-06 22:02:47.000000000 +0000
> +++ openldap-src-context/libraries/libldap/options.c 2007-02-17 13:22:45.000000000 +0000
> @@ -97,16 +97,6 @@
> {
> struct ldapoptions *lo;
>
> - /* Get pointer to global option structure */
> - lo = LDAP_INT_GLOBAL_OPT();
> - if (NULL == lo) {
> - return LDAP_NO_MEMORY;
> - }
> -
> - if( lo->ldo_valid != LDAP_INITIALIZED ) {
> - ldap_int_initialize(lo, NULL);
> - }
> -
> if(ld != NULL) {
> assert( LDAP_VALID( ld ) );
>
> @@ -117,6 +107,18 @@
> lo = &ld->ld_options;
> }
>
> + if( lo == NULL ) {
> + /* Get pointer to global option structure */
> + lo = LDAP_INT_GLOBAL_OPT();
> + if (NULL == lo) {
> + return LDAP_NO_MEMORY;
> + }
> +
> + if( lo->ldo_valid != LDAP_INITIALIZED ) {
> + ldap_int_initialize(lo, NULL, NULL);
> + }
> + }
> +
> if(outvalue == NULL) {
> /* no place to get to */
> return LDAP_OPT_ERROR;
> @@ -347,19 +349,35 @@
> }
>
> int
> +ldap_set_option_in_context(
> + LDAPContext *context,
> + int option,
> + LDAP_CONST void *invalue)
> +{
> + return ldap_set_option_2( context, NULL, option, invalue );
> +}
> +
> +int
> ldap_set_option(
> LDAP *ld,
> int option,
> LDAP_CONST void *invalue)
> {
> - struct ldapoptions *lo;
> - int *dbglvl = NULL;
> + return ldap_set_option_2( NULL, ld, option, invalue );
> +}
>
> - /* Get pointer to global option structure */
> - lo = LDAP_INT_GLOBAL_OPT();
> - if (lo == NULL) {
> - return LDAP_NO_MEMORY;
> - }
> +/*
> + * ldap_set_option_2: can set options per LDAP handle or per context.
> + * if handle is given, the context is ignored.
> + */
> +int
> +ldap_set_option_2(
> + struct ldapoptions *lo,
> + LDAP *ld,
> + int option,
> + LDAP_CONST void *invalue)
> +{
> + int *dbglvl = NULL;
>
> /*
> * The architecture to turn on debugging has a chicken and egg
> @@ -370,10 +388,6 @@
> dbglvl = (int *) invalue;
> }
>
> - if( lo->ldo_valid != LDAP_INITIALIZED ) {
> - ldap_int_initialize(lo, dbglvl);
> - }
> -
> if(ld != NULL) {
> assert( LDAP_VALID( ld ) );
>
> @@ -384,6 +398,17 @@
> lo = &ld->ld_options;
> }
>
> + if( lo == NULL ) {
> + /* Get pointer to global option structure */
> + lo = LDAP_INT_GLOBAL_OPT();
> + if (lo == NULL) {
> + return LDAP_NO_MEMORY;
> + }
> + if( lo->ldo_valid != LDAP_INITIALIZED ) {
> + ldap_int_initialize(lo, dbglvl, NULL);
> + }
> + }
> +
> switch(option) {
> case LDAP_OPT_REFERRALS:
> if(invalue == LDAP_OPT_OFF) {
> @@ -668,7 +693,7 @@
>
> default:
> #ifdef HAVE_TLS
> - if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 )
> + if ( ldap_pvt_tls_set_option_2( lo, ld, option, (void *)invalue ) == 0 )
> return LDAP_OPT_SUCCESS;
> #endif
> #ifdef HAVE_CYRUS_SASL
> diff -Nru openldap-src/libraries/libldap/tls.c openldap-src-context/libraries/libldap/tls.c
> --- openldap-src/libraries/libldap/tls.c 2007-01-24 22:38:26.000000000 +0000
> +++ openldap-src-context/libraries/libldap/tls.c 2007-02-17 13:22:45.000000000 +0000
> @@ -1178,8 +1178,20 @@
> }
>
> int
> +ldap_int_tls_config_in_context( struct ldapoptions *lo, int option, const char *arg )
> +{
> + return ldap_int_tls_config_2( lo, NULL, option, arg );
> +}
> +
> +int
> ldap_int_tls_config( LDAP *ld, int option, const char *arg )
> {
> + return ldap_int_tls_config_2( NULL, ld, option, arg );
> +}
> +
> +int
> +ldap_int_tls_config_2( struct ldapconfig *lo, LDAP *ld, int option, const char *arg )
> +{
> int i;
>
> switch( option ) {
> @@ -1190,7 +1202,7 @@
> case LDAP_OPT_X_TLS_RANDOM_FILE:
> case LDAP_OPT_X_TLS_CIPHER_SUITE:
> case LDAP_OPT_X_TLS_DHFILE:
> - return ldap_pvt_tls_set_option( ld, option, (void *) arg );
> + return ldap_pvt_tls_set_option_2( lo, ld, option, (void *) arg );
>
> case LDAP_OPT_X_TLS_REQUIRE_CERT:
> case LDAP_OPT_X_TLS:
> @@ -1216,7 +1228,7 @@
> }
>
> if (i >= 0) {
> - return ldap_pvt_tls_set_option( ld, option, &i );
> + return ldap_pvt_tls_set_option_2( lo, ld, option, &i );
> }
> return -1;
> #ifdef HAVE_OPENSSL_CRL
> @@ -1230,7 +1242,7 @@
> i = LDAP_OPT_X_TLS_CRL_ALL ;
> }
> if (i >= 0) {
> - return ldap_pvt_tls_set_option( ld, option, &i );
> + return ldap_pvt_tls_set_option_2( lo, ld, option, &i );
> }
> return -1;
> #endif
> @@ -1334,7 +1346,12 @@
> int
> ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
> {
> - struct ldapoptions *lo;
> + return ldap_pvt_tls_set_option_2( NULL, ld, option, arg );
> +}
> +
> +int
> +ldap_pvt_tls_set_option_2( struct ldapoptions *lo, LDAP *ld, int option, void *arg )
> +{
>
> if( ld != NULL ) {
> assert( LDAP_VALID( ld ) );
> @@ -1345,7 +1362,8 @@
>
> lo = &ld->ld_options;
>
> - } else {
> + }
> + if( lo == NULL ) {
> /* Get pointer to global option structure */
> lo = LDAP_INT_GLOBAL_OPT();
> if ( lo == NULL ) {
>
> --pf9I7BMVVzbSWLtt
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: attachment; filename="nss_ldap.patch"
>
> This patch file is derived from PADL Software (nss_ldap).
> All of the modifications to PADL Software represented in the following
> patch(es) were developed by Timo Felbinger <timo@physik.uni-potsdam.de>.
> These modifications are not subject to any license of University of Potsdam.
>
> I, Timo Felbinger, hereby place the following modifications to PADL Software
> (and only these modifications) into the public domain.
> Hence, these modifications may be freely used and/or redistributed for any purpose
> with or without attribution and/or other notice.
>
> diff -Nru nss_ldap-254/config.h.in nss_ldap-254-context/config.h.in
> --- nss_ldap-254/config.h.in 2006-12-18 08:12:56.000000000 +0000
> +++ nss_ldap-254-context/config.h.in 2007-02-17 14:46:02.000000000 +0000
> @@ -132,6 +132,9 @@
> /* Define to 1 if you have the `ldap_initialize' function. */
> #undef HAVE_LDAP_INITIALIZE
>
> +/* Define to 1 if you have the `ldap_create_context' function. */
> +#undef HAVE_LDAP_CREATE_CONTEXT
> +
> /* Define to 1 if you have the `ldap_ld_free' function. */
> #undef HAVE_LDAP_LD_FREE
>
> diff -Nru nss_ldap-254/configure nss_ldap-254-context/configure
> --- nss_ldap-254/configure 2006-12-18 08:12:56.000000000 +0000
> +++ nss_ldap-254-context/configure 2007-02-17 14:46:37.000000000 +0000
> @@ -1,4 +1,6 @@
> #! /bin/sh
> +echo please run autoconf first!
> +exit 1
>
> # Guess values for system-dependent variables and create Makefiles.
> # Generated automatically using autoconf version 2.13
> diff -Nru nss_ldap-254/configure.in nss_ldap-254-context/configure.in
> --- nss_ldap-254/configure.in 2006-12-18 08:12:56.000000000 +0000
> +++ nss_ldap-254-context/configure.in 2007-02-17 14:46:02.000000000 +0000
> @@ -297,7 +297,7 @@
> AC_CHECK_FUNCS(sasl_auxprop_request)
> AC_CHECK_FUNCS(ldap_init ldap_get_lderrno ldap_parse_result ldap_memfree ldap_controls_free)
> AC_CHECK_FUNCS(ldap_ld_free ldap_explode_rdn ldap_set_option ldap_get_option)
> -AC_CHECK_FUNCS(ldap_sasl_interactive_bind_s ldap_initialize ldap_search_ext)
> +AC_CHECK_FUNCS(ldap_sasl_interactive_bind_s ldap_initialize ldap_search_ext ldap_create_context)
> AC_CHECK_FUNCS(ldap_create_control ldap_create_page_control ldap_parse_page_control)
> if test "$enable_ssl" \!= "no"; then
> AC_CHECK_FUNCS(ldapssl_client_init ldap_start_tls_s ldap_pvt_tls_set_option ldap_start_tls)
> diff -Nru nss_ldap-254/ldap-nss.c nss_ldap-254-context/ldap-nss.c
> --- nss_ldap-254/ldap-nss.c 2006-12-18 08:12:56.000000000 +0000
> +++ nss_ldap-254-context/ldap-nss.c 2007-02-17 14:46:02.000000000 +0000
> @@ -137,7 +137,7 @@
> /*
> * Global LDAP session.
> */
> -static ldap_session_t __session = { NULL, NULL, 0, LS_UNINITIALIZED };
> +static ldap_session_t __session = { NULL, NULL, NULL, 0, LS_UNINITIALIZED };
>
> #if defined(HAVE_PTHREAD_ATFORK) || defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H)
> static pthread_once_t __once = PTHREAD_ONCE_INIT;
> @@ -1003,7 +1003,7 @@
> }
>
> static NSS_STATUS
> -do_init_session (LDAP ** ld, const char *uri, int defport)
> +do_init_session ( LDAPContext **ldap_context, LDAP ** ld, const char *uri, int defport)
> {
> int rc;
> int ldaps;
> @@ -1011,6 +1011,17 @@
> char *p;
> NSS_STATUS stat;
>
> +#ifdef HAVE_LDAP_CREATE_CONTEXT
> + if( ! *ldap_context )
> + {
> + /* make sure ldap config is read in a safe way */
> + static const char *directives[2] = { "file=" NSS_LDAP_PATH_CONF, NULL };
> + int rc = ldap_create_context( ldap_context, directives );
> + if (rc != LDAP_SUCCESS)
> + return NSS_UNAVAIL;
> + }
> +#endif
> +
> ldaps = (strncasecmp (uri, "ldaps://", sizeof ("ldaps://") - 1) == 0);
> p = strchr (uri, ':');
> /* we should be looking for the second instance to find the port number */
> @@ -1028,7 +1039,11 @@
> uri = uribuf;
> }
>
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + rc = ldap_initialize_in_context (ld, uri, *ldap_context);
> +# else
> rc = ldap_initialize (ld, uri);
> +# endif
> #else
> if (strncasecmp (uri, "ldap://", sizeof ("ldap://") - 1) != 0)
> {
> @@ -1311,7 +1326,7 @@
> assert (__session.ls_current_uri <= NSS_LDAP_CONFIG_URI_MAX);
> assert (cfg->ldc_uris[__session.ls_current_uri] != NULL);
>
> - stat = do_init_session (&__session.ls_conn,
> + stat = do_init_session ( &__session.ldap_context, &__session.ls_conn,
> cfg->ldc_uris[__session.ls_current_uri],
> cfg->ldc_port);
> if (stat != NSS_SUCCESS)
> diff -Nru nss_ldap-254/ldap-nss.h nss_ldap-254-context/ldap-nss.h
> --- nss_ldap-254/ldap-nss.h 2006-12-18 08:12:56.000000000 +0000
> +++ nss_ldap-254-context/ldap-nss.h 2007-02-17 14:46:02.000000000 +0000
> @@ -416,12 +416,19 @@
>
> typedef enum ldap_session_state ldap_session_state_t;
>
> +/* for readability, make sure LDAPContext is at least a dummy type: */
> +#ifndef HAVE_LDAP_CREATE_CONTEXT
> +# define LDAPContext void
> +#endif
> +
> /*
> * convenient wrapper around pointer into global config list, and a
> * connection to an LDAP server.
> */
> struct ldap_session
> {
> + /* the context, if supported */
> + LDAPContext *ldap_context;
> /* the connection */
> LDAP *ls_conn;
> /* pointer into config table */
>
> --pf9I7BMVVzbSWLtt
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: attachment; filename="pam_ldap.patch"
>
> This patch file is derived from PADL Software (pam_ldap).
> All of the modifications to PADL Software represented in the following
> patch(es) were developed by Timo Felbinger <timo@physik.uni-potsdam.de>.
> These modifications are not subject to any license of University of Potsdam.
>
> I, Timo Felbinger, hereby place the following modifications to PADL Software
> (and only these modifications) into the public domain.
> Hence, these modifications may be freely used and/or redistributed for any purpose
> with or without attribution and/or other notice.
>
> diff -Nru pam_ldap-183/config.h.in pam_ldap-183-context/config.h.in
> --- pam_ldap-183/config.h.in 2006-10-19 13:22:27.000000000 +0000
> +++ pam_ldap-183-context/config.h.in 2007-02-17 14:55:38.000000000 +0000
> @@ -33,6 +33,9 @@
> /* Define if you have the ldap_initialize function. */
> #undef HAVE_LDAP_INITIALIZE
>
> +/* Define if you have the ldap_create_context function. */
> +#undef HAVE_LDAP_CREATE_CONTEXT
> +
> /* Define if you have the ldap_memfree function. */
> #undef HAVE_LDAP_MEMFREE
>
> diff -Nru pam_ldap-183/configure pam_ldap-183-context/configure
> --- pam_ldap-183/configure 2006-10-19 13:22:27.000000000 +0000
> +++ pam_ldap-183-context/configure 2007-02-17 14:55:38.000000000 +0000
> @@ -1,4 +1,6 @@
> #! /bin/sh
> +echo Please run autoconf first!
> +exit 1
>
> # Guess values for system-dependent variables and create Makefiles.
> # Generated automatically using autoconf version 2.13
> diff -Nru pam_ldap-183/configure.in pam_ldap-183-context/configure.in
> --- pam_ldap-183/configure.in 2006-10-19 13:22:27.000000000 +0000
> +++ pam_ldap-183-context/configure.in 2007-02-17 14:55:38.000000000 +0000
> @@ -131,6 +131,7 @@
> AC_CHECK_FUNCS(ldapssl_init ldap_start_tls_s ldap_pvt_tls_set_option)
> fi
> AC_CHECK_FUNCS(ldap_initialize)
> +AC_CHECK_FUNCS(ldap_create_context)
> AC_CHECK_FUNCS(ldap_sasl_bind ldap_sasl_interactive_bind_s)
> AC_CHECK_FUNCS(gethostbyname_r)
>
> diff -Nru pam_ldap-183/pam_ldap.c pam_ldap-183-context/pam_ldap.c
> --- pam_ldap-183/pam_ldap.c 2006-10-19 13:22:27.000000000 +0000
> +++ pam_ldap-183-context/pam_ldap.c 2007-02-17 15:08:39.000000000 +0000
> @@ -155,6 +155,11 @@
> #endif
> static int pam_debug_level __UNUSED__ = 0;
>
> +#ifndef HAVE_LDAP_CREATE_CONTEXT
> +# typedef LDAPContext void;
> +#endif
> +static LDAPContext *ldap_context = 0;
> +
> #ifdef HAVE_LDAPSSL_INIT
> static int ssl_initialized = 0;
> #endif
> @@ -1190,6 +1195,36 @@
> struct timeval tv;
> #endif
>
> +#ifdef HAVE_LDAP_CREATE_CONTEXT
> + /* make sure ldap config is read in a safe and transparent way */
> + if( ! ldap_context )
> + {
> + char *directives[2];
> + int rc;
> +
> + if( session->conf->configFile == NULL )
> + {
> + directives[0] = NULL;
> + }
> + else
> + {
> + directives[0] = malloc (strlen (session->conf->configFile) + 6);
> + if( directives[0] == NULL )
> + return PAM_BUF_ERR;
> + strcpy( directives[0], "file=" );
> + strcpy( directives[0]+5, session->conf->configFile );
> + }
> + directives[1] = NULL;
> + rc = ldap_create_context( &ldap_context, directives );
> + _pam_drop( directives[0] );
> + if (rc != LDAP_SUCCESS || ! ldap_context )
> + {
> + syslog (LOG_ERR, "pam_ldap: ldap_create_context: %s", ldap_err2string (rc));
> + return PAM_SERVICE_ERR;
> + }
> + }
> +#endif
> +
> #ifdef HAVE_LDAP_SET_OPTION
> if (session->conf->debug)
> {
> @@ -1253,7 +1288,11 @@
> #ifdef HAVE_LDAP_INITIALIZE
> if (session->conf->uri != NULL)
> {
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + int rc = ldap_initialize_in_context (&session->ld, session->conf->uri, ldap_context);
> +# else
> int rc = ldap_initialize (&session->ld, session->conf->uri);
> +# endif
> if (rc != LDAP_SUCCESS)
> {
> syslog (LOG_ERR, "pam_ldap: ldap_initialize %s",
> @@ -1400,8 +1439,12 @@
> /* rand file */
> if (session->conf->tls_randfile != NULL)
> {
> - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
> - session->conf->tls_randfile);
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + rc = ldap_set_option_in_context ( ldap_context,
> +# else
> + rc = ldap_set_option (NULL,
> +# endif
> + LDAP_OPT_X_TLS_RANDOM_FILE, session->conf->tls_randfile);
> if (rc != LDAP_SUCCESS)
> {
> syslog (LOG_ERR,
> @@ -1415,7 +1458,12 @@
> /* ca cert file */
> if (session->conf->tls_cacertfile != NULL)
> {
> - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE,
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + rc = ldap_set_option_in_context ( ldap_context,
> +# else
> + rc = ldap_set_option (NULL,
> +# endif
> + LDAP_OPT_X_TLS_CACERTFILE,
> session->conf->tls_cacertfile);
> if (rc != LDAP_SUCCESS)
> {
> @@ -1429,7 +1477,12 @@
> if (session->conf->tls_cacertdir != NULL)
> {
> /* ca cert directory */
> - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR,
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + rc = ldap_set_option_in_context ( ldap_context,
> +# else
> + rc = ldap_set_option (NULL,
> +# endif
> + LDAP_OPT_X_TLS_CACERTDIR,
> session->conf->tls_cacertdir);
> if (rc != LDAP_SUCCESS)
> {
> @@ -1443,7 +1496,12 @@
> if (session->conf->tls_checkpeer > -1)
> {
> /* require cert? */
> - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + rc = ldap_set_option_in_context ( ldap_context,
> +# else
> + rc = ldap_set_option (NULL,
> +# endif
> + LDAP_OPT_X_TLS_REQUIRE_CERT,
> &session->conf->tls_checkpeer);
> if (rc != LDAP_SUCCESS)
> {
> @@ -1457,7 +1515,12 @@
> if (session->conf->tls_ciphers != NULL)
> {
> /* set cipher suite, certificate and private key: */
> - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + rc = ldap_set_option_in_context ( ldap_context,
> +# else
> + rc = ldap_set_option (NULL,
> +# endif
> + LDAP_OPT_X_TLS_CIPHER_SUITE,
> session->conf->tls_ciphers);
> if (rc != LDAP_SUCCESS)
> {
> @@ -1470,7 +1533,12 @@
>
> if (session->conf->tls_cert != NULL)
> {
> - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE,
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + rc = ldap_set_option_in_context ( ldap_context,
> +# else
> + rc = ldap_set_option (NULL,
> +# endif
> + LDAP_OPT_X_TLS_CERTFILE,
> session->conf->tls_cert);
> if (rc != LDAP_SUCCESS)
> {
> @@ -1483,7 +1551,12 @@
>
> if (session->conf->tls_key != NULL)
> {
> - rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE,
> +# ifdef HAVE_LDAP_CREATE_CONTEXT
> + rc = ldap_set_option_in_context ( ldap_context,
> +# else
> + rc = ldap_set_option (NULL,
> +# endif
> + LDAP_OPT_X_TLS_KEYFILE,
> session->conf->tls_key);
> if (rc != LDAP_SUCCESS)
> {
>
> --pf9I7BMVVzbSWLtt--
>
>
>
--
-- Howard Chu
Chief Architect, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/