예제 #1
0
파일: open.c 프로젝트: kele/illumos-fsd
/* returns 0 if connection opened and -1 if an error occurs */
int
nsldapi_open_ldap_defconn( LDAP *ld )
{
	LDAPServer	*srv;

	if (( srv = (LDAPServer *)NSLDAPI_CALLOC( 1, sizeof( LDAPServer ))) ==
	    NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host =
	    nsldapi_strdup( ld->ld_defhost )) == NULL )) {
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		return( -1 );
	}
	srv->lsrv_port = ld->ld_defport;

#ifdef LDAP_SSLIO_HOOKS
	if (( ld->ld_options & LDAP_BITOPT_SSL ) != 0 ) {
		srv->lsrv_options |= LDAP_SRV_OPT_SECURE;
	}
#endif

	if (( ld->ld_defconn = nsldapi_new_connection( ld, &srv, 1, 1, 0 ))
	    == NULL ) {
		if ( ld->ld_defhost != NULL ) {
			NSLDAPI_FREE( srv->lsrv_host );
		}
		NSLDAPI_FREE( (char *)srv );
		return( -1 );
	}
	++ld->ld_defconn->lconn_refcnt;	/* so it never gets closed/freed */

	return( 0 );
}
예제 #2
0
void LDAP_CALL ldap_value_free(char **vals) {
  int i;

  if (vals == NULL) return;
  for (i = 0; vals[i] != NULL; i++) NSLDAPI_FREE(vals[i]);
  NSLDAPI_FREE((char *)vals);
}
예제 #3
0
void
LDAP_CALL
ldap_free_sort_keylist (
	LDAPsortkey **sortKeyList
)
{
	LDAPsortkey *this_one = NULL;
	int i = 0;

	if ( NULL == sortKeyList ) {
		return;
	}

	/* Walk down the list freeing the LDAPsortkey structures */
	for (this_one = sortKeyList[0]; this_one ; this_one = sortKeyList[++i]) {
		/* Free the strings, if present */
		if (NULL != this_one->sk_attrtype) {
			NSLDAPI_FREE(this_one->sk_attrtype);
		}
		if (NULL != this_one->sk_matchruleoid) {
			NSLDAPI_FREE(this_one->sk_matchruleoid);
		}
		NSLDAPI_FREE(this_one);
	}
	/* Free the pointer list */
	NSLDAPI_FREE(sortKeyList);
}
예제 #4
0
파일: request.c 프로젝트: andreiw/polaris
void
nsldapi_free_connection( LDAP *ld, LDAPConn *lc, LDAPControl **serverctrls,
    LDAPControl **clientctrls, int force, int unbind )
{
	LDAPConn	*tmplc, *prevlc;

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

	if ( force || --lc->lconn_refcnt <= 0 ) {
		if ( lc->lconn_status == LDAP_CONNST_CONNECTED ) {
			nsldapi_iostatus_interest_clear( ld, lc->lconn_sb );
			if ( unbind ) {
				nsldapi_send_unbind( ld, lc->lconn_sb,
				    serverctrls, clientctrls );
			}
		}
		nsldapi_close_connection( ld, lc->lconn_sb );
		prevlc = NULL;
		for ( tmplc = ld->ld_conns; tmplc != NULL;
		    tmplc = tmplc->lconn_next ) {
			if ( tmplc == lc ) {
				if ( prevlc == NULL ) {
				    ld->ld_conns = tmplc->lconn_next;
				} else {
				    prevlc->lconn_next = tmplc->lconn_next;
				}
				break;
			}
			prevlc = tmplc;
		}
		free_servers( lc->lconn_server );
		if ( lc->lconn_krbinstance != NULL ) {
			NSLDAPI_FREE( lc->lconn_krbinstance );
		}
		/*
		 * if this is the default connection (lc->lconn_sb==ld->ld_sbp)
		 * we do not free the Sockbuf here since it will be freed
		 * later inside ldap_unbind().
		 */
		if ( lc->lconn_sb != ld->ld_sbp ) {
			ber_sockbuf_free( lc->lconn_sb );
			lc->lconn_sb = NULL;
		}
		if ( lc->lconn_ber != NULLBER ) {
			ber_free( lc->lconn_ber, 1 );
		}
		if ( lc->lconn_binddn != NULL ) {
			NSLDAPI_FREE( lc->lconn_binddn );
		}
		NSLDAPI_FREE( lc );
		LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_free_connection: actually freed\n",
		    0, 0, 0 );
	} else {
		lc->lconn_lastused = time( 0 );
		LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_free_connection: refcnt %d\n",
		    lc->lconn_refcnt, 0, 0 );
	}
}
예제 #5
0
void LDAP_CALL
ldap_x_hostlist_statusfree(struct ldap_x_hostlist_status *status) {
  if (NULL != status) {
    if (NULL != status->lhs_hostlist) {
      NSLDAPI_FREE(status->lhs_hostlist);
    }
    NSLDAPI_FREE(status);
  }
}
예제 #6
0
void LDAP_CALL ldap_value_free_len(struct berval **vals) {
  int i;

  if (vals == NULL) return;
  for (i = 0; vals[i] != NULL; i++) {
    NSLDAPI_FREE(vals[i]->bv_val);
    NSLDAPI_FREE(vals[i]);
  }
  NSLDAPI_FREE((char *)vals);
}
예제 #7
0
파일: request.c 프로젝트: andreiw/polaris
void
nsldapi_free_request( LDAP *ld, LDAPRequest *lr, int free_conn )
{
	LDAPRequest	*tmplr, *nextlr;

	LDAPDebug( LDAP_DEBUG_TRACE,
		"nsldapi_free_request 0x%x (origid %d, msgid %d)\n",
		lr, lr->lr_origid, lr->lr_msgid );

	if ( lr->lr_parent != NULL ) {
		--lr->lr_parent->lr_outrefcnt;
	}

	/* free all of our spawned referrals (child requests) */
	for ( tmplr = lr->lr_child; tmplr != NULL; tmplr = nextlr ) {
		nextlr = tmplr->lr_sibling;
		nsldapi_free_request( ld, tmplr, free_conn );
	}

	if ( free_conn ) {
		nsldapi_free_connection( ld, lr->lr_conn, NULL, NULL, 0, 1 );
	}

	if ( lr->lr_prev == NULL ) {
		ld->ld_requests = lr->lr_next;
	} else {
		lr->lr_prev->lr_next = lr->lr_next;
	}

	if ( lr->lr_next != NULL ) {
		lr->lr_next->lr_prev = lr->lr_prev;
	}

	if ( lr->lr_ber != NULL ) {
		ber_free( lr->lr_ber, 1 );
	}

	if ( lr->lr_res_error != NULL ) {
		NSLDAPI_FREE( lr->lr_res_error );
	}

	if ( lr->lr_res_matched != NULL ) {
		NSLDAPI_FREE( lr->lr_res_matched );
	}

	if ( lr->lr_binddn != NULL ) {
		NSLDAPI_FREE( lr->lr_binddn );
	}
	NSLDAPI_FREE( lr );
}
예제 #8
0
void
LDAP_CALL
ldap_control_free( LDAPControl *ctrl )
{
	if ( ctrl != NULL ) {
		if ( ctrl->ldctl_oid != NULL ) {
			NSLDAPI_FREE( ctrl->ldctl_oid );
		}
		if ( ctrl->ldctl_value.bv_val != NULL ) {
			NSLDAPI_FREE( ctrl->ldctl_value.bv_val );
		}
		NSLDAPI_FREE( (char *)ctrl );
	}
}
예제 #9
0
파일: url.c 프로젝트: rn10950/RetroZilla
void
LDAP_CALL
ldap_free_urldesc( LDAPURLDesc *ludp )
{
	if ( ludp != NULLLDAPURLDESC ) {
		if ( ludp->lud_string != NULL ) {
			NSLDAPI_FREE( ludp->lud_string );
		}
		if ( ludp->lud_attrs != NULL ) {
			NSLDAPI_FREE( ludp->lud_attrs );
		}
		NSLDAPI_FREE( ludp );
	}
}
예제 #10
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 );
}
예제 #11
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 );
}
예제 #12
0
void nsldapi_handle_reconnect( LDAP *ld )
{

	LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_handle_reconnect\n", 0, 0, 0 );
	
	/*
	 * if the default connection has been lost and is now marked dead,
	 * dispose of the default connection so it will get re-established.
	 *
	 * if not, clear the bind DN and status to ensure that we don't
	 * report the wrong bind DN to a different thread while waiting
	 * for our bind result to return from the server.
	 */
	LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
	if ( NULL != ld->ld_defconn ) {
	    if ( LDAP_CONNST_DEAD == ld->ld_defconn->lconn_status ) {
			nsldapi_free_connection( ld, ld->ld_defconn, NULL, NULL, 1, 0 );
			ld->ld_defconn = NULL;
	    } else if ( ld->ld_defconn->lconn_binddn != NULL ) {
			NSLDAPI_FREE( ld->ld_defconn->lconn_binddn );
			ld->ld_defconn->lconn_binddn = NULL;
			ld->ld_defconn->lconn_bound = 0;
	    }
	}
	LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
}
예제 #13
0
LDAP_CALL
ldap_getfirstfilter( LDAPFiltDesc *lfdp, char *tagpat, char *value )
{
    LDAPFiltList	*flp;

    if ( lfdp == NULL || tagpat == NULL || value == NULL ) {
	return( NULL );	/* punt */
    }

    if ( lfdp->lfd_curvalcopy != NULL ) {
	NSLDAPI_FREE( lfdp->lfd_curvalcopy );
	NSLDAPI_FREE( lfdp->lfd_curvalwords );
    }

    NSLDAPI_FREE(lfdp->lfd_curval);
    if ((lfdp->lfd_curval = nsldapi_strdup(value)) == NULL) {
	return( NULL );
    }

    lfdp->lfd_curfip = NULL;

    for ( flp = lfdp->lfd_filtlist; flp != NULL; flp = flp->lfl_next ) {
	if ( re_comp( tagpat ) == NULL && re_exec( flp->lfl_tag ) == 1
		&& re_comp( flp->lfl_pattern ) == NULL
		&& re_exec( lfdp->lfd_curval ) == 1 ) {
	    lfdp->lfd_curfip = flp->lfl_ilist;
	    break;
	}
    }

    if ( lfdp->lfd_curfip == NULL ) {
	return( NULL );
    }

    if (( lfdp->lfd_curvalcopy = nsldapi_strdup( value )) == NULL ) {
	return( NULL );
    }

    if ( break_into_words( lfdp->lfd_curvalcopy, flp->lfl_delims,
		&lfdp->lfd_curvalwords ) < 0 ) {
	NSLDAPI_FREE( lfdp->lfd_curvalcopy );
	lfdp->lfd_curvalcopy = NULL;
	return( NULL );
    }

    return( ldap_getnextfilter( lfdp ));
}
예제 #14
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 );
}
예제 #15
0
파일: request.c 프로젝트: andreiw/polaris
static void
free_servers( LDAPServer *srvlist )
{
    LDAPServer	*nextsrv;

    while ( srvlist != NULL ) {
	nextsrv = srvlist->lsrv_next;
	if ( srvlist->lsrv_dn != NULL ) {
		NSLDAPI_FREE( srvlist->lsrv_dn );
	}
	if ( srvlist->lsrv_host != NULL ) {
		NSLDAPI_FREE( srvlist->lsrv_host );
	}
	NSLDAPI_FREE( srvlist );
	srvlist = nextsrv;
    }
}
예제 #16
0
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 );
}
예제 #17
0
int LDAP_CALL ldap_set_filter_additions(LDAPFiltDesc *lfdp, char *prefix,
                                        char *suffix) {
  if (lfdp == NULL) {
    return (LDAP_PARAM_ERROR);
  }

  if (lfdp->lfd_filtprefix != NULL) {
    NSLDAPI_FREE(lfdp->lfd_filtprefix);
  }
  lfdp->lfd_filtprefix = (prefix == NULL) ? NULL : nsldapi_strdup(prefix);

  if (lfdp->lfd_filtsuffix != NULL) {
    NSLDAPI_FREE(lfdp->lfd_filtsuffix);
  }
  lfdp->lfd_filtsuffix = (suffix == NULL) ? NULL : nsldapi_strdup(suffix);

  return (LDAP_SUCCESS);
}
예제 #18
0
void
LDAP_CALL
ldap_controls_free( LDAPControl **ctrls )
{
	int	i;

	if ( ctrls != NULL ) {
		for ( i = 0; ctrls[i] != NULL; i++ ) {
			ldap_control_free( ctrls[i] );
		}
		NSLDAPI_FREE( (char *)ctrls );
	}
}
예제 #19
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 );
}
예제 #20
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 );
}
예제 #21
0
파일: request.c 프로젝트: andreiw/polaris
/*
 * returns an LDAP error code
 *
 * XXXmcs: this function used to have #ifdef LDAP_DNS code in it but I
 *	removed it when I improved the parsing (we don't define LDAP_DNS
 *	here at Netscape).
 */
