Esempio n. 1
0
/*
 * Return the next host and port in hostlist (setting *hostp and *portp).
 * Return value is an LDAP API error code (LDAP_SUCCESS if all goes well).
 * If no more hosts are available, LDAP_SUCCESS is returned but *hostp is set
 * to NULL.
 */
int LDAP_CALL ldap_x_hostlist_next(char **hostp, int *portp,
                                   struct ldap_x_hostlist_status *status) {
  char *q;
  int squarebrackets = 0;

  if (NULL == hostp || NULL == portp) {
    return (LDAP_PARAM_ERROR);
  }

  if (NULL == status || NULL == status->lhs_nexthost) {
    *hostp = NULL;
    return (LDAP_SUCCESS);
  }

  /*
   * skip past leading '[' if present (IPv6 addresses may be surrounded
   * with square brackets, e.g., [fe80::a00:20ff:fee5:c0b4]:389
   */
  if (status->lhs_nexthost[0] == '[') {
    ++status->lhs_nexthost;
    squarebrackets = 1;
  }

  /* copy host into *hostp */
  if (NULL != (q = strchr(status->lhs_nexthost, ' '))) {
    size_t len = q - status->lhs_nexthost;
    *hostp = NSLDAPI_MALLOC(len + 1);
    if (NULL == *hostp) {
      return (LDAP_NO_MEMORY);
    }
    strncpy(*hostp, status->lhs_nexthost, len);
    (*hostp)[len] = '\0';
    status->lhs_nexthost += (len + 1);
  } else { /* last host */
    *hostp = nsldapi_strdup(status->lhs_nexthost);
    if (NULL == *hostp) {
      return (LDAP_NO_MEMORY);
    }
    status->lhs_nexthost = NULL;
  }

  /*
   * Look for closing ']' and skip past it before looking for port.
   */
  if (squarebrackets && NULL != (q = strchr(*hostp, ']'))) {
    *q++ = '\0';
  } else {
    q = *hostp;
  }

  /* determine and set port */
  if (NULL != (q = strchr(q, ':'))) {
    *q++ = '\0';
    *portp = atoi(q);
  } else {
    *portp = status->lhs_defport;
  }

  return (LDAP_SUCCESS);
}
Esempio n. 2
0
/*
 * duplicate the contents of "ctrl_src" and place in "ctrl_dst"
 */
static int
/* LDAP_CALL */		/* keep this routine internal for now */
ldap_control_copy_contents( LDAPControl *ctrl_dst, LDAPControl *ctrl_src )
{
	size_t	len;

	if ( NULL == ctrl_dst || NULL == ctrl_src ) {
		return( LDAP_PARAM_ERROR );
	}

	ctrl_dst->ldctl_iscritical = ctrl_src->ldctl_iscritical;

	/* fill in the fields of this new control */
	if (( ctrl_dst->ldctl_oid = nsldapi_strdup( ctrl_src->ldctl_oid ))
	    == NULL ) {
		return( LDAP_NO_MEMORY );
	}

	len = (size_t)(ctrl_src->ldctl_value).bv_len;
	if ( ctrl_src->ldctl_value.bv_val == NULL || len <= 0 ) {
		ctrl_dst->ldctl_value.bv_len = 0;
		ctrl_dst->ldctl_value.bv_val = NULL;
	} else {
		ctrl_dst->ldctl_value.bv_len = len;
		if (( ctrl_dst->ldctl_value.bv_val = NSLDAPI_MALLOC( len ))
		    == NULL ) {
			NSLDAPI_FREE( ctrl_dst->ldctl_oid );
			return( LDAP_NO_MEMORY );
		}
		SAFEMEMCPY( ctrl_dst->ldctl_value.bv_val,
		    ctrl_src->ldctl_value.bv_val, len );
	}

	return ( LDAP_SUCCESS );
}
Esempio n. 3
0
/* returns an LDAP error code */
int
nsldapi_append_referral( LDAP *ld, char **referralsp, char *s )
{
	int	first;

	if ( *referralsp == NULL ) {
		first = 1;
		*referralsp = (char *)NSLDAPI_MALLOC( strlen( s ) +
		    LDAP_REF_STR_LEN + 1 );
	} else {
		first = 0;
		*referralsp = (char *)NSLDAPI_REALLOC( *referralsp,
		    strlen( *referralsp ) + strlen( s ) + 2 );
	}

	if ( *referralsp == NULL ) {
		return( LDAP_NO_MEMORY );
	}

	if ( first ) {
		strcpy( *referralsp, LDAP_REF_STR );
	} else {
		strcat( *referralsp, "\n" );
	}
	strcat( *referralsp, s );

	return( LDAP_SUCCESS );
}
Esempio n. 4
0
/* if s is NULL, returns NULL */
char *nsldapi_strdup(const char *s) {
  char *p;

  if (s == NULL || (p = (char *)NSLDAPI_MALLOC(strlen(s) + 1)) == NULL)
    return (NULL);

  strcpy(p, s);

  return (p);
}
Esempio n. 5
0
/*
 * build an allocated LDAPv3 control.  Returns an LDAP error code.
 */
