int ldap_get_option( LDAP *ld, int option, void *outvalue) { struct ldapoptions *lo; int rc = LDAP_OPT_ERROR; /* Get pointer to global option structure */ lo = LDAP_INT_GLOBAL_OPT(); if (NULL == lo) { return LDAP_NO_MEMORY; } if( lo->ldo_valid != LDAP_INITIALIZED ) { ldap_int_initialize(lo, NULL); if ( lo->ldo_valid != LDAP_INITIALIZED ) return LDAP_LOCAL_ERROR; } if(ld != NULL) { assert( LDAP_VALID( ld ) ); if( !LDAP_VALID( ld ) ) { return LDAP_OPT_ERROR; } lo = &ld->ld_options; } if(outvalue == NULL) { /* no place to get to */ return LDAP_OPT_ERROR; } LDAP_MUTEX_LOCK( &lo->ldo_mutex ); switch(option) { case LDAP_OPT_API_INFO: { struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue; if(info == NULL) { /* outvalue must point to an apiinfo structure */ break; /* LDAP_OPT_ERROR */ } if(info->ldapai_info_version != LDAP_API_INFO_VERSION) { /* api info version mismatch */ info->ldapai_info_version = LDAP_API_INFO_VERSION; break; /* LDAP_OPT_ERROR */ } info->ldapai_api_version = LDAP_API_VERSION; info->ldapai_protocol_version = LDAP_VERSION_MAX; if(features[0].ldapaif_name == NULL) { info->ldapai_extensions = NULL; } else { int i; info->ldapai_extensions = LDAP_MALLOC(sizeof(char *) * sizeof(features)/sizeof(LDAPAPIFeatureInfo)); for(i=0; features[i].ldapaif_name != NULL; i++) { info->ldapai_extensions[i] = LDAP_STRDUP(features[i].ldapaif_name); } info->ldapai_extensions[i] = NULL; } info->ldapai_vendor_name = LDAP_STRDUP(LDAP_VENDOR_NAME); info->ldapai_vendor_version = LDAP_VENDOR_VERSION; rc = LDAP_OPT_SUCCESS; break; } break; case LDAP_OPT_DESC: if( ld == NULL || ld->ld_sb == NULL ) { /* bad param */ break; } ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, outvalue ); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_SOCKBUF: if( ld == NULL ) break; *(Sockbuf **)outvalue = ld->ld_sb; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_TIMEOUT: /* the caller has to free outvalue ! */ if ( lo->ldo_tm_api.tv_sec < 0 ) { *(void **)outvalue = NULL; } else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_api ) != 0 ) { break; /* LDAP_OPT_ERROR */ } rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_NETWORK_TIMEOUT: /* the caller has to free outvalue ! */ if ( lo->ldo_tm_net.tv_sec < 0 ) { *(void **)outvalue = NULL; } else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_net ) != 0 ) { break; /* LDAP_OPT_ERROR */ } rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_DEREF: * (int *) outvalue = lo->ldo_deref; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_SIZELIMIT: * (int *) outvalue = lo->ldo_sizelimit; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_TIMELIMIT: * (int *) outvalue = lo->ldo_timelimit; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_REFERRALS: * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_REFERRALS); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_RESTART: * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_PROTOCOL_VERSION: * (int *) outvalue = lo->ldo_version; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_SERVER_CONTROLS: * (LDAPControl ***) outvalue = ldap_controls_dup( lo->ldo_sctrls ); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_CLIENT_CONTROLS: * (LDAPControl ***) outvalue = ldap_controls_dup( lo->ldo_cctrls ); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_HOST_NAME: * (char **) outvalue = ldap_url_list2hosts(lo->ldo_defludp); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_URI: * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_DEFBASE: if( lo->ldo_defbase == NULL ) { * (char **) outvalue = NULL; } else { * (char **) outvalue = LDAP_STRDUP(lo->ldo_defbase); } rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_CONNECT_ASYNC: * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_CONNECT_ASYNC); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_CONNECT_CB: { /* Getting deletes the specified callback */ ldaplist **ll = &lo->ldo_conn_cbs; for (;*ll;ll = &(*ll)->ll_next) { if ((*ll)->ll_data == outvalue) { ldaplist *lc = *ll; *ll = lc->ll_next; LDAP_FREE(lc); break; } } } rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_RESULT_CODE: if(ld == NULL) { /* bad param */ break; } * (int *) outvalue = ld->ld_errno; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_DIAGNOSTIC_MESSAGE: if(ld == NULL) { /* bad param */ break; } if( ld->ld_error == NULL ) { * (char **) outvalue = NULL; } else { * (char **) outvalue = LDAP_STRDUP(ld->ld_error); } rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_MATCHED_DN: if(ld == NULL) { /* bad param */ break; } if( ld->ld_matched == NULL ) { * (char **) outvalue = NULL; } else { * (char **) outvalue = LDAP_STRDUP( ld->ld_matched ); } rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_REFERRAL_URLS: if(ld == NULL) { /* bad param */ break; } if( ld->ld_referrals == NULL ) { * (char ***) outvalue = NULL; } else { * (char ***) outvalue = ldap_value_dup(ld->ld_referrals); } rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_API_FEATURE_INFO: { LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue; int i; if(info == NULL) break; /* LDAP_OPT_ERROR */ if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) { /* api info version mismatch */ info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION; break; /* LDAP_OPT_ERROR */ } if(info->ldapaif_name == NULL) break; /* LDAP_OPT_ERROR */ for(i=0; features[i].ldapaif_name != NULL; i++) { if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) { info->ldapaif_version = features[i].ldapaif_version; rc = LDAP_OPT_SUCCESS; break; } } } break; case LDAP_OPT_DEBUG_LEVEL: * (int *) outvalue = lo->ldo_debug; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_SESSION_REFCNT: if(ld == NULL) { /* bad param */ break; } LDAP_MUTEX_LOCK( &ld->ld_ldcmutex ); * (int *) outvalue = ld->ld_ldcrefcnt; LDAP_MUTEX_UNLOCK( &ld->ld_ldcmutex ); rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_X_KEEPALIVE_IDLE: * (int *) outvalue = lo->ldo_keepalive_idle; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_X_KEEPALIVE_PROBES: * (int *) outvalue = lo->ldo_keepalive_probes; rc = LDAP_OPT_SUCCESS; break; case LDAP_OPT_X_KEEPALIVE_INTERVAL: * (int *) outvalue = lo->ldo_keepalive_interval; rc = LDAP_OPT_SUCCESS; break; default: #ifdef HAVE_TLS if ( ldap_pvt_tls_get_option( ld, option, outvalue ) == 0 ) { rc = LDAP_OPT_SUCCESS; break; } #endif #ifdef HAVE_CYRUS_SASL if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) { rc = LDAP_OPT_SUCCESS; break; } #endif #ifdef HAVE_GSSAPI if ( ldap_int_gssapi_get_option( ld, option, outvalue ) == 0 ) { rc = LDAP_OPT_SUCCESS; break; } #endif /* bad param */ break; } LDAP_MUTEX_UNLOCK( &lo->ldo_mutex ); return ( rc ); }
static int ldap_back_monitor_modify( Operation *op, SlapReply *rs, Entry *e, void *priv ) { ldapinfo_t *li = (ldapinfo_t *) priv; Attribute *save_attrs = NULL; Modifications *ml, *ml_olmDbURIList = NULL; struct berval ul = BER_BVNULL; int got = 0; for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) { if ( ml->sml_desc == ad_olmDbURIList ) { if ( ml_olmDbURIList != NULL ) { rs->sr_err = LDAP_CONSTRAINT_VIOLATION; rs->sr_text = "conflicting modifications"; goto done; } if ( ml->sml_op != LDAP_MOD_REPLACE ) { rs->sr_err = LDAP_CONSTRAINT_VIOLATION; rs->sr_text = "modification not allowed"; goto done; } ml_olmDbURIList = ml; got++; continue; } } if ( got == 0 ) { return SLAP_CB_CONTINUE; } save_attrs = attrs_dup( e->e_attrs ); if ( ml_olmDbURIList != NULL ) { Attribute *a = NULL; LDAPURLDesc *ludlist = NULL; int rc; ml = ml_olmDbURIList; assert( ml->sml_nvalues != NULL ); if ( BER_BVISNULL( &ml->sml_nvalues[ 0 ] ) ) { rs->sr_err = LDAP_CONSTRAINT_VIOLATION; rs->sr_text = "no value provided"; goto done; } if ( !BER_BVISNULL( &ml->sml_nvalues[ 1 ] ) ) { rs->sr_err = LDAP_CONSTRAINT_VIOLATION; rs->sr_text = "multiple values provided"; goto done; } rc = ldap_url_parselist_ext( &ludlist, ml->sml_nvalues[ 0 ].bv_val, NULL, LDAP_PVT_URL_PARSE_NOEMPTY_HOST | LDAP_PVT_URL_PARSE_DEF_PORT ); if ( rc != LDAP_URL_SUCCESS ) { rs->sr_err = LDAP_INVALID_SYNTAX; rs->sr_text = "unable to parse URI list"; goto done; } ul.bv_val = ldap_url_list2urls( ludlist ); ldap_free_urllist( ludlist ); if ( ul.bv_val == NULL ) { rs->sr_err = LDAP_OTHER; goto done; } ul.bv_len = strlen( ul.bv_val ); a = attr_find( e->e_attrs, ad_olmDbURIList ); if ( a != NULL ) { if ( a->a_nvals == a->a_vals ) { a->a_nvals = ch_calloc( sizeof( struct berval ), 2 ); } ber_bvreplace( &a->a_vals[ 0 ], &ul ); ber_bvreplace( &a->a_nvals[ 0 ], &ul ); } else { attr_merge_normalize_one( e, ad_olmDbURIList, &ul, NULL ); } } /* apply changes */ if ( !BER_BVISNULL( &ul ) ) { ldap_pvt_thread_mutex_lock( &li->li_uri_mutex ); if ( li->li_uri ) { ch_free( li->li_uri ); } li->li_uri = ul.bv_val; ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex ); BER_BVZERO( &ul ); } done:; if ( !BER_BVISNULL( &ul ) ) { ldap_memfree( ul.bv_val ); } if ( rs->sr_err == LDAP_SUCCESS ) { attrs_free( save_attrs ); return SLAP_CB_CONTINUE; } attrs_free( e->e_attrs ); e->e_attrs = save_attrs; return rs->sr_err; }