static int nsldapi_search_s( LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, struct timeval *localtimeoutp, int timelimit, /* -1 means use ld->ld_timelimit */ int sizelimit, /* -1 means use ld->ld_sizelimit */ LDAPMessage **res ) { int err, msgid; /* * It is an error to pass in a zero'd timeval. */ if ( localtimeoutp != NULL && localtimeoutp->tv_sec == 0 && localtimeoutp->tv_usec == 0 ) { if ( ld != NULL ) { LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); } if ( res != NULL ) { *res = NULL; } return( LDAP_PARAM_ERROR ); } if (( err = nsldapi_search( ld, base, scope, filter, attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, &msgid )) != LDAP_SUCCESS ) { if ( res != NULL ) { *res = NULL; } return( err ); } if ( ldap_result( ld, msgid, 1, localtimeoutp, res ) == -1 ) { /* * Error. ldap_result() sets *res to NULL for us. */ return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } if ( LDAP_GET_LDERRNO( ld, NULL, NULL ) == LDAP_TIMEOUT ) { (void) ldap_abandon( ld, msgid ); err = LDAP_TIMEOUT; LDAP_SET_LDERRNO( ld, err, NULL, NULL ); if ( res != NULL ) { *res = NULL; } return( err ); } return( ldap_result2error( ld, *res, 0 ) ); }
int LDAP_CALL ldap_url_search_s( LDAP *ld, const char *url, int attrsonly, LDAPMessage **res ) { int msgid; if (( msgid = ldap_url_search( ld, url, attrsonly )) == -1 ) { return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, res ) == -1 ) { return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } return( ldap_result2error( ld, *res, 0 )); }
/* * ldap_extended_operation_s - perform an arbitrary ldapv3 extended operation. * the oid and data of the extended operation are supplied. LDAP_SUCCESS * is returned upon success, the ldap error code otherwise. * * Example: * struct berval exdata, exretval; * char *exoid; * int rc; * ... fill in oid and data ... * rc = ldap_extended_operation_s( ld, exoid, &exdata, &exretval ); */ int LDAP_CALL ldap_extended_operation_s( LDAP *ld, const char *requestoid, const struct berval *requestdata, LDAPControl **serverctrls, LDAPControl **clientctrls, char **retoidp, struct berval **retdatap ) { int err, msgid; LDAPMessage *result; if (( err = ldap_extended_operation( ld, requestoid, requestdata, serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) { return( err ); } if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 ) { return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } if (( err = ldap_parse_extended_result( ld, result, retoidp, retdatap, 0 )) != LDAP_SUCCESS ) { ldap_msgfree( result ); return( err ); } return( ldap_result2error( ld, result, 1 ) ); }
/* * ldap_sasl_bind_s - bind to the ldap server using sasl authentication * The dn, mechanism, and credentials of the entry to which to bind are * supplied. LDAP_SUCCESS is returned upon success, the ldap error code * otherwise. * * Example: * struct berval creds; * ... fill in creds with credentials ... * ldap_sasl_bind_s( ld, "cn=manager, o=university of michigan, c=us", * "mechanismname", &creds ) */ int LDAP_CALL ldap_sasl_bind_s( LDAP *ld, const char *dn, const char *mechanism, const struct berval *cred, LDAPControl **serverctrls, LDAPControl **clientctrls, struct berval **servercredp ) { int err, msgid; LDAPMessage *result; LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_bind_s\n", 0, 0, 0 ); if ( ( err = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) return( err ); if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 ) return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); if (( err = ldap_parse_sasl_bind_result( ld, result, servercredp, 0 )) != LDAP_SUCCESS ) { ldap_msgfree( result ); return( err ); } return( ldap_result2error( ld, result, 1 ) ); }
/* * ldap_simple_bind - bind to the ldap server using simple * authentication. The dn and password of the entry to which to bind are * supplied. LDAP_SUCCESS is returned upon success, the ldap error code * otherwise. * * Example: * ldap_simple_bind_s( ld, "cn=manager, o=university of michigan, c=us", * "secret" ) */ int LDAP_CALL ldap_simple_bind_s( LDAP *ld, const char *dn, const char *passwd ) { int msgid; LDAPMessage *result; LDAPDebug( LDAP_DEBUG_TRACE, "ldap_simple_bind_s\n", 0, 0, 0 ); if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { return( LDAP_PARAM_ERROR ); } if ( (msgid = ldap_simple_bind( ld, dn, passwd )) == -1 ) return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 ) return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); return( ldap_result2error( ld, result, 1 ) ); }
/* * ldap_simple_bind - bind to the ldap server using simple * authentication. The dn and password of the entry to which to bind are * supplied. LDAP_SUCCESS is returned upon success, the ldap error code * otherwise. * * Example: * ldap_simple_bind_s( ld, "cn=manager, o=university of michigan, c=us", * "secret" ) */ int LDAP_CALL ldap_simple_bind_s( LDAP *ld, const char *dn, const char *passwd ) { int msgid; LDAPMessage *result; LDAPDebug( LDAP_DEBUG_TRACE, "ldap_simple_bind_s\n", 0, 0, 0 ); if ( NSLDAPI_VALID_LDAP_POINTER( ld ) && ( ld->ld_options & LDAP_BITOPT_RECONNECT ) != 0 ) { return( simple_bindifnot_s( ld, dn, passwd )); } if ( (msgid = ldap_simple_bind( ld, dn, passwd )) == -1 ) return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 ) return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); return( ldap_result2error( ld, result, 1 ) ); }
int LDAP_CALL ldap_url_search_st( LDAP *ld, const char *url, int attrsonly, struct timeval *timeout, LDAPMessage **res ) { int msgid; /* * It is an error to pass in a zero'd timeval. */ if ( timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0 ) { if ( ld != NULL ) { LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); } if ( res != NULL ) { *res = NULL; } return( LDAP_PARAM_ERROR ); } if (( msgid = ldap_url_search( ld, url, attrsonly )) == -1 ) { return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 ) { return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } if ( LDAP_GET_LDERRNO( ld, NULL, NULL ) == LDAP_TIMEOUT ) { (void) ldap_abandon( ld, msgid ); LDAP_SET_LDERRNO( ld, LDAP_TIMEOUT, NULL, NULL ); return( LDAP_TIMEOUT ); } return( ldap_result2error( ld, *res, 0 )); }
static int nsldapi_sasl_bind_s( LDAP *ld, const char *dn, const char *mechanism, const struct berval *cred, LDAPControl **serverctrls, LDAPControl **clientctrls, struct berval **servercredp, LDAPControl ***responsectrls ) { int err, msgid; LDAPMessage *result; LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_sasl_bind_s\n", 0, 0, 0 ); if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { return( LDAP_PARAM_ERROR ); } if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) { LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL ); return( LDAP_NOT_SUPPORTED ); } if ( ( err = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) return( err ); if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 ) return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); /* Get the controls sent by the server if requested */ if ( responsectrls ) { if ( ( err = ldap_parse_result( ld, result, &err, NULL, NULL, NULL, responsectrls, 0 )) != LDAP_SUCCESS ) return( err ); } err = ldap_parse_sasl_bind_result( ld, result, servercredp, 0 ); if (err != LDAP_SUCCESS && err != LDAP_SASL_BIND_IN_PROGRESS) { ldap_msgfree( result ); return( err ); } return( ldap_result2error( ld, result, 1 ) ); }
int LDAP_CALL ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods, LDAPControl **serverctrls, LDAPControl **clientctrls ) { int msgid, err; LDAPMessage *res; if (( err = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) { return( err ); } if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) { return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } return( ldap_result2error( ld, res, 1 ) ); }
/* * ldap_sasl_bind - authenticate to the ldap server. The dn, mechanism, * and credentials of the entry to which to bind are supplied. An LDAP * error code is returned and if LDAP_SUCCESS is returned *msgidp is set * to the id of the request initiated. * * Example: * struct berval creds; * LDAPControl **ctrls; * int err, msgid; * ... fill in creds with credentials ... * ... fill in ctrls with server controls ... * err = ldap_sasl_bind( ld, "cn=manager, o=university of michigan, c=us", * "mechanismname", &creds, ctrls, NULL, &msgid ); */ int LDAP_CALL ldap_sasl_bind( LDAP *ld, const char *dn, const char *mechanism, const struct berval *cred, LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp ) { BerElement *ber; int rc, simple, msgid, ldapversion; /* * The ldapv3 bind request looks like this: * BindRequest ::= SEQUENCE { * version INTEGER, * name DistinguishedName, -- who * authentication CHOICE { * simple [0] OCTET STRING, -- passwd * sasl [3] SaslCredentials -- v3 only * } * } * SaslCredentials ::= SEQUENCE { * mechanism LDAPString, * credentials OCTET STRING * } * all wrapped up in an LDAPMessage sequence. */ LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 ); if ( msgidp == NULL ) { LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); return( LDAP_PARAM_ERROR ); } simple = ( mechanism == LDAP_SASL_SIMPLE ); ldapversion = NSLDAPI_LDAP_VERSION( ld ); /* only ldapv3 or higher can do sasl binds */ if ( !simple && ldapversion < LDAP_VERSION3 ) { LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL ); return( LDAP_NOT_SUPPORTED ); } LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK ); msgid = ++ld->ld_msgid; LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK ); if ( dn == NULL ) dn = ""; if ( ld->ld_cache_on && ld->ld_cache_bind != NULL ) { LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); if ( (rc = (ld->ld_cache_bind)( ld, msgid, LDAP_REQ_BIND, dn, cred, LDAP_AUTH_SASL )) != 0 ) { *msgidp = rc; LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); return( LDAP_SUCCESS ); } LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); } /* create a message to send */ if (( rc = nsldapi_alloc_ber_with_options( ld, &ber )) != LDAP_SUCCESS ) { return( rc ); } /* fill it in */ if ( simple ) { /* simple bind; works in LDAPv2 or v3 */ struct berval tmpcred; if ( cred == NULL ) { tmpcred.bv_val = ""; tmpcred.bv_len = 0; cred = &tmpcred; } rc = ber_printf( ber, "{it{isto}", msgid, LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SIMPLE, cred->bv_val, (int)cred->bv_len /* XXX lossy cast */ ); } else { /* SASL bind; requires LDAPv3 or better */ if ( cred == NULL ) { rc = ber_printf( ber, "{it{ist{s}}", msgid, LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL, mechanism ); } else { rc = ber_printf( ber, "{it{ist{so}}", msgid, LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL, mechanism, cred->bv_val, (int)cred->bv_len /* XXX lossy cast */ ); } } if ( rc == -1 ) { LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL ); ber_free( ber, 1 ); return( LDAP_ENCODING_ERROR ); } if ( (rc = nsldapi_put_controls( ld, serverctrls, 1, ber )) != LDAP_SUCCESS ) { ber_free( ber, 1 ); return( rc ); } /* send the message */ rc = nsldapi_send_initial_request( ld, msgid, LDAP_REQ_BIND, (char *)dn, ber ); *msgidp = rc; return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS ); }
/* * 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 ); }
int LDAP_CALL ldap_extended_operation( LDAP *ld, const char *exoid, const struct berval *exdata, LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp ) { BerElement *ber; int rc, msgid; /* * the ldapv3 extended operation request looks like this: * * ExtendedRequest ::= [APPLICATION 23] SEQUENCE { * requestName LDAPOID, * requestValue OCTET STRING * } * * all wrapped up in an LDAPMessage sequence. */ LDAPDebug( LDAP_DEBUG_TRACE, "ldap_extended_operation\n", 0, 0, 0 ); if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { return( LDAP_PARAM_ERROR ); } /* only ldapv3 or higher can do extended operations */ if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) { rc = LDAP_NOT_SUPPORTED; LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); return( rc ); } if ( msgidp == NULL || exoid == NULL || *exoid == '\0' ) { rc = LDAP_PARAM_ERROR; LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); return( rc ); } LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK ); msgid = ++ld->ld_msgid; LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK ); #if 0 if ( ld->ld_cache_on && ld->ld_cache_extendedop != NULL ) { LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); if ( (rc = (ld->ld_cache_extendedop)( ld, msgid, LDAP_REQ_EXTENDED, exoid, cred )) != 0 ) { LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); return( rc ); } LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); } #endif /* create a message to send */ if (( rc = nsldapi_alloc_ber_with_options( ld, &ber )) != LDAP_SUCCESS ) { return( rc ); } /* fill it in */ if ( ber_printf( ber, "{it{tsto}", msgid, LDAP_REQ_EXTENDED, LDAP_TAG_EXOP_REQ_OID, exoid, LDAP_TAG_EXOP_REQ_VALUE, exdata->bv_val, (int)exdata->bv_len /* XXX lossy cast */ ) == -1 ) { rc = LDAP_ENCODING_ERROR; LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); ber_free( ber, 1 ); return( rc ); } if (( rc = nsldapi_put_controls( ld, serverctrls, 1, ber )) != LDAP_SUCCESS ) { ber_free( ber, 1 ); return( rc ); } /* send the message */ rc = nsldapi_send_initial_request( ld, msgid, LDAP_REQ_EXTENDED, NULL, ber ); *msgidp = rc; return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS ); }
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 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 ); }
/* * Like ldap_search_ext() except an integer timelimit is passed instead of * using the overloaded struct timeval *timeoutp. */ static int nsldapi_search( LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, int timelimit, /* -1 means use ld->ld_timelimit */ int sizelimit, /* -1 means use ld->ld_sizelimit */ int *msgidp ) { BerElement *ber; int rc, rc_key; unsigned long key; /* XXXmcs: memcache */ LDAPDebug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 ); if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { return( LDAP_PARAM_ERROR ); } if ( base == NULL ) { base = ""; } if ( filter == NULL ) { filter = "(objectclass=*)"; } if ( msgidp == NULL || ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL && scope != LDAP_SCOPE_SUBTREE ) || ( sizelimit < -1 )) { LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); return( LDAP_PARAM_ERROR ); } LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK ); *msgidp = ++ld->ld_msgid; LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK ); /* * XXXmcs: should use cache function pointers to hook in memcache */ if ( ld->ld_memcache == NULL ) { rc_key = LDAP_NOT_SUPPORTED; } else if (( rc_key = ldap_memcache_createkey( ld, base, scope, filter, attrs, attrsonly, serverctrls, clientctrls, &key)) == LDAP_SUCCESS && ldap_memcache_result( ld, *msgidp, key ) == LDAP_SUCCESS ) { return LDAP_SUCCESS; } /* check the cache */ if ( ld->ld_cache_on && ld->ld_cache_search != NULL ) { LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); if ( (rc = (ld->ld_cache_search)( ld, *msgidp, LDAP_REQ_SEARCH, base, scope, filter, attrs, attrsonly )) != 0 ) { *msgidp = rc; LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); return( LDAP_SUCCESS ); } LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); } /* caching off or did not find it in the cache - check the net */ if (( rc = nsldapi_build_search_req( ld, base, scope, filter, attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, *msgidp, &ber )) != LDAP_SUCCESS ) { return( rc ); } /* send the message */ rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_SEARCH, (char *) base, ber ); /* * XXXmcs: should use cache function pointers to hook in memcache */ if ( (rc_key == LDAP_SUCCESS) && (rc >= 0) ) { ldap_memcache_new( ld, rc, key, base ); } *msgidp = rc; return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS ); }
static int nsldapi_get_sasl_mechs ( LDAP *ld, char **pmech ) { char *attr[] = { "supportedSASLMechanisms", NULL }; char **values, **v, *mech, *m; LDAPMessage *res, *e; struct timeval timeout; int slen, rc; if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { return( LDAP_PARAM_ERROR ); } timeout.tv_sec = SEARCH_TIMEOUT_SECS; timeout.tv_usec = 0; rc = ldap_search_st( ld, "", LDAP_SCOPE_BASE, "objectclass=*", attr, 0, &timeout, &res ); if ( rc != LDAP_SUCCESS ) { return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } e = ldap_first_entry( ld, res ); if ( e == NULL ) { ldap_msgfree( res ); if ( ld->ld_errno == LDAP_SUCCESS ) { LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_OBJECT, NULL, NULL ); } return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); } values = ldap_get_values( ld, e, "supportedSASLMechanisms" ); if ( values == NULL ) { ldap_msgfree( res ); LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_ATTRIBUTE, NULL, NULL ); return( LDAP_NO_SUCH_ATTRIBUTE ); } slen = 0; for(v = values; *v != NULL; v++ ) { slen += strlen(*v) + 1; } if ( (mech = NSLDAPI_CALLOC(1, slen)) == NULL) { ldap_value_free( values ); ldap_msgfree( res ); LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL ); return( LDAP_NO_MEMORY ); } m = mech; for(v = values; *v; v++) { if (v != values) { *m++ = ' '; } slen = strlen(*v); strncpy(m, *v, slen); m += slen; } *m = '\0'; ldap_value_free( values ); ldap_msgfree( res ); *pmech = mech; return( LDAP_SUCCESS ); }
int LDAP_CALL ldap_modify_ext( LDAP *ld, const char *dn, LDAPMod **mods, LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp ) { BerElement *ber; int i, rc, lderr; /* * A modify request looks like this: * ModifyRequet ::= SEQUENCE { * object DistinguishedName, * modifications SEQUENCE OF SEQUENCE { * operation ENUMERATED { * add (0), * delete (1), * replace (2) * }, * modification SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } * } */ LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 ); if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { return( LDAP_PARAM_ERROR ); } if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp )) { LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); return( LDAP_PARAM_ERROR ); } if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods )) { lderr = LDAP_PARAM_ERROR; LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); return( lderr ); } if ( dn == NULL ) { dn = ""; } LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK ); *msgidp = ++ld->ld_msgid; LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK ); /* see if we should add to the cache */ if ( ld->ld_cache_on && ld->ld_cache_modify != NULL ) { LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); if ( (rc = (ld->ld_cache_modify)( ld, *msgidp, LDAP_REQ_MODIFY, dn, mods )) != 0 ) { *msgidp = rc; LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); return( LDAP_SUCCESS ); } LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); } /* create a message to send */ if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber )) != LDAP_SUCCESS ) { return( lderr ); } if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_MODIFY, dn ) == -1 ) { lderr = LDAP_ENCODING_ERROR; LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); ber_free( ber, 1 ); return( lderr ); } /* for each modification to be performed... */ for ( i = 0; mods[i] != NULL; i++ ) { if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) { rc = ber_printf( ber, "{e{s[V]}}", mods[i]->mod_op & ~LDAP_MOD_BVALUES, mods[i]->mod_type, mods[i]->mod_bvalues ); } else { rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op, mods[i]->mod_type, mods[i]->mod_values ); } if ( rc == -1 ) { lderr = LDAP_ENCODING_ERROR; LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); ber_free( ber, 1 ); return( lderr ); } } if ( ber_printf( ber, "}}" ) == -1 ) { lderr = LDAP_ENCODING_ERROR; LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); ber_free( ber, 1 ); return( lderr ); } if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber )) != LDAP_SUCCESS ) { ber_free( ber, 1 ); return( lderr ); } /* send the message */ rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODIFY, (char *)dn, ber ); *msgidp = rc; return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS ); }
/* * simple_bindifnot_s() is like ldap_simple_bind_s() except that it only does * a bind if the default connection is not currently bound. * If a successful bind using the same DN has already taken place we just * return LDAP_SUCCESS without conversing with the server at all. */ static int simple_bindifnot_s( LDAP *ld, const char *dn, const char *passwd ) { int msgid, rc; LDAPMessage *result; char *binddn; LDAPDebug( LDAP_DEBUG_TRACE, "simple_bindifnot_s\n", 0, 0, 0 ); if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { return( LDAP_PARAM_ERROR ); } if ( dn == NULL ) { dn = ""; /* to make comparisons simpler */ } /* * if we are already bound using the same DN, just return LDAP_SUCCESS. */ if ( NULL != ( binddn = nsldapi_get_binddn( ld )) && 0 == strcmp( dn, binddn )) { rc = LDAP_SUCCESS; LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); return rc; } /* * 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 ); /* * finally, bind (this will open a new connection if necessary) * * do everything under the protection of the result lock to * ensure that only one thread will be in this code at a time. * XXXmcs: we should use a condition variable instead? */ LDAP_MUTEX_LOCK( ld, LDAP_RESULT_LOCK ); if ( (msgid = simple_bind_nolock( ld, dn, passwd, 0 )) == -1 ) { rc = LDAP_GET_LDERRNO( ld, NULL, NULL ); goto unlock_and_return; } /* * Note that at this point the bind request is on its way to the * server and at any time now we will either be bound as the new * DN (if the bind succeeded) or we will be bound as anonymous (if * the bind failed). */ /* * Wait for the bind result. Code inside result.c:read1msg() * takes care of setting the connection's bind DN and status. */ if ( nsldapi_result_nolock( ld, msgid, 1, 0, (struct timeval *) 0, &result ) == -1 ) { rc = LDAP_GET_LDERRNO( ld, NULL, NULL ); goto unlock_and_return; } rc = ldap_result2error( ld, result, 1 ); unlock_and_return: LDAP_MUTEX_UNLOCK( ld, LDAP_RESULT_LOCK ); return( rc ); }