int
nsldapi_build_control( char *oid, BerElement *ber, int freeber, char iscritical,
    LDAPControl **ctrlp )
{
	int		rc;
	struct berval	*bvp;

	if ( ber == NULL ) {
		bvp = NULL;
	} else {
		/* allocate struct berval with contents of the BER encoding */
		rc = ber_flatten( ber, &bvp );
		if ( freeber ) {
			ber_free( ber, 1 );
		}
		if ( rc == -1 ) {
			return( LDAP_NO_MEMORY );
		}
	}

	/* allocate the new control structure */
	if (( *ctrlp = (LDAPControl *)NSLDAPI_MALLOC( sizeof(LDAPControl)))
	    == NULL ) {
		if ( bvp != NULL ) {
			ber_bvfree( bvp );
		}
		return( LDAP_NO_MEMORY );
	}

	/* fill in the fields of this new control */
	(*ctrlp)->ldctl_iscritical = iscritical;  
	if (( (*ctrlp)->ldctl_oid = nsldapi_strdup( oid )) == NULL ) {
		NSLDAPI_FREE( *ctrlp ); 
		if ( bvp != NULL ) {
			ber_bvfree( bvp );
		}
		return( LDAP_NO_MEMORY );
	}				

	if ( bvp == NULL ) {
		(*ctrlp)->ldctl_value.bv_len = 0;
		(*ctrlp)->ldctl_value.bv_val = NULL;
	} else {
		(*ctrlp)->ldctl_value = *bvp;	/* struct copy */
		NSLDAPI_FREE( bvp );	/* free container, not contents! */
	}

	return( LDAP_SUCCESS );
}
Esempio n. 6
0
int
LDAP_CALL
ldap_init_templates( char *file, struct ldap_disptmpl **tmpllistp )
{
    FILE	*fp;
    char	*buf;
    long	rlen, len;
    int		rc, eof;

    *tmpllistp = NULLDISPTMPL;

    if (( fp = fopen( file, "rF" )) == NULL ) {
        return( LDAP_TMPL_ERR_FILE );
    }

    if ( fseek( fp, 0L, SEEK_END ) != 0 ) {	/* move to end to get len */
        fclose( fp );
        return( LDAP_TMPL_ERR_FILE );
    }

    len = ftell( fp );

    if ( fseek( fp, 0L, SEEK_SET ) != 0 ) {	/* back to start of file */
        fclose( fp );
        return( LDAP_TMPL_ERR_FILE );
    }

    if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) {
        fclose( fp );
        return( LDAP_TMPL_ERR_MEM );
    }

    rlen = fread( buf, 1, (size_t)len, fp );
    eof = feof( fp );
    fclose( fp );

    if ( rlen != len && !eof ) {	/* error:  didn't get the whole file */
        NSLDAPI_FREE( buf );
        return( LDAP_TMPL_ERR_FILE );
    }

    rc = ldap_init_templates_buf( buf, rlen, tmpllistp );
    NSLDAPI_FREE( buf );

    return( rc );
}
Esempio n. 7
0
int
LDAP_CALL
ldap_create_sort_keylist (
	LDAPsortkey ***sortKeyList,
	const char *string_rep
)
{
	int count = 0;
	LDAPsortkey **pointer_array = NULL;
	const char *current_position = NULL;
	int retval = 0;
	int i = 0;

	/* Figure out how many there are */
	if (NULL == string_rep) {
		return LDAP_PARAM_ERROR;
	}
	if (NULL == sortKeyList) {
		return LDAP_PARAM_ERROR;
	}
	count = count_tokens(string_rep);
	if (0 == count) {
		*sortKeyList = NULL;
		return LDAP_PARAM_ERROR;
	}
	/* Allocate enough memory for the pointers */
	pointer_array = (LDAPsortkey**)NSLDAPI_MALLOC(sizeof(LDAPsortkey*)
	    * (count + 1) );
	if (NULL == pointer_array) {
		return LDAP_NO_MEMORY;
	}
	/* Now walk along the string, allocating and filling in the LDAPsearchkey structure */
	current_position = string_rep;

	for (i = 0; i < count; i++) {
		if (0 != (retval = read_next_token(&current_position,&(pointer_array[i])))) {
			pointer_array[count] = NULL;
			ldap_free_sort_keylist(pointer_array);
			*sortKeyList = NULL;
			return retval;
		}
	}
	pointer_array[count] = NULL;
	*sortKeyList = pointer_array;
	return LDAP_SUCCESS;
}
LDAP_CALL
ldap_init_getfilter( char *fname )
{
    FILE		*fp;
    char		*buf;
    long		rlen, len;
    int 		eof;
    LDAPFiltDesc	*lfdp;

    if (( fp = NSLDAPI_FOPEN( fname, "r" )) == NULL ) {
	return( NULL );
    }

    if ( fseek( fp, 0L, SEEK_END ) != 0 ) {	/* move to end to get len */
	fclose( fp );
	return( NULL );
    }

    len = ftell( fp );

    if ( fseek( fp, 0L, SEEK_SET ) != 0 ) {	/* back to start of file */
	fclose( fp );
	return( NULL );
    }

    if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) {
	fclose( fp );
	return( NULL );
    }

    rlen = fread( buf, 1, (size_t)len, fp );
    eof = feof( fp );
    fclose( fp );

    if ( rlen != len && !eof ) {	/* error:  didn't get the whole file */
	NSLDAPI_FREE( buf );
	return( NULL );
    }


    lfdp = ldap_init_getfilter_buf( buf, rlen );
    NSLDAPI_FREE( buf );

    return( lfdp );
}
Esempio n. 9
0
/*
 * return a malloc'd copy of "ctrl" (NULL if memory allocation fails)
 */
static LDAPControl *
/* LDAP_CALL */		/* keep this routine internal for now */
ldap_control_dup( LDAPControl *ctrl )
{
	LDAPControl	*rctrl;

	if (( rctrl = (LDAPControl *)NSLDAPI_MALLOC( sizeof( LDAPControl )))
	    == NULL ) {
		return( NULL );
	}

	if ( ldap_control_copy_contents( rctrl, ctrl ) != LDAP_SUCCESS ) {
		NSLDAPI_FREE( rctrl );
		return( NULL );
	}

	return( rctrl );
}
Esempio n. 10
0
LDAP_CALL
ldap_explode_dns( const char *dn )
{
	int	ncomps, maxcomps;
	char	*s, *cpydn;
	char	**rdns;
#ifdef HAVE_STRTOK_R	/* defined in portable.h */
	char	*lasts;
#endif

	if ( dn == NULL ) {
		dn = "";
	}

	if ( (rdns = (char **)NSLDAPI_MALLOC( 8 * sizeof(char *) )) == NULL ) {
		return( NULL );
	}

	maxcomps = 8;
	ncomps = 0;
	cpydn = nsldapi_strdup( (char *)dn );
	for ( s = STRTOK( cpydn, "@.", &lasts ); s != NULL;
	    s = STRTOK( NULL, "@.", &lasts ) ) {
		if ( ncomps == maxcomps ) {
			maxcomps *= 2;
			if ( (rdns = (char **)NSLDAPI_REALLOC( rdns, maxcomps *
			    sizeof(char *) )) == NULL ) {
				NSLDAPI_FREE( cpydn );
				return( NULL );
			}
		}
		rdns[ncomps++] = nsldapi_strdup( s );
	}
	rdns[ncomps] = NULL;
	NSLDAPI_FREE( cpydn );

	return( rdns );
}
Esempio n. 11
0
LDAP_CALL
ldap_control_append( LDAPControl **ctrl_src, LDAPControl *ctrl )
{
    int nctrls = 0;
	LDAPControl **ctrlp;
	int i;

	if ( NULL == ctrl )
	    return ( NULL );

	/* Count the existing controls */
	if ( NULL != ctrl_src ) {
		while( NULL != ctrl_src[nctrls] ) {
			nctrls++;
		}
	}

	/* allocate the new control structure */
	if ( ( ctrlp = (LDAPControl **)NSLDAPI_MALLOC( sizeof(LDAPControl *)
	    * (nctrls + 2) ) ) == NULL ) {
		return( NULL );
	}
	memset( ctrlp, 0, sizeof(*ctrlp) * (nctrls + 2) );

	for( i = 0; i < (nctrls + 1); i++ ) {
	    if ( i < nctrls ) {
		    ctrlp[i] = ldap_control_dup( ctrl_src[i] );
	    } else {
		    ctrlp[i] = ldap_control_dup( ctrl );
	    }
	    if ( NULL == ctrlp[i] ) {
		    ldap_controls_free( ctrlp );
		    return( NULL );
	    }
	}
	return ctrlp;
}
Esempio n. 12
0
/*
 * Replace *ldctrls with a copy of newctrls.
 * returns 0 if successful.
 * return -1 if not and set error code inside LDAP *ld.
 */
