1/* $NetBSD: referral.c,v 1.3 2021/08/14 16:14:59 christos Exp $ */ 2 3/* referral.c - DNS SRV backend referral handler */ 4/* $OpenLDAP$ */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 2000-2021 The OpenLDAP Foundation. 8 * Portions Copyright 2000-2003 Kurt D. Zeilenga. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted only as authorized by the OpenLDAP 13 * Public License. 14 * 15 * A copy of this license is available in the file LICENSE in the 16 * top-level directory of the distribution or, alternatively, at 17 * <http://www.OpenLDAP.org/license.html>. 18 */ 19/* ACKNOWLEDGEMENTS: 20 * This work was originally developed by Kurt D. Zeilenga for inclusion 21 * in OpenLDAP Software. 22 */ 23 24#include <sys/cdefs.h> 25__RCSID("$NetBSD: referral.c,v 1.3 2021/08/14 16:14:59 christos Exp $"); 26 27#include "portable.h" 28 29#include <stdio.h> 30 31#include <ac/string.h> 32#include <ac/socket.h> 33 34#include "slap.h" 35#include "proto-dnssrv.h" 36 37int 38dnssrv_back_referrals( 39 Operation *op, 40 SlapReply *rs ) 41{ 42 int i; 43 int rc = LDAP_OTHER; 44 char *domain = NULL; 45 char *hostlist = NULL; 46 char **hosts = NULL; 47 BerVarray urls = NULL; 48 49 if ( BER_BVISEMPTY( &op->o_req_dn ) ) { 50 /* FIXME: need some means to determine whether the database 51 * is a glue instance */ 52 if ( SLAP_GLUE_INSTANCE( op->o_bd ) ) { 53 return LDAP_SUCCESS; 54 } 55 56 rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed"; 57 return LDAP_UNWILLING_TO_PERFORM; 58 } 59 60 if( get_manageDSAit( op ) ) { 61 if( op->o_tag == LDAP_REQ_SEARCH ) { 62 return LDAP_SUCCESS; 63 } 64 65 rs->sr_text = "DNS SRV problem processing manageDSAit control"; 66 return LDAP_OTHER; 67 } 68 69 if( ldap_dn2domain( op->o_req_dn.bv_val, &domain ) || domain == NULL ) { 70 rs->sr_err = LDAP_REFERRAL; 71 rs->sr_ref = default_referral; 72 send_ldap_result( op, rs ); 73 rs->sr_ref = NULL; 74 return LDAP_REFERRAL; 75 } 76 77 Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n", 78 op->o_req_dn.bv_val, domain ); 79 80 i = ldap_domain2hostlist( domain, &hostlist ); 81 if ( i ) { 82 Debug( LDAP_DEBUG_TRACE, 83 "DNSSRV: domain2hostlist(%s) returned %d\n", 84 domain, i ); 85 rs->sr_text = "no DNS SRV RR available for DN"; 86 rc = LDAP_NO_SUCH_OBJECT; 87 goto done; 88 } 89 90 hosts = ldap_str2charray( hostlist, " " ); 91 92 if( hosts == NULL ) { 93 Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charray error\n" ); 94 rs->sr_text = "problem processing DNS SRV records for DN"; 95 goto done; 96 } 97 98 for( i=0; hosts[i] != NULL; i++) { 99 struct berval url; 100 101 url.bv_len = STRLENOF( "ldap://" ) + strlen( hosts[i] ); 102 url.bv_val = ch_malloc( url.bv_len + 1 ); 103 104 strcpy( url.bv_val, "ldap://" ); 105 strcpy( &url.bv_val[STRLENOF( "ldap://" )], hosts[i] ); 106 107 if ( ber_bvarray_add( &urls, &url ) < 0 ) { 108 free( url.bv_val ); 109 rs->sr_text = "problem processing DNS SRV records for DN"; 110 goto done; 111 } 112 } 113 114 Debug( LDAP_DEBUG_STATS, 115 "%s DNSSRV p=%d dn=\"%s\" url=\"%s\"\n", 116 op->o_log_prefix, op->o_protocol, 117 op->o_req_dn.bv_val, urls[0].bv_val ); 118 119 Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> url=\"%s\"\n", 120 op->o_req_dn.bv_val, urls[0].bv_val ); 121 122 rs->sr_ref = urls; 123 send_ldap_error( op, rs, LDAP_REFERRAL, 124 "DNS SRV generated referrals" ); 125 rs->sr_ref = NULL; 126 rc = LDAP_REFERRAL; 127 128done: 129 if( domain != NULL ) ch_free( domain ); 130 if( hostlist != NULL ) ch_free( hostlist ); 131 if( hosts != NULL ) ldap_charray_free( hosts ); 132 ber_bvarray_free( urls ); 133 return rc; 134} 135