Add a function for formatting network locations of the form host:port for use in URLs.

If the host part is a literal IPv6 address, it must be enclosed in square
brackets (RFC 2732).

ticket 1869
This commit is contained in:
Jan Cholasta 2011-09-30 10:09:55 +02:00 committed by Martin Kosek
parent 49de0c0575
commit 087251c88b
15 changed files with 59 additions and 40 deletions

View File

@ -111,7 +111,7 @@ class CSReplicationManager(replication.ReplicationManager):
dn = 'cn=%s,cn=mapping tree,cn=config' % esc1_suffix
# TODO: should we detect proto/port somehow ?
mod = [(ldap.MOD_DELETE, 'nsslapd-referral',
'ldap://%s:%s/%s' % (hostname, PORT, esc2_suffix))]
'ldap://%s/%s' % (ipautil.format_netloc(hostname, PORT), esc2_suffix))]
try:
self.conn.modify_s(dn, mod)
@ -226,7 +226,7 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
except errors.NotFound:
sys.exit("'%s' has no replication agreement for '%s'" % (replica1, replica2))
except ldap.SERVER_DOWN, e:
sys.exit("Unable to connect to %s:%d: %s" % (replica1, PORT, convert_error(e)))
sys.exit("Unable to connect to %s: %s" % (ipautil.format_netloc(replica1, PORT), convert_error(e)))
except Exception, e:
sys.exit("Failed to get data from '%s': %s" % (replica1, convert_error(e)))
@ -322,7 +322,7 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
except ldap.NO_SUCH_OBJECT:
sys.exit('%s does not have a CA configured.' % replica2)
except ldap.SERVER_DOWN, e:
sys.exit("Unable to connect to %s:636: %s" % (replica2, convert_error(e)))
sys.exit("Unable to connect to %s: %s" % (ipautil.format_netloc(replica2, 636), convert_error(e)))
except Exception, e:
sys.exit("Failed to get data from '%s': %s" % (replica1, convert_error(e)))
@ -337,7 +337,7 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
except ldap.NO_SUCH_OBJECT:
sys.exit("Cannot find replica '%s'" % replica1)
except ldap.SERVER_DOWN, e:
sys.exit("Unable to connect to %s:%d %s" % (replica1, PORT, convert_error(e)))
sys.exit("Unable to connect to %s %s" % (ipautil.format_netloc(replica1, PORT), convert_error(e)))
except Exception, e:
sys.exit("Failed to get data from '%s': %s" % (replica1, convert_error(e)))

View File

@ -201,8 +201,8 @@ def configure_krb5_conf(realm, kdc, filename):
#the following are necessary only if DNS discovery does not work
#[realms]
realms_info =[{'name':'kdc', 'type':'option', 'value':kdc+':88'},
{'name':'admin_server', 'type':'option', 'value':kdc+':749'}]
realms_info =[{'name':'kdc', 'type':'option', 'value':ipautil.format_netloc(kdc, 88)},
{'name':'admin_server', 'type':'option', 'value':ipautil.format_netloc(kdc, 749)}]
realms = [{'name':realm, 'type':'subsection', 'value':realms_info}]
opts.append({'name':'realms', 'type':'section', 'value':realms})

View File