int
nsldapi_dup_controls( LDAP *ld, LDAPControl ***ldctrls, LDAPControl **newctrls )
{
	int	count;

	if ( *ldctrls != NULL ) {
		ldap_controls_free( *ldctrls );
	}

	if ( newctrls == NULL || newctrls[0] == NULL ) {
		*ldctrls = NULL;
		return( 0 );
	}

	for ( count = 0; newctrls[ count ] != NULL; ++count ) {
		;
	}

	if (( *ldctrls = (LDAPControl **)NSLDAPI_MALLOC(( count + 1 ) *
	    sizeof( LDAPControl *))) == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		return( -1 );
	}
	(*ldctrls)[ count ] = NULL;

	for ( count = 0; newctrls[ count ] != NULL; ++count ) {
		if (( (*ldctrls)[ count ] =
		    ldap_control_dup( newctrls[ count ] )) == NULL ) {
			ldap_controls_free( *ldctrls );
			*ldctrls = NULL;
			LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
			return( -1 );
		}
	}

	return( 0 );
}
Esempio n. 13
0
static int
do_entry2text_search(
	LDAP			*ld,
	char			*dn,		/* if NULL, use entry */
	char			*base,		/* if NULL, no search actions */
	LDAPMessage		*entry,		/* if NULL, use dn */
	struct ldap_disptmpl*	tmpllist,	/* if NULL, no template used */
	char			**defattrs,
	char			***defvals,
	writeptype		writeproc,
	void			*writeparm,
	char			*eol,
	int			rdncount,	/* if 0, display full DN */
	unsigned long		opts,
	char			*urlprefix
)
{
    int				err, freedn, html;
    char			*buf, **fetchattrs, **vals;
    LDAPMessage			*ldmp;
    struct ldap_disptmpl	*tmpl;
    struct timeval		timeout;

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
	return( LDAP_PARAM_ERROR );
    }

    if ( dn == NULL && entry == NULLMSG ) {
	err = LDAP_PARAM_ERROR;
	LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	return( err );
    }

    html = ( urlprefix != NULL );

    timeout.tv_sec = SEARCH_TIMEOUT_SECS;
    timeout.tv_usec = 0;

    if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) {
	err = LDAP_NO_MEMORY;
	LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	return( err );
    }

    freedn = 0;
    tmpl = NULL;

    if ( dn == NULL ) {
	if (( dn = ldap_get_dn( ld, entry )) == NULL ) {
	    NSLDAPI_FREE( buf );
	    return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}
	freedn = 1;
    }


    if ( tmpllist != NULL ) {
	ldmp = NULLMSG;

	if ( entry == NULL ) {
	    char	*ocattrs[2];

	    ocattrs[0] = OCATTRNAME;
	    ocattrs[1] = NULL;
#ifdef CLDAP
	    if ( LDAP_IS_CLDAP( ld ))
		    err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE,
			"objectClass=*", ocattrs, 0, &ldmp, NULL );
	    else
#endif /* CLDAP */
		    err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE,
			    "objectClass=*", ocattrs, 0, &timeout, &ldmp );

	    if ( err == LDAP_SUCCESS ) {
		entry = ldap_first_entry( ld, ldmp );
	    }
	}

	if ( entry != NULL ) {
	    vals = ldap_get_values( ld, entry, OCATTRNAME );
	    tmpl = ldap_oc2template( vals, tmpllist );
	    if ( vals != NULL ) {
		ldap_value_free( vals );
	    }
	}
	if ( ldmp != NULL ) {
	    ldap_msgfree( ldmp );
	}
    }

    entry = NULL;

    if ( tmpl == NULL ) {
	fetchattrs = NULL;
    } else {
	fetchattrs = ldap_tmplattrs( tmpl, NULL, 1, LDAP_SYN_OPT_DEFER );
    }

#ifdef CLDAP
    if ( LDAP_IS_CLDAP( ld ))
	err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
		fetchattrs, 0, &ldmp, NULL );
    else
#endif /* CLDAP */
	err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
		fetchattrs, 0, &timeout, &ldmp );

    if ( freedn ) {
	NSLDAPI_FREE( dn );
    }
    if ( fetchattrs != NULL ) {
	ldap_value_free( fetchattrs );
    }

    if ( err != LDAP_SUCCESS ||
	    ( entry = ldap_first_entry( ld, ldmp )) == NULL ) {
	NSLDAPI_FREE( buf );
	return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
    }

    err = do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals,
	    writeproc, writeparm, eol, rdncount, opts, urlprefix );

    NSLDAPI_FREE( buf );
    ldap_msgfree( ldmp );
    return( err );
}
Esempio n. 14
0
LDAP_CALL
ldap_init( const char *defhost, int defport )
{
	LDAP	*ld;

	if ( !nsldapi_initialized ) {
		nsldapi_initialize_defaults();
	}

	if ( defport < 0 || defport > LDAP_PORT_MAX ) {
	    LDAPDebug( LDAP_DEBUG_ANY,
		    "ldap_init: port %d is invalid (port numbers must range from 1 to %d)\n",
		    defport, LDAP_PORT_MAX, 0 );
#if !defined( macintosh ) && !defined( DOS )
	    errno = EINVAL;
#endif
	    return( NULL );
	}

	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 );

	if ( (ld = (LDAP*)NSLDAPI_MALLOC( sizeof(struct ldap) )) == NULL ) {
		return( NULL );
	}

	/* copy defaults */
	SAFEMEMCPY( ld, &nsldapi_ld_defaults, sizeof( struct ldap ));
	if ( nsldapi_ld_defaults.ld_io_fns_ptr != NULL ) {
		if (( ld->ld_io_fns_ptr = (struct ldap_io_fns *)NSLDAPI_MALLOC(
		    sizeof( struct ldap_io_fns ))) == NULL ) {
			NSLDAPI_FREE( (char *)ld );
			return( NULL );
		}
		/* struct copy */
		*(ld->ld_io_fns_ptr) = *(nsldapi_ld_defaults.ld_io_fns_ptr);
	}

	/* call the new handle I/O callback if one is defined */
	if ( ld->ld_extnewhandle_fn != NULL ) {
		/*
		 * We always pass the session extended I/O argument to
		 * the new handle callback.
		 */
		if ( ld->ld_extnewhandle_fn( ld, ld->ld_ext_session_arg )
		    != LDAP_SUCCESS ) {
			NSLDAPI_FREE( (char*)ld );
			return( NULL );
		}
	}

	/* allocate session-specific resources */
	if (( ld->ld_sbp = ber_sockbuf_alloc()) == NULL ||
	    ( defhost != NULL &&
	    ( ld->ld_defhost = nsldapi_strdup( defhost )) == NULL ) ||
	    ((ld->ld_mutex = (void **) NSLDAPI_CALLOC( LDAP_MAX_LOCK, sizeof(void *))) == NULL )) {
		if ( ld->ld_sbp != NULL ) {
			ber_sockbuf_free( ld->ld_sbp );
		}
		if( ld->ld_mutex != NULL ) {
			NSLDAPI_FREE( ld->ld_mutex );
		}
		NSLDAPI_FREE( (char*)ld );
		return( NULL );
	}

	/* install Sockbuf I/O functions if set in LDAP * */
	if ( ld->ld_extread_fn != NULL || ld->ld_extwrite_fn != NULL ) {
		struct lber_x_ext_io_fns lberiofns;

		memset( &lberiofns, 0, sizeof( lberiofns ));

		lberiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
		lberiofns.lbextiofn_read = ld->ld_extread_fn;
		lberiofns.lbextiofn_write = ld->ld_extwrite_fn;
		lberiofns.lbextiofn_writev = ld->ld_extwritev_fn;
		lberiofns.lbextiofn_socket_arg = NULL;
		ber_sockbuf_set_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS,
			(void *)&lberiofns );
	}

