/* * 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); }
/* * 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 ); }
/* 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 ); }
/* 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); }
/* * 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 ); }
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 ); }
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(¤t_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 ); }
/* * 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 ); }
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 ); }
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; }
/* * 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 ); }
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 ); }
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 ); }
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; }
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; }
/* * 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); }
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 ); }
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 ); }
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 ); }
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 ); }