@ -230,7 +230,7 @@ def install_dns_records(config, options):
# before our DS server is installed.
cur_uri = api.Backend.ldap2.ldap_uri
object.__setattr__(api.Backend.ldap2, 'ldap_uri',
'ldaps://%s' % config.master_host_name)
'ldaps://%s' % ipautil.format_netloc(config.master_host_name))
api.Backend.ldap2.connect(bind_dn="cn=Directory Manager",
bind_pw=config.dirman_password,
tls_cacertfile=CACERT)
@ -358,7 +358,7 @@ def main():
fd.write("basedn=" + util.realm_to_suffix(config.realm_name) + "\n")
fd.write("realm=" + config.realm_name + "\n")
fd.write("domain=" + config.domain_name + "\n")
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % config.host_name)
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % ipautil.format_netloc(config.host_name))
fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % dsinstance.realm_to_serverid(config.realm_name))
if ipautil.file_exists(config.dir + "/cacert.p12"):
fd.write("enable_ra=True\n")
@ -395,7 +395,7 @@ def main():
install_ca_cert(config)
# Try out the password
ldapuri = 'ldaps://%s' % config.master_host_name
ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name)
try:
conn = ldap2(shared_instance=False, ldap_uri=ldapuri, base_dn='')
conn.connect(bind_dn='cn=directory manager',

View File

@ -830,7 +830,7 @@ def main():
fd.write("basedn=" + util.realm_to_suffix(realm_name) + "\n")
fd.write("realm=" + realm_name + "\n")
fd.write("domain=" + domain_name + "\n")
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % host_name)
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name))
fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % dsinstance.realm_to_serverid(realm_name))
fd.write("enable_ra=True\n")
if not options.selfsign:

View File