#ifdef _SOLARIS_SDK
	/* Install the functions for IPv6 support	*/
	/* code sequencing is critical from here to nsldapi_mutex_alloc_all */
        if ( prldap_install_thread_functions( ld, 1 ) != 0 ||
             prldap_install_io_functions( ld, 1 ) != 0 ||
             prldap_install_dns_functions( ld ) != 0 ) {
		/* go through ld and free resources */
		ldap_unbind( ld );
		ld = NULL;
		return( NULL );
        }
#else

	/* allocate mutexes */
	nsldapi_mutex_alloc_all( ld );
#endif

	/* set default port */
	ld->ld_defport = ( defport == 0 ) ? LDAP_PORT : defport;

	return( ld );
}
Esempio n. 15
0
static int read_next_token(const char **s,LDAPsortkey **key)
{
	char c = 0;
	const char *pos = *s;
	int retval = 0;
	LDAPsortkey *new_key = NULL;

	const char *matchrule_source = NULL;
	int matchrule_size = 0;
	const char *attrdesc_source = NULL;
	int attrdesc_size = 0;
	int reverse = 0;

	int state = 0;
	
	while ( ((c = *pos++) != '\0') && (state != 4) ) {
		switch (state) {
		case 0:
		/* case where we've not seen the beginning of the attr yet */
			/* If we still see whitespace, nothing to do */
			if (!isspace(c)) {
				/* Otherwise, something to look at */
				/* Is it a minus sign ? */
				if ('-' == c) {
					reverse = 1;
				} else {
					attrdesc_source = pos - 1;
					state = 1;
				}
			}
			break;
		case 1:
		/* case where we've seen the beginning of the attr, but not the end */
			/* Is this char either whitespace or a ';' ? */
			if ( isspace(c) || (':' == c)) {
				attrdesc_size = (pos - attrdesc_source) - 1;
				if (':' == c) {
					state = 2;
				} else {
					state = 4;
				}
			} 
			break;
		case 2:
		/* case where we've seen the end of the attr and want the beginning of match rule */
			if (!isspace(c)) {
				matchrule_source = pos - 1;
				state = 3;
			} else {
				state = 4;
			}
			break;
		case 3:
		/* case where we've seen the beginning of match rule and want to find the end */
			if (isspace(c)) {
				matchrule_size = (pos - matchrule_source) - 1;
				state = 4;
			}
			break;
		default:
			break;
		}
	}
	
	if (3 == state) {
		/* means we fell off the end of the string looking for the end of the marching rule */
		matchrule_size = (pos - matchrule_source) - 1;
	}

	if (1 == state) {
		/* means we fell of the end of the string looking for the end of the attribute */
		attrdesc_size = (pos - attrdesc_source) - 1;
	}

	if (NULL == attrdesc_source)  {
		/* Didn't find anything */
		return -1;
	}

	new_key = (LDAPsortkey*)NSLDAPI_MALLOC(sizeof(LDAPsortkey));
	if (0 == new_key) {
		return LDAP_NO_MEMORY;
	}
	
	/* Allocate the strings */
	new_key->sk_attrtype = (char *)NSLDAPI_MALLOC(attrdesc_size + 1);
	if (NULL != matchrule_source) {
		new_key->sk_matchruleoid = (char *)NSLDAPI_MALLOC(
		    matchrule_size + 1);
	} else {
		new_key->sk_matchruleoid = NULL;
	}
	/* Copy over the strings */
	memcpy(new_key->sk_attrtype,attrdesc_source,attrdesc_size);
	*(new_key->sk_attrtype + attrdesc_size) = '\0';
	if (NULL != matchrule_source) {
		memcpy(new_key->sk_matchruleoid,matchrule_source,matchrule_size);
		*(new_key->sk_matchruleoid + matchrule_size) = '\0';
	}

	new_key->sk_reverseorder = reverse;

	*s = pos - 1;
	*key = new_key;
	return retval;
}
Esempio n. 16
0
static int
parse_subtypes( const char *target, int *baseLenp, char **langp,
				_SubStringIndex **subs, int *nsubtypes )
{
	int nSubtypes = 0;
	int ind = 0;
	char *nextToken;
 	_SubStringIndex *result = NULL;
	int langIndex;
	int targetLen;
	int subtypeStart;

	langIndex = LANG_SUBTYPE_INDEX_NONE;
	*subs = NULL;
	*langp = NULL;
	*baseLenp = 0;
	*nsubtypes = 0;
	targetLen = strlen( target );

	/* Parse past base attribute */
	nextToken = strchr( target, ';' );
	if ( NULL != nextToken ) {
		subtypeStart = nextToken - target + 1;
		*baseLenp = subtypeStart - 1;
	}
	else {
		subtypeStart = targetLen;
		*baseLenp = subtypeStart;
	}
	ind = subtypeStart;

	/* How many subtypes? */
	nextToken = (char *)target + subtypeStart;
	while ( nextToken && *nextToken ) {
		char *thisToken = nextToken;
		nextToken = strchr( thisToken, ';' );
		if ( NULL != nextToken )
			nextToken++;
		if ( 0 == strncasecmp( thisToken, "lang-", 5 ) ) {
			/* If there was a previous lang tag, this is illegal! */
			if ( langIndex != LANG_SUBTYPE_INDEX_NONE ) {
				langIndex = LANG_SUBTYPE_INDEX_DUPLICATE;
				return langIndex;
			}
			else {
				langIndex = nSubtypes;
			}
		} else {
			nSubtypes++;
		}
	}
	/* No language subtype? */
	if ( langIndex < 0 )
		return langIndex;

	/* Allocate array of non-language subtypes */
	if ( nSubtypes > 0 ) {
		result = (_SubStringIndex *)NSLDAPI_MALLOC( sizeof(*result)
		    * nSubtypes );
		if (result == NULL) {
			return LANG_SUBTYPE_INDEX_NONE;	/* Error */
		}
		memset( result, 0, sizeof(*result) * nSubtypes );
	}
	ind = 0;
	nSubtypes = 0;
	ind = subtypeStart;
	nextToken = (char *)target + subtypeStart;
	while ( nextToken && *nextToken ) {
		char *thisToken = nextToken;
		int len;
		nextToken = strchr( thisToken, ';' );
		if ( NULL != nextToken ) {
			len = nextToken - thisToken;
			nextToken++;
		}
		else {
			nextToken = (char *)target + targetLen;
			len = nextToken - thisToken;
		}
		if ( 0 == strncasecmp( thisToken, "lang-", 5 ) ) {
			int i;
			*langp = (char *)NSLDAPI_MALLOC( len + 1 );
			if (*langp == NULL) {
				if (result != NULL)
					NSLDAPI_FREE(result);
				return LANG_SUBTYPE_INDEX_NONE;	/* Error */
			}
			for( i = 0; i < len; i++ )
				(*langp)[i] = toupper( target[ind+i] );
			(*langp)[len] = 0;
		}
		else {
			result[nSubtypes].start = thisToken - target;
			result[nSubtypes].length = len;
			nSubtypes++;
		}
	}
	*subs = result;
	*nsubtypes = nSubtypes;
	return langIndex;
}
Esempio n. 17
0
/*
 * Abandon all outstanding requests for msgid (included child requests
 * spawned when chasing referrals).  This function calls itself recursively.
 * No locking is done is this function so it must be done by the caller.
 * Returns an LDAP error code and sets it in LDAP *ld as well
 */