static int
chase_one_referral( LDAP *ld, LDAPRequest *lr, LDAPRequest *origreq,
    char *refurl, char *desc, int *unknownp )
{
	int		rc, tmprc, secure, msgid;
	LDAPServer	*srv;
	BerElement	*ber;
	LDAPURLDesc	*ludp;

	*unknownp = 0;
	ludp = NULLLDAPURLDESC;

	if ( nsldapi_url_parse( refurl, &ludp, 0 ) != 0 ) {
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "ignoring unknown %s <%s>\n", desc, refurl, 0 );
		*unknownp = 1;
		rc = LDAP_SUCCESS;
		goto cleanup_and_return;
	}

	secure = (( ludp->lud_options & LDAP_URL_OPT_SECURE ) != 0 );

/* XXXmcs: can't tell if secure is supported by connect callback */
	if ( secure && ld->ld_extconnect_fn == NULL ) {
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "ignoring LDAPS %s <%s>\n", desc, refurl, 0 );
		*unknownp = 1;
		rc = LDAP_SUCCESS;
		goto cleanup_and_return;
	}

	LDAPDebug( LDAP_DEBUG_TRACE, "chasing LDAP%s %s: <%s>\n",
	    secure ? "S" : "", desc, refurl );

	LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
	msgid = ++ld->ld_msgid;
	LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );

	if (( tmprc = re_encode_request( ld, origreq->lr_ber, msgid,
	    ludp, &ber )) != LDAP_SUCCESS ) {
		rc = tmprc;
		goto cleanup_and_return;
	}

	if (( srv = (LDAPServer *)NSLDAPI_CALLOC( 1, sizeof( LDAPServer )))
	    == NULL ) {
		ber_free( ber, 1 );
		rc = LDAP_NO_MEMORY;
		goto cleanup_and_return;
	}

	if (ludp->lud_host == NULL && ld->ld_defhost == NULL) {
		srv->lsrv_host = NULL;
	} else {
		if (ludp->lud_host == NULL) {
			srv->lsrv_host =
			    nsldapi_strdup( origreq->lr_conn->lconn_server->lsrv_host );
			LDAPDebug(LDAP_DEBUG_TRACE,
			    "chase_one_referral: using hostname '%s' from original "
			    "request on new request\n",
			    srv->lsrv_host, 0, 0);
		} else {
			srv->lsrv_host = nsldapi_strdup(ludp->lud_host);
			LDAPDebug(LDAP_DEBUG_TRACE,
			    "chase_one_referral: using hostname '%s' as specified "
			    "on new request\n",
			    srv->lsrv_host, 0, 0);
		}

		if (srv->lsrv_host == NULL) {
			NSLDAPI_FREE((char *)srv);
			ber_free(ber, 1);
			rc = LDAP_NO_MEMORY;
			goto cleanup_and_return;
		}
	}

	/*
	 * According to our reading of RFCs 2255 and 1738, the
	 * following algorithm applies:
	 * - no hostport (no host, no port) provided in LDAP URL, use those
	 *   of previous request
	 * - no port but a host, use default LDAP port
	 * - else use given hostport
	 */
	if (ludp->lud_port == 0 && ludp->lud_host == NULL) {
		srv->lsrv_port = origreq->lr_conn->lconn_server->lsrv_port;
		LDAPDebug(LDAP_DEBUG_TRACE,
		    "chase_one_referral: using port (%d) from original "
		    "request on new request\n",
		    srv->lsrv_port, 0, 0);
	} else if (ludp->lud_port == 0 && ludp->lud_host != NULL) {
		srv->lsrv_port = (secure) ? LDAPS_PORT : LDAP_PORT;
		LDAPDebug(LDAP_DEBUG_TRACE,
		    "chase_one_referral: using default port (%d) \n",
		    srv->lsrv_port, 0, 0);
	} else {
		srv->lsrv_port = ludp->lud_port;
		LDAPDebug(LDAP_DEBUG_TRACE,
		    "chase_one_referral: using port (%d) as specified on "
		    "new request\n",
		    srv->lsrv_port, 0, 0);
	}

	if ( secure ) {
		srv->lsrv_options |= LDAP_SRV_OPT_SECURE;
	}

	if ( nsldapi_send_server_request( ld, ber, msgid,
	    lr, srv, NULL, NULL, 1 ) < 0 ) {
		rc = LDAP_GET_LDERRNO( ld, NULL, NULL );
		LDAPDebug( LDAP_DEBUG_ANY, "Unable to chase %s %s (%s)\n",
		    desc, refurl, ldap_err2string( rc ));
	} else {
		rc = LDAP_SUCCESS;
	}