@ -352,7 +352,7 @@ def configure_ipa_conf(fstore, cli_basedn, cli_realm, cli_domain, cli_server):
{'name':'realm', 'type':'option', 'value':cli_realm},
{'name':'domain', 'type':'option', 'value':cli_domain},
{'name':'server', 'type':'option', 'value':cli_server},
{'name':'xmlrpc_uri', 'type':'option', 'value':'https://%s/ipa/xml' % cli_server},
{'name':'xmlrpc_uri', 'type':'option', 'value':'https://%s/ipa/xml' % ipautil.format_netloc(cli_server)},
{'name':'enable_ra', 'type':'option', 'value':'True'}]
opts.append({'name':'global', 'type':'section', 'value':defopts})
@ -389,7 +389,7 @@ def configure_ldap_conf(fstore, cli_basedn, cli_realm, cli_domain, cli_server, d
if options.on_master:
opts.append({'name':'uri', 'type':'option', 'value':'ldap://localhost'})
else:
opts.append({'name':'uri', 'type':'option', 'value':'ldap://'+cli_server})
opts.append({'name':'uri', 'type':'option', 'value':'ldap://'+ipautil.format_netloc(cli_server)})
else:
opts.append({'name':'nss_srv_domain', 'type':'option', 'value':cli_domain})
@ -428,7 +428,7 @@ def configure_nslcd_conf(fstore, cli_basedn, cli_realm, cli_domain, cli_server,
if options.on_master:
opts.append({'name':'uri', 'type':'option', 'value':'ldap://localhost'})
else:
opts.append({'name':'uri', 'type':'option', 'value':'ldap://'+cli_server})
opts.append({'name':'uri', 'type':'option', 'value':'ldap://'+ipautil.format_netloc(cli_server)})
else:
opts.append({'name':'uri', 'type':'option', 'value':'DNS'})
@ -471,7 +471,7 @@ def hardcode_ldap_server(cli_server):
ldapconf = ipaclient.ipachangeconf.IPAChangeConf("IPA Installer")
ldapconf.setOptionAssignment(" ")
opts = [{'name':'uri', 'type':'option', 'action':'set', 'value':'ldap://'+cli_server},
opts = [{'name':'uri', 'type':'option', 'action':'set', 'value':'ldap://'+ipautil.format_netloc(cli_server)},
{'name':'empty', 'type':'empty'}]
# Errors raised by this should be caught by the caller
@ -509,8 +509,8 @@ def configure_krb5_conf(fstore, cli_basedn, cli_realm, cli_domain, cli_server, c
#the following are necessary only if DNS discovery does not work
if not dnsok or not cli_kdc or options.force:
#[realms]
kropts =[{'name':'kdc', 'type':'option', 'value':cli_server+':88'},
{'name':'admin_server', 'type':'option', 'value':cli_server+':749'},
kropts =[{'name':'kdc', 'type':'option', 'value':ipautil.format_netloc(cli_server, 88)},
{'name':'admin_server', 'type':'option', 'value':ipautil.format_netloc(cli_server, 749)},
{'name':'default_domain', 'type':'option', 'value':cli_domain}]
else:
kropts = []
@ -887,7 +887,7 @@ def install(options, env, fstore, statestore):
pass
try:
run(["/usr/bin/wget", "-O", "/etc/ipa/ca.crt", "http://%s/ipa/config/ca.crt" % cli_server])
run(["/usr/bin/wget", "-O", "/etc/ipa/ca.crt", "http://%s/ipa/config/ca.crt" % ipautil.format_netloc(cli_server)])
except CalledProcessError, e:
print 'Retrieving CA from %s failed.\n%s' % (cli_server, str(e))
return CLIENT_INSTALL_ERROR

View File

@ -25,7 +25,7 @@ import tempfile
import ldap
from ldap import LDAPError
from ipapython.ipautil import run, CalledProcessError, valid_ip, get_ipa_basedn, \
realm_to_suffix
realm_to_suffix, format_netloc
NOT_FQDN = -1
@ -220,15 +220,15 @@ class IPADiscovery:
raise RuntimeError("Creating temporary directory failed: %s" % str(e))
try:
run(["/usr/bin/wget", "-O", "%s/ca.crt" % temp_ca_dir, "http://%s/ipa/config/ca.crt" % thost])
run(["/usr/bin/wget", "-O", "%s/ca.crt" % temp_ca_dir, "http://%s/ipa/config/ca.crt" % format_netloc(thost)])
except CalledProcessError, e:
logging.debug('Retrieving CA from %s failed.\n%s' % (thost, str(e)))
return [NOT_IPA_SERVER]
#now verify the server is really an IPA server
try:
logging.debug("Init ldap with: ldap://"+thost+":389")
lh = ldap.initialize("ldap://"+thost+":389")
logging.debug("Init ldap with: ldap://"+format_netloc(thost, 389))
lh = ldap.initialize("ldap://"+format_netloc(thost, 389))
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, True)
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, "%s/ca.crt" % temp_ca_dir)
lh.set_option(ldap.OPT_PROTOCOL_VERSION, 3)

View File

@ -306,7 +306,7 @@ class xmlclient(Connectible):
scheme = "https"
else:
scheme = "http"
server = '%s://%s%s' % (scheme, self.conn._ServerProxy__host, self.conn._ServerProxy__handler)
server = '%s://%s%s' % (scheme, ipautil.format_netloc(self.conn._ServerProxy__host), self.conn._ServerProxy__handler)
return server
def get_url_list(self):
@ -321,7 +321,7 @@ class xmlclient(Connectible):
for r in rs:
if r.dns_type == dnsclient.DNS_T_SRV:
rsrv = r.rdata.server.rstrip('.')
servers.append('https://%s%s' % (rsrv, path))
servers.append('https://%s%s' % (ipautil.format_netloc(rsrv), path))
servers = list(set(servers))
# the list/set conversion won't preserve order so stick in the
# local config file version here.

View File

@ -20,7 +20,7 @@
from ipalib import api, errors
import httplib
import xml.dom.minidom
from ipapython import nsslib
from ipapython import nsslib, ipautil
import nss.nss as nss
from nss.error import NSPRError
from ipalib.errors import NetworkError, CertificateOperationError
@ -72,7 +72,7 @@ def https_request(host, port, url, secdir, password, nickname, **kw):
"""
if isinstance(host, unicode):
host = host.encode('utf-8')
uri = 'https://%s:%d%s' % (host, port, url)
uri = 'https://%s%s' % (ipautil.format_netloc(host, port), url)
post = urlencode(kw)
logging.info('sslget %r', uri)
logging.debug('sslget post %r', post)
@ -110,7 +110,7 @@ def http_request(host, port, url, **kw):
"""
if isinstance(host, unicode):
host = host.encode('utf-8')
uri = 'http://%s:%s%s' % (host, port, url)
uri = 'http://%s%s' % (ipautil.format_netloc(host, port), url)
post = urlencode(kw)
logging.info('request %r', uri)
logging.debug('request post %r', post)

View File

@ -151,6 +151,24 @@ class CheckedIPAddress(netaddr.IPAddress):
def valid_ip(addr):
return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
def format_netloc(host, port=None):
"""
Format network location (host:port).
If the host part is a literal IPv6 address, it must be enclosed in square
brackets (RFC 2732).
"""
host = str(host)
try:
socket.inet_pton(socket.AF_INET6, host)
host = '[%s]' % host
except socket.error:
pass
if port is None:
return host
else:
return '%s:%s' % (host, str(port))
def realm_to_suffix(realm_name):
s = realm_name.split(".")
terms = ["dc=" + x.lower() for x in s]

View File

@ -96,7 +96,7 @@ def dns_container_exists(fqdn, suffix):
return True
try:
server = ldap.initialize("ldap://" + fqdn)
server = ldap.initialize("ldap://" + ipautil.format_netloc(fqdn))
server.simple_bind_s()
except ldap.SERVER_DOWN:
raise RuntimeError('LDAP server on %s is not responding. Is IPA installed?' % fqdn)

View File

@ -663,7 +663,7 @@ class CAInstance(service.Service):
args.append("-clone_start_tls")
args.append("true")
args.append("-clone_uri")
args.append("https://%s:%d" % (self.master_host, 443))
args.append("https://%s" % ipautil.format_netloc(self.master_host, 443))
else:
args.append("-clone")
args.append("false")
@ -747,7 +747,7 @@ class CAInstance(service.Service):
'-p', self.admin_password,
'-d', self.ca_agent_db,
'-r', '/ca/agent/ca/profileReview?requestId=%s' % self.requestId,
'%s:%d' % (self.fqdn, AGENT_SECURE_PORT),
'%s' % ipautil.format_netloc(self.fqdn, AGENT_SECURE_PORT),
]
(stdout, stderr, returncode) = ipautil.run(args, nolog=(self.admin_password,))
@ -767,7 +767,7 @@ class CAInstance(service.Service):
'-d', self.ca_agent_db,
'-e', params,
'-r', '/ca/agent/ca/profileProcess',
'%s:%d' % (self.fqdn, AGENT_SECURE_PORT),
'%s' % ipautil.format_netloc(self.fqdn, AGENT_SECURE_PORT),
]
(stdout, stderr, returncode) = ipautil.run(args, nolog=(self.admin_password,))
@ -810,7 +810,7 @@ class CAInstance(service.Service):
# Create an RA user in the CA LDAP server and add that user to
# the appropriate groups so it can issue certificates without
# manual intervention.
ld = ldap.initialize("ldap://%s:%d" % (self.fqdn, self.ds_port))
ld = ldap.initialize("ldap://%s" % ipautil.format_netloc(self.fqdn, self.ds_port))
ld.protocol_version=ldap.VERSION3
ld.simple_bind_s("cn=Directory Manager", self.dm_password)
@ -1035,7 +1035,7 @@ class CAInstance(service.Service):
installutils.set_directive(caconfig, 'ca.publish.rule.instance.LdapXCertRule.enable', 'false', quotes=False, separator='=')
# Fix the CRL URI in the profile
installutils.set_directive('/var/lib/%s/profiles/ca/caIPAserviceCert.cfg' % PKI_INSTANCE_NAME, 'policyset.serverCertSet.9.default.params.crlDistPointsPointName_0', 'https://%s/ipa/crl/MasterCRL.bin' % self.fqdn, quotes=False, separator='=')
installutils.set_directive('/var/lib/%s/profiles/ca/caIPAserviceCert.cfg' % PKI_INSTANCE_NAME, 'policyset.serverCertSet.9.default.params.crlDistPointsPointName_0', 'https://%s/ipa/crl/MasterCRL.bin' % ipautil.format_netloc(self.fqdn), quotes=False, separator='=')
ipaservices.restore_context(publishdir)

View File

@ -112,7 +112,7 @@ def is_ds_running():
def has_managed_entries(host_name, dm_password):
"""Check to see if the Managed Entries plugin is available"""
ldapuri = 'ldap://%s' % host_name
ldapuri = 'ldap://%s' % ipautil.format_netloc(host_name)
conn = None
try:
conn = ldap2(shared_instance=False, ldap_uri=ldapuri, base_dn='cn=config')

View File

@ -319,7 +319,7 @@ class ReplicationManager(object):
return cn
def to_ldap_url(self, conn):
return "ldap://%s:%d/" % (conn.host, conn.port)
return "ldap://%s/" % ipautil.format_netloc(conn.host, conn.port)
def setup_chaining_farm(self, conn):
try:
@ -544,7 +544,7 @@ class ReplicationManager(object):
dn = 'cn=%s,cn=mapping tree,cn=config' % esc1_suffix
# TODO: should we detect proto/port somehow ?
mod = [(ldap.MOD_DELETE, 'nsslapd-referral',
'ldap://%s:389/%s' % (hostname, esc2_suffix))]
'ldap://%s/%s' % (ipautil.format_netloc(hostname, 389), esc2_suffix))]
try:
self.conn.modify_s(dn, mod)
@ -700,7 +700,7 @@ class ReplicationManager(object):
self.ad_suffix = ""
try:
# Validate AD connection
ad_conn = ldap.initialize('ldap://%s' % ad_dc_name)
ad_conn = ldap.initialize('ldap://%s' % ipautil.format_netloc(ad_dc_name))
#the next one is to workaround bugs arounf opendalp libs+NSS db
ad_conn.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
ad_conn.set_option(ldap.OPT_X_TLS_CACERTFILE, cacert)