static int do_abandon(LDAP *ld, int origid, int msgid,
                      LDAPControl **serverctrls, LDAPControl **clientctrls) {
  BerElement *ber;
  int i, bererr, lderr, sendabandon;
  LDAPRequest *lr = NULL;

  /*
   * An abandon request looks like this:
   * AbandonRequest ::= MessageID
   */
  LDAPDebug(LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n", origid, msgid,
            0);

  /* optimistic */
  lderr = LDAP_SUCCESS;

  /*
   * Find the request that we are abandoning.  Don't send an
   * abandon message unless there is something to abandon.
   */
  sendabandon = 0;
  for (lr = ld->ld_requests; lr != NULL; lr = lr->lr_next) {
    if (lr->lr_msgid == msgid) { /* this message */
      if (origid == msgid && lr->lr_parent != NULL) {
        /* don't let caller abandon child requests! */
        lderr = LDAP_PARAM_ERROR;
        goto set_errorcode_and_return;
      }
      if (lr->lr_status == LDAP_REQST_INPROGRESS) {
        /*
         * We only need to send an abandon message if
         * the request is in progress.
         */
        sendabandon = 1;
      }
      break;
    }
    if (lr->lr_origid == msgid) { /* child:  abandon it */
      (void)do_abandon(ld, msgid, lr->lr_msgid, serverctrls, clientctrls);
      /* we ignore errors from child abandons... */
    }
  }

  if (ldap_msgdelete(ld, msgid) == 0) {
    /* we had all the results and deleted them */
    goto set_errorcode_and_return;
  }

  if (lr != NULL && sendabandon) {
    /* create a message to send */
    if ((lderr = nsldapi_alloc_ber_with_options(ld, &ber)) == LDAP_SUCCESS) {
      int abandon_msgid;

      LDAP_MUTEX_LOCK(ld, LDAP_MSGID_LOCK);
      abandon_msgid = ++ld->ld_msgid;
      LDAP_MUTEX_UNLOCK(ld, LDAP_MSGID_LOCK);
#ifdef CLDAP
      if (ld->ld_dbp->sb_naddr > 0) {
        bererr = ber_printf(ber, "{isti", abandon_msgid, ld->ld_cldapdn,
                            LDAP_REQ_ABANDON, msgid);
      } else {
#endif /* CLDAP */
        bererr =
            ber_printf(ber, "{iti", abandon_msgid, LDAP_REQ_ABANDON, msgid);
#ifdef CLDAP
      }
#endif /* CLDAP */

      if (bererr == -1 || (lderr = nsldapi_put_controls(ld, serverctrls, 1,
                                                        ber)) != LDAP_SUCCESS) {
        lderr = LDAP_ENCODING_ERROR;
        ber_free(ber, 1);
      } else {
        /* try to send the message */
        lderr =
            nsldapi_send_abandon_message(ld, lr->lr_conn, ber, abandon_msgid);
      }
    }
  }

  if (lr != NULL) {
    /*
     * Always call nsldapi_free_connection() so that the connection's
     * ref count is correctly decremented.  It is OK to always pass
     * 1 for the "unbind" parameter because doing so will only affect
     * connections that resulted from a child request (because the
     * default connection's ref count never goes to zero).
     */
    nsldapi_free_connection(ld, lr->lr_conn, NULL, NULL, 0 /* do not force */,
                            1 /* send unbind before closing */);

    /*
     * Free the entire request chain if we finished abandoning everything.
     */
    if (origid == msgid) {
      nsldapi_free_request(ld, lr, 0);
    }
  }

  /*
   * Record the abandoned message ID (used to discard any server responses
   * that arrive later).
   */
  LDAP_MUTEX_LOCK(ld, LDAP_ABANDON_LOCK);
  if (ld->ld_abandoned == NULL) {
    if ((ld->ld_abandoned = (int *)NSLDAPI_MALLOC(2 * sizeof(int))) == NULL) {
      lderr = LDAP_NO_MEMORY;
      LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);
      goto set_errorcode_and_return;
    }
    i = 0;
  } else {
    for (i = 0; ld->ld_abandoned[i] != -1; i++)
      ; /* NULL */
    if ((ld->ld_abandoned = (int *)NSLDAPI_REALLOC(
             (char *)ld->ld_abandoned, (i + 2) * sizeof(int))) == NULL) {
      lderr = LDAP_NO_MEMORY;
      LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);
      goto set_errorcode_and_return;
    }
  }
  ld->ld_abandoned[i] = msgid;
  ld->ld_abandoned[i + 1] = -1;
  LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);