cleanup_and_return:
	if ( ludp != NULLLDAPURLDESC ) {
		ldap_free_urldesc( ludp );
	}

	return( rc );
}
예제 #22
0
파일: request.c 프로젝트: andreiw/polaris
/*
 * Initiate chasing of LDAPv2+ (Umich extension) referrals.
 *
 * Returns an LDAP error code.
 *
 * Note that *hadrefp will be set to 1 if one or more referrals were found in
 * "*errstrp" (even if we can't chase them) and zero if none were found.
 * 
 * XXX merging of errors in this routine needs to be improved.
 */
int
nsldapi_chase_v2_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp,
    int *totalcountp, int *chasingcountp )
{
	char		*p, *ref, *unfollowed;
	LDAPRequest	*origreq;
	int		rc, tmprc, len, unknown;

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

	*totalcountp = *chasingcountp = 0;

	if ( *errstrp == NULL ) {
		return( LDAP_SUCCESS );
	}

	len = strlen( *errstrp );
	for ( p = *errstrp; len >= LDAP_REF_STR_LEN; ++p, --len ) {
		if (( *p == 'R' || *p == 'r' ) && strncasecmp( p,
		    LDAP_REF_STR, LDAP_REF_STR_LEN ) == 0 ) {
			*p = '\0';
			p += LDAP_REF_STR_LEN;
			break;
		}
	}

	if ( len < LDAP_REF_STR_LEN ) {
		return( LDAP_SUCCESS );
	}

	if ( lr->lr_parentcnt >= ld->ld_refhoplimit ) {
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "more than %d referral hops (dropping)\n",
		    ld->ld_refhoplimit, 0, 0 );
		return( LDAP_REFERRAL_LIMIT_EXCEEDED );
	}

	/* find original request */
	for ( origreq = lr; origreq->lr_parent != NULL;
	     origreq = origreq->lr_parent ) {
		;
	}

	unfollowed = NULL;
	rc = LDAP_SUCCESS;

	/* parse out & follow referrals */
	for ( ref = p; rc == LDAP_SUCCESS && ref != NULL; ref = p ) {
		if (( p = strchr( ref, '\n' )) != NULL ) {
			*p++ = '\0';
		} else {
			p = NULL;
		}

		++*totalcountp;

		rc = chase_one_referral( ld, lr, origreq, ref, "v2 referral",
		    &unknown );

		if ( rc != LDAP_SUCCESS || unknown ) {
			if (( tmprc = nsldapi_append_referral( ld, &unfollowed,
			    ref )) != LDAP_SUCCESS ) {
				rc = tmprc;
			}
		} else {
			++*chasingcountp;
		}
	}

	NSLDAPI_FREE( *errstrp );
	*errstrp = unfollowed;

	return( rc );
}
예제 #23
0
파일: request.c 프로젝트: andreiw/polaris
LDAPConn *
nsldapi_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
	int connect, int bind )
{
    int	rc;
    
	LDAPConn	*lc;
	LDAPServer	*prevsrv, *srv;
	Sockbuf		*sb = NULL;

	/*
	 * make a new LDAP server connection
	 */
	if (( lc = (LDAPConn *)NSLDAPI_CALLOC( 1, sizeof( LDAPConn ))) == NULL
	    || ( !use_ldsb && ( sb = ber_sockbuf_alloc()) == NULL )) {
		if ( lc != NULL ) {
			NSLDAPI_FREE( (char *)lc );
		}
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		return( NULL );
	}

	LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
	if ( !use_ldsb ) {
		/*
		 * we have allocated a new sockbuf
		 * set I/O routines to match those in default LDAP sockbuf
		 */
		IFP				sb_fn;
		struct lber_x_ext_io_fns	extiofns;
		
		extiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;

		if ( ber_sockbuf_get_option( ld->ld_sbp,
		    LBER_SOCKBUF_OPT_EXT_IO_FNS, &extiofns ) == 0 ) {
			ber_sockbuf_set_option( sb,
			    LBER_SOCKBUF_OPT_EXT_IO_FNS, &extiofns );
		}
		if ( ber_sockbuf_get_option( ld->ld_sbp,
		    LBER_SOCKBUF_OPT_READ_FN, (void *)&sb_fn ) == 0
		    && sb_fn != NULL ) {
			ber_sockbuf_set_option( sb, LBER_SOCKBUF_OPT_READ_FN,
			    (void *)sb_fn );
		}
		if ( ber_sockbuf_get_option( ld->ld_sbp,
		    LBER_SOCKBUF_OPT_WRITE_FN, (void *)&sb_fn ) == 0
		    && sb_fn != NULL ) {
			ber_sockbuf_set_option( sb, LBER_SOCKBUF_OPT_WRITE_FN,
			    (void *)sb_fn );
		}
	}

	lc->lconn_sb = ( use_ldsb ) ? ld->ld_sbp : sb;
	lc->lconn_version = ld->ld_version;	/* inherited */
	LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );

	if ( connect ) {
		prevsrv = NULL;
        /* 
         * save the return code for later
         */ 
		for ( srv = *srvlistp; srv != NULL; srv = srv->lsrv_next ) {
			rc = nsldapi_connect_to_host( ld, lc->lconn_sb,
				   srv->lsrv_host, srv->lsrv_port,
			       (  srv->lsrv_options & LDAP_SRV_OPT_SECURE ) != 0,
					&lc->lconn_krbinstance );
			if (rc != -1) {
				break;
			}
			prevsrv = srv;
		}

		if ( srv == NULL ) {
		    if ( !use_ldsb ) {
			NSLDAPI_FREE( (char *)lc->lconn_sb );
		    }
		    NSLDAPI_FREE( (char *)lc );
		    /* nsldapi_open_ldap_connection has already set ld_errno */
		    return( NULL );
		}

		if ( prevsrv == NULL ) {
		    *srvlistp = srv->lsrv_next;
		} else {
		    prevsrv->lsrv_next = srv->lsrv_next;
		}
		lc->lconn_server = srv;
	}

	if (ld->ld_options & LDAP_BITOPT_ASYNC && rc == -2)
    {
        lc->lconn_status = LDAP_CONNST_CONNECTING;
    }
    else {
        lc->lconn_status = LDAP_CONNST_CONNECTED;
    }
    
	lc->lconn_next = ld->ld_conns;
	ld->ld_conns = lc;

	/*
	 * XXX for now, we always do a synchronous bind.  This will have
	 * to change in the long run...
	 */
	if ( bind ) {
		int		err, lderr, freepasswd, authmethod;
		char		*binddn, *passwd;
		LDAPConn	*savedefconn;

		freepasswd = err = 0;

		if ( ld->ld_rebind_fn == NULL ) {
			binddn = passwd = "";
			authmethod = LDAP_AUTH_SIMPLE;
		} else {
			if (( lderr = (*ld->ld_rebind_fn)( ld, &binddn, &passwd,
			    &authmethod, 0, ld->ld_rebind_arg ))
			    == LDAP_SUCCESS ) {
				freepasswd = 1;
			} else {
				LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
				err = -1;
			}
		}


		if ( err == 0 ) {
			savedefconn = ld->ld_defconn;
			ld->ld_defconn = lc;
			++lc->lconn_refcnt;	/* avoid premature free */

			/*
			 * when binding, we will back down as low as LDAPv2
			 * if we get back "protocol error" from bind attempts
			 */
			for ( ;; ) {
				/* LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK); */
				if (( lderr = ldap_bind_s( ld, binddn, passwd,
				    authmethod )) == LDAP_SUCCESS ) {
					/* LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK); */
					break;
				}
				/* LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK); */
				if ( lc->lconn_version <= LDAP_VERSION2
				    || lderr != LDAP_PROTOCOL_ERROR ) {
					err = -1;
					break;
				}
				--lc->lconn_version;	/* try lower version */
			}
			--lc->lconn_refcnt;
			ld->ld_defconn = savedefconn;
		}

		if ( freepasswd ) {
			(*ld->ld_rebind_fn)( ld, &binddn, &passwd,
				&authmethod, 1, ld->ld_rebind_arg );
		}

		if ( err != 0 ) {
			nsldapi_free_connection( ld, lc, NULL, NULL, 1, 0 );
			lc = NULL;
		}
	}

	return( lc );
}
예제 #24
0
파일: request.c 프로젝트: andreiw/polaris
/* returns the message id of the request or -1 if an error occurs */
int
nsldapi_send_server_request(
    LDAP *ld,			/* session handle */
    BerElement *ber,		/* message to send */
    int msgid,			/* ID of message to send */
    LDAPRequest *parentreq,	/* non-NULL for referred requests */
    LDAPServer *srvlist,	/* servers to connect to (NULL for default) */
    LDAPConn *lc,		/* connection to use (NULL for default) */
    char *bindreqdn,		/* non-NULL for bind requests */
    int bind			/* perform a bind after opening new conn.? */
)
{
	LDAPRequest	*lr;
	int		err;
	int		incparent;	/* did we bump parent's ref count? */

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

	incparent = 0;
	LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
	if ( lc == NULL ) {
		if ( srvlist == NULL ) {
			if ( ld->ld_defconn == NULL ) {
				LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
				if ( bindreqdn == NULL && ( ld->ld_options
				    & LDAP_BITOPT_RECONNECT ) != 0 ) {
					LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN,
					    NULL, NULL );
					ber_free( ber, 1 );
					LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
					LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
					return( -1 );
				}
				LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );

				if ( nsldapi_open_ldap_defconn( ld ) < 0 ) {
					ber_free( ber, 1 );
					LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
					return( -1 );
				}
			}
			lc = ld->ld_defconn;
		} else {
			if (( lc = find_connection( ld, srvlist, 1 )) ==
			    NULL ) {
				if ( bind && (parentreq != NULL) ) {
					/* Remember the bind in the parent */
					incparent = 1;
					++parentreq->lr_outrefcnt;
				}

				lc = nsldapi_new_connection( ld, &srvlist, 0,
					1, bind );
			}
			free_servers( srvlist );
		}
	}


    /*
     * the logic here is:
     * if 
     * 1. no connections exists, 
     * or 
     * 2. if the connection is either not in the connected 
     *     or connecting state in an async io model
     * or 
     * 3. the connection is notin a connected state with normal (non async io)
     */
	if (   lc == NULL
		|| (  (ld->ld_options & LDAP_BITOPT_ASYNC 
               && lc->lconn_status != LDAP_CONNST_CONNECTING
		    && lc->lconn_status != LDAP_CONNST_CONNECTED)
              || (!(ld->ld_options & LDAP_BITOPT_ASYNC )
		    && lc->lconn_status != LDAP_CONNST_CONNECTED) ) ) {

		ber_free( ber, 1 );
		if ( lc != NULL ) {
			LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN, NULL, NULL );
		}
		if ( incparent ) {
			/* Forget about the bind */
			--parentreq->lr_outrefcnt; 
		}
		LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
		return( -1 );
	}

	use_connection( ld, lc );
	if (( lr = (LDAPRequest *)NSLDAPI_CALLOC( 1, sizeof( LDAPRequest ))) ==
	    NULL || ( bindreqdn != NULL && ( bindreqdn =
	    nsldapi_strdup( bindreqdn )) == NULL )) {
		if ( lr != NULL ) {
			NSLDAPI_FREE( lr );
		}
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		nsldapi_free_connection( ld, lc, NULL, NULL, 0, 0 );
		ber_free( ber, 1 );
		if ( incparent ) {
			/* Forget about the bind */
			--parentreq->lr_outrefcnt; 
		}
		LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
		return( -1 );
	} 
	lr->lr_binddn = bindreqdn;
	lr->lr_msgid = msgid;
	lr->lr_status = LDAP_REQST_INPROGRESS;
	lr->lr_res_errno = LDAP_SUCCESS;	/* optimistic */
	lr->lr_ber = ber;
	lr->lr_conn = lc;

	if ( parentreq != NULL ) {	/* sub-request */
		if ( !incparent ) { 
			/* Increment if we didn't do it before the bind */
			++parentreq->lr_outrefcnt;
		}
		lr->lr_origid = parentreq->lr_origid;
		lr->lr_parentcnt = parentreq->lr_parentcnt + 1;
		lr->lr_parent = parentreq;
		if ( parentreq->lr_child != NULL ) {
			lr->lr_sibling = parentreq->lr_child;
		}
		parentreq->lr_child = lr;
	} else {			/* original request */
		lr->lr_origid = lr->lr_msgid;
	}

	LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
	if (( lr->lr_next = ld->ld_requests ) != NULL ) {
		lr->lr_next->lr_prev = lr;
	}
	ld->ld_requests = lr;
	lr->lr_prev = NULL;

	if (( err = nsldapi_ber_flush( ld, lc->lconn_sb, ber, 0, 1 )) != 0 ) {

		/* need to continue write later */
		if (ld->ld_options & LDAP_BITOPT_ASYNC && err == -2 ) {	
			lr->lr_status = LDAP_REQST_WRITING;
			nsldapi_iostatus_interest_write( ld, lc->lconn_sb );
		} else {

			LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN, NULL, NULL );
			nsldapi_free_request( ld, lr, 0 );
			nsldapi_free_connection( ld, lc, NULL, NULL, 0, 0 );
			LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
			LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
			return( -1 );
		}

	} else {
		if ( parentreq == NULL ) {
			ber->ber_end = ber->ber_ptr;
			ber->ber_ptr = ber->ber_buf;
		}

		/* sent -- waiting for a response */
		if (ld->ld_options & LDAP_BITOPT_ASYNC) {
			lc->lconn_status = LDAP_CONNST_CONNECTED;
		}

		nsldapi_iostatus_interest_read( ld, lc->lconn_sb );
	}
	LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
	LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );

	LDAP_SET_LDERRNO( ld, LDAP_SUCCESS, NULL, NULL );
	return( msgid );
}
예제 #25
0
파일: request.c 프로젝트: andreiw/polaris
/* returns an LDAP error code */
static int
re_encode_request( LDAP *ld, BerElement *origber, int msgid, LDAPURLDesc *ludp,
    BerElement **berp )
{
/*
 * XXX this routine knows way too much about how the lber library works!
 */
	ber_uint_t		along;
	ber_tag_t		tag;
	ber_int_t		ver;
	int			rc;
	BerElement		*ber;
	struct berelement	tmpber;
	char			*dn, *orig_dn;

	LDAPDebug( LDAP_DEBUG_TRACE,
	    "re_encode_request: new msgid %d, new dn <%s>\n",
	    msgid, ( ludp->lud_dn == NULL ) ? "NONE" : ludp->lud_dn, 0 );

	tmpber = *origber;

	/*
	 * All LDAP requests are sequences that start with a message id.  For
	 * everything except delete requests, this is followed by a sequence
	 * that is tagged with the operation code.  For deletes, there is just
	 * a DN that is tagged with the operation code.
	 */

	/* skip past msgid and get operation tag */
	if ( ber_scanf( &tmpber, "{it", &along, &tag ) == LBER_ERROR ) {
		return( LDAP_DECODING_ERROR );
	}

	/*
	 * XXXmcs: we don't support scope or filters in search referrals yet,
	 * so if either were present we return an error which is probably
	 * better than just ignoring the extra info.
	 */
	if ( tag == LDAP_REQ_SEARCH &&
	    ( ludp->lud_scope != -1 || ludp->lud_filter != NULL )) {
		return( LDAP_LOCAL_ERROR );
	}

	if ( tag == LDAP_REQ_BIND ) {
		/* bind requests have a version number before the DN */
		rc = ber_scanf( &tmpber, "{ia", &ver, &orig_dn );
	} else if ( tag == LDAP_REQ_DELETE ) {
		/* delete requests DNs are not within a sequence */
		rc = ber_scanf( &tmpber, "a", &orig_dn );
	} else {
		rc = ber_scanf( &tmpber, "{a", &orig_dn );
	}

	if ( rc == LBER_ERROR ) {
		return( LDAP_DECODING_ERROR );
	}

	if ( ludp->lud_dn == NULL ) {
		dn = orig_dn;
	} else {
		dn = ludp->lud_dn;
		NSLDAPI_FREE( orig_dn );
		orig_dn = NULL;
	}

	/* allocate and build the new request */
        if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
	    != LDAP_SUCCESS ) {
		if ( orig_dn != NULL ) {
			NSLDAPI_FREE( orig_dn );
		}
                return( rc );
        }

	if ( tag == LDAP_REQ_BIND ) {
		rc = ber_printf( ber, "{it{is", msgid, tag,
		    (int)ver /* XXX lossy cast */, dn );
	} else if ( tag == LDAP_REQ_DELETE ) {
		rc = ber_printf( ber, "{its}", msgid, tag, dn );
	} else {
		rc = ber_printf( ber, "{it{s", msgid, tag, dn );
	}

	if ( orig_dn != NULL ) {
		NSLDAPI_FREE( orig_dn );
	}