View File

@ -34,6 +34,7 @@ from ldap.controls import LDAPControl,DecodeControlTuples,EncodeControlTuples
from ldap.ldapobject import SimpleLDAPObject
from ipaserver import ipautil
from ipalib import errors
from ipapython.ipautil import format_netloc
# Global variable to define SASL auth
SASL_AUTH = ldap.sasl.sasl({},'GSSAPI')
@ -215,12 +216,12 @@ class IPAdmin(SimpleLDAPObject):
its own encryption.
"""
if self.cacert is not None:
SimpleLDAPObject.__init__(self,'ldaps://%s:%d' % (self.host,self.port))
SimpleLDAPObject.__init__(self,'ldaps://%s' % format_netloc(self.host, self.port))
else:
if self.ldapi:
SimpleLDAPObject.__init__(self,'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % "-".join(self.realm.split(".")))
else:
SimpleLDAPObject.__init__(self,'ldap://%s:%d' % (self.host,self.port))
SimpleLDAPObject.__init__(self,'ldap://%s' % format_netloc(self.host, self.port))
def __init__(self,host='',port=389,cacert=None,bindcert=None,bindkey=None,proxydn=None,debug=None,ldapi=False,realm=None):
"""We just set our instance variables and wrap the methods - the real
@ -330,7 +331,7 @@ class IPAdmin(SimpleLDAPObject):
raise errors.DatabaseError(desc=desc,info=info)
def toLDAPURL(self):
return "ldap://%s:%d/" % (self.host,self.port)
return "ldap://%s/" % format_netloc(self.host, self.port)
def set_proxydn(self, proxydn):
self.proxydn = proxydn

View File

@ -42,7 +42,7 @@ class test_ldap(object):
def setUp(self):
self.conn = None
self.ldapuri = 'ldap://%s' % api.env.host
self.ldapuri = 'ldap://%s' % ipautil.format_netloc(api.env.host)
self.ccache = '/tmp/krb5cc_%d' % os.getuid()
nss.nss_init_nodb()
self.dn = str(DN(('krbprincipalname','ldap/%s@%s' % (api.env.host, api.env.realm)),