set_errorcode_and_return:
  LDAP_SET_LDERRNO(ld, lderr, NULL, NULL);
  return (lderr);
}
Esempio n. 18
0
static int
do_vals2text(
	LDAP			*ld,
	char			*buf,		/* NULL for "use internal" */
	char			**vals,
	char			*label,
	int			labelwidth,	/* 0 means use default */
	unsigned long		syntaxid,
	writeptype		writeproc,
	void			*writeparm,
	char			*eol,
	int			rdncount,
	char			*urlprefix
)
{
    int		err, i, html, writeoutval, freebuf, notascii;
    char	*p, *s, *outval;

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || writeproc == NULL ) {
	return( LDAP_PARAM_ERROR );
    }

    if ( vals == NULL ) {
	return( LDAP_SUCCESS );
    }

    html = ( urlprefix != NULL );

    switch( LDAP_GET_SYN_TYPE( syntaxid )) {
    case LDAP_SYN_TYPE_TEXT:
    case LDAP_SYN_TYPE_BOOLEAN:
	break;		/* we only bother with these two types... */
    default:
	return( LDAP_SUCCESS );
    }

    if ( labelwidth == 0 || labelwidth < 0 ) {
	labelwidth = DEF_LABEL_WIDTH;
    }

    if ( buf == NULL ) {
	if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) {
	    err = LDAP_NO_MEMORY;
	    LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	    return( err );
	}
	freebuf = 1;
    } else {
	freebuf = 0;
    }

    output_label( buf, label, labelwidth, writeproc, writeparm, eol, html );

    for ( i = 0; vals[ i ] != NULL; ++i ) {
	for ( p = vals[ i ]; *p != '\0'; ++p ) {
	    if ( !isascii( *p )) {
		break;
	    }
	}
	notascii = ( *p != '\0' );
	outval = notascii ? dgettext(TEXT_DOMAIN,
		"(unable to display non-ASCII text value)")
		: vals[ i ];

	writeoutval = 0;	/* if non-zero, write outval after switch */

	switch( syntaxid ) {
	case LDAP_SYN_CASEIGNORESTR:
	    ++writeoutval;
	    break;

	case LDAP_SYN_RFC822ADDR:
	    if ( html ) {
		strcpy( buf, "<DD><A HREF=\"mailto:" );
		strcat_escaped( buf, outval );
		sprintf( buf + strlen( buf ), "\">%s</A><BR>%s", outval, eol );
		(*writeproc)( writeparm, buf, strlen( buf ));
	    } else {
		++writeoutval;
	    }
	    break;

	case LDAP_SYN_DN:	/* for now */
	    output_dn( buf, outval, labelwidth, rdncount, writeproc,
		    writeparm, eol, urlprefix );
	    break;

	case LDAP_SYN_MULTILINESTR:
	    if ( i > 0 && !html ) {
		output_label( buf, label, labelwidth, writeproc,
			writeparm, eol, html );
	    }

	    p = s = outval;
	    while (( s = strchr( s, '$' )) != NULL ) {
		*s++ = '\0';
		while ( ldap_utf8isspace( s )) {
		    ++s;
		}
		if ( html ) {
		    sprintf( buf, "<DD>%s<BR>%s", p, eol );
		} else {
		    sprintf( buf, "%-*s%s%s", labelwidth, " ", p, eol );
		}
		(*writeproc)( writeparm, buf, strlen( buf ));
		p = s;
	    }
	    outval = p;
	    ++writeoutval;
	    break;

	case LDAP_SYN_BOOLEAN:
	    outval = toupper( outval[ 0 ] ) == 'T' ?
		dgettext(TEXT_DOMAIN, "TRUE") : dgettext(TEXT_DOMAIN, "FALSE");
	    ++writeoutval;
	    break;

	case LDAP_SYN_TIME:
	case LDAP_SYN_DATE:
	    outval = time2text( outval, syntaxid == LDAP_SYN_DATE );
	    ++writeoutval;
	    break;

	case LDAP_SYN_LABELEDURL:
	    if ( !notascii && ( p = strchr( outval, '$' )) != NULL ) {
		*p++ = '\0';
		while ( ldap_utf8isspace( p )) {
		    ++p;
		}
		s = outval;
	    } else if ( !notascii && ( s = strchr( outval, ' ' )) != NULL ) {
		*s++ = '\0';
		while ( ldap_utf8isspace( s )) {
		    ++s;
		}
		p = outval;
	    } else {
		s = "URL";
		p = outval;
	    }

	    /*
	     * at this point `s' points to the label & `p' to the URL
	     */
	    if ( html ) {
		sprintf( buf, "<DD><A HREF=\"%s\">%s</A><BR>%s", p, s, eol );
	    } else {
		sprintf( buf, "%-*s%s%s%-*s%s%s", labelwidth, " ",
		    s, eol, labelwidth + 2, " ",p , eol );
	    }
	    (*writeproc)( writeparm, buf, strlen( buf ));
	    break;

	default:
	    sprintf( buf, dgettext(TEXT_DOMAIN,
		" Can't display item type %ld%s"),
		    syntaxid, eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	}

	if ( writeoutval ) {
	    if ( html ) {
		sprintf( buf, "<DD>%s<BR>%s", outval, eol );
	    } else {
		sprintf( buf, "%-*s%s%s", labelwidth, " ", outval, eol );
	    }
	    (*writeproc)( writeparm, buf, strlen( buf ));
	}
    }

    if ( freebuf ) {
	NSLDAPI_FREE( buf );
    }

    return( LDAP_SUCCESS );
}
Esempio n. 19
0
LDAP_CALL
ldap_tmplattrs( struct ldap_disptmpl *tmpl, char **includeattrs,
                int exclude, unsigned long syntaxmask )
{
    /*
     * this routine should filter out duplicate attributes...
     */
    struct ldap_tmplitem	*tirowp, *ticolp;
    int			i, attrcnt, memerr;
    char		**attrs;

    attrcnt = 0;
    memerr = 0;

    if (( attrs = (char **)NSLDAPI_MALLOC( sizeof( char * ))) == NULL ) {
        return( NULL );
    }

    if ( includeattrs != NULL ) {
        for ( i = 0; !memerr && includeattrs[ i ] != NULL; ++i ) {
            if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 ) *
                                                    sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] =
                                                            nsldapi_strdup( includeattrs[ i ] )) == NULL ) {
                memerr = 1;
            } else {
                attrs[ attrcnt ] = NULL;
            }
        }
    }

    for ( tirowp = ldap_first_tmplrow( tmpl );
            !memerr && tirowp != NULLTMPLITEM;
            tirowp = ldap_next_tmplrow( tmpl, tirowp )) {
        for ( ticolp = ldap_first_tmplcol( tmpl, tirowp );
                ticolp != NULLTMPLITEM;
                ticolp = ldap_next_tmplcol( tmpl, tirowp, ticolp )) {

            if ( syntaxmask != 0 ) {
                if (( exclude &&
                        ( syntaxmask & ticolp->ti_syntaxid ) != 0 ) ||
                        ( !exclude &&
                          ( syntaxmask & ticolp->ti_syntaxid ) == 0 )) {
                    continue;
                }
            }

            if ( ticolp->ti_attrname != NULL ) {
                if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 )
                                                        * sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] =
                                                                nsldapi_strdup( ticolp->ti_attrname )) == NULL ) {
                    memerr = 1;
                } else {
                    attrs[ attrcnt ] = NULL;
                }
            }
        }
    }

    if ( memerr || attrcnt == 0 ) {
        for ( i = 0; i < attrcnt; ++i ) {
            if ( attrs[ i ] != NULL ) {
                NSLDAPI_FREE( attrs[ i ] );
            }
        }

        NSLDAPI_FREE( (char *)attrs );
        return( NULL );
    }

    return( attrs );
}
Esempio n. 20
0
static int
do_entry2text(
	LDAP			*ld,
	char			*buf,		/* NULL for use-internal */
	char			*base,		/* used for search actions */
	LDAPMessage		*entry,
	struct ldap_disptmpl	*tmpl,
	char			**defattrs,
	char			***defvals,
	writeptype		writeproc,
	void			*writeparm,
	char			*eol,
	int			rdncount,
	unsigned long		opts,
	char			*urlprefix	/* if non-NULL, do HTML */
)
{
    int				i, err, html, show, labelwidth;
    int				freebuf,  freevals;
    char			*dn, **vals;
    struct ldap_tmplitem	*rowp, *colp;

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
	return( LDAP_PARAM_ERROR );
    }

    if ( writeproc == NULL ||
	    !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) {
	err = LDAP_PARAM_ERROR;
	LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	return( err );
    }

    if (( dn = ldap_get_dn( ld, entry )) == NULL ) {
	return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
    }

    if ( buf == NULL ) {
	if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) {
	    err = LDAP_NO_MEMORY;
	    LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	    NSLDAPI_FREE( dn );
	    return( err );
	}
	freebuf = 1;
    } else {
	freebuf = 0;
    }

    html = ( urlprefix != NULL );

    if ( html ) {
	/*
	 * add HTML intro. and title
	 */
	if (!(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) {
	    sprintf( buf, "<HTML>%s<HEAD>%s<TITLE>%s%s - ", eol, eol, eol,
		    ( tmpl == NULL ) ? "Entry" : tmpl->dt_name );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	    output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
	    sprintf( buf, "%s</TITLE>%s</HEAD>%s<BODY>%s<H3>%s - ", eol, eol,
		    eol, eol, ( tmpl == NULL ) ? "Entry" : tmpl->dt_name );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	    output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
	    sprintf( buf, "</H3>%s", eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	}

	if (( opts & LDAP_DISP_OPT_NONLEAF ) != 0 &&
		( vals = ldap_explode_dn( dn, 0 )) != NULL ) {
	    char	*untagged;

	    /*
	     * add "Move Up" link
	     */
	    sprintf( buf, "<A HREF=\"%s", urlprefix );
	    for ( i = 1; vals[ i ] != NULL; ++i ) {
		if ( i > 1 ) {
		     strcat_escaped( buf, ", " );
		}
		strcat_escaped( buf, vals[ i ] );
	    }
	    if ( vals[ 1 ] != NULL ) {
		untagged = strchr( vals[ 1 ], '=' );
	    } else {
		untagged = "=The World";
	    }
	    sprintf( buf + strlen( buf ),
		    "%s\">Move Up To <EM>%s</EM></A>%s<BR>",
		    ( vals[ 1 ] == NULL ) ? "??one" : "",
		    ( untagged != NULL ) ? untagged + 1 : vals[ 1 ], eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));

	    /*
	     * add "Browse" link
	     */
	    untagged = strchr( vals[ 0 ], '=' );
	    sprintf( buf, "<A HREF=\"%s", urlprefix );
	    strcat_escaped( buf, dn );
	    sprintf( buf + strlen( buf ), "??one?(!(objectClass=dsa))\">Browse Below <EM>%s</EM></A>%s%s",
		    ( untagged != NULL ) ? untagged + 1 : vals[ 0 ], eol, eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));

	    ldap_value_free( vals );
	}

	(*writeproc)( writeparm, "<HR>", 4 );	/* horizontal rule */
    } else {
	(*writeproc)( writeparm, "\"", 1 );
	output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
	sprintf( buf, "\"%s", eol );
	(*writeproc)( writeparm, buf, strlen( buf ));
    }

    if ( tmpl != NULL && ( opts & LDAP_DISP_OPT_AUTOLABELWIDTH ) != 0 ) {
	labelwidth = max_label_len( tmpl ) + 3;
    } else {
	labelwidth = DEF_LABEL_WIDTH;;
    }

    err = LDAP_SUCCESS;

    if ( tmpl == NULL ) {
	BerElement	*ber;
	char		*attr;

	ber = NULL;
	for ( attr = ldap_first_attribute( ld, entry, &ber );
		NONFATAL_LDAP_ERR( err ) && attr != NULL;
		attr = ldap_next_attribute( ld, entry, ber )) {
	    if (( vals = ldap_get_values( ld, entry, attr )) == NULL ) {
		freevals = 0;
		if ( defattrs != NULL ) {
		    for ( i = 0; defattrs[ i ] != NULL; ++i ) {
			if ( strcasecmp( attr, defattrs[ i ] ) == 0 ) {
			    break;
			}
		    }
		    if ( defattrs[ i ] != NULL ) {
			vals = defvals[ i ];
		    }
		}
	    } else {
		freevals = 1;
	    }

	    if ( islower( *attr )) {	/* cosmetic -- upcase attr. name */
		*attr = toupper( *attr );
	    }

	    err = do_vals2text( ld, buf, vals, attr, labelwidth,
		    LDAP_SYN_CASEIGNORESTR, writeproc, writeparm, eol, 
		    rdncount, urlprefix );
	    if ( freevals ) {
		ldap_value_free( vals );
	    }
	}
	if ( ber == NULL ) {
	    ber_free( ber, 0 );
	}
	/*
	 * XXX check for errors in ldap_first_attribute/ldap_next_attribute
	 * here (but what should we do if there was one?)
	 */

    } else {
	for ( rowp = ldap_first_tmplrow( tmpl );
		NONFATAL_LDAP_ERR( err ) && rowp != NULLTMPLITEM;
		rowp = ldap_next_tmplrow( tmpl, rowp )) {
	    for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM;
		    colp = ldap_next_tmplcol( tmpl, rowp, colp )) {
		vals = NULL;
		if ( colp->ti_attrname == NULL || ( vals = ldap_get_values( ld,
			entry, colp->ti_attrname )) == NULL ) {
		    freevals = 0;
		    if ( !LDAP_IS_TMPLITEM_OPTION_SET( colp,
			    LDAP_DITEM_OPT_HIDEIFEMPTY ) && defattrs != NULL
			    && colp->ti_attrname != NULL ) {
			for ( i = 0; defattrs[ i ] != NULL; ++i ) {
			    if ( strcasecmp( colp->ti_attrname, defattrs[ i ] )
				    == 0 ) {
				break;
			    }
			}
			if ( defattrs[ i ] != NULL ) {
			    vals = defvals[ i ];
			}
		    }
		} else {
		    freevals = 1;
		    if ( LDAP_IS_TMPLITEM_OPTION_SET( colp,
			    LDAP_DITEM_OPT_SORTVALUES ) && vals[ 0 ] != NULL
			    && vals[ 1 ] != NULL ) {
			ldap_sort_values(ld, vals, ldap_sort_strcasecmp);
		    }
		}

		/*
		 * don't bother even calling do_vals2text() if no values
		 * or boolean with value false and "hide if false" option set
		 */
		show = ( vals != NULL && vals[ 0 ] != NULL );
		if ( show && LDAP_GET_SYN_TYPE( colp->ti_syntaxid )
			== LDAP_SYN_TYPE_BOOLEAN && LDAP_IS_TMPLITEM_OPTION_SET(
			colp, LDAP_DITEM_OPT_HIDEIFFALSE ) &&
			toupper( vals[ 0 ][ 0 ] ) != 'T' ) {
		    show = 0;
		}

		if ( colp->ti_syntaxid == LDAP_SYN_SEARCHACTION ) {
		    if (( opts & LDAP_DISP_OPT_DOSEARCHACTIONS ) != 0 ) {
			if ( colp->ti_attrname == NULL || ( show &&
				toupper( vals[ 0 ][ 0 ] ) == 'T' )) {
			    err = searchaction( ld, buf, base, entry, dn, colp,
				    labelwidth, rdncount, writeproc,
				    writeparm, eol, urlprefix );
			}
		    }
		    show = 0;
		}

		if ( show ) {
		    err = do_vals2text( ld, buf, vals, colp->ti_label,
			labelwidth, colp->ti_syntaxid, writeproc, writeparm,
			eol, rdncount, urlprefix );
		}

		if ( freevals ) {
		    ldap_value_free( vals );
		}
	    }
	}
    }

    if ( html  && !(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) {
	sprintf( buf, "</BODY>%s</HTML>%s", eol, eol );
	(*writeproc)( writeparm, buf, strlen( buf ));
    }

    NSLDAPI_FREE( dn );
    if ( freebuf ) {
	NSLDAPI_FREE( buf );
    }

    return( err );
}
Esempio n. 21
0
static int
searchaction( LDAP *ld, char *buf, char *base, LDAPMessage *entry, char *dn,
	struct ldap_tmplitem *tip, int labelwidth, int rdncount,
	writeptype writeproc, void *writeparm, char *eol, char *urlprefix )
{
    int			err = LDAP_SUCCESS, lderr, i, count, html;
    char		**vals, **members;
    char		*value, *filtpattern, *attr, *selectname;
    char		*retattrs[2], filter[ 256 ];
    LDAPMessage		*ldmp;
    struct timeval	timeout;

    html = ( urlprefix != NULL );

    for ( i = 0; tip->ti_args != NULL && tip->ti_args[ i ] != NULL; ++i ) {
	;
    }
    if ( i < 3 ) {
	return( LDAP_PARAM_ERROR );
    }
    attr = tip->ti_args[ 0 ];
    filtpattern = tip->ti_args[ 1 ];
    retattrs[ 0 ] = tip->ti_args[ 2 ];
    retattrs[ 1 ] = NULL;
    selectname = tip->ti_args[ 3 ];

    vals = NULL;
    if ( attr == NULL ) {
	value = NULL;
    } else if ( strcasecmp( attr, "-dnb" ) == 0 ) {
	return( LDAP_PARAM_ERROR );
    } else if ( strcasecmp( attr, "-dnt" ) == 0 ) {
	value = dn;
    } else if (( vals = ldap_get_values( ld, entry, attr )) != NULL ) {
	value = vals[ 0 ];
    } else {
	value = NULL;
    }

    ldap_build_filter( filter, sizeof( filter ), filtpattern, NULL, NULL, NULL,
	    value, NULL );

    if ( html ) {
	/*
	 * if we are generating HTML, we add an HREF link that embodies this
	 * search action as an LDAP URL, instead of actually doing the search
	 * now.
	 */
	sprintf( buf, "<DT><A HREF=\"%s", urlprefix );
	if ( base != NULL ) {
	    strcat_escaped( buf, base );
	}
	strcat( buf, "??sub?" );
	strcat_escaped( buf, filter );
	sprintf( buf + strlen( buf ), "\"><B>%s</B></A><DD><BR>%s",
		tip->ti_label, eol );
	if ((*writeproc)( writeparm, buf, strlen( buf )) < 0 ) {
	    return( LDAP_LOCAL_ERROR );
	}
	return( LDAP_SUCCESS );
    }

    timeout.tv_sec = SEARCH_TIMEOUT_SECS;
    timeout.tv_usec = 0;

#ifdef CLDAP
    if ( LDAP_IS_CLDAP( ld ))
	lderr = cldap_search_s( ld, base, LDAP_SCOPE_SUBTREE, filter, retattrs,
		0, &ldmp, NULL );
    else
#endif /* CLDAP */
	lderr = ldap_search_st( ld, base, LDAP_SCOPE_SUBTREE, filter,
		retattrs, 0, &timeout, &ldmp );

    if ( lderr == LDAP_SUCCESS || NONFATAL_LDAP_ERR( lderr )) {
	if (( count = ldap_count_entries( ld, ldmp )) > 0 ) {
	    if (( members = (char **)NSLDAPI_MALLOC( (count + 1)
		    * sizeof(char *))) == NULL ) {
		err = LDAP_NO_MEMORY;
	    } else {
		for ( i = 0, entry = ldap_first_entry( ld, ldmp );
			entry != NULL;
			entry = ldap_next_entry( ld, entry ), ++i ) {
		    members[ i ] = ldap_get_dn( ld, entry );
		}
		members[ i ] = NULL;

		ldap_sort_values(ld,members, ldap_sort_strcasecmp);

		err = do_vals2text( ld, NULL, members, tip->ti_label,
			html ? -1 : 0, LDAP_SYN_DN, writeproc, writeparm,
			eol, rdncount, urlprefix );

		ldap_value_free( members );
	    }
	}
	ldap_msgfree( ldmp );
    }

    
    if ( vals != NULL ) {
	ldap_value_free( vals );
    }

    return(( err == LDAP_SUCCESS ) ? lderr : err );
}