/*
 * can't use "dn" or "orig_dn" from this point on (they've been freed)
 */

	if ( rc == -1 ) {
		ber_free( ber, 1 );
		return( LDAP_ENCODING_ERROR );
	}

	if ( tag != LDAP_REQ_DELETE &&
	    ( ber_write( ber, tmpber.ber_ptr, ( tmpber.ber_end -
	    tmpber.ber_ptr ), 0 ) != ( tmpber.ber_end - tmpber.ber_ptr )
	    || ber_printf( ber, "}}" ) == -1 )) {
		ber_free( ber, 1 );
		return( LDAP_ENCODING_ERROR );
	}

#ifdef LDAP_DEBUG
	if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
		LDAPDebug( LDAP_DEBUG_ANY, "re_encode_request new request is:\n",
		    0, 0, 0 );
		ber_dump( ber, 0 );
	}
#endif /* LDAP_DEBUG */

	*berp = ber;
	return( LDAP_SUCCESS );
}
예제 #26
0
/*
 * Pull the oid returned by the server and the data out of an extended
 * operation result.  Return an LDAP error code.
 */
int
LDAP_CALL
ldap_parse_extended_result(
    LDAP		*ld,
    LDAPMessage		*res,
    char		**retoidp,	/* may be NULL */
    struct berval	**retdatap,	/* may be NULL */
    int			freeit
)
{
	struct berelement	ber;
	unsigned long		len;
	long			err;
	char			*m, *e, *roid;
	struct berval		*rdata;

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

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

        if ( !NSLDAPI_VALID_LDAPMESSAGE_EXRESULT_POINTER( res )) {
		return( LDAP_PARAM_ERROR );
	}

	m = e = NULL;
	ber = *(res->lm_ber);
	if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
		LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
		return( LDAP_NOT_SUPPORTED );
	}

	if ( ber_scanf( &ber, "{iaa", &err, &m, &e ) == LBER_ERROR ) {
		goto decoding_error;
	}
	roid = NULL;
	if ( ber_peek_tag( &ber, &len ) == LDAP_TAG_EXOP_RES_OID ) {
		if ( ber_scanf( &ber, "a", &roid ) == LBER_ERROR ) {
			goto decoding_error;
		}
	}
	if ( retoidp != NULL ) {
		*retoidp = roid;
	} else if ( roid != NULL ) {
		NSLDAPI_FREE( roid );
	}

	rdata = NULL;
	if ( ber_peek_tag( &ber, &len ) == LDAP_TAG_EXOP_RES_VALUE ) {
		if ( ber_scanf( &ber, "O", &rdata ) == LBER_ERROR ) {
			goto decoding_error;
		}
	}
	if ( retdatap != NULL ) {
		*retdatap = rdata;
	} else if ( rdata != NULL ) {
		ber_bvfree( rdata );
	}

	LDAP_SET_LDERRNO( ld, err, m, e );

	if ( freeit ) {
		ldap_msgfree( res );
	}

	return( LDAP_SUCCESS );

