struct berval * slap_passwd_return( struct berval *cred ) { int rc; struct berval *bv = NULL; BerElementBuffer berbuf; /* opaque structure, size unknown but smaller than berbuf */ BerElement *ber = (BerElement *)&berbuf; assert( cred != NULL ); Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n", (long) cred->bv_len, 0, 0 ); ber_init_w_nullc( ber, LBER_USE_DER ); rc = ber_printf( ber, "{tON}", LDAP_TAG_EXOP_MODIFY_PASSWD_GEN, cred ); if( rc >= 0 ) { (void) ber_flatten( ber, &bv ); } ber_free_buf( ber ); return bv; }
struct berval * slap_passwd_return( struct berval *cred ) { int rc; struct berval *bv = NULL; char berbuf[LBER_ELEMENT_SIZEOF]; /* opaque structure, size unknown but smaller than berbuf */ BerElement *ber = (BerElement *)berbuf; assert( cred != NULL ); #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "slap_passwd_return: %ld\n",(long)cred->bv_len, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n", (long) cred->bv_len, 0, 0 ); #endif ber_init_w_nullc( ber, LBER_USE_DER ); rc = ber_printf( ber, "{tON}", LDAP_TAG_EXOP_MODIFY_PASSWD_GEN, cred ); if( rc >= 0 ) { (void) ber_flatten( ber, &bv ); } ber_free_buf( ber ); return bv; }
static int send_ldap_response( Operation *op, SlapReply *rs ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *) &berbuf; int rc = LDAP_SUCCESS; long bytes; /* op was actually aborted, bypass everything if client didn't Cancel */ if (( rs->sr_err == SLAPD_ABANDON ) && !op->o_cancel ) { rc = SLAPD_ABANDON; goto clean2; } if ( op->o_callback ) { rc = slap_response_play( op, rs ); if ( rc != SLAP_CB_CONTINUE ) { goto clean2; } } /* op completed, connection aborted, bypass sending response */ if ( op->o_abandon && !op->o_cancel ) { rc = SLAPD_ABANDON; goto clean2; } #ifdef LDAP_CONNECTIONLESS if (op->o_conn && op->o_conn->c_is_udp) ber = op->o_res_ber; else #endif { ber_init_w_nullc( ber, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); } rc = rs->sr_err; if ( rc == SLAPD_ABANDON && op->o_cancel ) rc = LDAP_CANCELLED; Debug( LDAP_DEBUG_TRACE, "send_ldap_response: msgid=%d tag=%lu err=%d\n", rs->sr_msgid, rs->sr_tag, rc ); if( rs->sr_ref ) { Debug( LDAP_DEBUG_ARGS, "send_ldap_response: ref=\"%s\"\n", rs->sr_ref[0].bv_val ? rs->sr_ref[0].bv_val : "NULL" ); } #ifdef LDAP_CONNECTIONLESS if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2 ) { rc = ber_printf( ber, "t{ess" /*"}"*/, rs->sr_tag, rc, rs->sr_matched == NULL ? "" : rs->sr_matched, rs->sr_text == NULL ? "" : rs->sr_text ); } else #endif if ( rs->sr_type == REP_INTERMEDIATE ) { rc = ber_printf( ber, "{it{" /*"}}"*/, rs->sr_msgid, rs->sr_tag ); } else { rc = ber_printf( ber, "{it{ess" /*"}}"*/, rs->sr_msgid, rs->sr_tag, rc, rs->sr_matched == NULL ? "" : rs->sr_matched, rs->sr_text == NULL ? "" : rs->sr_text ); } if( rc != -1 ) { if ( rs->sr_ref != NULL ) { assert( rs->sr_err == LDAP_REFERRAL ); rc = ber_printf( ber, "t{W}", LDAP_TAG_REFERRAL, rs->sr_ref ); } else { assert( rs->sr_err != LDAP_REFERRAL ); } } if( rc != -1 && rs->sr_type == REP_SASL && rs->sr_sasldata != NULL ) { rc = ber_printf( ber, "tO", LDAP_TAG_SASL_RES_CREDS, rs->sr_sasldata ); } if( rc != -1 && ( rs->sr_type == REP_EXTENDED || rs->sr_type == REP_INTERMEDIATE )) { if ( rs->sr_rspoid != NULL ) { rc = ber_printf( ber, "ts", rs->sr_type == REP_EXTENDED ? LDAP_TAG_EXOP_RES_OID : LDAP_TAG_IM_RES_OID, rs->sr_rspoid ); } if( rc != -1 && rs->sr_rspdata != NULL ) { rc = ber_printf( ber, "tO", rs->sr_type == REP_EXTENDED ? LDAP_TAG_EXOP_RES_VALUE : LDAP_TAG_IM_RES_VALUE, rs->sr_rspdata ); } } if( rc != -1 ) { rc = ber_printf( ber, /*"{"*/ "N}" ); } if( rc != -1 ) { rc = send_ldap_controls( op, ber, rs->sr_ctrls ); } if( rc != -1 ) { rc = ber_printf( ber, /*"{"*/ "N}" ); } #ifdef LDAP_CONNECTIONLESS if( op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1 ) { rc = ber_printf( ber, /*"{"*/ "N}" ); } #endif if ( rc == -1 ) { Debug( LDAP_DEBUG_ANY, "ber_printf failed\n" ); #ifdef LDAP_CONNECTIONLESS if (!op->o_conn || op->o_conn->c_is_udp == 0) #endif { ber_free_buf( ber ); } goto cleanup; } /* send BER */ bytes = send_ldap_ber( op, ber ); #ifdef LDAP_CONNECTIONLESS if (!op->o_conn || op->o_conn->c_is_udp == 0) #endif { ber_free_buf( ber ); } if ( bytes < 0 ) { Debug( LDAP_DEBUG_ANY, "send_ldap_response: ber write failed\n" ); goto cleanup; } ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); ldap_pvt_mp_add_ulong( op->o_counters->sc_pdu, 1 ); ldap_pvt_mp_add_ulong( op->o_counters->sc_bytes, (unsigned long)bytes ); ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); cleanup:; /* Tell caller that we did this for real, as opposed to being * overridden by a callback */ rc = SLAP_CB_CONTINUE; clean2:; if ( op->o_callback ) { (void)slap_cleanup_play( op, rs ); } if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) { rs->sr_flags ^= REP_MATCHED_MUSTBEFREED; /* paranoia */ if ( rs->sr_matched ) { free( (char *)rs->sr_matched ); rs->sr_matched = NULL; } } if ( rs->sr_flags & REP_REF_MUSTBEFREED ) { rs->sr_flags ^= REP_REF_MUSTBEFREED; /* paranoia */ if ( rs->sr_ref ) { ber_bvarray_free( rs->sr_ref ); rs->sr_ref = NULL; } } if ( rs->sr_flags & REP_CTRLS_MUSTBEFREED ) { rs->sr_flags ^= REP_CTRLS_MUSTBEFREED; /* paranoia */ if ( rs->sr_ctrls ) { slap_free_ctrls( op, rs->sr_ctrls ); rs->sr_ctrls = NULL; } } return rc; }
int slap_send_search_reference( Operation *op, SlapReply *rs ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *) &berbuf; int rc = 0; int bytes; char *edn = rs->sr_entry ? rs->sr_entry->e_name.bv_val : "(null)"; AttributeDescription *ad_ref = slap_schema.si_ad_ref; AttributeDescription *ad_entry = slap_schema.si_ad_entry; rs->sr_type = REP_SEARCHREF; if ( op->o_callback ) { rc = slap_response_play( op, rs ); if ( rc != SLAP_CB_CONTINUE ) { goto rel; } } Debug( LDAP_DEBUG_TRACE, "=> send_search_reference: dn=\"%s\"\n", edn ); if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry, ad_entry, NULL, ACL_READ, NULL ) ) { Debug( LDAP_DEBUG_ACL, "send_search_reference: access to entry not allowed\n" ); rc = 1; goto rel; } if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry, ad_ref, NULL, ACL_READ, NULL ) ) { Debug( LDAP_DEBUG_ACL, "send_search_reference: access " "to reference not allowed\n" ); rc = 1; goto rel; } if( op->o_domain_scope ) { Debug( LDAP_DEBUG_ANY, "send_search_reference: domainScope control in (%s)\n", edn ); rc = 0; goto rel; } if( rs->sr_ref == NULL ) { Debug( LDAP_DEBUG_ANY, "send_search_reference: null ref in (%s)\n", edn ); rc = 1; goto rel; } if( op->o_protocol < LDAP_VERSION3 ) { rc = 0; /* save the references for the result */ if( rs->sr_ref[0].bv_val != NULL ) { if( value_add( &rs->sr_v2ref, rs->sr_ref ) ) rc = LDAP_OTHER; } goto rel; } #ifdef LDAP_CONNECTIONLESS if( op->o_conn && op->o_conn->c_is_udp ) { ber = op->o_res_ber; } else #endif { ber_init_w_nullc( ber, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); } rc = ber_printf( ber, "{it{W}" /*"}"*/ , op->o_msgid, LDAP_RES_SEARCH_REFERENCE, rs->sr_ref ); if( rc != -1 ) { rc = send_ldap_controls( op, ber, rs->sr_ctrls ); } if( rc != -1 ) { rc = ber_printf( ber, /*"{"*/ "N}" ); } if ( rc == -1 ) { Debug( LDAP_DEBUG_ANY, "send_search_reference: ber_printf failed\n" ); #ifdef LDAP_CONNECTIONLESS if (!op->o_conn || op->o_conn->c_is_udp == 0) #endif ber_free_buf( ber ); set_ldap_error( rs, LDAP_OTHER, "encode DN error" ); goto rel; } rc = 0; rs_flush_entry( op, rs, NULL ); #ifdef LDAP_CONNECTIONLESS if (!op->o_conn || op->o_conn->c_is_udp == 0) { #endif bytes = send_ldap_ber( op, ber ); ber_free_buf( ber ); if ( bytes < 0 ) { rc = LDAP_UNAVAILABLE; } else { ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); ldap_pvt_mp_add_ulong( op->o_counters->sc_bytes, (unsigned long)bytes ); ldap_pvt_mp_add_ulong( op->o_counters->sc_refs, 1 ); ldap_pvt_mp_add_ulong( op->o_counters->sc_pdu, 1 ); ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); } #ifdef LDAP_CONNECTIONLESS } #endif if ( rs->sr_ref != NULL ) { int r; for ( r = 0; !BER_BVISNULL( &rs->sr_ref[ r ] ); r++ ) { Statslog( LDAP_DEBUG_STATS2, "%s REF #%d \"%s\"\n", op->o_log_prefix, r, rs->sr_ref[0].bv_val ); } } else { Statslog( LDAP_DEBUG_STATS2, "%s REF \"(null)\"\n", op->o_log_prefix ); } Debug( LDAP_DEBUG_TRACE, "<= send_search_reference\n" ); if ( 0 ) { rel: rs_flush_entry( op, rs, NULL ); } if ( op->o_callback ) { (void)slap_cleanup_play( op, rs ); } if ( rs->sr_flags & REP_CTRLS_MUSTBEFREED ) { rs->sr_flags ^= REP_CTRLS_MUSTBEFREED; /* paranoia */ if ( rs->sr_ctrls ) { slap_free_ctrls( op, rs->sr_ctrls ); rs->sr_ctrls = NULL; } } return rc; }
int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op) { struct berval npw; int32_t tmpint32; char dnc[1024]; char uidc[32]; char opwc[256]; char npwc[256]; char svcc[256]; struct paminfo pi; int rc; READ_STRING(fp,uidc); pi.uid.bv_val = uidc; pi.uid.bv_len = tmpint32; READ_STRING(fp,dnc); pi.dn.bv_val = dnc; pi.dn.bv_len = tmpint32; READ_STRING(fp,svcc); pi.svc.bv_val = svcc; pi.svc.bv_len = tmpint32; READ_STRING(fp,opwc); pi.pwd.bv_val = opwc; pi.pwd.bv_len = tmpint32; READ_STRING(fp,npwc); npw.bv_val = npwc; npw.bv_len = tmpint32; Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(%s), %s\n", pi.dn.bv_val,pi.uid.bv_val,0); BER_BVZERO(&pi.msg); /* This is a prelim check */ if (BER_BVISEMPTY(&pi.dn)) { rc = pam_do_bind(ni,fp,op,&pi); if (rc == NSLCD_PAM_IGNORE) rc = NSLCD_PAM_SUCCESS; } else { BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval bv; SlapReply rs = {REP_RESULT}; slap_callback cb = {0}; ber_init_w_nullc(ber, LBER_USE_DER); ber_printf(ber, "{"); if (!BER_BVISEMPTY(&pi.pwd)) ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, &pi.pwd); if (!BER_BVISEMPTY(&npw)) ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, &npw); ber_printf(ber, "N}"); ber_flatten2(ber, &bv, 0); op->o_tag = LDAP_REQ_EXTENDED; op->ore_reqoid = slap_EXOP_MODIFY_PASSWD; op->ore_reqdata = &bv; op->o_dn = pi.dn; op->o_ndn = pi.dn; op->o_callback = &cb; op->o_conn->c_authz_backend = op->o_bd; cb.sc_response = slap_null_cb; op->o_bd = frontendDB; rc = op->o_bd->be_extended(op, &rs); if (rs.sr_text) ber_str2bv(rs.sr_text, 0, 0, &pi.msg); if (rc == LDAP_SUCCESS) rc = NSLCD_PAM_SUCCESS; else rc = NSLCD_PAM_PERM_DENIED; } WRITE_INT32(fp,NSLCD_VERSION); WRITE_INT32(fp,NSLCD_ACTION_PAM_PWMOD); WRITE_INT32(fp,NSLCD_RESULT_BEGIN); WRITE_BERVAL(fp,&pi.uid); WRITE_BERVAL(fp,&pi.dn); WRITE_INT32(fp,rc); WRITE_BERVAL(fp,&pi.msg); return 0; }
static int dds_op_extended( 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; } if ( bvmatch( &op->ore_reqoid, &slap_EXOP_REFRESH ) ) { Entry *e = NULL; time_t ttl; BackendDB db = *op->o_bd; SlapReply rs2 = { REP_RESULT }; Operation op2 = *op; slap_callback sc = { 0 }; Modifications ttlmod = { { 0 } }; struct berval ttlvalues[ 2 ]; char ttlbuf[STRLENOF("31557600") + 1]; rs->sr_err = slap_parse_refresh( op->ore_reqdata, NULL, &ttl, &rs->sr_text, NULL ); assert( rs->sr_err == LDAP_SUCCESS ); if ( ttl <= 0 || ttl > DDS_RF2589_MAX_TTL ) { rs->sr_err = LDAP_PROTOCOL_ERROR; rs->sr_text = "invalid time-to-live for dynamicObject"; return rs->sr_err; } if ( ttl > di->di_max_ttl ) { /* FIXME: I don't understand if this has to be an error, * or an indication that the requested Ttl has been * shortened to di->di_max_ttl >= 1 day */ rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; rs->sr_text = "time-to-live for dynamicObject exceeds limit"; return rs->sr_err; } if ( di->di_min_ttl && ttl < di->di_min_ttl ) { ttl = di->di_min_ttl; } /* This does not apply to multi-master case */ if ( !( !SLAP_SINGLE_SHADOW( op->o_bd ) || be_isupdate( op ) ) ) { /* we SHOULD return a referral in this case */ BerVarray defref = op->o_bd->be_update_refs ? op->o_bd->be_update_refs : default_referral; if ( defref != NULL ) { rs->sr_ref = referral_rewrite( op->o_bd->be_update_refs, NULL, NULL, LDAP_SCOPE_DEFAULT ); if ( rs->sr_ref ) { rs->sr_flags |= REP_REF_MUSTBEFREED; } else { rs->sr_ref = defref; } rs->sr_err = LDAP_REFERRAL; } else { rs->sr_text = "shadow context; no update referral"; rs->sr_err = LDAP_UNWILLING_TO_PERFORM; } return rs->sr_err; } assert( !BER_BVISNULL( &op->o_req_ndn ) ); /* check if exists but not dynamicObject */ op->o_bd->bd_info = (BackendInfo *)on->on_info; rs->sr_err = be_entry_get_rw( op, &op->o_req_ndn, slap_schema.si_oc_dynamicObject, NULL, 0, &e ); if ( rs->sr_err != LDAP_SUCCESS ) { rs->sr_err = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e ); if ( rs->sr_err == LDAP_SUCCESS && e != NULL ) { /* 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; } else { rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; rs->sr_text = "refresh operation only applies to dynamic objects"; } be_entry_release_r( op, e ); } else { rs->sr_err = LDAP_NO_SUCH_OBJECT; } return rs->sr_err; } else if ( e != NULL ) { be_entry_release_r( op, e ); } /* we require manage privileges on the entryTtl, * and fake a Relax control */ op2.o_tag = LDAP_REQ_MODIFY; op2.o_bd = &db; db.bd_info = (BackendInfo *)on->on_info; op2.o_callback = ≻ sc.sc_response = slap_null_cb; op2.o_relax = SLAP_CONTROL_CRITICAL; op2.orm_modlist = &ttlmod; ttlmod.sml_op = LDAP_MOD_REPLACE; ttlmod.sml_flags = SLAP_MOD_MANAGING; ttlmod.sml_desc = slap_schema.si_ad_entryTtl; ttlmod.sml_values = ttlvalues; ttlmod.sml_numvals = 1; ttlvalues[ 0 ].bv_val = ttlbuf; ttlvalues[ 0 ].bv_len = snprintf( ttlbuf, sizeof( ttlbuf ), "%ld", ttl ); BER_BVZERO( &ttlvalues[ 1 ] ); /* the entryExpireTimestamp is added by modify */ rs->sr_err = slap_biglock_call_be( op_modify, &op2, &rs2 ); if ( ttlmod.sml_next != NULL ) { slap_mods_free( ttlmod.sml_next, 1 ); } if ( rs->sr_err == LDAP_SUCCESS ) { int rc; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; ber_init_w_nullc( ber, LBER_USE_DER ); rc = ber_printf( ber, "{tiN}", LDAP_TAG_EXOP_REFRESH_RES_TTL, (int)ttl ); if ( rc < 0 ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "internal error"; } else { (void)ber_flatten( ber, &rs->sr_rspdata ); rs->sr_rspoid = ch_strdup( slap_EXOP_REFRESH.bv_val ); Log3( LDAP_DEBUG_TRACE, LDAP_LEVEL_INFO, "%s REFRESH dn=\"%s\" TTL=%ld\n", op->o_log_prefix, op->o_req_ndn.bv_val, ttl ); } ber_free_buf( ber ); } return rs->sr_err; } return SLAP_CB_CONTINUE; }