int shell_back_compare( Operation *op, SlapReply *rs ) { struct shellinfo *si = (struct shellinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; Entry e; FILE *rfp, *wfp; if ( si->si_compare == NULL ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "compare not implemented" ); return( -1 ); } e.e_id = NOID; e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; e.e_attrs = NULL; e.e_ocflags = 0; e.e_bv.bv_len = 0; e.e_bv.bv_val = NULL; e.e_private = NULL; if ( ! access_allowed( op, &e, entry, NULL, ACL_READ, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( forkandexec( si->si_compare, &rfp, &wfp ) == (pid_t)-1 ) { send_ldap_error( op, rs, LDAP_OTHER, "could not fork/exec" ); return( -1 ); } /* * FIX ME: This should use LDIF routines so that binary * values are properly dealt with */ /* write out the request to the compare process */ fprintf( wfp, "COMPARE\n" ); fprintf( wfp, "msgid: %ld\n", (long) op->o_msgid ); print_suffixes( wfp, op->o_bd ); fprintf( wfp, "dn: %s\n", op->o_req_dn.bv_val ); fprintf( wfp, "%s: %s\n", op->oq_compare.rs_ava->aa_desc->ad_cname.bv_val, op->oq_compare.rs_ava->aa_value.bv_val /* could be binary! */ ); fclose( wfp ); /* read in the result and send it along */ read_and_send_results( op, rs, rfp ); fclose( rfp ); return( 0 ); }
int sock_back_compare( Operation *op, SlapReply *rs ) { struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; Entry e; FILE *fp; char *text; e.e_id = NOID; e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; e.e_attrs = NULL; e.e_ocflags = 0; e.e_bv.bv_len = 0; e.e_bv.bv_val = NULL; e.e_private = NULL; if ( ! access_allowed( op, &e, entry, NULL, ACL_COMPARE, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( (fp = opensock( si->si_sockpath )) == NULL ) { send_ldap_error( op, rs, LDAP_OTHER, "could not open socket" ); return( -1 ); } /* write out the request to the compare process */ fprintf( fp, "COMPARE\n" ); fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); sock_print_conn( fp, op->o_conn, si ); sock_print_suffixes( fp, op->o_bd ); fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val ); /* could be binary */ text = ldif_put_wrap( LDIF_PUT_VALUE, op->orc_ava->aa_desc->ad_cname.bv_val, op->orc_ava->aa_value.bv_val, op->orc_ava->aa_value.bv_len, LDIF_LINE_WIDTH_MAX ); if ( text ) { fprintf( fp, "%s\n", text ); ber_memfree( text ); } else { fprintf( fp, "\n\n" ); } /* read in the result and send it along */ sock_read_and_send_results( op, rs, fp ); fclose( fp ); return( 0 ); }
int shell_back_modrdn( Operation *op, SlapReply *rs ) { struct shellinfo *si = (struct shellinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; Entry e; FILE *rfp, *wfp; if ( si->si_modrdn == NULL ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "modrdn not implemented" ); return( -1 ); } e.e_id = NOID; e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; e.e_attrs = NULL; e.e_ocflags = 0; e.e_bv.bv_len = 0; e.e_bv.bv_val = NULL; e.e_private = NULL; if ( ! access_allowed( op, &e, entry, NULL, op->oq_modrdn.rs_newSup ? ACL_WDEL : ACL_WRITE, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( forkandexec( si->si_modrdn, &rfp, &wfp ) == (pid_t)-1 ) { send_ldap_error( op, rs, LDAP_OTHER, "could not fork/exec" ); return( -1 ); } /* write out the request to the modrdn process */ fprintf( wfp, "MODRDN\n" ); fprintf( wfp, "msgid: %ld\n", (long) op->o_msgid ); print_suffixes( wfp, op->o_bd ); fprintf( wfp, "dn: %s\n", op->o_req_dn.bv_val ); fprintf( wfp, "newrdn: %s\n", op->oq_modrdn.rs_newrdn.bv_val ); fprintf( wfp, "deleteoldrdn: %d\n", op->oq_modrdn.rs_deleteoldrdn ? 1 : 0 ); if ( op->oq_modrdn.rs_newSup != NULL ) { fprintf( wfp, "newSuperior: %s\n", op->oq_modrdn.rs_newSup->bv_val ); } fclose( wfp ); /* read in the results and send them along */ read_and_send_results( op, rs, rfp ); fclose( rfp ); return( 0 ); }
static int slap_exop_refresh( Operation *op, SlapReply *rs ) { BackendDB *bd = op->o_bd; rs->sr_err = slap_parse_refresh( op->ore_reqdata, &op->o_req_ndn, NULL, &rs->sr_text, op->o_tmpmemctx ); if ( rs->sr_err != LDAP_SUCCESS ) { return rs->sr_err; } Log2( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO, "%s REFRESH dn=\"%s\"\n", op->o_log_prefix, op->o_req_ndn.bv_val ); op->o_req_dn = op->o_req_ndn; op->o_bd = select_backend( &op->o_req_ndn, 0 ); if ( op->o_bd == NULL ) { send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, "no global superior knowledge" ); goto done; } if ( !SLAP_DYNAMIC( op->o_bd ) ) { send_ldap_error( op, rs, LDAP_UNAVAILABLE_CRITICAL_EXTENSION, "backend does not support dynamic directory services" ); goto done; } rs->sr_err = backend_check_restrictions( op, rs, (struct berval *)&slap_EXOP_REFRESH ); if ( rs->sr_err != LDAP_SUCCESS ) { goto done; } if ( op->o_bd->be_extended == NULL ) { send_ldap_error( op, rs, LDAP_UNAVAILABLE_CRITICAL_EXTENSION, "backend does not support extended operations" ); goto done; } op->o_bd->be_extended( op, rs ); done:; if ( !BER_BVISNULL( &op->o_req_ndn ) ) { op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_req_ndn ); BER_BVZERO( &op->o_req_dn ); } op->o_bd = bd; return rs->sr_err; }
int sock_back_modrdn( Operation *op, SlapReply *rs ) { struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; Entry e; FILE *fp; e.e_id = NOID; e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; e.e_attrs = NULL; e.e_ocflags = 0; e.e_bv.bv_len = 0; e.e_bv.bv_val = NULL; e.e_private = NULL; if ( ! access_allowed( op, &e, entry, NULL, op->oq_modrdn.rs_newSup ? ACL_WDEL : ACL_WRITE, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( (fp = opensock( si->si_sockpath )) == NULL ) { send_ldap_error( op, rs, LDAP_OTHER, "could not open socket" ); return( -1 ); } /* write out the request to the modrdn process */ fprintf( fp, "MODRDN\n" ); fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); sock_print_conn( fp, op->o_conn, si ); sock_print_suffixes( fp, op->o_bd ); fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val ); fprintf( fp, "newrdn: %s\n", op->oq_modrdn.rs_newrdn.bv_val ); fprintf( fp, "deleteoldrdn: %d\n", op->oq_modrdn.rs_deleteoldrdn ? 1 : 0 ); if ( op->oq_modrdn.rs_newSup != NULL ) { fprintf( fp, "newSuperior: %s\n", op->oq_modrdn.rs_newSup->bv_val ); } fprintf( fp, "\n" ); /* read in the results and send them along */ sock_read_and_send_results( op, rs, fp ); fclose( fp ); return( 0 ); }
int sock_back_bind( Operation *op, SlapReply *rs ) { struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; Entry e; FILE *fp; int rc; e.e_id = NOID; e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; e.e_attrs = NULL; e.e_ocflags = 0; e.e_bv.bv_len = 0; e.e_bv.bv_val = NULL; e.e_private = NULL; if ( ! access_allowed( op, &e, entry, NULL, ACL_AUTH, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( (fp = opensock( si->si_sockpath )) == NULL ) { send_ldap_error( op, rs, LDAP_OTHER, "could not open socket" ); return( -1 ); } /* write out the request to the bind process */ fprintf( fp, "BIND\n" ); fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); sock_print_conn( fp, op->o_conn, si ); sock_print_suffixes( fp, op->o_bd ); fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val ); fprintf( fp, "method: %d\n", op->oq_bind.rb_method ); fprintf( fp, "credlen: %lu\n", op->oq_bind.rb_cred.bv_len ); fprintf( fp, "cred: %s\n", op->oq_bind.rb_cred.bv_val ); /* XXX */ fprintf( fp, "\n" ); /* read in the results and send them along */ rc = sock_read_and_send_results( op, rs, fp ); fclose( fp ); return( rc ); }
int sock_back_unbind( Operation *op, SlapReply *rs ) { struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; FILE *fp; if ( (fp = opensock( si->si_sockpath )) == NULL ) { send_ldap_error( op, rs, LDAP_OTHER, "could not open socket" ); return( -1 ); } /* write out the request to the unbind process */ fprintf( fp, "UNBIND\n" ); fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); sock_print_conn( fp, op->o_conn, si ); sock_print_suffixes( fp, op->o_bd ); fprintf( fp, "\n" ); /* no response to unbind */ fclose( fp ); return 0; }
int dnssrv_back_bind( Operation *op, SlapReply *rs ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind dn=\"%s\" (%d)\n", BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, op->orb_method, 0 ); /* allow rootdn as a means to auth without the need to actually * contact the proxied DSA */ switch ( be_rootdn_bind( op, NULL ) ) { case LDAP_SUCCESS: /* frontend will send result */ return rs->sr_err; default: /* treat failure and like any other bind, otherwise * it could reveal the DN of the rootdn */ break; } if ( !BER_BVISNULL( &op->orb_cred ) && !BER_BVISEMPTY( &op->orb_cred ) ) { /* simple bind */ Statslog( LDAP_DEBUG_STATS, "%s DNSSRV BIND dn=\"%s\" provided cleartext passwd\n", op->o_log_prefix, BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val , 0, 0, 0 ); send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "you shouldn't send strangers your password" ); } else { /* unauthenticated bind */ /* NOTE: we're not going to get here anyway: * unauthenticated bind is dealt with by the frontend */ Debug( LDAP_DEBUG_TRACE, "DNSSRV: BIND dn=\"%s\"\n", BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 0, 0 ); send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "anonymous bind expected" ); } return 1; }
static int valsort_modify( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; valsort_info *vi = on->on_bi.bi_private; Modifications *ml; int i; char *ptr, *end; /* See if any weighted sorting applies to this entry */ for ( ;vi;vi=vi->vi_next ) { if ( !dnIsSuffix( &op->o_req_ndn, &vi->vi_dn )) continue; if ( !(vi->vi_sort & VALSORT_WEIGHTED )) continue; for (ml = op->orm_modlist; ml; ml=ml->sml_next ) { /* Must be a Delete Attr op, so no values to consider */ if ( !ml->sml_values ) continue; if ( ml->sml_desc == vi->vi_ad ) break; } if ( !ml ) continue; for (i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++) { ptr = ber_bvchr(&ml->sml_values[i], '{' ); if ( !ptr ) { Debug(LDAP_DEBUG_TRACE, "weight missing from attribute %s\n", vi->vi_ad->ad_cname.bv_val, 0, 0); send_ldap_error( op, rs, LDAP_CONSTRAINT_VIOLATION, "weight missing from attribute" ); return rs->sr_err; } strtol( ptr+1, &end, 0 ); if ( *end != '}' ) { Debug(LDAP_DEBUG_TRACE, "weight is misformatted in %s\n", vi->vi_ad->ad_cname.bv_val, 0, 0); send_ldap_error( op, rs, LDAP_CONSTRAINT_VIOLATION, "weight is misformatted" ); return rs->sr_err; } } } return SLAP_CB_CONTINUE; }
int shell_back_search( Operation *op, SlapReply *rs ) { struct shellinfo *si = (struct shellinfo *) op->o_bd->be_private; FILE *rfp, *wfp; AttributeName *an; if ( si->si_search == NULL ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "search not implemented" ); return( -1 ); } if ( forkandexec( si->si_search, &rfp, &wfp ) == (pid_t)-1 ) { send_ldap_error( op, rs, LDAP_OTHER, "could not fork/exec" ); return( -1 ); } /* write out the request to the search process */ fprintf( wfp, "SEARCH\n" ); fprintf( wfp, "msgid: %ld\n", (long) op->o_msgid ); print_suffixes( wfp, op->o_bd ); fprintf( wfp, "base: %s\n", op->o_req_dn.bv_val ); fprintf( wfp, "scope: %d\n", op->oq_search.rs_scope ); fprintf( wfp, "deref: %d\n", op->oq_search.rs_deref ); fprintf( wfp, "sizelimit: %d\n", op->oq_search.rs_slimit ); fprintf( wfp, "timelimit: %d\n", op->oq_search.rs_tlimit ); fprintf( wfp, "filter: %s\n", op->oq_search.rs_filterstr.bv_val ); fprintf( wfp, "attrsonly: %d\n", op->oq_search.rs_attrsonly ? 1 : 0 ); fprintf( wfp, "attrs:%s", op->oq_search.rs_attrs == NULL ? " all" : "" ); for ( an = op->oq_search.rs_attrs; an && an->an_name.bv_val; an++ ) { fprintf( wfp, " %s", an->an_name.bv_val ); } fprintf( wfp, "\n" ); fclose( wfp ); /* read in the results and send them along */ rs->sr_attrs = op->oq_search.rs_attrs; read_and_send_results( op, rs, rfp ); fclose( rfp ); return( 0 ); }
int shell_back_add( Operation *op, SlapReply *rs ) { struct shellinfo *si = (struct shellinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; FILE *rfp, *wfp; int len; if ( si->si_add == NULL ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "add not implemented" ); return( -1 ); } if ( ! access_allowed( op, op->oq_add.rs_e, entry, NULL, ACL_WADD, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( forkandexec( si->si_add, &rfp, &wfp ) == (pid_t)-1 ) { send_ldap_error( op, rs, LDAP_OTHER, "could not fork/exec" ); return( -1 ); } /* write out the request to the add process */ fprintf( wfp, "ADD\n" ); fprintf( wfp, "msgid: %ld\n", (long) op->o_msgid ); print_suffixes( wfp, op->o_bd ); ldap_pvt_thread_mutex_lock( &entry2str_mutex ); fprintf( wfp, "%s", entry2str( op->oq_add.rs_e, &len ) ); ldap_pvt_thread_mutex_unlock( &entry2str_mutex ); fclose( wfp ); /* read in the result and send it along */ read_and_send_results( op, rs, rfp ); fclose( rfp ); return( 0 ); }
static int dds_op_rename( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; dds_info_t *di = on->on_bi.bi_private; if ( DDS_OFF( di ) ) { return SLAP_CB_CONTINUE; } /* we don't allow dynamicObjects to have static subordinates */ if ( op->orr_nnewSup != NULL ) { Entry *e = NULL; BackendInfo *bi = op->o_bd->bd_info; int is_dynamicObject = 0, rc; rs->sr_err = LDAP_SUCCESS; op->o_bd->bd_info = (BackendInfo *)on->on_info; rc = be_entry_get_rw( op, &op->o_req_ndn, slap_schema.si_oc_dynamicObject, NULL, 0, &e ); if ( rc == LDAP_SUCCESS && e != NULL ) { be_entry_release_r( op, e ); e = NULL; is_dynamicObject = 1; } rc = be_entry_get_rw( op, op->orr_nnewSup, slap_schema.si_oc_dynamicObject, NULL, 0, &e ); if ( rc == LDAP_SUCCESS && e != NULL ) { if ( !is_dynamicObject ) { /* return referral only if "disclose" * is granted on the object */ if ( ! access_allowed( op, e, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE, NULL ) ) { rs->sr_err = LDAP_NO_SUCH_OBJECT; send_ldap_result( op, rs ); } else { send_ldap_error( op, rs, LDAP_CONSTRAINT_VIOLATION, "static entry cannot have dynamicObject as newSuperior" ); } } be_entry_release_r( op, e ); } op->o_bd->bd_info = bi; if ( rs->sr_err != LDAP_SUCCESS ) { return rs->sr_err; } } return SLAP_CB_CONTINUE; }
static int denyop_func( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; denyop_info *oi = (denyop_info *)on->on_bi.bi_private; int deny = 0; switch( op->o_tag ) { case LDAP_REQ_BIND: deny = oi->do_op[denyop_bind]; break; case LDAP_REQ_ADD: deny = oi->do_op[denyop_add]; break; case LDAP_REQ_DELETE: deny = oi->do_op[denyop_delete]; break; case LDAP_REQ_MODRDN: deny = oi->do_op[denyop_modrdn]; break; case LDAP_REQ_MODIFY: deny = oi->do_op[denyop_modify]; break; case LDAP_REQ_COMPARE: deny = oi->do_op[denyop_compare]; break; case LDAP_REQ_SEARCH: deny = oi->do_op[denyop_search]; break; case LDAP_REQ_EXTENDED: deny = oi->do_op[denyop_extended]; break; case LDAP_REQ_UNBIND: deny = oi->do_op[denyop_unbind]; break; } if ( !deny ) { return SLAP_CB_CONTINUE; } op->o_bd->bd_info = (BackendInfo *)on->on_info; send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "operation not allowed within namingContext" ); return 0; }
static int valsort_add( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; valsort_info *vi = on->on_bi.bi_private; Attribute *a; int i; char *ptr, *end; /* See if any weighted sorting applies to this entry */ for ( ;vi;vi=vi->vi_next ) { if ( !dnIsSuffix( &op->o_req_ndn, &vi->vi_dn )) continue; if ( !(vi->vi_sort & VALSORT_WEIGHTED )) continue; a = attr_find( op->ora_e->e_attrs, vi->vi_ad ); if ( !a ) continue; for (i=0; !BER_BVISNULL( &a->a_vals[i] ); i++) { ptr = ber_bvchr(&a->a_vals[i], '{' ); if ( !ptr ) { Debug(LDAP_DEBUG_TRACE, "weight missing from attribute %s\n", vi->vi_ad->ad_cname.bv_val, 0, 0); send_ldap_error( op, rs, LDAP_CONSTRAINT_VIOLATION, "weight missing from attribute" ); return rs->sr_err; } strtol( ptr+1, &end, 0 ); if ( *end != '}' ) { Debug(LDAP_DEBUG_TRACE, "weight is misformatted in %s\n", vi->vi_ad->ad_cname.bv_val, 0, 0); send_ldap_error( op, rs, LDAP_CONSTRAINT_VIOLATION, "weight is misformatted" ); return rs->sr_err; } } } return SLAP_CB_CONTINUE; }
int sock_back_add( Operation *op, SlapReply *rs ) { struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; FILE *fp; int len; if ( ! access_allowed( op, op->oq_add.rs_e, entry, NULL, ACL_WADD, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( (fp = opensock( si->si_sockpath )) == NULL ) { send_ldap_error( op, rs, LDAP_OTHER, "could not open socket" ); return( -1 ); } /* write out the request to the add process */ fprintf( fp, "ADD\n" ); fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); sock_print_conn( fp, op->o_conn, si ); sock_print_suffixes( fp, op->o_bd ); ldap_pvt_thread_mutex_lock( &entry2str_mutex ); fprintf( fp, "%s", entry2str( op->oq_add.rs_e, &len ) ); ldap_pvt_thread_mutex_unlock( &entry2str_mutex ); fprintf (fp, "\n" ); /* read in the result and send it along */ sock_read_and_send_results( op, rs, fp ); fclose( fp ); return( 0 ); }
static int translucent_delete(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; Debug(LDAP_DEBUG_TRACE, "==> translucent_delete: %s\n", op->o_req_dn.bv_val, 0, 0); if(!be_isroot(op)) { op->o_bd->bd_info = (BackendInfo *) on->on_info; send_ldap_error(op, rs, LDAP_INSUFFICIENT_ACCESS, "user modification of overlay database not permitted"); op->o_bd->bd_info = (BackendInfo *) on; return(rs->sr_err); } return(SLAP_CB_CONTINUE); }
int dnssrv_back_compare( Operation *op, SlapReply *rs ) { #if 0 assert( get_manageDSAit( op ) ); #endif send_ldap_error( op, rs, LDAP_OTHER, "Operation not supported within naming context" ); /* not implemented */ return 1; }
static int example_search(Operation *op, char *attrcontent) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; example_data *ex = on->on_bi.bi_private; Operation nop = *op; slap_callback cb = { NULL, example_callback, NULL, NULL, ex}; SlapReply nrs = { REP_RESULT }; int rc; Filter *filter = NULL; struct berval fstr = BER_BVNULL; char *buffer; size_t len; len = strlen(ex->principalattr) + 5; buffer = (char *)malloc(sizeof(char) * len); if (!buffer) { nop.o_bd->bd_info = (BackendInfo *)(on->on_info); send_ldap_error(&nop, &nrs, LDAP_OTHER, "Cannot allocate memory in example_search()"); return nrs.sr_err; } snprintf(buffer, len, "(krbPrincipalName=%s@%s)", attrcontent, ex->exampledomain) ; filter = str2filter(buffer); filter2bv(filter, &fstr); nop.o_callback = &cb; op->o_bd->bd_info = (BackendInfo *) on->on_info; nop.o_tag = LDAP_REQ_SEARCH; nop.o_ctrls = NULL; nop.ors_scope = LDAP_SCOPE_SUBTREE; nop.ors_deref = LDAP_DEREF_NEVER; nop.ors_slimit = SLAP_NO_LIMIT; nop.ors_tlimit = SLAP_NO_LIMIT; nop.ors_attrsonly = 1; nop.ors_attrs = slap_anlist_no_attrs; nop.ors_filter = filter; nop.ors_filterstr = fstr; if (nop.o_bd->be_search) rc = nop.o_bd->be_search(&nop, &nrs); free(buffer); if (filter) filter_free(filter); if (fstr.bv_val) ch_free(fstr.bv_val); return SLAP_CB_CONTINUE; }
static int translucent_modrdn(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; translucent_info *ov = on->on_bi.bi_private; Debug(LDAP_DEBUG_TRACE, "==> translucent_modrdn: %s -> %s\n", op->o_req_dn.bv_val, op->orr_newrdn.bv_val, 0); if(!be_isroot(op)) { op->o_bd->bd_info = (BackendInfo *) on->on_info; send_ldap_error(op, rs, LDAP_INSUFFICIENT_ACCESS, "user modification of overlay database not permitted"); op->o_bd->bd_info = (BackendInfo *) on; return(rs->sr_err); } if(!ov->no_glue) { op->o_tag = LDAP_REQ_ADD; glue_parent(op); op->o_tag = LDAP_REQ_MODRDN; } return(SLAP_CB_CONTINUE); }
static int translucent_exop(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; translucent_info *ov = on->on_bi.bi_private; const struct berval bv_exop_pwmod = BER_BVC(LDAP_EXOP_MODIFY_PASSWD); Debug(LDAP_DEBUG_TRACE, "==> translucent_exop: %s\n", op->o_req_dn.bv_val, 0, 0); if(ov->defer_db_open) { send_ldap_error(op, rs, LDAP_UNAVAILABLE, "remote DB not available"); return(rs->sr_err); } if ( bvmatch( &bv_exop_pwmod, &op->ore_reqoid ) ) { return translucent_pwmod( op, rs ); } return SLAP_CB_CONTINUE; }
int sock_back_search( Operation *op, SlapReply *rs ) { struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; FILE *fp; AttributeName *an; if ( (fp = opensock( si->si_sockpath )) == NULL ) { send_ldap_error( op, rs, LDAP_OTHER, "could not open socket" ); return( -1 ); } /* write out the request to the search process */ fprintf( fp, "SEARCH\n" ); fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); sock_print_conn( fp, op->o_conn, si ); sock_print_suffixes( fp, op->o_bd ); fprintf( fp, "base: %s\n", op->o_req_dn.bv_val ); fprintf( fp, "scope: %d\n", op->oq_search.rs_scope ); fprintf( fp, "deref: %d\n", op->oq_search.rs_deref ); fprintf( fp, "sizelimit: %d\n", op->oq_search.rs_slimit ); fprintf( fp, "timelimit: %d\n", op->oq_search.rs_tlimit ); fprintf( fp, "filter: %s\n", op->oq_search.rs_filterstr.bv_val ); fprintf( fp, "attrsonly: %d\n", op->oq_search.rs_attrsonly ? 1 : 0 ); fprintf( fp, "attrs:%s", op->oq_search.rs_attrs == NULL ? " all" : "" ); for ( an = op->oq_search.rs_attrs; an && an->an_name.bv_val; an++ ) { fprintf( fp, " %s", an->an_name.bv_val ); } fprintf( fp, "\n\n" ); /* end of attr line plus blank line */ /* read in the results and send them along */ rs->sr_attrs = op->oq_search.rs_attrs; sock_read_and_send_results( op, rs, fp ); fclose( fp ); return( 0 ); }
static int translucent_compare(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; translucent_info *ov = on->on_bi.bi_private; AttributeAssertion *ava = op->orc_ava; Entry *e = NULL; BackendDB *db; int rc; Debug(LDAP_DEBUG_TRACE, "==> translucent_compare: <%s> %s:%s\n", op->o_req_dn.bv_val, ava->aa_desc->ad_cname.bv_val, ava->aa_value.bv_val); /* ** if the local backend has an entry for this attribute: ** CONTINUE and let it do the compare; ** */ rc = overlay_entry_get_ov(op, &op->o_req_ndn, NULL, ava->aa_desc, 0, &e, on); if(rc == LDAP_SUCCESS && e) { overlay_entry_release_ov(op, e, 0, on); return(SLAP_CB_CONTINUE); } if(ov->defer_db_open) { send_ldap_error(op, rs, LDAP_UNAVAILABLE, "remote DB not available"); return(rs->sr_err); } /* ** call compare() in the captive backend; ** return the result; ** */ db = op->o_bd; op->o_bd = &ov->db; ov->db.be_acl = op->o_bd->be_acl; rc = ov->db.bd_info->bi_op_compare(op, rs); op->o_bd = db; return(rc); }
static int translucent_bind(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; translucent_info *ov = on->on_bi.bi_private; BackendDB *db; slap_callback sc = { 0 }, *save_cb; int rc; Debug(LDAP_DEBUG_TRACE, "translucent_bind: <%s> method %d\n", op->o_req_dn.bv_val, op->orb_method, 0); if(ov->defer_db_open) { send_ldap_error(op, rs, LDAP_UNAVAILABLE, "remote DB not available"); return(rs->sr_err); } if (ov->bind_local) { sc.sc_response = slap_null_cb; save_cb = op->o_callback; op->o_callback = ≻ } db = op->o_bd; op->o_bd = &ov->db; ov->db.be_acl = op->o_bd->be_acl; rc = ov->db.bd_info->bi_op_bind(op, rs); op->o_bd = db; if (ov->bind_local) { op->o_callback = save_cb; if (rc != LDAP_SUCCESS) { rc = SLAP_CB_CONTINUE; } } return rc; }
int dnssrv_back_search( Operation *op, SlapReply *rs ) { int i; int rc; char *domain = NULL; char *hostlist = NULL; char **hosts = NULL; char *refdn; struct berval nrefdn = BER_BVNULL; BerVarray urls = NULL; int manageDSAit; rs->sr_ref = NULL; if ( BER_BVISEMPTY( &op->o_req_ndn ) ) { /* FIXME: need some means to determine whether the database * is a glue instance; if we got here with empty DN, then * we passed this same test in dnssrv_back_referrals() */ if ( !SLAP_GLUE_INSTANCE( op->o_bd ) ) { rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed"; } else { rs->sr_err = LDAP_SUCCESS; } goto done; } manageDSAit = get_manageDSAit( op ); /* * FIXME: we may return a referral if manageDSAit is not set */ if ( !manageDSAit ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "manageDSAit must be set" ); goto done; } if( ldap_dn2domain( op->o_req_dn.bv_val, &domain ) || domain == NULL ) { rs->sr_err = LDAP_REFERRAL; rs->sr_ref = default_referral; send_ldap_result( op, rs ); rs->sr_ref = NULL; goto done; } Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n", op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", domain ); if( ( rc = ldap_domain2hostlist( domain, &hostlist ) ) ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n", rc ); send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, "no DNS SRV RR available for DN" ); goto done; } hosts = ldap_str2charray( hostlist, " " ); if( hosts == NULL ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charray error\n" ); send_ldap_error( op, rs, LDAP_OTHER, "problem processing DNS SRV records for DN" ); goto done; } for( i=0; hosts[i] != NULL; i++) { struct berval url; url.bv_len = STRLENOF( "ldap://" ) + strlen(hosts[i]); url.bv_val = ch_malloc( url.bv_len + 1 ); strcpy( url.bv_val, "ldap://" ); strcpy( &url.bv_val[STRLENOF( "ldap://" )], hosts[i] ); if( ber_bvarray_add( &urls, &url ) < 0 ) { free( url.bv_val ); send_ldap_error( op, rs, LDAP_OTHER, "problem processing DNS SRV records for DN" ); goto done; } } Debug( LDAP_DEBUG_STATS, "%s DNSSRV p=%d dn=\"%s\" url=\"%s\"\n", op->o_log_prefix, op->o_protocol, op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", urls[0].bv_val ); Debug( LDAP_DEBUG_TRACE, "DNSSRV: ManageDSAit scope=%d dn=\"%s\" -> url=\"%s\"\n", op->oq_search.rs_scope, op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", urls[0].bv_val ); rc = ldap_domain2dn(domain, &refdn); if( rc != LDAP_SUCCESS ) { send_ldap_error( op, rs, LDAP_OTHER, "DNS SRV problem processing manageDSAit control" ); goto done; } else { struct berval bv; bv.bv_val = refdn; bv.bv_len = strlen( refdn ); rc = dnNormalize( 0, NULL, NULL, &bv, &nrefdn, op->o_tmpmemctx ); if( rc != LDAP_SUCCESS ) { send_ldap_error( op, rs, LDAP_OTHER, "DNS SRV problem processing manageDSAit control" ); goto done; } } if( !dn_match( &nrefdn, &op->o_req_ndn ) ) { /* requested dn is subordinate */ Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" subordinate to refdn=\"%s\"\n", op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", refdn == NULL ? "" : refdn ); rs->sr_matched = refdn; rs->sr_err = LDAP_NO_SUCH_OBJECT; send_ldap_result( op, rs ); rs->sr_matched = NULL; } else if ( op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) { send_ldap_error( op, rs, LDAP_SUCCESS, NULL ); } else { Entry e = { 0 }; AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; AttributeDescription *ad_ref = slap_schema.si_ad_ref; e.e_name.bv_val = ch_strdup( op->o_req_dn.bv_val ); e.e_name.bv_len = op->o_req_dn.bv_len; e.e_nname.bv_val = ch_strdup( op->o_req_ndn.bv_val ); e.e_nname.bv_len = op->o_req_ndn.bv_len; e.e_attrs = NULL; e.e_private = NULL; attr_merge_one( &e, ad_objectClass, &slap_schema.si_oc_referral->soc_cname, NULL ); attr_merge_one( &e, ad_objectClass, &slap_schema.si_oc_extensibleObject->soc_cname, NULL ); if ( ad_dc ) { char *p; struct berval bv; bv.bv_val = domain; p = strchr( bv.bv_val, '.' ); if ( p == bv.bv_val ) { bv.bv_len = 1; } else if ( p != NULL ) { bv.bv_len = p - bv.bv_val; } else { bv.bv_len = strlen( bv.bv_val ); } attr_merge_normalize_one( &e, ad_dc, &bv, NULL ); } if ( ad_associatedDomain ) { struct berval bv; ber_str2bv( domain, 0, 0, &bv ); attr_merge_normalize_one( &e, ad_associatedDomain, &bv, NULL ); } attr_merge_normalize_one( &e, ad_ref, urls, NULL ); rc = test_filter( op, &e, op->oq_search.rs_filter ); if( rc == LDAP_COMPARE_TRUE ) { rs->sr_entry = &e; rs->sr_attrs = op->oq_search.rs_attrs; rs->sr_flags = REP_ENTRY_MODIFIABLE; send_search_entry( op, rs ); rs->sr_entry = NULL; rs->sr_attrs = NULL; rs->sr_flags = 0; } entry_clean( &e ); rs->sr_err = LDAP_SUCCESS; send_ldap_result( op, rs ); } free( refdn ); if ( nrefdn.bv_val ) free( nrefdn.bv_val ); done: if( domain != NULL ) ch_free( domain ); if( hostlist != NULL ) ch_free( hostlist ); if( hosts != NULL ) ldap_charray_free( hosts ); if( urls != NULL ) ber_bvarray_free( urls ); return 0; }
int dnssrv_back_referrals( Operation *op, SlapReply *rs ) { int i; int rc = LDAP_OTHER; char *domain = NULL; char *hostlist = NULL; char **hosts = NULL; BerVarray urls = NULL; if ( BER_BVISEMPTY( &op->o_req_dn ) ) { /* FIXME: need some means to determine whether the database * is a glue instance */ if ( SLAP_GLUE_INSTANCE( op->o_bd ) ) { return LDAP_SUCCESS; } rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed"; return LDAP_UNWILLING_TO_PERFORM; } if( get_manageDSAit( op ) ) { if( op->o_tag == LDAP_REQ_SEARCH ) { return LDAP_SUCCESS; } rs->sr_text = "DNS SRV problem processing manageDSAit control"; return LDAP_OTHER; } if( ldap_dn2domain( op->o_req_dn.bv_val, &domain ) || domain == NULL ) { rs->sr_err = LDAP_REFERRAL; rs->sr_ref = default_referral; send_ldap_result( op, rs ); rs->sr_ref = NULL; return LDAP_REFERRAL; } Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n", op->o_req_dn.bv_val, domain, 0 ); i = ldap_domain2hostlist( domain, &hostlist ); if ( i ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist(%s) returned %d\n", domain, i, 0 ); rs->sr_text = "no DNS SRV RR available for DN"; rc = LDAP_NO_SUCH_OBJECT; goto done; } hosts = ldap_str2charray( hostlist, " " ); if( hosts == NULL ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 ); rs->sr_text = "problem processing DNS SRV records for DN"; goto done; } for( i=0; hosts[i] != NULL; i++) { struct berval url; url.bv_len = STRLENOF( "ldap://" ) + strlen( hosts[i] ); url.bv_val = ch_malloc( url.bv_len + 1 ); strcpy( url.bv_val, "ldap://" ); strcpy( &url.bv_val[STRLENOF( "ldap://" )], hosts[i] ); if ( ber_bvarray_add( &urls, &url ) < 0 ) { free( url.bv_val ); rs->sr_text = "problem processing DNS SRV records for DN"; goto done; } } Statslog( LDAP_DEBUG_STATS, "%s DNSSRV p=%d dn=\"%s\" url=\"%s\"\n", op->o_log_prefix, op->o_protocol, op->o_req_dn.bv_val, urls[0].bv_val, 0 ); Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> url=\"%s\"\n", op->o_req_dn.bv_val, urls[0].bv_val, 0 ); rs->sr_ref = urls; send_ldap_error( op, rs, LDAP_REFERRAL, "DNS SRV generated referrals" ); rs->sr_ref = NULL; rc = LDAP_REFERRAL; done: if( domain != NULL ) ch_free( domain ); if( hostlist != NULL ) ch_free( hostlist ); if( hosts != NULL ) ldap_charray_free( hosts ); ber_bvarray_free( urls ); return rc; }
int shell_back_bind( Operation *op, SlapReply *rs ) { struct shellinfo *si = (struct shellinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; Entry e; FILE *rfp, *wfp; int rc; /* allow rootdn as a means to auth without the need to actually * contact the proxied DSA */ switch ( be_rootdn_bind( op, rs ) ) { case SLAP_CB_CONTINUE: break; default: return rs->sr_err; } if ( si->si_bind == NULL ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "bind not implemented" ); return( -1 ); } e.e_id = NOID; e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; e.e_attrs = NULL; e.e_ocflags = 0; e.e_bv.bv_len = 0; e.e_bv.bv_val = NULL; e.e_private = NULL; if ( ! access_allowed( op, &e, entry, NULL, ACL_AUTH, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( forkandexec( si->si_bind, &rfp, &wfp ) == (pid_t)-1 ) { send_ldap_error( op, rs, LDAP_OTHER, "could not fork/exec" ); return( -1 ); } /* write out the request to the bind process */ fprintf( wfp, "BIND\n" ); fprintf( wfp, "msgid: %ld\n", (long) op->o_msgid ); print_suffixes( wfp, op->o_bd ); fprintf( wfp, "dn: %s\n", op->o_req_dn.bv_val ); fprintf( wfp, "method: %d\n", op->oq_bind.rb_method ); fprintf( wfp, "credlen: %lu\n", op->oq_bind.rb_cred.bv_len ); fprintf( wfp, "cred: %s\n", op->oq_bind.rb_cred.bv_val ); /* XXX */ fclose( wfp ); /* read in the results and send them along */ rc = read_and_send_results( op, rs, rfp ); fclose( rfp ); return( rc ); }
int do_search( Operation *op, /* info about the op to which we're responding */ SlapReply *rs /* all the response data we'll send */ ) { struct berval base = BER_BVNULL; ber_len_t siz, off, i; Debug( LDAP_DEBUG_TRACE, "%s do_search\n", op->o_log_prefix, 0, 0 ); /* * Parse the search request. It looks like this: * * SearchRequest := [APPLICATION 3] SEQUENCE { * baseObject DistinguishedName, * scope ENUMERATED { * baseObject (0), * singleLevel (1), * wholeSubtree (2), * subordinate (3) -- OpenLDAP extension * }, * derefAliases ENUMERATED { * neverDerefaliases (0), * derefInSearching (1), * derefFindingBaseObj (2), * alwaysDerefAliases (3) * }, * sizelimit INTEGER (0 .. 65535), * timelimit INTEGER (0 .. 65535), * attrsOnly BOOLEAN, * filter Filter, * attributes SEQUENCE OF AttributeType * } */ /* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */ if ( ber_scanf( op->o_ber, "{miiiib" /*}*/, &base, &op->ors_scope, &op->ors_deref, &op->ors_slimit, &op->ors_tlimit, &op->ors_attrsonly ) == LBER_ERROR ) { send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" ); rs->sr_err = SLAPD_DISCONNECT; goto return_results; } if ( op->ors_tlimit < 0 || op->ors_tlimit > SLAP_MAX_LIMIT ) { send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid time limit" ); goto return_results; } if ( op->ors_slimit < 0 || op->ors_slimit > SLAP_MAX_LIMIT ) { send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid size limit" ); goto return_results; } switch( op->ors_scope ) { case LDAP_SCOPE_BASE: case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBORDINATE: break; default: send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid scope" ); goto return_results; } switch( op->ors_deref ) { case LDAP_DEREF_NEVER: case LDAP_DEREF_FINDING: case LDAP_DEREF_SEARCHING: case LDAP_DEREF_ALWAYS: break; default: send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid deref" ); goto return_results; } rs->sr_err = dnPrettyNormal( NULL, &base, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); if( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_search: invalid dn: \"%s\"\n", op->o_log_prefix, base.bv_val, 0 ); send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" ); goto return_results; } Debug( LDAP_DEBUG_ARGS, "SRCH \"%s\" %d %d", base.bv_val, op->ors_scope, op->ors_deref ); Debug( LDAP_DEBUG_ARGS, " %d %d %d\n", op->ors_slimit, op->ors_tlimit, op->ors_attrsonly); /* filter - returns a "normalized" version */ rs->sr_err = get_filter( op, op->o_ber, &op->ors_filter, &rs->sr_text ); if( rs->sr_err != LDAP_SUCCESS ) { if( rs->sr_err == SLAPD_DISCONNECT ) { rs->sr_err = LDAP_PROTOCOL_ERROR; send_ldap_disconnect( op, rs ); rs->sr_err = SLAPD_DISCONNECT; } else { send_ldap_result( op, rs ); } goto return_results; } filter2bv_x( op, op->ors_filter, &op->ors_filterstr ); Debug( LDAP_DEBUG_ARGS, " filter: %s\n", !BER_BVISEMPTY( &op->ors_filterstr ) ? op->ors_filterstr.bv_val : "empty", 0, 0 ); /* attributes */ siz = sizeof(AttributeName); off = offsetof(AttributeName,an_name); if ( ber_scanf( op->o_ber, "{M}}", &op->ors_attrs, &siz, off ) == LBER_ERROR ) { send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding attrs error" ); rs->sr_err = SLAPD_DISCONNECT; goto return_results; } for ( i=0; i<siz; i++ ) { const char *dummy; /* ignore msgs from bv2ad */ op->ors_attrs[i].an_desc = NULL; op->ors_attrs[i].an_oc = NULL; op->ors_attrs[i].an_flags = 0; if ( slap_bv2ad( &op->ors_attrs[i].an_name, &op->ors_attrs[i].an_desc, &dummy ) != LDAP_SUCCESS ) { if ( slap_bv2undef_ad( &op->ors_attrs[i].an_name, &op->ors_attrs[i].an_desc, &dummy, SLAP_AD_PROXIED|SLAP_AD_NOINSERT ) ) { struct berval *bv = &op->ors_attrs[i].an_name; /* RFC 4511 LDAPv3: All User Attributes */ if ( bvmatch( bv, slap_bv_all_user_attrs ) ) { continue; } /* RFC 3673 LDAPv3: All Operational Attributes */ if ( bvmatch( bv, slap_bv_all_operational_attrs ) ) { continue; } /* RFC 4529 LDAP: Requesting Attributes by Object Class */ if ( bv->bv_len > 1 && bv->bv_val[0] == '@' ) { /* FIXME: check if remaining is valid oc name? */ continue; } /* add more "exceptions" to RFC 4511 4.5.1.8. */ /* invalid attribute description? remove */ if ( ad_keystring( bv ) ) { /* NOTE: parsed in-place, don't modify; * rather add "1.1", which must be ignored */ BER_BVSTR( &op->ors_attrs[i].an_name, LDAP_NO_ATTRS ); } /* otherwise leave in place... */ } } } if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_search: get_ctrls failed\n", op->o_log_prefix, 0, 0 ); goto return_results; } Debug( LDAP_DEBUG_ARGS, " attrs:", 0, 0, 0 ); if ( siz != 0 ) { for ( i = 0; i<siz; i++ ) { Debug( LDAP_DEBUG_ARGS, " %s", op->ors_attrs[i].an_name.bv_val, 0, 0 ); } } Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 ); if ( StatslogTest( LDAP_DEBUG_STATS ) ) { char abuf[BUFSIZ/2], *ptr = abuf; unsigned len = 0, alen; sprintf(abuf, "scope=%d deref=%d", op->ors_scope, op->ors_deref); Statslog( LDAP_DEBUG_STATS, "%s SRCH base=\"%s\" %s filter=\"%s\"\n", op->o_log_prefix, op->o_req_dn.bv_val, abuf, op->ors_filterstr.bv_val, 0 ); for ( i = 0; i<siz; i++ ) { alen = op->ors_attrs[i].an_name.bv_len; if (alen >= sizeof(abuf)) { alen = sizeof(abuf)-1; } if (len && (len + 1 + alen >= sizeof(abuf))) { Statslog( LDAP_DEBUG_STATS, "%s SRCH attr=%s\n", op->o_log_prefix, abuf, 0, 0, 0 ); len = 0; ptr = abuf; } if (len) { *ptr++ = ' '; len++; } ptr = lutil_strncopy(ptr, op->ors_attrs[i].an_name.bv_val, alen); len += alen; *ptr = '\0'; } if (len) { Statslog( LDAP_DEBUG_STATS, "%s SRCH attr=%s\n", op->o_log_prefix, abuf, 0, 0, 0 ); } } op->o_bd = frontendDB; rs->sr_err = frontendDB->be_search( op, rs ); return_results:; if ( !BER_BVISNULL( &op->o_req_dn ) ) { slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &op->o_req_ndn ) ) { slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &op->ors_filterstr ) ) { op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); } if ( op->ors_filter != NULL) { filter_free_x( op, op->ors_filter, 1 ); } if ( op->ors_attrs != NULL ) { op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx ); } return rs->sr_err; }
int fe_op_search( Operation *op, SlapReply *rs ) { BackendDB *bd = op->o_bd; if ( op->ors_scope == LDAP_SCOPE_BASE ) { Entry *entry = NULL; if ( BER_BVISEMPTY( &op->o_req_ndn ) ) { #ifdef LDAP_CONNECTIONLESS /* Ignore LDAPv2 CLDAP Root DSE queries */ if (op->o_protocol == LDAP_VERSION2 && op->o_conn->c_is_udp) { goto return_results; } #endif /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto return_results; } rs->sr_err = root_dse_info( op->o_conn, &entry, &rs->sr_text ); } else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) { /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto return_results; } rs->sr_err = schema_info( &entry, &rs->sr_text ); } if( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto return_results; } else if ( entry != NULL ) { if ( get_assert( op ) && ( test_filter( op, entry, get_assertion( op )) != LDAP_COMPARE_TRUE )) { rs->sr_err = LDAP_ASSERTION_FAILED; goto fail1; } rs->sr_err = test_filter( op, entry, op->ors_filter ); if( rs->sr_err == LDAP_COMPARE_TRUE ) { /* note: we set no limits because either * no limit is specified, or at least 1 * is specified, and we're going to return * at most one entry */ op->ors_slimit = SLAP_NO_LIMIT; op->ors_tlimit = SLAP_NO_LIMIT; rs->sr_entry = entry; rs->sr_attrs = op->ors_attrs; rs->sr_operational_attrs = NULL; rs->sr_flags = 0; send_search_entry( op, rs ); rs->sr_entry = NULL; rs->sr_operational_attrs = NULL; } rs->sr_err = LDAP_SUCCESS; fail1: entry_free( entry ); send_ldap_result( op, rs ); goto return_results; } } if( BER_BVISEMPTY( &op->o_req_ndn ) && !BER_BVISEMPTY( &default_search_nbase ) ) { slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx ); slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx ); ber_dupbv_x( &op->o_req_dn, &default_search_base, op->o_tmpmemctx ); ber_dupbv_x( &op->o_req_ndn, &default_search_nbase, op->o_tmpmemctx ); } /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ op->o_bd = select_backend( &op->o_req_ndn, 1 ); if ( op->o_bd == NULL ) { rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, op->ors_scope ); if (!rs->sr_ref) rs->sr_ref = default_referral; rs->sr_err = LDAP_REFERRAL; op->o_bd = bd; send_ldap_result( op, rs ); if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); rs->sr_ref = NULL; goto return_results; } /* check restrictions */ if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto return_results; } /* check for referrals */ if( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { goto return_results; } if ( SLAP_SHADOW(op->o_bd) && get_dontUseCopy(op) ) { /* don't use shadow copy */ BerVarray defref = op->o_bd->be_update_refs ? op->o_bd->be_update_refs : default_referral; if( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, op->ors_scope ); if( !rs->sr_ref) rs->sr_ref = defref; rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); if (rs->sr_ref != defref) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "copy not used; no referral information available" ); } } else if ( op->o_bd->be_search ) { if ( limits_check( op, rs ) == 0 ) { /* actually do the search and send the result(s) */ (op->o_bd->be_search)( op, rs ); } /* else limits_check() sends error */ } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "operation not supported within namingContext" ); } return_results:; op->o_bd = bd; return rs->sr_err; }
int sock_back_modify( Operation *op, SlapReply *rs ) { Modification *mod; struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; AttributeDescription *entry = slap_schema.si_ad_entry; Modifications *ml = op->orm_modlist; Entry e; FILE *fp; int i; e.e_id = NOID; e.e_name = op->o_req_dn; e.e_nname = op->o_req_ndn; e.e_attrs = NULL; e.e_ocflags = 0; e.e_bv.bv_len = 0; e.e_bv.bv_val = NULL; e.e_private = NULL; if ( ! access_allowed( op, &e, entry, NULL, ACL_WRITE, NULL ) ) { send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL ); return -1; } if ( (fp = opensock( si->si_sockpath )) == NULL ) { send_ldap_error( op, rs, LDAP_OTHER, "could not open socket" ); return( -1 ); } /* write out the request to the modify process */ fprintf( fp, "MODIFY\n" ); fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); sock_print_conn( fp, op->o_conn, si ); sock_print_suffixes( fp, op->o_bd ); fprintf( fp, "dn: %s\n", op->o_req_dn.bv_val ); for ( ; ml != NULL; ml = ml->sml_next ) { mod = &ml->sml_mod; /* FIXME: should use LDIF routines to deal with binary data */ switch ( mod->sm_op ) { case LDAP_MOD_ADD: fprintf( fp, "add: %s\n", mod->sm_desc->ad_cname.bv_val ); break; case LDAP_MOD_DELETE: fprintf( fp, "delete: %s\n", mod->sm_desc->ad_cname.bv_val ); break; case LDAP_MOD_REPLACE: fprintf( fp, "replace: %s\n", mod->sm_desc->ad_cname.bv_val ); break; } if( mod->sm_values != NULL ) { for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) { fprintf( fp, "%s: %s\n", mod->sm_desc->ad_cname.bv_val, mod->sm_values[i].bv_val /* binary! */ ); } } fprintf( fp, "-\n" ); } fprintf( fp, "\n" ); /* read in the results and send them along */ sock_read_and_send_results( op, rs, fp ); fclose( fp ); return( 0 ); }
int do_bind( Operation *op, SlapReply *rs ) { BerElement *ber = op->o_ber; ber_int_t version; ber_tag_t method; struct berval mech = BER_BVNULL; struct berval dn = BER_BVNULL; ber_tag_t tag; Backend *be = NULL; Debug( LDAP_DEBUG_TRACE, "%s do_bind\n", op->o_log_prefix ); /* * Force the connection to "anonymous" until bind succeeds. */ ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); if ( op->o_conn->c_sasl_bind_in_progress ) { be = op->o_conn->c_authz_backend; } if ( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) { /* log authorization identity demotion */ Statslog( LDAP_DEBUG_STATS, "%s BIND anonymous mech=implicit ssf=0\n", op->o_log_prefix ); } connection2anonymous( op->o_conn ); if ( op->o_conn->c_sasl_bind_in_progress ) { op->o_conn->c_authz_backend = be; } ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); if ( !BER_BVISNULL( &op->o_dn ) ) { /* NOTE: temporarily wasting few bytes * (until bind is completed), but saving * a couple of ch_free() and ch_strdup("") */ op->o_dn.bv_val[0] = '\0'; op->o_dn.bv_len = 0; } if ( !BER_BVISNULL( &op->o_ndn ) ) { op->o_ndn.bv_val[0] = '\0'; op->o_ndn.bv_len = 0; } /* * Parse the bind request. It looks like this: * * BindRequest ::= SEQUENCE { * version INTEGER, -- version * name DistinguishedName, -- dn * authentication CHOICE { * simple [0] OCTET STRING -- passwd * krbv42ldap [1] OCTET STRING -- OBSOLETE * krbv42dsa [2] OCTET STRING -- OBSOLETE * SASL [3] SaslCredentials * } * } * * SaslCredentials ::= SEQUENCE { * mechanism LDAPString, * credentials OCTET STRING OPTIONAL * } */ tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method ); if ( tag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, "%s do_bind: ber_scanf failed\n", op->o_log_prefix ); send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" ); rs->sr_err = SLAPD_DISCONNECT; goto cleanup; } op->o_protocol = version; op->orb_method = method; if( op->orb_method != LDAP_AUTH_SASL ) { tag = ber_scanf( ber, /*{*/ "m}", &op->orb_cred ); } else { tag = ber_scanf( ber, "{m" /*}*/, &mech ); if ( tag != LBER_ERROR ) { ber_len_t len; tag = ber_peek_tag( ber, &len ); if ( tag == LDAP_TAG_LDAPCRED ) { tag = ber_scanf( ber, "m", &op->orb_cred ); } else { tag = LDAP_TAG_LDAPCRED; BER_BVZERO( &op->orb_cred ); } if ( tag != LBER_ERROR ) { tag = ber_scanf( ber, /*{{*/ "}}" ); } } } if ( tag == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, "%s do_bind: ber_scanf failed\n", op->o_log_prefix ); send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" ); rs->sr_err = SLAPD_DISCONNECT; goto cleanup; } if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_bind: get_ctrls failed\n", op->o_log_prefix ); goto cleanup; } /* We use the tmpmemctx here because it speeds up normalization. * However, we must dup with regular malloc when storing any * resulting DNs in the op or conn structures. */ rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_bind: invalid dn (%s)\n", op->o_log_prefix, dn.bv_val ); send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" ); goto cleanup; } Statslog( LDAP_DEBUG_STATS, "%s BIND dn=\"%s\" method=%ld\n", op->o_log_prefix, op->o_req_dn.bv_val, (unsigned long) op->orb_method ); if( op->orb_method == LDAP_AUTH_SASL ) { Debug( LDAP_DEBUG_TRACE, "do_bind: dn (%s) SASL mech %s\n", op->o_req_dn.bv_val, mech.bv_val ); } else { Debug( LDAP_DEBUG_TRACE, "do_bind: version=%ld dn=\"%s\" method=%ld\n", (unsigned long) version, op->o_req_dn.bv_val, (unsigned long) op->orb_method ); } if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) { Debug( LDAP_DEBUG_ANY, "%s do_bind: unknown version=%ld\n", op->o_log_prefix, (unsigned long) version ); send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "requested protocol version not supported" ); goto cleanup; } else if (!( global_allows & SLAP_ALLOW_BIND_V2 ) && version < LDAP_VERSION3 ) { send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "historical protocol version requested, use LDAPv3 instead" ); goto cleanup; } /* * we set connection version regardless of whether bind succeeds or not. */ ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); op->o_conn->c_protocol = version; ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); op->orb_mech = mech; op->o_bd = frontendDB; rs->sr_err = frontendDB->be_bind( op, rs ); cleanup: if ( rs->sr_err == LDAP_SUCCESS ) { if ( op->orb_method != LDAP_AUTH_SASL ) { ber_dupbv( &op->o_conn->c_authmech, &mech ); } op->o_conn->c_authtype = op->orb_method; } if( !BER_BVISNULL( &op->o_req_dn ) ) { slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_req_dn ); } if( !BER_BVISNULL( &op->o_req_ndn ) ) { slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_req_ndn ); } return rs->sr_err; }