/* * parse_dn * * Parse and reconstruct @attr if @out_userdn is not %NULL * * Returns: %TRUE if all OK */ gboolean gda_ldap_parse_dn (const char *attr, gchar **out_userdn) { LDAPDN tmpDN; if (out_userdn) *out_userdn = NULL; if (!attr) return FALSE; /* decoding */ if (ldap_str2dn (attr, &tmpDN, LDAP_DN_FORMAT_LDAPV3) != LDAP_SUCCESS) { if (ldap_str2dn (attr, &tmpDN, LDAP_DN_FORMAT_LDAPV2) != LDAP_SUCCESS) { if (ldap_str2dn (attr, &tmpDN, LDAP_DN_FORMAT_DCE) != LDAP_SUCCESS) return FALSE; } } if (out_userdn) { gchar *userdn; userdn = _gda_dn2str (tmpDN); ldap_dnfree (tmpDN); if (userdn) *out_userdn = userdn; else return FALSE; } else ldap_dnfree (tmpDN); return TRUE; }
int dnPretty2( Syntax *syntax, struct berval *val, struct berval *out) { assert( val ); assert( out ); #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ARGS, ">>> dnPretty: <%s>\n", val->bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, ">>> dnPretty: <%s>\n", val->bv_val, 0, 0 ); #endif if ( val->bv_len == 0 ) { ber_dupbv( out, val ); } else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) { return LDAP_INVALID_SYNTAX; } else { LDAPDN *dn = NULL; int rc; /* FIXME: should be liberal in what we accept */ rc = ldap_bv2dn( val, &dn, LDAP_DN_FORMAT_LDAP ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } assert( strlen( val->bv_val ) == val->bv_len ); /* * Schema-aware rewrite */ if ( LDAPDN_rewrite( dn, SLAP_LDAPDN_PRETTY ) != LDAP_SUCCESS ) { ldap_dnfree( dn ); return LDAP_INVALID_SYNTAX; } /* FIXME: not sure why the default isn't pretty */ /* RE: the default is the form that is used as * an internal representation; the pretty form * is a variant */ rc = ldap_dn2bv( dn, out, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY ); ldap_dnfree( dn ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } } Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 ); return LDAP_SUCCESS; }
int dnNormalize2( Syntax *syntax, struct berval *val, struct berval *out ) { assert( val ); assert( out ); Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val, 0, 0 ); if ( val->bv_len != 0 ) { LDAPDN *dn = NULL; int rc; /* * Go to structural representation */ rc = ldap_bv2dn( val, &dn, LDAP_DN_FORMAT_LDAP ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } assert( strlen( val->bv_val ) == val->bv_len ); /* * Schema-aware rewrite */ if ( LDAPDN_rewrite( dn, 0 ) != LDAP_SUCCESS ) { ldap_dnfree( dn ); return LDAP_INVALID_SYNTAX; } /* * Back to string representation */ rc = ldap_dn2bv( dn, out, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY ); ldap_dnfree( dn ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } } else { ber_dupbv( out, val ); } Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val, 0, 0 ); return LDAP_SUCCESS; }
int dnPrettyNormalDN( Syntax *syntax, struct berval *val, LDAPDN **dn, int flags ) { assert( val ); assert( dn ); #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ARGS, ">>> dn%sDN: <%s>\n", flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal", val->bv_val, 0 ); #else Debug( LDAP_DEBUG_TRACE, ">>> dn%sDN: <%s>\n", flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal", val->bv_val, 0 ); #endif if ( val->bv_len == 0 ) { return LDAP_SUCCESS; } else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) { return LDAP_INVALID_SYNTAX; } else { int rc; /* FIXME: should be liberal in what we accept */ rc = ldap_bv2dn( val, dn, LDAP_DN_FORMAT_LDAP ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } assert( strlen( val->bv_val ) == val->bv_len ); /* * Schema-aware rewrite */ if ( LDAPDN_rewrite( *dn, flags ) != LDAP_SUCCESS ) { ldap_dnfree( *dn ); *dn = NULL; return LDAP_INVALID_SYNTAX; } } Debug( LDAP_DEBUG_TRACE, "<<< dn%sDN\n", flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal", 0, 0 ); return LDAP_SUCCESS; }
void check_access_permission(const char *group_dn, const char *identifier, struct pox509_info *pox509_info) { if (group_dn == NULL || identifier == NULL || pox509_info == NULL) { fatal("group_dn, identifier or pox509_info == NULL"); } size_t group_dn_length = strlen(group_dn); if (group_dn_length == 0) { fatal("group_dn must be > 0"); } LDAPDN dn = NULL; int rc = ldap_str2dn(group_dn, &dn, LDAP_DN_FORMAT_LDAPV3); if (rc != LDAP_SUCCESS) { fatal("ldap_str2dn(): '%s' (%d)\n", ldap_err2string(rc), rc); } if (dn == NULL) { fatal("dn == NULL"); } LDAPRDN rdn = dn[0]; char *rdn_value = NULL; rc = ldap_rdn2str(rdn, &rdn_value, LDAP_DN_FORMAT_UFN); if (rc != LDAP_SUCCESS) { fatal("ldap_rdn2str(): '%s' (%d)\n", ldap_err2string(rc), rc); } rc = strcmp(rdn_value, identifier); if (rc == 0) { pox509_info->has_access = 1; } else { pox509_info->has_access = 0; } ldap_memfree(rdn_value); ldap_dnfree(dn); }
/* * dn validate routine */ int dnValidate( Syntax *syntax, struct berval *in ) { int rc; LDAPDN dn = NULL; assert( in != NULL ); if ( in->bv_len == 0 ) { return LDAP_SUCCESS; } else if ( in->bv_len > SLAP_LDAPDN_MAXLEN ) { return LDAP_INVALID_SYNTAX; } rc = ldap_bv2dn( in, &dn, LDAP_DN_FORMAT_LDAP ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } assert( strlen( in->bv_val ) == in->bv_len ); /* * Schema-aware validate */ rc = LDAPDN_validate( dn ); ldap_dnfree( dn ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } return LDAP_SUCCESS; }
DWORD LwCAIsValidDN( PCSTR pcszDN, PBOOLEAN pbIsValid ) { DWORD dwError = 0; LDAPDN dn = NULL; if (IsNullOrEmptyString(pcszDN) || !pbIsValid) { dwError = LWCA_ERROR_INVALID_PARAMETER; BAIL_ON_LWCA_ERROR(dwError); } dwError = ldap_str2dn(pcszDN, &dn, LDAP_DN_FORMAT_LDAPV3); if (dwError == LDAP_SUCCESS && dn != NULL) { *pbIsValid = TRUE; } else { *pbIsValid = FALSE; } error: if (dn) { ldap_dnfree(dn); } if (pbIsValid) { *pbIsValid = FALSE; } return dwError; }
/* Extract a name from policy_dn, which must be directly under the realm * container. */ krb5_error_code krb5_ldap_policydn_to_name(krb5_context context, const char *policy_dn, char **name_out) { size_t len1, len2, plen; krb5_error_code ret; kdb5_dal_handle *dal_handle; krb5_ldap_context *ldap_context; const char *realmdn; *name_out = NULL; SETUP_CONTEXT(); realmdn = ldap_context->lrparams->realmdn; if (realmdn == NULL) return EINVAL; /* policyn_dn should be "cn=<policyname>,<realmdn>". */ len1 = strlen(realmdn); len2 = strlen(policy_dn); if (len1 == 0 || len2 == 0 || len1 + 1 >= len2) return EINVAL; plen = len2 - len1 - 1; if (policy_dn[plen] != ',' || strcmp(realmdn, policy_dn + plen + 1) != 0) return EINVAL; #if defined HAVE_LDAP_STR2DN { char *rdn; LDAPDN dn; rdn = k5memdup0(policy_dn, plen, &ret); if (rdn == NULL) return ret; ret = ldap_str2dn(rdn, &dn, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PEDANTIC); free(rdn); if (ret) return EINVAL; if (dn[0] == NULL || dn[1] != NULL || dn[0][0]->la_attr.bv_len != 2 || strncasecmp(dn[0][0]->la_attr.bv_val, "cn", 2) != 0) { ret = EINVAL; } else { *name_out = k5memdup0(dn[0][0]->la_value.bv_val, dn[0][0]->la_value.bv_len, &ret); } ldap_dnfree(dn); return ret; } #elif defined HAVE_LDAP_EXPLODE_DN { char **parsed_dn; /* 1 = return DN components without type prefix */ parsed_dn = ldap_explode_dn(policy_dn, 1); if (parsed_dn == NULL) return EINVAL; *name_out = strdup(parsed_dn[0]); if (*name_out == NULL) return ENOMEM; ldap_value_free(parsed_dn); return 0; } #else return EINVAL; #endif }
int ldap_dn2domain( LDAP_CONST char *dn_in, char **domainp) { int i, j; char *ndomain; LDAPDN dn = NULL; LDAPRDN rdn = NULL; LDAPAVA *ava = NULL; struct berval domain = BER_BVNULL; static const struct berval DC = BER_BVC("DC"); static const struct berval DCOID = BER_BVC("0.9.2342.19200300.100.1.25"); assert( dn_in != NULL ); assert( domainp != NULL ); *domainp = NULL; if ( ldap_str2dn( dn_in, &dn, LDAP_DN_FORMAT_LDAP ) != LDAP_SUCCESS ) { return -2; } if( dn ) for( i=0; dn[i] != NULL; i++ ) { rdn = dn[i]; for( j=0; rdn[j] != NULL; j++ ) { ava = rdn[j]; if( rdn[j+1] == NULL && (ava->la_flags & LDAP_AVA_STRING) && ava->la_value.bv_len && ( ber_bvstrcasecmp( &ava->la_attr, &DC ) == 0 || ber_bvcmp( &ava->la_attr, &DCOID ) == 0 ) ) { if( domain.bv_len == 0 ) { ndomain = LDAP_REALLOC( domain.bv_val, ava->la_value.bv_len + 1); if( ndomain == NULL ) { goto return_error; } domain.bv_val = ndomain; AC_MEMCPY( domain.bv_val, ava->la_value.bv_val, ava->la_value.bv_len ); domain.bv_len = ava->la_value.bv_len; domain.bv_val[domain.bv_len] = '\0'; } else { ndomain = LDAP_REALLOC( domain.bv_val, ava->la_value.bv_len + sizeof(".") + domain.bv_len ); if( ndomain == NULL ) { goto return_error; } domain.bv_val = ndomain; domain.bv_val[domain.bv_len++] = '.'; AC_MEMCPY( &domain.bv_val[domain.bv_len], ava->la_value.bv_val, ava->la_value.bv_len ); domain.bv_len += ava->la_value.bv_len; domain.bv_val[domain.bv_len] = '\0'; } } else { domain.bv_len = 0; } } } if( domain.bv_len == 0 && domain.bv_val != NULL ) { LDAP_FREE( domain.bv_val ); domain.bv_val = NULL; } ldap_dnfree( dn ); *domainp = domain.bv_val; return 0; return_error: ldap_dnfree( dn ); LDAP_FREE( domain.bv_val ); return -1; }
int main( int argc, char *argv[] ) { int rc, i, debug = 0, f2 = 0; unsigned flags[ 2 ] = { 0U, 0 }; char *strin, *str = NULL, buf[ 1024 ]; LDAPDN dn, dn2 = NULL; while ( 1 ) { int opt = getopt( argc, argv, "d:" ); if ( opt == EOF ) { break; } switch ( opt ) { case 'd': debug = atoi( optarg ); break; } } optind--; argc -= optind; argv += optind; if ( argc < 2 ) { fprintf( stderr, "usage: dntest <dn> [flags-in[,...]] [flags-out[,...]]\n\n" ); fprintf( stderr, "\tflags-in: V3,V2,DCE,<flags>\n" ); fprintf( stderr, "\tflags-out: V3,V2,UFN,DCE,AD,<flags>\n\n" ); fprintf( stderr, "\t<flags>: PRETTY,PEDANTIC,NOSPACES,NOONESPACE\n\n" ); return( 0 ); } if ( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) { fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug ); } if ( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) { fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug ); } if ( strcmp( argv[ 1 ], "-" ) == 0 ) { size_t len = fgets( buf, sizeof( buf ), stdin ) ? strlen( buf ) : 0; if ( len == 0 || buf[ --len ] == '\n' ) { buf[ len ] = '\0'; } strin = buf; } else { strin = argv[ 1 ]; } if ( argc >= 3 ) { for ( i = 0; i < argc - 2; i++ ) { char *s, *e; for ( s = argv[ 2 + i ]; s; s = e ) { e = strchr( s, ',' ); if ( e != NULL ) { e[ 0 ] = '\0'; e++; } if ( !strcasecmp( s, "V3" ) ) { flags[ i ] |= LDAP_DN_FORMAT_LDAPV3; } else if ( !strcasecmp( s, "V2" ) ) { flags[ i ] |= LDAP_DN_FORMAT_LDAPV2; } else if ( !strcasecmp( s, "DCE" ) ) { flags[ i ] |= LDAP_DN_FORMAT_DCE; } else if ( !strcasecmp( s, "UFN" ) ) { flags[ i ] |= LDAP_DN_FORMAT_UFN; } else if ( !strcasecmp( s, "AD" ) ) { flags[ i ] |= LDAP_DN_FORMAT_AD_CANONICAL; } else if ( !strcasecmp( s, "PRETTY" ) ) { flags[ i ] |= LDAP_DN_PRETTY; } else if ( !strcasecmp( s, "PEDANTIC" ) ) { flags[ i ] |= LDAP_DN_PEDANTIC; } else if ( !strcasecmp( s, "NOSPACES" ) ) { flags[ i ] |= LDAP_DN_P_NOLEADTRAILSPACES; } else if ( !strcasecmp( s, "NOONESPACE" ) ) { flags[ i ] |= LDAP_DN_P_NOSPACEAFTERRDN; } } } } if ( flags[ 1 ] == 0 ) flags[ 1 ] = LDAP_DN_FORMAT_LDAPV3; f2 = 1; rc = ldap_str2dn( strin, &dn, flags[ 0 ] ); if ( rc == LDAP_SUCCESS ) { int i; if ( dn ) { for ( i = 0; dn[ i ]; i++ ) { LDAPRDN rdn = dn[ i ]; char *rstr = NULL; if ( ldap_rdn2str( rdn, &rstr, flags[ f2 ] ) ) { fprintf( stdout, "\tldap_rdn2str() failed\n" ); continue; } fprintf( stdout, "\tldap_rdn2str() = \"%s\"\n", rstr ); ldap_memfree( rstr ); } } else { fprintf( stdout, "\tempty DN\n" ); } } str = NULL; if ( rc == LDAP_SUCCESS && ldap_dn2str( dn, &str, flags[ f2 ] ) == LDAP_SUCCESS ) { char **values, *tmp, *tmp2, *str2 = NULL; int n; fprintf( stdout, "\nldap_dn2str(ldap_str2dn(\"%s\"))\n" "\t= \"%s\"\n", strin, str ); switch ( flags[ f2 ] & LDAP_DN_FORMAT_MASK ) { case LDAP_DN_FORMAT_UFN: case LDAP_DN_FORMAT_AD_CANONICAL: return( 0 ); case LDAP_DN_FORMAT_LDAPV3: case LDAP_DN_FORMAT_LDAPV2: n = ldap_dn2domain( strin, &tmp ); if ( n ) { fprintf( stdout, "\nldap_dn2domain(\"%s\") FAILED\n", strin ); } else { fprintf( stdout, "\nldap_dn2domain(\"%s\")\n" "\t= \"%s\"\n", strin, tmp ? tmp : "" ); } ldap_memfree( tmp ); tmp = ldap_dn2ufn( strin ); fprintf( stdout, "\nldap_dn2ufn(\"%s\")\n" "\t= \"%s\"\n", strin, tmp ? tmp : "" ); ldap_memfree( tmp ); tmp = ldap_dn2dcedn( strin ); fprintf( stdout, "\nldap_dn2dcedn(\"%s\")\n" "\t= \"%s\"\n", strin, tmp ? tmp : "" ); tmp2 = ldap_dcedn2dn( tmp ); fprintf( stdout, "\nldap_dcedn2dn(\"%s\")\n" "\t= \"%s\"\n", tmp ? tmp : "", tmp2 ? tmp2 : "" ); ldap_memfree( tmp ); ldap_memfree( tmp2 ); tmp = ldap_dn2ad_canonical( strin ); fprintf( stdout, "\nldap_dn2ad_canonical(\"%s\")\n" "\t= \"%s\"\n", strin, tmp ? tmp : "" ); ldap_memfree( tmp ); fprintf( stdout, "\nldap_explode_dn(\"%s\"):\n", str ); values = ldap_explode_dn( str, 0 ); for ( n = 0; values && values[ n ]; n++ ) { char **vv; int nn; fprintf( stdout, "\t\"%s\"\n", values[ n ] ); fprintf( stdout, "\tldap_explode_rdn(\"%s\")\n", values[ n ] ); vv = ldap_explode_rdn( values[ n ], 0 ); for ( nn = 0; vv && vv[ nn ]; nn++ ) { fprintf( stdout, "\t\t'%s'\n", vv[ nn ] ); } LDAP_VFREE( vv ); fprintf( stdout, "\tldap_explode_rdn(\"%s\")" " (no types)\n", values[ n ] ); vv = ldap_explode_rdn( values[ n ], 1 ); for ( nn = 0; vv && vv[ nn ]; nn++ ) { fprintf( stdout, "\t\t\t\"%s\"\n", vv[ nn ] ); } LDAP_VFREE( vv ); } LDAP_VFREE( values ); fprintf( stdout, "\nldap_explode_dn(\"%s\")" " (no types):\n", str ); values = ldap_explode_dn( str, 1 ); for ( n = 0; values && values[ n ]; n++ ) { fprintf( stdout, "\t\"%s\"\n", values[ n ] ); } LDAP_VFREE( values ); break; } dn2 = NULL; rc = ldap_str2dn( str, &dn2, flags[ f2 ] ); str2 = NULL; if ( rc == LDAP_SUCCESS && ldap_dn2str( dn2, &str2, flags[ f2 ] ) == LDAP_SUCCESS ) { int iRDN; fprintf( stdout, "\n\"%s\"\n\t == \"%s\" ? %s\n", str, str2, strcmp( str, str2 ) == 0 ? "yes" : "no" ); if( dn != NULL && dn2 == NULL ) { fprintf( stdout, "dn mismatch\n" ); } else if (( dn != NULL ) && (dn2 != NULL)) for ( iRDN = 0; dn[ iRDN ] && dn2[ iRDN ]; iRDN++ ) { LDAPRDN r = dn[ iRDN ]; LDAPRDN r2 = dn2[ iRDN ]; int iAVA; for ( iAVA = 0; r[ iAVA ] && r2[ iAVA ]; iAVA++ ) { LDAPAVA *a = r[ iAVA ]; LDAPAVA *a2 = r2[ iAVA ]; if ( a->la_attr.bv_len != a2->la_attr.bv_len ) { fprintf( stdout, "ava(%d), rdn(%d) attr len mismatch (%ld->%ld)\n", iAVA + 1, iRDN + 1, a->la_attr.bv_len, a2->la_attr.bv_len ); } else if ( memcmp( a->la_attr.bv_val, a2->la_attr.bv_val, a->la_attr.bv_len ) ) { fprintf( stdout, "ava(%d), rdn(%d) attr mismatch\n", iAVA + 1, iRDN + 1 ); } else if ( a->la_flags != a2->la_flags ) { fprintf( stdout, "ava(%d), rdn(%d) flag mismatch (%x->%x)\n", iAVA + 1, iRDN + 1, a->la_flags, a2->la_flags ); } else if ( a->la_value.bv_len != a2->la_value.bv_len ) { fprintf( stdout, "ava(%d), rdn(%d) value len mismatch (%ld->%ld)\n", iAVA + 1, iRDN + 1, a->la_value.bv_len, a2->la_value.bv_len ); } else if ( memcmp( a->la_value.bv_val, a2->la_value.bv_val, a->la_value.bv_len ) ) { fprintf( stdout, "ava(%d), rdn(%d) value mismatch\n", iAVA + 1, iRDN + 1 ); } } } ldap_dnfree( dn2 ); ldap_memfree( str2 ); } ldap_memfree( str ); } ldap_dnfree( dn ); /* note: dn is not freed */ return( 0 ); }
static PyObject* l_ldap_str2dn( PyObject* unused, PyObject *args ) { struct berval str; LDAPDN dn; int flags = 0; PyObject *result = NULL, *tmp; int res, i, j; Py_ssize_t str_len; /* * From a DN string such as "a=b,c=d;e=f", build * a list-equivalent of AVA structures; namely: * ((('a','b',1),('c','d',1)),(('e','f',1),)) * The integers are a bit combination of the AVA_* flags */ if (!PyArg_ParseTuple( args, "z#|i:str2dn", &str.bv_val, &str_len, &flags )) return NULL; str.bv_len = (ber_len_t) str_len; res = ldap_bv2dn(&str, &dn, flags); if (res != LDAP_SUCCESS) return LDAPerr(res); tmp = PyList_New(0); if (!tmp) goto failed; for (i = 0; dn[i]; i++) { LDAPRDN rdn; PyObject *rdnlist; rdn = dn[i]; rdnlist = PyList_New(0); if (!rdnlist) goto failed; if (PyList_Append(tmp, rdnlist) == -1) { Py_DECREF(rdnlist); goto failed; } for (j = 0; rdn[j]; j++) { LDAPAVA *ava = rdn[j]; PyObject *tuple; tuple = Py_BuildValue("(O&O&i)", LDAPberval_to_unicode_object, &ava->la_attr, LDAPberval_to_unicode_object, &ava->la_value, ava->la_flags & ~(LDAP_AVA_FREE_ATTR|LDAP_AVA_FREE_VALUE)); if (!tuple) { Py_DECREF(rdnlist); goto failed; } if (PyList_Append(rdnlist, tuple) == -1) { Py_DECREF(tuple); goto failed; } Py_DECREF(tuple); } Py_DECREF(rdnlist); } result = tmp; tmp = NULL; failed: Py_XDECREF(tmp); ldap_dnfree(dn); return result; }
/** * Convert LDAP DN to absolute DNS names. * * @param[in] dn LDAP DN with one or two idnsName components at the * beginning. * @param[out] target Absolute DNS name derived from the first two idnsNames. * @param[out] origin Absolute DNS name derived from the last idnsName * component of DN, i.e. zone. Can be NULL. * @param[out] iszone ISC_TRUE if DN points to zone object, ISC_FALSE otherwise. * * @code * Examples: * dn = "idnsName=foo.bar, idnsName=example.org., cn=dns, dc=example, dc=org" * target = "foo.bar.example.org." * origin = "example.org." * * dn = "idnsname=89, idnsname=4.34.10.in-addr.arpa, cn=dns, dc=example, dc=org" * target = "89.4.34.10.in-addr.arpa." * origin = "4.34.10.in-addr.arpa." * * dn = "idnsname=third.test., idnsname=test., cn=dns, dc=example, dc=org" * target = "third.test." * origin = "test." * @endcode */ isc_result_t dn_to_dnsname(isc_mem_t *mctx, const char *dn_str, dns_name_t *target, dns_name_t *otarget, isc_boolean_t *iszone) { LDAPDN dn = NULL; LDAPRDN rdn = NULL; LDAPAVA *attr = NULL; int idx; int ret; DECLARE_BUFFERED_NAME(name); DECLARE_BUFFERED_NAME(origin); isc_buffer_t name_buf; isc_buffer_t origin_buf; isc_result_t result; REQUIRE(dn_str != NULL); REQUIRE(target != NULL); INIT_BUFFERED_NAME(name); INIT_BUFFERED_NAME(origin); isc_buffer_initnull(&name_buf); isc_buffer_initnull(&origin_buf); /* Example DN: cn=a+sn=b, ou=people */ ret = ldap_str2dn(dn_str, &dn, LDAP_DN_FORMAT_LDAPV3); if (ret != LDAP_SUCCESS || dn == NULL) { log_bug("ldap_str2dn failed: %u", ret); CLEANUP_WITH(ISC_R_UNEXPECTED); } /* iterate over DN components: e.g. cn=a+sn=b */ for (idx = 0; dn[idx] != NULL; idx++) { rdn = dn[idx]; /* "iterate" over RDN components: e.g. cn=a */ INSIST(rdn[0] != NULL); /* RDN without (attr=value)?! */ if (rdn[1] != NULL) { log_bug("multi-valued RDNs are not supported"); CLEANUP_WITH(ISC_R_NOTIMPLEMENTED); } /* attribute in current RDN component */ attr = rdn[0]; if ((attr->la_flags & LDAP_AVA_STRING) == 0) { log_error("non-string attribute detected: position %u", idx); CLEANUP_WITH(ISC_R_NOTIMPLEMENTED); } if (strncasecmp("idnsName", attr->la_attr.bv_val, attr->la_attr.bv_len) == 0) { if (idx == 0) { isc_buffer_init(&name_buf, attr->la_value.bv_val, attr->la_value.bv_len); isc_buffer_add(&name_buf, attr->la_value.bv_len); } else if (idx == 1) { isc_buffer_init(&origin_buf, attr->la_value.bv_val, attr->la_value.bv_len); isc_buffer_add(&origin_buf, attr->la_value.bv_len); } else { /* more than two idnsNames?! */ break; } } else { /* no match - idx holds position */ break; } } /* filter out unsupported cases */ if (idx <= 0) { log_error("no idnsName component found in DN"); CLEANUP_WITH(ISC_R_UNEXPECTEDEND); } else if (idx == 1) { /* zone only */ if (iszone != NULL) *iszone = ISC_TRUE; CHECK(dns_name_copy(dns_rootname, &origin, NULL)); CHECK(dns_name_fromtext(&name, &name_buf, dns_rootname, 0, NULL)); } else if (idx == 2) { /* owner and zone */ if (iszone != NULL) *iszone = ISC_FALSE; CHECK(dns_name_fromtext(&origin, &origin_buf, dns_rootname, 0, NULL)); CHECK(dns_name_fromtext(&name, &name_buf, &origin, 0, NULL)); if (dns_name_issubdomain(&name, &origin) == ISC_FALSE) { log_error("out-of-zone data: first idnsName is not a " "subdomain of the other"); CLEANUP_WITH(DNS_R_BADOWNERNAME); } else if (dns_name_equal(&name, &origin) == ISC_TRUE) { log_error("attempt to redefine zone apex: first " "idnsName equals to zone name"); CLEANUP_WITH(DNS_R_BADOWNERNAME); } } else { log_error("unsupported number of idnsName components in DN: " "%u components found", idx); CLEANUP_WITH(ISC_R_NOTIMPLEMENTED); } cleanup: if (result == ISC_R_SUCCESS) result = dns_name_dupwithoffsets(&name, mctx, target); else log_error_r("failed to convert DN '%s' to DNS name", dn_str); if (result == ISC_R_SUCCESS && otarget != NULL) result = dns_name_dupwithoffsets(&origin, mctx, otarget); if (result != ISC_R_SUCCESS) { if (dns_name_dynamic(target)) dns_name_free(target, mctx); if (otarget) { if (dns_name_dynamic(otarget)) dns_name_free(otarget, mctx); } } if (dn != NULL) ldap_dnfree(dn); return result; }
/* * Combination of both dnPretty and dnNormalize */ int dnPrettyNormal( Syntax *syntax, struct berval *val, struct berval *pretty, struct berval *normal) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ENTRY, ">>> dnPrettyNormal: <%s>\n", val->bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, ">>> dnPrettyNormal: <%s>\n", val->bv_val, 0, 0 ); #endif assert( val ); assert( pretty ); assert( normal ); if ( val->bv_len == 0 ) { ber_dupbv( pretty, val ); ber_dupbv( normal, val ); } else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) { /* too big */ return LDAP_INVALID_SYNTAX; } else { LDAPDN *dn = NULL; int rc; pretty->bv_val = NULL; normal->bv_val = NULL; pretty->bv_len = 0; normal->bv_len = 0; /* FIXME: should be liberal in what we accept */ rc = ldap_bv2dn( val, &dn, LDAP_DN_FORMAT_LDAP ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } assert( strlen( val->bv_val ) == val->bv_len ); /* * Schema-aware rewrite */ if ( LDAPDN_rewrite( dn, SLAP_LDAPDN_PRETTY ) != LDAP_SUCCESS ) { ldap_dnfree( dn ); return LDAP_INVALID_SYNTAX; } rc = ldap_dn2bv( dn, pretty, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY ); if ( rc != LDAP_SUCCESS ) { ldap_dnfree( dn ); return LDAP_INVALID_SYNTAX; } if ( LDAPDN_rewrite( dn, 0 ) != LDAP_SUCCESS ) { ldap_dnfree( dn ); free( pretty->bv_val ); pretty->bv_val = NULL; pretty->bv_len = 0; return LDAP_INVALID_SYNTAX; } rc = ldap_dn2bv( dn, normal, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY ); ldap_dnfree( dn ); if ( rc != LDAP_SUCCESS ) { free( pretty->bv_val ); pretty->bv_val = NULL; pretty->bv_len = 0; return LDAP_INVALID_SYNTAX; } } #ifdef NEW_LOGGING LDAP_LOG (OPERATION, RESULTS, "<<< dnPrettyNormal: <%s>, <%s>\n", pretty->bv_val, normal->bv_val, 0 ); #else Debug( LDAP_DEBUG_TRACE, "<<< dnPrettyNormal: <%s>, <%s>\n", pretty->bv_val, normal->bv_val, 0 ); #endif return LDAP_SUCCESS; }
/** Convert a LDAP DN to a DNS domain name. * * Example: CN=Blarg,CN=Blorg,DC=AD,DC=LOCAL => AD.LOCAL. * * This is very much AD specific. It won't work for Lotus Domino DNs. */ int kdldap_DN_to_DNS(apr_pool_t *pool, const char *ldap_dn, char **dns_dom) { apr_pool_t *fn_pool; char *dom_str = NULL; #if LDAP_API_VERSION == 3001 LDAPDN dn; #elif LDAP_API_VERSION == 2004 LDAPDN *dn; #else #error Unknown LDAP API version #endif int i, err = -1; err = ldap_str2dn(ldap_dn, &dn, LDAP_DN_FORMAT_LDAPV3); if (err < 0) { kdldap_paranoid_push_error(NULL, err); KERROR_PUSH(_ldap_, 0, "unable to convert DN %s to DNS domain"); return -1; } if (dn) { apr_pool_create(&fn_pool, pool); for (i = 0; #if LDAP_API_VERSION == 2004 (*dn)[i] != NULL; #elif LDAP_API_VERSION == 3001 dn[i] != NULL; #endif i++) { char *attr, *val; #if LDAP_API_VERSION == 2004 LDAPAVA *v = **(*dn)[i]; #elif LDAP_API_VERSION == 3001 LDAPAVA *v = *dn[i]; #endif #if LDAP_API_VERSION == 3001 /* Security to make sure we don't append binary crap. */ if (!(v->la_flags & LDAP_AVA_STRING)) continue; #endif // LDAP_API_VERSION attr = apr_pstrmemdup(fn_pool, v->la_attr.bv_val, v->la_attr.bv_len); val = apr_pstrmemdup(fn_pool, v->la_value.bv_val, v->la_value.bv_len); if (strcasecmp(attr, "DC") == 0) { if (dom_str == NULL) dom_str = apr_pstrdup(fn_pool, val); else dom_str = apr_pstrcat(fn_pool, dom_str, ".", val, NULL); } } ldap_dnfree(dn); } if (dom_str != NULL) { *dns_dom = apr_pstrdup(pool, dom_str); err = 0; } else KERROR_PUSH(_ldap_, 0, "unable to convert system DN to DNS domain"); apr_pool_destroy(fn_pool); return err; }