Import latest from devel

This commit is contained in:
Kurt Zeilenga 2000-07-29 03:52:27 +00:00
parent 0c7768fe63
commit dda62b2b69
194 changed files with 13247 additions and 7053 deletions

View file

@ -32,3 +32,6 @@ to the University of Michigan at Ann Arbor. The name of the University
may not be used to endorse or promote products derived from this
software without specific prior written permission. This software
is provided ``as is'' without express or implied warranty.
---
$OpenLDAP$

13
INSTALL
View file

@ -90,7 +90,7 @@ these steps:
7. install the binaries and man pages. You may need to be superuser to
do this (depending on where you are installing things):
% su root -c make install
% su root -c 'make install'
That's it!
@ -107,10 +107,10 @@ these steps:
ldaptemplates.conf - display template definitions
Server configuration files:
ldapd.conf - LDAP - X.500 daemon
slapd.conf - Standalone LDAP daemon
slapd.conf - Standalone LDAP daemon configuration
schema/*.schema - Schema Definitions
There are section 5 man pages for all of these files.
There are section 5 man pages for these configuration files.
Building LDAP For More Than One Platform
@ -138,8 +138,6 @@ Follow these steps for each different platform:
4. Continue as above (starting at step 6).
Note: make depend in VPATH environment is not yet supported.
CONFIGURE OPTIONS
@ -224,4 +222,5 @@ HINTS
./configure
End of OpenLDAP INSTALL file.
---
$OpenLDAP$

23
LICENSE
View file

@ -1,31 +1,32 @@
The OpenLDAP Public License
Version 2.2.1, 1 March 2000
Version 2.3, 28 July 2000
Redistribution and use of this software and associated documentation
("Software"), with or without modification, are permitted provided
that the following conditions are met:
1. Redistributions of source code must retain copyright statements
and notices. Redistributions must also contain a copy of this
document.
and notices.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
2. Redistributions in binary form must reproduce applicable copyright
statements and notices, this list of conditions, and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. The name "OpenLDAP" must not be used to endorse or promote
3. Redistributions must contain a verbatim copy of this document.
4. The name "OpenLDAP" must not be used to endorse or promote
products derived from this Software without prior written permission
of the OpenLDAP Foundation.
4. Products derived from this Software may not be called "OpenLDAP"
5. Products derived from this Software may not be called "OpenLDAP"
nor may "OpenLDAP" appear in their names without prior written
permission of the OpenLDAP Foundation.
5. Due credit should be given to the OpenLDAP Project
6. Due credit should be given to the OpenLDAP Project
(http://www.openldap.org/).
6. The OpenLDAP Foundation may revise this license from time to
7. The OpenLDAP Foundation may revise this license from time to
time. Each revision is distinguished by a version number. You
may use the Software under terms of this license revision or under
the terms of any subsequent revision of the license.

3
README
View file

@ -74,3 +74,6 @@ SUPPORT / FEEDBACK / PROBLEM REPORTS / DISCUSSIONS
by sending mail to OpenLDAP-its@OpenLDAP.org. Do not use
this system for general or software equiries. Please direct
these to the appropriate mailing list.
---
$OpenLDAP$

View file

@ -139,11 +139,12 @@ main( int argc, char **argv )
#ifdef GO500_HOSTNAME
strcpy( myhost, GO500_HOSTNAME );
#else
if ( myhost[0] == '\0' && gethostname( myhost, sizeof(myhost) )
if ( myhost[0] == '\0' && gethostname( myhost, sizeof(myhost)-1 )
== -1 ) {
perror( "gethostname" );
exit( EXIT_FAILURE );
}
myhost[sizeof(myhost)-1] = '\0';
#endif
#ifdef HAVE_SYSCONF
@ -213,7 +214,7 @@ main( int argc, char **argv )
}
#ifdef LDAP_PROCTITLE
setproctitle( hp == NULL ? inet_ntoa( from.sin_addr ) :
setproctitle( "%s", hp == NULL ? inet_ntoa( from.sin_addr ) :
hp->h_name );
#endif
}
@ -344,7 +345,7 @@ wait4child( int sig )
; /* NULL */
#endif
(void) SIGNAL( SIGCHLD, wait4child );
(void) SIGNAL_REINSTALL ( SIGCHLD, wait4child );
}
static void

View file

@ -176,11 +176,12 @@ main (int argc, char **argv )
#ifdef GO500GW_HOSTNAME
strcpy( myhost, GO500GW_HOSTNAME );
#else
if ( myhost[0] == '\0' && gethostname( myhost, sizeof(myhost) )
if ( myhost[0] == '\0' && gethostname( myhost, sizeof(myhost)-1 )
== -1 ) {
perror( "gethostname" );
exit( EXIT_FAILURE );
}
myhost[sizeof(myhost)-1] = '\0';
#endif
/* detach if stderr is redirected or no debugging */
@ -236,7 +237,7 @@ main (int argc, char **argv )
}
#ifdef LDAP_PROCTITLE
setproctitle( hp == NULL ? inet_ntoa( from.sin_addr ) :
setproctitle( "%s", hp == NULL ? inet_ntoa( from.sin_addr ) :
hp->h_name );
#endif
}
@ -370,7 +371,7 @@ wait4child( int sig )
; /* NULL */
#endif
(void) SIGNAL( SIGCHLD, wait4child );
(void) SIGNAL_REINSTALL ( SIGCHLD, wait4child );
}
static void

View file

@ -17,18 +17,22 @@
#include <ac/unistd.h>
#include <ldap.h>
#include "lutil_ldap.h"
#include "ldap_defaults.h"
static char *prog;
static char *binddn = NULL;
static struct berval passwd = { 0, NULL};
static struct berval passwd = { 0, NULL };
static char *ldaphost = NULL;
static int ldapport = 0;
static int prune = 0;
#ifdef HAVE_CYRUS_SASL
static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
static char *sasl_mech = NULL;
static char *sasl_realm = NULL;
static char *sasl_authc_id = NULL;
static char *sasl_authz_id = NULL;
static char *sasl_mech = NULL;
static int sasl_integrity = 0;
static int sasl_privacy = 0;
static char *sasl_secprops = NULL;
#endif
static int use_tls = 0;
static int not, verbose, contoper;
@ -50,30 +54,32 @@ usage( const char *s )
"usage: %s [options] [dn]...\n"
" dn: list of DNs to delete. If not given, it will be readed from stdin\n"
" or from the file specified with \"-f file\".\n"
"options:\n"
" -c\t\tcontinuous operation mode (do not stop on errors)\n"
" -C\t\tchase referrals\n"
" -d level\tset LDAP debugging level to `level'\n"
" -D binddn\tbind DN\n"
" -E\t\trequest SASL privacy (-EE to make it critical)\n"
" -f file\t\tdelete DNs listed in `file'\n"
" -h host\t\tLDAP server\n"
" -I\t\trequest SASL integrity checking (-II to make it\n"
" \tcritical)\n"
" -k\t\tuse Kerberos authentication\n"
" -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
" -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
" -n\t\tshow what would be done but don't actually delete\n"
" -p port\t\tport on LDAP server\n"
" -P version\tprocotol version (default: 3)\n"
" -r\t\tdelete recursively\n"
" -U user\t\tSASL authentication identity (username)\n"
" -v\t\trun in verbose mode (diagnostics to standard output)\n"
" -w passwd\tbind passwd (for simple authentication)\n"
" -W\t\tprompt for bind passwd\n"
" -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech\t\tSASL mechanism\n"
" -Z\t\tissue Start TLS request (-ZZ to require successful response)\n"
"Delete Options:\n"
" -r delete recursively\n"
"Common options:\n"
" -d level set LDAP debugging level to `level'\n"
" -D binddn bind DN\n"
" -f file read operations from `file'\n"
" -h host LDAP server\n"
" -I use SASL Interactive mode\n"
" -k use Kerberos authentication\n"
" -K like -k, but do only step 1 of the Kerberos bind\n"
" -M enable Manage DSA IT control (-MM to make critical)\n"
" -n show what would be done but don't actually search\n"
" -O props SASL security properties\n"
" -p port port on LDAP server\n"
" -P version procotol version (default: 3)\n"
" -Q use SASL Quiet mode\n"
" -R realm SASL realm\n"
" -U user SASL authentication identity (username)\n"
" -v run in verbose mode (diagnostics to standard output)\n"
" -w passwd bind passwd (for simple authentication)\n"
" -W prompt for bind passwd\n"
" -x Simple authentication\n"
" -X id SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech SASL mechanism\n"
" -Z Start TLS request (-ZZ to require successful response)\n"
, s );
exit( EXIT_FAILURE );
@ -89,38 +95,258 @@ main( int argc, char **argv )
not = verbose = contoper = want_bindpw = debug = manageDSAit = referrals = 0;
fp = NULL;
authmethod = LDAP_AUTH_SIMPLE;
authmethod = -1;
version = -1;
while (( i = getopt( argc, argv, "cCD:d:Ef:h:IKMnP:p:rU:vWw:X:Y:Z" )) != EOF ) {
prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : ++prog;
while (( i = getopt( argc, argv, "cf:r" "Cd:D:h:IkKMnO:p:P:QRU:vw:WxX:Y:Z" )) != EOF ) {
switch( i ) {
/* Delete Specific Options */
case 'c': /* continuous operation mode */
++contoper;
break;
case 'f': /* read DNs from a file */
if( fp != NULL ) {
fprintf( stderr, "%s: -f previously specified\n" );
return EXIT_FAILURE;
}
if (( fp = fopen( optarg, "r" )) == NULL ) {
perror( optarg );
exit( EXIT_FAILURE );
}
break;
case 'r':
prune = 1;
break;
/* Common Options */
case 'C':
referrals++;
break;
case 'd':
debug |= atoi( optarg );
break;
case 'D': /* bind DN */
if( binddn != NULL ) {
fprintf( stderr, "%s: -D previously specified\n" );
return EXIT_FAILURE;
}
binddn = strdup( optarg );
break;
case 'h': /* ldap host */
if( ldaphost != NULL ) {
fprintf( stderr, "%s: -h previously specified\n" );
return EXIT_FAILURE;
}
ldaphost = strdup( optarg );
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -I incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_INTERACTIVE;
break;
#else
fprintf( stderr, "%s: was not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'k': /* kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: -k incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
return( EXIT_FAILURE );
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return EXIT_FAILURE;
#endif
break;
case 'K': /* kerberos bind, part one only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return( EXIT_FAILURE );
#endif
break;
case 'c': /* continuous operation mode */
++contoper;
break;
case 'C':
referrals++;
case 'M':
/* enable Manage DSA IT */
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
manageDSAit++;
version = LDAP_VERSION3;
break;
case 'h': /* ldap host */
ldaphost = strdup( optarg );
case 'n': /* print deletes, don't actually do them */
++not;
break;
case 'D': /* bind DN */
binddn = strdup( optarg );
case 'O':
#ifdef HAVE_CYRUS_SASL
if( sasl_secprops != NULL ) {
fprintf( stderr, "%s: -O previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_secprops = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'p':
if( ldapport ) {
fprintf( stderr, "%s: -p previously specified\n" );
return EXIT_FAILURE;
}
ldapport = atoi( optarg );
break;
case 'P':
switch( atoi(optarg) ) {
case 2:
if( version == LDAP_VERSION3 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION2;
break;
case 3:
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
break;
default:
fprintf( stderr, "%s: protocol version should be 2 or 3\n",
prog );
usage( prog );
return( EXIT_FAILURE );
} break;
case 'Q':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Q incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_QUIET;
break;
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'R':
#ifdef HAVE_CYRUS_SASL
if( sasl_realm != NULL ) {
fprintf( stderr, "%s: -R previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -R incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_realm = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
if( sasl_authc_id != NULL ) {
fprintf( stderr, "%s: -U previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -U incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authc_id = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'w': /* password */
passwd.bv_val = strdup( optarg );
@ -128,151 +354,103 @@ main( int argc, char **argv )
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '*';
*p = '\0';
}
}
passwd.bv_len = strlen( passwd.bv_val );
break;
case 'f': /* read DNs from a file */
if (( fp = fopen( optarg, "r" )) == NULL ) {
perror( optarg );
exit( EXIT_FAILURE );
}
break;
case 'd':
debug |= atoi( optarg );
break;
case 'p':
ldapport = atoi( optarg );
break;
case 'n': /* print deletes, don't actually do them */
++not;
break;
case 'r':
prune = 1;
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'M':
/* enable Manage DSA IT */
manageDSAit++;
break;
case 'W':
want_bindpw++;
break;
case 'P':
switch( atoi(optarg) )
{
case 2:
version = LDAP_VERSION2;
break;
case 3:
version = LDAP_VERSION3;
break;
default:
fprintf( stderr, "protocol version should be 2 or 3\n" );
usage( argv[0] );
return( EXIT_FAILURE );
}
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
sasl_integrity++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'E':
#ifdef HAVE_CYRUS_SASL
sasl_privacy++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) {
sasl_mech = strdup( optarg );
if( sasl_mech != NULL ) {
fprintf( stderr, "%s: -Y previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Y incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_mech = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
sasl_authc_id = strdup( optarg );
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
case 'x':
if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SIMPLE;
break;
case 'X':
#ifdef HAVE_CYRUS_SASL
sasl_authz_id = strdup( optarg );
if( sasl_authz_id != NULL ) {
fprintf( stderr, "%s: -X previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: -X incompatible with "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authz_id = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'Z':
#ifdef HAVE_TLS
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Z incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
use_tls++;
#else
fprintf( stderr, "%s was not compiled with TLS support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with TLS support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
default:
usage( argv[0] );
fprintf( stderr, "%s: unrecongized option -%c\n",
prog, optopt );
usage( prog );
return( EXIT_FAILURE );
}
}
if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod ==
LDAP_AUTH_KRBV41 ) ) {
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "Kerberos requires LDAPv2\n" );
return( EXIT_FAILURE );
}
version = LDAP_VERSION2;
}
else if ( authmethod == LDAP_AUTH_SASL ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf( stderr, "SASL requires LDAPv3\n" );
return( EXIT_FAILURE );
}
if (version == -1) {
version = LDAP_VERSION3;
}
if( manageDSAit ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf(stderr, "manage DSA control requires LDAPv3\n");
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
}
if( use_tls ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf(stderr, "Start TLS requires LDAPv3\n");
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
if (authmethod == -1 && version > LDAP_VERSION2) {
#ifdef HAVE_CYRUS_SASL
authmethod = LDAP_AUTH_SASL;
#else
authmethod = LDAP_AUTH_SIMPLE;
#endif
}
if ( fp == NULL ) {
@ -314,10 +492,6 @@ main( int argc, char **argv )
return EXIT_FAILURE;
}
if (version == -1 ) {
version = 3;
}
if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
!= LDAP_OPT_SUCCESS )
{
@ -341,41 +515,37 @@ main( int argc, char **argv )
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
int minssf = 0, maxssf = 0;
void *defaults;
if ( sasl_integrity > 0 )
maxssf = 1;
if ( sasl_integrity > 1 )
minssf = 1;
if ( sasl_privacy > 0 )
maxssf = 100000; /* Something big value */
if ( sasl_privacy > 1 )
minssf = 56;
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
(void *)&minssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
"%d\n", minssf);
return( EXIT_FAILURE );
}
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
(void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
"%d\n", maxssf);
return( EXIT_FAILURE );
if( sasl_secprops != NULL ) {
rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
(void *) sasl_secprops );
if( rc != LDAP_OPT_SUCCESS ) {
fprintf( stderr,
"Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
sasl_secprops );
return( EXIT_FAILURE );
}
}
rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
sasl_authz_id, sasl_mech,
passwd.bv_len ? &passwd : NULL,
NULL, NULL );
defaults = lutil_sasl_defaults( ld,
sasl_mech,
sasl_realm,
sasl_authc_id,
passwd.bv_val,
sasl_authz_id );
rc = ldap_sasl_interactive_bind_s( ld, binddn,
sasl_mech, NULL, NULL,
sasl_flags, lutil_sasl_interact, defaults );
if( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
return( EXIT_FAILURE );
}
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
fprintf( stderr, "%s: not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
@ -456,8 +626,8 @@ static int dodelete(
rc = ldap_delete_ext( ld, dn, NULL, NULL, &id );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldapdelete: ldap_delete_ext: %s (%d)\n",
ldap_err2string( rc ), rc );
fprintf( stderr, "%s: ldap_delete_ext: %s (%d)\n",
prog, ldap_err2string( rc ), rc );
return rc;
}
@ -470,8 +640,8 @@ static int dodelete(
rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 1 );
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldapdelete: ldap_parse_result: %s (%d)\n",
ldap_err2string( rc ), rc );
fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
prog, ldap_err2string( rc ), rc );
return rc;
}

View file

@ -29,20 +29,22 @@
#include <ldap.h>
#include "lutil_ldap.h"
#include "ldif.h"
#include "ldap_defaults.h"
static char *prog;
static char *binddn = NULL;
static struct berval passwd = { 0, NULL};
static struct berval passwd = { 0, NULL };
static char *ldaphost = NULL;
static int ldapport = 0;
#ifdef HAVE_CYRUS_SASL
static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
static char *sasl_realm = NULL;
static char *sasl_authc_id = NULL;
static char *sasl_authz_id = NULL;
static char *sasl_mech = NULL;
static int sasl_integrity = 0;
static int sasl_privacy = 0;
static char *sasl_secprops = NULL;
#endif
static int use_tls = 0;
static int ldapadd, replace, not, verbose, contoper, force;
@ -97,32 +99,36 @@ usage( const char *prog )
"usage: %s [options]\n"
" The list of desired operations are read from stdin or from the file\n"
" specified by \"-f file\".\n"
"options:\n"
" -a\t\tadd values (default%s)\n"
" -b\t\tread values from files (for binary attributes)\n"
" -c\t\tcontinuous operation\n"
" -C\t\tchase referrals\n"
" -d level\tset LDAP debugging level to `level'\n"
" -D dn\t\tbind DN\n"
" -E\t\trequest SASL privacy (-EE to make it critical)\n"
" -f file\t\tperform sequence of operations listed in file\n"
" -F\t\tforce all changes records to be used\n"
" -h host\t\tLDAP server\n"
" -I\t\trequest SASL integrity checking (-II to make it\n"
" \tcritical)\n"
" -k\t\tuse Kerberos authentication\n"
" -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
" -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
" -n\t\tprint changes, don't actually do them\n"
" -p port\t\tport on LDAP server\n"
" -r\t\treplace values\n"
" -U user\t\tSASL authentication identity (username)\n"
" -v\t\tverbose mode\n"
" -w passwd\tbind password (for Simple authentication)\n"
" -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech\t\tSASL mechanism\n"
" -Z\t\tissue Start TLS request (-ZZ to require successful response)\n"
"Add or modify options:\n"
" -a add values (default%s)\n"
" -r replace values\n"
" -F force all changes records to be used\n"
"Common options:\n"
" -d level set LDAP debugging level to `level'\n"
" -D binddn bind DN\n"
" -f file read operations from `file'\n"
" -h host LDAP server\n"
" -I use SASL Interactive mode\n"
" -k use Kerberos authentication\n"
" -K like -k, but do only step 1 of the Kerberos bind\n"
" -M enable Manage DSA IT control (-MM to make critical)\n"
" -n show what would be done but don't actually search\n"
" -O props SASL security properties\n"
" -p port port on LDAP server\n"
" -P version procotol version (default: 3)\n"
" -Q use SASL Quiet mode\n"
" -R realm SASL realm\n"
" -U user SASL authentication identity (username)\n"
" -v run in verbose mode (diagnostics to standard output)\n"
" -w passwd bind passwd (for simple authentication)\n"
" -W prompt for bind passwd\n"
" -x Simple authentication\n"
" -X id SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech SASL mechanism\n"
" -Z Start TLS request (-ZZ to require successful response)\n"
, prog, (strcmp( prog, "ldapadd" ) ? " is to replace" : "") );
exit( EXIT_FAILURE );
}
@ -148,196 +154,367 @@ main( int argc, char **argv )
infile = NULL;
not = verbose = want_bindpw = debug = manageDSAit = referrals = 0;
authmethod = LDAP_AUTH_SIMPLE;
authmethod = -1;
version = -1;
while (( i = getopt( argc, argv, "acCD:d:EFf:h:IKkMnP:p:rtU:vWw:X:Y:Z" )) != EOF ) {
while (( i = getopt( argc, argv, "acrf:F" "Cd:D:h:IkKMnO:p:P:QRU:vw:WxX:Y:Z" )) != EOF ) {
switch( i ) {
/* Modify Options */
case 'a': /* add */
ldapadd = 1;
break;
case 'c': /* continuous operation */
contoper = 1;
break;
case 'C':
referrals++;
break;
case 'r': /* default is to replace rather than add values */
replace = 1;
break;
case 'k': /* kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'K': /* kerberos bind, part 1 only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
return( EXIT_FAILURE );
#endif
case 'f': /* read from file */
if( infile != NULL ) {
fprintf( stderr, "%s: -f previously specified\n" );
return EXIT_FAILURE;
}
infile = strdup( optarg );
break;
case 'F': /* force all changes records to be used */
force = 1;
break;
case 'h': /* ldap host */
ldaphost = strdup( optarg );
case 'r': /* default is to replace rather than add values */
replace = 1;
break;
/* Common Options */
case 'C':
referrals++;
break;
case 'd':
debug |= atoi( optarg );
break;
case 'D': /* bind DN */
if( binddn != NULL ) {
fprintf( stderr, "%s: -D previously specified\n" );
return EXIT_FAILURE;
}
binddn = strdup( optarg );
break;
case 'h': /* ldap host */
if( ldaphost != NULL ) {
fprintf( stderr, "%s: -h previously specified\n" );
return EXIT_FAILURE;
}
ldaphost = strdup( optarg );
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -I incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_INTERACTIVE;
break;
#else
fprintf( stderr, "%s: was not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'k': /* kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: -k incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return EXIT_FAILURE;
#endif
break;
case 'K': /* kerberos bind, part one only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return( EXIT_FAILURE );
#endif
break;
case 'M':
/* enable Manage DSA IT */
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
manageDSAit++;
version = LDAP_VERSION3;
break;
case 'n': /* print deletes, don't actually do them */
++not;
break;
case 'O':
#ifdef HAVE_CYRUS_SASL
if( sasl_secprops != NULL ) {
fprintf( stderr, "%s: -O previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_secprops = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'p':
if( ldapport ) {
fprintf( stderr, "%s: -p previously specified\n" );
return EXIT_FAILURE;
}
ldapport = atoi( optarg );
break;
case 'P':
switch( atoi(optarg) ) {
case 2:
if( version == LDAP_VERSION3 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION2;
break;
case 3:
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
break;
default:
fprintf( stderr, "%s: protocol version should be 2 or 3\n",
prog );
usage( prog );
return( EXIT_FAILURE );
} break;
case 'Q':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Q incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_QUIET;
break;
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'R':
#ifdef HAVE_CYRUS_SASL
if( sasl_realm != NULL ) {
fprintf( stderr, "%s: -R previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -R incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_realm = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
if( sasl_authc_id != NULL ) {
fprintf( stderr, "%s: -U previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -U incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authc_id = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'w': /* password */
passwd.bv_val = strdup( optarg );
{
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '*';
*p = '\0';
}
}
passwd.bv_len = strlen( passwd.bv_val );
break;
case 'd':
debug |= atoi( optarg );
break;
case 'f': /* read from file */
infile = strdup( optarg );
break;
case 'p':
ldapport = atoi( optarg );
break;
case 'n': /* print adds, don't actually do them */
++not;
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'M':
/* enable Manage DSA IT */
manageDSAit++;
break;
case 'W':
want_bindpw++;
break;
case 'P':
switch( atoi(optarg) )
{
case 2:
version = LDAP_VERSION2;
break;
case 3:
version = LDAP_VERSION3;
break;
default:
fprintf( stderr, "protocol version should be 2 or 3\n" );
usage( argv[0] );
}
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
sasl_integrity++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'E':
#ifdef HAVE_CYRUS_SASL
sasl_privacy++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) {
sasl_mech = strdup( optarg );
if( sasl_mech != NULL ) {
fprintf( stderr, "%s: -Y previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Y incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_mech = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
sasl_authc_id = strdup( optarg );
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
case 'x':
if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SIMPLE;
break;
case 'X':
#ifdef HAVE_CYRUS_SASL
sasl_authz_id = strdup( optarg );
if( sasl_authz_id != NULL ) {
fprintf( stderr, "%s: -X previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: -X incompatible with "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authz_id = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'Z':
#ifdef HAVE_TLS
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Z incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
use_tls++;
#else
fprintf( stderr, "%s was not compiled with TLS support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with TLS support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
default:
fprintf( stderr, "%s: unrecongized option -%c\n",
prog, optopt );
usage( prog );
}
}
if ( argc != optind )
if (version == -1) {
version = LDAP_VERSION3;
}
if (authmethod == -1 && version > LDAP_VERSION2) {
#ifdef HAVE_CYRUS_SASL
authmethod = LDAP_AUTH_SASL;
#else
authmethod = LDAP_AUTH_SIMPLE;
#endif
}
if ( argc != optind )
usage( prog );
if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod ==
LDAP_AUTH_KRBV41 ) ) {
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "Kerberos requires LDAPv2\n" );
return( EXIT_FAILURE );
}
version = LDAP_VERSION2;
}
else if ( authmethod == LDAP_AUTH_SASL ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf( stderr, "SASL requires LDAPv3\n" );
return( EXIT_FAILURE );
}
version = LDAP_VERSION3;
}
if( manageDSAit ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf(stderr, "manage DSA control requires LDAPv3\n");
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
}
if( use_tls ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf(stderr, "Start TLS requires LDAPv3\n");
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
}
if ( infile != NULL ) {
if (( fp = fopen( infile, "r" )) == NULL ) {
perror( infile );
@ -404,41 +581,37 @@ main( int argc, char **argv )
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
int minssf = 0, maxssf = 0;
void *defaults;
if ( sasl_integrity > 0 )
maxssf = 1;
if ( sasl_integrity > 1 )
minssf = 1;
if ( sasl_privacy > 0 )
maxssf = 100000; /* Something big value */
if ( sasl_privacy > 1 )
minssf = 56;
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
(void *)&minssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
"%d\n", minssf);
return( EXIT_FAILURE );
}
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
(void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
"%d\n", minssf);
return( EXIT_FAILURE );
if( sasl_secprops != NULL ) {
rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
(void *) sasl_secprops );
if( rc != LDAP_OPT_SUCCESS ) {
fprintf( stderr,
"Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
sasl_secprops );
return( EXIT_FAILURE );
}
}
rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
sasl_authz_id, sasl_mech,
passwd.bv_len ? &passwd : NULL,
NULL, NULL );
defaults = lutil_sasl_defaults( ld,
sasl_mech,
sasl_realm,
sasl_authc_id,
passwd.bv_val,
sasl_authz_id );
rc = ldap_sasl_interactive_bind_s( ld, binddn,
sasl_mech, NULL, NULL,
sasl_flags, lutil_sasl_interact, defaults );
if( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
return( EXIT_FAILURE );
}
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
fprintf( stderr, "%s: not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif

View file

@ -29,17 +29,21 @@
#include <ac/unistd.h>
#include <ldap.h>
#include "lutil_ldap.h"
#include "ldap_defaults.h"
static char *prog = NULL;
static char *binddn = NULL;
static struct berval passwd = { 0, NULL};
static struct berval passwd = { 0, NULL };
static char *ldaphost = NULL;
static int ldapport = 0;
#ifdef HAVE_CYRUS_SASL
static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
static char *sasl_realm = NULL;
static char *sasl_authc_id = NULL;
static char *sasl_authz_id = NULL;
static char *sasl_mech = NULL;
static int sasl_integrity = 0;
static int sasl_privacy = 0;
static char *sasl_secprops = NULL;
#endif
static int use_tls = 0;
static int not, verbose, contoper;
@ -61,31 +65,35 @@ usage( const char *s )
" dn rdn: If given, rdn will replace the RDN of the entry specified by DN\n"
" If not given, the list of modifications is read from stdin or\n"
" from the file specified by \"-f file\" (see man page).\n"
"options:\n"
" -c\t\tcontinuous operation mode (do not stop on errors)\n"
" -C\t\tchase referrals\n"
" -d level\tset LDAP debugging level to `level'\n"
" -D binddn\tbind DN\n"
" -E\t\trequest SASL privacy (-EE to make it critical)\n"
" -f file\t\tdo renames listed in `file'\n"
" -h host\t\tLDAP server\n"
" -I\t\trequest SASL integrity checking (-II to make it\n"
" \tcritical)\n"
" -k\t\tuse Kerberos authentication\n"
" -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
" -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
" -n\t\tshow what would be done but don't actually do it\n"
" -p port\t\tport on LDAP server\n"
" -P version\tprocotol version (default: 3)\n"
" -r\t\tremove old RDN\n"
" -s newsuperior\tnew superior entry\n"
" -U user\t\tSASL authentication identity (username)\n"
" -v\t\trun in verbose mode (diagnostics to standard output)\n"
" -w passwd\tbind passwd (for simple authentication)\n"
" -W\t\tprompt for bind passwd\n"
" -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech\t\tSASL mechanism\n"
" -Z\t\tissue Start TLS request (-ZZ to require successful response)\n"
"Rename options:\n"
" -c continuous operation mode (do not stop on errors)\n"
" -f file read operations from `file'\n"
" -r remove old RDN\n"
" -s newsup new superior entry\n"
"Common options:\n"
" -d level set LDAP debugging level to `level'\n"
" -D binddn bind DN\n"
" -f file read operations from `file'\n"
" -h host LDAP server\n"
" -I use SASL Interactive mode\n"
" -k use Kerberos authentication\n"
" -K like -k, but do only step 1 of the Kerberos bind\n"
" -M enable Manage DSA IT control (-MM to make critical)\n"
" -n show what would be done but don't actually search\n"
" -O props SASL security properties\n"
" -p port port on LDAP server\n"
" -P version procotol version (default: 3)\n"
" -Q use SASL Quiet mode\n"
" -R realm SASL realm\n"
" -U user SASL authentication identity (username)\n"
" -v run in verbose mode (diagnostics to standard output)\n"
" -w passwd bind passwd (for simple authentication)\n"
" -W prompt for bind passwd\n"
" -x Simple authentication\n"
" -X id SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech SASL mechanism\n"
" -Z Start TLS request (-ZZ to require successful response)\n"
, s );
exit( EXIT_FAILURE );
@ -94,7 +102,7 @@ usage( const char *s )
int
main(int argc, char **argv)
{
char *myname,*infile, *entrydn = NULL, *rdn = NULL, buf[ 4096 ];
char *infile, *entrydn = NULL, *rdn = NULL, buf[ 4096 ];
FILE *fp;
int rc, i, remove, havedn, authmethod, version, want_bindpw, debug, manageDSAit;
int referrals;
@ -106,41 +114,261 @@ main(int argc, char **argv)
authmethod = LDAP_AUTH_SIMPLE;
version = -1;
myname = (myname = strrchr(argv[0], '/')) == NULL ? argv[0] : ++myname;
prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : ++prog;
while (( i = getopt( argc, argv, "cCD:d:Ef:h:IKkMnP:p:rs:U:vWw:X:Y:Z" )) != EOF ) {
while (( i = getopt( argc, argv, "cf:rs:" "Cd:D:h:IkKMnO:p:P:QRU:vw:WxX:Y:Z" )) != EOF ) {
switch( i ) {
case 'k': /* kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
return( EXIT_FAILURE );
#endif
/* Modrdn Options */
case 'c':
contoper++;
break;
case 'K': /* kerberos bind, part one only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'c': /* continuous operation mode */
++contoper;
case 'f': /* read from file */
if( infile != NULL ) {
fprintf( stderr, "%s: -f previously specified\n" );
return EXIT_FAILURE;
}
infile = strdup( optarg );
break;
case 'r': /* remove old RDN */
remove++;
break;
case 's': /* newSuperior */
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
newSuperior = strdup( optarg );
version = LDAP_VERSION3;
break;
/* Common Options */
case 'C':
referrals++;
break;
case 'h': /* ldap host */
ldaphost = strdup( optarg );
case 'd':
debug |= atoi( optarg );
break;
case 'D': /* bind DN */
if( binddn != NULL ) {
fprintf( stderr, "%s: -D previously specified\n" );
return EXIT_FAILURE;
}
binddn = strdup( optarg );
break;
case 's': /* newSuperior */
newSuperior = strdup( optarg );
version = LDAP_VERSION3; /* This option => force V3 */
case 'h': /* ldap host */
if( ldaphost != NULL ) {
fprintf( stderr, "%s: -h previously specified\n" );
return EXIT_FAILURE;
}
ldaphost = strdup( optarg );
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -I incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_INTERACTIVE;
break;
#else
fprintf( stderr, "%s: was not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'k': /* kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: -k incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return EXIT_FAILURE;
#endif
break;
case 'K': /* kerberos bind, part one only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return( EXIT_FAILURE );
#endif
break;
case 'M':
/* enable Manage DSA IT */
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
manageDSAit++;
version = LDAP_VERSION3;
break;
case 'n': /* print deletes, don't actually do them */
++not;
break;
case 'O':
#ifdef HAVE_CYRUS_SASL
if( sasl_secprops != NULL ) {
fprintf( stderr, "%s: -O previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_secprops = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'p':
if( ldapport ) {
fprintf( stderr, "%s: -p previously specified\n" );
return EXIT_FAILURE;
}
ldapport = atoi( optarg );
break;
case 'P':
switch( atoi(optarg) ) {
case 2:
if( version == LDAP_VERSION3 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION2;
break;
case 3:
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
break;
default:
fprintf( stderr, "%s: protocol version should be 2 or 3\n",
prog );
usage( prog );
return( EXIT_FAILURE );
} break;
case 'Q':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Q incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_QUIET;
break;
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'R':
#ifdef HAVE_CYRUS_SASL
if( sasl_realm != NULL ) {
fprintf( stderr, "%s: -R previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -R incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_realm = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
if( sasl_authc_id != NULL ) {
fprintf( stderr, "%s: -U previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -U incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authc_id = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'w': /* password */
passwd.bv_val = strdup( optarg );
@ -148,161 +376,105 @@ main(int argc, char **argv)
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '*';
*p = '\0';
}
}
passwd.bv_len = strlen( passwd.bv_val );
break;
case 'd':
debug |= atoi( optarg );
break;
case 'f': /* read from file */
infile = strdup( optarg );
break;
case 'p':
ldapport = atoi( optarg );
break;
case 'n': /* print adds, don't actually do them */
++not;
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'r': /* remove old RDN */
remove++;
break;
case 'M':
/* enable Manage DSA IT */
manageDSAit++;
break;
case 'W':
want_bindpw++;
break;
case 'P':
switch( atoi(optarg) )
{
case 2:
version = LDAP_VERSION2;
break;
case 3:
version = LDAP_VERSION3;
break;
default:
fprintf( stderr, "protocol version should be 2 or 3\n" );
usage( argv[0] );
return( EXIT_FAILURE );
}
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
sasl_integrity++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'E':
#ifdef HAVE_CYRUS_SASL
sasl_privacy++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) {
sasl_mech = strdup( optarg );
if( sasl_mech != NULL ) {
fprintf( stderr, "%s: -Y previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Y incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_mech = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
sasl_authc_id = strdup( optarg );
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
case 'x':
if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SIMPLE;
break;
case 'X':
#ifdef HAVE_CYRUS_SASL
sasl_authz_id = strdup( optarg );
if( sasl_authz_id != NULL ) {
fprintf( stderr, "%s: -X previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: -X incompatible with "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authz_id = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'Z':
#ifdef HAVE_TLS
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Z incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
use_tls++;
#else
fprintf( stderr, "%s was not compiled with TLS support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with TLS support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
default:
fprintf( stderr, "%s: unrecongized option -%c\n",
prog, optopt );
usage( argv[0] );
return( EXIT_FAILURE );
}
}
if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod ==
LDAP_AUTH_KRBV41 ) ) {
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "Kerberos requires LDAPv2\n" );
return( EXIT_FAILURE );
}
version = LDAP_VERSION2;
}
else if ( authmethod == LDAP_AUTH_SASL ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf( stderr, "SASL requires LDAPv3\n" );
return( EXIT_FAILURE );
}
if (version == -1) {
version = LDAP_VERSION3;
}
if (authmethod == -1 && version > LDAP_VERSION2) {
#ifdef HAVE_CYRUS_SASL
authmethod = LDAP_AUTH_SASL;
#else
authmethod = LDAP_AUTH_SIMPLE;
#endif
}
if( manageDSAit ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf(stderr, "manage DSA control requires LDAPv3\n");
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
}
if( use_tls ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf(stderr, "Start TLS requires LDAPv3\n");
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
}
if (newSuperior != NULL) {
if (version == LDAP_VERSION2) {
fprintf( stderr,
"%s: version conflict!, -s newSuperior requires LDAPv3\n",
myname);
usage( argv[0] );
return( EXIT_FAILURE );
}
version = LDAP_VERSION3;
}
havedn = 0;
if (argc - optind == 2) {
if (( rdn = strdup( argv[argc - 1] )) == NULL ) {
@ -315,7 +487,8 @@ main(int argc, char **argv)
}
++havedn;
} else if ( argc - optind != 0 ) {
fprintf( stderr, "%s: invalid number of arguments, only two allowed\n", myname);
fprintf( stderr, "%s: invalid number of arguments (%d), "
"only two allowed\n", prog, argc-optind );
usage( argv[0] );
return( EXIT_FAILURE );
}
@ -356,10 +529,6 @@ main(int argc, char **argv)
return EXIT_FAILURE;
}
if (version == -1 ) {
version = 3;
}
if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
!= LDAP_OPT_SUCCESS )
{
@ -383,41 +552,37 @@ main(int argc, char **argv)
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
int minssf = 0, maxssf = 0;
void *defaults;
if ( sasl_integrity > 0 )
maxssf = 1;
if ( sasl_integrity > 1 )
minssf = 1;
if ( sasl_privacy > 0 )
maxssf = 100000; /* Something big value */
if ( sasl_privacy > 1 )
minssf = 56;
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
(void *)&minssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
"%d\n", minssf);
return( EXIT_FAILURE );
}
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
(void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
"%d\n", maxssf);
return( EXIT_FAILURE );
if( sasl_secprops != NULL ) {
rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
(void *) sasl_secprops );
if( rc != LDAP_OPT_SUCCESS ) {
fprintf( stderr,
"Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
sasl_secprops );
return( EXIT_FAILURE );
}
}
rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
sasl_authz_id, sasl_mech,
passwd.bv_len ? &passwd : NULL,
NULL, NULL );
defaults = lutil_sasl_defaults( ld,
sasl_mech,
sasl_realm,
sasl_authc_id,
passwd.bv_val,
sasl_authz_id );
rc = ldap_sasl_interactive_bind_s( ld, binddn,
sasl_mech, NULL, NULL,
sasl_flags, lutil_sasl_interact, defaults );
if( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
return( EXIT_FAILURE );
}
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
fprintf( stderr, "%s: not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
@ -509,8 +674,8 @@ static int domodrdn(
NULL, NULL, &id );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldapmodrdn: ldap_rename: %s (%d)\n",
ldap_err2string( rc ), rc );
fprintf( stderr, "%s: ldap_rename: %s (%d)\n",
prog, ldap_err2string( rc ), rc );
return rc;
}
@ -523,8 +688,8 @@ static int domodrdn(
rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 1 );
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldapmodrdn: ldap_parse_result: %s (%d)\n",
ldap_err2string( rc ), rc );
fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
prog, ldap_err2string( rc ), rc );
return rc;
}

View file

@ -19,6 +19,7 @@
#include <ldap.h>
#include "lutil_ldap.h"
#include "ldap_defaults.h"
static int verbose = 0;
@ -27,30 +28,34 @@ static void
usage(const char *s)
{
fprintf(stderr,
"Change the password of an LDAP entry\n\n"
"usage: %s [options] dn\n"
" dn: the DN of the entry whose password must be changed\n"
"options:\n"
" -a secret\told password\n"
" -A\t\tprompt for old password\n"
" -d level\tdebugging level\n"
" -C\t\tchase referrals\n"
" -D binddn\tbind DN\n"
" -E\t\trequest SASL privacy (-EE to make it critical)\n"
" -h host\t\tLDAP server (default: localhost)\n"
" -I\t\trequest SASL integrity checking (-II to make it\n"
" \tcritical)\n"
" -n\t\tmake no modifications\n"
" -p port\t\tport on LDAP server\n"
" -S\t\tprompt for new password\n"
" -s secret\tnew password\n"
" -U user\t\tSASL authentication identity (username)\n"
" -v\t\tverbose mode\n"
" -w passwd\tbind password (for simple authentication)\n"
" -W\t\tprompt for bind password\n"
" -X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech\t\tSASL mechanism\n"
" -Z\t\tissue Start TLS request (-ZZ to require successful response)\n"
"Change password of an LDAP user\n\n"
"usage: %s [options] user\n"
" user: the identity of the user, normally a DN\n"
"Password change options:\n"
" -a secret old password\n"
" -A prompt for old password\n"
" -s secret new password\n"
" -S prompt for new password\n"
"Common options:\n"
" -d level set LDAP debugging level to `level'\n"
" -D binddn bind DN\n"
" -f file read operations from `file'\n"
" -h host LDAP server\n"
" -I use SASL Interactive mode\n"
" -n show what would be done but don't actually search\n"
" -O props SASL security properties\n"
" -p port port on LDAP server\n"
" -Q use SASL Quiet mode\n"
" -R realm SASL realm\n"
" -U user SASL authentication identity (username)\n"
" -v run in verbose mode (diagnostics to standard output)\n"
" -w passwd bind passwd (for simple authentication)\n"
" -W prompt for bind passwd\n"
" -x Simple authentication\n"
" -X id SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech SASL mechanism\n"
" -Z Start TLS request (-ZZ to require successful response)\n"
, s );
exit( EXIT_FAILURE );
@ -60,12 +65,13 @@ int
main( int argc, char *argv[] )
{
int rc;
char *prog = NULL;
char *ldaphost = NULL;
char *dn = NULL;
char *binddn = NULL;
struct berval passwd = { 0, NULL};
struct berval passwd = { 0, NULL };
char *newpw = NULL;
char *oldpw = NULL;
@ -73,18 +79,20 @@ main( int argc, char *argv[] )
int want_newpw = 0;
int want_oldpw = 0;
int noupdates = 0;
int not = 0;
int i;
int ldapport = 0;
int debug = 0;
int version = -1;
int authmethod = LDAP_AUTH_SIMPLE;
int authmethod = -1;
int manageDSAit = 0;
#ifdef HAVE_CYRUS_SASL
unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
char *sasl_realm = NULL;
char *sasl_authc_id = NULL;
char *sasl_authz_id = NULL;
char *sasl_mech = NULL;
int sasl_integrity = 0;
int sasl_privacy = 0;
char *sasl_secprops = NULL;
#endif
int use_tls = 0;
int referrals = 0;
@ -97,16 +105,20 @@ main( int argc, char *argv[] )
char *retoid = NULL;
struct berval *retdata = NULL;
prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : ++prog;
if (argc == 1)
usage (argv[0]);
while( (i = getopt( argc, argv,
"Aa:CD:d:EIh:np:Ss:U:vWw:X:Y:Z" )) != EOF )
"Aa:Ss:" "Cd:D:h:InO:p:QRU:vw:WxX:Y:Z" )) != EOF )
{
switch (i) {
case 'A': /* prompt for oldr password */
/* Password Options */
case 'A': /* prompt for old password */
want_oldpw++;
break;
case 'a': /* old password (secret) */
oldpw = strdup (optarg);
@ -114,32 +126,10 @@ main( int argc, char *argv[] )
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '*';
*p = '\0';
}
}
break;
case 'C':
referrals++;
break;
case 'D': /* bind distinguished name */
binddn = strdup (optarg);
break;
case 'd': /* debugging option */
debug |= atoi (optarg);
break;
case 'h': /* ldap host */
ldaphost = strdup (optarg);
break;
case 'n': /* don't update entry(s) */
noupdates++;
break;
case 'p': /* ldap port */
ldapport = strtol( optarg, NULL, 10 );
break;
case 'S': /* prompt for user password */
want_newpw++;
@ -151,95 +141,330 @@ main( int argc, char *argv[] )
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '*';
*p = '\0';
}
}
break;
case 'v': /* verbose */
verbose++;
break;
/* Common Options (including options we don't use) */
case 'C':
referrals++;
break;
case 'd':
debug |= atoi( optarg );
break;
case 'D': /* bind DN */
if( binddn != NULL ) {
fprintf( stderr, "%s: -D previously specified\n" );
return EXIT_FAILURE;
}
binddn = strdup( optarg );
break;
case 'h': /* ldap host */
if( ldaphost != NULL ) {
fprintf( stderr, "%s: -h previously specified\n" );
return EXIT_FAILURE;
}
ldaphost = strdup( optarg );
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -I incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_INTERACTIVE;
break;
#else
fprintf( stderr, "%s: was not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'k': /* kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
case 'W': /* prompt for bind password */
want_bindpw++;
break;
if( authmethod != -1 ) {
fprintf( stderr, "%s: -k incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return EXIT_FAILURE;
#endif
break;
case 'K': /* kerberos bind, part one only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
case 'w': /* bind password */
passwd.bv_val = strdup (optarg);
{
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '*';
}
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return( EXIT_FAILURE );
#endif
break;
case 'M':
/* enable Manage DSA IT */
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
manageDSAit++;
version = LDAP_VERSION3;
break;
case 'n': /* print deletes, don't actually do them */
++not;
break;
case 'O':
#ifdef HAVE_CYRUS_SASL
if( sasl_secprops != NULL ) {
fprintf( stderr, "%s: -O previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_secprops = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'p':
if( ldapport ) {
fprintf( stderr, "%s: -p previously specified\n" );
return EXIT_FAILURE;
}
ldapport = atoi( optarg );
break;
case 'P':
switch( atoi(optarg) ) {
case 2:
if( version == LDAP_VERSION3 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
passwd.bv_len = strlen( passwd.bv_val );
version = LDAP_VERSION2;
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
sasl_integrity++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL "
"support\n", argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'E':
#ifdef HAVE_CYRUS_SASL
sasl_privacy++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL "
"support\n", argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if ( strcasecmp( optarg, "any" ) &&
strcmp( optarg, "*" ) ) {
sasl_mech = strdup( optarg );
case 3:
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL "
"support\n", argv[0] );
return( EXIT_FAILURE );
#endif
version = LDAP_VERSION3;
break;
case 'U':
default:
fprintf( stderr, "%s: protocol version should be 2 or 3\n",
prog );
usage( prog );
return( EXIT_FAILURE );
} break;
case 'Q':
#ifdef HAVE_CYRUS_SASL
sasl_authc_id = strdup( optarg );
authmethod = LDAP_AUTH_SASL;
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Q incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_QUIET;
break;
#else
fprintf( stderr, "%s was not compiled with SASL "
"support\n", argv[0] );
return( EXIT_FAILURE );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'X':
case 'R':
#ifdef HAVE_CYRUS_SASL
sasl_authz_id = strdup( optarg );
authmethod = LDAP_AUTH_SASL;
if( sasl_realm != NULL ) {
fprintf( stderr, "%s: -R previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -R incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_realm = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL "
"support\n", argv[0] );
return( EXIT_FAILURE );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'Z':
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
if( sasl_authc_id != NULL ) {
fprintf( stderr, "%s: -U previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -U incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authc_id = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'w': /* password */
passwd.bv_val = strdup( optarg );
{
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '\0';
}
}
passwd.bv_len = strlen( passwd.bv_val );
break;
case 'W':
want_bindpw++;
break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if( sasl_mech != NULL ) {
fprintf( stderr, "%s: -Y previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Y incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_mech = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'x':
if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SIMPLE;
break;
case 'X':
#ifdef HAVE_CYRUS_SASL
if( sasl_authz_id != NULL ) {
fprintf( stderr, "%s: -X previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: -X incompatible with "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authz_id = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'Z':
#ifdef HAVE_TLS
use_tls++;
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Z incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
use_tls++;
#else
fprintf( stderr, "%s was not compiled with TLS "
"support\n", argv[0] );
return( EXIT_FAILURE );
fprintf( stderr, "%s: not compiled with TLS support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
break;
default:
fprintf( stderr, "%s: unrecongized option -%c\n",
prog, optopt );
usage (argv[0]);
}
}
@ -248,6 +473,14 @@ main( int argc, char *argv[] )
usage( argv[0] );
}
if (authmethod == -1) {
#ifdef HAVE_CYRUS_SASL
authmethod = LDAP_AUTH_SASL;
#else
authmethod = LDAP_AUTH_SIMPLE;
#endif
}
dn = strdup( argv[optind] );
if( want_oldpw && oldpw == NULL ) {
@ -342,41 +575,37 @@ main( int argc, char *argv[] )
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
int minssf = 0, maxssf = 0;
void *defaults;
if ( sasl_integrity > 0 )
maxssf = 1;
if ( sasl_integrity > 1 )
minssf = 1;
if ( sasl_privacy > 0 )
maxssf = 100000; /* Something big value */
if ( sasl_privacy > 1 )
minssf = 56;
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
(void *)&minssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
"%d\n", minssf);
return( EXIT_FAILURE );
}
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
(void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
"%d\n", maxssf);
return( EXIT_FAILURE );
if( sasl_secprops != NULL ) {
rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
(void *) sasl_secprops );
if( rc != LDAP_OPT_SUCCESS ) {
fprintf( stderr,
"Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
sasl_secprops );
return( EXIT_FAILURE );
}
}
rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
sasl_authz_id, sasl_mech,
passwd.bv_len ? &passwd : NULL,
NULL, NULL );
defaults = lutil_sasl_defaults( ld,
sasl_mech,
sasl_realm,
sasl_authc_id,
passwd.bv_val,
sasl_authz_id );
rc = ldap_sasl_interactive_bind_s( ld, binddn,
sasl_mech, NULL, NULL,
sasl_flags, lutil_sasl_interact, defaults );
if( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
return( EXIT_FAILURE );
}
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
fprintf( stderr, "%s: not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
@ -432,7 +661,7 @@ main( int argc, char *argv[] )
ber_free( ber, 1 );
}
if ( noupdates ) {
if ( not ) {
rc = LDAP_SUCCESS;
goto skip;
}

View file

@ -31,6 +31,7 @@
#include "ldif.h"
#include "lutil.h"
#include "lutil_ldap.h"
#include "ldap_defaults.h"
static void
@ -38,50 +39,55 @@ usage( const char *s )
{
fprintf( stderr,
"usage: %s [options] [filter [attributes...]]\nwhere:\n"
"\tfilter\tRFC-2254 compliant LDAP search filter\n"
"\tattributes\twhitespace-separated list of attribute descriptions\n"
"\t which may include:\n"
"\t\t1.1 -- no attributes\n"
"\t\t* -- all user attributes\n"
"\t\t+ -- all operational attributes\n"
"options:\n"
"\t-a deref\tdereference aliases: never (default), always, search, or find\n"
"\t-A\t\tretrieve attribute names only (no values)\n"
"\t-b basedn\tbase dn for search\n"
"\t-d level\tset LDAP debugging level to `level'\n"
"\t-D binddn\tbind DN\n"
"\t-E\t\trequest SASL privacy (-EE to make it critical)\n"
"\t-f file\t\tperform sequence of searches listed in `file'\n"
"\t-h host\t\tLDAP server\n"
"\t-I\t\trequest SASL integrity checking (-II to make it\n"
"\t\t\tcritical)\n"
"\t-k\t\tuse Kerberos authentication\n"
"\t-K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
"\t-l limit\ttime limit (in seconds) for search\n"
"\t-L\t\tprint responses in LDIFv1 format\n"
"\t-LL\t\tprint responses in LDIF format without comments\n"
"\t-LLL\t\tprint responses in LDIF format without comments\n"
"\t\t\tand version\n"
"\t-M\t\tenable Manage DSA IT control (-MM to make critical)\n"
"\t-n\t\tshow what would be done but don't actually search\n"
"\t-p port\t\tport on LDAP server\n"
"\t-P version\tprocotol version (default: 3)\n"
"\t-s scope\tone of base, one, or sub (search scope)\n"
"\t-S attr\t\tsort the results by attribute `attr'\n"
"\t-t\t\twrite binary values to files in temporary directory\n"
"\t-tt\t\twrite all values to files in temporary directory\n"
"\t-T path\t\twrite files to directory specified by path (default:\n"
"\t\t\t\"" LDAP_TMPDIR "\")\n"
"\t-u\t\tinclude User Friendly entry names in the output\n"
"\t-U user\t\tSASL authentication identity (username)\n"
"\t-v\t\trun in verbose mode (diagnostics to standard output)\n"
"\t-V prefix\tURL prefix for files (default: \"" LDAP_FILE_URI_PREFIX ")\n"
"\t-w passwd\tbind passwd (for simple authentication)\n"
"\t-W\t\tprompt for bind passwd\n"
"\t-X id\t\tSASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
"\t-Y mech\t\tSASL mechanism\n"
"\t-z limit\tsize limit (in entries) for search\n"
"\t-Z\t\tissue Start TLS request (-ZZ to require successful response)\n"
" filter\tRFC-2254 compliant LDAP search filter\n"
" attributes\twhitespace-separated list of attribute descriptions\n"
" which may include:\n"
" 1.1 no attributes\n"
" * all user attributes\n"
" + all operational attributes\n"
"Search options:\n"
" -a deref one of never (default), always, search, or find\n"
" -A retrieve attribute names only (no values)\n"
" -b basedn base dn for search\n"
" -l limit time limit (in seconds) for search\n"
" -L print responses in LDIFv1 format\n"
" -LL print responses in LDIF format without comments\n"
" -LLL print responses in LDIF format without comments\n"
" and version\n"
" -s scope one of base, one, or sub (search scope)\n"
" -S attr sort the results by attribute `attr'\n"
" -t write binary values to files in temporary directory\n"
" -tt write all values to files in temporary directory\n"
" -T path write files to directory specified by path (default:\n"
" " LDAP_TMPDIR ")\n"
" -u include User Friendly entry names in the output\n"
" -V prefix URL prefix for files (default: \"" LDAP_FILE_URI_PREFIX ")\n"
" -z limit size limit (in entries) for search\n"
"Common options:\n"
" -d level set LDAP debugging level to `level'\n"
" -D binddn bind DN\n"
" -f file read operations from `file'\n"
" -h host LDAP server\n"
" -I use SASL Interactive mode\n"
" -k use Kerberos authentication\n"
" -K like -k, but do only step 1 of the Kerberos bind\n"
" -M enable Manage DSA IT control (-MM to make critical)\n"
" -n show what would be done but don't actually search\n"
" -O props SASL security properties\n"
" -p port port on LDAP server\n"
" -P version procotol version (default: 3)\n"
" -Q use SASL Quiet mode\n"
" -R realm SASL realm\n"
" -U user SASL authentication identity (username)\n"
" -v run in verbose mode (diagnostics to standard output)\n"
" -w passwd bind passwd (for simple authentication)\n"
" -W prompt for bind passwd\n"
" -x Simple authentication\n"
" -X id SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
" -Y mech SASL mechanism\n"
" -Z Start TLS request (-ZZ to require successful response)\n"
, s );
exit( EXIT_FAILURE );
@ -134,17 +140,19 @@ static int dosearch LDAP_P((
static char *tmpdir = NULL;
static char *urlpre = NULL;
static char *prog = NULL;
static char *binddn = NULL;
static struct berval passwd = { 0, NULL };
static char *base = NULL;
static char *ldaphost = NULL;
static int ldapport = 0;
#ifdef HAVE_CYRUS_SASL
static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
static char *sasl_realm = NULL;
static char *sasl_authc_id = NULL;
static char *sasl_authz_id = NULL;
static char *sasl_mech = NULL;
static int sasl_integrity = 0;
static int sasl_privacy = 0;
static char *sasl_secprops = NULL;
#endif
static int use_tls = 0;
static char *sortattr = NULL;
@ -167,73 +175,15 @@ main( int argc, char **argv )
deref = sizelimit = timelimit = version = -1;
scope = LDAP_SCOPE_SUBTREE;
authmethod = LDAP_AUTH_SIMPLE;
authmethod = -1;
prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : ++prog;
while (( i = getopt( argc, argv,
"Aa:b:CD:d:Ef:h:IKkLl:MnP:p:RS:s:T:tU:uV:vWw:X:Y:Zz:")) != EOF )
"Aa:b:f:Ll:S:s:T:tuV:z:" "Cd:D:h:IkKMnO:p:P:QRU:vw:WxX:Y:Z")) != EOF )
{
switch( i ) {
case 'n': /* do nothing */
++not;
break;
case 'v': /* verbose mode */
++verbose;
break;
case 'd':
debug |= atoi( optarg );
break;
case 'k': /* use kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'K': /* use kerberos bind, 1st part only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] );
return( EXIT_FAILURE );
#endif
break;
break;
case 'u': /* include UFN */
++includeufn;
break;
case 't': /* write attribute values to TMPDIR files */
++vals2tmp;
break;
case 'M':
/* enable Manage DSA IT */
manageDSAit++;
break;
case 'C':
referrals++;
break;
case 'R': /* ignore */
break;
case 'A': /* retrieve attribute names only -- no values */
++attrsonly;
break;
case 'L': /* print entries in LDIF format */
++ldif;
break;
case 's': /* search scope */
if ( strcasecmp( optarg, "base" ) == 0 ) {
scope = LDAP_SCOPE_BASE;
} else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) {
scope = LDAP_SCOPE_ONELEVEL;
} else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) {
scope = LDAP_SCOPE_SUBTREE;
} else {
fprintf( stderr, "scope should be base, one, or sub\n" );
usage( argv[ 0 ] );
}
break;
/* Search Options */
case 'a': /* set alias deref option */
if ( strcasecmp( optarg, "never" ) == 0 ) {
deref = LDAP_DEREF_NEVER;
@ -248,7 +198,46 @@ main( int argc, char **argv )
usage( argv[ 0 ] );
}
break;
case 'A': /* retrieve attribute names only -- no values */
++attrsonly;
break;
case 'b': /* search base */
base = strdup( optarg );
break;
case 'f': /* input file */
if( infile != NULL ) {
fprintf( stderr, "%s: -f previously specified\n" );
return EXIT_FAILURE;
}
infile = strdup( optarg );
break;
case 'l': /* time limit */
timelimit = atoi( optarg );
break;
case 'L': /* print entries in LDIF format */
++ldif;
break;
case 's': /* search scope */
if ( strcasecmp( optarg, "base" ) == 0 ) {
scope = LDAP_SCOPE_BASE;
} else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) {
scope = LDAP_SCOPE_ONELEVEL;
} else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) {
scope = LDAP_SCOPE_SUBTREE;
} else {
fprintf( stderr, "scope should be base, one, or sub\n" );
usage( argv[ 0 ] );
}
break;
case 'S': /* sort attribute */
sortattr = strdup( optarg );
break;
case 'u': /* include UFN */
++includeufn;
break;
case 't': /* write attribute values to TMPDIR files */
++vals2tmp;
break;
case 'T': /* tmpdir */
if( tmpdir ) free( tmpdir );
tmpdir = strdup( optarg );
@ -257,157 +246,346 @@ main( int argc, char **argv )
if( urlpre ) free( urlpre );
urlpre = strdup( optarg );
break;
case 'f': /* input file */
infile = strdup( optarg );
break;
case 'h': /* ldap host */
ldaphost = strdup( optarg );
break;
case 'b': /* search base */
base = strdup( optarg );
break;
case 'D': /* bind DN */
binddn = strdup( optarg );
break;
case 'p': /* ldap port */
ldapport = atoi( optarg );
break;
case 'w': /* bind password */
passwd.bv_val = strdup( optarg );
{
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '*';
}
}
passwd.bv_len = strlen( passwd.bv_val );
break;
case 'l': /* time limit */
timelimit = atoi( optarg );
break;
case 'z': /* size limit */
sizelimit = atoi( optarg );
break;
case 'S': /* sort attribute */
sortattr = strdup( optarg );
/* Common Options */
case 'C':
referrals++;
break;
case 'W':
want_bindpw++;
case 'd':
debug |= atoi( optarg );
break;
case 'D': /* bind DN */
if( binddn != NULL ) {
fprintf( stderr, "%s: -D previously specified\n" );
return EXIT_FAILURE;
}
binddn = strdup( optarg );
break;
case 'h': /* ldap host */
if( ldaphost != NULL ) {
fprintf( stderr, "%s: -h previously specified\n" );
return EXIT_FAILURE;
}
ldaphost = strdup( optarg );
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -I incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_INTERACTIVE;
break;
#else
fprintf( stderr, "%s: was not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'k': /* kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: -k incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return EXIT_FAILURE;
#endif
break;
case 'K': /* kerberos bind, part one only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return( EXIT_FAILURE );
#endif
break;
case 'M':
/* enable Manage DSA IT */
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
manageDSAit++;
version = LDAP_VERSION3;
break;
case 'n': /* print deletes, don't actually do them */
++not;
break;
case 'O':
#ifdef HAVE_CYRUS_SASL
if( sasl_secprops != NULL ) {
fprintf( stderr, "%s: -O previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_secprops = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'p':
if( ldapport ) {
fprintf( stderr, "%s: -p previously specified\n" );
return EXIT_FAILURE;
}
ldapport = atoi( optarg );
break;
case 'P':
switch( atoi( optarg ) )
{
switch( atoi(optarg) ) {
case 2:
if( version == LDAP_VERSION3 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION2;
break;
case 3:
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
break;
default:
fprintf( stderr, "protocol version should be 2 or 3\n" );
usage( argv[0] );
fprintf( stderr, "%s: protocol version should be 2 or 3\n",
prog );
usage( prog );
return( EXIT_FAILURE );
} break;
case 'Q':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Q incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
sasl_integrity++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'E':
#ifdef HAVE_CYRUS_SASL
sasl_privacy++;
authmethod = LDAP_AUTH_SASL;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
return( EXIT_FAILURE );
#endif
break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) {
sasl_mech = strdup( optarg );
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_QUIET;
break;
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'R':
#ifdef HAVE_CYRUS_SASL
if( sasl_realm != NULL ) {
fprintf( stderr, "%s: -R previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -R incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_realm = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
sasl_authc_id = strdup( optarg );
if( sasl_authc_id != NULL ) {
fprintf( stderr, "%s: -U previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -U incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authc_id = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'w': /* password */
passwd.bv_val = strdup( optarg );
{
char* p;
for( p = optarg; *p == '\0'; p++ ) {
*p = '\0';
}
}
passwd.bv_len = strlen( passwd.bv_val );
break;
case 'W':
want_bindpw++;
break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if( sasl_mech != NULL ) {
fprintf( stderr, "%s: -Y previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Y incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_mech = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'x':
if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SIMPLE;
break;
case 'X':
#ifdef HAVE_CYRUS_SASL
sasl_authz_id = strdup( optarg );
if( sasl_authz_id != NULL ) {
fprintf( stderr, "%s: -X previously specified\n" );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: -X incompatible with "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authz_id = strdup( optarg );
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'Z':
#ifdef HAVE_TLS
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Z incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
use_tls++;
#else
fprintf( stderr, "%s was not compiled with TLS support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with TLS support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
default:
fprintf( stderr, "%s: unrecongized option -%c\n",
prog, optopt );
usage( argv[0] );
}
}
if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod ==
LDAP_AUTH_KRBV41 ) ) {
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "Kerberos requires LDAPv2\n" );
return( EXIT_FAILURE );
}
version = LDAP_VERSION2;
}
else if ( authmethod == LDAP_AUTH_SASL ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf( stderr, "SASL requires LDAPv3\n" );
return( EXIT_FAILURE );
}
if (version == -1) {
version = LDAP_VERSION3;
}
if( manageDSAit ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf(stderr, "manage DSA control requires LDAPv3\n");
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
if (authmethod == -1 && version > LDAP_VERSION2) {
#ifdef HAVE_CYRUS_SASL
authmethod = LDAP_AUTH_SASL;
#else
authmethod = LDAP_AUTH_SIMPLE;
#endif
}
if( use_tls ) {
if( version != -1 && version != LDAP_VERSION3 ) {
fprintf(stderr, "Start TLS requires LDAPv3\n");
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
}
if ( argc - optind < 1 ) {
if (( argc - optind < 1 ) ||
( *argv[optind] != '(' /*')'*/ &&
( strchr( argv[optind], '=' ) == NULL ) ) )
{
filtpattern = "(objectclass=*)";
} else {
filtpattern = strdup( argv[optind++] );
@ -531,42 +709,38 @@ main( int argc, char **argv )
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
int minssf = 0, maxssf = 0;
void *defaults;
if ( sasl_integrity > 0 )
maxssf = 1;
if ( sasl_integrity > 1 )
minssf = 1;
if ( sasl_privacy > 0 )
maxssf = 100000; /* Something big value */
if ( sasl_privacy > 1 )
minssf = 56;
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF,
(void *)&minssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF"
"%d\n", minssf);
return( EXIT_FAILURE );
}
if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF,
(void *)&maxssf ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF"
"%d\n", maxssf);
return( EXIT_FAILURE );
if( sasl_secprops != NULL ) {
rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
(void *) sasl_secprops );
if( rc != LDAP_OPT_SUCCESS ) {
fprintf( stderr,
"Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
sasl_secprops );
return( EXIT_FAILURE );
}
}
rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
sasl_authz_id, sasl_mech,
passwd.bv_len ? &passwd : NULL,
NULL, NULL );
defaults = lutil_sasl_defaults( ld,
sasl_mech,
sasl_realm,
sasl_authc_id,
passwd.bv_val,
sasl_authz_id );
rc = ldap_sasl_interactive_bind_s( ld, binddn,
sasl_mech, NULL, NULL,
sasl_flags, lutil_sasl_interact, defaults );
if( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
return( EXIT_FAILURE );
}
#else
fprintf( stderr, "%s was not compiled with SASL support\n",
argv[0] );
fprintf( stderr, "%s: not compiled with SASL support\n",
prog, argv[0] );
return( EXIT_FAILURE );
#endif
} else {
@ -713,8 +887,8 @@ static int dosearch(
sctrls, cctrls, timelimit, sizelimit, &msgid );
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldapsearch: ldap_search_ext: %s (%d)\n",
ldap_err2string( rc ), rc );
fprintf( stderr, "%s: ldap_search_ext: %s (%d)\n",
prog, ldap_err2string( rc ), rc );
return( rc );
}

View file

@ -727,7 +727,7 @@ attn( int sig )
fflush(stdout);
printf("\n\n INTERRUPTED!\n");
(void) SIGNAL (SIGINT, attn);
(void) SIGNAL_REINSTALL (SIGINT, attn);
longjmp(env, 1);
}
@ -746,6 +746,6 @@ chwinsz( int sig )
col_size = win.ws_col;
}
(void) SIGNAL (SIGWINCH, chwinsz);
(void) SIGNAL_REINSTALL (SIGWINCH, chwinsz);
}
#endif

View file

@ -603,7 +603,7 @@ time2text( char *ldtimestr, int dateonly )
timestr[ strlen( timestr ) - 1 ] = zone; /* replace trailing newline */
if ( dateonly ) {
SAFEMEMCPY( timestr + 11, timestr + 20, strlen( timestr + 20 ) + 1 );
AC_MEMCPY( timestr + 11, timestr + 20, strlen( timestr + 20 ) + 1 );
}
return( strdup( timestr ) );

View file

@ -208,13 +208,13 @@ StringToKey(
strncat (password, cell, sizeof(password)-passlen);
if ((passlen = strlen(password)) > sizeof(password)) passlen = sizeof(password);
memcpy(ivec, "kerberos", 8);
memcpy(temp_key, "kerberos", 8);
AC_MEMCPY(ivec, "kerberos", 8);
AC_MEMCPY(temp_key, "kerberos", 8);
des_fixup_key_parity (temp_key);
des_key_sched (temp_key, schedule);
des_cbc_cksum (password, ivec, passlen, schedule, ivec);
memcpy(temp_key, ivec, 8);
AC_MEMCPY(temp_key, ivec, 8);
des_fixup_key_parity (temp_key);
des_key_sched (temp_key, schedule);
des_cbc_cksum (password, key, passlen, schedule, ivec);

View file

@ -92,7 +92,7 @@ fetch_buffer( char *buffer, int length, FILE *where )
if ( isprint( (unsigned char) *p )) {
++p;
} else {
SAFEMEMCPY( p, p + 1, strlen( p + 1 ) + 1 );
AC_MEMCPY( p, p + 1, strlen( p + 1 ) + 1 );
}
}

1044
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -100,35 +100,35 @@ AC_SUBST(ldap_subdir)dnl
dnl ----------------------------------------------------------------
dnl General "enable" options
OL_ARG_ENABLE(debug,[ --enable-debug enable debugging], yes)dnl
OL_ARG_ENABLE(syslog,[ --enable-syslog enable syslog support], auto)dnl
OL_ARG_ENABLE(proctitle,[ --enable-proctitle enable proctitle support], yes)dnl
OL_ARG_ENABLE(cache,[ --enable-cache enable caching], yes)dnl
OL_ARG_ENABLE(referrals,[ --enable-referrals enable V2 Referrals extension], yes)dnl
OL_ARG_ENABLE(kbind,[ --enable-kbind enable V2 Kerberos IV bind], auto)dnl
OL_ARG_ENABLE(cldap,[ --enable-cldap enable connectionless ldap], no)dnl
OL_ARG_ENABLE(ipv6,[ --enable-ipv6 enable IPv6 support], auto)dnl
OL_ARG_ENABLE(unix,[ --enable-unix enable UNIX domain socket support], auto)dnl
OL_ARG_ENABLE(x_compile,[ --enable-x-compile enable cross compiling],
OL_ARG_ENABLE(debug,[ --enable-debug enable debugging], yes)dnl
OL_ARG_ENABLE(syslog,[ --enable-syslog enable syslog support], auto)dnl
OL_ARG_ENABLE(proctitle,[ --enable-proctitle enable proctitle support], yes)dnl
OL_ARG_ENABLE(cache,[ --enable-cache enable caching], yes)dnl
OL_ARG_ENABLE(referrals,[ --enable-referrals enable V2 Referrals extension], yes)dnl
OL_ARG_ENABLE(kbind,[ --enable-kbind enable V2 Kerberos IV bind], auto)dnl
OL_ARG_ENABLE(cldap,[ --enable-cldap enable connectionless ldap], no)dnl
OL_ARG_ENABLE(ipv6,[ --enable-ipv6 enable IPv6 support], auto)dnl
OL_ARG_ENABLE(local,[ --enable-local enable AF_LOCAL (AF_UNIX) socket support], auto)dnl
OL_ARG_ENABLE(x_compile,[ --enable-x-compile enable cross compiling],
no, [yes no])dnl
dnl ----------------------------------------------------------------
dnl General "with" options
dnl OL_ARG_ENABLE(dmalloc,[ --enable-dmalloc enable debug malloc support], no)dnl
dnl OL_ARG_ENABLE(dmalloc,[ --enable-dmalloc enable debug malloc support], no)dnl
OL_ARG_WITH(cyrus_sasl,[ --with-cyrus-sasl with Cyrus SASL support],
OL_ARG_WITH(cyrus_sasl,[ --with-cyrus-sasl with Cyrus SASL support],
auto, [auto yes no] )
OL_ARG_WITH(fetch,[ --with-fetch with fetch URL support],
OL_ARG_WITH(fetch,[ --with-fetch with fetch URL support],
auto, [auto yes no] )
OL_ARG_WITH(kerberos,[ --with-kerberos with support],
OL_ARG_WITH(kerberos,[ --with-kerberos with support],
auto, [auto k5 k5only k425 kth k4 afs yes no])
OL_ARG_WITH(readline,[ --with-readline with readline support],
OL_ARG_WITH(readline,[ --with-readline with readline support],
auto, [auto yes no] )
OL_ARG_WITH(threads,[ --with-threads use threads],
OL_ARG_WITH(threads,[ --with-threads with threads],
auto, [auto nt posix mach pth lwp yes no manual] )
OL_ARG_WITH(tls,[ --with-tls with TLS/SSL support],
OL_ARG_WITH(tls,[ --with-tls with TLS/SSL support],
auto, [auto ssleay openssl yes no] )
OL_ARG_WITH(yielding_select,[ --with-yielding-select with implicitly yielding select],
OL_ARG_WITH(yielding_select,[ --with-yielding-select with implicitly yielding select],
auto, [auto yes no manual] )
dnl ----------------------------------------------------------------
@ -138,47 +138,47 @@ dnl ----------------------------------------------------------------
dnl ----------------------------------------------------------------
dnl SLAPD OPTIONS
AC_ARG_WITH(xxslapdoptions,[SLAPD (Standalone LDAP Daemon) Options:])
OL_ARG_ENABLE(slapd,[ --enable-slapd enable building slapd], yes)dnl
OL_ARG_ENABLE(cleartext,[ --enable-cleartext enable cleartext passwords], yes)dnl
OL_ARG_ENABLE(crypt,[ --enable-crypt enable crypt(3) passwords], auto)dnl
OL_ARG_ENABLE(kpasswd,[ --enable-kpasswd enable kerberos password verification], no)dnl
OL_ARG_ENABLE(spasswd,[ --enable-spasswd enable (Cyrus) SASL password verification], no)dnl
OL_ARG_ENABLE(modules,[ --enable-modules enable dynamic module support], no)dnl
OL_ARG_ENABLE(multimaster,[ --enable-multimaster enable multimaster replication], no)dnl
OL_ARG_ENABLE(phonetic,[ --enable-phonetic enable phonetic/soundex], no)dnl
OL_ARG_ENABLE(rlookups,[ --enable-rlookups enable reverse lookups], auto)dnl
OL_ARG_ENABLE(aci,[ --enable-aci enable per-object ACIs], no)dnl
OL_ARG_ENABLE(wrappers,[ --enable-wrappers enable tcp wrapper support], no)dnl
OL_ARG_ENABLE(dynamic,[ --enable-dynamic enable linking built binaries with dynamic libs], no)dnl
OL_ARG_ENABLE(slapd,[ --enable-slapd enable building slapd], yes)dnl
OL_ARG_ENABLE(cleartext,[ --enable-cleartext enable cleartext passwords], yes)dnl
OL_ARG_ENABLE(crypt,[ --enable-crypt enable crypt(3) passwords], auto)dnl
OL_ARG_ENABLE(kpasswd,[ --enable-kpasswd enable kerberos password verification], no)dnl
OL_ARG_ENABLE(spasswd,[ --enable-spasswd enable (Cyrus) SASL password verification], no)dnl
OL_ARG_ENABLE(modules,[ --enable-modules enable dynamic module support], no)dnl
OL_ARG_ENABLE(multimaster,[ --enable-multimaster enable multimaster replication], no)dnl
OL_ARG_ENABLE(phonetic,[ --enable-phonetic enable phonetic/soundex], no)dnl
OL_ARG_ENABLE(rlookups,[ --enable-rlookups enable reverse lookups], auto)dnl
OL_ARG_ENABLE(aci,[ --enable-aci enable per-object ACIs], no)dnl
OL_ARG_ENABLE(wrappers,[ --enable-wrappers enable tcp wrapper support], no)dnl
OL_ARG_ENABLE(dynamic,[ --enable-dynamic enable linking built binaries with dynamic libs], no)dnl
dnl SLAPD Backend options
OL_ARG_ENABLE(dnssrv,[ --enable-dnssrv enable dnssrv backend], no)dnl
OL_ARG_WITH(dnssrv_module,[ --with-dnssrv-module module type], static,
OL_ARG_ENABLE(dnssrv,[ --enable-dnssrv enable dnssrv backend], no)dnl
OL_ARG_WITH(dnssrv_module,[ --with-dnssrv-module module type], static,
[static dynamic])
OL_ARG_ENABLE(ldap,[ --enable-ldap enable ldap backend], no)dnl
OL_ARG_WITH(ldap_module,[ --with-ldap-module module type], static,
OL_ARG_ENABLE(ldap,[ --enable-ldap enable ldap backend], no)dnl
OL_ARG_WITH(ldap_module,[ --with-ldap-module module type], static,
[static dynamic])
OL_ARG_ENABLE(ldbm,[ --enable-ldbm enable ldbm backend], yes)dnl
OL_ARG_WITH(ldbm_api,[ --with-ldbm-api use LDBM API], auto,
OL_ARG_ENABLE(ldbm,[ --enable-ldbm enable ldbm backend], yes)dnl
OL_ARG_WITH(ldbm_api,[ --with-ldbm-api with LDBM API], auto,
[auto berkeley bcompat mdbm gdbm])
OL_ARG_WITH(ldbm_module,[ --with-ldbm-module module type], static,
OL_ARG_WITH(ldbm_module,[ --with-ldbm-module module type], static,
[static dynamic])
OL_ARG_WITH(ldbm_type,[ --with-ldbm-type use LDBM type], auto,
OL_ARG_WITH(ldbm_type,[ --with-ldbm-type use LDBM type], auto,
[auto btree hash])
OL_ARG_ENABLE(passwd,[ --enable-passwd enable passwd backend], no)dnl
OL_ARG_WITH(passwd_module,[ --with-passwd-module module type], static,
OL_ARG_ENABLE(passwd,[ --enable-passwd enable passwd backend], no)dnl
OL_ARG_WITH(passwd_module,[ --with-passwd-module module type], static,
[static dynamic])
OL_ARG_ENABLE(shell,[ --enable-shell enable shell backend], no)dnl
OL_ARG_WITH(shell_module,[ --with-shell-module module type], static,
OL_ARG_ENABLE(shell,[ --enable-shell enable shell backend], no)dnl
OL_ARG_WITH(shell_module,[ --with-shell-module module type], static,
[static dynamic])
OL_ARG_ENABLE(sql,[ --enable-sql enable sql backend], no)dnl
OL_ARG_WITH(sql_module,[ --with-sql-module module type], static,
OL_ARG_ENABLE(sql,[ --enable-sql enable sql backend], no)dnl
OL_ARG_WITH(sql_module,[ --with-sql-module module type], static,
[static dynamic])
dnl ----------------------------------------------------------------
dnl SLURPD OPTIONS
AC_ARG_WITH(xxslurpdoptions,[SLURPD (Replication Daemon) Options:])
OL_ARG_ENABLE(slurpd,[ --enable-slurpd enable building slurpd], auto)dnl
OL_ARG_ENABLE(slurpd,[ --enable-slurpd enable building slurpd], auto)dnl
dnl ----------------------------------------------------------------
AC_ARG_WITH(xxliboptions,[Library Generation & Linking Options])
@ -541,7 +541,7 @@ AC_CHECK_LIB(s, afopen, [
dnl ----------------------------------------------------------------
dnl PF_INET6 support requires getaddrinfo
dnl PF_UNIX may use getaddrinfo in available
dnl PF_LOCAL may use getaddrinfo in available
AC_CHECK_FUNCS( getaddrinfo )
if test $ac_cv_func_getaddrinfo = no ; then
@ -551,13 +551,13 @@ if test $ac_cv_func_getaddrinfo = no ; then
ol_enable_ipv6=no
fi
if test $ol_enable_unix != no ; then
if test $ol_enable_local != no ; then
AC_CHECK_HEADERS( sys/un.h )
if test $ol_enable_unix = auto ; then
ol_enable_unix=$ac_cv_header_sys_un_h
if test $ol_enable_local = auto ; then
ol_enable_local=$ac_cv_header_sys_un_h
elif test $ac_cv_header_sys_un_h = no ; then
AC_MSG_ERROR([UNIX domain support requires sys/un.h])
AC_MSG_ERROR([AF_LOCAL domain support requires sys/un.h])
fi
fi
@ -913,7 +913,6 @@ dnl ----------------------------------------------------------------
dnl TLS/SSL
ol_link_tls=no
if test $ol_with_tls != no ; then
AC_CHECK_HEADERS(openssl/ssl.h ssl.h)
if test $ac_cv_header_openssl_ssl_h = yes -o $ac_cv_header_ssl_h = yes ; then
@ -954,11 +953,21 @@ if test $ol_with_tls != no ; then
fi
fi
fi
else
AC_WARN([TLS privacy protection not supported!])
fi
if test $ol_link_tls = yes ; then
AC_DEFINE(HAVE_TLS, 1, [define if you have TLS])
fi
elif test $ol_with_tls = auto ; then
AC_WARN([Could not locate TLS/SSL package])
AC_WARN([TLS privacy protection not supported!])
elif test $ol_with_tls != no ; then
AC_ERROR([Could not locate TLS/SSL package])
fi
dnl ----------------------------------------------------------------
dnl Tests for reentrant functions necessary to build a
@ -1746,8 +1755,21 @@ if test $ol_with_cyrus_sasl != no ; then
fi
fi
if test $ol_link_sasl = no -a $ol_with_cyrus_sasl = yes ; then
AC_MSG_ERROR(no suitable API for --with-cyrus-sasl=$ol_with_cyrus_sasl)
if test $ol_link_sasl = no ; then
if test $ol_with_cyrus_sasl != auto ; then
AC_MSG_ERROR([Could not locate Cyrus SASL])
else
AC_MSG_WARN([Could not locate Cyrus SASL])
AC_MSG_WARN([SASL authentication not supported!])
if test $ol_link_tls = no ; then
AC_MSG_WARN([Strong authentication not supported!])
fi
fi
fi
else
AC_MSG_WARN([SASL authentication not supported!])
if test $ol_link_tls = no ; then
AC_MSG_WARN([Strong authentication not supported!])
fi
fi
@ -2032,8 +2054,8 @@ fi
if test "$ol_enable_cldap" != no ; then
AC_DEFINE(LDAP_CONNECTIONLESS,1,[define to support CLDAP])
fi
if test "$ol_enable_unix" != no; then
AC_DEFINE(LDAP_PF_UNIX,1,[define to support PF_UNIX])
if test "$ol_enable_local" != no; then
AC_DEFINE(LDAP_PF_LOCAL,1,[define to support PF_LOCAL])
fi
if test "$ol_enable_ipv6" != no; then
AC_DEFINE(LDAP_PF_INET6,1,[define to support PF_INET6])

View file

@ -9,7 +9,7 @@ or to cite them other than as "work in progress."
OpenLDAP maintains copies of drafts for which we find interesting.
It existance does not necessarily imply any support or any plans to
support for the I-D. The I-D found in this directory may be stale,
support for the I-D. The I-Ds found in this directory may be stale,
expired, or otherwise out of date.
Please refer to http://www.ietf.org/ for latest revisions (and

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
INTERNET-DRAFT Michael P. Armijo
<draft-ietf-ldapext-locate-02.txt> Levon Esibov
April, 2000 Paul Leach
Expires: October, 2000 Microsoft Corporation
<draft-ietf-ldapext-locate-03.txt> Levon Esibov
July, 2000 Paul Leach
Expires: January, 2001 Microsoft Corporation
R.L. Morgan
University of Washington
@ -29,7 +29,7 @@ Status of this Memo
http://www.ietf.org/shadow.html.
Distribution of this memo is unlimited. It is filed as <draft-
ietf-ldapext-locate-02.txt>, and expires on October 15, 2000.
ietf-ldapext-locate-03.txt>, and expires on January 14, 2001.
Please send comments to the authors.
@ -89,17 +89,31 @@ Status of this Memo
This section defines a method of converting a DN into a DNS domain
name for use in the server location method described below. Some
DNs cannot be converted into a domain name.
DNs cannot be converted into a domain name. Converted DNs result
in a fully qualified domain name.
The output domain name is initially empty. For each RDN component
of the DN, beginning with the first, if the attribute type is "DC",
then the attribute value is used as a domain name component (label).
of the DN, beginning with the rightmost and working left, if the
attribute type is "DC", then the attribute value is used as a domain
name component (label).
The first such value becomes the most significant (i.e., rightmost)
domain name component, and successive values occupy less significant
positions (i.e., extending leftward), in order. If the attribute
type is not "DC", then processing stops. If the first RDN component
type is not "DC", then processing stops. If the final RDN component
of the DN is not of type "DC" then the DN cannot be converted to a
domain name.
domain name.
For DN:
cn=John Doe,ou=accounting,dc=example,dc=net
The client would convert the DC components as defined above into
DNS name:
example.net.
The determined DNS name will be submitted as a DNS query using the
algorithm defined in section 4.
4. Locating LDAP servers through DNS
@ -114,11 +128,13 @@ Status of this Memo
_<Service>._<Proto>.<Domain>
where <Service> is always "ldap", and <Proto> is a protocol that can
be either "udp" or "tcp". <Domain> is the domain name formed by
converting the DN of a naming context mastered by the LDAP Server
into a domain name using the algorithm in Section 2. Note that
"ldap" is the symbolic name for the LDAP service in Assigned
Numbers[6], as required by [5].
be either "udp" or "tcp". "_ldap._tcp" applies to services
compatible with LDAPv2 [7] or LDAPv3 [1]. "_ldap._udp"
applies to services compatible with CLDAP [8]. <Domain> is
the domain name formed by converting the DN of a naming context
mastered by the LDAP Server into a domain name using the algorithm in
Section 3. Note that "ldap" is the symbolic name for the LDAP service
in Assigned Numbers[6], as required by [5].
Presence of such records enables clients to find the LDAP servers
using standard DNS query [4]. A client (or server) seeking an LDAP
@ -139,8 +155,10 @@ Status of this Memo
_ldap._tcp.example.net. IN SRV 0 0 389 phoenix.example.net.
The set of returned records may contain multiple records in the case
where multiple LDAP servers serve the same domain.
where multiple LDAP servers serve the same domain. If there are no
matching SRV records available for the converted DN the client SHOULD
NOT attempt to 'walk the tree' by removing the least significant
portion of the constructed fully qualified domain name.
5. Security Considerations
@ -173,8 +191,14 @@ Status of this Memo
[6] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC
1700, October 1994.
[7] Yeong, W., Howes, T. and Kille, S., "Lightweight Directory Access
Protocol", RFC 1777, March 1995
6. Authors' Addresses
[8] Young, A., "Connection-less Lightweight Directory Access Protocol",
RFC 1798, June 1995
7. Authors' Addresses
Michael P. Armijo
One Microsoft Way
@ -201,5 +225,7 @@ Status of this Memo
EMail: rlmorgan@washington.edu
URI: http://staff.washington.edu/rlmorgan/
Expires October, 2000
Expires January, 2001

View file

@ -1,307 +1,405 @@
Internet-Draft David Chadwick
LDAPExt WG University of Salford
Intended Category: Standards Track Sean Mullan
Sun
Microsystems
Expires: 8 March 2000 8 September 1999
Returning Matched Values with LDAPv3
<draft-ietf-ldapext-matchedval-01.txt>
STATUS OF THIS MEMO
This document is an Internet-Draft and is in full conformance with
all the provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
This Internet-Draft expires on 8 March 2000. Comments and suggestions
on this document are encouraged. Comments on this document should be
sent to the LDAPExt working group discussion list:
ietf-ldapext@netscape.com
or directly to the authors.
ABSTRACT
This document describes a control for the Lightweight Directory
Access Protocol v3 that is used to return a subset of attribute
values from an entry, specifically, only those values that
contributed to the search filter evaluating to TRUE. Without support
for this control, a client must retrieve all of an attribute's values
and search for specific values locally.
1. Introduction
When reading an attribute from an entry using LDAP v2 [1] or LDAPv3
[2], it is normally only possible to read either the attribute type,
or the attribute type and all its values. It is not possible to
selectively read just a few of the attribute values. If an attribute
holds many values, for example, the userCertificate attribute, or the
subschema publishing operational attributes objectClasses and
attributeTypes [3], then it may be desirable for the user to be able
to selectively retrieve a subset of the values, specifically, those
attribute values that match the selection criteria as specified by
the user in the filter. Without the control specified in this
[ID/standard] a client must read all of the attribute's values and
filter out the unwanted values, necessitating the client to implement
the matching rules. It also requires the client to potentially read
and process many irrelevant values, which can be inefficient if the
values are large or complex, or there are many values stored per
attribute.
This Internet Draft specifies an LDAPv3 control to enable a user to
return only those values that matched (i.e. returned TRUE to) one or
more elements of the Search filter. This control can be especially
useful when used in conjunction with extensible matching rules that
match on one or more components of complex binary attribute values.
The control has been described in such a way as to be fully
compatible with the matchedValuesOnly boolean of the X.500 DAP [4]
Search argument, as amended in the latest version [6].
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC 2119 [5].
2. The matchedValuesOnly Control
The matchedValuesOnly control MAY be critical or non-critical as
determined by the user. It is only applicable to the Search
operation, and SHALL be ignored by the server if it is present on any
other LDAP operation (even if marked critical on such operations).
The object identifier for this control is 1.2.826.0.1.3344810.2.2
The controlValue is absent.
If the server supports this control, the server MUST make use of the
control as follows:
(1) If the typesOnly parameter of the Search Request is TRUE,
the control has no effect and the Search Request SHOULD be
processed as if the control had not been specified.
(2) If the attributes parameter of the Search Request consists
of a list containing only the attribute with OID "1.1"
(specifying that no attributes are to be returned), the control
has no effect and the Search Request SHOULD be processed as if
the control had not been specified.
(3) For each attribute listed in the attributes parameter of the
Search Request, the server MUST apply the control as follows:
i) Every attribute value that evaluates TRUE against one or
more filters, excluding the ignored filters (see below),
is logically marked by the server as contributing to the
filter matching.
ii) Attributes that have no values marked as contributing,
have all their values returned to the user.
iii) Attributes that have one or more values marked as
contributing have only the contributing values returned to
the user, whilst the other values of the same attribute
(if there are any) are not returned.
Certain filters are ignored for the purposes of marking the attribute
values as contributing. These are:
the ôpresentö filter, since this filter does not test against
any attribute values;
the ônotö filter, since this would have the effect of marking
all the attribute values except the one(s) that matched the
non-negated filter.
3. Relationship to X.500
The matchedValuesOnly control defined in this document is derived
from the matchedValuesOnly boolean parameter of the X.511 (93) DAP
Search operation [4]. Note however that in X.511 (93), the
matchedValuesOnly parameter is ignored when used with an "equality"
match FilterItem, and so the user must use the extensibleMatch filter
along with the equality matching rule if only matched values are
wanted with equality matching. This slightly spurious equality match
restriction has been removed from the 2000 version of X.511 [6]. For
LDAP servers acting as a gateway to an X.500 directory, the matched
valuesOnly control can be directly mapped onto the X.511
matchedValuesOnly Search parameter as follows:
(1) If the matchedValuesOnly control is specified, the
matchedValuesOnly DAP parameter MUST be set to true. If the
control criticality value is TRUE then bit 17 of the DAP
criticalExtensions MUST be set.
(2) If an equality matching rule is specified in the filter of
the LDAPv3 search operation, then if operating with a pre-2000
edition DSA, the corresponding equality FilterItem contained in
the X.511 filter parameter MUST NOT be used, but rather the
extensibleMatch filter item MUST be used instead (the assertion
consisting of the equality matching rule, the attribute type to
match on, and the asserted value). When operating with DSAs
that support the 2000 DAP enhancement, the equality FilterItem
MAY be used.
4. Examples
(1) The first example simply shows how the control can be used to
selectively read a subset of attribute values.
The entry below represents a groupOfNames object class containing
several members from different organizations.
cn: Cross Organizational Standards Body
member: cn=joe, o=acme
member: cn=alice, o=acme
member: cn=bob, o=foo
member: cn=sue, o=bar
An LDAP search operation is specified with a baseObject set to the
DN of the entry, a baseObject scope, a filter set to
"member=*o=acme", and the list of attributes to be returned set to
"member". In addition, a matchedValuesOnly control is attached to the
search request.
The search results returned by the server would consist of the
following entry:
cn: Cross Organizational Standards Body
member: cn=joe, o=acme
member: cn=alice, o=acme
(2) The second example shows how the control has no effect on
attributes that do not participate in the search filter.
The entries below represent inetOrgPerson [7] object classes located
below some distinguished name in the directory.
cn: Sean Mullan
mail: sean.mullan@sun.com
mail: mullan@east.sun.com
telephoneNumber: +1 781 442 0926
telephoneNumber: 555-9999
cn: David Chadwick
mail: d.w.chadwick@salford.ac.uk
An LDAP search operation is specified with a baseObject set to the
DN of the entry, a subtree scope, a filter set to
"(|(mail=sean.mullan@sun.com)(mail=d.w.chadwick@salford.ac.uk))", and
the list of attributes to be returned set to "mail telephoneNumber".
In addition, a matchedValuesOnly control is attached to the search
request.
The search results returned by the server would consist of the
following entries:
cn: Sean Mullan
mail: sean.mullan@sun.com
telephoneNumber: +1 781 442 0926
telephoneNumber: 555-9999
cn: David Chadwick
mail: d.w.chadwick@salford.ac.uk
Note that the control has no effect on the values returned for the
"telephoneNumber" attribute (all of the values are returned), since
it did not participate in the search filter.
5. Security Considerations
This Internet Draft does not discuss security issues at all.
Note that attribute values MUST only be returned if the access
controls applied by the LDAP server allow them to be returned, and in
this respect the effect of the matchedValuesOnly control is of no
consequence.
Note that the matchedValuesOnly control may have a positive effect on
the deployment of public key infrastructures. Certain PKI operations,
like searching for specific certificates, become more practical (when
combined with X.509 certificate matching rules at the server) and
more scalable, since the control avoids the downloading of
potentially large numbers of irrelevant certificates which would have
to be processed and filtered locally (which in some cases is very
difficult to perform).
6. Copyright
Copyright (C) The Internet Society (date). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
7. References
[1] Yeong, W., Howes, T., and Kille, S. "Lightweight Directory Access
Protocol", RFC 1777, March 1995.
[2] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access
Protocol (v3)", Dec. 1997, RFC 2251
[3] M. Wahl, A. Coulbeck, T. Howes, S. Kille, ôLightweight Directory
Access Protocol (v3): Attribute Syntax Definitionsö, RFC 2252, Dec
1997
[4] ITU-T Rec. X.511, "The Directory: Abstract Service Definition",
1993.
[5] S.Bradner. "Key words for use in RFCs to Indicate Requirement
Levels", RFC 2119, March 1997.
[6] ôFPDAMs to ISO/IEC 9594 Parts 1, 2, 3, 4, 5, 6, 7 and 9 to
support the ITU-T Rec. F.510 "Automated Directory Assistance, White
Pages Service Definitions"ö, Collaborative ITU-T/SG7/Q15 and
JTC1/SC6/WG7 OSI Directory Meeting 7-15 April 1999, Orlando, USA
[7] M. Smith. "Definition of the inetOrgPerson LDAP Object Class",
Internet Draft <draft-smith-ldap-inetorgperson-03.txt>, April 1999.
8. Authors Addresses
David Chadwick
IS Institute
University of Salford
Salford M5 4WT
England
Email: d.w.chadwick@salford.ac.uk
Sean Mullan
Sun Microsystems Laboratories
One Network Drive
Burlington
MA 01803-0902
USA
Tel: +1 781 442-0926 Fax: +1 781 442-1692
Email: sean.mullan@sun.com
Internet-Draft Returning Matched Values with LDAPv3 8 September 1999
5
Internet-Draft David Chadwick
LDAPExt WG University of Salford
Intended Category: Standards Track Sean Mullan
Sun Microsystems
Expires: 1 January 2001 1 July 2000
Returning Matched Values with LDAPv3
<draft-ietf-ldapext-matchedval-02.txt>
STATUS OF THIS MEMO
This document is an Internet-Draft and is in full conformance with
all the provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
This Internet-Draft expires on 1 January 2001. Comments and
suggestions on this document are encouraged. Comments on this
document should be sent to the LDAPExt working group discussion list:
ietf-ldapext@netscape.com
or directly to the authors.
ABSTRACT
This document describes a control for the Lightweight Directory
Access Protocol v3 that is used to return a subset of attribute
values from an entry, specifically, only those values that match a
"values return" filter. Without support for this control, a client
must retrieve all of an attribute's values and search for specific
values locally.
1. Introduction
When reading an attribute from an entry using LDAP v2 [1] or LDAPv3
[2], it is normally only possible to read either the attribute type,
or the attribute type and all its values. It is not possible to
selectively read just a few of the attribute values. If an attribute
holds many values, for example, the userCertificate attribute, or the
subschema publishing operational attributes objectClasses and
attributeTypes [3], then it may be desirable for the user to be able
to selectively retrieve a subset of the values, specifically, those
attribute values that match some user defined selection criteria.
Without the control specified in this [ID/standard] a client must
read all of the attribute's values and filter out the unwanted
values, necessitating the client to implement the matching rules. It
also requires the client to potentially read and process many
irrelevant values, which can be inefficient if the values are large
or complex, or there are many values stored per attribute.
This Internet Draft specifies an LDAPv3 control to enable a user to
return only those values that matched (i.e. returned TRUE to) one or
more elements of a newly defined "values return" filter. This control
can be especially useful when used in conjunction with extensible
matching rules that match on one or more components of complex binary
attribute values.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC 2119 [5].
2. The valuesReturnFilter Control
The valuesReturnFilter control MAY be critical or non-critical as
determined by the user. It is only applicable to the Search
operation, and SHALL be ignored by the server if it is present on any
other LDAP operation (even if marked critical on such operations).
The object identifier for this control is 1.2.826.0.1.3344810.2.3
The controlValue is
ValuesReturnFilter ::= SEQUENCE OF SimpleFilterItem
SimpleFilterItem ::= CHOICE {
equalityMatch [3] AttributeValueAssertion,
substrings [4] SubstringFilter,
greaterOrEqual [5] AttributeValueAssertion,
lessOrEqual [6] AttributeValueAssertion,
present [7] AttributeDescription,
approxMatch [8] AttributeValueAssertion,
extensibleMatch [9] SimpleMatchingAssertion }
SimpleMatchingAssertion ::= SEQUENCE {
matchingRule [1] MatchingRuleId OPTIONAL,
type [2] AttributeDescription OPTIONAL,
matchValue [3] AssertionValue}
All the above data types have their standard meanings as defined in
[2].
If the server supports this control, the server MUST make use of the
control as follows:
(1) The Search Filter is first executed in order to determine
which entries satisfy the Search criteria. The control has no
impact on this step.
(2) If the typesOnly parameter of the Search Request is TRUE,
the control has no effect and the Search Request SHOULD be
processed as if the control had not been specified.
(3) If the attributes parameter of the Search Request consists
of a list containing only the attribute with OID "1.1"
(specifying that no attributes are to be returned), the control
has no effect and the Search Request SHOULD be processed as if
the control had not been specified.
(4) For each attribute listed in the attributes parameter of the
Search Request, the server MUST apply the control as follows:
i) Every attribute value that evaluates TRUE against one or
more elements of the ValuesReturnFilter is placed in the
SearchResultEntry.
ii) Every attribute value that evaluates FALSE or undefined
against all elements of the ValuesReturnFilter is not
placed in the SearchResultEntry. An attribute that has no
values selected is returned with an empty set of vals.
Editor's Note. There is possibly a more efficient but slightly more
complex way of achieving the value filtering. An alternative is to
remove the 'present' SimpleFilterItem (which obviously evaluates true
for every attribute value of the 'present' attribute description),
and to say that any attribute whose type is not mentioned in the
ValuesReturnFilter is not filtered and has all its attribute values
returned. Comments please.
3. Relationship to X.500
The control is a superset of the matchedValuesOnly boolean of the
X.500 DAP [4] Search argument, as amended in the latest version [6].
Close examination of the matchedValuesOnly boolean by the LDAPExt
group revealed ambiguities and complexities in the MVO boolean that
could not easily be resolved. For example, are only those attribute
values that contributed to the overall truth of the filter governed
by the MVO boolean, or all values of attributes in the filter
governed by the MVO boolean, even if the filter item containing the
attribute evaluated to false. For this reason the LDAP group decided
to replace the MVO boolean with a simple filter that removes any
uncertainty as to whether an attribute value has been selected or
not.
4. Examples
(1) The first example simply shows how the control can be used to
selectively read a subset of attribute values.
The entry below represents a groupOfNames object class containing
several members from different organizations.
cn: Cross Organizational Standards Body
member: cn=joe,o=acme
member: cn=alice,o=acme
member: cn=bob,o=foo
member: cn=sue,o=bar
An LDAP search operation is specified with a baseObject set to the
DN of the entry, a baseObject scope, a filter set to
"member=*o=acme", and the list of attributes to be returned set to
"member". In addition, a ValuesReturnFilter control is set to
"member=*o=acme".
The search results returned by the server would consist of the
following entry:
cn: Cross Organizational Standards Body
member: cn=joe, o=acme
member: cn=alice, o=acme
(2) The second example shows how the control can be set to match on
attributes that are (mail) and are not (telephoneNumber) part of the
search filter. It also shows how a user can filter some attribute
values (mail) and not others (telephoneNumber).
The entries below represent inetOrgPerson [7] object classes located
below some distinguished name in the directory.
cn: Sean Mullan
mail: sean.mullan@sun.com
mail: mullan@east.sun.com
telephoneNumber: +1 781 442 0926
telephoneNumber: 555-9999
cn: David Chadwick
mail: d.w.chadwick@salford.ac.uk
An LDAP search operation is specified with a baseObject set to the
DN of the entry, a subtree scope, a filter set to
"(|(mail=sean.mullan@sun.com)(mail=d.w.chadwick@salford.ac.uk))", and
the list of attributes to be returned set to "mail telephoneNumber".
In addition, a ValuesReturnFilter control is set to
"mail=sean.mullan@sun.com, mail=d.w.chadwick@salford.ac.uk,
telephoneNumber=*"
The search results returned by the server would consist of the
following entries:
cn: Sean Mullan
mail: sean.mullan@sun.com
telephoneNumber: +1 781 442 0926
telephoneNumber: 555-9999
cn: David Chadwick
mail: d.w.chadwick@salford.ac.uk
Note that the control has no effect on the values returned for the
"telephoneNumber" attribute (all of the values are returned), since
the control specified that all values should be returned.
(3) The third example shows how one might retrieve a single attribute
type schema definition for the "gunk" attribute with OID 1.2.3.4.5
Assume the subschema subentry is held somewhere below the root entry
with RDN "subschema subentry", and this holds an attributeTypes
operational attribute holding the descriptions of the 35 attributes
known to this server (each description is held as a single attribute
value of the attributeTypes attribute).
cn: subschema subentry
objectClass: subschema
attributeTypes: ( 2.5.4.3 NAME 'cn' SUP name )
attributeTypes: ( 2.5.4.6 NAME 'c' SUP name SINGLE-VALUE )
attributeTypes: ( 2.5.4.0 NAME 'objectClass' EQUALITY
objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )
attributeTypes: ( 2.5.18.2 NAME 'modifyTimestamp' EQUALITY
generalizedTimeMatch ORDERING generalizedTimeOrderingMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-
MODIFICATION USAGE directoryOperation )
attributeTypes: ( 2.5.21.6 NAME 'objectClasses' EQUALITY
objectIdentifierFirstComponentMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.37 USAGE directoryOperation )
attributeTypes: ( 1.2.3.4.5 NAME 'gunk' EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.44{64} )
attributeTypes: ( 2.5.21.5 NAME 'attributeTypes' EQUALITY
objectIdentifierFirstComponentMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.3 USAGE directoryOperation )
plus another 28 - you get the idea.
The user creates an LDAP search operation with a baseObject set to
root, a subtree scope, a filter set to "objectClass=subschema", the
list of attributes to be returned set to "attributeTypes", and the
ValuesReturnFilter set to "attributeTypes=1.2.3.4.5"
The search result returned by the server would consist of the
following entry:
cn: subschema subentry
attributeTypes: ( 1.2.3.4.5 NAME 'gunk' EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.44{64} )
(4) The final example shows how the control can be set to match on
attributes that are not part of the search filter. For example,
searching for all entries that have an email address in the
sun.com domain, and returning the telephone number for any attribute
values that start with "555".
The entries below represent inetOrgPerson [7] object classes located
below some distinguished name in the directory.
cn: Sean Mullan
mail: sean.mullan@sun.com
mail: mullan@east.sun.com
telephoneNumber: +1 781 442 0926
telephoneNumber: 555-9999
cn: David Chadwick
mail: d.w.chadwick@salford.ac.uk
An LDAP search operation is specified with a baseObject set to the
DN of the entry, a subtree scope, a filter set to "mail=*sun.com",
and the list of attributes to be returned set to "telephoneNumber".
In addition, a ValuesReturnFilter control is set to
"telephoneNumber=555*"
The search results returned by the server would consist of the
following entry:
cn: Sean Mullan
telephoneNumber: 555-9999
5. Security Considerations
This Internet Draft does not discuss security issues at all.
Note that attribute values MUST only be returned if the access
controls applied by the LDAP server allow them to be returned, and in
this respect the effect of the ValuesReturnFilter control is of no
consequence.
Note that the ValuesReturnFilter control may have a positive effect
on the deployment of public key infrastructures. Certain PKI
operations, like searching for specific certificates, become more
practical (when combined with X.509 certificate matching rules at the
server) and more scalable, since the control avoids the downloading
of potentially large numbers of irrelevant certificates which would
have to be processed and filtered locally (which in some cases is
very difficult to perform).
6. Acknowledgements
The authors would like to thank members of the LDAPExt list for their
constructive comments on earlier versions of this draft, and in
particular to Harald Alvestrand who first suggested having an
attribute return filter and Bruce Greenblatt who first proposed a
syntax for this control.
7. Copyright
Copyright (C) The Internet Society (date). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
8. References
[1] Yeong, W., Howes, T., and Kille, S. "Lightweight Directory Access
Protocol", RFC 1777, March 1995.
[2] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access
Protocol (v3)", Dec. 1997, RFC 2251
[3] M. Wahl, A. Coulbeck, T. Howes, S. Kille, "Lightweight Directory
Access Protocol (v3): Attribute Syntax Definitions", RFC 2252, Dec
1997
[4] ITU-T Rec. X.511, "The Directory: Abstract Service Definition",
1993.
[5] S.Bradner. "Key words for use in RFCs to Indicate Requirement
Levels", RFC 2119, March 1997.
[6] ISO/IEC 9594 / ITU-T Rec X.511 (2000) The Directory: Abstract
Service Definition.
[7] M. Smith. "Definition of the inetOrgPerson LDAP Object Class",
Internet Draft <draft-smith-ldap-inetorgperson-03.txt>, April 1999.
9. Authors Addresses
David Chadwick
IS Institute
University of Salford
Salford M5 4WT
England
Email: d.w.chadwick@salford.ac.uk
Sean Mullan
Sun Microsystems
East Point Business Park
Dublin 3
Ireland
Tel: +353 1 853 0655
Email: sean.mullan@sun.com
Internet-Draft Returning Matched Values with LDAPv3 1 July 2000
1

View file

@ -1,774 +0,0 @@
IETF LDAPEXT Working Group Christopher Lukas [Editor]
INTERNET-DRAFT Internet Scout Project
Tim Howes
Netscape Communications Corp.
Michael Roszkowski
Internet Scout Project
Mark C. Smith
Netscape Communications Corp.
Mark Wahl
Critial Angle, Inc.
June 1999
Named Referrals in LDAP Directories
<draft-ietf-ldapext-namedref-00.txt>
1. Status of this Memo
This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other groups
may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet- Drafts as reference material
or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
Distribution of this document is unlimited. Please send comments to the
authors or the LDAPEXT mailing list, ietf-ldapext@netscape.com.
Copyright Notice: Copyright (C) The Internet Society (1999). All Rights
Reserved.
This draft is a revision of a draft formerly published as draft-ietf-
ldapext-referral-00.txt.
This draft expires December 6, 1999.
Howes, et al. IETF LDAPEXT Working Group [Page 1]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
2. Abstract
This document defines a "ref" attribute and associated "referral" object
class for representing generic knowledge information in LDAP directories
[RFC2251]. The attribute uses URIs [RFC1738] to represent knowledge,
enabling LDAP and non-LDAP services alike to be referenced. The object
class can be used to construct entries in an LDAP directory containing
references to other directories or services. This document also defines
procedures directory servers should follow when supporting these schema
elements and when responding to requests for which the directory server
does not contain the requested object but may contain some knowledge of
the location of the requested object.
3. Background and intended usage
The broadening of interest in LDAP directories beyond their use as front
ends to X.500 directories has created a need to represent knowledge
information in a more general way. Knowledge information is information
about one or more servers maintained in another server, used to link
servers and services together.
This document defines a general method of representing knowledge infor-
mation in LDAP directories, based on URIs.
The key words "MUST", "SHOULD", and "MAY" used in this document are to
be interpreted as described in [RFC2119].
4. The ref attribute type
This section defines the ref attribute type for holding general
knowledge reference information.
( 2.16.840.1.113730.3.1.34 NAME 'ref' DESC 'URL reference'
EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
USAGE distributedOperation )
The ref attribute type has IA5 syntax and is case sensitive. The ref
attribute is multivalued. Values placed in the attribute MUST conform to
the specification given for the labeledURI attribute defined in
[RFC2079]. The labeledURI specification defines a format that is a URI,
optionally followed by whitespace and a label. This document does not
make use of the label portion of the syntax. Future documents MAY enable
new functionality by imposing additional structure on the label portion
of the syntax as it appears in the ref attribute.
If the URI contained in the ref attribute refers to an LDAPv3 server, it
must be in the LDAP URI format described in [RFC2255].
Howes, et al. IETF LDAPEXT Working Group [Page 2]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
When returning a referral result, the server must not return the label
portion of the labeledURI as part of the referral. Only the URI portion
of the ref attribute should be returned.
5. Use of the ref attribute
One usage of the ref attribute is defined in this document. Other uses
of the ref attribute MAY be defined in subsequent documents, or by bila-
teral agreement between cooperating clients and servers.
Except when the manageDsaIT control (documented in section 8 of this
document) is present in the operation request, the ref attribute is not
visible to clients, except as its value is returned in referrals or con-
tinuation references.
If the manageDsaIT control is not set, and the entry named in a request
contains the ref attribute, and the entry is not the root DSE, the
server returns an LDAPResult with the resultCode field set to "referral"
and the referral field set to contain the value(s) of the ref attribute
minus any optional trailing whitespace and labels that might be present.
If the manageDsaIT control is not set, and an entry containing the ref
attribute is in the scope of a one level or subtree search request, the
server returns a SearchResultReference for each such entry containing
the value(s) of the entry's ref attribute.
When the manageDsaIT control is present in a request, the server will
treat an entry containing the ref attribute as an ordinary entry, and
the ref attribute as an ordinary attribute, and the server will not
return referrals or continuation references corresponding to ref attri-
butes.
The following sections detail these usages of the ref attribute.
5.1. Named reference
This use of the ref attribute is to facilitate distributed name resolu-
tion or search across multiple servers. The ref attribute appears in an
entry named in the referencing server. The value of the ref attribute
points to the corresponding entry maintained in the referenced server.
While the distinguished name in a value of the ref attribute is typi-
cally that of an entry in a naming context below the naming context held
by the referencing server, it is permitted to be the distinguished name
of any entry. If the ref attribute is multi-valued all the DNs in the
values of the ref attribute SHOULD have the same value. It is the
responsibility of clients to not loop repeatedly if a naming loop is
present in the directory. Administrators SHOULD avoid configuring
Howes, et al. IETF LDAPEXT Working Group [Page 3]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
naming loops using referrals.
Clients SHOULD perform at least simple "depth-of-referral count" loop
detection by incrementing a counter each time a new set of referrals is
received. Clients MAY perform more sophisticated loop detection, for
example not chasing the same URI twice.
If an entry containing the ref attribute is immediately subordinate to
the base object named in a one level search request, then the referring
server MUST include a scope of "base" in any LDAP URIs returned in the
corresponding SearchResultReference.
5.1.1. Scenarios
The following sections contain specifications of how the ref attribute
should be used in different scenarios followed by examples that illus-
trate that usage. The scenarios described consist of referral operation
when finding a base or target object, referral operation when performing
a one level search, and referral operation when performing a subtree
search.
It is to be noted that, in this document, a search operation is concep-
tually divided into two distinct, sequential phases: (1) finding the
base object where the search is to begin, and (2) performing the search
itself. The operation of the server with respect to referrals in phase
(1) is almost identical to the operation of the server while finding the
target object for a non-search operation.
It is to also be noted that multiple ref attributes are allowed in any
entry and, where these sections refer to a single ref attribute, multi-
ple ref attributes may be substituted and should be processed and
returned as a group in an LDAPResult or search result in the same way as
described for a single attribute. The order of the returned continuation
references within a result is not defined.
5.1.1.1. Example configuration
Howes, et al. IETF LDAPEXT Working Group [Page 4]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
|------------------------------------------------------------|
| Server A |
| dn: o=abc,c=us dn: o=xyz,c=us |
| o: abc o: xyz |
| ref: ldap://hostB/o=abc,c=us ref: ldap://hostD/o=xyz,c=us |
| ref: ldap://hostC/o=abc,c=us objectclass: referral |
| objectclass: referral objectclass: extensibleObject|
| objectclass: extensibleObject |
|____________________________________________________________|
|---------------------| |---------------------| |---------------------|
| Server B | | Server D | | Server C |
| dn: o=abc,c=us | | dn: o=xyz,c=us | | dn: o=abc,c=us |
| o: abc | | o: xyz | | o: abc |
| other attributes... | | other attributes... | | other attributes... |
|_____________________| |_____________________| |_____________________|
In this example, Server A holds references for two entries: "o=abc,c=us"
and "o=xyz,c=us". For the "o=abc,c=us" entry, Server A holds two refer-
ences, one to Server B and one to Server C. The entries referenced are
replicas of each other. For the "o=xyz,c=us" entry, Server A holds a
single reference to the entry contained in Server D.
In the following protocol interaction examples, the client has contacted
Server A. Server A holds the naming context "c=us".
5.1.1.2. Base or target object considerations
As previously described, the process of generating referrals for a
search can be described in two phases. The first, which is described in
this section, is generating referrals based on the base object specified
in the search. This process is identical to the process of generating
referrals based on the target object while processing other operations
(modify, add, delete, modify DN, and compare) with the sole exception
that for these other operations, the DN in the referral must be modified
in some cases.
If a client requests any of these operations, there are four cases that
the server must handle with respect to the base or target object speci-
fied in the request.
Case 1: The base or target object is not held by the server and is not
subordinate to any object held by the server with a ref attribute.
The handling of this case is described in section 6.
Case 2: The base or target object is held by the server and contains a
ref attribute
Howes, et al. IETF LDAPEXT Working Group [Page 5]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
In this case, if the type of operation requested is a search or the URI
contained in the ref attribute of the requested base object is NOT an
LDAP URI as defined in [RFC2255], the server should return the URI value
contained in the ref attribute of the base object whose DN is the DN
requested by the client as the base for the operation.
Example:
If the client issues a search in which the base object is "o=xyz,c=us",
server A will return
SearchResultDone "referral" {
ldap://hostD/o=xyz,c=us
}
If the type of operation requested is not a search and the URI contained
in the ref attribute of the requested target object is an LDAP URI
[RFC2255], the server should return a modified form of this URL. The
returned URL must have only the protocol, host, port, and trailing "/"
portion of the URL contained in the ref attribute. The server should
strip any dn, attributes, scope, and filter parts of the URL.
Example:
If the client issues a modify request for the target object of
"o=abc,c=us", server A will return
ModifyResponse "referral" {
ldap://hostB/
ldap://hostC/
}
Case 3: The base or target object is not held by the server, but is
subordinate to an object with a ref attribute held by the server.
If a client requests an operation for which the base or target object is
not held by the server, but is subordinate to one or more objects with a
ref attribute held by the server, the server must return the referral
from the superior held object nearest to the requested base or target
object. Nearest superior object with a referral, in this document, means
an object superior to the base or target object with the DN that has the
most attribute values in common with the DN of the base or target object
and contains a ref attribute.
The process of finding the nearest superior object can be envisioned as
walking up the locally held part of the DIT from the requested base or
target object checking each superior object until either an object with
Howes, et al. IETF LDAPEXT Working Group [Page 6]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
a ref attribute is found or the top-most locally held object is reached.
Once possible implementation of this algorithm is as follows:
1. Remove the leftmost attribute/value pair from the DN of the
requested base or target object.
2. If the remaining DN represents a locally held object that contains
a ref attribute, that object is the nearest superior object with a
referral. Stop and process the referral as described below.
3. If the remaining DN is the root of the locally held part of the
DIT, stop and proceed as described in section 6.
4. Continue with step 1.
Once the nearest superior object has been identified, if the referral
contained in that object is not an LDAP URI [RFC2255], it should be
returned as-is. If the referral is an LDAP URI, the referral must be
modified, regardless of the type of operation, as case 2 describes for a
non-search requuest. That is, the dn, attributes, scope, and filter
parts of the URL must be stripped from the referral and the referral
returned.
Example:
If the client issues an add request where the target object has a DN of
"cn=Chris Lukas,o=abc,c=us", server A will return
AddResponse "referral" {
ldap://hostB/
ldap://hostC/
}
5.1.1.3. Search with one level scope
For search operations, once the base object has been found and deter-
mined not to contain a ref attribute, the search may progress. Any
entries matching the filter and scope of the search that do NOT contain
a ref attribute are returned to the client normally as described in
[RFC2251]. Any entries matching the filter and one level scope that do
contain a ref attribute must be returned as referrals as described here.
If a matching entry contains a ref attribute and the URI contained in
the ref attribute is NOT an LDAP URI [RFC2255], the server should return
the URI value contained in the ref attribute of that entry in a Sear-
chResultReference.
If a matching entry contains a ref attribute in the LDAP URI syntax
Howes, et al. IETF LDAPEXT Working Group [Page 7]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
[RFC2255], the URL from the ref attribute must be modified before it is
returned by adding or substituting a "base" scope into the URL. If the
URL does not contain a scope specifier, the "base" scope specifier must
be added. If the URL does contain a scope specifier, the existing scope
specifier must be replaced by the "base" scope.
Example:
If a client requests a one level search of "c=US" then, in addition to
any entries one level below the "c=US" naming context matching the
filter (shown below as "... SearchResultEntry responses ..."), the
server will also return referrals modified to include the "base" scope
to maintain the one level search semantics.
The order of the SearchResultEntry responses and the SearchResultRefer-
ence responses is undefined. One possible sequence is shown.
... SearchResultEntry responses ...
SearchResultReference {
ldap://hostB/o=abc,c=us??base
ldap://hostC/o=abc,c=us??base
}
SearchResultReference {
ldap://hostD/o=xyz,c=us??base
}
SearchResultDone "success"
5.1.1.4. Search with subtree scope
For a search operation with a subtree scope, once the base object has
been found, the search progresses. As with the one level search, any
entries matching the filter and scope of the search that do NOT contain
a ref attribute are returned to the client normally as described in
[RFC2251].
If an entry matching the requested scope and filter contains a ref
attribute, the server should return the URI value in a SearchResul-
tReference.
Example:
If a client requests a subtree search of "c=us", then in addition to any
entries in the "c=us" naming context which match the filter, Server A
will also return two continuation references. As described in the
Howes, et al. IETF LDAPEXT Working Group [Page 8]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
preceding section, the order of the responses is not defined.
One possible response might be:
... SearchResultEntry responses ...
SearchResultReference {
ldap://hostB/o=abc,c=us
ldap://hostC/o=abc,c=us
}
SearchResultReference {
ldap://hostD/o=xyz,c=us
}
SearchResultDone "success"
6. Superior Reference
An LDAP server may be configured to return a superior reference in the
case where the server does not hold either the requested base object or
an object containing a ref attribute that is superior to that base
object.
An LDAP server's root DSE MAY contain a ref attribute. The values of the
ref attribute in the root DSE that are LDAP URIs SHOULD NOT contain any
dn part, just the host name and optional port number.
If the LDAP server's root DSE contains a ref attribute and a client
requests an object not held by the server and not subordinate to any
held object, the server must return the URI component of the values in
the ref attribute of the root DSE as illustrated in the example.
If the LDAP server's root DSE does not contain a ref attribute, the
server may return one or more references that the server determines via
a method not defined in this document to be appropriate.
The default reference may be to any server that might contain more
knowledge of the namespace than the responding server. In particular,
the client must not expect the superior reference to be identical from
session to session as the reference may be dynamically created by the
server based on the details of the query submitted by the client.
When the server receives an operation for which the base or target entry
of the request is not contained in or subordinate to any naming context
held by the server or a referral entry, the server will return an
LDAPResult with the resultCode set to "referral", and with the referral
Howes, et al. IETF LDAPEXT Working Group [Page 9]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
field filled with a referral that the server has determined to be
appropriate.
Example:
If a client requests a subtree search of "c=de" from server A in the
example configuration, and server A has the following ref attribute
defined in it's root DSE:
ref: ldap://hostG/
then server A will return
SearchResultDone "referral" {
ldap://hostG/
}
7. The referral object class
The referral object class is defined as follows.
( 2.16.840.1.113730.3.2.6 NAME 'referral' SUP top STRUCTURAL
MAY ( ref ) )
The referral object class is a subclass of top and may contain the
referral attribute. The referral object class should, in general, be
used in conjunction with the extensibleObject object class to support
the naming attributes used in the entry's distinguished name.
Servers must support the ref attribute through use of the referral
object class. Any named reference must be of the referral object class
and will likely also be of the extensibleObject object class to support
naming and use of other attributes.
8. The manageDsaIT control
A client MAY specify the following control when issuing a search, com-
pare, add, delete, modify, or modifyDN request or an extended operation
for which the control is defined.
The control type is 2.16.840.1.113730.3.4.2. The control SHOULD be
marked as critical. There is no value; the controlValue field is
absent.
This control causes entries with the "ref" attribute to be treated as
normal entries, allowing clients to read and modify these entries.
Howes, et al. IETF LDAPEXT Working Group [Page 10]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
This control is not needed if the entry containing the referral attri-
bute is one used for directory administrative purposes, such as the root
DSE, or the server change log entries. Operations on these entries
never cause referrals or continuation references to be returned.
9. Relationship to X.500 Knowledge References
The X.500 standard defines several types of knowledge references, used
to bind together different parts of the X.500 namespace. In X.500,
knowledge references can be associated with a set of unnamed entries
(e.g., a reference, associated with an entry, to a server containing the
descendants of that entry).
This creates a potential problem for LDAP clients resolving an LDAPv3
URL referral referring to an LDAP directory back-ended by X.500. Sup-
pose the search is a subtree search, and that server A holds the base
object of the search, and server B holds the descendants of the base
object. The behavior of X.500(1993) subordinate references is that the
base object on server A is searched, and a single continuation reference
is returned pointing to all of the descendants held on server B.
An LDAP URI only allows the base object to be specified. It is not pos-
sible using standard LDAP URIs to indicate a search of several entries
whose names are not known to the server holding the superior entry.
X.500 solves this problem by having two fields, one indicating the pro-
gress of name resolution and the other indicating the target of the
search. In the above example, name resolution would be complete by the
time the query reached server B, indicating that it should not refer the
request.
This document does not address this problem. This problem will be
addressed in separate documents which define the changes to the X.500
distribution model and LDAPv3 extensions to indicate the progress of
name resolution.
10. Security Considerations
This document defines mechanisms that can be used to "glue" LDAP (and
other) servers together. The information used to specify this glue
information should be protected from unauthorized modification. If the
server topology information itself is not public information, the infor-
mation should be protected from unauthorized access as well.
Clients should use caution when re-using credentials while following
referrals as the client may be directed to any server which may or may
not respect or use those credentials appropriately.
Howes, et al. IETF LDAPEXT Working Group [Page 11]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
11. References
[RFC1738]
Berners-Lee, T., Masinter, L., and McCahill, M., "Uniform Resource
Locators (URL)", RFC 1738, CERN, Xerox Corporation, University of
Minnesota, December 1994.
[RFC2079]
M. Smith, "Definition of an X.500 Attribute Type and an Object Class
to Hold Uniform Resource Identifiers (URIs)", RFC 2079, January
1997.
[RFC2119]
S. Bradner, "Key Words for use in RFCs to Indicate Requirement Lev-
els", RFC 2119, March 1997. (Format: TXT=4723 bytes) (Also BCP0014)
(Status: BEST CURRENT PRACTICE)
[RFC2251]
M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol
(v3)", RFC 2251, December 1997.
[RFC2255]
T. Howes, M. Smith, "The LDAP URL Format", RFC 2255, December, 1997.
(Format: TXT=20685 bytes) (Status: PROPOSED STANDARD)
[X500]
ITU-T Rec. X.501, "The Directory: Models", 1993.
12. Author's Address
Tim Howes
Netscape Communications Corp.
501 E. Middlefield Rd.
Mailstop MV068
Mountain View, CA 94043
USA
+1 650 937-3419
EMail: howes@netscape.com
Christopher E. Lukas
Internet Scout Project
Computer Sciences Dept.
University of Wisconsin-Madison
1210 W. Dayton St.
Madison, WI 53706
USA
EMail: lukas@cs.wisc.edu
Howes, et al. IETF LDAPEXT Working Group [Page 12]
INTERNET-DRAFT LDAPv3 Named Referrals March 1999
Michael Roszkowski
Internet Scout Project
Computer Sciences Dept.
University of Wisconsin-Madison
1210 W. Dayton St.
Madison, WI 53706
USA
EMail: mfr@cs.wisc.edu
Mark C. Smith
Netscape Communications Corp.
501 E. Middlefield Rd.
Mailstop MV068
Mountain View, CA 94043
USA
EMail: mcs@netscape.com
Mark Wahl
Innosoft International, Inc.
8911 Capital of Texas Hwy #4140
Austin TX 78759
EMail: M.Wahl@innosoft.com
This draft expires December 6, 1999.
Howes, et al. IETF LDAPEXT Working Group [Page 13]

View file

@ -0,0 +1,728 @@
IETF LDAPEXT Working Group Roland Hedberg
Internet-Draft Catalogix
Expires: January 12, 2000 July 12, 2000
Referrals in LDAP Directories
<draft-ietf-ldapext-refer-00.txt>
Status of this Memo
This document is an Internet-Draft and is in full conformance with
all provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF), its areas, and its working groups. Note that
other groups may also distribute working documents as
Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six
months and may be updated, replaced, or obsoleted by other documents
at any time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
This Internet-Draft will expire on January 12, 2000.
Copyright Notice
Copyright (C) The Internet Society (2000). All Rights Reserved.
Hedberg Expires September 30, 2000 [Page 1]
Internet-Draft LDAP Knowledge references July 2000
Abstract
This document defines two reference attributes and associated "referral"
object class for representing generic knowledge information in LDAP
directories [RFC2251].
The attribute uses URIs [RFC1738] to represent knowledge,
enabling LDAP and non-LDAP services alike to be referenced.
The object class can be used to construct entries in an LDAP directory
containing references to other directories or services. This document
also defines procedures directory servers should follow when supporting
these schema elements and when responding to requests for which the
directory server does not contain the requested object but may contain
some knowledge of the location of the requested object.
1. Background and intended usage
The broadening of interest in LDAP directories beyond their use as front
ends to X.500 directories has created a need to represent knowledge
information in a more general way. Knowledge information is information
about one or more servers maintained in another server, used to link
servers and services together.
This document is based on the following basic assumptions:
- several naming domains
The usage of LDAP as a access protocol to other than X.500 servers has
created islands of directory service systems containing one or more
LDAP servers. Each of these islands are free to pick their own naming
domain. And that they also do; some use the old country,organization,
organizationalUnit naming scheme[X.521], some use the newer domain name
based naming scheme but these two are in no way the only ones in use. The
existence of several naming domains are in itself no real problem as
long as they produce unique names for the objects in the directory.
Still naming schemes like the domain name based one, might easily create
non-continues naming structures because some toplevel domain names
might no find organizations that are interested and/or willing
to manage them. Therefor tree transversal might not longer be possible
except in parts of the whole tree.
- authoritive structure vs directory structure
In some instances even if a part of the tree is delegated to one
organization, the organization doing the delegation might want to
remain as the authority for the baseobject of the delegated tree.
- support for onelevel searches
At points in the tree where the responsibility for all or almost all
of the children of a object is delegated to different organizations
and resides in different directory servers a one-level search is not
very efficient if not supported by special facilities in the directory
as such.
Hedberg Expires September 30, 2000 [Page 2]
Internet-Draft LDAP Knowledge references July 2000
-- directory server discovery
LDAP servers that do not use dc nameing or are not registered with
SRV records in the DNS are very hard to find.
This document defines a general method of representing knowledge
information in LDAP directories, based on URIs.
Two types of knowledge reference are defined: refer and subRefer.
The key words "MUST", "SHOULD", and "MAY" used in this document are to
be interpreted as described in [RFC2119].
2. Knowledge references
2.1 The refer attribute
( 1.2.752.17.1.100
NAME 'refer'
DESC 'URL reference'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
USAGE distributedOperation )
The refer attribute type has IA5 syntax and is case sensitive.
It is multivalued. Values placed in the attribute MUST conform to the
specification given for the labeledURI attribute as defined in [RFC2079].
The labeledURI specification defines a format that is a URI,
optionally followed by whitespace and a label. This document does not
make use of the label portion of the syntax. Future documents MAY enable
new functionality by imposing additional structure on the label portion
of the syntax as it appears in a refer attribute.
If the URI contained in a refer attribute refers to an LDAP
server, it must be in the LDAP URI format described in [RFC2255].
When returning a referral result, the server must not return the label
portion of the labeledURI as part of the referral. Only the URI portion
of the refer attributes should be returned.
The refer attribute can be further specified by the use of options as
defined in section 4.1.5 of [RFC2251]. This document defines five
options and their use. Future documents might defined other options.
The options defined are:
"me", "sup", "cross", "nssr" and "sub" .
'refer;me' is used to hold the reference of this server, and is always
held in the root DSE
'refer;sup' is used to hold the reference of a server superior to this
one in this global LDAP naming domain e.g. a server holding the dc=com,
dc=se, or the c=se node. The 'refer;sup' is always held in the root DSE.
Hedberg Expires September 30, 2000 [Page 3]
Internet-Draft LDAP Knowledge references July 2000
'refer;cross' indicates that this is a cross reference pointing to another
naming context within or outside this global LDAP naming domain.
'refer;sub' indicates that this is a subordinate reference pointing to
a subordinate naming context in this global LDAP naming domain.
'refer;nssr' indicates that this is a non-specific subordinate reference
pointing to a subordinate naming context in this global LDAP naming domain.
3. Use of the knowledge attribute
Except when the manageDsaIT control (documented in section 6 of this
document) is present in the operation request, the refer attribute is not
visible to clients, except as its value is returned in referrals or con-
tinuation references.
If the manageDsaIT control is not set, and the entry named in a request
contains the refer attribute, and the entry is not the root DSE, the
server returns an LDAPResult with the resultCode field set to "referral"
and the referral field set to contain the value(s) of the refer attribute
minus any optional trailing whitespace and labels that might be present.
If the manageDsaIT control is not set, and an entry containing the ref
attribute is in the scope of a one level or subtree search request, the
server returns a SearchResultReference for each such entry containing
the value(s) of the entry's refer attribute.
When the manageDsaIT control is present in a request, the server will
treat an entry containing the refer attribute as an ordinary entry, and
the refer attribute as an ordinary attribute, and the server will not
return referrals or continuation references corresponding to refer
attributes.
4 Behaviour specification
4.1 Name resolution for any operation
Clients SHOULD perform at least simple "depth-of-referral count" loop
detection by incrementing a counter each time a new set of referrals is
received. (The maximum value for this count SHOULD be twice the number
of RDNs in the target object less one, to allow for ascending and
descending the DIT.) Clients MAY perform more sophisticated loop
detection, for example not chasing the same referral twice.
Case 1: The target entry is not held by the server and is
superior to some entry held by the server.
If the server DSE contains a "refer;sup" attribute then
the server will return an LDAPResult with the result code field set
Hedberg Expires September 30, 2000 [Page 4]
Internet-Draft LDAP Knowledge references July 2000
to referral, and the referral field set to contain the value(s) of
the "refer;sup" attribute minus any optional trailing whitespace and
labels that might be present.
Case 2: The target entry is not held by the server and is
subordinate to some entry, held by the server, that contains a
refer attribute.
The server will return an LDAPResult with the result code field set
to referral, and the referral field set to contain the value(s) of
the refer attribute minus any optional trailing whitespace and labels
that might be present.
Case 3: The target entry is held by the server and contains a
refer attribute without the 'nssr' option.
The server will return an LDAPResult with the result code field set
to referral, and the referral field set to contain the value(s) of
the refer attribute minus any optional trailing whitespace and labels
that might be present.
Case 4: The target entry is not held by the server, and is not
subordinate or superior to any object held by the server.
If the server contains a "refer;cross" attribute
in the root DSE with a baseobject that is either the same or
superior to the target entry then
the server will return an LDAPResult with the result code field set
to referral, and the referral field set to contain the value(s) of
these refer attributes minus any optional trailing whitespace and labels
that might be present.
4.2 Search evaluation
For search operations, once the base object has been found and
determined NOT to contain a refer attribute without the 'nssr'
option, the search may progress.
4.2.1 base-level
If the entry matches the filter and does NOT contain a refer attribute
it will be returned to the client as described in [RFC2251].
If the entry matches the filter contains a refer attribute without
the 'nssr' option it will be returned as a referral as described here.
If a matching entry contains a refer attribute and the URI
contained in the refer attribute is NOT an LDAP URI [RFC2255],
the server should return the URI value contained in the refer
attribute of that entry in a SearchResultReference.
Hedberg Expires September 30, 2000 [Page 5]
Internet-Draft LDAP Knowledge references July 2000
If a matching entry contains a refer attribute in the LDAP
URI syntax, the server will return an SearchResultReference
containing the value(s) of the refer attribute minus any optional
trailing whitespace and labels that might be present.
The URL from the refer attribute must be modified before it is
returned by adding or substituting a "base" scope into the URL. If the
URL does not contain a scope specifier, the "base" scope specifier must
be added. If the URL does contain a scope specifier, the existing scope
specifier must be replaced by the "base" scope.
4.2.2 One-level
Any entries matching the filter and one level scope that
do NOT contain a refer attribute are returned to the client normally as
described in [RFC2251]. Any entries matching the filter and one level
scope that contains a refer attribute without the 'nssr' option must
be returned as referrals as described here.
If a matching entry contains a refer attribute and the URI
contained in the refer attribute is NOT an LDAP URI [RFC2255],
the server should return the URI value contained in the refer
attribute of that entry in a SearchResultReference.
If a matching entry contains a refer attribute in the LDAP
URI syntax, the server will return an SearchResultReference
containing the value(s) of the refer attribute minus any optional
trailing whitespace and labels that might be present.
The URL from the refer attribute must be modified before it is
returned by adding or substituting a "base" scope into the URL. If the
URL does not contain a scope specifier, the "base" scope specifier must
be added. If the URL does contain a scope specifier, the existing scope
specifier must be replaced by the "base" scope.
4.2.3 Subtree search evaluation
Any entries, held by the server, matching the filter and
subtree scope that do NOT contain a refer attribute or contains
a refer attribute with the 'nssr' option are
returned to the client normally as described in [RFC2251].
Any entries matching the subtree scope and containing a refer
attribute must be returned as referrals as described here.
If a matching entry contains a refer attribute and the URI
contained in that attribute is NOT an LDAP URI [RFC2255],
the server should return the URI value contained in the refer
attribute of that entry in a SearchResultReference.
Hedberg Expires September 30, 2000 [Page 6]
Internet-Draft LDAP Knowledge references July 2000
If a matching entry contains a refer attribute in the LDAP
URI syntax, the server will return an SearchResultReference
containing the value(s) of the refer attribute minus any
optional trailing whitespace and labels that might be present.
N.B. in subtree search evaluation a entry containing a
refer attribut with the 'nssr' option might appear twice in the
result, first as a entry and then as a reference. A client
following all references might therefore end up with a resultset
containing two representations of the same entry, one from the
server getting the original query and one from the server
that the 'nssr' reference points to.
5. The referral object class
The referral object class is defined as follows.
( 1.2.752.17.2.10
NAME 'referral'
SUP top
STRUCTURAL
MAY ( refer ) )
The referral object class is a subclass of top and may contain the
refer attribute. The referral object class should, in general,
be used in conjunction with the extensibleObject object class to support
the naming attributes used in the entry's distinguished name.
Servers must support the refer attributes through use of the
referral object class. Any named reference must be of the referral
object class and will likely also be of the extensibleObject object
class to support naming and use of other attributes.
6. The manageDsaIT control
A client MAY specify the following control when issuing a search, com-
pare, add, delete, modify, or modifyDN request.
The control type is 2.16.840.1.113730.3.4.2. The control SHOULD be
marked as critical. There is no value; the controlValue field is
absent.
This control causes entries with the knowledge reference attributes to be
treated as normal entries, allowing clients to read and modify these entries.
Hedberg Expires September 30, 2000 [Page 7]
Internet-Draft LDAP Knowledge references July 2000
7. Superior Reference
This document defines two types of knowledge references that point to
parts of the naming context that is above of beyone the part held by a server.
The 'sup' option when referring to a LDAP server that holds a
naming context that is closer to the root of the same naming context and
'other' when referring to a LDAP server that holds a naming
context that belongs to a different naming domain then the one the
server belongs to.
Thus if the server receives a request for an operation where the
target entry is a entry closer to the root than the naming
context held the server and if the server holds a 'refer;sup' attribute
in the DSE, then the server MUST return an LDAPResult with the result
code field set to referral, and the referral field set to contain the
value(s) of the 'refer;sub' attribute minus any optional trailing
whitespace and labels that might be present.
On the other hand if the server receives a request for an operation
where the target entry is a entry that belongs to a other naming domain
and if there is any 'refer;other' attributes in the DSE with a base entry
that belongs to the same naming domain as the target entry and is
closer to the root then the target entry, then the server SHOULD return
an LDAPResult with the result code field set to referral, and the referral
field set to contain the value(s) of the 'refer;other' attribute minus
any optional trailing hitespace and labels that might be present.
8. Security Considerations
This document defines mechanisms that can be used to "glue" LDAP (and
other) servers together. The information used to specify this glue
information should be protected from unauthorized modification. If the
server topology information itself is not public information, the
information should be protected from unauthorized access as well.
9. References
[RFC1738]
Berners-Lee, T., Masinter, L., and McCahill, M., "Uniform Resource
Locators (URL)", RFC 1738, CERN, Xerox Corporation, University of
Minnesota, December 1994,
[RFC2079]
M. Smith, "Definition of an X.500 Attribute Type and an Object Class
to Hold Uniform Resource Identifiers (URIs)", RFC 2079, January
1997.
Hedberg Expires September 30, 2000 [Page 8]
Internet-Draft LDAP Knowledge references July 2000
[RFC2119]
S. Bradner, "Key Words for use in RFCs to Indicate Requirement Lev-
els", RFC 2119, March 1997. (Format: TXT=4723 bytes) (Also BCP0014)
(Status: BEST CURRENT PRACTICE)
[RFC2251]
M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol
(v3)", RFC 2251, December 1997. 1997.
[RFC2255]
T. Howes, M. Smith, "The LDAP URL Format", RFC 2255, December, 1997.
(Format: TXT=20685 bytes) (Status: PROPOSED STANDARD)
[X500]
ITU-T Rec. X.501, "The Directory: Models", 1993.
[X521]
ITU-T Rec. X.521, "---------------------", 1993.
12. Acknowledgements
This draft is heavily based on the previous drafts on knowledge
references in LDAP written by Christopher Lukas, Tim Howes,
Michael Roszkowski, Mark C. Smith, Mark Wahl and David Chadwick.
Peter Valkenburg and Henny Bekker has also made valueable
contributions.
13. Authors Address
Roland Hedberg
Catalogix
Dalsveien 53
0775 Oslo
Norway
EMail: Roland@catalogix.se
Hedberg Expires September 30, 2000 [Page 9]
Internet-Draft LDAP Knowledge references July 2000
Appendix A
Example of usage.
Information stored in a server.
dn:
objectclass: referral
refer;me: ldap://hostCAT/dc=cat,dc=se
refer;sup: ldap://hostSE/dc=se
refer;cross: ldap://hostNO/dc=no
refer;cross: ldap://hostNL/c=nl
dn: dc=cat,dc=se
objectclass: domain
dc: cat
dn: dc=one,dc=cat,dc=se
objectclass: extendedObject
objectclass: referral
refer;nssr: ldap://hostCAT1/dc=one,dc=cat,dc=se
ou: one
l: umea
dc: dc=two,dc=cat,dc=se
objectclass: referral
objectclass: extendedObject
refer;sub: ldap://hostCAT2/dc=two,dc=cat,dc=se
dn: dc=three,dc=cat,dc=se
objectclass: referral
objectclass: extendedObject
refer;cross: ldap://hostCAT3/dc=cat,dc=nl
dc: dc=four,dc=cat,dc=se
objectclass: domain
objectclass: extendedObject
ou: four
l: umea
Hedberg Expires September 30, 2000 [Page 10]
Internet-Draft LDAP Knowledge references July 2000
==========================================
A number of descriptive cases
==========================================
case 1: One-level search, target object on the server
search
baseobject: dc=cat,dc=se
scope: onelevel
filter: (objectclass=*)
attributes: ou
returns
searchResultEntry {
dn: dc=one,dc=cat,dc=se
ou: one
}
searchResultReference {
ldapurl: ldap://hostCAT2/dc=two,dc=cat,dc=se
}
searchResultReference {
ldapurl: ldap://hostCAT3/dc=cat,dc=nl
}
searchResultEntry {
dn: dc=four,dc=cat,dc=se
ou: four
}
searchResultDone {
resultCode: success
}
case 2: Subtree search, target object on the server
search
baseobject: dc=cat,dc=se
scope: subtree
filter: (objectclass=*)
attributes: ou
returns
searchResultEntry {
dn: dc=one,dc=cat,dc=se
ou: one
}
searchResultReference {
ldapurl: ldap://hostCAT1/dc=one,dc=cat,dc=se
}
searchResultReference {
ldapurl: ldap://hostCAT2/dc=two,dc=cat,dc=se
}
Hedberg Expires September 30, 2000 [Page 11]
Internet-Draft LDAP Knowledge references July 2000
searchResultReference {
ldapurl: ldap://hostCAT3/dc=cat,dc=nl
}
searchResultEntry {
dn: dc=four,dc=cat,dc=se
ou: four
}
searchResultDone {
resultCode: success
}
case 3: base search, target entry contains a 'refer;nssr' attribute
search
baseobject: dc=one,dc=cat,dc=se
scope: base
filter: (objectclass=*)
attributes: ou
returns
searchResultEntry {
dn: dc=one,dc=cat,dc=se
ou: four
}
searchResultDone {
resultCode: success
}
case 4: base search, target entry contains a 'refer;sub' attribute
search
baseobject: dc=two,dc=cat,dc=se
scope: base
filter: (objectclass=*)
attributes: ou
returns
searchResultDone {
resultCode: referral
matchedDN: dc=two,dc=cat,dc=se
referral: ldap://hostCAT2/dc=two,dc=cat,dc=se
}
Hedberg Expires September 30, 2000 [Page 12]
Internet-Draft LDAP Knowledge references July 2000
case 5: one-level search, target entry contains a 'refer;nssr' attribute
search
baseobject: dc=one,dc=cat,dc=se
scope: onelevel
filter: (objectclass=*)
attributes: ou
searchResultDone {
resultCode: referral
matchedDN: dc=one,dc=cat,dc=se
referral: ldap://hostCAT1/dc=one,dc=cat,dc=nu
}
case 6: Search on area above the baseobject of the server
search
baseobject: dc=pi,dc=se
scope: subtree
filter: (objectclass=*)
attributes: ou
returns
searchResultDone {
resultCode: referral
matchedDN: dc=se
referral: ldap://hostSE/dc=se
}
case 7: Search on area beyond, but not below the baseobject
of the server
search
baseobject: o=surfnet,c=nl
scope: base
filter: (objectclass=*)
returns
searchResultDone {
resultCode: referral
matchedDN: c=nl
referral: ldap://hostNL/c=NL
}
Hedberg Expires September 30, 2000 [Page 13]

View file

@ -1,229 +1,278 @@
INTERNET-DRAFT
draft-ietf-ldup-subentry-01.txt
Ed Reed
Novell, Inc.
August 29, 1999
LDAP Subentry Schema
1. Status of this Memo
This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference material
or to cite them other than as "work in progress."
INTERNET-DRAFT
draft-ietf-ldup-subentry-03.txt
Ed Reed
Reed-Matthews, Inc.
July 13, 2000
LDAP Subentry Schema
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be accessed at
http://www.ietf.org/shadow.html.
1. Status of this Memo
This Internet-Draft expires on February 29, 1999.
This document is an Internet-Draft and is in full
conformance with all provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet
Engineering Task Force (IETF), its areas, and its working
groups. Note that other groups may also distribute working
documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of
six months and may be updated, replaced, or obsoleted by
other documents at any time. It is inappropriate to use
Internet-Drafts as reference material or to cite them other
than as "work in progress."
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt.
The list of Internet-Draft Shadow Directories can be
accessed at http://www.ietf.org/shadow.html.
This Internet-Draft expires on January 13, 2001.
2. Abstract
2. Abstract
This document describes an object class called ldapSubEntry which MAY
be used to indicate operations and management related entries in the
directory, called LDAP Subentries. This version of this document is
updated with an assigned OID for the ldapSubEntry object class.
This document describes an object class called ldapSubEntry
which MAY be used to indicate operations and management
related entries in the directory, called LDAP Subentries.
This version of this document is updated with an assigned
OID for the ldapSubEntry object class.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC 2119 [RFC2119]. The
sections below reiterate these definitions and include some additional
ones.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in RFC 2119 [RFC2119]. The sections below
reiterate these definitions and include some additional
ones.
Reed . [Page 1]
Expires January 13, 2001
INTERNET-DRAFT 13 July 2000
LDAP Subentry Schema
3. Definition
Reed [Page 1]
Expires February 29, 2000
3.1 ldapSubEntry Class
INTERNET-DRAFT 29 August 1999
LDAP Subentry Schema
( 2.16.840.1.113719.2.142.6.1.1 NAME 'ldapSubEntry'
DESC 'LDAP Subentry class, version 1'
SUP top STRUCTURAL
MAY ( cn ) )
3. Definition
The class ldapSubEntry is intended to be used as a super-
class when defining other structural classes to be used
as LDAP Subentries, and as the structural class to which
Auxiliary classes may be added for application specific
subentry information. Where possible, the use of Auxiliary
classes to extend ldapSubEntries is strongly preferred.
The presence of ldapSubEntry in the list of super-classes
of an entry in the directory makes that entry an LDAP
Subentry. Object classes derived from ldapSubEntry are
themselves considered ldapSubEntry classes, for the purpose
of this discussion.
LDAP Subentries MAY be named by their commonName attribute
[LDAPv3]. Other naming attributes are also permitted.
3.1 ldapSubEntry Class
LDAP Subentries MAY be containers, unlike their [X.501]
counterparts.
( 2.16.840.1.113719.2.142.6.1.1 NAME 'ldapSubEntry'
DESC 'LDAP Subentry class, version 1'
SUP top STRUCTURAL
MUST ( cn ) )
LDAP Subentries MAY be contained by, and will usually be
located in the directory information tree immediately
subordinate to, administrative points and/or naming
contexts. Further (unlike X.500 subentries), LDAP
Subentries MAY be contained by other LDAP Subentries (the
way organizational units may be contained by other
organizational units). Deep nestings of LDAP Subentries
are discouraged, but not prohibited.
LDAP Subentries SHOULD be treated as "operational objects"
in much the same way that "operational attributes" are not
regularly provided in search results and read operations
when only user attributes are requested).
LDAP servers SHOULD implement the following special
handling of ldapSubEntry entries:
a) search operations which include a matching criteria
"objectclass=ldapSubEntry" MUST include entries derived
Reed . [Page 2]
Expires January 13, 2001
INTERNET-DRAFT 13 July 2000
LDAP Subentry Schema
from the ldapSubEntry class in the scope of their
operations;
b) search operations which do not include a matching
criteria "objectclass=ldapSubEntry" MUST IGNORE entries
derived from the ldapSubEntry class, and exclude them from
the scope of their operations.
The combination of SHOULD and MUST in the special handling
instructions, above, are meant to convey this: Servers
SHOULD support this special handling, and if they do they
MUST do it as described, and not some other way.
The class ldapSubEntry is intended to be used as a super class when
defining other structural classes to be used as LDAP Subentries. The
presence of ldapSubEntry in the list of super-classes of an entry in
the directory makes that entry an LDAP Subentry. Object classes
derived from ldapSubEntry are themselves considered ldapSubEntry
classes, for the purpose of this discussion.
LDAP Subentries MAY be named by their commonName attribute [LDAPv3].
Other naming attributes are also permitted.
LDAP Subentries MAY be containers, unlike their [X.501] counterparts.
4. Security Considerations
LDAP Subentries MAY be contained by, and will usually be located in
the directory information tree immediately subordinate to,
administrative points and/or naming contexts [LDUPINFO]. Further
(unlike X.500 subentries), LDAP Subentries MAY be contained by other
LDAP Subentries (the way organizational units may be contained by
other organizational units). Deep nestings of LDAP Subentries are
discouraged, but not prohibited.
LDAP Subentries will frequently be used to hold data which
reflects either the actual or intended behavior of the
directory service. As such, permission to read such
entries MAY need to be restricted to authorized users.
More importantly, IF a directory service treats the
information in an LDAP Subentry as the authoritative source
of policy to be used to control the behavior of the
directory, then permission to create, modify, or delete
such entries MUST be carefully restricted to authorized
administrators.
LDAP Subentries SHOULD be treated as "operational objects" in much the
same way that "operational attributes" are not regularly provided in
search results and read operations when only user attributes are
requested).
LDAP servers SHOULD implement the following special handling of
ldapSubEntry entries:
a) search operations which include a matching criteria
"objectclass=ldapSubEntry" MUST include entries derived from the
ldapSubEntry class in the scope of their operations;
5. References
[LDAPv3] S. Kille, M. Wahl, and T. Howes, "Lightweight
Directory Access Protocol (v3)", RFC 2251, December 1997
[X.501] ITU-T Rec. X.501, "The Directory: Models", 1993
b) search operations which do not include a matching criteria
"objectclass=ldapSubEntry" MUST IGNORE entries derived from the
ldapSubEntry class, and exclude them from the scope of their
operations.
6. Copyright Notice
Copyright (C) The Internet Society (1999). All Rights
Reserved.
This document and translations of it may be copied and
furnished to others, and derivative works that comment on
or otherwise explain it or assist in its implementation may
be prepared, copied, published and distributed, in whole or
Reed [Page 2]
Expires February 29, 2000
Reed . [Page 3]
Expires January 13, 2001
INTERNET-DRAFT 29 August 1999
LDAP Subentry Schema
INTERNET-DRAFT 13 July 2000
LDAP Subentry Schema
The combination of SHOULD and MUST in the special handling
instructions, above, are meant to convey this: Servers SHOULD support
this special handling, and if they do they MUST do it as described,
and not some other way.
in part, without restriction of any kind, provided that the
above copyright notice and this paragraph are included on
all such copies and derivative works. However, this
document itself may not be modified in any way, such as by
removing the copyright notice or references to the Internet
Society or other Internet organizations, except as needed
for the purpose of developing Internet standards in which
case the procedures for copyrights defined in the Internet
Standards process must be followed, or as required to
translate it into languages other than English.
The limited permissions granted above are perpetual and
will not be revoked by the Internet Society or its
successors or assigns.
This document and the information contained herein is
provided on an "AS IS" basis and THE INTERNET SOCIETY AND
THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL
NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
7. Acknowledgements
4. Security Considerations
The use of subEntry object class to store Replica and
Replication Agreement information is due primarily to the
lucid explanation by Mark Wahl, Innosoft, of how they could
be used and extended.
The IETF takes no position regarding the validity or scope
of any intellectual property or other rights that might be
claimed to pertain to the implementation or use of the
technology described in this document or the extent to
which any license under such rights might or might not be
available; neither does it represent that it has made any
effort to identify any such rights. Information on the
IETF's procedures with respect to rights in standards-track
and standards-related documentation can be found in BCP-11.
Copies of claims of rights made available for publication
and any assurances of licenses to be made available, or the
result of an attempt made to obtain a general license or
permission for the use of such proprietary rights by
implementors or users of this specification can be obtained
from the IETF Secretariat.
LDAP Subentries will frequently be used to hold data which reflects
either the actual or intended behavior of the directory service. As
such, permission to read such entries MAY need to be restricted to
authorized users. More importantly, IF a directory service treats the
information in an LDAP Subentry as the authoritative source of policy
to be used to control the behavior of the directory, then permission
to create, modify, or delete such entries MUST be carefully restricted
to authorized administrators.
Reed . [Page 4]
Expires January 13, 2001
5. References
INTERNET-DRAFT 13 July 2000
LDAP Subentry Schema
[LDUPINFO] _ E. Reed, "LDUP Replication Information Model", draft-
ietf-ldup-infomod-01.txt
The IETF invites any interested party to bring to its
attention any copyrights, patents or patent applications,
or other proprietary rights which may cover technology that
may be required to practice this standard. Please address
the information to the IETF Executive Director.
[LDAPv3] S. Kille, M. Wahl, and T. Howes, "Lightweight Directory
Access Protocol (v3)", RFC 2251, December 1997
[X.501] ITU-T Rec. X.501, "The Directory: Models", 1993
8. Author's Address
Edwards E. Reed
Reed-Matthews, Inc.
1064 E 140 North
Lindon, UT 84042
USA
E-mail: eer@oncalldba.com
LDUP Mailing List: ietf-ldup@imc.org
LDAPEXT Mailing List: ietf-ldapext@netscape.com
6. Copyright Notice
Copyright (C) The Internet Society (1999). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published and
distributed, in whole or in part, without restriction of any kind,
provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of developing
Internet standards in which case the procedures for copyrights defined
in the Internet Standards process must be followed, or as required to
translate it into languages other than English.
Reed [Page 3]
Expires February 29, 2000
INTERNET-DRAFT 29 August 1999
LDAP Subentry Schema
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN
WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
7. Acknowledgements
The use of subEntry object class to store Replica and Replication
Agreement information is due primarily to the lucid explanation by
Mark Wahl, Innosoft, of how they could be used and extended.
The IETF takes no position regarding the validity or scope of any
intellectual property or other rights that might be claimed to pertain
to the implementation or use of the technology described in this
document or the extent to which any license under such rights might or
might not be available; neither does it represent that it has made any
effort to identify any such rights. Information on the IETF's
procedures with respect to rights in standards-track and standards-
related documentation can be found in BCP-11. Copies of claims of
rights made available for publication and any assurances of licenses
to be made available, or the result of an attempt made to obtain a
general license or permission for the use of such proprietary rights
by implementors or users of this specification can be obtained from
the IETF Secretariat.
The IETF invites any interested party to bring to its attention any
copyrights, patents or patent applications, or other proprietary
rights which may cover technology that may be required to practice
this standard. Please address the information to the IETF Executive
Director.
8. Author's Address
Edwards E. Reed
Novell, Inc.
122 E 1700 S
Provo, UT 84606
USA
E-mail: Ed_Reed@Novell.com
Reed [Page 4]
Expires February 29, 2000
INTERNET-DRAFT 29 August 1999
LDAP Subentry Schema
LDUP Mailing List: ietf-ldup@imc.org
@ -232,45 +281,6 @@ INTERNET-DRAFT 29 August 1999
Reed [Page 5]
Expires February 29, 2000
Reed . [Page 5]
Expires January 13, 2001

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,501 @@
INTERNET-DRAFT Kurt D. Zeilenga
Intended Category: Standard Track OpenLDAP Foundation
Expires: 11 January 2001 11 July 2000
LDAP Authentication Password Attribute
<draft-zeilenga-ldap-authpasswd-03.txt>
1. Status of this Memo
This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026.
This document is intended to be, after appropriate review and
revision, submitted to the RFC Editor as a Standard Track document.
Distribution of this memo is unlimited. Technical discussion of this
document will take place on the IETF LDAP Extension Working Group
mailing list <ietf-ldapext@netscape.com>. Please send editorial
comments directly to the author <Kurt@OpenLDAP.org>.
Internet-Drafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft
Shadow Directories can be accessed at http://www.ietf.org/shadow.html.
Copyright 2000, The Internet Society. All Rights Reserved.
Please see the Copyright section near the end of this document for
more information.
2. Abstract
This document describes schema for storing information in support of
user/password authentication in a LDAP [RFC2251] directory. The
document defines the authPassword attribute type and related schema.
The attribute type is used to store values derived from the user's
password(s) (commonly using cryptographic strength one-way hash).
authPassword is intended to used instead of clear text password
Zeilenga [Page 1]
INTERNET-DRAFT LDAP AuthPasswd 11 July 2000
storage mechanisms such as userPassword [RFC2256]. The values of
authPassword may be used to support both LDAP "simple" and SASL
[RFC2222] password authentication mechanisms [RFC2829].
The key words ``MUST'', ``MUST NOT'', ``REQUIRED'', ``SHALL'', ``SHALL
NOT'', ``SHOULD'', ``SHOULD NOT'', ``RECOMMENDED'', and ``MAY'' in
this document are to be interpreted as described in RFC 2119
[RFC2119].
3. Background and Intended Use
The userPassword attribute type [RFC 2256] is intended be used to used
to support the LDAP [RFC2251] "simple" bind operation. However,
values of userPassword must be clear text passwords. It is often
desirable to store values derived from the user's password(s) instead
of actual passwords.
The authPassword attribute type is intended to be used to store
information used to implement password based authentication. The
attribute type may be used by LDAP servers to implement user/password
authentication operations [RFC2829] such "simple" and SASL [RFC2222] /
DIGEST-MD5 [RFC2831].
The attribute type supports multiple storage schemes. A matching rule
is provided for use with extensible search filters to allow clients to
assert that a clear text password "matches" one of the attribute's
values. Storage schemes often use of cryptographic strength one-way
hashing.
This attribute may be used in conjunction with server side password
generation mechanisms (such as [PW-EXOP]).
Access to this attribute may governed by administrative controls such
as those which implement password change policies.
4. Schema Definitions
The following schema definitions are described in terms of LDAPv3
Attribute Syntax Definitions [RFC2252] with specific syntax detailed
using Augmented BNF [RFC2234].
Editor's Note: object identifiers (OIDs) will be assigned before this
document is published as an RFC.
4.1. authPasswordSyntax
Zeilenga [Page 2]
INTERNET-DRAFT LDAP AuthPasswd 11 July 2000
( authPasswordSyntaxOID
DESC 'authentication password syntax' )
Values of this syntax are encoded according to the following BNF:
authPasswordValue = w scheme s [authInfo] s authValue w
scheme = <an IA5 string of uppercase letters, numbers,
and "-", "_", and "/">
authInfo = schemeSpecificValue
authValue = schemeSpecfiicValue
schemeSpecificValue = <an IA5 printable string
not containing "$" or " ">
s = w sep w
w = *sp
sep = "$" ; an IA5 dollar sign (36)
sp = " " ; an IA5 space (20)
where scheme describes the storage mechanism, authInfo and authValue
are a scheme specific. The authInfo field is often a base64 encoded
salt. The authValue field is often a base64 encoded value derived
from a user's password(s). Values of this attribute are case
sensitive.
This document describes a number of schemes, as well as requirements
for the scheme naming, in section 5.
4.2. authPasswordMatch
( authPasswordMatchOID
NAME 'authPasswordMatch'
DESC 'authentication password matching rule'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
This matching rule allows a client to assert that a password matches
values of authPasswordSyntax using an extensibleMatch filter
component. Each value is matched per its scheme. The assertion is
TRUE if one or more attribute values matches the asserted value, FALSE
if all values do not matches, and Undefined otherwise.
Servers which support use of this matching rule SHOULD publish
appropriate matchingRuleUse values per [RFC2252], 4.4.
Transfer of authPasswordMatch assertion values is strongly discouraged
where the underlying transport service cannot guarantee
confidentiality and may result in disclosure of the values to
unauthorized parties.
Zeilenga [Page 3]
INTERNET-DRAFT LDAP AuthPasswd 11 July 2000
4.3. supportedAuthPasswordSchemes
( supportedAuthPasswordSchemesOID
NAME 'supportedAuthPasswordSchemes'
DESC 'supported password storage schemes'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32}
USAGE dSAOperation )
The values of this attribute are names of supported authentication
password schemes which the server supports. The syntax of a scheme
name is described in section 4.1. This attribute may only be present
in the root DSE. If the server does not support any mechanisms this
attribute will not be present.
4.4. authPassword
( authPasswordOID NAME 'authPassword'
SYNTAX authPasswordSyntaxOID )
The values of this attribute are representative of the user's
password(s) and conform to the authPasswordSyntax described in 4.1.
The values of this attribute may be used for authentication purposes.
This attribute type is defined without any built-in matching rules.
The absence of an EQUALITY matching rules disallows modification of
individual values.
Transfer of authPassword values is strongly discouraged where the
underlying transport service cannot guarantee confidentiality and may
result in disclosure of the values to unauthorized parties.
4.5. authPasswordObject
( authPasswordObjectOID NAME 'authPasswordObject'
DESC 'authentication password mix in class'
MAY 'authPassword' AUXILIARY )
Entries of this object class may contain authPassword attribute types.
5. Schemes
This section describes the "MD5", "SHA1", and "SASL/DIGEST-MD5".
Other schemes may be defined by other documents. Schemes starting
with string "SASL/" indicate association with a SASL mechanism.
Zeilenga [Page 4]
INTERNET-DRAFT LDAP AuthPasswd 11 July 2000
Schemes which are not described by standard track documents SHOULD be
named with a leading "X-" or, if associated with a SASL mechanism,
"SASL/X-" to indicate they are a private or implementation specific
mechanism, or may be named using the dotted-decimal representation
[RFC2252] of an OID assigned to the mechanism.
5.1. MD5 scheme
The MD5 [RFC1321] scheme name is "MD5".
The authValue is the base64 encoding of an MD5 digest of the
concatenation the user password and optional salt. The base64
encoding of the salt is provided in the authInfo field.
Implementations of this scheme must support salts up to 128-bit in
length. Use with a 64-bit or larger salt is RECOMMENDED.
Example:
Given a user "joe" who's password is "mary" and a salt of "salt",
the authInfo field would be the base64 encoding of "salt" and the
authValue field would be the base64 encoding of the MD5 digest of
"marysalt".
A match against an asserted password and an attribute value of this
scheme SHALL be true if and only if the MD5 digest of concatenation of
the asserted value and the salt is equal to the MD5 digest contained
in AuthValue. The match SHALL be undefined if the server is unable to
complete the equality test for any reason. Otherwise the match SHALL
be false.
Values of this scheme SHOULD only be used to implement simple
user/password authentication.
It is RECOMMENDED that values of this scheme be protected as if they
were clear text passwords.
5.2. SHA1 scheme
The SHA1 [SHA1] scheme name is "SHA1".
The authValue is the base64 encoding of an SHA1 digest of the
concatenation the user password and the optional salt. The base64
encoding of the salt is provided in the authInfo field.
Implementations of this scheme must support salts up to 128-bit in
length. Use with a 64-bit or larger salt is RECOMMENDED.
Example:
Zeilenga [Page 5]
INTERNET-DRAFT LDAP AuthPasswd 11 July 2000
Given a user "joe" who's password is "mary" and a salt of "salt",
the authInfo field would be the base64 encoding of "salt" and the
authValue field would be the base64 encoding of the SHA1 digest of
"marysalt".
A match against an asserted password and an attribute value of this
scheme SHALL be true if and only if the SHA1 digest of concatenation
of the asserted value and the salt is equal to the SHA1 digest
contained in AuthValue. The match SHALL be undefined if the server is
unable to complete the equality test for any reason. Otherwise the
match SHALL be false.
Values of this scheme SHOULD only be used to implement simple
user/password authentication.
It is RECOMMENDED that values of this scheme be protected as if they
were clear text passwords.
5.3. DIGEST-MD5 scheme
The DIGEST-MD5 scheme name is "SASL/DIGEST-MD5".
The authValue is the base64 encoding of
H( { username-value, ":", realm-value, ":", passwd } )
and authInfo is the base64 encoding of
{ username-value, ":", realm-value }
as defined by RFC2831.
Example:
Given a user "joe" within the realm "localhost" who's password is
"mary", the info field would be the base64 encoding of
"joe:localhost" and the authValue field would be the base64 encoding
of the MD5 digest of "joe:localhost:mary".
Values of this scheme SHOULD only be used to implement the
SASL/DIGEST-MD5 as described by the Authentication Methods for LDAP
[RFC2829]. A simple password assertion against a value of this scheme
SHALL be considered undefined.
Values of this scheme MUST be protected as if it the values were clear
text passwords per reasons detailed in DIGEST-MD5, Section 3.9,
"Storing Passwords."
6. Implementation Issues
Zeilenga [Page 6]
INTERNET-DRAFT LDAP AuthPasswd 11 July 2000
For implementations of this specification:
Servers MAY restrict which schemes are used in conjunction with a
particular authentication process but SHOULD use all values of
selected schemes. If the asserted password matches any of the
stored values, the asserted password SHOULD be considered valid.
Servers MAY use other authentication storage mechanisms, such as
userPassword or an external password store, in conjunction with
authPassword to support the authentication process.
Servers that support simple bind MUST support the MD5 scheme and
SHOULD support the SHA1 scheme.
Servers SHOULD not publish values of authPassword nor allow
operations which expose authPassword or AuthPasswordMatch values to
unless confidentiality protection is in place.
Clients SHOULD not initiate operations which provide or request
values of authPassword or make authPasswordMatch assertions unless
confidentiality protection is in place.
Clients SHOULD not assume that a successful AuthPasswordMatch,
whether by compare or search, is sufficient to gain directory
access. The bind operation MUST be used to authentication to the
directory.
7. Security Considerations
This document describes how authentication information may be stored
in a directory. Authentication information must be adequately
protected as unintended disclosure will allow attackers to gain
immediate access to the directory as described by [RFC2829].
Values of authPassword SHOULD be protected as if they were clear text
passwords. When values are transferred, privacy protections, such as
IPSEC or TLS, SHOULD be in place.
Clients SHOULD use strong authentication mechanisms [RFC2829].
AuthPasswordMatch matching rule allows applications to test the
validity of a user password and, hence, may be used to mount a
dictionary attack. Servers SHOULD take appropriate measures to
protect the directory from such attacks.
Some password schemes may require CPU intensive operations. Servers
SHOULD take appropriate measures to protect against Denial of Service
attacks.
Zeilenga [Page 7]
INTERNET-DRAFT LDAP AuthPasswd 11 July 2000
AuthPassword does not restrict an authentication identity to a single
password. An attacker who gains write access to this attribute may
store additional values without disabling the user's true password(s).
Use of policy aware clients and servers is RECOMMENDED.
The level of protection offered against various attacks differ from
scheme to scheme. It is RECOMMENDED that servers support scheme
selection as a configuration item. This allows for a scheme to be
easily disabled if a significant security flaw is discovered.
8. Copyright
Copyright 2000, The Internet Society. All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published and
distributed, in whole or in part, without restriction of any kind,
provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be followed,
or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE AUTHORS, THE INTERNET SOCIETY, AND THE INTERNET
ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
9. Acknowledgment
This document borrows from a number of IETF documents and is based
upon input from the IETF LDAPext working group.
10. Bibliography
[RFC1321] R. Rivest, "The MD5 Message-Digest Algorithm", RFC 1321,
Zeilenga [Page 8]
INTERNET-DRAFT LDAP AuthPasswd 11 July 2000
April 1992
[RFC2219] S. Bradner, "Key words for use in RFCs to Indicate
Requirement Levels", RFC 2119, March 1997.
[RFC2222] J. Myers, "Simple Authentication and Security Layer (SASL)",
RFC 2222, October 1997.
[RFC2234] D. Crocker (editor), P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", RFC 2234, November 1997.
[RFC2251] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access
Protocol (v3)", RFC 2251, December 1997.
[RFC2252] M. Wahl, A. Coulbeck, T. Howes, S. Kille, "Lightweight
Directory Access Protocol (v3): Attribute Syntax
Definitions", RFC 2252, December 1997.
[RFC2256] M. Wahl, "A Summary of the X.500(96) User Schema for use
with LDAPv3", RFC 2256, December 1997.
[RFC2307] L. Howard, "An Approach for Using LDAP as a Network
Information Service", RFC 2307, March 1998.
[RFC2829] M. Wahl, H. Alvestrand, J. Hodges, RL "Bob" Morgan,
"Authentication Methods for LDAP", RFC 2829, June 2000.
[RFC2831] P. Leach, C. Newman, "Using Digest Authentication as a SASL
Mechanism", RFC 2831, June 2000.
[PW-EXOP] K. Zeilenga, "LDAP Password Modify Extended Operation"
draft-zeilenga-ldap-passwd-exop-xx.txt, a work in progress.
[SHA1] NIST, FIPS PUB 180-1: Secure Hash Standard, April 1995.
11. Author's Address
Kurt D. Zeilenga
OpenLDAP Foundation
<Kurt@OpenLDAP.org>
Zeilenga [Page 9]

View file

@ -0,0 +1,507 @@
INTERNET-DRAFT Kurt D. Zeilenga
Intended Category: Standard Track OpenLDAP Foundation
Expires: 4 January 2001 4 July 2000
LDAPv3: Grouping of Related Operations
<draft-zeilenga-ldap-grouping-00.txt>
Status of Memo
This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026.
This document is intended to be, after appropriate review and
revision, submitted to the RFC Editor as a Standard Track document.
Distribution of this memo is unlimited. Technical discussion of this
document will take place on the IETF LDAP Extension Working Group
mailing list <ietf-ldapext@netscape.com>. Please send editorial
comments directly to the author <Kurt@OpenLDAP.org>.
Internet-Drafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft
Shadow Directories can be accessed at http://www.ietf.org/shadow.html.
Copyright 2000, The Internet Society. All Rights Reserved.
Please see the Copyright section near the end of this document for
more information.
1. Abstract
This document provides a general mechanisms for grouping related LDAP
operations. Grouping of operations may be used to support
replication, proxies, and higher level operations such as
transactions. This document describes a set of LDAP [RFC2251]
extended operations and other protocol and schema elements to support
grouping of related operations.
Zeilenga [Page 1]
INTERNET-DRAFT draft-zeilenga-ldap-grouping-00 4 July 2000
2. Overview
This document provides a mechanism to allow clients to group
operations.
A group of operations is defined as a set of operations upon a common
session identified by a unique cookie. All requests which are
initiated with the same cookie belong to same grouping. The cookie is
obtained using the create group operation and is normally valid until
the end group operation is issued. A group may be ended by a server
prematurely as noted described below.
Operations regardless of their grouping (or lack of grouping) may be
intermixed. Groups may be nested.
Each group is of a particular type. This type defines the semantics
of the group and is specified when the group is created.
The key words "SHALL", "SHALL NOT", "MUST", "MUST NOT", "SHOULD",
"SHOULD NOT", "MAY" and "MAY NOT" used in this document are to be
interpreted as described in [RFC2119].
3. Protocol Elements
This document describes two extended operations, one unsolicited
notification, and one control. Extended operations and controls are
described by LDAP [RFC2251] as follows:
ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
requestName [0] LDAPOID,
requestValue [1] OCTET STRING OPTIONAL
}
ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
COMPONENTS of LDAPResult,
responseName [10] LDAPOID OPTIONAL,
response [11] OCTET STRING OPTIONAL
}
Control ::= SEQUENCE {
controlType LDAPOID,
criticality BOOLEAN DEFAULT FALSE,
controlValue OCTET STRING OPTIONAL
}
Editor's Note:
Zeilenga [Page 2]
INTERNET-DRAFT draft-zeilenga-ldap-grouping-00 4 July 2000
OID which appear in this document are fictious. Actual OIDs will be
assigned before this document is progressed.
3.1 Common Protocol Elements
groupCookie :== OCTET STRING
A groupCookie is an arbitrary octet string uniquely identify a
grouping of related operations within the session.
A groupCookie is a notational convenience.
3.2 createGrouping Operation
The createGrouping extended operation is used to create or start a
grouping of related operations. The operation consists of the
createGroupingRequest and the createGroupingResponse. The OID
createGroupingOID identifies this operation and SHOULD be listed as a
value of supportedExtensions in the root DSE of servers which support
this operation.
createGroupingOID ::= "1.1.1"
3.2.1 createGroupingRequest
The client initiates this operation by sending a
createGroupingRequest. This request is an ExtendedRequest where the
requestName is the value createGroupOID and requestValue is BER
encoded createGroupingRequestValue
createGroupingRequestValue ::= SEQUENCE {
createGroupType [0] LDAPOID,
createGroupValue [1] OCTET STRING OPTIONAL
}
where createGroupType is an OID that describes the specific type of
grouping and createGroupValue contains a type specific payload.
3.2.1 createGroupingResponse
The createGroupingResponse is sent in response to a
createGroupingRequest. This response is an ExtendedResponse where the
responseName MUST be the value of the requestName provided in request
and the response is a BER encoded createGroupingResponseValue.
Zeilenga [Page 3]
INTERNET-DRAFT draft-zeilenga-ldap-grouping-00 4 July 2000
createGroupingResponseValue ::= SEQUENCE {
createGroupCookie [0] groupCookie,
createGroupValue [1] OCTET STRING OPTIONAL
}
where createGroupCookie is a cookie uniquely identifying the grouping
and createGroupValue is a type specific payload.
3.3 endGrouping Operation
The endGrouping extended operation is used to end or stop a grouping
of related operations. The operation consists of the
endGroupingRequest and the endGroupingResponse. The OID
endGroupingOID identifies this operation and SHOULD be listed as a
value of supportedExtensions in the root DSE of servers which support
this operation.
endGroupingOID ::= "1.1.2"
3.3.1 endGroupingRequest
The client initiates this operation by sending an endGroupingRequest.
This request is an ExtendedRequest where the requestName is the value
endGroupOID and requestValue is BER encoded endGroupingRequestValue
endGroupingRequestValue ::= SEQUENCE {
endGroupCookie [0] groupCookie,
groupValue [1] OCTET STRING OPTIONAL
}
where endGroupCookie is an cookie identifying the grouping and
groupValue contains a type specific payload.
3.3.2 endGroupingResponse
The endGroupingResponse is sent in response to a endGroupingRequest.
This response is an ExtendedResponse where the responseName MUST be
the value of the requestName provided in request and the response is a
BER encoded endGroupingResponseValue
endGroupingResponseValue ::= SEQUENCE {
groupValue [1] OCTET STRING OPTIONAL
}
where groupValue is a type specific payload.
Zeilenga [Page 4]
INTERNET-DRAFT draft-zeilenga-ldap-grouping-00 4 July 2000
3.4 endGroupingNotice
The endGroupingNotice is an LDAP unsolicited notification. The
notification may be sent to the client to end a grouping which the
server is unable or unwilling to continue to process. The notice is
an extendedResponse where the responseName is the OID
endGroupingNoticeOID and the response is a BER encoded
endGroupingNoticeValue
endGroupingNoticeOID ::= "1.1.3"
endGroupingNoticeValue ::= SEQUENCE {
endGroupingCookie [0] groupCookie,
groupValue [1] OCTET STRING OPTIONAL
}
where endGroupingCookie is a cookie uniquely identifying the grouping
and groupingValue contains a type specific payload.
3.5 groupingControl
The groupingControl is used to identify requests and responses as
belonging to grouping of operations. The groupingControl is a Control
where the controlType is the OID groupingControlOID and the
criticalValue is a BER encoded groupingControlValue
groupingControlOID ::= "1.1.4"
groupingControlValue ::= SEQUENCE {
groupingCookie [0] groupCookie,
groupValue [1] OCTET STRING OPTIONAL
}
where groupingCookie is a cookie uniquely identifying the grouping,
the critical is TRUE, and groupingValue contains a type specific
payload.
The value groupingControlOID SHOULD be listed as a value of
supportedControls in the root DSE by servers which support this
control.
The control MAY be present on add, compare, delete, moddn, modify, and
search requests and responses. The control SHALL NOT be present on a
abandon, bind, unbind. The control SHALL NOT be present on any
extended operation which affects the behavior of the session such as
the Start TLS [RFC2830] operation. The control SHALL NOT be present
if the operation includes any control which likewise causes the
Zeilenga [Page 5]
INTERNET-DRAFT draft-zeilenga-ldap-grouping-00 4 July 2000
operation to affects the behavior of the session.
The control SHALL NOT appear multiple times in the same LDAP PDU and.
If multiple occurrences of the control are detected, the PDU MUST be
treated as a protocol error.
4. Schema Elements
4.1. supportedGroupingTypes
Servers SHOULD publish grouping types they support listing their OID
as values of the supportedGrouping attribute type in the root DSE.
The supportedGrouping attribute type is defined as:
( 1.1.5 NAME 'supportedGroupingTypes'
DESC 'supported types of groupings of operations'
EQUALITY objectIdentifierMatch
SYNTAX ObjectIdentifierSyntax )
5. Operational Semantics
This section needs work.
5.1 Grouping Operations
5.1.1 createGrouping
To group related operations, the client MUST request a groupCookie
from the server by sending a createGroupingRequest as described in
3.2.1. The client SHALL provide type specific payload in
createGroupValue if so required by the grouping type.
The server SHALL respond with a createGroupingResponse as described in
3.2.2. If the server is willing and able to create the grouping as
requested (and per type requirements), it SHALL respond with success,
provide a session-unique groupCookie and, if appropriate, a type
specific payload. Otherwise the server SHALL respond with a non-
successful response and provide no groupCookie, but MAY, if
appropriate, provide a type specific payload.
5.1.2 endGrouping
When the client wishes to end the grouping, the client SHALL send a
endGroupingRequest as described in 3.3.1. The client SHALL provide
Zeilenga [Page 6]
INTERNET-DRAFT draft-zeilenga-ldap-grouping-00 4 July 2000
the groupCookie of the grouping to be ended and MAY provided a type
specific payload.
The server SHALL respond with an endGroupingResponse as described in
3.3.2.
5.1.3 endGroupNotice
The server MAY end a group without solicitation for any reason but
MUST send a endGrouping Notice, as described in 3.4, indicating this
action. The server SHALL provide the groupCookie of the group it
terminated and MAY provide a type specific payload. The notice SHALL
have a non-success resultCode.
5.1.4 grouped operations
Operations with a group are carry a groupingControl as described in
3.5.
Group type specifications MAY restrict the types and/or number of
operations which may be related. Servers MAY also place restrictions
upon groupings. Clients SHOULD NOT assume arbitrary support for
grouping.
5.1.5 nested groupings
Groups of the same or different types may be nested. A nested group
is instantiated by providing a groupingControl containing the parent
group with the createGroupingRequest.
Group type specifications MAY restrict the types of groupings which
may be nested. Servers MAY also place restrictions upon nesting.
Clients SHOULD NOT assume arbitrary support for nesting.
5.3 Other Operations
Upon issuing of any grouping operation, semantics of non-grouping
operations listed is modified as described below.
5.3.1 bind
The client SHOULD end all outstanding groupings before issuing a bind
request.
Zeilenga [Page 7]
INTERNET-DRAFT draft-zeilenga-ldap-grouping-00 4 July 2000
The bind operation MUST, in addition to the behavior described in RFC
2251, must abandon all outstanding groups.
5.3.2 unbind
The unbind operation MUST, in addition to the behavior described in
RFC 2251, must abandon all outstanding groups.
5.3.3 Start TLS
The client SHALL end all outstanding groupings before issuing a Start
TLS request.
The Start TLS operation MUST, in addition to the behavior described in
RFC 2830, return operationsError if there are any outstanding
groupings.
7. Security Considerations
This mechanism may be used to support complex groupings of related
operations for arbitrary purposes. This document places no
restrictions on how the grouped operations relate to each other.
It is conceived that different groups of operations may have different
authorization and/or access controls associated with them (when used
to multiplex proxied directory sessions). Authors of specifications
for such groupings take special care in addressing security issues.
It is conceived that different groups of operations may form complex
super-operations such as transactions. Authors of specifications for
such groupings should take special care to address denial of service
issues.
8. References
[RFC2119] S. Bradner, "Key Words for use in RFCs to Indicate
Requirement Levels", Harvard University, RFC 2119, March
1997.
[RFC2251] M. Wahl, S. Kille, T. Howes, "Lightweight Directory Access
Protocol (v3)", RFC 2251, December 1997.
9. Acknowledgments
Zeilenga [Page 8]
INTERNET-DRAFT draft-zeilenga-ldap-grouping-00 4 July 2000
The author gratefully acknowledge the contributions of the IETF LDUP
and LDAPext working group.
10. Additional Information
Discussions regarding these suggestions may directed to the author:
Kurt D. Zeilenga
OpenLDAP Foundation
<Kurt@OpenLDAP.org>
or the LDAPext Working Group mailing list:
<ietf-ldapext@netscape.com>
Copyright 2000, The Internet Society. All Rights Reserved.
This document and translations of it may be copied and furnished
to others, and derivative works that comment on or otherwise explain
it or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph
are included on all such copies and derivative works. However,
this document itself may not be modified in any way, such as by
removing the copyright notice or references to the Internet Society
or other Internet organizations, except as needed for the purpose
of developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not
be revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on
an "AS IS" basis and THE AUTHORS, THE INTERNET SOCIETY, AND THE
INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
PURPOSE.
Zeilenga [Page 9]

View file

@ -0,0 +1,675 @@
INTERNET-DRAFT Kurt D. Zeilenga
Intended Category: Standard Track OpenLDAP Foundation
Expires: 4 January 2001 4 July 2000
Named References in LDAP Directories
<draft-zeilenga-ldap-namedref-00.txt>
1. Status of this Memo
This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026.
This document is intended to be, after appropriate review and
revision, submitted to the RFC Editor as a Standard Track document.
Distribution of this memo is unlimited. Technical discussion of this
document will take place on the IETF LDAP Extension Working Group
mailing list <ietf-ldapext@netscape.com>. Please send editorial
comments directly to the author <Kurt@OpenLDAP.org>.
Internet-Drafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft
Shadow Directories can be accessed at http://www.ietf.org/shadow.html.
Copyright 2000, The Internet Society. All Rights Reserved.
Please see the Copyright section near the end of this document for
more information.
2. Abstract
This document defines schema and protocol elements for representing
and manipulating generic knowledge information in LDAP [RFC2251]
directories. An attribute type "ref" is used to store URIs [RFC1738]
which may refer to LDAP and non-LDAP services. An object class
"referral" is used to construct entries in an LDAP directory which
references to other directories or services. An control, ManageDsaIT,
is defined to allow clients to manipulate referral objects as normal
entries. The document describes procedures directory servers should
follow when supporting these elements.
Zeilenga [Page 1]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
3. Background and intended usage
The broadening of interest in LDAP directories beyond their use as
front ends to X.500 directories has created a need to represent
knowledge information in a more general way. Knowledge information is
information about one or more servers maintained in another server,
used to link servers and services together.
This document defines a general method of representing knowledge
information in LDAP directories, based on URIs.
This document does not detail client processing of referral and search
reference responses. This is detailed in RFC 2251 or subsequent
documents.
The key words "SHALL", "SHALL NOT", "MUST", "MUST NOT", "SHOULD",
"SHOULD NOT", "MAY" and "MAY NOT" used in this document are to be
interpreted as described in [RFC2119].
4. Schema
4.1 The ref attribute type
This section defines the ref attribute type for holding general
knowledge reference information.
( 2.16.840.1.113730.3.1.34
NAME 'ref'
DESC 'URI reference'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
USAGE distributedOperation )
The ref attribute type has IA5 syntax and is case sensitive. The ref
attribute is multi valued. Values placed in the attribute MUST conform
to the specification given for the labeledURI attribute defined in
[RFC2079]. The labeledURI specification defines a format that is a
URI, optionally followed by whitespace and a label. This document does
not make use of the label portion of the syntax. Future documents MAY
enable new functionality by imposing additional structure on the label
portion of the syntax as it appears in the ref attribute.
If the URI contained in a ref attribute value refers to an LDAPv3
server, it MUST be in the LDAP URI scheme described in [RFC2255].
Other URI schemes MAY be used but MUST refer to services which are
capable of completing operations referred to the services. The URI
values, regardless of scheme, contained in a ref attribute must point
Zeilenga [Page 2]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
to services which are equally capable of handling operations refer to
said services.
The integrity of the URI SHALL NOT be validated by the server holding
or returning the reference.
When returning a referral result, the server MUST NOT return the label
portion of the labeledURI as part of the referral. Only the URI
portion of the ref attribute SHOULD be returned.
The ref attribute SHOULD NOT be used for naming.
4.2. The referral object class
The referral object class is defined as follows.
( 2.16.840.1.113730.3.2.6
NAME 'referral'
DESC 'named reference object'
STRUCTURAL MUST ref )
The referral object class is a structural object class used to
represent a named reference in the directory. The referral object
class SHOULD be used in conjunction with the extensibleObject object
class to support the naming attributes used in the entry's
distinguished name.
In the presence of a ManageDsaIT control, referral objects are treated
as normal entries. Note that the ref attribute is operational and
will only returned in a search entry response when requested.
In the absence of a ManageDsaIT control, referral objects contents are
used to construct referrals and search references and, as such, the
referral entries themselves are general visible to clients.
5. Use of the ref attribute
Two uses the ref attribute is defined in this document. The first
use, in conjunction with the referral object class, represents a named
reference. The second use, in conjunction with the Root DSE,
represents superior reference. The following sections detail these
usages of the ref attribute.
Other uses of the ref attribute MAY be defined in subsequent
documents, or by bilateral agreement between cooperating clients and
servers and SHOULD be defined in conjunction with an object class
Zeilenga [Page 3]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
indicating the usage.
5.1. Named reference
A named reference is used to facilitate distributed name resolution or
search across multiple servers. The ref attribute appears in an
referral object (an entry with object class of referral) named in the
referencing server. The value of the ref attribute points to the
corresponding entry maintained in the referenced server.
While the distinguished name in a value of the ref attribute is
typically that of an entry in a naming context below the naming
context held by the referencing server, it is permitted to be the
distinguished name of any entry. If the ref attribute is multi-valued
all the DNs in the values of the ref attribute SHOULD have the same
value. Administrators SHOULD avoid configuring naming loops using
referrals.
The URI SHOULD NOT explicitly define a scope and the server SHOULD NOT
explicitly add a scope to the URI before returning it to the client as
a referral or search reference as the scope is implied by the
operation.
Named references MUST be treated as normal entries if the request
includes the ManageDsaIT control. The remainder of this section
describes processing of requests which do not include the ManageDsaIT
control.
5.1.1. Scenarios
The following sections contain specifications of how referral objects
should be used in different scenarios followed by examples that
illustrate that usage. The scenarios described consist of referral
operation when finding target of a non-search operation, when finding
the base of a search operation, and when generating search references.
It is to be noted that, in this document, a search operation is
conceptually divided into two distinct, sequential phases: (1) finding
the base object where the search is to begin, and (2) performing the
search itself. The operation of the server with respect to referrals
in phase (1) is similar to the operation of the server while finding
the target object for a non-search operations.
It is to also be noted that the ref attribute may have multiple values
and, where these sections refer to a single ref attribute value,
multiple ref attribute values may be substituted and SHOULD be
Zeilenga [Page 4]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
processed and returned as a group in a referral or search reference in
the same way as described for a single ref attribute value.
Search references returned for a given request may be returned in any
order.
5.1.1.1. Example configuration
|------------------------------------------------------------|
| Server A |
| dn: o=abc,c=us dn: o=xyz,c=us |
| o: abc o: xyz |
| ref: ldap://hostB/o=abc,c=us ref: ldap://hostD/o=xyz,c=us |
| ref: ldap://hostC/o=abc,c=us objectclass: referral |
| objectclass: referral objectclass: extensibleObject|
| objectclass: extensibleObject |
|____________________________________________________________|
|------------------| |------------------| |------------------|
| Server B | | Server D | | Server C |
| dn: o=abc,c=us | | dn: o=xyz,c=us | | dn: o=abc,c=us |
| o: abc | | o: xyz | | o: abc |
| other attributes | | other attributes | | other attributes |
|__________________| |__________________| |__________________|
In this example, Server A holds references for two entries:
"o=abc,c=us" and "o=xyz,c=us". For the "o=abc,c=us" entry, Server A
holds two references, one to Server B and one to Server C. The
entries referenced are replicas of each other. For the "o=xyz,c=us"
entry, Server A holds a single reference to the entry contained in
Server D.
In the following protocol interaction examples, the client has
contacted Server A. Server A holds the naming context "c=us".
5.1.1.2. Base or Target object considerations
As previously described, the process of generating referrals for a
search can be described in two phases. The first, which is described
in this section, is generating referrals based on the base object
specified in the search. This process is similar to the process of
generating referrals based on the target object while processing other
operations (modify, add, delete, modify DN, and compare) with the sole
exception that for these other operations, the DN in the referral must
be modified in some cases.
Zeilenga [Page 5]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
If a client requests any of these operations, there are four cases
that the server must handle with respect to the base or target object
specified in the request.
Case 1: The base or target object is not held by the server and is not
within or subordinate to any naming context nor is subordinate to any
referral object held by the server.
The handling of this case is described in section 6.
Case 2: The base or target object is held by the server and is a
referral object.
In this case, if the type of operation requested is a search or the
URI contained in the ref attribute of the requested base object is NOT
an LDAP URI, the server SHOULD return the URI value contained in the
ref attribute of the base object whose DN is the DN requested by the
client as the base for the operation.
Example:
If the client issues a search in which the base object is
"o=xyz,c=us", server A will return
SearchResultDone "referral" {
ldap://hostD/o=xyz,c=us
}
If the type of operation requested is not a search and the URI
contained in the ref attribute of the requested target object is an
LDAP URI, the server SHOULD return a modified form of this URI. The
returned URI MUST have only the protocol, host, port, and trailing "/"
portion of the URI contained in the ref attribute. The server SHOULD
strip any DN, attributes, scope, and filter parts of the URI.
Example:
If the client issues a modify request for the target object of
"o=abc,c=us", server A will return
ModifyResponse "referral" {
ldap://hostB/
ldap://hostC/
}
Case 3: The base or target object is not held by the server, but is
object where the nearest naming context contains no referral object
which the base or target object is subordinate to.
Zeilenga [Page 6]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
In the context of this document, the nearest naming context means the
deepest context which the object is within. That is, if the object is
within multiple naming contexts, the nearest naming context the one
which is subordinate to all other naming contexts the object is
within.
If the nearest naming context contains no referral object which the
base or target object is subordinate to the request, request SHOULD be
process normally as appropriate for a nonexistent base or target
object (generally return noSuchObject).
Case 4: The base or target object is not held by the server, but is
object where the nearest naming context contains a referral object
which the base or target object is subordinate to.
As noted above, the nearest naming context means the deepest context
which the object is within.
If a client requests an operation for which the base or target object
is not held by the server but the nearest naming context contains a
referral object which the base or target object is subordinate to, the
server MUST return a referral response which contains referral values
constructed from the URI components of ref attribute values of the
referral object.
For each ref attribute value, if the URI component is not an LDAP
URIs, it SHOULD be returned as-is. If URI component is an LDAP URI,
the URI MUST be modified, regardless of the type of operation, as case
2 describes for a non-search request. That is, the DN, attributes,
scope, and filter parts of the URI MUST be stripped from the returned
URI.
Example:
If the client issues an add request where the target object has a DN
of "cn=Chris Lukas,o=abc,c=us", server A will return
AddResponse "referral" {
ldap://hostB/
ldap://hostC/
}
5.1.1.3. Search with one level or subtree scope
For search operations, once the base object has been found and
determined not to be a referral object, the search may progress. Any
entries matching the filter and scope of the search which is not a
Zeilenga [Page 7]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
referral object are returned to the client normally as described in
[RFC2251].
For each referral object within the requested scope, regardless of the
filter, the server SHOULD return a SearchResultReference which is
constructed from the URI component of values of the ref attribute. If
the URI component is not an LDAP URI, it should be returned as is. If
the URI component is an LDAP URI, the URI must be modified to remove
any explicit scope specifier.
One Level Example:
If a client requests a one level search of "c=US" then, in addition to
any entries one level below the "c=US" naming context matching the
filter (shown below as "... SearchResultEntry responses ..."), the
server will also return search references for any referral object
within the scope of the search.
The order of the SearchResultEntry responses and the
SearchResultReference responses is undefined. One possible sequence
is shown.
... SearchResultEntry responses ...
SearchResultReference {
ldap://hostB/o=abc,c=us
ldap://hostC/o=abc,c=us
}
SearchResultReference {
ldap://hostD/o=xyz,c=us
}
SearchResultDone "success"
Subtree Example:
If a client requests a subtree search of "c=us", then in addition to
any entries in the "c=us" naming context which match the filter,
Server A will also return two continuation references. As described in
the preceding section, the order of the responses is not defined.
One possible response might be:
SearchResultReference {
ldap://hostB/o=abc,c=us
ldap://hostC/o=abc,c=us
Zeilenga [Page 8]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
}
... SearchResultEntry responses ...
SearchResultReference {
ldap://hostD/o=xyz,c=us
}
SearchResultDone "success"
6. Superior Reference
An LDAP server may be configured to return a superior reference in the
case where the requested base or target object is not contained within
or subordinate to a naming context held by the server or referral
object.
An LDAP server's root DSE MAY contain a ref attribute. The values of
the ref attribute in the root DSE that are LDAP URIs SHOULD NOT
contain any DN part nor other search parameters (scope, filter,
attribute list). They MUST include the URI hostpart.
If the LDAP server's root DSE contains a ref attribute and a client
requests a target or base object not held by the server and not
contained within or subordinate to any naming context held by the
server or referral object, the server MUST return the URI component of
the values in the ref attribute of the root DSE as illustrated in the
example.
If the LDAP server's root DSE does not contain a ref attribute, the
server may return referral result with or more URIs determined via an
appropriate method, return noSuchObject, or other appropriate
resultCode.
The presence of the ref attribute within the root DSE SHALL NOT cause
operations upon the root DSE to generate a referral.
Example:
If a client requests a subtree search of "c=de" from server A in the
example configuration, and server A has the following ref attribute
defined in it's root DSE:
ref: ldap://hostG/
then server A will return
Zeilenga [Page 9]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
SearchResultDone "referral" {
ldap://hostG/
}
8. The ManageDsaIT control
The ManageDsaIT control indicates that the operation has been
requested so that the DSA (server) Information Tree is managed. The
controls causes DSEs, regardless of type, to be treated as normal
entries allowing clients to interrogate and update these entries using
LDAP operations. This control is analogous to the ManageDsaIT option
described in X.511(93) [X.511].
A client MAY specify the following control when issuing an add,
compare, delete, modify, modifyDN, search request or an extended
operation for which the control is defined.
The control type is 2.16.840.1.113730.3.4.2. The control criticality
may be TRUE or FALSE. There is no value; the controlValue field is
absent.
When present in the request, the server SHALL NOT generate a referral
or continuation reference for any referral object and instead perform
treat the referral object as an normal entry. When not present,
referral objects SHALL be handled as described above.
The control MAY cause other objects to be treated as normal entries as
defined by subsequent documents.
9. Relationship to X.500 Knowledge References
The X.500 standard defines several types of knowledge references, used
to bind together different parts of the X.500 namespace. In X.500,
knowledge references can be associated with a set of unnamed entries
(e.g., a reference, associated with an entry, to a server containing
the descendants of that entry).
This creates a potential problem for LDAP clients resolving an LDAPv3
URI referral referring to an LDAP directory back-ended by X.500.
Suppose the search is a subtree search, and that server A holds the
base object of the search, and server B holds the descendants of the
base object. The behavior of X.500(1993) subordinate references is
that the base object on server A is searched, and a single
continuation reference is returned pointing to all of the descendants
held on server B.
Zeilenga [Page 10]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
An LDAP URI only allows the base object to be specified. It is not
possible using standard LDAP URIs to indicate a search of several
entries whose names are not known to the server holding the superior
entry.
X.500 solves this problem by having two fields, one indicating the
progress of name resolution and the other indicating the target of the
search. In the above example, name resolution would be complete by the
time the query reached server B, indicating that it should not refer
the request.
This document does not address this problem. This problem will be
addressed in separate documents which define the changes to the X.500
distribution model and LDAPv3 extensions to indicate the progress of
name resolution.
10. Security Considerations
This document defines mechanisms that can be used to "glue" LDAP (and
other) servers together. The information used to specify this glue
information should be protected from unauthorized modification. If
the server topology information itself is not public information, the
information should be protected from unauthorized access as well.
11. References
[RFC1738] Berners-Lee, T., Masinter, L., and McCahill, M., "Uniform
Resource Locators (URL)", RFC 1738, CERN, Xerox Corporation,
University of Minnesota, December 1994.
[RFC2079] M. Smith, "Definition of an X.500 Attribute Type and an
Object Class to Hold Uniform Resource Identifiers (URIs)",
RFC 2079, January 1997.
[RFC2119] S. Bradner, "Key Words for use in RFCs to Indicate
Requirement Levels", RFC 2119 (Also BCP0014), March 1997.
[RFC2251] M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access
Protocol (v3)", RFC 2251, December 1997.
[RFC2255] T. Howes, M. Smith, "The LDAP URL Format", RFC 2255,
December, 1997.
[X.500] ITU-T Rec. X.501, "The Directory: Models", 1993.
[X.511] ITU-T Rec. X.511, "The Directory: Abstract Service
Zeilenga [Page 11]
INTERNET-DRAFT draft-zeilenga-ldap-namedref-00 4 July 2000
Definition", 1993.
12. Acknowledgments
This document is borrows heavily from previous work by IETF LDAPext
working group. In particular, this document is based upon "Named
Referral in LDAP Directories" (a work in progress) by Christopher
Lukes, Tim Howes, Michael Roszkowski, Mark C. Smith, and Mark Wahl.
13. Author's Address
Kurt D. Zeilenga
OpenLDAP Foundation
<Kurt@OpenLDAP.org>
This draft expires 4 Jan. 2001.
Zeilenga [Page 12]

View file

@ -0,0 +1,333 @@
INTERNET-DRAFT Kurt D. Zeilenga
Intended Category: Standard Track OpenLDAP Foundation
Expires: 13 December 2000 13 June 2000
LDAP Password Modify Extended Operation
<draft-zeilenga-ldap-passwd-exop-03.txt>
1. Status of this Memo
This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026.
This document is intended to be, after appropriate review and
revision, submitted to the RFC Editor as a Standard Track document.
Distribution of this memo is unlimited. Technical discussion of this
document will take place on the IETF LDAP Extension Working Group
mailing list <ietf-ldapext@netscape.com>. Please send editorial
comments directly to the author <Kurt@OpenLDAP.org>.
Internet-Drafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft
Shadow Directories can be accessed at http://www.ietf.org/shadow.html.
Copyright 2000, The Internet Society. All Rights Reserved.
Please see the Copyright section near the end of this document for
more information.
2. Abstract
The integration of LDAP [RFC2251] and external authentication services
has introduced non-DN authentication identities and allowed for
non-directory storage of passwords. As such, mechanisms which update
the directory, such as Modify operation, cannot be used to change a
user's password. This document describes an LDAP extended operation
to allow allow modification of user passwords which is not dependent
upon the form of the authentication identity nor the password storage
Zeilenga [Page 1]
INTERNET-DRAFT draft-zeilenga-ldap-passwd-exop-03 13 June 2000
mechanism used.
The key words ``MUST'', ``MUST NOT'', ``REQUIRED'', ``SHALL'', ``SHALL
NOT'', ``SHOULD'', ``SHOULD NOT'', ``RECOMMENDED'', and ``MAY'' in
this document are to be interpreted as described in RFC 2119
[RFC2119].
3. Background and Intent of Use
Lightweight Directory Access Protocol (LDAP) [RFC2251] is designed to
support an number of authentication mechanisms including simple user
name/password pairs. Traditionally LDAP users where identified by the
Distinguished Name [RFC2253] of a directory entry and this entry
contained a userPassword [RFC2256] attribute containing one or more
passwords.
The protocol does not mandate that passwords associated with a user be
stored in the directory server. The server may use any attribute
suitable for password storage, such as userPassword or authPassword
[AuthPasswd], or use non-directory storage.
The integration of application neutral SASL [RFC2222] services which
support simple username/password mechanisms (such as DIGEST-MD5) has
introduced non-LDAP DN authentication identity forms and made storage
of passwords the responsibility of the SASL service provider.
LDAP update operations are designed to act upon attributes of an entry
within the directory. LDAP update operations cannot be used to modify
a user's password when the user is not represented by a DN, does not
have a entry, or when that password used by the server is not stored
as an attribute of an entry. An alternative mechanism are needed.
This document describes an LDAP Extended Operation intended to be
allow directory clients to update user passwords. The user may or may
not have be associated with a directory entry. The user may or may not
be represented as an LDAP DN. The user's password may or may not be
stored in the directory.
The operation SHOULD NOT be used without adequate security protection
as the operation affords no privacy or integrity protect itself. This
operation SHOULD NOT be used by "anonymous" clients.
4. Password Modify Request and Response
The Password Modify operation is an LDAPv3 Extended Operation
[RFC2251, Section 4.12] and is identified by the OBJECT IDENTIFIER
Zeilenga [Page 2]
INTERNET-DRAFT draft-zeilenga-ldap-passwd-exop-03 13 June 2000
passwdModifyOID. This section details the syntax of the protocol
request and response.
passwdModifyOID OBJECT IDENTIFIER ::= 1.3.6.1.4.1.4203.666.6.1
[Editor's Note: this OID is temporary. A permanent OID
will be assigned to this object before this document is
progressed as an RFC.]
PasswdModifyRequestValue ::= SEQUENCE {
userIdentity [0] OCTET STRING OPTIONAL
oldPasswd [1] OCTET STRING OPTIONAL
newPasswd [2] OCTET STRING OPTIONAL }
PasswordModifyResponseValue ::= SEQUENCE {
genPasswd [0] OCTET STRING OPTIONAL }
4.1. Password Modify Request
A Password Modify request is an ExtendedRequest with the requestName
field containing passwdModifyOID OID and optionally provides a
requestValue field. If the requestValue field is provided, it SHALL
contain a PasswdModifyRequestValue with one or more fields present.
The userIdentity field, if present, SHALL contain an octet string
representation of the user associated with the request. This string
may or may not be an LDAPDN [RFC2253]. If no userIdentity field is
present, the request acts up upon the password of the user currently
associated with the LDAP session.
The oldPasswd field, if present, SHALL contain the user's current
password.
The newPasswd field, if present, SHALL contain the desired password
for this user.
4.2. Password Modify Response
A Password Modify response is an ExtendedResponse where the
responseName field is absent and the response field is optional. The
response field, if present, SHALL contain a PasswdModifyResponseValue
with genPasswd field present.
The genPasswd field, if present, SHALL contain a generated password
for the user.
Zeilenga [Page 3]
INTERNET-DRAFT draft-zeilenga-ldap-passwd-exop-03 13 June 2000
If an resultCode other than success (0) is indicated in the response,
the response field MUST be absent.
5. Operation Requirements
Clients SHOULD NOT submit a Password Modification request without
ensuring adequate security safeguards are in place. Servers SHOULD
return a non-success resultCode if sufficient security protection are
not in place.
Servers SHOULD indicate their support for this extended operation by
providing PasswordModifyOID as a value of the supportedExtensions
attribute type in their root DSE. Clients SHOULD verify the server
implements this extended operation prior to attempting the operation
by asserting the supportedExtensions attribute contains a value of
PasswordModifyOID.
The server SHALL only return success upon successfully changing the
user's password. The server SHALL leave the password unmodified and
return a non-success resultCode otherwise.
If the server does not recognize provided fields or does not support
the combination of fields provided, it SHALL NOT change the user
password.
If the provided oldPasswd value cannot be verified or is incorrect,
the server SHALL NOT change the user password.
The server SHALL NOT generate a password on behalf of the client if
the client has provided a newPassword. In absence of a client
provided newPassword, the server SHALL either generate a password on
behalf of the client or return a non-success result code. The server
MUST provide the generated password upon success as the value of the
genPasswd field.
The server MAY return adminLimitExceeded, busy,
confidentialityRequired, operationsError, unavailable,
unwillingToPerform, or other non-success resultCode as appropriate to
indicate that it was unable to successfully complete the operation.
Servers MAY implement administrative policies which restrict this
operation.
6. Other requirements
A server which supports this operation SHOULD provide a
Zeilenga [Page 4]
INTERNET-DRAFT draft-zeilenga-ldap-passwd-exop-03 13 June 2000
supportedExtension attribute in the Root DSE which contains as one of
its values the passwdModifyOID OID. A server MAY advertise the
extension only when the client is authorized and/or has established
the necessary security protections to use this operation. Clients
SHOULD verify the server has advertised the extension before
attempting the operation.
7. Security Considerations
This operation is used to modify user passwords. The operation itself
does not provide any security protection to ensure integrity and/or
confidentiality of the information. Use of this operation is strongly
discouraged when privacy protections are not in place to guarantee
confidentiality and may result in the disclosure of the password to
unauthorized parties.
8. Copyright
Copyright 2000, The Internet Society. All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published and
distributed, in whole or in part, without restriction of any kind,
provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be followed,
or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE AUTHORS, THE INTERNET SOCIETY, AND THE INTERNET
ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
9. Bibliography
Zeilenga [Page 5]
INTERNET-DRAFT draft-zeilenga-ldap-passwd-exop-03 13 June 2000
[RFC2219] S. Bradner, "Key words for use in RFCs to Indicate
Requirement Levels", RFC 2119, March 1997.
[RFC2222] J. Myers, "Simple Authentication and Security
Layer (SASL)", RFC 2222, October 1997.
[RFC2251] M. Wahl, T. Howes, S. Kille, "Lightweight
Directory Access Protocol (v3)", RFC 2251,
December 1997.
[RFC2252] M. Wahl, A. Coulbeck, T. Howes, S. Kille,
"Lightweight Directory Access Protocol (v3):
Attribute Syntax Definitions", RFC 2252,
December 1997.
[RFC2253] M. Wahl, S. Kille, T. Howes, "Lightweight
Directory Access Protocol (v3): UTF-8 String
Representation of Distinguished Names", RFC 2253,
December 1997.
[RFC2256] M. Wahl, "A Summary of the X.500(96) User Schema
for use with LDAPv3", RFC 2256, December 1997.
[AuthPasswd] K. Zeilenga, "LDAP Authentication Password
Attribute", draft-zeilenga-ldap-authpasswd-xx.txt,
a work in progress.
10. Acknowledgment
This document borrows from a number of IETF documents and is based
upon input from the IETF LDAPext working group.
11. Author's Address
Kurt D. Zeilenga
OpenLDAP Foundation
<Kurt@OpenLDAP.org>
Zeilenga [Page 6]

View file

@ -0,0 +1,221 @@
INTERNET-DRAFT Kurt D. Zeilenga
Intended Category: Standard Track OpenLDAP Foundation
Expires: 29 December 2000 29 June 2000
LDAPv3: All Operational Attributes
<draft-zeilenga-ldapv3bis-opattrs-00.txt>
1. Status of this Memo
This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026.
This document is intended to be, after appropriate review and
revision, submitted to the RFC Editor as a Standard Track document.
Distribution of this memo is unlimited. Technical discussion of this
document will take place on the IETF LDAP Extension Working Group
mailing list <ietf-ldapext@netscape.com>. Please send editorial
comments directly to the author <Kurt@OpenLDAP.org>.
Internet-Drafts are working documents of the Internet Engineering Task
Force (IETF), its areas, and its working groups. Note that other
groups may also distribute working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
The list of current Internet-Drafts can be accessed at
http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft
Shadow Directories can be accessed at http://www.ietf.org/shadow.html.
Copyright 2000, The Internet Society. All Rights Reserved.
Please see the Copyright section near the end of this document for
more information.
2. Overview
X.500 provides a mechanism for clients to request all operational
attributes be returned with entries provided in response to a search
operation. LDAP [RFC2251] does not provide a similar mechanism to
clients to request the return of operational attributes. The lack of
such a mechanisms hinders discovery of operational attributes present
in an entry.
Zeilenga [Page 1]
INTERNET-DRAFT draft-zeilenga-ldapv3bis-opattrs-00 13 June 2000
This document defines a simple mechanism which clients may use to
request all operation attributes. This document updates RFC 2251 as
detailed below.
The key words ``MUST'', ``MUST NOT'', ``REQUIRED'', ``SHALL'', ``SHALL
NOT'', ``SHOULD'', ``SHOULD NOT'', ``RECOMMENDED'', and ``MAY'' in
this document are to be interpreted as described in RFC 2119
[RFC2119].
3. Changes to RFC 2251
This document updates RFC 2251 as follows:
In Section 3.2.1, Attributes of Entries, the paragraph:
Some attributes, termed operational attributes, are used by
servers for administering the directory system itself. They are
not returned in search results unless explicitly requested by
name. Attributes which are not operational, such as "mail", will
have their schema and syntax constraints enforced by servers, but
servers will generally not make use of their values.
is replaced with:
Some attributes, termed operational attributes, are used by
servers for administering the directory system itself. They are
not returned in search results unless explicitly requested.
Attributes which are not operational, such as "mail", will have
their schema and syntax constraints enforced by servers, but
servers will generally not make use of their values.
In Section 4.5.1, Search Request, the paragraph:
- attributes: A list of the attributes to be returned from each
entry which matches the search filter. There are two special
values which may be used: an empty list with no attributes, and
the attribute description string "*". Both of these signify that
all user attributes are to be returned. (The "*" allows the
client to request all user attributes in addition to specific
operational attributes).
is replaced with:
- attributes: A list of the attributes to be returned from each
entry which matches the search filter. There are three special
values which may be used. An empty list with no attributes
signifies that all user attributes are to be returned. An
attribute list containing the attribute description string "*"
signifies that all user attributes are to be returned. An
attribute list containing the attribute description string "+"
signifies that all operational attributes are to be returned.
Zeilenga [Page 2]
INTERNET-DRAFT draft-zeilenga-ldapv3bis-opattrs-00 13 June 2000
(The "*" allows the client to request all user attributes in
addition to any requested operational attributes. The "+" allows
the client to request all operational attributes in addition to
requested user attributes. A client may list both "*" and "+" to
request all attributes.)
and the paragraph:
Client implementors should note that even if all user attributes
are requested, some attributes of the entry may not be included in
search results due to access control or other restrictions.
Furthermore, servers will not return operational attributes, such
as objectClasses or attributeTypes, unless they are listed by
name, since there may be extremely large number of values for
certain operational attributes. (A list of operational attributes
for use in LDAP is given in [5].)
is replaced with:
Client implementors should note that results may not include all
requested attributes due to access controls or other restrictions.
In addition, client implementors should request types only be
returned when discovering operational attributes as certain
operational attributes may have extremely large number of values.
Furthermore, servers will not return operational attributes, such
as objectClasses or attributeTypes, unless they are requested,
since there may be extremely large number of values for certain
operational attributes. (A list of operational attributes for use
in LDAP is given in [5].)
5. Interoperability Considerations
The addition of this mechanism to LDAPv3 is not believed to cause
significant interoperability problems. A server which does not
support the "+" should ignore the attribute description per RFC 2251,
section 4.5.1 and only return the attributes for the attribute
descriptions strings they do recognize. From the client's
perspective, this is one possible "other restriction" noted above.
5. Security Considerations
This document provides a mechanism which clients may use to discover
operational attributes. Access controls should be used to restrict
access to operational attributes per local policy.
6. Copyright
Zeilenga [Page 3]
INTERNET-DRAFT draft-zeilenga-ldapv3bis-opattrs-00 13 June 2000
Copyright 2000, The Internet Society. All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published and
distributed, in whole or in part, without restriction of any kind,
provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be followed,
or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE AUTHORS, THE INTERNET SOCIETY, AND THE INTERNET
ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
7. Bibliography
[RFC2219] S. Bradner, "Key words for use in RFCs to Indicate
Requirement Levels", RFC 2119, March 1997.
[RFC2251] M. Wahl, T. Howes, S. Kille, "Lightweight
Directory Access Protocol (v3)", RFC 2251,
December 1997.
[X.500] ITU-T Rec. X.500, "The Directory: Overview of
Concepts, Models and Service", 1993.
8. Author's Address
Kurt D. Zeilenga
OpenLDAP Foundation
<Kurt@OpenLDAP.org>
Zeilenga [Page 4]

View file

@ -1,4 +1,4 @@
.TH LDAPDELETE 1 "20 April 2000" "OpenLDAP LDVERSION"
.TH LDAPDELETE 1 "12 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
@ -37,12 +37,16 @@ ldapdelete \- LDAP delete entry tool
[\c
.BI \-p \ ldapport\fR]
[\c
.BR \-E[E] ]
[\c
.BR \-I[I] ]
.BR \-O \ security-properties ]
[\c
.BI \-U \ username\fR]
[\c
.BR \-x ]
[\c
.BR \-I ]
[\c
.BR \-Q ]
[\c
.BI \-X \ authzid\fR]
[\c
.BI \-Y \ mech\fR]
@ -109,6 +113,9 @@ each line. In this case, the \fIfilter\fP given on the command line
is treated as a pattern where the first occurrence of \fB%s\fP is
replaced with a line from \fIfile\fP.
.TP
.B \-x
Use simple authentication instead of SASL.
.TP
.BI \-D \ binddn
Use \fIbinddn\fP to bind to the LDAP directory. \fIbinddn\fP should be
a string-represented DN as defined in RFC 1779.
@ -129,30 +136,21 @@ Specify an alternate TCP port where the ldap server is listening.
.BI \-P \ 2\fR\||\|\fI3
Specify the LDAP protocol version to use.
.TP
.BI \-r
.B \-r
Do a recursive delete. If the DN specified isn't a leaf, its
children, and all their children are deleted down the tree. No
verification is done, so if you add this switch, ldapdelete will
happily delete large portions of your tree. Use with care.
.TP
.B \-E[E]
Requset the use of SASL privacy (encryption). If the server allows it, data
sent between the client and the server will be encrypted. If the server
requires the use of encryption and this flag is not specified, the command
will fail. If you use
.B \-EE\c
, the command will fail if the server does not support encryption.
.B \-E[E]
implies
.B \-I[I]
.BI \-O \ security-properties
Specify SASL security properties.
.TP
.B \-I[I]
Request the use of SASL integrity checking. It protects data sent between the
client and the server from being modified along the way, but it does not
prevent sniffing. If the server requires the use of integrity checking and
this flag is not specified, the command will fail.If you use
.B \-II\c
, the command will fail if the server does not support this function.
.B \-I
Enable SASL Interactive mode. Always prompt. Default is to prompt
only as needed.
.TP
.B \-Q
Enable SASL Quiet mode. Never prompt.
.TP
.BI \-U \ username
Specify the username for SASL bind. The syntax of the username depends on the
@ -206,6 +204,8 @@ Kille, S.,
ISODE Consortium, March 1995.
.SH BUGS
There is no interactive mode, but there probably should be.
.SH AUTHOR
The OpenLDAP Project <http://www.openldap.org/>
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).

View file

@ -1,4 +1,4 @@
.TH LDAPMODIFY 1 "20 April 2000" "OpenLDAP LDVERSION"
.TH LDAPMODIFY 1 "12 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
@ -41,12 +41,16 @@ ldapmodify, ldapadd \- LDAP modify entry and LDAP add entry tools
[\c
.BI \-P \ 2\fR\||\|\fI3\fR]
[\c
.BR \-E[E] ]
.BR \-O \ security-properties ]
[\c
.BR \-I[I] ]
.BR \-I ]
[\c
.BR \-Q ]
[\c
.BI \-U \ username\fR]
[\c
.BR \-x ]
[\c
.BI \-X \ authzid\fR]
[\c
.BI \-Y \ mech\fR]
@ -180,6 +184,9 @@ must be compiled with LDAP_DEBUG defined for this option to have any effect.
Read the entry modification information from \fIfile\fP instead of from
standard input.
.TP
.B \-x
Use simple authentication instead of SASL.
.TP
.BI \-D \ binddn
Use \fIbinddn\fP to bind to the LDAP directory. \fIbinddn\fP should be
a string-represented DN as defined in RFC 1779.
@ -200,24 +207,15 @@ Specify an alternate TCP port where the ldap server is listening.
.BI \-P \ 2\fR\||\|\fI3
Specify the LDAP protocol version to use.
.TP
.B \-E[E]
Requset the use of SASL privacy (encryption). If the server allows it, data
sent between the client and the server will be encrypted. If the server
requires the use of encryption and this flag is not specified, the command
will fail. If you use
.B \-EE\c
, the command will fail if the server does not support encryption.
.B \-E[E]
implies
.B \-I[I]
.BI \-O \ security-properties
Specify SASL security properties.
.TP
.B \-I[I]
Request the use of SASL integrity checking. It protects data sent between the
client and the server from being modified along the way, but it does not
prevent sniffing. If the server requires the use of integrity checking and
this flag is not specified, the command will fail.If you use
.B \-II\c
, the command will fail if the server does not support this function.
.B \-I
Enable SASL Interactive mode. Always prompt. Default is to prompt
only as needed.
.TP
.B \-Q
Enable SASL Quiet mode. Never prompt.
.TP
.BI \-U \ username
Specify the username for SASL bind. The syntax of the username depends on the
@ -426,6 +424,8 @@ Kille, S.,
ISODE Consortium, March 1995.
.SH BUGS
There is no interactive mode, but there probably should be.
.SH AUTHOR
The OpenLDAP Project <http://www.openldap.org/>
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).

View file

@ -1,4 +1,4 @@
.TH LDAPMODRDN 1 "20 April 2000" "OpenLDAP LDVERSION"
.TH LDAPMODRDN 1 "12 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
@ -37,12 +37,16 @@ ldapmodrdn \- LDAP rename entry tool
[\c
.BI \-P \ 2\fR\||\|\fI3\fR]
[\c
.BR \-E[E] ]
.BR \-O \ security-properties ]
[\c
.BR \-I[I] ]
.BR \-I ]
[\c
.BR \-Q ]
[\c
.BI \-U \ username\fR]
[\c
.BR \-x ]
[\c
.BI \-X \ authzid\fR]
[\c
.BI \-Y \ mech\fR]
@ -111,6 +115,9 @@ compiled with LDAP_DEBUG defined for this option to have any effect.
Read the entry modification information from \fIfile\fP instead of from
standard input or the command-line.
.TP
.B \-x
Use simple authentication instead of SASL.
.TP
.B \-D binddn
Use \fIbinddn\fP to bind to the LDAP directory. \fIbinddn\fP should be
a string-represented DN as defined in RFC 1779.
@ -131,24 +138,15 @@ Specify an alternate TCP port where the ldap server is listening.
.BI \-P \ 2\fR\||\|\fI3
Specify the LDAP protocol version to use.
.TP
.B \-E[E]
Requset the use of SASL privacy (encryption). If the server allows it, data
sent between the client and the server will be encrypted. If the server
requires the use of encryption and this flag is not specified, the command
will fail. If you use
.B \-EE\c
, the command will fail if the server does not support encryption.
.B \-E[E]
implies
.B \-I[I]
.BI \-O \ security-properties
Specify SASL security properties.
.TP
.B \-I[I]
Request the use of SASL integrity checking. It protects data sent between the
client and the server from being modified along the way, but it does not
prevent sniffing. If the server requires the use of integrity checking and
this flag is not specified, the command will fail.If you use
.B \-II\c
, the command will fail if the server does not support this function.
.B \-I
Enable SASL Interactive mode. Always prompt. Default is to prompt
only as needed.
.TP
.B \-Q
Enable SASL Quiet mode. Never prompt.
.TP
.BI \-U \ username
Specify the username for SASL bind. The syntax of the username depends on the
@ -225,6 +223,8 @@ Kille, S.,
ISODE Consortium, March 1995.
.SH BUGS
There is no interactive mode, but there probably should be.
.SH AUTHOR
The OpenLDAP Project <http://www.openldap.org/>
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).

View file

@ -1,4 +1,4 @@
.TH LDAPPASSWD 1 "20 April 2000" "LDAPPasswd"
.TH LDAPPASSWD 1 "12 July 2000" "LDAPPasswd"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
@ -33,12 +33,16 @@ ldappasswd \- change the password of an LDAP entry
[\c
.BI \-w \ passwd\fR]
[\c
.BR \-E[E] ]
.BR \-O \ security-properties ]
[\c
.BR \-I[I] ]
.BR \-I ]
[\c
.BR \-Q ]
[\c
.BI \-U \ username\fR]
[\c
.BR \-x ]
[\c
.BI \-X \ authzid\fR]
[\c
.BI \-Y \ mech\fR]
@ -47,15 +51,17 @@ ldappasswd \- change the password of an LDAP entry
.SH DESCRIPTION
.B ldappasswd
is a tool to set the password of an LDAP user.
It is neither designed nor intended to be a replacement for
.BR passwd (1)
and should not be installed as such.
.LP
.B ldappasswd
sets the password of associated with the user. If the new
password is not specified on the command line or the user
doesn't enable prompting, the server will be asked to generate
a password for the user.
.LP
.B ldappasswd
is neither designed nor intended to be a replacement for
.BR passwd (1)
and should not be installed as such.
.SH OPTIONS
.TP
.BI \-A
@ -68,6 +74,9 @@ Set the old password to \fIoldPasswd\fP.
.B \-C
Automatically chase referrals.
.TP
.B \-x
Use simple authentication instead of SASL.
.TP
.BI \-D \ binddn
Use \fIbinddn\fP to bind to the LDAP directory. \fIbinddn\fP should
be a string-represented DN as defined in RFC 2253.
@ -107,24 +116,15 @@ This is used instead of specifying the password on the command line.
.BI \-w \ passwd
Use \fIpasswd\fP as the password to bind with.
.TP
.B \-E[E]
Requset the use of SASL privacy (encryption). If the server allows it, data
sent between the client and the server will be encrypted. If the server
requires the use of encryption and this flag is not specified, the command
will fail. If you use
.B \-EE\c
, the command will fail if the server does not support encryption.
.B \-E[E]
implies
.B \-I[I]
.BI \-O \ security-properties
Specify SASL security properties.
.TP
.B \-I[I]
Request the use of SASL integrity checking. It protects data sent between the
client and the server from being modified along the way, but it does not
prevent sniffing. If the server requires the use of integrity checking and
this flag is not specified, the command will fail.If you use
.B \-II\c
, the command will fail if the server does not support this function.
.B \-I
Enable SASL Interactive mode. Always prompt. Default is to prompt
only as needed.
.TP
.B \-Q
Enable SASL Quiet mode. Never prompt.
.TP
.BI \-U \ username
Specify the username for SASL bind. The syntax of the username depends on the
@ -134,11 +134,9 @@ actual SASL mechanism used.
Specify the requested authorization ID for SASL bind.
.I authzid
must be one of the following formats:
.B dn:\c
.I <distinguished name>
.BI dn: <distinguished name>
or
.B u:\c
.I <username>
.BI u: <username>\fP.
.TP
.BI \-Y \ mech
Specify the SASL mechanism to be used for authentication. If it's not
@ -146,10 +144,14 @@ specified, the program will choose the best mechanism the server knows.
.TP
.B \-Z[Z]
Issue StartTLS (Transport Layer Security) extended operation. If you use
.B \-ZZ\c
, the command will require the operation to be successful.
.BR \-ZZ ,
the command will require the operation to be successful
.SH SEE ALSO
.BR ldap_bind (3)
.BR ldap_sasl_bind (3)
.BR ldap_extended_operation (3)
.BR ldap_start_tls (3)
.SH AUTHOR
The OpenLDAP Project <http://www.openldap.org/>
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).

View file

@ -1,4 +1,4 @@
.TH LDAPSEARCH 1 "20 April 2000" "OpenLDAP LDVERSION"
.TH LDAPSEARCH 1 "12 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
@ -53,12 +53,16 @@ ldapsearch \- LDAP search tool
[\c
.BI \-z \ sizelimit\fR]
[\c
.BR \-E[E] ]
.BR \-O \ security-properties ]
[\c
.BR \-I[I] ]
.BR \-I ]
[\c
.BR \-Q ]
[\c
.BI \-U \ username\fR]
[\c
.BR \-x ]
[\c
.BI \-X \ authzid\fR]
[\c
.BI \-Y \ mech\fR]
@ -157,6 +161,9 @@ is treated as a pattern where the first occurrence of \fB%s\fP is
replaced with a line from \fIfile\fP. If \fIfile\fP is a single \fI-\fP
character, then the lines are read from standard input.
.TP
.B \-x
Use simple authentication instead of SASL.
.TP
.BI \-D \ binddn
Use \fIbinddn\fP to bind to the LDAP directory. \fIbinddn\fP should be
a string-represented DN as defined in RFC 1779.
@ -222,29 +229,21 @@ limit.
A server may impose a maximal sizelimit which only
the root user may override.
.TP
.B \-E[E]
Requset the use of SASL privacy (encryption). If the server allows it, data
sent between the client and the server will be encrypted. If the server
requires the use of encryption and this flag is not specified, the command
will fail. If you use
.B \-EE\c
, the command will fail if the server does not support encryption.
.B \-E[E]
implies
.B \-I[I]
.BI \-O \ security-properties
Specify SASL security properties.
.TP
.B \-I[I]
Request the use of SASL integrity checking. It protects data sent between the
client and the server from being modified along the way, but it does not
prevent sniffing. If the server requires the use of integrity checking and
this flag is not specified, the command will fail.If you use
.B \-II\c
, the command will fail if the server does not support this function.
.B \-I
Enable SASL Interactive mode. Always prompt. Default is to prompt
only as needed.
.TP
.B \-Q
Enable SASL Quiet mode. Never prompt.
.TP
.BI \-U \ username
Specify the username for SASL bind. The syntax of the username depends on the
actual SASL mechanism used.
.TP
.TP
.BI \-X \ authzid
Specify the requested authorization ID for SASL bind.
.I authzid
@ -390,6 +389,8 @@ Howes, T.,
.SM RFC
1558,
University of Michigan, December 1993.
.SH AUTHOR
The OpenLDAP Project <http://www.openldap.org/>
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).

View file

@ -1,4 +1,4 @@
.TH LBER_DECODE 3 "12 May 2000" "OpenLDAP LDVERSION"
.TH LBER_DECODE 3 "12 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
@ -349,20 +349,11 @@ Some routines may dynamically allocate memory
which must be freed by the caller using supplied deallocation routines.
.SH SEE ALSO
.BR lber-encode (3)
.BR lber-memory (3)
.BR lber-types (3)
.BR ldap-parse (3)
.BR ldap-sync (3)
.BR ldap-async (3)
.LP
Yeong, W., Howes, T., and Hardcastle-Kille, S.,
"Lightweight Directory Access Protocol", OSI-DS-26, April 1992.
.LP
Information Processing - Open Systems Interconnection - Model and Notation -
Service Definition - Specification of Basic Encoding Rules for Abstract
Syntax Notation One, International Organization for Standardization,
International Standard 8825.
.SH AUTHOR
Tim Howes, University of Michigan
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).

View file

@ -317,20 +317,11 @@ The return values for all of these functions are declared in the
<lber.h> header file.
.SH SEE ALSO
.BR lber-decode (3)
.BR lber-memory (3)
.BR lber-types (3)
.BR ldap-async (3)
.BR ldap-sync (3)
.BR ldap-parse (3)
.LP
Yeong, W., Howes, T., and Hardcastle-Kille, S.,
"Lightweight Directory Access Protocol", OSI-DS-26, April 1992.
.LP
Information Processing - Open Systems Interconnection - Model and Notation -
Service Definition - Specification of Basic Encoding Rules for Abstract
Syntax Notation One, International Organization for Standardization,
International Standard 8825.
.SH AUTHOR
Tim Howes, University of Michigan
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).

View file

@ -0,0 +1,58 @@
.TH LBER_MEMORY 3 "12 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
ber_memalloc, ber_memcalloc, ber_memrealloc, ber_memfree \- LBER memory allocators
.SH SYNOPSIS
.nf
.ft B
#include <lber.h>
.ft
.fi
.LP
.nf
.ft B
void * ber_memalloc(
ber_len_t bytes )
.ft
.fi
.LP
.nf
.ft B
void * ber_memcalloc(
ber_len_t nelems, ber_len_t bytes )
.ft
.fi
.LP
.nf
.ft B
void * ber_memrealloc(
void \(**ptr,
ber_len_t bytes);
.ft
.fi
.LP
.nf
.ft B
void * ber_memfree(
void \(**ptr );
.ft
.fi
.SH DESCRIPTION
.LP
These routines are used to allocate/deallocate memory used/returned
by the Lightweight BER library as required by
.BR lber-encode (3)
and
.BR lber-decode (3).
.SH SEE ALSO
.BR lber-decode (3)
.BR lber-encode (3)
.BR lber-types (3)
.LP
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
.B OpenLDAP
is derived from University of Michigan LDAP 3.3 Release.

45
doc/man/man3/lber-types.3 Normal file
View file

@ -0,0 +1,45 @@
.TH LBER_TYPES 3 "12 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
ber_int_t, ber_len_t, ber_tag_t \- LBER types
.SH SYNOPSIS
.nf
.ft B
#include <lber.h>
.ft
.fi
.LP
.nf
.ft B
typedef impl_int_t ber_int_t;
typedef impl_len_t ber_len_t;
typedef impl_tag_t ber_tag_t;
.ft
.fi
.SH DESCRIPTION
.LP
The are basic types defined for use with the Lightweight BER library.
.LP
.B ber_int_t
is a signed integer of at least 32 bits.
.LP
.B ber_len_t
is a unsigned integer of at least 32 bits used to represent a length.
It is commonly equivalent to a
.BR size_t .
.LP
.B ber_len_t
is a unsigned integer of at least 32 bits used to represent a
BER tag. It is commonly equivalent to a
.BR unsigned\ long .
.SH SEE ALSO
.BR lber-encode (3)
.BR lber-decode (3)
.LP
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
.B OpenLDAP
is derived from University of Michigan LDAP 3.3 Release.

View file

@ -1,4 +1,4 @@
.TH LDAP 3 "13 May 2000" "OpenLDAP LDVERSION"
.TH LDAP 3 "21 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
@ -12,8 +12,12 @@ ldap - OpenLDAP Lightweight Directory Access Protocol API
.fi
.SH DESCRIPTION
.LP
The Lightweight Directory Access Protocol provides TCP/IP access to
the X.500 Directory or to a stand-alone LDAP server.
The Lightweight Directory Access Protocol provides access to
X.500 directory services. The services may be stand\-alone
part of a distributed directory service. This API supports
LDAP over TCP, LDAP over SSL, and LDAP over IPC (UNIX domain
sockets).
.LP
The OpenLDAP LDAP package includes a stand-alone server in
.BR slapd (8),
various LDAP clients, and an LDAP client library used to provide
@ -24,28 +28,27 @@ Both synchronous and asynchronous APIs are provided. Also included are
various routines to parse the results returned from these routines.
These routines are found in the \-lldap library.
.LP
The basic interaction is as follows. A connection is made to an LDAP
server by calling
.BR ldap_open (3).
An LDAP bind operation is performed by calling
one of
.BR ldap_bind (3)
The basic interaction is as follows. A session handle associated
with created using
.BR ldap_init (3).
The underlying session is established upon first use which is
commonly an LDAP bind operation. The LDAP bind operation is
performed by calling one of
.BR ldap_sasl_bind (3)
and friends. Next, other operations are performed
by calling one of the synchronous or asynchronous routines (e.g.,
.BR ldap_search_s (3)
.BR ldap_search_ext_s (3)
or
.BR ldap_search (3)
.BR ldap_search_ext (3)
followed by
.BR ldap_result (3)).
Results returned from these routines are interpreted by calling the
LDAP parsing routines. The LDAP association is terminated by calling
.BR ldap_unbind (3).
LDAP parsing routines such as
.BR ldap_parse_result (3).
The LDAP association and underlying connection is terminated by calling
.BR ldap_unbind_ext (3).
Errors can be interpreted by calling
.BR ldap_perror (3).
The
.BR ldap_set_rebind_proc (3)
routine can be used to set a routine to be called back when an LDAP bind
operation needs to occur when handling a client referral.
.BR ldap_err2string (3).
.SH SEARCH FILTERS
Search filters to be passed to the ldap search routines can be
constructed by hand, or by calling the
@ -67,9 +70,8 @@ and
.BR ldap_next_attribute (3)
to step through an entry's attributes, and
.BR ldap_get_values (3)
to retrieve a given attribute's value, and then calling
.BR printf (3)
or whatever to display the values.
to retrieve a given attribute's value. Attribute values
may or may not be displayable.
.LP
Alternatively, the entry can be output automatically by calling
the
@ -94,7 +96,7 @@ The
.BR ldap_ufn (3)
routines implement a user friendly naming
scheme via LDAP. This scheme allows you to look up entries
using fuzzy, untyped names like "mark smith, umich, us".
using fuzzy, untyped names like "john smith, example corp, ca, us".
.SH CACHING
The
.BR ldap_cache (3)
@ -130,9 +132,10 @@ Also included in the distribution is a set of lightweight Basic
Encoding Rules routines. These routines are used by the LDAP library
routines to encode and decode LDAP protocol elements using the
(slightly simplified) Basic Encoding Rules defined by LDAP. They are
not normally used directly by an LDAP application program. The
not normally used directly by an LDAP application program excepting
in the handling of controls and extended operations. The
routines provide a printf and scanf-like interface, as well as
lower-level access. These routines are found in the liblber.a
lower-level access. These routines are found in the -llber
library.
.SH INDEX
.TP 20
@ -323,12 +326,6 @@ convert a DN into its component parts
.SM ldap_explode_rdn(3)
convert a RDN into its component parts
.TP
.SM ldap_explode_dns(3)
convert a DNS-style DN into its component parts (experimental)
.TP
.SM ldap_is_dns_dn(3)
check to see if a DN is a DNS-style DN (experimental)
.TP
.SM ldap_dn2ufn(3)
convert a DN into user friendly form
.TP
@ -467,24 +464,6 @@ sort a list of attribute values
.SM ldap_sort_strcasecmp(3)
case insensitive string comparison
.TP
.SM ldap_set_string_translators(3)
set character set translation routines used by LDAP library
.TP
.SM ldap_t61_to_8859(3)
translate from ISO-8859 characters to the T.61 characters
.TP
.SM ldap_8859_to_t61(3)
translate from T.61 characters to the ISO-8859 characters
.TP
.SM ldap_translate_from_t61(3)
translate from the T.61 character set to another character set
.TP
.SM ldap_translate_to_t61(3)
translate to the T.61 character set from another character set
.TP
.SM ldap_enable_translation(3)
enable or disable character translation for an LDAP entry result
.TP
.SM cldap_open(3)
open a connectionless LDAP (CLDAP) session
.TP
@ -498,9 +477,6 @@ set retry and timeout information using connectionless LDAP
terminate a connectionless LDAP session
.SH SEE ALSO
.BR slapd (8)
.SH AUTHORS
Tim Howes, Mark Smith, Gordon Good, Lance Sloan, and Steve Rothwell from
the University of Michigan, along with help from lots of others.
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).

View file

@ -0,0 +1 @@
ldap_abandon_ext.3

View file

@ -1 +1,3 @@
ldap_add_s.3
ldap_add_ext.3
ldap_add_ext_s.3

View file

@ -1,11 +1,15 @@
ldap_bind_s.3
ldap_simple_bind.3
ldap_simple_bind_s.3
ldap_sasl_bind.3
ldap_sasl_bind_s.3
ldap_kerberos_bind_s.3
ldap_kerberos_bind1.3
ldap_kerberos_bind1_s.3
ldap_kerberos_bind2.3
ldap_kerberos_bind2_s.3
ldap_unbind.3
ldap_unbind_ext.3
ldap_unbind_s.3
ldap_unbind_ext_s.3
ldap_set_rebind_proc.3

View file

@ -1,134 +0,0 @@
.TH LDAP_CHARSET 3 "22 September 1998" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
ldap_set_string_translators,
ldap_t61_to_8859,
ldap_8859_to_t61,
ldap_translate_from_t61,
ldap_translate_to_t61,
ldap_enable_translation \- LDAP character set translation routines
.SH SYNOPSIS
.nf
.ft B
#include <ldap.h>
.ft
.LP
.ft B
void ldap_set_string_translators( ld, encode_proc, decode_proc )
.ft
LDAP *ld;
BERTranslateProc encode_proc;
BERTranslateProc decode_proc;
.LP
.ft B
typedef int (*BERTranslateProc)( char **bufp, unsigned long *buflenp,
int free_input );
.ft
.LP
.ft B
int ldap_t61_to_8859( bufp, buflenp, free_input )
.ft
char **bufp;
unsigned long *buflenp;
int free_input;
.LP
.ft B
int ldap_8859_to_t61( bufp, buflenp, free_input )
.ft
char **bufp;
unsigned long *buflenp;
int free_input;
.LP
.ft B
int ldap_translate_from_t61( ld, bufp, lenp, free_input )
.ft
LDAP *ld;
char **bufp;
unsigned long *lenp;
int free_input;
.LP
.ft B
int ldap_translate_to_t61( ld, bufp, lenp, free_input )
.ft
LDAP *ld;
char **bufp;
unsigned long *lenp;
int free_input;
.LP
.ft B
void ldap_enable_translation( ld, entry, enable )
.ft
LDAP *ld;
LDAPMessage *entry;
int enable;
.fi
.SH DESCRIPTION
.LP
These routines are used to used to enable translation of character strings
used in the LDAP library to and from the T.61 character set used in the
LDAP protocol. These functions are only available if the LDAP and LBER
libraries are compiled with STR_TRANSLATION defined.
It is also possible to turn on character translation by default so that
all LDAP library callers will experience translation; see the LDAP
Make-common source file for details.
.LP
.B ldap_set_string_translators()
sets the translation routines that will
be used by the LDAP library. They are not actually used until the
\fIld_lberoptions\fP field of the LDAP structure is set to include the
LBER_TRANSLATE_STRINGS option.
.LP
.B ldap_t61_to_8859()
and
.B ldap_8859_to_t61()
are translation routines for
converting between T.61 characters and ISO-8859 characters. The specific
8859 character set used is determined at compile time.
.LP
.B ldap_translate_from_t61()
is used to translate a string of characters from the T.61 character set to a
different character set. The actual translation is done using the
\fIdecode_proc\fP that was passed to a previous call to
.B ldap_set_string_translators().
On entry, \fI*bufp\fP should point to the start of the T.61 characters
to be translated and \fI*lenp\fP should contain the number of bytes to
translate. If \fIfree_input\fP is non-zero, the input buffer will be
freed if translation is a success. If the translation is a success,
LDAP_SUCCESS will be returned, \fI*bufp\fP will point to a newly
dynamically allocated buffer that contains the translated characters, and
\fI*lenp\fP will contain the length of the result. If translation
fails, an LDAP error code will be returned.
.LP
.B ldap_translate_to_t61()
is used to translate a string of characters to the T.61 character set from a
different character set. The actual translation is done using the
\fIencode_proc\fP that was passed to a previous call to
.B ldap_set_string_translators().
This function is called just like
.B ldap_translate_from_t61().
.LP
.B ldap_enable_translation()
is used to turn on or off string translation for the LDAP entry \fIentry\fP
(typically obtained by calling
.B ldap_first_entry()
or
.B ldap_next_entry()
after a successful LDAP search operation). If \fIenable\fP is zero,
translation is disabled; if non-zero, translation is enabled. This routine
is useful if you need to ensure that a particular attribute is not
translated when it is extracted using
.B ldap_get_values()
or
.B ldap_get_values_len().
For example, you would not want to translate a binary attributes such as
jpegPhoto.
.SH SEE ALSO
.BR ldap (3)
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
.B OpenLDAP
is derived from University of Michigan LDAP 3.3 Release.

View file

@ -1,6 +0,0 @@
ldap_set_string_translators.3
ldap_enable_translation.3
ldap_translate_from_t61.3
ldap_translate_to_t61.3
ldap_t61_to_8859.3
ldap_8859_to_t61.3

View file

@ -1 +1,3 @@
ldap_compare_s.3
ldap_compare_ext.3
ldap_compare_ext_s.3

View file

@ -1 +1,3 @@
ldap_delete_s.3
ldap_delete_ext.3
ldap_delete_ext_s.3

View file

@ -1,9 +1,9 @@
.TH LDAP_GET_DN 3 "22 September 1998" "OpenLDAP LDVERSION"
.TH LDAP_GET_DN 3 "21 July 2000" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
ldap_get_dn, ldap_explode_dn, ldap_explode_rdn, ldap_dn2ufn, ldap_is_dns_dn, ldap_explode_dns \- LDAP DN handling routines
ldap_get_dn, ldap_explode_dn, ldap_explode_rdn, ldap_dn2ufn \- LDAP DN handling routines
.SH SYNOPSIS
.nf
.ft B
@ -31,16 +31,6 @@ int notypes;
char *ldap_dn2ufn(dn)
.ft
char *dn;
.LP
.ft B
int ldap_is_dns_dn(dn)
.ft
char *dn;
.LP
.ft B
char **ldap_explode_dns(dn)
.ft
char *dn;
.SH DESCRIPTION
These routines allow LDAP entry names (Distinguished Names, or DNs)
to be obtained, parsed, converted to a user-friendly form, and tested.
@ -93,20 +83,6 @@ for more details on the UFN format. The space for the UFN returned
is obtained dynamically and the user is responsible for freeing it
via a call to
.BR ldap_memfree (3).
.LP
.B ldap_is_dns_dn()
returns non-zero if the dn string is an experimental
DNS-style DN (generally in the form of an RFC 822 e-mail address). It
returns zero if the dn appears to be an RFC 1779 format DN.
.LP
.B ldap_explode_dns()
takes a DNS-style DN and breaks it up into its
component parts.
.B ldap_explode_dns()
returns a NULL-terminated array.
For example, the DN "mcs.umich.edu" will return { "mcs", "umich", "edu",
NULL }. The result can be freed by calling
.BR ldap_value_free (3).
.SH ERRORS
If an error occurs in
.BR ldap_get_dn() ,
@ -117,7 +93,6 @@ field in the \fIld\fP parameter is set to indicate the error. See
for a description of possible error codes.
.BR ldap_explode_dn() ,
.BR ldap_explode_rdn() ,
.B ldap_explode_dns()
and
.B ldap_dn2ufn()
will return NULL with

View file

@ -1,4 +1,3 @@
ldap_explode_dn.3
ldap_explode_dns.3
ldap_explode_rdn.3
ldap_dn2ufn.3
ldap_is_dns_dn.3

View file

@ -1,2 +1,4 @@
ldap_modify_s.3
ldap_modify_ext.3
ldap_modify_ext_s.3
ldap_mods_free.3

View file

@ -1,2 +1,4 @@
ldap_search_s.3
ldap_search_st.3
ldap_search_ext.3
ldap_search_ext_s.3

View file

@ -63,6 +63,9 @@ listed of host may be provided.
Used to specify the port used with connecting to LDAP servers(s).
The port may be specified as a number.
.TP 1i
\fBSASL_SECPROPS <string>\fP
Used to specify Cyrus SASL security properties.
.TP 1i
\fBSIZELIMIT <integer>\fP
Used to specify a size limit to use when performing searches. The
number should be an non-negative integer. \fISIZELIMIT\fP of zero (0)

View file

@ -74,10 +74,10 @@ by <who>).
See Developer's FAQ (http://www.openldap.org/faq/) for details.
.TP
.B
attributetype ( <oid> [NAME <name>] [DESC <description>] [OBSOLETE] \
[SUP <oid>] [EQUALITY <oid>] [ORDERING <oid>] [SUBSTR <oid>] \
[SYNTAX <oidlen>] [SINGLE-VALUE] [COLLECTIVE] [NO-USER-MODIFICATION] \
[USAGE <attributeUsage>] )
attributetype ( <oid> [NAME <name>] [DESC <description>] \
[OBSOLETE] [SUP <oid>] [EQUALITY <oid>] [ORDERING <oid>] \
[SUBSTR <oid>] [SYNTAX <oidlen>] [SINGLE\-VALUE] [COLLECTIVE] \
[NO\-USER\-MODIFICATION] [USAGE <attributeUsage>] )
Specify an attribute type using the LDAPv3 syntax defined in RFC 2252.
The slapd parser extends the RFC 2252 definition by allowing string
forms as well as numeric OIDs to be used for the attribute OID and

View file

@ -23,7 +23,7 @@ is used to generate an LDAP Directory Interchange Format
.BR slapd (8)
database.
It opens the given database determined by the database number or
suffix and and writes the corresponding LDIF to standard output or
suffix and writes the corresponding LDIF to standard output or
the specified file.
.LP
The LDIF generated by this tool is suitable for use with

83
doc/man/man8/slapindex.8 Normal file
View file

@ -0,0 +1,83 @@
.TH SLAPINDEX 8C "17 July 1999" "OpenLDAP LDVERSION"
.\" $OpenLDAP$
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
slapindex \- SLAPD index to LDIF utility
.SH SYNOPSIS
.B SBINDIR/slapcat
.B [\-v]
.B [\-c]
.B [\-d level]
.B [\-b suffix]
.B [\-n dbnum]
.B [\-f slapd.conf]
.B
.LP
.SH DESCRIPTION
.LP
.B Slapindex
is used to regenerate
.BR slapd (8)
indices based upon the current contents of a database.
It opens the given database determined by the database number or
suffix and updates the indices for all values of all attributes
of all entries.
.SH OPTIONS
.TP
.B \-v
enable verbose mode.
.TP
.B \-c
enable continue (ignore errors) mode.
.TP
.BI \-d " level"
enable debugging messages as defined by the specified
.IR level .
.TP
.BI \-b " suffix"
Use the specified \fIsuffix\fR to determine which database to
generate output for. The \-b cannot be used in conjunction
with the
.B \-n
option.
.TP
.BI \-n " dbnum"
Generate output for the \fIdbnum\fR\-th database listed in the
configuration file. The
.B \-n
cannot be used in conjunction with the
.B \-b
option.
.TP
.BI \-f " slapd.conf"
specify an alternative
.BR slapd.conf (5)
file.
.SH LIMITATIONS
Your
.BR slapd (8)
should not be running (at least, not in read-write
mode) when you do this to ensure consistency of the database.
.LP
This command provides ample opportunity for the user to obtain
and drink their favorite beverage.
.SH EXAMPLES
To reindex your SLAPD database, give the command:
.LP
.nf
.ft tt
SBINDIR/slapindex
.ft
.fi
.SH "SEE ALSO"
.BR ldap (3),
.BR ldif (5),
.BR slapadd (8),
.BR ldapadd (1),
.BR slapd (8)
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
.B OpenLDAP
is derived from University of Michigan LDAP 3.3 Release.

View file

@ -3,9 +3,10 @@
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
slappassword \- OpenLDAP password utility
slappasswd \- OpenLDAP password utility
.SH SYNOPSIS
.B SBINDIR/slappasswd
.B [\-a]
.B [\-v]
.B [\-s secret]
.B [\-h hash]
@ -20,6 +21,9 @@ as a userPassword value
.BR rootpw .
.SH OPTIONS
.TP
.B \-a
generate authPassword values instead of RFC2307 passwords
.TP
.B \-v
enable verbose mode.
.TP
@ -27,8 +31,8 @@ enable verbose mode.
The secret to hash. If not provided, the user will be prompted
for the secret to hash.
.TP
.BI \-h " hash"
The hash algorithm to use. Algorithms supported include
.BI \-h " scheme"
The hash scheme to use. RFC2307 schemes supported include
.IR {CRYPT} ,
.IR {MD5} ,
.IR {SMD5} ,
@ -36,10 +40,18 @@ The hash algorithm to use. Algorithms supported include
.IR {SHA} .
The default is
.IR {SSHA} .
.LP
If \-a is specified, the following authPassword schemes
may be specified:
.IR MD5 ,
.IR SHA1 ", and"
.IR X-CRYPT .
The default is
.IR SHA1 .
.SH LIMITATIONS
The practice storing hashed passwords in userPassword
violates Standard Track schema and may hinder
interoperability.
interoperability. authPassword is not yet widely supported.
.SH "SECURITY CONSIDERATIONS"
Use of hashed passwords does not protect passwords during
protocol transfer. TLS or other eavesdropping protections
@ -47,7 +59,8 @@ should be inplace before using LDAP simple bind. The
hashed password values should be protected as if they
were clear text passwords.
.SH "SEE ALSO"
.BR ldapmodify (3),
.BR ldappasswd (1),
.BR ldapmodify (1),
.BR slapd (8)
.SH ACKNOWLEDGEMENTS
.B OpenLDAP

View file

@ -1,12 +1,5 @@
This is an index of RFC contained in this directory:
STD Standard
DS Draft Standard
PS Proposed Standard
I Information
E Experimental
rfc1274.txt COSINE and Internet X.500 Schema (PS)
rfc1275.txt X.500 Replication Requirements (I)
rfc1279.txt X.500 and Domains (E)
@ -49,9 +42,19 @@ rfc2696.txt LDAP Simple Paged Result Control (PS)
rfc2713.txt LDAP Java schema (I)
rfc2714.txt LDAP COBRA schema (I)
rfc2798.txt LDAP inetOrgPerson schema (I)
rfc2829.txt LDAPv3/Authentication Methods (PS)
rfc2830.txt LDAPv3/StartTLS (PS)
rfc2820.txt Access Control Requirements for LDAP (I)
rfc2829.txt LDAPv3: Authentication Methods (PS)
rfc2830.txt LDAPv3: StartTLS (PS)
rfc2831.txt SASL/DIGEST-MD5 (PS)
rfc2849.txt LDIFv1 (PS)
Legend:
STD Standard
DS Draft Standard
PS Proposed Standard
I Information
E Experimental
FYI For Your Information
BCP Best Common Practice
$OpenLDAP$

507
doc/rfc/rfc2820.txt Normal file
View file

@ -0,0 +1,507 @@
Network Working Group E. Stokes
Request for Comments: 2820 D. Byrne
Category: Informational IBM
B. Blakley
Dascom
P. Behera
Netscape
May 2000
Access Control Requirements for LDAP
Status of this Memo
This memo provides information for the Internet community. It does
not specify an Internet standard of any kind. Distribution of this
memo is unlimited.
Copyright Notice
Copyright (C) The Internet Society (2000). All Rights Reserved.
Abstract
This document describes the fundamental requirements of an access
control list (ACL) model for the Lightweight Directory Application
Protocol (LDAP) directory service. It is intended to be a gathering
place for access control requirements needed to provide authorized
access to and interoperability between directories.
The keywords "MUST", "SHOULD", and "MAY" used in this document are to
be interpreted as described in [bradner97].
1. Introduction
The ability to securely access (replicate and distribute) directory
information throughout the network is necessary for successful
deployment. LDAP's acceptance as an access protocol for directory
information is driving the need to provide an access control model
definition for LDAP directory content among servers within an
enterprise and the Internet. Currently LDAP does not define an
access control model, but is needed to ensure consistent secure
access across heterogeneous LDAP implementations. The requirements
for access control are critical to the successful deployment and
acceptance of LDAP in the market place.
The RFC 2119 terminology is used in this document.
Stokes, et al. Informational [Page 1]
RFC 2820 Access Control Requirements for LDAP May 2000
2. Objectives
The major objective is to provide a simple, but secure, highly
efficient access control model for LDAP while also providing the
appropriate flexibility to meet the needs of both the Internet and
enterprise environments and policies.
This generally leads to several general requirements that are
discussed below.
3. Requirements
This section is divided into several areas of requirements: general,
semantics/policy, usability, and nested groups (an unresolved issue).
The requirements are not in any priority order. Examples and
explanatory text is provided where deemed necessary. Usability is
perhaps the one set of requirements that is generally overlooked, but
must be addressed to provide a secure system. Usability is a security
issue, not just a nice design goal and requirement. If it is
impossible to set and manage a policy for a secure situation that a
human can understand, then what was set up will probably be non-
secure. We all need to think of usability as a functional security
requirement.
3.1 General
G1. Model SHOULD be general enough to support extensibility to add
desirable features in the future.
G2. When in doubt, safer is better, especially when establishing
defaults.
G3. ACL administration SHOULD be part of the LDAP protocol. Access
control information MUST be an LDAP attribute.
G4. Object reuse protection SHOULD be provided and MUST NOT inhibit
implementation of object reuse. The directory SHOULD support policy
controlling the re-creation of deleted DNs, particularly in cases
where they are re-created for the purpose of assigning them to a
subject other than the owner of the deleted DN.
3.2 Semantics / Policy
S1. Omitted as redundant; see U8.
S2. More specific policies must override less specific ones (e.g.
individual user entry in ACL SHOULD take precedence over group entry)
for the evaluation of an ACL.
Stokes, et al. Informational [Page 2]
RFC 2820 Access Control Requirements for LDAP May 2000
S3. Multiple policies of equal specificity SHOULD be combined in
some easily-understood way (e.g. union or intersection). This is
best understood by example. Suppose user A belongs to 3 groups and
those 3 groups are listed on the ACL. Also suppose that the
permissions for each of those groups are not identical. Each group is
of equal specificity (e.g. each group is listed on the ACL) and the
policy for granting user A access (given the example) SHOULD be
combined in some easily understood way, such as by intersection or
union. For example, an intersection policy here may yield a more
limited access for user A than a union policy.
S4. Newly created directory entries SHOULD be subject to a secure
default policy.
S5. Access policy SHOULD NOT be expressed in terms of attributes
which the directory administrator or his organization cannot
administer (e.g. groups whose membership is administered by another
organization).
S6. Access policy SHOULD NOT be expressed in terms of attributes
which are easily forged (e.g. IP addresses). There may be valid
reasons for enabling access based on attributes that are easily
forged and the behavior/implications of doing that should be
documented.
S7. Humans (including administrators) SHOULD NOT be required to
manage access policy on the basis of attributes which are not
"human-readable" (e.g. IP addresses).
S8. It MUST be possible to deny a subject the right to invoke a
directory operation. The system SHOULD NOT require a specific
implementation of denial (e.g. explicit denial, implicit denial).
S9. The system MUST be able (semantically) to support either
default-grant or default-deny semantics (not simultaneously).
S10. The system MUST be able to support either union semantics or
intersection semantics for aggregate subjects (not simultaneously).
S11. Absence of policy SHOULD be interpretable as grant or deny.
Deny takes precedence over grant among entries of equal specificity.
S12. ACL policy resolution MUST NOT depend on the order of entries
in the ACL.
S13. Rights management MUST have no side effects. Granting a
subject one right to an object MUST NOT implicitly grant the same or
any other subject a different right to the same object. Granting a
Stokes, et al. Informational [Page 3]
RFC 2820 Access Control Requirements for LDAP May 2000
privilege attribute to one subject MUST NOT implicitly grant the same
privilege attribute to any other subject. Granting a privilege
attribute to one subject MUST NOT implicitly grant a different
privilege attribute to the same or any other subject. Definition: An
ACL's "scope" is defined as the set of directory objects governed by
the policy it defines; this set of objects is a sub-tree of the
directory. Changing the policy asserted by an ACL (by changing one
or more of its entries) MUST NOT implicitly change the policy
governed by an ACL in a different scope.
S14. It SHOULD be possible to apply a single policy to multiple
directory entries, even if those entries are in different subtrees.
Applying a single policy to multiple directory entries SHOULD NOT
require creation and storage of multiple copies of the policy data.
The system SHOULD NOT require a specific implementation (e.g. nested
groups, named ACLs) of support for policy sharing.
3.3 Usability (Manageability)
U1. When in doubt, simpler is better, both at the interface and in
the implementation.
U2. Subjects MUST be drawn from the "natural" LDAP namespace; they
should be DNs.
U3. It SHOULD NOT be possible via ACL administration to lock all
users, including all administrators, out of the directory.
U4. Administrators SHOULD NOT be required to evaluate arbitrary
Boolean predicates in order to create or understand policy.
U5. Administrators SHOULD be able to administer access to
directories and their attributes based on their sensitivity, without
having to understand the semantics of individual schema elements and
their attributes (see U9).
U6. Management of access to resources in an entire subtree SHOULD
require only one ACL (at the subtree root). Note that this makes
access control based explicitly on attribute types very hard, unless
you constrain the types of entries in subtrees. For example, another
attribute is added to an entry. That attribute may fall outside the
grouping covered by the ACL and hence require additional
administration where the desired affect is indeed a different ACL.
Access control information specified in one administrative area MUST
NOT have jurisdiction in another area. You SHOULD NOT be able to
control access to the aliased entry in the alias. You SHOULD be able
to control access to the alias name.
Stokes, et al. Informational [Page 4]
RFC 2820 Access Control Requirements for LDAP May 2000
U7. Override of subtree policy MUST be supported on a per-
directory-entry basis.
U8. Control of access to individual directory entry attributes (not
just the whole directory entry) MUST be supported.
U9. Administrator MUST be able to coarsen access policy granularity
by grouping attributes with similar access sensitivities.
U10. Control of access on a per-user granularity MUST be supported.
U11. Administrator MUST be able to aggregate users (for example, by
assigning them to groups or roles) to simplify administration.
U12. It MUST be possible to review "effective access" of any user,
group, or role to any entry's attributes. This aids the administrator
in setting the correct policy.
U13. A single administrator SHOULD be able to define policy for the
entire directory tree. An administrator MUST be able to delegate
policy administration for specific subtrees to other users. This
allows for the partitioning of the entire directory tree for policy
administration, but still allows a single policy to be defined for
the entire tree independent of partitioning. (Partition in this
context means scope of administration). An administrator MUST be able
to create new partitions at any point in the directory tree, and MUST
be able to merge a superior and subordinate partition. An
administrator MUST be able to configure whether delegated access
control information from superior partitions is to be accepted or
not.
U14. It MUST be possible to authorize users to traverse directory
structure even if they are not authorized to examine or modify some
traversed entries; it MUST also be possible to prohibit this. The
tree structure MUST be able to be protected from view if so desired
by the administrator.
U15. It MUST be possible to create publicly readable entries, which
may be read even by unauthenticated clients.
U16. The model for combining multiple access control list entries
referring to a single individual MUST be easy to understand.
U17. Administrator MUST be able to determine where inherited policy
information comes from, that is, where ACLs are located and which
ACLs were applied. Where inheritance of ACLs is applied, it must be
able to be shown how/where that new ACL is derived from.
Stokes, et al. Informational [Page 5]
RFC 2820 Access Control Requirements for LDAP May 2000
U18. It SHOULD be possible for the administrator to configure the
access control system to permit users to grant additional access
control rights for entries which they create.
4. Security Considerations
Access control is a security consideration. This documents addresses
the requirements.
5. Glossary
This glossary is intended to aid the novice not versed in depth about
access control. It contains a list of terms and their definitions
that are commonly used in discussing access control [emca].
Access control - The prevention of use of a resource by unidentified
and/or unauthorized entities in any other that an authorized manner.
Access control list - A set of control attributes. It is a list,
associated with a security object or a group of security objects.
The list contains the names of security subjects and the type of
access that may be granted.
Access control policy - A set of rules, part of a security policy, by
which human users, or their representatives, are authenticated and by
which access by these users to applications and other services and
security objects is granted or denied.
Access context - The context, in terms of such variables as location,
time of day, level of security of the underlying associations, etc.,
in which an access to a security object is made.
Authorization - The granting of access to a security object.
Authorization policy - A set of rules, part of an access control
policy, by which access by security subjects to security objects is
granted or denied. An authorization policy may be defined in terms
of access control lists, capabilities, or attributes assigned to
security subjects, security objects, or both.
Control attributes - Attributes, associated with a security object
that, when matched against the privilege attributes of a security
subject, are used to grant or deny access to the security object. An
access control list or list of rights or time of day range are
examples of control attributes.
Credentials - Data that serve to establish the claimed identity of a
security subject relative to a given security domain.
Stokes, et al. Informational [Page 6]
RFC 2820 Access Control Requirements for LDAP May 2000
Privilege attributes - Attributes, associated with a security subject
that, when matched against control attributes of a security object,
are used to grant or deny access to that subject. Group and role
memberships are examples of privilege attributes.
Security attributes - A general term covering both privilege
attributes and control attributes. The use of security attributes is
defined by a security policy.
Security object - An entity in a passive role to which a security
policy applies.
Security policy - A general term covering both access control
policies and authorization policies.
Security subject - An entity in an active role to which a security
policy applies.
6. References
[ldap] Kille, S., Howes, T. and M. Wahl, "Lightweight Directory
Access Protocol (v3)", RFC 2251, August 1997.
[ecma] ECMA, "Security in Open Systems: A Security Framework"
ECMA TR/46, July 1988.
[bradner97] Bradner, S., "Key Words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
Stokes, et al. Informational [Page 7]
RFC 2820 Access Control Requirements for LDAP May 2000
7. Authors' Addresses
Bob Blakley
Dascom
5515 Balcones Drive
Austin, TX 78731
USA
Phone: +1 512 458 4037 ext 5012
Fax: +1 512 458 2377
EMail: blakley@dascom.com
Ellen Stokes
IBM
11400 Burnet Rd
Austin, TX 78758
USA
Phone: +1 512 838 3725
Fax: +1 512 838 0156
EMail: stokes@austin.ibm.com
Debbie Byrne
IBM
11400 Burnet Rd
Austin, TX 78758
USA
Phone: +1 512 838 1930
Fax: +1 512 838 8597
EMail: djbyrne@us.ibm.com
Prasanta Behera
Netscape
501 Ellis Street
Mountain View, CA 94043
USA
Phone: +1 650 937 4948
Fax: +1 650 528-4164
EMail: prasanta@netscape.com
Stokes, et al. Informational [Page 8]
RFC 2820 Access Control Requirements for LDAP May 2000
8. Full Copyright Statement
Copyright (C) The Internet Society (2000). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement
Funding for the RFC Editor function is currently provided by the
Internet Society.
Stokes, et al. Informational [Page 9]

View file

@ -13,6 +13,9 @@
#ifndef _AC_ALLOCA_H
#define _AC_ALLOCA_H
/*
* use of alloca is disallowed as it is machine dependent
*/
#error "alloca() not supported, use malloc()"
/* AIX requires this to be the first thing in the file. */

View file

@ -16,10 +16,18 @@
#include <signal.h>
#undef SIGNAL
#ifdef HAVE_SIGSET
#if defined( HAVE_SIGACTION )
#define SIGNAL lutil_sigaction
typedef void (*lutil_sig_t)(int);
LDAP_LUTIL_F(lutil_sig_t) lutil_sigaction( int sig, lutil_sig_t func );
#define SIGNAL_REINSTALL(sig,act) (void)0
#elif defined( HAVE_SIGSET )
#define SIGNAL sigset
#define SIGNAL_REINSTALL sigset
#else
#define SIGNAL signal
#define SIGNAL_REINSTALL signal
#endif
#if !defined( LDAP_SIGUSR1 ) || !defined( LDAP_SIGUSR2 )

View file

@ -167,5 +167,13 @@ LDAP_F (int) ldap_pvt_inet_aton LDAP_P(( const char *, struct in_addr * ));
#define AC_HTONS( s ) htons( s )
#define AC_NTOHS( s ) ntohs( s )
#ifdef LDAP_PF_LOCAL
# if !defined( AF_LOCAL ) && defined( AF_UNIX )
# define AF_LOCAL AF_UNIX
# endif
# if !defined( PF_LOCAL ) && defined( PF_UNIX )
# define PF_LOCAL PF_UNIX
# endif
#endif
#endif /* _AC_SOCKET_H_ */

View file

@ -75,4 +75,10 @@ int (strncasecmp)();
# endif
#endif
#define AC_MEMCPY( d, s, n ) (SAFEMEMCPY((d),(s),(n)))
#define AC_FMEMCPY( d, s, n ) do { \
if((n) == 1) *((char*)(d)) = *((char*)(s)); \
else AC_MEMCPY( (d), (s), (n) ); \
} while(0)
#endif /* _AC_STRING_H */

View file

@ -122,6 +122,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_X_TLS 0x6007
#define LDAP_OPT_X_TLS_PROTOCOL 0x6008
#define LDAP_OPT_X_TLS_CIPHER_SUITE 0x6009
#define LDAP_OPT_X_TLS_RANDOM_FILE 0x600a
#define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1
@ -130,9 +131,17 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_X_TLS_TRY 4
/* OpenLDAP SASL options */
#define LDAP_OPT_X_SASL_MINSSF 0x6100
#define LDAP_OPT_X_SASL_MAXSSF 0x6101
#define LDAP_OPT_X_SASL_ACTSSF 0x6102
#define LDAP_OPT_X_SASL_MECH 0x6100
#define LDAP_OPT_X_SASL_REALM 0x6101
#define LDAP_OPT_X_SASL_AUTHCID 0x6102
#define LDAP_OPT_X_SASL_AUTHZID 0x6103
#define LDAP_OPT_X_SASL_SSF 0x6104 /* read-only */
#define LDAP_OPT_X_SASL_SSF_EXTERNAL 0x6105 /* write-only */
#define LDAP_OPT_X_SASL_SECPROPS 0x6106 /* write-only */
#define LDAP_OPT_X_SASL_SSF_MIN 0x6107
#define LDAP_OPT_X_SASL_SSF_MAX 0x6108
#define LDAP_OPT_X_SASL_MAXBUFSIZE 0x6109
/* on/off values */
#define LDAP_OPT_ON ((void *) 1)
@ -192,7 +201,7 @@ typedef struct ldapcontrol {
/* LDAP Extended Operations */
#define LDAP_EXOP_START_TLS "1.3.6.1.4.1.1466.20037"
#define LDAP_EXOP_X_MODIFY_PASSWD "1.3.6.1.4.1.4203.666.6.1"
#define LDAP_EXOP_X_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
#define LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
#define LDAP_TAG_EXOP_X_MODIFY_PASSWD_OLD ((ber_tag_t) 0x81U)
#define LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
@ -244,9 +253,9 @@ typedef struct ldapcontrol {
#define LDAP_REQ_MODIFY ((ber_tag_t) 0x66U) /* application + constructed */
#define LDAP_REQ_ADD ((ber_tag_t) 0x68U) /* application + constructed */
#define LDAP_REQ_DELETE ((ber_tag_t) 0x4aU) /* application + primitive */
#define LDAP_REQ_MODRDN ((ber_tag_t) 0x6cU) /* application + constructed */
#define LDAP_REQ_MODDN LDAP_REQ_MODRDN
#define LDAP_REQ_RENAME LDAP_REQ_MODRDN
#define LDAP_REQ_MODDN ((ber_tag_t) 0x6cU) /* application + constructed */
#define LDAP_REQ_MODRDN LDAP_REQ_MODDN
#define LDAP_REQ_RENAME LDAP_REQ_MODDN
#define LDAP_REQ_COMPARE ((ber_tag_t) 0x6eU) /* application + constructed */
#define LDAP_REQ_ABANDON ((ber_tag_t) 0x50U) /* application + primitive */
#define LDAP_REQ_EXTENDED ((ber_tag_t) 0x77U) /* application + constructed */
@ -259,9 +268,9 @@ typedef struct ldapcontrol {
#define LDAP_RES_MODIFY ((ber_tag_t) 0x67U) /* application + constructed */
#define LDAP_RES_ADD ((ber_tag_t) 0x69U) /* application + constructed */
#define LDAP_RES_DELETE ((ber_tag_t) 0x6bU) /* application + constructed */
#define LDAP_RES_MODRDN ((ber_tag_t) 0x6dU) /* application + constructed */
#define LDAP_RES_MODDN LDAP_RES_MODRDN /* application + constructed */
#define LDAP_RES_RENAME LDAP_RES_MODRDN /* application + constructed */
#define LDAP_RES_MODDN ((ber_tag_t) 0x6dU) /* application + constructed */
#define LDAP_RES_MODRDN LDAP_RES_MODDN /* application + constructed */
#define LDAP_RES_RENAME LDAP_RES_MODDN /* application + constructed */
#define LDAP_RES_COMPARE ((ber_tag_t) 0x6fU) /* application + constructed */
#define LDAP_RES_EXTENDED ((ber_tag_t) 0x78U) /* V3: application + constructed */
#define LDAP_RES_EXTENDED_PARTIAL ((ber_tag_t) 0x79U) /* V3+: application + constructed */
@ -271,7 +280,8 @@ typedef struct ldapcontrol {
/* sasl methods */
#define LDAP_SASL_SIMPLE NULL
#define LDAP_SASL_SIMPLE ((char*)0)
/* authentication methods available */
#define LDAP_AUTH_NONE ((ber_tag_t) 0x00U) /* no authentication */
@ -559,6 +569,13 @@ ldap_set_rebind_proc LDAP_P((
/*
* in controls.c:
*/
LDAP_F( int )
ldap_create_control LDAP_P((
const char *requestOID,
BerElement *ber,
int iscritical,
LDAPControl **ctrlp ));
LDAP_F( void )
ldap_control_free LDAP_P((
LDAPControl *ctrl ));
@ -686,16 +703,35 @@ ldap_sasl_bind LDAP_P((
LDAPControl **clientctrls,
int *msgidp ));
/* Interaction flags (should be passed about in a control)
* Automatic (default): use defaults, prompt otherwise
* Interactive: prompt always
* Quiet: never prompt
*/
#define LDAP_SASL_AUTOMATIC 0U
#define LDAP_SASL_INTERACTIVE 1U
#define LDAP_SASL_QUIET 2U
/*
* V3 SASL Interaction Function Callback Prototype
* when using Cyrus SASL, interact is pointer to sasl_interact_t
* should likely passed in a control (and provided controls)
*/
typedef int (LDAP_SASL_INTERACT_PROC) LDAP_P((
LDAP *ld, unsigned flags, void* defaults, void *interact ));
LDAP_F( int )
ldap_negotiated_sasl_bind_s LDAP_P((
ldap_sasl_interactive_bind_s LDAP_P((
LDAP *ld,
LDAP_CONST char *dn, /* usually NULL */
LDAP_CONST char *authenticationId,
LDAP_CONST char *authorizationId, /* usually NULL */
LDAP_CONST char *saslMechanism,
struct berval *passPhrase,
LDAPControl **serverControls,
LDAPControl **clientControls ));
LDAPControl **clientControls,
/* should be client controls */
unsigned flags,
LDAP_SASL_INTERACT_PROC *proc,
void *defaults ));
LDAP_F( int )
ldap_sasl_bind_s LDAP_P((

View file

@ -92,6 +92,10 @@ ldap_str2charray LDAP_P((
const char *str,
const char *brkstr ));
LDAP_F( char * )
ldap_charray2str LDAP_P((
char **array, const char* sep ));
/* url.c */
LDAP_F (void) ldap_pvt_hex_unescape LDAP_P(( char *s ));
LDAP_F (int) ldap_pvt_unhex( int c );
@ -118,23 +122,23 @@ LDAP_F (int) ldap_pvt_unhex( int c );
#define LDAP_NEEDSESCAPE(c) ((c) == '\\' || (c) == '"')
#ifdef HAVE_CYRUS_SASL
/* sasl.c */
LDAP_END_DECL
#include <sasl.h>
#include <ldap.h>
LDAP_BEGIN_DECL
/* cyrus.c */
struct sasl_security_properties; /* avoid pulling in <sasl.h> */
LDAP_F (int) ldap_pvt_sasl_secprops LDAP_P((
const char *in,
struct sasl_security_properties *secprops ));
LDAP_F (int) ldap_pvt_sasl_init LDAP_P(( void )); /* clientside init */
LDAP_F (int) ldap_pvt_sasl_install LDAP_P(( Sockbuf *, void * ));
LDAP_F (int) ldap_pvt_sasl_bind LDAP_P(( LDAP *, LDAP_CONST char *,
LDAP_CONST char *, LDAP_CONST sasl_callback_t *, LDAPControl **,
LDAPControl ** ));
LDAP_F (int) ldap_pvt_sasl_get_option LDAP_P(( LDAP *ld, int option,
void *arg ));
LDAP_F (int) ldap_pvt_sasl_set_option LDAP_P(( LDAP *ld, int option,
void *arg ));
LDAP_F (void *) ldap_pvt_sasl_mutex_new LDAP_P((void));
LDAP_F (int) ldap_pvt_sasl_mutex_lock LDAP_P((void *mutex));
LDAP_F (int) ldap_pvt_sasl_mutex_unlock LDAP_P((void *mutex));
LDAP_F (void) ldap_pvt_sasl_mutex_dispose LDAP_P((void *mutex));
struct sockbuf; /* avoid pulling in <lber.h> */
LDAP_F (int) ldap_pvt_sasl_install LDAP_P(( struct sockbuf *, void * ));
#endif /* HAVE_CYRUS_SASL */
#define LDAP_PVT_SASL_LOCAL_SSF 52 /* SSF for Unix Domain Sockets */
/* search.c */
LDAP_F( char * )
ldap_pvt_find_wildcard LDAP_P(( const char *s ));
@ -154,16 +158,16 @@ struct ldapoptions;
struct ldap;
LDAP_F (int) ldap_pvt_tls_init LDAP_P(( void ));
LDAP_F (int) ldap_pvt_tls_config LDAP_P(( struct ldapoptions *lo, int option, const char *arg ));
LDAP_F (int) ldap_pvt_tls_connect LDAP_P(( struct ldap *ld, Sockbuf *sb, void *ctx_arg ));
LDAP_F (int) ldap_pvt_tls_accept LDAP_P(( Sockbuf *sb, void *ctx_arg ));
LDAP_F (int) ldap_pvt_tls_get_option LDAP_P(( struct ldapoptions *lo, int option, void *arg ));
LDAP_F (int) ldap_pvt_tls_set_option LDAP_P(( struct ldapoptions *lo, int option, void *arg ));
LDAP_F (void *) ldap_pvt_tls_sb_handle LDAP_P(( Sockbuf *sb ));
LDAP_F (void *) ldap_pvt_tls_get_handle LDAP_P(( struct ldap *ld ));
LDAP_F (int) ldap_pvt_tls_inplace LDAP_P(( Sockbuf *sb ));
LDAP_F (int) ldap_pvt_tls_start LDAP_P(( struct ldap *ld, Sockbuf *sb, void *ctx_arg ));
LDAP_F (int) ldap_pvt_tls_get_option LDAP_P(( struct ldapoptions *lo, int option, void *arg ));
LDAP_F (int) ldap_pvt_tls_set_option LDAP_P(( struct ldapoptions *lo, int option, void *arg ));
/*
* UTF-8 (in utf-8.c)
*/

View file

@ -36,14 +36,14 @@ LDAP_BEGIN_DECL
typedef struct ldap_schema_extension_item {
char *lsei_name;
char **lsei_values;
} LDAP_SCHEMA_EXTENSION_ITEM;
} LDAPSchemaExtensionItem;
typedef struct ldap_syntax {
char *syn_oid; /* REQUIRED */
char **syn_names; /* OPTIONAL */
char *syn_desc; /* OPTIONAL */
LDAP_SCHEMA_EXTENSION_ITEM **syn_extensions; /* OPTIONAL */
} LDAP_SYNTAX;
LDAPSchemaExtensionItem **syn_extensions; /* OPTIONAL */
} LDAPSyntax;
typedef struct ldap_matchingrule {
char *mr_oid; /* REQUIRED */
@ -51,8 +51,8 @@ typedef struct ldap_matchingrule {
char *mr_desc; /* OPTIONAL */
int mr_obsolete; /* OPTIONAL */
char *mr_syntax_oid; /* REQUIRED */
LDAP_SCHEMA_EXTENSION_ITEM **mr_extensions; /* OPTIONAL */
} LDAP_MATCHING_RULE;
LDAPSchemaExtensionItem **mr_extensions; /* OPTIONAL */
} LDAPMatchingRule;
typedef struct ldap_attributetype {
char *at_oid; /* REQUIRED */
@ -70,8 +70,8 @@ typedef struct ldap_attributetype {
int at_no_user_mod; /* 0=no, 1=yes */
int at_usage; /* 0=userApplications, 1=directoryOperation,
2=distributedOperation, 3=dSAOperation */
LDAP_SCHEMA_EXTENSION_ITEM **at_extensions; /* OPTIONAL */
} LDAP_ATTRIBUTE_TYPE;
LDAPSchemaExtensionItem **at_extensions; /* OPTIONAL */
} LDAPAttributeType;
typedef struct ldap_objectclass {
char *oc_oid; /* REQUIRED */
@ -82,8 +82,8 @@ typedef struct ldap_objectclass {
int oc_kind; /* 0=ABSTRACT, 1=STRUCTURAL, 2=AUXILIARY */
char **oc_at_oids_must; /* OPTIONAL */
char **oc_at_oids_may; /* OPTIONAL */
LDAP_SCHEMA_EXTENSION_ITEM **oc_extensions; /* OPTIONAL */
} LDAP_OBJECT_CLASS;
LDAPSchemaExtensionItem **oc_extensions; /* OPTIONAL */
} LDAPObjectClass;
#define LDAP_SCHEMA_NO 0
#define LDAP_SCHEMA_YES 1
@ -109,81 +109,81 @@ typedef struct ldap_objectclass {
LDAP_F( LDAP_CONST char * )
ldap_syntax2name LDAP_P((
LDAP_SYNTAX * syn ));
LDAPSyntax * syn ));
LDAP_F( LDAP_CONST char * )
ldap_matchingrule2name LDAP_P((
LDAP_MATCHING_RULE * mr ));
LDAPMatchingRule * mr ));
LDAP_F( LDAP_CONST char * )
ldap_attributetype2name LDAP_P((
LDAP_ATTRIBUTE_TYPE * at ));
LDAPAttributeType * at ));
LDAP_F( LDAP_CONST char * )
ldap_objectclass2name LDAP_P((
LDAP_OBJECT_CLASS * oc ));
LDAPObjectClass * oc ));
LDAP_F( void )
ldap_syntax_free LDAP_P((
LDAP_SYNTAX * syn ));
LDAPSyntax * syn ));
LDAP_F( void )
ldap_matchingrule_free LDAP_P((
LDAP_MATCHING_RULE * mr ));
LDAPMatchingRule * mr ));
LDAP_F( void )
ldap_attributetype_free LDAP_P((
LDAP_ATTRIBUTE_TYPE * at ));
LDAPAttributeType * at ));
LDAP_F( void )
ldap_objectclass_free LDAP_P((
LDAP_OBJECT_CLASS * oc ));
LDAPObjectClass * oc ));
LDAP_F( LDAP_OBJECT_CLASS * )
LDAP_F( LDAPObjectClass * )
ldap_str2objectclass LDAP_P((
LDAP_CONST char * s,
int * code,
LDAP_CONST char ** errp,
LDAP_CONST int flags ));
LDAP_F( LDAP_ATTRIBUTE_TYPE * )
LDAP_F( LDAPAttributeType * )
ldap_str2attributetype LDAP_P((
LDAP_CONST char * s,
int * code,
LDAP_CONST char ** errp,
LDAP_CONST int flags ));
LDAP_F( LDAP_SYNTAX * )
LDAP_F( LDAPSyntax * )
ldap_str2syntax LDAP_P((
LDAP_CONST char * s,
int * code,
LDAP_CONST char ** errp,
LDAP_CONST int flags ));
LDAP_F( LDAP_MATCHING_RULE * )
LDAP_F( LDAPMatchingRule * )
ldap_str2matchingrule LDAP_P((
LDAP_CONST char * s,
int * code,
LDAP_CONST char ** errp,
LDAP_CONST int flags ));
LDAP_F( char *)
LDAP_F( char * )
ldap_objectclass2str LDAP_P((
LDAP_CONST LDAP_OBJECT_CLASS * oc ));
LDAP_CONST LDAPObjectClass * oc ));
LDAP_F( char *)
LDAP_F( char * )
ldap_attributetype2str LDAP_P((
LDAP_CONST LDAP_ATTRIBUTE_TYPE * at ));
LDAP_CONST LDAPAttributeType * at ));
LDAP_F( char *)
LDAP_F( char * )
ldap_syntax2str LDAP_P((
LDAP_CONST LDAP_SYNTAX * syn ));
LDAP_CONST LDAPSyntax * syn ));
LDAP_F( char *)
LDAP_F( char * )
ldap_matchingrule2str LDAP_P((
LDAP_CONST LDAP_MATCHING_RULE * mr ));
LDAP_CONST LDAPMatchingRule * mr ));
LDAP_F( char *)
LDAP_F( char * )
ldap_scherr2str LDAP_P((
int code )) LDAP_GCCATTR((const));

39
include/lutil_ldap.h Normal file
View file

@ -0,0 +1,39 @@
/* $OpenLDAP$ */
/*
* Copyright 2000 The OpenLDAP Foundation, Redwood City, California, USA
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted only
* as authorized by the OpenLDAP Public License. A copy of this
* license is available at http://www.OpenLDAP.org/license.html or
* in file LICENSE in the top-level directory of the distribution.
*/
#ifndef _LUTIL_LDAP_H
#define _LUTIL_LDAP_H 1
#include <ldap_cdefs.h>
#include <lber_types.h>
/*
* Include file for lutil LDAP routines
*/
LDAP_BEGIN_DECL
LDAP_LUTIL_F( void * )
lutil_sasl_defaults LDAP_P((
LDAP *ld,
char *mech,
char *realm,
char *authcid,
char *passwd,
char *authzid ));
LDAP_LUTIL_F( int )
lutil_sasl_interact LDAP_P((
LDAP *ld, unsigned flags, void *defaults, void *p ));
LDAP_END_DECL
#endif /* _LUTIL_LDAP_H */

View file

@ -846,8 +846,8 @@
/* define to support CLDAP */
#undef LDAP_CONNECTIONLESS
/* define to support PF_UNIX */
#undef LDAP_PF_UNIX
/* define to support PF_LOCAL */
#undef LDAP_PF_LOCAL
/* define to support PF_INET6 */
#undef LDAP_PF_INET6

View file

@ -136,29 +136,22 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
ber_tag_t
ber_peek_tag(
BerElement *ber_in,
BerElement *ber,
ber_len_t *len )
{
/*
* This implementation assumes ber_skip_tag() only
* modifies ber_ptr field of the BerElement.
*/
char *save;
ber_tag_t tag;
BerElement *ber;
assert( ber_in != NULL );
assert( BER_VALID( ber_in ) );
*len = 0;
ber = ber_dup( ber_in );
if( ber == NULL ) {
return LBER_ERROR;
}
assert( BER_VALID( ber ) );
save = ber->ber_ptr;
tag = ber_skip_tag( ber, len );
ber->ber_ptr = save;
ber_free( ber, 0 );
return( tag );
return tag;
}
static ber_len_t

View file

@ -533,7 +533,7 @@ ber_put_seqorset( BerElement *ber )
* the length field. Move the data if
* we don't actually need that much
*/
SAFEMEMCPY( (*sos)->sos_first + taglen +
AC_MEMCPY( (*sos)->sos_first + taglen +
lenlen, (*sos)->sos_first + taglen +
FOUR_BYTE_LEN, len );
}
@ -583,7 +583,7 @@ ber_put_seqorset( BerElement *ber )
tmptag >>= 8;
}
SAFEMEMCPY( (*sos)->sos_first,
AC_FMEMCPY( (*sos)->sos_first,
&nettag[sizeof(ber_tag_t) - taglen],
taglen );
@ -594,12 +594,12 @@ ber_put_seqorset( BerElement *ber )
}
/* one byte of length length */
SAFEMEMCPY( (*sos)->sos_first + 1, &ltag, 1 );
(*sos)->sos_first[1] = ltag;
if ( ber->ber_options & LBER_USE_DER ) {
if (lenlen > 1) {
/* Write the length itself */
SAFEMEMCPY( (*sos)->sos_first + 2,
AC_FMEMCPY( (*sos)->sos_first + 2,
&netlen[sizeof(ber_len_t) - (lenlen - 1)],
lenlen - 1 );
}
@ -609,13 +609,13 @@ ber_put_seqorset( BerElement *ber )
* the length field. Move the data if
* we don't actually need that much
*/
SAFEMEMCPY( (*sos)->sos_first + taglen +
AC_FMEMCPY( (*sos)->sos_first + taglen +
lenlen, (*sos)->sos_first + taglen +
FOUR_BYTE_LEN, len );
}
} else {
/* the length itself */
SAFEMEMCPY( (*sos)->sos_first + taglen + 1,
AC_FMEMCPY( (*sos)->sos_first + taglen + 1,
&netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN - 1)],
FOUR_BYTE_LEN - 1 );
}

View file

@ -34,11 +34,6 @@
#include "lber-int.h"
static ber_slen_t BerRead LDAP_P((
Sockbuf *sb,
char *buf,
ber_len_t len ));
#define EXBUFSIZ 1024
/* probably far too large... */
@ -52,7 +47,7 @@ static ber_slen_t BerRead LDAP_P((
static ber_slen_t
BerRead(
Sockbuf *sb,
char *buf,
unsigned char *buf,
ber_len_t len )
{
ber_slen_t c;
@ -69,7 +64,7 @@ BerRead(
break;
return( c );
}
buf+= c;
buf+=c;
nread+=c;
len-=c;
}
@ -93,7 +88,7 @@ ber_read(
nleft = ber->ber_end - ber->ber_ptr;
actuallen = nleft < len ? nleft : len;
SAFEMEMCPY( buf, ber->ber_ptr, actuallen );
AC_MEMCPY( buf, ber->ber_ptr, actuallen );
ber->ber_ptr += actuallen;
@ -117,7 +112,7 @@ ber_write(
if ( ber_realloc( ber, len ) != 0 )
return( -1 );
}
SAFEMEMCPY( ber->ber_ptr, buf, (size_t)len );
AC_MEMCPY( ber->ber_ptr, buf, (size_t)len );
ber->ber_ptr += len;
return( (ber_slen_t) len );
@ -126,7 +121,7 @@ ber_write(
if ( ber_realloc( ber, len ) != 0 )
return( -1 );
}
SAFEMEMCPY( ber->ber_sos->sos_ptr, buf, (size_t)len );
AC_MEMCPY( ber->ber_sos->sos_ptr, buf, (size_t)len );
ber->ber_sos->sos_ptr += len;
ber->ber_sos->sos_clen += len;
return( (ber_slen_t) len );
@ -397,7 +392,7 @@ int ber_flatten(
return( -1 );
}
SAFEMEMCPY( bv->bv_val, ber->ber_buf, len );
AC_MEMCPY( bv->bv_val, ber->ber_buf, len );
bv->bv_val[len] = '\0';
bv->bv_len = len;
}

View file

@ -71,8 +71,8 @@ struct sockbuf {
#define sb_options sb_opts.lbo_options
#define sb_debug sb_opts.lbo_debug
ber_socket_t sb_fd;
int sb_trans_needs_read:1;
int sb_trans_needs_write:1;
unsigned int sb_trans_needs_read:1;
unsigned int sb_trans_needs_write:1;
};
#define SOCKBUF_VALID( sb ) ( (sb)->sb_valid == LBER_VALID_SOCKBUF )

View file

@ -473,7 +473,7 @@ ber_bvdup(
return NULL;
}
SAFEMEMCPY( new->bv_val, bv->bv_val, bv->bv_len );
AC_MEMCPY( new->bv_val, bv->bv_val, bv->bv_len );
new->bv_val[bv->bv_len] = '\0';
new->bv_len = bv->bv_len;
@ -564,6 +564,6 @@ ber_strdup( LDAP_CONST char *s )
return( NULL );
}
SAFEMEMCPY( p, s, len );
AC_MEMCPY( p, s, len );
return( p );
}

View file

@ -124,7 +124,7 @@ ber_set_option(
return LBER_OPT_ERROR;
}
memcpy(ber_int_memory_fns, f, sizeof(BerMemoryFunctions));
AC_MEMCPY(ber_int_memory_fns, f, sizeof(BerMemoryFunctions));
ber_int_options.lbo_valid = LBER_INITIALIZED;
return LBER_OPT_SUCCESS;

View file

@ -232,12 +232,14 @@ ber_pvt_sb_copy_out( Sockbuf_Buf *sbb, char *buf, ber_len_t len )
assert( buf != NULL );
assert( sbb != NULL );
#if 0
assert( sbb->buf_size > 0 );
#endif
max = sbb->buf_end - sbb->buf_ptr;
max = ( max < len) ? max : len;
if ( max ) {
memcpy( buf, sbb->buf_base + sbb->buf_ptr, max );
AC_MEMCPY( buf, sbb->buf_base + sbb->buf_ptr, max );
sbb->buf_ptr += max;
if ( sbb->buf_ptr >= sbb->buf_end )
sbb->buf_ptr = sbb->buf_end = 0;
@ -656,7 +658,7 @@ sb_dgram_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
p = (struct dgram_data *)sbiod->sbiod_pvt;
if ( opt == LBER_SB_OPT_UDP_SET_DST ) {
memcpy( &p->dst, arg, sizeof( struct sockaddr ) );
AC_MEMCPY( &p->dst, arg, sizeof( struct sockaddr ) );
return 1;
}
else if ( opt == LBER_SB_OPT_UDP_GET_SRC ) {

View file

@ -10,7 +10,7 @@ XLIBRARY = ../libldap.a
PROGRAMS = apitest ltest ttest
SRCS = bind.c open.c result.c error.c compare.c search.c \
controls.c messages.c references.c extended.c \
controls.c messages.c references.c extended.c cyrus.c \
modify.c add.c modrdn.c delete.c abandon.c ufn.c cache.c \
getfilter.c sasl.c sbind.c kbind.c unbind.c friendly.c cldap.c \
free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
@ -20,7 +20,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
charray.c tls.c dn.c os-local.c dnssrv.c \
utf-8.c
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
controls.lo messages.lo references.lo extended.lo \
controls.lo messages.lo references.lo extended.lo cyrus.lo \
modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
getfilter.lo sasl.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \

View file

@ -240,7 +240,7 @@ ldap_add_request_to_cache( LDAP *ld, ber_tag_t msgtype, BerElement *request )
ld->ld_errno = LDAP_NO_MEMORY;
return;
}
SAFEMEMCPY( new->lm_ber->ber_buf, request->ber_buf,
AC_MEMCPY( new->lm_ber->ber_buf, request->ber_buf,
(size_t)len );
new->lm_ber->ber_ptr = new->lm_ber->ber_buf;
new->lm_ber->ber_end = new->lm_ber->ber_buf + len;
@ -498,7 +498,7 @@ msg_dup( LDAPMessage *msg )
LDAP_FREE( (char *)new );
return( NULL );
}
SAFEMEMCPY( new->lm_ber->ber_buf, msg->lm_ber->ber_buf,
AC_MEMCPY( new->lm_ber->ber_buf, msg->lm_ber->ber_buf,
(size_t)len );
new->lm_ber->ber_ptr = new->lm_ber->ber_buf +
( msg->lm_ber->ber_ptr - msg->lm_ber->ber_buf );

View file

@ -217,3 +217,48 @@ ldap_str2charray( const char *str_in, const char *brkstr )
LDAP_FREE( str );
return( res );
}
char * ldap_charray2str( char **a, const char *sep )
{
char *s, **v, *p;
int len = 0;
int slen;
if( sep == NULL ) sep = " ";
slen = strlen( sep );
for ( v = a; *v != NULL; v++ ) {
len += strlen( *v ) + slen; /* for a space */
}
if ( len == 0 ) {
return NULL;
}
len -= slen;
len += 1; /* EOS */
s = LDAP_MALLOC ( len );
if ( s == NULL ) {
return NULL;
}
p = s;
for ( v = a; *v != NULL; v++ ) {
int len;
if ( v != a ) {
strncpy( p, sep, slen );
p += slen;
}
len = strlen( *v );
strncpy( p, *v, len );
p += len;
}
*p = '\0';
return s;
}

View file

@ -139,7 +139,7 @@ cldap_open( LDAP_CONST char *host, int port )
}
for ( i = 0; hp->h_addr_list[ i ] != 0; ++i ) {
SAFEMEMCPY( (char *)&sock.sin_addr,
AC_MEMCPY( (char *)&sock.sin_addr,
(char *)hp->h_addr_list[ i ],
sizeof(sock.sin_addr));
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
@ -287,7 +287,7 @@ add_addr( LDAP *ld, struct sockaddr *sap )
return( -1 );
}
SAFEMEMCPY( (char *)newsap, (char *)sap, sizeof( struct sockaddr ));
AC_MEMCPY( (char *)newsap, (char *)sap, sizeof( struct sockaddr ));
addrs[ ld->ld_cldapnaddr++ ] = newsap;
ld->ld_cldapaddrs = (void **)addrs;
return( 0 );

View file

@ -348,7 +348,7 @@ ldap_control_dup( const LDAPControl *c )
return NULL;
}
SAFEMEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
c->ldctl_value.bv_len );
new->ldctl_value.bv_len = c->ldctl_value.bv_len;
@ -386,7 +386,7 @@ ldap_control_dup( const LDAPControl *c )
* June 2000 sfs Added control utilities
*/
/*---
ldap_int_create_control
ldap_create_control
Internal function to create an LDAP control from the encoded BerElement.
@ -402,8 +402,8 @@ ldap_control_dup( const LDAPControl *c )
---*/
int
ldap_int_create_control(
const char *requestOID,
ldap_create_control(
LDAP_CONST char *requestOID,
BerElement *ber,
int iscritical,
LDAPControl **ctrlp )
@ -415,24 +415,24 @@ ldap_int_create_control(
return LDAP_PARAM_ERROR;
}
if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
if ( ctrl == NULL ) {
return LDAP_NO_MEMORY;
}
ctrl = (LDAPControl *) LBER_MALLOC( sizeof(LDAPControl) );
if ( ctrl == NULL ) {
ber_bvfree( bvalp );
if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
LDAP_FREE( ctrl );
return LDAP_NO_MEMORY;
}
ctrl->ldctl_value = *bvalp;
LDAP_FREE( bvalp );
ber_memfree( bvalp );
ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
ctrl->ldctl_iscritical = iscritical;
if ( ctrl->ldctl_oid == NULL ) {
LBER_FREE( ctrl );
if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
ldap_control_free( ctrl );
return LDAP_NO_MEMORY;
}

943
libraries/libldap/cyrus.c Normal file
View file

@ -0,0 +1,943 @@
/* $OpenLDAP$ */
/*
* Copyright 1999-2000 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include <stdlib.h>
#include <stdio.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
#include <ac/errno.h>
#include "ldap-int.h"
#ifdef LDAP_R_COMPILE
#include "ldap_pvt_thread.h"
#endif
#ifdef HAVE_CYRUS_SASL
#include <sasl.h>
/*
* Various Cyrus SASL related stuff.
*/
#define SASL_MAX_BUFF_SIZE 65536
#define SASL_MIN_BUFF_SIZE 4096
int ldap_int_sasl_init( void )
{
/* XXX not threadsafe */
static int sasl_initialized = 0;
static sasl_callback_t client_callbacks[] = {
#ifdef SASL_CB_GETREALM
{ SASL_CB_GETREALM, NULL, NULL },
#endif
{ SASL_CB_USER, NULL, NULL },
{ SASL_CB_AUTHNAME, NULL, NULL },
{ SASL_CB_PASS, NULL, NULL },
{ SASL_CB_ECHOPROMPT, NULL, NULL },
{ SASL_CB_NOECHOPROMPT, NULL, NULL },
{ SASL_CB_LIST_END, NULL, NULL }
};
if ( sasl_initialized ) {
return 0;
}
#ifndef CSRIMALLOC
sasl_set_alloc(
ber_memalloc,
ber_memcalloc,
ber_memrealloc,
ber_memfree );
#endif /* CSRIMALLOC */
#ifdef LDAP_R_COMPILE
sasl_set_mutex(
ldap_pvt_sasl_mutex_new,
ldap_pvt_sasl_mutex_lock,
ldap_pvt_sasl_mutex_unlock,
ldap_pvt_sasl_mutex_dispose );
#endif
if ( sasl_client_init( client_callbacks ) == SASL_OK ) {
sasl_initialized = 1;
return 0;
}
return -1;
}
/*
* SASL encryption support for LBER Sockbufs
*/
struct sb_sasl_data {
sasl_conn_t *sasl_context;
Sockbuf_Buf sec_buf_in;
Sockbuf_Buf buf_in;
Sockbuf_Buf buf_out;
};
static int
sb_sasl_setup( Sockbuf_IO_Desc *sbiod, void *arg )
{
struct sb_sasl_data *p;
assert( sbiod != NULL );
p = LBER_MALLOC( sizeof( *p ) );
if ( p == NULL )
return -1;
p->sasl_context = (sasl_conn_t *)arg;
ber_pvt_sb_buf_init( &p->sec_buf_in );
ber_pvt_sb_buf_init( &p->buf_in );
ber_pvt_sb_buf_init( &p->buf_out );
if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, SASL_MIN_BUFF_SIZE ) < 0 ) {
errno = ENOMEM;
return -1;
}
sbiod->sbiod_pvt = p;
return 0;
}
static int
sb_sasl_remove( Sockbuf_IO_Desc *sbiod )
{
struct sb_sasl_data *p;
assert( sbiod != NULL );
p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
ber_pvt_sb_buf_destroy( &p->sec_buf_in );
ber_pvt_sb_buf_destroy( &p->buf_in );
ber_pvt_sb_buf_destroy( &p->buf_out );
LBER_FREE( p );
sbiod->sbiod_pvt = NULL;
return 0;
}
static ber_len_t
sb_sasl_pkt_length( const char *buf, int debuglevel )
{
ber_len_t size;
long tmp;
assert( buf != NULL );
tmp = *((long *)buf);
size = ntohl( tmp );
if ( size > SASL_MAX_BUFF_SIZE ) {
/* somebody is trying to mess me up. */
ber_log_printf( LDAP_DEBUG_ANY, debuglevel,
"sb_sasl_pkt_length: received illegal packet length "
"of %lu bytes\n", (unsigned long)size );
size = 16; /* this should lead to an error. */
}
return size + 4; /* include the size !!! */
}
/* Drop a processed packet from the input buffer */
static void
sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel )
{
ber_slen_t len;
len = sec_buf_in->buf_ptr - sec_buf_in->buf_end;
if ( len > 0 )
memmove( sec_buf_in->buf_base, sec_buf_in->buf_base +
sec_buf_in->buf_end, len );
if ( len >= 4 ) {
sec_buf_in->buf_end = sb_sasl_pkt_length( sec_buf_in->buf_base,
debuglevel);
}
else {
sec_buf_in->buf_end = 0;
}
sec_buf_in->buf_ptr = len;
}
static ber_slen_t
sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
struct sb_sasl_data *p;
ber_slen_t ret, bufptr;
assert( sbiod != NULL );
assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
/* Are there anything left in the buffer? */
ret = ber_pvt_sb_copy_out( &p->buf_in, buf, len );
bufptr = ret;
len -= ret;
if ( len == 0 )
return bufptr;
ber_pvt_sb_buf_destroy( &p->buf_in );
/* Read the length of the packet */
while ( p->sec_buf_in.buf_ptr < 4 ) {
ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base,
4 - p->sec_buf_in.buf_ptr );
#ifdef EINTR
if ( ( ret < 0 ) && ( errno == EINTR ) )
continue;
#endif
if ( ret <= 0 )
return ret;
p->sec_buf_in.buf_ptr += ret;
}
/* The new packet always starts at p->sec_buf_in.buf_base */
ret = sb_sasl_pkt_length( p->sec_buf_in.buf_base,
sbiod->sbiod_sb->sb_debug );
/* Grow the packet buffer if neccessary */
if ( ( p->sec_buf_in.buf_size < ret ) &&
ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 ) {
errno = ENOMEM;
return -1;
}
p->sec_buf_in.buf_end = ret;
/* Did we read the whole encrypted packet? */
while ( p->sec_buf_in.buf_ptr < p->sec_buf_in.buf_end ) {
/* No, we have got only a part of it */
ret = p->sec_buf_in.buf_end - p->sec_buf_in.buf_ptr;
ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
p->sec_buf_in.buf_ptr, ret );
#ifdef EINTR
if ( ( ret < 0 ) && ( errno == EINTR ) )
continue;
#endif
if ( ret <= 0 )
return ret;
p->sec_buf_in.buf_ptr += ret;
}
/* Decode the packet */
ret = sasl_decode( p->sasl_context, p->sec_buf_in.buf_base,
p->sec_buf_in.buf_end, &p->buf_in.buf_base,
(unsigned *)&p->buf_in.buf_end );
if ( ret != SASL_OK ) {
ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
"sb_sasl_read: failed to decode packet: %s\n",
sasl_errstring( ret, NULL, NULL ) );
sb_sasl_drop_packet( &p->sec_buf_in,
sbiod->sbiod_sb->sb_debug );
errno = EIO;
return -1;
}
/* Drop the packet from the input buffer */
sb_sasl_drop_packet( &p->sec_buf_in, sbiod->sbiod_sb->sb_debug );
p->buf_in.buf_size = p->buf_in.buf_end;
bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len );
return bufptr;
}
static ber_slen_t
sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
struct sb_sasl_data *p;
int ret;
assert( sbiod != NULL );
assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
/* Are there anything left in the buffer? */
if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
if ( ret <= 0 )
return ret;
}
/* now encode the next packet. */
ber_pvt_sb_buf_destroy( &p->buf_out );
ret = sasl_encode( p->sasl_context, buf, len, &p->buf_out.buf_base,
(unsigned *)&p->buf_out.buf_size );
if ( ret != SASL_OK ) {
ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
"sb_sasl_write: failed to encode packet: %s\n",
sasl_errstring( ret, NULL, NULL ) );
return -1;
}
p->buf_out.buf_end = p->buf_out.buf_size;
ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
if ( ret <= 0 )
return ret;
return len;
}
static int
sb_sasl_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
{
struct sb_sasl_data *p;
p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
if ( opt == LBER_SB_OPT_DATA_READY ) {
if ( p->buf_in.buf_ptr != p->buf_in.buf_end )
return 1;
}
return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
}
Sockbuf_IO ldap_pvt_sockbuf_io_sasl = {
sb_sasl_setup, /* sbi_setup */
sb_sasl_remove, /* sbi_remove */
sb_sasl_ctrl, /* sbi_ctrl */
sb_sasl_read, /* sbi_read */
sb_sasl_write, /* sbi_write */
NULL /* sbi_close */
};
int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg )
{
Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_install\n",
0, 0, 0 );
/* don't install the stuff unless security has been negotiated */
if ( !ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO,
&ldap_pvt_sockbuf_io_sasl ) )
ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_sasl,
LBER_SBIOD_LEVEL_APPLICATION, ctx_arg );
return LDAP_SUCCESS;
}
static int
sasl_err2ldap( int saslerr )
{
int rc;
switch (saslerr) {
case SASL_CONTINUE:
rc = LDAP_MORE_RESULTS_TO_RETURN;
break;
case SASL_INTERACT:
rc = LDAP_LOCAL_ERROR;
break;
case SASL_OK:
rc = LDAP_SUCCESS;
break;
case SASL_FAIL:
rc = LDAP_LOCAL_ERROR;
break;
case SASL_NOMEM:
rc = LDAP_NO_MEMORY;
break;
case SASL_NOMECH:
rc = LDAP_AUTH_UNKNOWN;
break;
case SASL_BADAUTH:
rc = LDAP_AUTH_UNKNOWN;
break;
case SASL_NOAUTHZ:
rc = LDAP_PARAM_ERROR;
break;
case SASL_TOOWEAK:
case SASL_ENCRYPT:
rc = LDAP_AUTH_UNKNOWN;
break;
default:
rc = LDAP_LOCAL_ERROR;
break;
}
assert( rc == LDAP_SUCCESS || LDAP_API_ERROR( rc ) );
return rc;
}
int
ldap_int_sasl_open(
LDAP *ld,
LDAPConn *lc,
const char * host,
ber_len_t ssf )
{
int rc;
sasl_conn_t *ctx;
sasl_callback_t *session_callbacks =
ber_memcalloc( 2, sizeof( sasl_callback_t ) );
if( session_callbacks == NULL ) return LDAP_NO_MEMORY;
session_callbacks[0].id = SASL_CB_USER;
session_callbacks[0].proc = NULL;
session_callbacks[0].context = ld;
session_callbacks[1].id = SASL_CB_LIST_END;
session_callbacks[1].proc = NULL;
session_callbacks[1].context = NULL;
assert( lc->lconn_sasl_ctx == NULL );
if ( host == NULL ) {
ld->ld_errno = LDAP_UNAVAILABLE;
return ld->ld_errno;
}
rc = sasl_client_new( "ldap", host, session_callbacks,
SASL_SECURITY_LAYER, &ctx );
if ( rc != SASL_OK ) {
ld->ld_errno = sasl_err2ldap( rc );
return ld->ld_errno;
}
Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: %s\n",
host, 0, 0 );
lc->lconn_sasl_ctx = ctx;
if( ssf ) {
sasl_external_properties_t extprops;
memset(&extprops, 0L, sizeof(extprops));
extprops.ssf = ssf;
(void) sasl_setprop( ctx, SASL_SSF_EXTERNAL,
(void *) &extprops );
Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: ssf=%ld\n",
(long) ssf, 0, 0 );
}
return LDAP_SUCCESS;
}
int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
{
sasl_conn_t *ctx = lc->lconn_sasl_ctx;
assert( ctx != NULL );
if( ctx ) {
sasl_dispose( &ctx );
lc->lconn_sasl_ctx = NULL;
}
return LDAP_SUCCESS;
}
int
ldap_int_sasl_bind(
LDAP *ld,
const char *dn,
const char *mechs,
LDAPControl **sctrls,
LDAPControl **cctrls,
unsigned flags,
LDAP_SASL_INTERACT_PROC *interact,
void * defaults )
{
char *data;
const char *mech = NULL;
const char *pmech = NULL;
int saslrc, rc;
sasl_ssf_t *ssf = NULL;
sasl_conn_t *ctx;
sasl_interact_t *prompts = NULL;
unsigned credlen;
struct berval ccred;
ber_socket_t sd;
Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: %s\n",
mechs ? mechs : "<null>", 0, 0 );
/* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */
if (ld->ld_version < LDAP_VERSION3) {
ld->ld_errno = LDAP_NOT_SUPPORTED;
return ld->ld_errno;
}
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
if ( sd == AC_SOCKET_INVALID ) {
/* not connected yet */
int rc = ldap_open_defconn( ld );
if( rc < 0 ) return ld->ld_errno;
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
if( sd == AC_SOCKET_INVALID ) {
ld->ld_errno = LDAP_UNAVAILABLE;
return ld->ld_errno;
}
}
ctx = ld->ld_defconn->lconn_sasl_ctx;
if( ctx == NULL ) {
ld->ld_errno = LDAP_UNAVAILABLE;
return ld->ld_errno;
}
/* (re)set security properties */
sasl_setprop( ctx, SASL_SEC_PROPS,
&ld->ld_options.ldo_sasl_secprops );
ccred.bv_val = NULL;
ccred.bv_len = 0;
do {
saslrc = sasl_client_start( ctx,
mechs,
NULL,
&prompts,
&ccred.bv_val,
&credlen,
&mech );
if( pmech == NULL && mech != NULL ) {
pmech = mech;
if( flags != LDAP_SASL_QUIET ) {
fprintf(stderr,
"SASL/%s authentication started\n",
pmech );
}
}
if( saslrc == SASL_INTERACT ) {
int res;
if( !interact ) break;
res = (interact)( ld, flags, defaults, prompts );
if( res != LDAP_SUCCESS ) {
break;
}
}
} while ( saslrc == SASL_INTERACT );
ccred.bv_len = credlen;
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
ld->ld_errno = sasl_err2ldap( saslrc );
return ld->ld_errno;
}
do {
struct berval *scred;
unsigned credlen;
scred = NULL;
rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
if ( ccred.bv_val != NULL ) {
LDAP_FREE( ccred.bv_val );
ccred.bv_val = NULL;
}
if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
return ld->ld_errno;
}
if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
/* we're done, no need to step */
if( scred ) {
/* but server provided us with data! */
Debug( LDAP_DEBUG_TRACE,
"ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n",
rc, saslrc, scred->bv_len );
ber_bvfree( scred );
return ld->ld_errno = LDAP_LOCAL_ERROR;
}
break;
}
do {
saslrc = sasl_client_step( ctx,
(scred == NULL) ? NULL : scred->bv_val,
(scred == NULL) ? 0 : scred->bv_len,
&prompts,
&ccred.bv_val,
&credlen );
Debug( LDAP_DEBUG_TRACE, "sasl_client_start: %d\n",
saslrc, 0, 0 );
if( saslrc == SASL_INTERACT ) {
int res;
if( !interact ) break;
res = (interact)( ld, flags, defaults, prompts );
if( res != LDAP_SUCCESS ) {
break;
}
}
} while ( saslrc == SASL_INTERACT );
ccred.bv_len = credlen;
ber_bvfree( scred );
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
ld->ld_errno = sasl_err2ldap( saslrc );
return ld->ld_errno;
}
} while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
if ( saslrc != SASL_OK ) {
return ld->ld_errno = sasl_err2ldap( saslrc );
}
/* likely should add a quiet option */
if( flags != LDAP_SASL_QUIET ) {
saslrc = sasl_getprop( ctx, SASL_USERNAME, (void **) &data );
if( saslrc == SASL_OK && data && *data ) {
fprintf( stderr, "SASL username: %s\n", data );
}
saslrc = sasl_getprop( ctx, SASL_REALM, (void **) &data );
if( saslrc == SASL_OK && data && *data ) {
fprintf( stderr, "SASL realm: %s\n", data );
}
}
saslrc = sasl_getprop( ctx, SASL_SSF, (void **) &ssf );
if( saslrc == SASL_OK ) {
if( flags != LDAP_SASL_QUIET ) {
fprintf( stderr, "SASL SSF: %lu\n",
(unsigned long) *ssf );
}
if( ssf && *ssf ) {
if( flags != LDAP_SASL_QUIET ) {
fprintf( stderr, "SASL installing layers\n" );
}
ldap_pvt_sasl_install( ld->ld_sb, ctx );
}
}
return rc;
}
int ldap_pvt_sasl_secprops(
const char *in,
sasl_security_properties_t *secprops )
{
int i;
char **props = ldap_str2charray( in, "," );
unsigned sflags = 0;
int got_sflags = 0;
sasl_ssf_t max_ssf;
int got_max_ssf = 0;
sasl_ssf_t min_ssf;
int got_min_ssf = 0;
unsigned maxbufsize;
int got_maxbufsize = 0;
if( props == NULL || secprops == NULL ) {
return LDAP_PARAM_ERROR;
}
for( i=0; props[i]; i++ ) {
if( !strcasecmp(props[i], "none") ) {
got_sflags++;
} else if( !strcasecmp(props[i], "noplain") ) {
got_sflags++;
sflags |= SASL_SEC_NOPLAINTEXT;
} else if( !strcasecmp(props[i], "noactive") ) {
got_sflags++;
sflags |= SASL_SEC_NOACTIVE;
} else if( !strcasecmp(props[i], "nodict") ) {
got_sflags++;
sflags |= SASL_SEC_NODICTIONARY;
} else if( !strcasecmp(props[i], "forwardsec") ) {
got_sflags++;
sflags |= SASL_SEC_FORWARD_SECRECY;
} else if( !strcasecmp(props[i], "noanonymous")) {
got_sflags++;
sflags |= SASL_SEC_NOANONYMOUS;
} else if( !strcasecmp(props[i], "passcred") ) {
got_sflags++;
sflags |= SASL_SEC_PASS_CREDENTIALS;
} else if( !strncasecmp(props[i],
"minssf=", sizeof("minssf")) )
{
if( isdigit( props[i][sizeof("minssf")] ) ) {
got_max_ssf++;
min_ssf = atoi( &props[i][sizeof("minssf")] );
} else {
return LDAP_NOT_SUPPORTED;
}
} else if( !strncasecmp(props[i],
"maxssf=", sizeof("maxssf")) )
{
if( isdigit( props[i][sizeof("maxssf")] ) ) {
got_max_ssf++;
max_ssf = atoi( &props[i][sizeof("maxssf")] );
} else {
return LDAP_NOT_SUPPORTED;
}
} else if( !strncasecmp(props[i],
"maxbufsize=", sizeof("maxbufsize")) )
{
if( isdigit( props[i][sizeof("maxbufsize")] ) ) {
got_maxbufsize++;
maxbufsize = atoi( &props[i][sizeof("maxbufsize")] );
} else {
return LDAP_NOT_SUPPORTED;
}
} else {
return LDAP_NOT_SUPPORTED;
}
}
if(got_sflags) {
secprops->security_flags = sflags;
}
if(got_min_ssf) {
secprops->min_ssf = min_ssf;
}
if(got_max_ssf) {
secprops->max_ssf = max_ssf;
}
if(got_maxbufsize) {
secprops->maxbufsize = maxbufsize;
}
ldap_charray_free( props );
return LDAP_SUCCESS;
}
int
ldap_int_sasl_config( struct ldapoptions *lo, int option, const char *arg )
{
int rc;
switch( option ) {
case LDAP_OPT_X_SASL_SECPROPS:
rc = ldap_pvt_sasl_secprops( arg, &lo->ldo_sasl_secprops );
if( rc == LDAP_SUCCESS ) return 0;
}
return -1;
}
int
ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
{
if ( ld == NULL )
return -1;
switch ( option ) {
case LDAP_OPT_X_SASL_MECH: {
*(char **)arg = ld->ld_options.ldo_def_sasl_mech
? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_mech ) : NULL;
} break;
case LDAP_OPT_X_SASL_REALM: {
*(char **)arg = ld->ld_options.ldo_def_sasl_realm
? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_realm ) : NULL;
} break;
case LDAP_OPT_X_SASL_AUTHCID: {
*(char **)arg = ld->ld_options.ldo_def_sasl_authcid
? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authcid ) : NULL;
} break;
case LDAP_OPT_X_SASL_AUTHZID: {
*(char **)arg = ld->ld_options.ldo_def_sasl_authzid
? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authzid ) : NULL;
} break;
case LDAP_OPT_X_SASL_SSF: {
int sc;
sasl_ssf_t *ssf;
sasl_conn_t *ctx;
if( ld->ld_defconn == NULL ) {
return -1;
}
ctx = ld->ld_defconn->lconn_sasl_ctx;
if ( ctx == NULL ) {
return -1;
}
sc = sasl_getprop( ctx, SASL_SSF,
(void **) &ssf );
if ( sc != SASL_OK ) {
return -1;
}
*(ber_len_t *)arg = *ssf;
} break;
case LDAP_OPT_X_SASL_SSF_EXTERNAL:
/* this option is write only */
return -1;
case LDAP_OPT_X_SASL_SSF_MIN:
*(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.min_ssf;
break;
case LDAP_OPT_X_SASL_SSF_MAX:
*(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.max_ssf;
break;
case LDAP_OPT_X_SASL_MAXBUFSIZE:
*(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.maxbufsize;
break;
case LDAP_OPT_X_SASL_SECPROPS:
/* this option is write only */
return -1;
default:
return -1;
}
return 0;
}
int
ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
{
if ( ld == NULL )
return -1;
switch ( option ) {
case LDAP_OPT_X_SASL_SSF:
/* This option is read-only */
return -1;
case LDAP_OPT_X_SASL_SSF_EXTERNAL: {
int sc;
sasl_external_properties_t extprops;
sasl_conn_t *ctx;
if( ld->ld_defconn == NULL ) {
return -1;
}
ctx = ld->ld_defconn->lconn_sasl_ctx;
if ( ctx == NULL ) {
return -1;
}
memset(&extprops, 0L, sizeof(extprops));
extprops.ssf = * (ber_len_t *) arg;
sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL,
(void *) &extprops );
if ( sc != SASL_OK ) {
return -1;
}
} break;
case LDAP_OPT_X_SASL_SSF_MIN:
ld->ld_options.ldo_sasl_secprops.min_ssf = *(ber_len_t *)arg;
break;
case LDAP_OPT_X_SASL_SSF_MAX:
ld->ld_options.ldo_sasl_secprops.max_ssf = *(ber_len_t *)arg;
break;
case LDAP_OPT_X_SASL_MAXBUFSIZE:
ld->ld_options.ldo_sasl_secprops.maxbufsize = *(ber_len_t *)arg;
break;
case LDAP_OPT_X_SASL_SECPROPS: {
int sc;
sc = ldap_pvt_sasl_secprops( (char *) arg,
&ld->ld_options.ldo_sasl_secprops );
return sc == LDAP_SUCCESS ? 0 : -1;
}
default:
return -1;
}
return 0;
}
#ifdef LDAP_R_COMPILE
void *ldap_pvt_sasl_mutex_new(void)
{
ldap_pvt_thread_mutex_t *mutex;
mutex = (ldap_pvt_thread_mutex_t *) LDAP_MALLOC(
sizeof(ldap_pvt_thread_mutex_t) );
if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {
return mutex;
}
return NULL;
}
int ldap_pvt_sasl_mutex_lock(void *mutex)
{
return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex )
? SASL_FAIL : SASL_OK;
}
int ldap_pvt_sasl_mutex_unlock(void *mutex)
{
return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex )
? SASL_FAIL : SASL_OK;
}
void ldap_pvt_sasl_mutex_dispose(void *mutex)
{
(void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex );
LDAP_FREE( mutex );
}
#endif
#else
int ldap_int_sasl_init( void )
{ return LDAP_SUCCESS; }
int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
{ return LDAP_SUCCESS; }
int
ldap_int_sasl_bind(
LDAP *ld,
const char *dn,
const char *mechs,
LDAPControl **sctrls,
LDAPControl **cctrls,
unsigned flags,
LDAP_SASL_INTERACT_PROC *interact,
void * defaults )
{ return LDAP_NOT_SUPPORTED; }
#endif /* HAVE_CYRUS_SASL */

View file

@ -135,7 +135,7 @@ next_line( char **bufp, ber_len_t *blenp, char **linep )
return( -1 ); /* fatal error */
}
(void) memcpy( line, linestart, p - linestart );
AC_MEMCPY( line, linestart, p - linestart );
line[ p - linestart - 1 ] = '\0';
*linep = line;
return( strlen( line ));

View file

@ -231,7 +231,7 @@ ldap_parse_result(
if(serverctrls != NULL) *serverctrls = NULL;
/* Find the next result... */
for ( lm = r; lm->lm_chain != NULL; lm = lm->lm_chain ) {
for ( lm = r; lm != NULL; lm = lm->lm_chain ) {
/* skip over entries and references */
if( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE &&

View file

@ -334,7 +334,7 @@ explode_name( const char *name, int notypes, int is_type )
if (( parts[ count-1 ] = (char *)LDAP_CALLOC( 1,
len + 1 )) != NULL )
{
SAFEMEMCPY( parts[ count-1 ], rdn, len );
AC_MEMCPY( parts[ count-1 ], rdn, len );
if( !endquote ) {
/* skip trailing spaces */

View file

@ -104,7 +104,7 @@ ldap_get_entry_controls(
}
/* make a local copy of the BerElement */
SAFEMEMCPY(&be, entry->lm_ber, sizeof(be));
AC_MEMCPY(&be, entry->lm_ber, sizeof(be));
if ( ber_scanf( &be, "{xx" /*}*/ ) == LBER_ERROR ) {
rc = LDAP_DECODING_ERROR;

View file

@ -370,7 +370,7 @@ ldap_build_filter(
*f++ = ' ';
}
slen = strlen( valwords[ i ] );
SAFEMEMCPY( f, valwords[ i ], slen );
AC_MEMCPY( f, valwords[ i ], slen );
f += slen;
}
}
@ -379,17 +379,17 @@ ldap_build_filter(
if ( wordcount > 0 ) {
wordnum = wordcount - 1;
slen = strlen( valwords[ wordnum ] );
SAFEMEMCPY( f, valwords[ wordnum ], slen );
AC_MEMCPY( f, valwords[ wordnum ], slen );
f += slen;
}
} else if ( value != NULL ) {
slen = strlen( value );
SAFEMEMCPY( f, value, slen );
AC_MEMCPY( f, value, slen );
f += slen;
}
} else if ( *p == 'a' && attr != NULL ) {
slen = strlen( attr );
SAFEMEMCPY( f, attr, slen );
AC_MEMCPY( f, attr, slen );
f += slen;
} else {
*f++ = *p;

View file

@ -26,8 +26,10 @@ struct ldapoptions ldap_int_global_options =
#define ATTR_INT 2
#define ATTR_KV 3
#define ATTR_STRING 4
#define ATTR_TLS 5
#define ATTR_URIS 6
#define ATTR_URIS 5
#define ATTR_SASL 6
#define ATTR_TLS 7
struct ol_keyvalue {
const char * key;
@ -59,26 +61,35 @@ static const struct ol_attribute {
offsetof(struct ldapoptions, ldo_defbinddn)},
{0, ATTR_STRING, "BASE", NULL,
offsetof(struct ldapoptions, ldo_defbase)},
{0, ATTR_INT, "PORT", NULL,
{0, ATTR_INT, "PORT", NULL, /* deprecated */
offsetof(struct ldapoptions, ldo_defport)},
/* **** keep this around for backward compatibility */
{0, ATTR_URIS, "HOST", NULL, 1},
/* **** */
{0, ATTR_URIS, "URI", NULL, 0},
{0, ATTR_URIS, "HOST", NULL, 1}, /* deprecated */
{0, ATTR_URIS, "URI", NULL, 0}, /* replaces HOST/URI */
{0, ATTR_BOOL, "REFERRALS", NULL, LDAP_BOOL_REFERRALS},
{0, ATTR_BOOL, "RESTART", NULL, LDAP_BOOL_RESTART},
#ifdef HAVE_CYRUS_SASL
{1, ATTR_STRING, "SASL_MECH", NULL,
offsetof(struct ldapoptions, ldo_def_sasl_mech)},
{1, ATTR_STRING, "SASL_REALM", NULL,
offsetof(struct ldapoptions, ldo_def_sasl_realm)},
{1, ATTR_STRING, "SASL_AUTHCID", NULL,
offsetof(struct ldapoptions, ldo_def_sasl_authcid)},
{1, ATTR_STRING, "SASL_AUTHZID", NULL,
offsetof(struct ldapoptions, ldo_def_sasl_authzid)},
{0, ATTR_SASL, "SASL_SECPROPS", NULL, LDAP_OPT_X_SASL_SECPROPS},
#endif
#ifdef HAVE_TLS
{0, ATTR_TLS, "TLS", NULL, LDAP_OPT_X_TLS},
{0, ATTR_TLS, "TLS_CERT", NULL, LDAP_OPT_X_TLS_CERTFILE},
{0, ATTR_TLS, "TLS_KEY", NULL, LDAP_OPT_X_TLS_KEYFILE},
{1, ATTR_TLS, "TLS_CERT", NULL, LDAP_OPT_X_TLS_CERTFILE},
{1, ATTR_TLS, "TLS_KEY", NULL, LDAP_OPT_X_TLS_KEYFILE},
{0, ATTR_TLS, "TLS_CACERT", NULL, LDAP_OPT_X_TLS_CACERTFILE},
{0, ATTR_TLS, "TLS_CACERTDIR",NULL, LDAP_OPT_X_TLS_CACERTDIR},
{0, ATTR_TLS, "TLS_REQCERT", NULL, LDAP_OPT_X_TLS_REQUIRE_CERT},
#ifdef HAVE_CYRUS_SASL
{0, ATTR_INT, "SASL_MINSSF", NULL,
offsetof(struct ldapoptions, ldo_sasl_minssf)},
{0, ATTR_INT, "SASL_MAXSSF", NULL,
offsetof(struct ldapoptions, ldo_sasl_maxssf)},
{1, ATTR_TLS, "TLS_REQCERT", NULL, LDAP_OPT_X_TLS_REQUIRE_CERT},
{1, ATTR_TLS, "TLS_RANDFILE", NULL, LDAP_OPT_X_TLS_RANDOM_FILE},
#endif
{0, ATTR_NONE, NULL, NULL, 0}
};
@ -200,11 +211,6 @@ static void openldap_ldap_init_w_conf(
if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
* (char**) p = LDAP_STRDUP(opt);
break;
case ATTR_TLS:
#ifdef HAVE_TLS
ldap_pvt_tls_config( gopts, attrs[i].offset, opt );
#endif
break;
case ATTR_URIS:
if (attrs[i].offset == 0) {
ldap_set_option( NULL, LDAP_OPT_URI, opt );
@ -212,7 +218,18 @@ static void openldap_ldap_init_w_conf(
ldap_set_option( NULL, LDAP_OPT_HOST_NAME, opt );
}
break;
case ATTR_SASL:
#ifdef HAVE_CYRUS_SASL
ldap_int_sasl_config( gopts, attrs[i].offset, opt );
#endif
break;
case ATTR_TLS:
#ifdef HAVE_TLS
ldap_int_tls_config( gopts, attrs[i].offset, opt );
#endif
break;
}
break;
}
}
@ -334,11 +351,6 @@ static void openldap_ldap_init_w_env(
* (char**) p = LDAP_STRDUP(value);
}
break;
case ATTR_TLS:
#ifdef HAVE_TLS
ldap_pvt_tls_config( gopts, attrs[i].offset, value );
#endif
break;
case ATTR_URIS:
if (attrs[i].offset == 0) {
ldap_set_option( NULL, LDAP_OPT_URI, value );
@ -346,6 +358,16 @@ static void openldap_ldap_init_w_env(
ldap_set_option( NULL, LDAP_OPT_HOST_NAME, value );
}
break;
case ATTR_SASL:
#ifdef HAVE_CYRUS_SASL
ldap_int_sasl_config( gopts, attrs[i].offset, value );
#endif
break;
case ATTR_TLS:
#ifdef HAVE_TLS
ldap_int_tls_config( gopts, attrs[i].offset, value );
#endif
break;
}
}
}
@ -381,34 +403,57 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
LDAP_BOOL_SET(gopts, LDAP_BOOL_REFERRALS);
#ifdef HAVE_CYRUS_SASL
gopts->ldo_def_sasl_mech = NULL;
gopts->ldo_def_sasl_realm = NULL;
gopts->ldo_def_sasl_authcid = NULL;
gopts->ldo_def_sasl_authzid = NULL;
memset( &gopts->ldo_sasl_secprops, '\0', sizeof(gopts->ldo_sasl_secprops) );
gopts->ldo_sasl_secprops.max_ssf = INT_MAX;
gopts->ldo_sasl_secprops.maxbufsize = 65536;
gopts->ldo_sasl_secprops.security_flags = SASL_SEC_NOPLAINTEXT|SASL_SEC_NOANONYMOUS;
#endif
#ifdef HAVE_TLS
gopts->ldo_tls_ctx = NULL;
#endif
#ifdef HAVE_CYRUS_SASL
gopts->ldo_sasl_minssf = 0;
gopts->ldo_sasl_maxssf = INT_MAX;
#endif
gopts->ldo_valid = LDAP_INITIALIZED;
return;
}
#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
|| defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
char * ldap_int_hostname = "localhost";
#endif
void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
{
if ( gopts->ldo_valid == LDAP_INITIALIZED ) {
return;
}
#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
|| defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
{
char hostbuf[MAXHOSTNAMELEN+1];
if( gethostname( hostbuf, MAXHOSTNAMELEN ) == 0 ) {
hostbuf[MAXHOSTNAMELEN] = '\0';
ldap_int_hostname = hostbuf;
}
}
#endif
ldap_int_utils_init();
#ifdef HAVE_TLS
ldap_pvt_tls_init();
#endif
#ifdef HAVE_CYRUS_SASL
ldap_pvt_sasl_init();
#endif
ldap_int_sasl_init();
if ( ldap_int_tblsize == 0 )
ldap_int_ip_init();
@ -419,6 +464,21 @@ void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
return;
}
#ifdef HAVE_CYRUS_SASL
{
/* set authentication identity to current user name */
char *user = getenv("USER");
if( user == NULL ) user = getenv("USERNAME");
if( user == NULL ) user = getenv("LOGNAME");
if( user != NULL ) {
/* this value is leaked, need at_exit() handler */
gopts->ldo_def_sasl_authcid = LDAP_STRDUP( user );
}
}
#endif
openldap_ldap_init_w_sysconf(LDAP_CONF_FILE);
openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);

View file

@ -275,7 +275,7 @@ ldap_get_kerberosv4_credentials(
}
*len = ktxt.length;
memcpy( cred, ktxt.dat, ktxt.length );
AC_MEMCPY( cred, ktxt.dat, ktxt.length );
return( cred );
}

View file

@ -18,6 +18,11 @@
#include "../liblber/lber-int.h"
#ifdef HAVE_CYRUS_SASL
/* the need for this should be removed */
#include <sasl.h>
#endif
/*
* Support needed if the library is running in the kernel
*/
@ -120,7 +125,17 @@ struct ldapoptions {
LDAPURLDesc *ldo_defludp;
int ldo_defport;
char* ldo_defbase;
char* ldo_defbinddn; /* simple bind dn */
char* ldo_defbinddn; /* bind dn */
#ifdef HAVE_CYRUS_SASL
char* ldo_def_sasl_mech; /* SASL Mechanism(s) */
char* ldo_def_sasl_realm; /* SASL realm */
char* ldo_def_sasl_authcid; /* SASL authentication identity */
char* ldo_def_sasl_authzid; /* SASL authorization identity */
/* SASL Security Properties */
struct sasl_security_properties ldo_sasl_secprops;
#endif
#ifdef LDAP_CONNECTIONLESS
int ldo_cldaptries; /* connectionless search retry count */
@ -140,10 +155,6 @@ struct ldapoptions {
/* tls context */
void *ldo_tls_ctx;
int ldo_tls_mode;
#endif
#ifdef HAVE_CYRUS_SASL
sasl_ssf_t ldo_sasl_minssf;
sasl_ssf_t ldo_sasl_maxssf;
#endif
LDAP_BOOLEANS ldo_booleans; /* boolean options */
};
@ -164,7 +175,8 @@ typedef struct ldap_server {
* structure for representing an LDAP server connection
*/
typedef struct ldap_conn {
Sockbuf *lconn_sb;
Sockbuf *lconn_sb;
void *lconn_sasl_ctx;
int lconn_refcnt;
time_t lconn_lastused; /* time */
int lconn_rebind_inprogress; /* set if rebind in progress */
@ -266,7 +278,8 @@ struct ldap {
#define ld_cctrls ld_options.ldo_cctrls
#define ld_rebindproc ld_options.ldo_rebindproc
#define ld_version ld_options.ldo_version
#define ld_version ld_options.ldo_version
char *ld_host;
int ld_port;
@ -298,22 +311,20 @@ struct ldap {
LDAPConn *ld_defconn; /* default connection */
LDAPConn *ld_conns; /* list of server connections */
void *ld_selectinfo; /* platform specifics for select */
#ifdef HAVE_CYRUS_SASL
sasl_conn_t *ld_sasl_context;
#endif /* HAVE_CYRUS_SASL */
};
#define LDAP_VALID(ld) ( (ld)->ld_valid == LDAP_VALID_SESSION )
#if defined(HAVE_RES_QUERY) && defined(LDAP_R_COMPILE)
#include <ldap_pvt_thread.h>
extern ldap_pvt_thread_mutex_t ldap_int_resolv_mutex;
LDAP_V ( ldap_pvt_thread_mutex_t ) ldap_int_resolv_mutex;
#endif /* HAVE_RES_QUERY && LDAP_R_COMPILE */
/*
* in init.c
*/
LDAP_F ( struct ldapoptions ) ldap_int_global_options;
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_global_options LDAP_P((
struct ldapoptions *, int *));
@ -371,12 +382,6 @@ LDAP_F (int) ldap_int_put_controls LDAP_P((
LDAPControl *const *ctrls,
BerElement *ber ));
LDAP_F( int )
ldap_int_create_control LDAP_P((
const char *requestOID,
BerElement *ber,
int iscritical,
LDAPControl **ctrlp ));
/*
* in dsparse.c
@ -400,16 +405,20 @@ LDAP_F (char *) ldap_get_kerberosv4_credentials LDAP_P((
* in open.c
*/
LDAP_F (int) ldap_open_defconn( LDAP *ld );
LDAP_F (int) open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srvlist, char **krbinstancep, int async );
LDAP_F (int) ldap_int_open_connection( LDAP *ld,
LDAPConn *conn, LDAPURLDesc *srvlist, int async );
/*
* in os-ip.c
*/
LDAP_F (int) ldap_int_tblsize;
LDAP_F (int) ldap_int_timeval_dup( struct timeval **dest, const struct timeval *tm );
LDAP_F (int) ldap_connect_to_host( LDAP *ld, Sockbuf *sb, const char *host, unsigned long address, int port, int async );
LDAP_F (int) ldap_connect_to_host( LDAP *ld, Sockbuf *sb,
int proto, const char *host, unsigned long address, int port,
int async );
#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
LDAP_V (char *) ldap_int_hostname;
LDAP_F (char *) ldap_host_connected_to( Sockbuf *sb );
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
@ -427,7 +436,8 @@ LDAP_F (int) ldap_is_write_ready( LDAP *ld, Sockbuf *sb );
* in os-local.c
*/
#ifdef LDAP_PF_UNIX
LDAP_F (int) ldap_connect_to_path( LDAP *ld, Sockbuf *sb, const char *path, int async );
LDAP_F (int) ldap_connect_to_path( LDAP *ld, Sockbuf *sb, int proto,
const char *path, int async );
#endif /* LDAP_PF_UNIX */
/*
@ -518,6 +528,38 @@ LDAP_F (char *) ldap_url_list2urls LDAP_P((
LDAP_F (void) ldap_free_urllist LDAP_P((
LDAPURLDesc *ludlist ));
/*
* in cyrus.c
*/
LDAP_F (int) ldap_int_sasl_init LDAP_P(( void ));
LDAP_F (int) ldap_int_sasl_open LDAP_P((
LDAP *ld, LDAPConn *conn,
const char* host, ber_len_t ssf ));
LDAP_F (int) ldap_int_sasl_close LDAP_P(( LDAP *ld, LDAPConn *conn ));
LDAP_F (int) ldap_int_sasl_get_option LDAP_P(( LDAP *ld,
int option, void *arg ));
LDAP_F (int) ldap_int_sasl_set_option LDAP_P(( LDAP *ld,
int option, void *arg ));
LDAP_F (int) ldap_int_sasl_config LDAP_P(( struct ldapoptions *lo,
int option, const char *arg ));
LDAP_F (int) ldap_int_sasl_bind LDAP_P((
struct ldap *ld,
const char *,
const char *,
LDAPControl **, LDAPControl **,
/* should be passed in client controls */
unsigned flags,
LDAP_SASL_INTERACT_PROC *interact,
void *defaults ));
/*
* in tls.c
*/
LDAP_F (int) ldap_int_tls_config LDAP_P(( struct ldapoptions *lo, int option, const char *arg ));
LDAP_END_DECL

View file

@ -7,9 +7,6 @@
# This file should be world readable.
#BASE dc=OpenLDAP, dc=Org
#HOST ldap.openldap.org
#PORT 389
#URI ldap://ldap.openldap.org ldap://ldap-master.openldap.org:666
#SIZELIMIT 12

View file

@ -163,6 +163,10 @@ SOURCE=.\controls.c
# End Source File
# Begin Source File
SOURCE=.\cyrus.c
# End Source File
# Begin Source File
SOURCE=.\delete.c
# End Source File
# Begin Source File

View file

@ -26,14 +26,15 @@
int ldap_open_defconn( LDAP *ld )
{
if (( ld->ld_defconn = ldap_new_connection( ld, ld->ld_options.ldo_defludp, 1,1,NULL )) == NULL )
{
ld->ld_defconn = ldap_new_connection( ld,
ld->ld_options.ldo_defludp, 1, 1, NULL );
if( ld->ld_defconn == NULL ) {
ld->ld_errno = LDAP_SERVER_DOWN;
return -1;
}
++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
return 0;
}
@ -91,7 +92,7 @@ ldap_create( LDAP **ldp )
ldap_int_initialize(gopts, NULL);
}
Debug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "ldap_create\n", 0, 0, 0 );
#ifdef HAVE_WINSOCK2
{ WORD wVersionRequested;
@ -134,15 +135,25 @@ ldap_create( LDAP **ldp )
}
/* copy the global options */
memcpy(&ld->ld_options, gopts, sizeof(ld->ld_options));
AC_MEMCPY(&ld->ld_options, gopts, sizeof(ld->ld_options));
ld->ld_valid = LDAP_VALID_SESSION;
/* but not pointers to malloc'ed items */
ld->ld_options.ldo_defludp = NULL;
ld->ld_options.ldo_sctrls = NULL;
ld->ld_options.ldo_cctrls = NULL;
#ifdef HAVE_CYRUS_SASL
ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech
? LDAP_STRDUP( gopts->ldo_def_sasl_mech ) : NULL;
ld->ld_options.ldo_def_sasl_realm = gopts->ldo_def_sasl_realm
? LDAP_STRDUP( gopts->ldo_def_sasl_realm ) : NULL;
ld->ld_options.ldo_def_sasl_authcid = gopts->ldo_def_sasl_authcid
? LDAP_STRDUP( gopts->ldo_def_sasl_authcid ) : NULL;
ld->ld_options.ldo_def_sasl_authzid = gopts->ldo_def_sasl_authzid
? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL;
#endif
ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
if ( ld->ld_options.ldo_defludp == NULL ) {
@ -179,7 +190,7 @@ ldap_create( LDAP **ldp )
*
* Example:
* LDAP *ld;
* ld = ldap_open( host, port );
* ld = ldap_init( host, port );
*/
LDAP *
ldap_init( LDAP_CONST char *defhost, int defport )
@ -250,8 +261,9 @@ ldap_start_tls_s ( LDAP *ld,
if (ldap_pvt_tls_inplace(lc->lconn_sb) != 0)
return LDAP_OPERATIONS_ERROR;
/* XXYYZ: this initiates operaton only on default connection! */
rc = ldap_extended_operation_s(ld, LDAP_EXOP_START_TLS,
NULL, serverctrls, clientctrls, &rspoid, &rspdata);
NULL, serverctrls, clientctrls, &rspoid, &rspdata);
if (rc != LDAP_SUCCESS)
return rc;
@ -270,14 +282,21 @@ ldap_start_tls_s ( LDAP *ld,
}
int
open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
char **krbinstancep, int async )
ldap_int_open_connection(
LDAP *ld,
LDAPConn *conn,
LDAPURLDesc *srv,
int async )
{
int rc = -1;
#ifdef HAVE_CYRUS_SASL
char *sasl_host = NULL;
int sasl_ssf = 0;
#endif
int port;
long addr;
Debug( LDAP_DEBUG_TRACE, "open_ldap_connection\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "ldap_int_open_connection\n", 0, 0, 0 );
port = srv->lud_port;
if (port == 0)
@ -290,62 +309,78 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
switch ( ldap_pvt_url_scheme2proto( srv->lud_scheme ) ) {
case LDAP_PROTO_TCP:
rc = ldap_connect_to_host( ld, sb, srv->lud_host,
addr, port, async );
if ( rc == -1 )
return rc;
ber_sockbuf_add_io( sb, &ber_sockbuf_io_tcp,
rc = ldap_connect_to_host( ld, conn->lconn_sb, 0,
srv->lud_host, addr, port, async );
if ( rc == -1 ) return rc;
ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_tcp,
LBER_SBIOD_LEVEL_PROVIDER, NULL );
#ifdef HAVE_CYRUS_SASL
sasl_host = ldap_host_connected_to( conn->lconn_sb );
#endif
break;
case LDAP_PROTO_UDP:
rc = ldap_connect_to_host( ld, sb, srv->lud_host,
addr, port, async );
if ( rc == -1 )
return rc;
ber_sockbuf_add_io( sb, &ber_sockbuf_io_udp,
rc = ldap_connect_to_host( ld, conn->lconn_sb, 1,
srv->lud_host, addr, port, async );
if ( rc == -1 ) return rc;
ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_udp,
LBER_SBIOD_LEVEL_PROVIDER, NULL );
break;
case LDAP_PROTO_IPC:
#ifdef LDAP_PF_UNIX
/* only IPC mechanism supported is PF_UNIX */
rc = ldap_connect_to_path( ld, sb, srv->lud_host,
async );
if ( rc == -1 )
return rc;
ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd,
#ifdef LDAP_PF_LOCAL
/* only IPC mechanism supported is PF_LOCAL (PF_UNIX) */
rc = ldap_connect_to_path( ld, conn->lconn_sb, 0,
srv->lud_host, async );
if ( rc == -1 ) return rc;
ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_fd,
LBER_SBIOD_LEVEL_PROVIDER, NULL );
#ifdef HAVE_CYRUS_SASL
sasl_host = ldap_host_connected_to( conn->lconn_sb );
sasl_ssf = LDAP_PVT_SASL_LOCAL_SSF;
#endif
break;
#endif /* LDAP_PF_UNIX */
#endif /* LDAP_PF_LOCAL */
default:
return -1;
break;
}
ber_sockbuf_add_io( sb, &ber_sockbuf_io_readahead,
#ifdef HAVE_CYRUS_SASL
if( sasl_host != NULL ) {
ldap_int_sasl_open( ld, conn, sasl_host, sasl_ssf );
}
#endif
ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_readahead,
LBER_SBIOD_LEVEL_PROVIDER, NULL );
#ifdef LDAP_DEBUG
ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, INT_MAX, NULL );
ber_sockbuf_add_io( conn->lconn_sb, &ber_sockbuf_io_debug,
INT_MAX, NULL );
#endif
#ifdef HAVE_TLS
if (ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
strcmp( srv->lud_scheme, "ldaps" ) == 0 )
{
rc = ldap_pvt_tls_start( ld, sb, ld->ld_options.ldo_tls_ctx );
rc = ldap_pvt_tls_start( ld, conn->lconn_sb,
ld->ld_options.ldo_tls_ctx );
if (rc != LDAP_SUCCESS)
return rc;
}
#endif
if ( krbinstancep != NULL ) {
if ( conn->lconn_krbinstance != NULL ) {
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
char *c;
if (( *krbinstancep = ldap_host_connected_to( sb )) != NULL &&
( c = strchr( *krbinstancep, '.' )) != NULL ) {
conn->lconn_krbinstance = ldap_host_connected_to( conn->sb );
if( conn->lconn_krbinstance != NULL &&
( c = strchr( conn->lconn_krbinstance, '.' )) != NULL ) {
*c = '\0';
}
#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
*krbinstancep = NULL;
conn->lconn_krbinstance = NULL;
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
}

View file

@ -285,7 +285,7 @@ ldap_get_option(
return LDAP_OPT_SUCCESS;
#endif
#ifdef HAVE_CYRUS_SASL
if ( ldap_pvt_sasl_get_option(ld, option, outvalue ) == 0 )
if ( ldap_int_sasl_get_option(ld, option, outvalue ) == 0 )
return LDAP_OPT_SUCCESS;
#endif
/* bad param */
@ -582,7 +582,7 @@ ldap_set_option(
return LDAP_OPT_SUCCESS;
#endif
#ifdef HAVE_CYRUS_SASL
if ( ldap_pvt_sasl_set_option( ld, option, (void *)invalue ) == 0 )
if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 )
return LDAP_OPT_SUCCESS;
#endif
/* bad param */

View file

@ -74,7 +74,7 @@ ldap_int_timeval_dup( struct timeval **dest, const struct timeval *src )
return 1;
}
SAFEMEMCPY( (char *) new, (const char *) src, sizeof(struct timeval));
AC_MEMCPY( (char *) new, (const char *) src, sizeof(struct timeval));
*dest = new;
return 0;
@ -95,9 +95,9 @@ ldap_pvt_ndelay_off(LDAP *ld, int fd)
}
static ber_socket_t
ldap_pvt_socket(LDAP *ld, int family)
ldap_int_socket(LDAP *ld, int family, int type )
{
ber_socket_t s = socket(family, SOCK_STREAM, 0);
ber_socket_t s = socket(family, type, 0);
osip_debug(ld, "ldap_new_socket: %d\n",s,0,0);
return ( s );
}
@ -110,22 +110,23 @@ ldap_pvt_close_socket(LDAP *ld, int s)
}
static int
ldap_pvt_prepare_socket(LDAP *ld, int fd)
ldap_int_prepare_socket(LDAP *ld, int s, int proto )
{
osip_debug(ld, "ldap_prepare_socket: %d\n",fd,0,0);
osip_debug(ld, "ldap_prepare_socket: %d\n", s,0,0);
#ifdef TCP_NODELAY
{
int dummy = 1;
if ( setsockopt( fd, IPPROTO_TCP, TCP_NODELAY,
(char*) &dummy, sizeof(dummy) ) == AC_SOCKET_ERROR )
{
osip_debug(ld, "ldap_prepare_socket: "
"setsockopt(%d, TCP_NODELAY) failed (ignored).\n",
fd, 0, 0);
if( proto = LDAP_PROTO_TCP ) {
int dummy = 1;
if ( setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
(char*) &dummy, sizeof(dummy) ) == AC_SOCKET_ERROR )
{
osip_debug(ld, "ldap_prepare_socket: "
"setsockopt(%d, TCP_NODELAY) failed (ignored).\n",
s, 0, 0);
}
}
}
#endif
return 0;
}
@ -183,7 +184,9 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s)
#undef TRACE
static int
ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr *sin, socklen_t addrlen, int async)
ldap_pvt_connect(LDAP *ld, ber_socket_t s,
struct sockaddr *sin, socklen_t addrlen,
int async)
{
struct timeval tv, *opt_tv=NULL;
fd_set wfds, *z=NULL;
@ -275,8 +278,10 @@ ldap_pvt_inet_aton( const char *host, struct in_addr *in)
int
ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
unsigned long address, int port, int async)
ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
int proto,
const char *host,
unsigned long address, int port, int async)
{
struct sockaddr_in sin;
struct in_addr in;
@ -290,12 +295,13 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
if (host != NULL) {
#ifdef HAVE_GETADDRINFO
char serv[7];
char serv[7];
struct addrinfo hints, *res, *sai;
memset( &hints, '\0', sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_socktype = proto == LDAP_PROTO_UDP
? SOCK_DGRAM : SOCK_STREAM;
snprintf(serv, sizeof serv, "%d", ntohs(port));
if ( getaddrinfo(host, serv, &hints, &res) ) {
@ -305,11 +311,18 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
sai = res;
rc = -1;
do {
s = ldap_pvt_socket( ld, sai->ai_family );
/* we assume AF_x and PF_x are equal for all x */
s = ldap_int_socket( ld, sai->ai_family,
proto == LDAP_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM );
if ( s == -1 ) {
continue;
}
if ( ldap_int_prepare_socket(ld, s, proto ) == -1 ) {
ldap_pvt_close_socket(ld, s);
break;
}
switch (sai->ai_family) {
#ifdef LDAP_PF_INET6
case AF_INET6: {
@ -330,6 +343,7 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
addr, serv, 0);
} break;
}
rc = ldap_pvt_connect(ld, s, sai->ai_addr, sai->ai_addrlen, async);
if ( (rc == 0) || (rc == -2) ) {
ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
@ -363,15 +377,15 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
rc = s = -1;
for ( i = 0; !use_hp || (hp->h_addr_list[i] != 0); ++i, rc = -1 ) {
s = ldap_pvt_socket( ld, AF_INET );
s = ldap_int_socket( ld, PF_INET,
proto == LDAP_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM );
if ( s == -1 ) {
/* use_hp ? continue : break; */
break;
}
if ( ldap_pvt_prepare_socket(ld, s) == -1 ) {
if ( ldap_int_prepare_socket( ld, s, proto ) == -1 ) {
ldap_pvt_close_socket(ld, s);
/* use_hp ? continue : break; */
break;
}
@ -380,12 +394,14 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
sin.sin_port = port;
p = (char *)&sin.sin_addr;
q = use_hp ? (char *)hp->h_addr_list[i] : (char *)&address;
SAFEMEMCPY(p, q, sizeof(sin.sin_addr) );
AC_MEMCPY(p, q, sizeof(sin.sin_addr) );
osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n",
inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),0);
rc = ldap_pvt_connect(ld, s, (struct sockaddr *)&sin, sizeof(struct sockaddr_in), async);
rc = ldap_pvt_connect(ld, s,
(struct sockaddr *)&sin, sizeof(struct sockaddr_in),
async);
if ( (rc == 0) || (rc == -2) ) {
ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
@ -401,27 +417,28 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
return rc;
}
#if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND ) || defined( HAVE_TLS ) || defined( HAVE_CYRUS_SASL )
#if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND ) \
|| defined( HAVE_TLS ) || defined( HAVE_CYRUS_SASL )
char *
ldap_host_connected_to( Sockbuf *sb )
{
struct hostent *hp;
socklen_t len;
struct sockaddr sa;
char *addr;
struct hostent *hp;
socklen_t len;
struct sockaddr sa;
char *addr;
char *host;
/* buffers for gethostbyaddr_r */
struct hostent he_buf;
int local_h_errno;
struct hostent he_buf;
int local_h_errno;
char *ha_buf=NULL;
ber_socket_t sd;
#define DO_RETURN(x) if (ha_buf) LDAP_FREE(ha_buf); return (x);
ber_socket_t sd;
(void)memset( (char *)&sa, '\0', sizeof( struct sockaddr ));
len = sizeof( sa );
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
if ( getpeername( sd, (struct sockaddr *)&sa, &len ) == -1 ) {
if ( getpeername( sd, &sa, &len ) == -1 ) {
return( NULL );
}
@ -432,6 +449,10 @@ ldap_host_connected_to( Sockbuf *sb )
*/
switch (sa.sa_family) {
#ifdef LDAP_PF_LOCAL
case AF_LOCAL:
return LDAP_STRDUP( ldap_int_hostname );
#endif
#ifdef LDAP_PF_INET6
case AF_INET6:
addr = (char *) &((struct sockaddr_in6 *)&sa)->sin6_addr;
@ -441,25 +462,37 @@ ldap_host_connected_to( Sockbuf *sb )
case AF_INET:
addr = (char *) &((struct sockaddr_in *)&sa)->sin_addr;
len = sizeof( struct in_addr );
{
struct sockaddr_in localhost;
localhost.sin_addr.s_addr = htonl( INADDR_ANY );
if( memcmp ( &localhost.sin_addr,
&((struct sockaddr_in *)&sa)->sin_addr,
sizeof(localhost.sin_addr) ) == 0 )
{
return LDAP_STRDUP( ldap_int_hostname );
}
}
break;
default:
return( NULL );
break;
}
host = NULL;
if ((ldap_pvt_gethostbyaddr_a( addr, len,
sa.sa_family, &he_buf, &ha_buf,
&hp,&local_h_errno ) ==0 ) && (hp != NULL) )
&hp,&local_h_errno ) == 0 ) &&
(hp != NULL) && ( hp->h_name != NULL ) )
{
if ( hp->h_name != NULL ) {
char *host = LDAP_STRDUP( hp->h_name );
DO_RETURN( host );
}
host = LDAP_STRDUP( hp->h_name );
}
DO_RETURN( NULL );
LDAP_FREE( ha_buf );
return host;
}
#undef DO_RETURN
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND || HAVE_TLS */

View file

@ -13,7 +13,7 @@
#include "portable.h"
#ifdef LDAP_PF_UNIX
#ifdef LDAP_PF_LOCAL
#include <stdio.h>
@ -65,7 +65,7 @@ ldap_pvt_ndelay_off(LDAP *ld, int fd)
static ber_socket_t
ldap_pvt_socket(LDAP *ld)
{
ber_socket_t s = socket(AF_UNIX, SOCK_STREAM, 0);
ber_socket_t s = socket(PF_LOCAL, SOCK_STREAM, 0);
oslocal_debug(ld, "ldap_new_socket: %d\n",s,0,0);
return ( s );
}
@ -203,7 +203,7 @@ ldap_connect_to_path(LDAP *ld, Sockbuf *sb, const char *path, int async)
oslocal_debug(ld, "ldap_connect_to_path: Trying %s\n", path, 0, 0);
memset( &server, '\0', sizeof(server) );
server.sun_family = AF_UNIX;
server.sun_family = AF_LOCAL;
strcpy( server.sun_path, path );
rc = ldap_pvt_connect(ld, s, &server, async);
@ -217,4 +217,4 @@ ldap_connect_to_path(LDAP *ld, Sockbuf *sb, const char *path, int async)
}
#else
static int dummy;
#endif /* LDAP_PF_UNIX */
#endif /* LDAP_PF_LOCAL */

View file

@ -105,7 +105,7 @@ ldap_parse_reference(
}
/* make a private copy of BerElement */
SAFEMEMCPY(&be, ref->lm_ber, sizeof(be));
AC_MEMCPY(&be, ref->lm_ber, sizeof(be));
if ( ber_scanf( &be, "{v" /*}*/, &refs ) == LBER_ERROR ) {
rc = LDAP_DECODING_ERROR;

View file

@ -256,9 +256,7 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
if ( connect ) {
for ( srv = srvlist; srv != NULL; srv = srv->lud_next ) {
if ( open_ldap_connection( ld, lc->lconn_sb,
srv, &lc->lconn_krbinstance, 0 ) != -1 )
{
if ( ldap_int_open_connection( ld, lc, srv, 0 ) != -1 ) {
break;
}
}
@ -396,6 +394,8 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
ber_free( lc->lconn_ber, 1 );
}
ldap_int_sasl_close( ld, lc );
prevlc = NULL;
for ( tmplc = ld->ld_conns; tmplc != NULL;
tmplc = tmplc->lconn_next ) {

View file

@ -27,6 +27,7 @@
#include "portable.h"
#include <stdlib.h>
#include <stdio.h>
#include <ac/socket.h>
@ -345,367 +346,6 @@ ldap_parse_sasl_bind_result(
return( ld->ld_errno );
}
#ifdef HAVE_CYRUS_SASL
/*
* Various Cyrus SASL related stuff.
*/
#define MAX_BUFF_SIZE 65536
#define MIN_BUFF_SIZE 4096
static char *
array2str( char **a )
{
char *s, **v, *p;
int len = 0;
for ( v = a; *v != NULL; v++ ) {
len += strlen( *v ) + 1; /* for a space */
}
if ( len == 0 ) {
return NULL;
}
s = LDAP_MALLOC ( len ); /* last space holds \0 */
if ( s == NULL ) {
return NULL;
}
p = s;
for ( v = a; *v != NULL; v++ ) {
int len;
if ( v != a ) {
strncpy( p, " ", 1 );
++p;
}
len = strlen( *v );
strncpy( p, *v, len );
p += len;
}
*p = '\0';
return s;
}
int ldap_pvt_sasl_init( void )
{
/* XXX not threadsafe */
static int sasl_initialized = 0;
if ( sasl_initialized ) {
return 0;
}
#ifndef CSRIMALLOC
sasl_set_alloc( ber_memalloc, ber_memcalloc, ber_memrealloc, ber_memfree );
#endif /* CSRIMALLOC */
if ( sasl_client_init( NULL ) == SASL_OK ) {
sasl_initialized = 1;
return 0;
}
return -1;
}
/*
* SASL encryption support for LBER Sockbufs
*/
struct sb_sasl_data {
sasl_conn_t *sasl_context;
Sockbuf_Buf sec_buf_in;
Sockbuf_Buf buf_in;
Sockbuf_Buf buf_out;
};
static int
sb_sasl_setup( Sockbuf_IO_Desc *sbiod, void *arg )
{
struct sb_sasl_data *p;
assert( sbiod != NULL );
p = LBER_MALLOC( sizeof( *p ) );
if ( p == NULL )
return -1;
p->sasl_context = (sasl_conn_t *)arg;
ber_pvt_sb_buf_init( &p->sec_buf_in );
ber_pvt_sb_buf_init( &p->buf_in );
ber_pvt_sb_buf_init( &p->buf_out );
if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, MIN_BUFF_SIZE ) < 0 ) {
errno = ENOMEM;
return -1;
}
sbiod->sbiod_pvt = p;
return 0;
}
static int
sb_sasl_remove( Sockbuf_IO_Desc *sbiod )
{
struct sb_sasl_data *p;
assert( sbiod != NULL );
p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
ber_pvt_sb_buf_destroy( &p->sec_buf_in );
ber_pvt_sb_buf_destroy( &p->buf_in );
ber_pvt_sb_buf_destroy( &p->buf_out );
LBER_FREE( p );
sbiod->sbiod_pvt = NULL;
return 0;
}
static ber_len_t
sb_sasl_pkt_length( const char *buf, int debuglevel )
{
ber_len_t size;
long tmp;
assert( buf != NULL );
tmp = *((long *)buf);
size = ntohl( tmp );
if ( size > MAX_BUFF_SIZE ) {
/* somebody is trying to mess me up. */
ber_log_printf( LDAP_DEBUG_ANY, debuglevel,
"sb_sasl_pkt_length: received illegal packet length "
"of %lu bytes\n", (unsigned long)size );
size = 16; /* this should lead to an error. */
}
return size + 4; /* include the size !!! */
}
/* Drop a processed packet from the input buffer */
static void
sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel )
{
ber_slen_t len;
len = sec_buf_in->buf_ptr - sec_buf_in->buf_end;
if ( len > 0 )
memmove( sec_buf_in->buf_base, sec_buf_in->buf_base +
sec_buf_in->buf_end, len );
if ( len >= 4 ) {
sec_buf_in->buf_end = sb_sasl_pkt_length( sec_buf_in->buf_base,
debuglevel);
}
else {
sec_buf_in->buf_end = 0;
}
sec_buf_in->buf_ptr = len;
}
static ber_slen_t
sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
struct sb_sasl_data *p;
ber_slen_t ret, bufptr;
assert( sbiod != NULL );
assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
/* Are there anything left in the buffer? */
ret = ber_pvt_sb_copy_out( &p->buf_in, buf, len );
bufptr = ret;
len -= ret;
if ( len == 0 )
return bufptr;
ber_pvt_sb_buf_destroy( &p->buf_in );
/* Read the length of the packet */
while ( p->sec_buf_in.buf_ptr < 4 ) {
ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base,
4 - p->sec_buf_in.buf_ptr );
#ifdef EINTR
if ( ( ret < 0 ) && ( errno == EINTR ) )
continue;
#endif
if ( ret <= 0 )
return ret;
p->sec_buf_in.buf_ptr += ret;
}
/* The new packet always starts at p->sec_buf_in.buf_base */
ret = sb_sasl_pkt_length( p->sec_buf_in.buf_base,
sbiod->sbiod_sb->sb_debug );
/* Grow the packet buffer if neccessary */
if ( ( p->sec_buf_in.buf_size < ret ) &&
ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 ) {
errno = ENOMEM;
return -1;
}
p->sec_buf_in.buf_end = ret;
/* Did we read the whole encrypted packet? */
while ( p->sec_buf_in.buf_ptr < p->sec_buf_in.buf_end ) {
/* No, we have got only a part of it */
ret = p->sec_buf_in.buf_end - p->sec_buf_in.buf_ptr;
ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
p->sec_buf_in.buf_ptr, ret );
#ifdef EINTR
if ( ( ret < 0 ) && ( errno == EINTR ) )
continue;
#endif
if ( ret <= 0 )
return ret;
p->sec_buf_in.buf_ptr += ret;
}
/* Decode the packet */
ret = sasl_decode( p->sasl_context, p->sec_buf_in.buf_base,
p->sec_buf_in.buf_end, &p->buf_in.buf_base,
(unsigned *)&p->buf_in.buf_end );
if ( ret != SASL_OK ) {
ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
"sb_sasl_read: failed to decode packet: %s\n",
sasl_errstring( ret, NULL, NULL ) );
sb_sasl_drop_packet( &p->sec_buf_in,
sbiod->sbiod_sb->sb_debug );
errno = EIO;
return -1;
}
/* Drop the packet from the input buffer */
sb_sasl_drop_packet( &p->sec_buf_in, sbiod->sbiod_sb->sb_debug );
p->buf_in.buf_size = p->buf_in.buf_end;
bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len );
return bufptr;
}
static ber_slen_t
sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
struct sb_sasl_data *p;
int ret;
assert( sbiod != NULL );
assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
/* Are there anything left in the buffer? */
if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
if ( ret <= 0 )
return ret;
}
/* now encode the next packet. */
ber_pvt_sb_buf_destroy( &p->buf_out );
ret = sasl_encode( p->sasl_context, buf, len, &p->buf_out.buf_base,
(unsigned *)&p->buf_out.buf_size );
if ( ret != SASL_OK ) {
ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
"sb_sasl_write: failed to encode packet: %s\n",
sasl_errstring( ret, NULL, NULL ) );
return -1;
}
p->buf_out.buf_end = p->buf_out.buf_size;
ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
if ( ret <= 0 )
return ret;
return len;
}
static int
sb_sasl_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
{
struct sb_sasl_data *p;
p = (struct sb_sasl_data *)sbiod->sbiod_pvt;
if ( opt == LBER_SB_OPT_DATA_READY ) {
if ( p->buf_in.buf_ptr != p->buf_in.buf_end )
return 1;
}
return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
}
Sockbuf_IO ldap_pvt_sockbuf_io_sasl =
{
sb_sasl_setup, /* sbi_setup */
sb_sasl_remove, /* sbi_remove */
sb_sasl_ctrl, /* sbi_ctrl */
sb_sasl_read, /* sbi_read */
sb_sasl_write, /* sbi_write */
NULL /* sbi_close */
};
int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg )
{
/* don't install the stuff unless security has been negotiated */
if ( !ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO,
&ldap_pvt_sockbuf_io_sasl ) )
ber_sockbuf_add_io( sb, &ldap_pvt_sockbuf_io_sasl,
LBER_SBIOD_LEVEL_APPLICATION, ctx_arg );
return LDAP_SUCCESS;
}
static int
sasl_err2ldap( int saslerr )
{
int rc;
switch (saslerr) {
case SASL_CONTINUE:
rc = LDAP_MORE_RESULTS_TO_RETURN;
break;
case SASL_OK:
rc = LDAP_SUCCESS;
break;
case SASL_FAIL:
rc = LDAP_LOCAL_ERROR;
break;
case SASL_NOMEM:
rc = LDAP_NO_MEMORY;
break;
case SASL_NOMECH:
rc = LDAP_AUTH_UNKNOWN;
break;
case SASL_BADAUTH:
rc = LDAP_AUTH_UNKNOWN;
break;
case SASL_NOAUTHZ:
rc = LDAP_PARAM_ERROR;
break;
case SASL_TOOWEAK:
case SASL_ENCRYPT:
rc = LDAP_AUTH_UNKNOWN;
break;
default:
rc = LDAP_LOCAL_ERROR;
break;
}
assert( rc == LDAP_SUCCESS || LDAP_API_ERROR( rc ) );
return rc;
}
int
ldap_pvt_sasl_getmechs ( LDAP *ld, char **pmechlist )
{
@ -739,7 +379,7 @@ ldap_pvt_sasl_getmechs ( LDAP *ld, char **pmechlist )
return ld->ld_errno;
}
mechlist = array2str( values );
mechlist = ldap_charray2str( values, " " );
if ( mechlist == NULL ) {
ld->ld_errno = LDAP_NO_MEMORY;
LDAP_VFREE( values );
@ -755,361 +395,51 @@ ldap_pvt_sasl_getmechs ( LDAP *ld, char **pmechlist )
return LDAP_SUCCESS;
}
int
ldap_pvt_sasl_bind(
LDAP *ld,
LDAP_CONST char *dn,
LDAP_CONST char *mechs,
LDAP_CONST sasl_callback_t *callbacks,
LDAPControl **sctrls,
LDAPControl **cctrls )
{
const char *mech;
int saslrc, rc;
sasl_ssf_t *ssf = NULL;
unsigned credlen;
struct berval ccred, *scred;
char *host;
sasl_interact_t *client_interact = NULL;
struct sockaddr_in sin;
socklen_t len;
sasl_security_properties_t secprops;
ber_socket_t sd;
Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_bind\n", 0, 0, 0 );
/* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */
if (ld->ld_version < LDAP_VERSION3) {
ld->ld_errno = LDAP_NOT_SUPPORTED;
return ld->ld_errno;
}
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
if ( sd == AC_SOCKET_INVALID ) {
/* not connected yet */
int rc = ldap_open_defconn( ld );
if( rc < 0 ) return ld->ld_errno;
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd );
}
/* XXX this doesn't work with PF_LOCAL hosts */
host = ldap_host_connected_to( ld->ld_sb );
if ( host == NULL ) {
ld->ld_errno = LDAP_UNAVAILABLE;
return ld->ld_errno;
}
if ( ld->ld_sasl_context != NULL ) {
sasl_dispose( &ld->ld_sasl_context );
}
saslrc = sasl_client_new( "ldap", host, callbacks, SASL_SECURITY_LAYER,
&ld->ld_sasl_context );
LDAP_FREE( host );
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
ld->ld_errno = sasl_err2ldap( saslrc );
sasl_dispose( &ld->ld_sasl_context );
return ld->ld_errno;
}
len = sizeof( sin );
if ( getpeername( sd, (struct sockaddr *)&sin, &len ) == -1 ) {
Debug( LDAP_DEBUG_ANY, "SASL: can't query remote IP.\n",
0, 0, 0 );
ld->ld_errno = LDAP_OPERATIONS_ERROR;
return ld->ld_errno;
}
sasl_setprop( ld->ld_sasl_context, SASL_IP_REMOTE, &sin );
len = sizeof( sin );
if ( getsockname( sd, (struct sockaddr *)&sin, &len ) == -1 ) {
Debug( LDAP_DEBUG_ANY, "SASL: can't query local IP.\n",
0, 0, 0 );
ld->ld_errno = LDAP_OPERATIONS_ERROR;
return ld->ld_errno;
}
sasl_setprop( ld->ld_sasl_context, SASL_IP_LOCAL, &sin );
memset( &secprops, '\0', sizeof( secprops ) );
secprops.min_ssf = ld->ld_options.ldo_sasl_minssf;
secprops.max_ssf = ld->ld_options.ldo_sasl_maxssf;
secprops.security_flags = SASL_SECURITY_LAYER;
secprops.maxbufsize = 65536;
sasl_setprop( ld->ld_sasl_context, SASL_SEC_PROPS, &secprops );
ccred.bv_val = NULL;
ccred.bv_len = 0;
saslrc = sasl_client_start( ld->ld_sasl_context,
mechs,
NULL,
&client_interact,
&ccred.bv_val,
&credlen,
&mech );
ccred.bv_len = credlen;
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
ld->ld_errno = sasl_err2ldap( saslrc );
sasl_dispose( &ld->ld_sasl_context );
return ld->ld_errno;
}
scred = NULL;
do {
unsigned credlen;
sasl_interact_t *client_interact = NULL;
rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
if ( rc == LDAP_SUCCESS ) {
break;
} else if ( rc != LDAP_SASL_BIND_IN_PROGRESS ) {
if ( ccred.bv_val != NULL ) {
LDAP_FREE( ccred.bv_val );
}
sasl_dispose( &ld->ld_sasl_context );
return ld->ld_errno;
}
if ( ccred.bv_val != NULL ) {
LDAP_FREE( ccred.bv_val );
ccred.bv_val = NULL;
}
saslrc = sasl_client_step( ld->ld_sasl_context,
(scred == NULL) ? NULL : scred->bv_val,
(scred == NULL) ? 0 : scred->bv_len,
&client_interact,
&ccred.bv_val,
&credlen );
ccred.bv_len = credlen;
ber_bvfree( scred );
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
ld->ld_errno = sasl_err2ldap( saslrc );
sasl_dispose( &ld->ld_sasl_context );
return ld->ld_errno;
}
} while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
assert ( rc == LDAP_SUCCESS );
if ( sasl_getprop( ld->ld_sasl_context, SASL_SSF, (void **)&ssf )
== SASL_OK && ssf && *ssf ) {
ldap_pvt_sasl_install( ld->ld_sb, ld->ld_sasl_context );
}
return rc;
}
/* based on sample/sample-client.c */
static int
ldap_pvt_sasl_getsecret(sasl_conn_t *conn,
void *context, int id, sasl_secret_t **psecret)
{
struct berval *passphrase = (struct berval *)context;
size_t len;
if ( conn == NULL || psecret == NULL || id != SASL_CB_PASS ) {
return SASL_BADPARAM;
}
len = (passphrase != NULL) ? (size_t)passphrase->bv_len: 0;
*psecret = (sasl_secret_t *) LDAP_MALLOC( sizeof( sasl_secret_t ) + len );
if ( *psecret == NULL ) {
return SASL_NOMEM;
}
(*psecret)->len = passphrase->bv_len;
if ( passphrase != NULL ) {
memcpy((*psecret)->data, passphrase->bv_val, len);
}
return SASL_OK;
}
static int
ldap_pvt_sasl_getsimple(void *context, int id, const char **result, int *len)
{
const char *value = (const char *)context;
if ( result == NULL ) {
return SASL_BADPARAM;
}
switch ( id ) {
case SASL_CB_USER:
case SASL_CB_AUTHNAME:
*result = value;
if ( len )
*len = value ? strlen( value ) : 0;
break;
case SASL_CB_LANGUAGE:
*result = NULL;
if ( len )
*len = 0;
break;
default:
return SASL_BADPARAM;
}
return SASL_OK;
}
int
ldap_pvt_sasl_get_option( LDAP *ld, int option, void *arg )
{
sasl_ssf_t *ssf;
if ( ld == NULL )
return -1;
switch ( option ) {
case LDAP_OPT_X_SASL_MINSSF:
*(int *)arg = ld->ld_options.ldo_sasl_minssf;
break;
case LDAP_OPT_X_SASL_MAXSSF:
*(int *)arg = ld->ld_options.ldo_sasl_maxssf;
break;
case LDAP_OPT_X_SASL_ACTSSF:
if ( ld->ld_sasl_context == NULL ) {
*(int *)arg = -1;
break;
}
if ( sasl_getprop( ld->ld_sasl_context, SASL_SSF,
(void **) &ssf ) != SASL_OK )
{
return -1;
}
*(int *)arg = *ssf;
break;
default:
return -1;
}
return 0;
}
int
ldap_pvt_sasl_set_option( LDAP *ld, int option, void *arg )
{
if ( ld == NULL )
return -1;
switch ( option ) {
case LDAP_OPT_X_SASL_MINSSF:
ld->ld_options.ldo_sasl_minssf = *(int *)arg;
break;
case LDAP_OPT_X_SASL_MAXSSF:
ld->ld_options.ldo_sasl_maxssf = *(int *)arg;
break;
case LDAP_OPT_X_SASL_ACTSSF:
/* This option is read-only */
default:
return -1;
}
return 0;
}
/*
* ldap_negotiated_sasl_bind_s - bind to the ldap server (and X.500)
* using SASL authentication.
* ldap_sasl_interactive_bind_s - interactive SASL authentication
*
* This routine attempts to authenticate the user referred by the
* authentication id using the provided password. An optional
* authorization identity may be provided. An DN is generally not
* provided [see AuthMethod].
* This routine uses interactive callbacks.
*
* If the mechanism negotiated does not require a password, the
* passwd field is ignored. [A callback mechanism should really
* be used].
*
* LDAP_SUCCESS is returned upon success, the ldap error code
* otherwise.
*
* Examples:
* ldap_negotiated_sasl_bind_s( ld, NULL,
* NULL, NULL, NULL,
* NULL, NULL, NULL, NULL );
*
* ldap_negotiated_sasl_bind_s( ld, NULL,
* "user@OPENLDAP.ORG", NULL, NULL,
* "GSSAPI", NULL, NULL, NULL );
*
* ldap_negotiated_sasl_bind_s( ld, NULL,
* "manager", "dn:cn=user,dc=openldap,dc=org", NULL,
* "DIGEST-MD5", NULL, NULL, NULL );
*
* ldap_negotiated_sasl_bind_s( ld, NULL,
* "root@OPENLDAP.ORG", "u:user@OPENLDAP.ORG", NULL,
* "GSSAPI", NULL, NULL, NULL );
*
* ldap_negotiated_sasl_bind_s( ld, NULL,
* "manager", "dn:cn=user,dc=openldap,dc=org", NULL,
* "DIGEST-MD5", NULL, NULL, NULL );
*/
int
ldap_negotiated_sasl_bind_s(
ldap_sasl_interactive_bind_s(
LDAP *ld,
LDAP_CONST char *dn, /* usually NULL */
LDAP_CONST char *authenticationId,
LDAP_CONST char *authorizationId, /* commonly NULL */
LDAP_CONST char *saslMechanism,
struct berval *passPhrase,
LDAP_CONST char *mechs,
LDAPControl **serverControls,
LDAPControl **clientControls)
LDAPControl **clientControls,
unsigned flags,
LDAP_SASL_INTERACT_PROC *interact,
void *defaults )
{
int n;
sasl_callback_t callbacks[4];
int rc;
Debug( LDAP_DEBUG_TRACE, "ldap_negotiated_sasl_bind_s\n", 0, 0, 0 );
if( mechs == NULL || *mechs == '\0' ) {
char *smechs;
if( saslMechanism == NULL || *saslMechanism == '\0' ) {
char *mechs;
rc = ldap_pvt_sasl_getmechs( ld, &mechs );
rc = ldap_pvt_sasl_getmechs( ld, &smechs );
if( rc != LDAP_SUCCESS ) {
return rc;
}
saslMechanism = mechs;
Debug( LDAP_DEBUG_TRACE,
"ldap_interactive_sasl_bind_s: server supports: %s\n",
smechs, 0, 0 );
mechs = smechs;
} else {
Debug( LDAP_DEBUG_TRACE,
"ldap_interactive_sasl_bind_s: user selected: %s\n",
mechs, 0, 0 );
}
/* SASL Authentication Identity */
callbacks[n=0].id = SASL_CB_AUTHNAME;
callbacks[n].proc = ldap_pvt_sasl_getsimple;
callbacks[n].context = (void *)authenticationId;
/* SASL Authorization Identity (userid) */
if( authorizationId != NULL ) {
callbacks[++n].id = SASL_CB_USER;
callbacks[n].proc = ldap_pvt_sasl_getsimple;
callbacks[n].context = (void *)authorizationId;
}
callbacks[++n].id = SASL_CB_PASS;
callbacks[n].proc = ldap_pvt_sasl_getsecret;
callbacks[n].context = (void *)passPhrase;
callbacks[++n].id = SASL_CB_LIST_END;
callbacks[n].proc = NULL;
callbacks[n].context = NULL;
assert( n * sizeof(sasl_callback_t) < sizeof(callbacks) );
rc = ldap_pvt_sasl_bind(ld, dn, saslMechanism, callbacks,
serverControls, clientControls);
rc = ldap_int_sasl_bind( ld, dn, mechs,
serverControls, clientControls,
flags, interact, defaults );
return rc;
}
#endif /* HAVE_CYRUS_SASL */

View file

@ -27,25 +27,25 @@ choose_name( char *names[], LDAP_CONST char *fallback )
}
LDAP_CONST char *
ldap_syntax2name( LDAP_SYNTAX * syn )
ldap_syntax2name( LDAPSyntax * syn )
{
return( syn->syn_oid );
}
LDAP_CONST char *
ldap_matchingrule2name( LDAP_MATCHING_RULE * mr )
ldap_matchingrule2name( LDAPMatchingRule * mr )
{
return( choose_name( mr->mr_names, mr->mr_oid ) );
}
LDAP_CONST char *
ldap_attributetype2name( LDAP_ATTRIBUTE_TYPE * at )
ldap_attributetype2name( LDAPAttributeType * at )
{
return( choose_name( at->at_names, at->at_oid ) );
}
LDAP_CONST char *
ldap_objectclass2name( LDAP_OBJECT_CLASS * oc )
ldap_objectclass2name( LDAPObjectClass * oc )
{
return( choose_name( oc->oc_names, oc->oc_oid ) );
}
@ -267,9 +267,9 @@ print_noidlen(safe_string *ss, char *s, int l)
}
static int
print_extensions(safe_string *ss, LDAP_SCHEMA_EXTENSION_ITEM **extensions)
print_extensions(safe_string *ss, LDAPSchemaExtensionItem **extensions)
{
LDAP_SCHEMA_EXTENSION_ITEM **ext;
LDAPSchemaExtensionItem **ext;
if ( extensions ) {
print_whsp(ss);
@ -286,7 +286,7 @@ print_extensions(safe_string *ss, LDAP_SCHEMA_EXTENSION_ITEM **extensions)
}
char *
ldap_syntax2str( const LDAP_SYNTAX * syn )
ldap_syntax2str( const LDAPSyntax * syn )
{
safe_string * ss;
char * retstring;
@ -318,7 +318,7 @@ ldap_syntax2str( const LDAP_SYNTAX * syn )
}
char *
ldap_matchingrule2str( const LDAP_MATCHING_RULE * mr )
ldap_matchingrule2str( const LDAPMatchingRule * mr )
{
safe_string * ss;
char * retstring;
@ -367,7 +367,7 @@ ldap_matchingrule2str( const LDAP_MATCHING_RULE * mr )
}
char *
ldap_objectclass2str( const LDAP_OBJECT_CLASS * oc )
ldap_objectclass2str( const LDAPObjectClass * oc )
{
safe_string * ss;
char * retstring;
@ -446,7 +446,7 @@ ldap_objectclass2str( const LDAP_OBJECT_CLASS * oc )
}
char *
ldap_attributetype2str( const LDAP_ATTRIBUTE_TYPE * at )
ldap_attributetype2str( const LDAPAttributeType * at )
{
safe_string * ss;
char * retstring;
@ -966,13 +966,13 @@ parse_oids(const char **sp, int *code, const int allow_quoted)
}
static int
add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions,
add_extension(LDAPSchemaExtensionItem ***extensions,
char * name, char ** values)
{
int n;
LDAP_SCHEMA_EXTENSION_ITEM **tmp, *ext;
LDAPSchemaExtensionItem **tmp, *ext;
ext = LDAP_CALLOC(1, sizeof(LDAP_SCHEMA_EXTENSION_ITEM));
ext = LDAP_CALLOC(1, sizeof(LDAPSchemaExtensionItem));
if ( !ext )
return 1;
ext->lsei_name = name;
@ -980,7 +980,7 @@ add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions,
if ( !*extensions ) {
*extensions =
LDAP_CALLOC(2, sizeof(LDAP_SCHEMA_EXTENSION_ITEM *));
LDAP_CALLOC(2, sizeof(LDAPSchemaExtensionItem *));
if ( !*extensions )
return 1;
n = 0;
@ -988,7 +988,7 @@ add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions,
for ( n=0; (*extensions)[n] != NULL; n++ )
;
tmp = LDAP_REALLOC(*extensions,
(n+2)*sizeof(LDAP_SCHEMA_EXTENSION_ITEM *));
(n+2)*sizeof(LDAPSchemaExtensionItem *));
if ( !tmp )
return 1;
*extensions = tmp;
@ -999,9 +999,9 @@ add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions,
}
static void
free_extensions(LDAP_SCHEMA_EXTENSION_ITEM **extensions)
free_extensions(LDAPSchemaExtensionItem **extensions)
{
LDAP_SCHEMA_EXTENSION_ITEM **ext;
LDAPSchemaExtensionItem **ext;
if ( extensions ) {
for ( ext = extensions; *ext != NULL; ext++ ) {
@ -1014,15 +1014,16 @@ free_extensions(LDAP_SCHEMA_EXTENSION_ITEM **extensions)
}
void
ldap_syntax_free( LDAP_SYNTAX * syn )
ldap_syntax_free( LDAPSyntax * syn )
{
LDAP_FREE(syn->syn_oid);
LDAP_VFREE(syn->syn_names);
LDAP_FREE(syn->syn_desc);
free_extensions(syn->syn_extensions);
LDAP_FREE(syn);
}
LDAP_SYNTAX *
LDAPSyntax *
ldap_str2syntax( const char * s, int * code, const char ** errp, const int flags )
{
int kind;
@ -1030,7 +1031,7 @@ ldap_str2syntax( const char * s, int * code, const char ** errp, const int flags
char * sval;
int seen_name = 0;
int seen_desc = 0;
LDAP_SYNTAX * syn;
LDAPSyntax * syn;
char ** ext_vals;
if ( !s ) {
@ -1040,7 +1041,7 @@ ldap_str2syntax( const char * s, int * code, const char ** errp, const int flags
}
*errp = s;
syn = LDAP_CALLOC(1,sizeof(LDAP_SYNTAX));
syn = LDAP_CALLOC(1,sizeof(LDAPSyntax));
if ( !syn ) {
*code = LDAP_SCHERR_OUTOFMEM;
@ -1151,7 +1152,7 @@ ldap_str2syntax( const char * s, int * code, const char ** errp, const int flags
}
void
ldap_matchingrule_free( LDAP_MATCHING_RULE * mr )
ldap_matchingrule_free( LDAPMatchingRule * mr )
{
LDAP_FREE(mr->mr_oid);
LDAP_VFREE(mr->mr_names);
@ -1161,7 +1162,7 @@ ldap_matchingrule_free( LDAP_MATCHING_RULE * mr )
LDAP_FREE(mr);
}
LDAP_MATCHING_RULE *
LDAPMatchingRule *
ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int flags )
{
int kind;
@ -1171,7 +1172,7 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int
int seen_desc = 0;
int seen_obsolete = 0;
int seen_syntax = 0;
LDAP_MATCHING_RULE * mr;
LDAPMatchingRule * mr;
char ** ext_vals;
const char * savepos;
@ -1182,7 +1183,7 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int
}
*errp = s;
mr = LDAP_CALLOC(1,sizeof(LDAP_MATCHING_RULE));
mr = LDAP_CALLOC(1,sizeof(LDAPMatchingRule));
if ( !mr ) {
*code = LDAP_SCHERR_OUTOFMEM;
@ -1342,7 +1343,7 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int
}
void
ldap_attributetype_free(LDAP_ATTRIBUTE_TYPE * at)
ldap_attributetype_free(LDAPAttributeType * at)
{
LDAP_FREE(at->at_oid);
LDAP_VFREE(at->at_names);
@ -1356,7 +1357,7 @@ ldap_attributetype_free(LDAP_ATTRIBUTE_TYPE * at)
LDAP_FREE(at);
}
LDAP_ATTRIBUTE_TYPE *
LDAPAttributeType *
ldap_str2attributetype( const char * s, int * code, const char ** errp, const int flags )
{
int kind;
@ -1371,7 +1372,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in
int seen_substr = 0;
int seen_syntax = 0;
int seen_usage = 0;
LDAP_ATTRIBUTE_TYPE * at;
LDAPAttributeType * at;
char ** ext_vals;
const char * savepos;
@ -1382,7 +1383,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in
}
*errp = s;
at = LDAP_CALLOC(1,sizeof(LDAP_ATTRIBUTE_TYPE));
at = LDAP_CALLOC(1,sizeof(LDAPAttributeType));
if ( !at ) {
*code = LDAP_SCHERR_OUTOFMEM;
@ -1689,7 +1690,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in
}
void
ldap_objectclass_free(LDAP_OBJECT_CLASS * oc)
ldap_objectclass_free(LDAPObjectClass * oc)
{
LDAP_FREE(oc->oc_oid);
LDAP_VFREE(oc->oc_names);
@ -1701,7 +1702,7 @@ ldap_objectclass_free(LDAP_OBJECT_CLASS * oc)
LDAP_FREE(oc);
}
LDAP_OBJECT_CLASS *
LDAPObjectClass *
ldap_str2objectclass( const char * s, int * code, const char ** errp, const int flags )
{
int kind;
@ -1714,7 +1715,7 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp, const int
int seen_kind = 0;
int seen_must = 0;
int seen_may = 0;
LDAP_OBJECT_CLASS * oc;
LDAPObjectClass * oc;
char ** ext_vals;
const char * savepos;
@ -1725,7 +1726,7 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp, const int
}
*errp = s;
oc = LDAP_CALLOC(1,sizeof(LDAP_OBJECT_CLASS));
oc = LDAP_CALLOC(1,sizeof(LDAPObjectClass));
if ( !oc ) {
*code = LDAP_SCHERR_OUTOFMEM;

View file

@ -327,7 +327,7 @@ ldap_create_sort_control (
tag = ber_printf(ber, /*{*/ "N}");
if( tag == LBER_ERROR ) goto exit;
ld->ld_errno = ldap_int_create_control( LDAP_CONTROL_SORTREQUEST,
ld->ld_errno = ldap_create_control( LDAP_CONTROL_SORTREQUEST,
ber, isCritical, ctrlp);
ber_free(ber, 1);

View file

@ -29,6 +29,7 @@
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#elif defined( HAVE_SSL_H )
#include <ssl.h>
#endif
@ -40,6 +41,7 @@ static char *tls_opt_cacertfile = NULL;
static char *tls_opt_cacertdir = NULL;
static int tls_opt_require_cert = 0;
static char *tls_opt_ciphersuite = NULL;
static char *tls_opt_randfile = NULL;
#define HAS_TLS( sb ) ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
(void *)&ldap_pvt_sockbuf_io_tls )
@ -57,6 +59,8 @@ static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
static SSL_CTX *tls_def_ctx = NULL;
static int tls_seed_PRNG( const char *randfile );
#ifdef LDAP_R_COMPILE
/*
* provide mutexes for the SSLeay library.
@ -100,8 +104,10 @@ ldap_pvt_tls_init( void )
{
static int tls_initialized = 0;
if ( tls_initialized )
return 0;
if ( tls_initialized ) return 0;
(void) tls_seed_PRNG( tls_opt_randfile );
tls_initialized = 1;
#ifdef LDAP_R_COMPILE
tls_init_threads();
@ -622,6 +628,7 @@ ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
#endif
return -1;
}
return 0;
}
@ -664,7 +671,7 @@ ldap_pvt_tls_get_peer_issuer( LDAP *ld )
}
int
ldap_pvt_tls_config( struct ldapoptions *lo, int option, const char *arg )
ldap_int_tls_config( struct ldapoptions *lo, int option, const char *arg )
{
int i;
@ -673,6 +680,7 @@ ldap_pvt_tls_config( struct ldapoptions *lo, int option, const char *arg )
case LDAP_OPT_X_TLS_CACERTDIR:
case LDAP_OPT_X_TLS_CERTFILE:
case LDAP_OPT_X_TLS_KEYFILE:
case LDAP_OPT_X_TLS_RANDOM_FILE:
return ldap_pvt_tls_set_option( NULL, option, (void *) arg );
case LDAP_OPT_X_TLS_REQUIRE_CERT:
i = ( ( strcasecmp( arg, "on" ) == 0 ) ||
@ -694,9 +702,9 @@ ldap_pvt_tls_config( struct ldapoptions *lo, int option, const char *arg )
if (i >= 0)
return ldap_pvt_tls_set_option( lo, option, &i );
return -1;
default:
return -1;
}
return -1;
}
int
@ -731,6 +739,9 @@ ldap_pvt_tls_get_option( struct ldapoptions *lo, int option, void *arg )
case LDAP_OPT_X_TLS_REQUIRE_CERT:
*(int *)arg = tls_opt_require_cert;
break;
case LDAP_OPT_X_TLS_RANDOM_FILE:
*(char **)arg = tls_opt_randfile;
break;
default:
return -1;
}
@ -794,6 +805,10 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
if ( tls_opt_ciphersuite ) free( tls_opt_ciphersuite );
tls_opt_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
case LDAP_OPT_X_TLS_RANDOM_FILE:
if (tls_opt_randfile ) free (tls_opt_randfile );
tls_opt_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
default:
return -1;
}
@ -803,6 +818,9 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
int
ldap_pvt_tls_start ( LDAP *ld, Sockbuf *sb, void *ctx_arg )
{
/* Make sure tls is initialized, including PRNG properly seeded. */
ldap_pvt_tls_init();
/*
* Fortunately, the lib uses blocking io...
*/
@ -919,13 +937,57 @@ tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length )
tmp_rsa = RSA_generate_key( key_length, RSA_F4, NULL, NULL );
if ( !tmp_rsa ) {
Debug( LDAP_DEBUG_ANY, "TLS: Failed to generate temporary %d-bit %s RSA key\n",
key_length, is_export ? "export" : "domestic", 0 );
Debug( LDAP_DEBUG_ANY,
"TLS: Failed to generate temporary %d-bit %s RSA key\n",
key_length, is_export ? "export" : "domestic", 0 );
return NULL;
}
return tmp_rsa;
}
static int
tls_seed_PRNG( const char *randfile )
{
#ifndef URANDOM_DEVICE
/* no /dev/urandom (or equiv) */
char buffer[1024];
static int egdsocket = 0;
if (randfile == NULL) {
/* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd.
* If $HOME is not set or buffer too small to hold the pathname,
* an error occurs. - From RAND_file_name() man page.
* The fact is that when $HOME is NULL, .rnd is used.
*/
randfile = RAND_file_name(buffer, sizeof( buffer ));
} else if (RAND_egd(randfile) > 0) {
/* EGD socket */
egdsocket = 1;
return 0;
}
if (randfile == NULL) {
Debug( LDAP_DEBUG_ANY,
"TLS: Use configuration file or $RANDFILE to define seed file",
0, 0, 0);
return -1;
}
RAND_load_file(randfile, -1);
if (RAND_status() == 0) {
Debug( LDAP_DEBUG_ANY,
"TLS: PRNG has not been seeded with enough data",
0, 0, 0);
return -1;
}
#endif
return 0;
}
#if 0
static DH *
tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )

Some files were not shown because too many files have changed in this diff Show more