/*********************************************************************** * ldap_explode_dnW (WLDAP32.@) * * Break up a DN into its components. * * PARAMS * dn [I] DN to break up. * notypes [I] Remove attribute type information from the components. * * RETURNS * Success: Pointer to a NULL-terminated array that contains the DN * components. * Failure: NULL * * NOTES * Free the string array with ldap_value_free. */ PWCHAR * CDECL ldap_explode_dnW( PWCHAR dn, ULONG notypes ) { PWCHAR *ret = NULL; #ifdef HAVE_LDAP char *dnU, **retU; TRACE( "(%s, 0x%08x)\n", debugstr_w(dn), notypes ); dnU = strWtoU( dn ); if (!dnU) return NULL; retU = ldap_explode_dn( dnU, notypes ); ret = strarrayUtoW( retU ); strfreeU( dnU ); ldap_memvfree( (void **)retU ); #endif return ret; }
static int constraint_cf_gen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)(c->bi); constraint *cn = on->on_bi.bi_private, *cp; struct berval bv; int i, rc = 0; constraint ap = { NULL }; const char *text = NULL; switch ( c->op ) { case SLAP_CONFIG_EMIT: switch (c->type) { case CONSTRAINT_ATTRIBUTE: for (cp=cn; cp; cp=cp->ap_next) { char *s; char *tstr = NULL; int quotes = 0; int j; bv.bv_len = STRLENOF(" "); for (j = 0; cp->ap[j]; j++) { bv.bv_len += cp->ap[j]->ad_cname.bv_len; } /* room for commas */ bv.bv_len += j - 1; if (cp->re) { tstr = REGEX_STR; } else if (cp->lud) { tstr = URI_STR; quotes = 1; } else if (cp->set) { tstr = SET_STR; quotes = 1; } else if (cp->size) { tstr = SIZE_STR; } else if (cp->count) { tstr = COUNT_STR; } bv.bv_len += strlen(tstr); bv.bv_len += cp->val.bv_len + 2*quotes; if (cp->restrict_lud != NULL) { bv.bv_len += cp->restrict_val.bv_len + STRLENOF(" restrict=\"\""); } s = bv.bv_val = ch_malloc(bv.bv_len + 1); s = lutil_strncopy( s, cp->ap[0]->ad_cname.bv_val, cp->ap[0]->ad_cname.bv_len ); for (j = 1; cp->ap[j]; j++) { *s++ = ','; s = lutil_strncopy( s, cp->ap[j]->ad_cname.bv_val, cp->ap[j]->ad_cname.bv_len ); } *s++ = ' '; s = lutil_strcopy( s, tstr ); *s++ = ' '; if ( quotes ) *s++ = '"'; s = lutil_strncopy( s, cp->val.bv_val, cp->val.bv_len ); if ( quotes ) *s++ = '"'; if (cp->restrict_lud != NULL) { s = lutil_strcopy( s, " restrict=\"" ); s = lutil_strncopy( s, cp->restrict_val.bv_val, cp->restrict_val.bv_len ); *s++ = '"'; } *s = '\0'; rc = value_add_one( &c->rvalue_vals, &bv ); if (rc == LDAP_SUCCESS) rc = value_add_one( &c->rvalue_nvals, &bv ); ch_free(bv.bv_val); if (rc) return rc; } break; default: abort(); break; } break; case LDAP_MOD_DELETE: switch (c->type) { case CONSTRAINT_ATTRIBUTE: if (!cn) break; /* nothing to do */ if (c->valx < 0) { /* zap all constraints */ while (cn) { cp = cn->ap_next; constraint_free( cn, 1 ); cn = cp; } on->on_bi.bi_private = NULL; } else { constraint **cpp; /* zap constraint numbered 'valx' */ for(i=0, cp = cn, cpp = &cn; (cp) && (i<c->valx); i++, cpp = &cp->ap_next, cp = *cpp); if (cp) { /* zap cp, and join cpp to cp->ap_next */ *cpp = cp->ap_next; constraint_free( cp, 1 ); } on->on_bi.bi_private = cn; } break; default: abort(); break; } break; case SLAP_CONFIG_ADD: case LDAP_MOD_ADD: switch (c->type) { case CONSTRAINT_ATTRIBUTE: { int j; char **attrs = ldap_str2charray( c->argv[1], "," ); for ( j = 0; attrs[j]; j++) /* just count */ ; ap.ap = ch_calloc( sizeof(AttributeDescription*), j + 1 ); for ( j = 0; attrs[j]; j++) { if ( slap_str2ad( attrs[j], &ap.ap[j], &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s <%s>: %s\n", c->argv[0], attrs[j], text ); rc = ARG_BAD_CONF; goto done; } } if ( strcasecmp( c->argv[2], REGEX_STR ) == 0) { int err; ap.re = ch_malloc( sizeof(regex_t) ); if ((err = regcomp( ap.re, c->argv[3], REG_EXTENDED )) != 0) { char errmsg[1024]; regerror( err, ap.re, errmsg, sizeof(errmsg) ); ch_free(ap.re); snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Illegal regular expression \"%s\": Error %s", c->argv[0], c->argv[1], c->argv[3], errmsg); ap.re = NULL; rc = ARG_BAD_CONF; goto done; } ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else if ( strcasecmp( c->argv[2], SIZE_STR ) == 0 ) { size_t size; if ( ( size = atoi(c->argv[3]) ) != 0 ) ap.size = size; } else if ( strcasecmp( c->argv[2], COUNT_STR ) == 0 ) { size_t count; if ( ( count = atoi(c->argv[3]) ) != 0 ) ap.count = count; } else if ( strcasecmp( c->argv[2], URI_STR ) == 0 ) { int err; err = ldap_url_parse(c->argv[3], &ap.lud); if ( err != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Invalid URI \"%s\"", c->argv[0], c->argv[1], c->argv[3]); rc = ARG_BAD_CONF; goto done; } if (ap.lud->lud_host != NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unsupported hostname in URI \"%s\"", c->argv[0], c->argv[1], c->argv[3]); ldap_free_urldesc(ap.lud); rc = ARG_BAD_CONF; goto done; } for ( i=0; ap.lud->lud_attrs[i]; i++); /* FIXME: This is worthless without at least one attr */ if ( i ) { ap.attrs = ch_malloc( (i+1)*sizeof(AttributeDescription *)); for ( i=0; ap.lud->lud_attrs[i]; i++) { ap.attrs[i] = NULL; if ( slap_str2ad( ap.lud->lud_attrs[i], &ap.attrs[i], &text ) ) { ch_free( ap.attrs ); snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s <%s>: %s\n", c->argv[0], ap.lud->lud_attrs[i], text ); rc = ARG_BAD_CONF; goto done; } } ap.attrs[i] = NULL; } if (ap.lud->lud_dn == NULL) { ap.lud->lud_dn = ch_strdup(""); } else { struct berval dn, ndn; ber_str2bv( ap.lud->lud_dn, 0, 0, &dn ); if (dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) ) { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: URI %s DN normalization failed", c->argv[0], c->argv[1], c->argv[3] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); rc = ARG_BAD_CONF; goto done; } ldap_memfree( ap.lud->lud_dn ); ap.lud->lud_dn = ndn.bv_val; } if (ap.lud->lud_filter == NULL) { ap.lud->lud_filter = ch_strdup("objectClass=*"); } else if ( ap.lud->lud_filter[0] == '(' ) { ber_len_t len = strlen( ap.lud->lud_filter ); if ( ap.lud->lud_filter[len - 1] != ')' ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: invalid URI filter: %s", c->argv[0], c->argv[1], ap.lud->lud_filter ); rc = ARG_BAD_CONF; goto done; } AC_MEMCPY( &ap.lud->lud_filter[0], &ap.lud->lud_filter[1], len - 2 ); ap.lud->lud_filter[len - 2] = '\0'; } ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else if ( strcasecmp( c->argv[2], SET_STR ) == 0 ) { ap.set = 1; ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Unknown constraint type: %s", c->argv[0], c->argv[1], c->argv[2] ); rc = ARG_BAD_CONF; goto done; } if ( c->argc > 4 ) { int argidx; for ( argidx = 4; argidx < c->argc; argidx++ ) { if ( strncasecmp( c->argv[argidx], "restrict=", STRLENOF("restrict=") ) == 0 ) { int err; char *arg = c->argv[argidx] + STRLENOF("restrict="); err = ldap_url_parse(arg, &ap.restrict_lud); if ( err != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Invalid restrict URI \"%s\"", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } if (ap.restrict_lud->lud_host != NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unsupported hostname in restrict URI \"%s\"", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } if ( ap.restrict_lud->lud_attrs != NULL ) { if ( ap.restrict_lud->lud_attrs[0] != '\0' ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: attrs not allowed in restrict URI %s\n", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } ldap_memvfree((void *)ap.restrict_lud->lud_attrs); ap.restrict_lud->lud_attrs = NULL; } if (ap.restrict_lud->lud_dn != NULL) { if (ap.restrict_lud->lud_dn[0] == '\0') { ldap_memfree(ap.restrict_lud->lud_dn); ap.restrict_lud->lud_dn = NULL; } else { struct berval dn, ndn; int j; ber_str2bv(ap.restrict_lud->lud_dn, 0, 0, &dn); if (dnNormalize(0, NULL, NULL, &dn, &ndn, NULL)) { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI %s DN normalization failed", c->argv[0], c->argv[1], arg ); rc = ARG_BAD_CONF; goto done; } assert(c->be != NULL); if (c->be->be_nsuffix == NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI requires suffix", c->argv[0], c->argv[1] ); rc = ARG_BAD_CONF; goto done; } for ( j = 0; !BER_BVISNULL(&c->be->be_nsuffix[j]); j++) { if (dnIsSuffix(&ndn, &c->be->be_nsuffix[j])) break; } if (BER_BVISNULL(&c->be->be_nsuffix[j])) { /* error */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI DN %s not within database naming context(s)", c->argv[0], c->argv[1], dn.bv_val ); rc = ARG_BAD_CONF; goto done; } ap.restrict_ndn = ndn; } } if (ap.restrict_lud->lud_filter != NULL) { ap.restrict_filter = str2filter(ap.restrict_lud->lud_filter); if (ap.restrict_filter == NULL) { /* error */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI filter %s invalid", c->argv[0], c->argv[1], ap.restrict_lud->lud_filter ); rc = ARG_BAD_CONF; goto done; } } ber_str2bv(c->argv[argidx], 0, 1, &ap.restrict_val); } else { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unrecognized arg #%d (%s)", c->argv[0], c->argv[1], argidx, c->argv[argidx] ); rc = ARG_BAD_CONF; goto done; } } } done:; if ( rc == LDAP_SUCCESS ) { constraint *a2 = ch_calloc( sizeof(constraint), 1 ); a2->ap_next = on->on_bi.bi_private; a2->ap = ap.ap; a2->re = ap.re; a2->val = ap.val; a2->lud = ap.lud; a2->set = ap.set; a2->size = ap.size; a2->count = ap.count; if ( a2->lud ) { ber_str2bv(a2->lud->lud_dn, 0, 0, &a2->dn); ber_str2bv(a2->lud->lud_filter, 0, 0, &a2->filter); } a2->attrs = ap.attrs; a2->restrict_lud = ap.restrict_lud; a2->restrict_ndn = ap.restrict_ndn; a2->restrict_filter = ap.restrict_filter; a2->restrict_val = ap.restrict_val; on->on_bi.bi_private = a2; } else { Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); constraint_free( &ap, 0 ); } ldap_memvfree((void**)attrs); } break; default: abort(); break; } break; default: abort(); } return rc; }
/*********************************************************************** * ldap_get_optionW (WLDAP32.@) * * Retrieve option values for a given LDAP context. * * PARAMS * ld [I] Pointer to an LDAP context. * option [I] Option to get values for. * value [O] Pointer to option values. * * RETURNS * Success: LDAP_SUCCESS * Failure: An LDAP error code. */ ULONG CDECL ldap_get_optionW( WLDAP32_LDAP *ld, int option, void *value ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP TRACE( "(%p, 0x%08x, %p)\n", ld, option, value ); if (!ld || !value) return WLDAP32_LDAP_PARAM_ERROR; switch (option) { case WLDAP32_LDAP_OPT_API_FEATURE_INFO: { LDAPAPIFeatureInfo featureU; LDAPAPIFeatureInfoW *featureW = value; if (!featureW->ldapaif_name) return WLDAP32_LDAP_PARAM_ERROR; featureU.ldapaif_info_version = featureW->ldapaif_info_version; featureU.ldapaif_name = strWtoU( featureW->ldapaif_name ); featureU.ldapaif_version = 0; if (!featureU.ldapaif_name) return WLDAP32_LDAP_NO_MEMORY; ret = map_error( ldap_get_option( ld, option, &featureU )); featureW->ldapaif_version = featureU.ldapaif_version; strfreeU( featureU.ldapaif_name ); return ret; } case WLDAP32_LDAP_OPT_API_INFO: { LDAPAPIInfo infoU; LDAPAPIInfoW *infoW = value; memset( &infoU, 0, sizeof(LDAPAPIInfo) ); infoU.ldapai_info_version = infoW->ldapai_info_version; ret = map_error( ldap_get_option( ld, option, &infoU )); infoW->ldapai_api_version = infoU.ldapai_api_version; infoW->ldapai_protocol_version = infoU.ldapai_protocol_version; if (infoU.ldapai_extensions) { infoW->ldapai_extensions = strarrayUtoW( infoU.ldapai_extensions ); if (!infoW->ldapai_extensions) return WLDAP32_LDAP_NO_MEMORY; } if (infoU.ldapai_vendor_name) { infoW->ldapai_vendor_name = strUtoW( infoU.ldapai_vendor_name ); if (!infoW->ldapai_vendor_name) { ldap_memvfree( (void **)infoU.ldapai_extensions ); return WLDAP32_LDAP_NO_MEMORY; } } infoW->ldapai_vendor_version = infoU.ldapai_vendor_version; ldap_memvfree( (void **)infoU.ldapai_extensions ); ldap_memfree( infoU.ldapai_vendor_name ); return ret; } case WLDAP32_LDAP_OPT_DEREF: case WLDAP32_LDAP_OPT_DESC: case WLDAP32_LDAP_OPT_ERROR_NUMBER: case WLDAP32_LDAP_OPT_PROTOCOL_VERSION: case WLDAP32_LDAP_OPT_REFERRALS: case WLDAP32_LDAP_OPT_SIZELIMIT: case WLDAP32_LDAP_OPT_TIMELIMIT: return map_error( ldap_get_option( ld, option, value )); case WLDAP32_LDAP_OPT_CACHE_ENABLE: case WLDAP32_LDAP_OPT_CACHE_FN_PTRS: case WLDAP32_LDAP_OPT_CACHE_STRATEGY: case WLDAP32_LDAP_OPT_IO_FN_PTRS: case WLDAP32_LDAP_OPT_REBIND_ARG: case WLDAP32_LDAP_OPT_REBIND_FN: case WLDAP32_LDAP_OPT_RESTART: case WLDAP32_LDAP_OPT_THREAD_FN_PTRS: return WLDAP32_LDAP_LOCAL_ERROR; case WLDAP32_LDAP_OPT_AREC_EXCLUSIVE: case WLDAP32_LDAP_OPT_AUTO_RECONNECT: case WLDAP32_LDAP_OPT_CLIENT_CERTIFICATE: case WLDAP32_LDAP_OPT_DNSDOMAIN_NAME: case WLDAP32_LDAP_OPT_ENCRYPT: case WLDAP32_LDAP_OPT_ERROR_STRING: case WLDAP32_LDAP_OPT_FAST_CONCURRENT_BIND: case WLDAP32_LDAP_OPT_GETDSNAME_FLAGS: case WLDAP32_LDAP_OPT_HOST_NAME: case WLDAP32_LDAP_OPT_HOST_REACHABLE: case WLDAP32_LDAP_OPT_PING_KEEP_ALIVE: case WLDAP32_LDAP_OPT_PING_LIMIT: case WLDAP32_LDAP_OPT_PING_WAIT_TIME: case WLDAP32_LDAP_OPT_PROMPT_CREDENTIALS: case WLDAP32_LDAP_OPT_REF_DEREF_CONN_PER_MSG: case WLDAP32_LDAP_OPT_REFERRAL_CALLBACK: case WLDAP32_LDAP_OPT_REFERRAL_HOP_LIMIT: case WLDAP32_LDAP_OPT_ROOTDSE_CACHE: case WLDAP32_LDAP_OPT_SASL_METHOD: case WLDAP32_LDAP_OPT_SECURITY_CONTEXT: case WLDAP32_LDAP_OPT_SEND_TIMEOUT: case WLDAP32_LDAP_OPT_SERVER_CERTIFICATE: case WLDAP32_LDAP_OPT_SERVER_CONTROLS: case WLDAP32_LDAP_OPT_SERVER_ERROR: case WLDAP32_LDAP_OPT_SERVER_EXT_ERROR: case WLDAP32_LDAP_OPT_SIGN: case WLDAP32_LDAP_OPT_SSL: case WLDAP32_LDAP_OPT_SSL_INFO: case WLDAP32_LDAP_OPT_SSPI_FLAGS: case WLDAP32_LDAP_OPT_TCP_KEEPALIVE: FIXME( "Unsupported option: 0x%02x\n", option ); return WLDAP32_LDAP_NOT_SUPPORTED; default: FIXME( "Unknown option: 0x%02x\n", option ); return WLDAP32_LDAP_LOCAL_ERROR; } #endif return ret; }