/*
*
* Portions Copyright 1998 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* ufn.c
*/
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h> /* malloc(), realloc(), free() */
#ifdef MACOS
#include <stdlib.h>
#include "macos.h"
#else /* MACOS */
#include "msdos.h"
#else /* DOS */
#endif /* DOS */
#endif /* MACOS */
#include "lber.h"
#include "ldap.h"
#include "ldap-private.h"
#include "ldap-int.h"
#ifdef SUN
/*
* to include definition of FILTERFILE and or TEMPLATEFILE
*/
#include "ldapconfig.h"
#endif
#ifdef NEEDPROTOS
#else /* NEEDPROTOS */
typedef int (*cancelptype)();
#endif /* NEEDPROTOS */
#ifdef NEEDPROTOS
char *tag3 );
#else /* NEEDPROTOS */
static LDAPMessage *ldap_msg_merge();
static LDAPMessage *ldap_ufn_expand();
#endif /* NEEDPROTOS */
static LDAPMessage *ldap_msg_merge();
static LDAPMessage *ldap_ufn_expand();
/*
* ldap_ufn_search_ctx - do user friendly searching; provide cancel feature;
* specify ldapfilter.conf tags for each phase of search
*
* ld LDAP descriptor
* ufncomp the exploded user friendly name to look for
* ncomp number of elements in ufncomp
* prefix where to start searching
* attrs list of attribute types to return for matches
* attrsonly 1 => attributes only 0 => attributes and values
* res will contain the result of the search
* cancelproc routine that returns non-zero if operation should be
* cancelled. This can be NULL. If it is non-NULL, the
* routine will be called periodically.
* cancelparm void * that is passed to cancelproc
* tag[123] the ldapfilter.conf tag that will be used in phases
* 1, 2, and 3 of the search, respectively
*
* Example:
* char *attrs[] = { "mail", "title", 0 };
* char *ufncomp[] = { "howes", "umich", "us", 0 }
* LDAPMessage *res;
* error = ldap_ufn_search_ctx( ld, ufncomp, 3, NULL, attrs, attrsonly,
* &res, acancelproc, along, "ufn first",
* "ufn intermediate", "ufn last" );
*/
static int
{
char **dns;
/* LDAPMessage *ldap_msg_merge(), *ldap_ufn_expand(); */
/*
* look up ufn components from most to least significant.
* there are 3 phases.
* phase 1 search the root for orgs or countries
* phase 2 search for orgs
* phase 3 search for a person
* in phases 1 and 2, we are building a list of candidate DNs,
* below which we will search for the final component of the ufn.
* for each component we try the filters listed in the
* filterconfig file, first one-level (except the last compoment),
* then subtree. if any of them produce any results, we go on to
* the next component.
*/
#if defined( SUN ) && defined( _REENTRANT )
#endif
candidates = NULL;
phase = 1;
char *quote;
*quote = '\0';
}
if ( ncomp == 0 )
phase = 3;
switch ( phase ) {
case 1:
break;
case 2:
break;
case 3:
break;
}
/*
* construct an array of DN's to search below from the
* list of candidates.
*/
if ( candidates == NULL ) {
* 2 )) == NULL ) {
#if defined( SUN ) && defined( _REENTRANT )
#endif
}
} else {
}
} else {
i = 0, max = 0;
{
continue;
sizeof(char *) * 8 )) == NULL ) {
#if defined( SUN ) && defined( _REENTRANT )
#endif
return( LDAP_NO_MEMORY );
}
max = 8;
} else if ( i >= max ) {
sizeof(char *) * 2 * max ))
== NULL )
{
#if defined( SUN ) && defined( _REENTRANT )
#endif
return( LDAP_NO_MEMORY );
}
max *= 2;
}
}
candidates = NULL;
}
tries = 0;
tries++;
{
{
break;
}
ldap_value_free( dns );
}
#if defined( SUN ) && defined( _REENTRANT )
#endif
return( err );
}
}
if ( candidates == NULL ) {
goto tryagain;
} else {
ldap_value_free( dns );
}
#if defined( SUN ) && defined( _REENTRANT )
#endif
return( err );
}
}
/* go on to the next component */
if ( phase == 1 )
phase++;
ldap_value_free( dns );
}
}
*res = candidates;
#if defined( SUN ) && defined( _REENTRANT )
#endif
return( err );
}
int
{
char *pbuf;
#if defined( SUN ) && defined( _REENTRANT )
#endif
/* initialize the getfilter stuff if it's not already */
== NULL ) {
#if defined( SUN ) && defined( _REENTRANT )
#endif
}
/* call ldap_explode_dn() to break the ufn into its components */
#if defined( SUN ) && defined( _REENTRANT )
#endif
}
; /* NULL */
/* more than two components => try it fully qualified first */
#if defined( SUN ) && defined( _REENTRANT )
#endif
return( err );
} else {
ldap_msgfree( *res );
}
}
#if defined( SUN ) && defined( _REENTRANT )
#endif
return( err );
}
/* if that failed, or < 2 components, use the prefix */
#if defined( SUN ) && defined( _REENTRANT )
#endif
}
; /* NULL */
== NULL ) {
#if defined( SUN ) && defined( _REENTRANT )
#endif
}
for ( i = 0; i < pcomp; i++ ) {
int j;
*pbuf = '\0';
for ( j = i; j < pcomp; j++ ) {
if ( j + 1 < pcomp )
}
break;
} else {
ldap_msgfree( *res );
}
}
#if defined( SUN ) && defined( _REENTRANT )
#endif
return( err );
}
/*
* same as ldap_ufn_search_ct, except without the ability to specify
* ldapfilter.conf tags.
*/
int
{
}
/*
* same as ldap_ufn_search_c without the cancel function
*/
int
LDAPMessage **res )
{
"ufn first", "ufn intermediate", "ufn last" ) );
}
/*
* ldap_msg_merge - merge two ldap search result chains. the more
* serious of the two error result codes is kept.
*/
static LDAPMessage *
{
if ( a == NULL )
return( b );
if ( b == NULL )
return( a );
/* find the ends of the a and b chains */
/* keep result a */
/* remove result b */
ldap_msgfree( bend );
else
b = NULL;
else
a = NULL;
/* keep result b */
} else {
/* remove result a */
ldap_msgfree( aend );
else
a = NULL;
else
b = NULL;
}
return( end );
if ( a == NULL ) {
return( b );
} else if ( b == NULL ) {
return( a );
} else {
return( a );
}
}
static LDAPMessage *
int *err )
{
char *dn;
int i, msgid;
/* search for this component below the current candidates */
i = 0;
do {
else
dn = "";
aonly )) == -1 ) {
ldap_msgfree( tmpcand );
return( NULL );
}
do {
(*cancelproc)( cancelparm ) != 0 ) {
}
} while ( *err == 0 );
ldap_msgfree( tmpcand );
return( NULL );
}
i++;
return( tmpcand );
} else {
ldap_msgfree( tmpcand );
return( NULL );
}
}
/*
* ldap_ufn_setfilter - set the filter config file used in ufn searching
*/
{
#if defined( SUN ) && defined( _REENTRANT )
#endif
#if defined( SUN ) && defined( _REENTRANT )
return( rv );
#else
#endif
}
void
{
#if defined( SUN ) && defined( _REENTRANT )
#endif
#if defined( SUN ) && defined( _REENTRANT )
#endif
}
int
{
}
}