decoding_error:;
	LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
	return( LDAP_DECODING_ERROR );
}
예제 #27
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;
}
예제 #28
0
파일: open.c 프로젝트: kele/illumos-fsd
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 );
}
예제 #29
0
static int
check_lang_match( const char *target, const char *baseTarget,
				  _SubStringIndex *targetTypes,
				  int ntargetTypes, char *targetLang, char *attr )
{
	int langIndex;
 	_SubStringIndex *subtypes;
	int baseLen;
	char *lang;
	int nsubtypes;
	int mismatch = 0;
	int match = -1;
	int i;

	/* Get all subtypes in the attribute name */
 	langIndex = parse_subtypes( attr, &baseLen, &lang, &subtypes, &nsubtypes );

	/* Check if there any required non-language subtypes which are
	   not in this attribute */
	for( i = 0; i < ntargetTypes; i++ ) {
		char *t = (char *)target+targetTypes[i].start;
		int tlen = targetTypes[i].length;
		int j;
		for( j = 0; j < nsubtypes; j++ ) {
			char *a = attr + subtypes[j].start;
			int alen = subtypes[j].length;
			if ( (tlen == alen) && !strncasecmp( t, a, tlen ) )
				break;
		}
		if ( j >= nsubtypes ) {
			mismatch = 1;
			break;
		}
	}
	if ( mismatch ) {
	    if ( NULL != subtypes )
		    NSLDAPI_FREE( subtypes );
		if ( NULL != lang )
		    NSLDAPI_FREE( lang );
		return -1;
	}

	/* If there was no language subtype... */
	if ( langIndex < 0 ) {
	    if ( NULL != subtypes )
		    NSLDAPI_FREE( subtypes );
		if ( NULL != lang )
		    NSLDAPI_FREE( lang );
		if ( LANG_SUBTYPE_INDEX_NONE == langIndex )
			return 0;
		else
			return -1;
	}

	/* Okay, now check the language subtag */
	i = 0;
	while( targetLang[i] && lang[i] &&
			(toupper(targetLang[i]) == toupper(lang[i])) )
		i++;

	/* The total length can't be longer than the requested subtype */
	if ( !lang[i] || (lang[i] == ';') ) {
		/* If the found subtype is shorter than the requested one, the next
		   character in the requested one should be "-" */
		if ( !targetLang[i] || (targetLang[i] == '-') )
			match = i;
	}
	return match;
}
예제 #30
0
int
nsldapi_sasl_secprops(
        const char *in,
        sasl_security_properties_t *secprops )
{
        int i;
        char **props = NULL;
        char *inp;
        unsigned sflags = 0;
        sasl_ssf_t max_ssf = 0;
        sasl_ssf_t min_ssf = 0;
        unsigned maxbufsize = 0;
        int got_sflags = 0;
        int got_max_ssf = 0;
        int got_min_ssf = 0;
        int got_maxbufsize = 0;

        if (in == NULL) {
                return LDAP_PARAM_ERROR;
        }
        inp = nsldapi_strdup(in);
        if (inp == NULL) {
                return LDAP_PARAM_ERROR;
        }
        props = ldap_str2charray( inp, "," );
        NSLDAPI_FREE( inp );

        if( props == NULL || secprops == NULL ) {
                return LDAP_PARAM_ERROR;
        }

        for( i=0; props[i]; i++ ) {
                if( strcasecmp(props[i], "none") == 0 ) {
                        got_sflags++;

                } else if( strcasecmp(props[i], "noactive") == 0 ) {
                        got_sflags++;
                        sflags |= SASL_SEC_NOACTIVE;

                } else if( strcasecmp(props[i], "noanonymous") == 0 ) {
                        got_sflags++;
                        sflags |= SASL_SEC_NOANONYMOUS;

                } else if( strcasecmp(props[i], "nodict") == 0 ) {
                        got_sflags++;
                        sflags |= SASL_SEC_NODICTIONARY;

                } else if( strcasecmp(props[i], "noplain") == 0 ) {
                        got_sflags++;
                        sflags |= SASL_SEC_NOPLAINTEXT;

                } else if( strcasecmp(props[i], "forwardsec") == 0 ) {
                        got_sflags++;
                        sflags |= SASL_SEC_FORWARD_SECRECY;

                } else if( strcasecmp(props[i], "passcred") == 0 ) {
                        got_sflags++;
                        sflags |= SASL_SEC_PASS_CREDENTIALS;

                } else if( strncasecmp(props[i],
                        "minssf=", sizeof("minssf")) == 0 ) {
                        if( isdigit( props[i][sizeof("minssf")] ) ) {
                                got_min_ssf++;
                                min_ssf = atoi( &props[i][sizeof("minssf")] );
                        } else {
                                return LDAP_NOT_SUPPORTED;
                        }

                } else if( strncasecmp(props[i],
                        "maxssf=", sizeof("maxssf")) == 0 ) {
                        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")) == 0 ) {
                        if( isdigit( props[i][sizeof("maxbufsize")] ) ) {
                                got_maxbufsize++;
                                maxbufsize = atoi( &props[i][sizeof("maxbufsize")] );
                                if( maxbufsize &&
                                    (( maxbufsize < SASL_MIN_BUFF_SIZE )
                                    || (maxbufsize > SASL_MAX_BUFF_SIZE ))) {
                                        return( LDAP_PARAM_ERROR );
                                }
                        } 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 );
}