**kadmind_listen**
(Whitespace- or comma-separated list.) Specifies the kadmin RPC
listening addresses and/or ports for the :ref:`kadmind(8)` daemon.
- Each entry may be an interface address, a port number, or an
- address and port number separated by a colon. If the address
- contains colons, enclose it in square brackets. If no address is
- specified, the wildcard address is used. To disable listening for
- kadmin RPC connections, set this relation to the empty string with
- ``kadmind_listen = ""``. If kadmind fails to bind to any of the
- specified addresses, it will fail to start. The default is to
- bind to the wildcard address at the port specified in
- **kadmind_port**, or the standard kadmin port (749). New in
- release 1.15.
+ Each entry may be an interface address, a port number, an address
+ and port number separated by a colon, or a UNIX domain socket
+ pathname. If the address contains colons, enclose it in square
+ brackets. If no address is specified, the wildcard address is
+ used. To disable listening for kadmin RPC connections, set this
+ relation to the empty string with ``kadmind_listen = ""``. If
+ kadmind fails to bind to any of the specified addresses, it will
+ fail to start. The default is to bind to the wildcard address at
+ the port specified in **kadmind_port**, or the standard kadmin
+ port (749). New in release 1.15.
**kadmind_port**
(Port number.) Specifies the port on which the :ref:`kadmind(8)`
**kdc_listen**
(Whitespace- or comma-separated list.) Specifies the UDP
listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon.
- Each entry may be an interface address, a port number, or an
- address and port number separated by a colon. If the address
- contains colons, enclose it in square brackets. If no address is
- specified, the wildcard address is used. If no port is specified,
- the standard port (88) is used. To disable listening on UDP, set
- this relation to the empty string with ``kdc_listen = ""``.
- If the KDC daemon fails to bind to any of the specified addresses,
- it will fail to start. The default is to bind to the wildcard
- address on the standard port. New in release 1.15.
+ Each entry may be an interface address, a port number, an address
+ and port number separated by a colon, or a UNIX domain socket
+ pathname. If the address contains colons, enclose it in square
+ brackets. If no address is specified, the wildcard address is
+ used. If no port is specified, the standard port (88) is used.
+ To disable listening on UDP, set this relation to the empty string
+ with ``kdc_listen = ""``. If the KDC daemon fails to bind to any
+ of the specified addresses, it will fail to start. The default is
+ to bind to the wildcard address on the standard port. New in
+ release 1.15.
**kdc_ports**
(Whitespace- or comma-separated list, deprecated.) Prior to
**kdc_tcp_listen** if that relation is not defined.
**kpasswd_listen**
- (Comma-separated list.) Specifies the kpasswd listening addresses
- and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be
- an interface address, a port number, or an address and port number
- separated by a colon. If the address contains colons, enclose it
- in square brackets. If no address is specified, the wildcard
- address is used. To disable listening for kpasswd requests, set
- this relation to the empty string with ``kpasswd_listen = ""``.
- If kadmind fails to bind to any of the specified addresses, it
- will fail to start. The default is to bind to the wildcard
- address at the port specified in **kpasswd_port**, or the standard
- kpasswd port (464). New in release 1.15.
+ (Comma-separated list.) Specifies the kpasswd listening
+ addresses and/or ports for the :ref:`kadmind(8)` daemon. Each
+ entry may be an interface address, a port number, an address and
+ port number separated by a colon, or a UNIX domain socket
+ pathname. If the address contains colons, enclose it in square
+ brackets. If no address is specified, the wildcard address is
+ used. To disable listening for kpasswd requests, set this
+ relation to the empty string with ``kpasswd_listen = ""``. If
+ kadmind fails to bind to any of the specified addresses, it will
+ fail to start. The default is to bind to the wildcard address at
+ the port specified in **kpasswd_port**, or the standard kpasswd
+ port (464). New in release 1.15.
**kpasswd_port**
(Port number.) Specifies the port on which the :ref:`kadmind(8)`
been set to ``FILE:/tmp/my_proxy.pem``.
**kdc**
- The name or address of a host running a KDC for that realm. An
- optional port number, separated from the hostname by a colon, may
- be included. If the name or address contains colons (for example,
- if it is an IPv6 address), enclose it in square brackets to
+ The name or address of a host running a KDC for the realm, or a
+ UNIX domain socket path of a locally running KDC. An optional
+ port number, separated from the hostname by a colon, may be
+ included. If the name or address contains colons (for example, if
+ it is an IPv6 address), enclose it in square brackets to
distinguish the colon from a port separator. For your computer to
be able to communicate with the KDC for each realm, this tag must
be given a value in each realm subsection in the configuration
file, or there must be DNS SRV records specifying the KDCs.
**kpasswd_server**
- Points to the server where all the password changes are performed.
- If there is no such entry, DNS will be queried (unless forbidden
- by **dns_lookup_kdc**). Finally, port 464 on the **admin_server**
- host will be tried.
+ The location of the password change server for the realm, using
+ the same syntax as **kdc**. If there is no such entry, DNS will
+ be queried (unless forbidden by **dns_lookup_kdc**). Finally,
+ port 464 on the **admin_server** host will be tried.
**master_kdc**
The name for **primary_kdc** prior to release 1.19. Its value is
#define KRB5_CONF_KDC_TCP_LISTEN "kdc_tcp_listen"
#define KRB5_CONF_KDC_TCP_LISTEN_BACKLOG "kdc_tcp_listen_backlog"
#define KRB5_CONF_KDC_TIMESYNC "kdc_timesync"
+#define KRB5_CONF_KDC_UNIXSOCK_LISTEN "kdc_unixsock_listen"
#define KRB5_CONF_KEY_STASH_FILE "key_stash_file"
#define KRB5_CONF_KPASSWD_LISTEN "kpasswd_listen"
#define KRB5_CONF_KPASSWD_PORT "kpasswd_port"
KADM, KADMVERS, kadm_1);
if (ret)
return ret;
+ ret = loop_add_unix_socket(params->kpasswd_listen);
+ if (ret)
+ return ret;
}
#ifndef DISABLE_IPROP
if (params->iprop_enabled) {
for (i = 0; i < shandle.kdc_numrealms; i++) {
realm = shandle.kdc_realmlist[i];
retval = loop_add_udp_address(KRB5_DEFAULT_PORT, realm->realm_listen);
+ if (retval)
+ goto net_init_error;
+ retval = loop_add_unix_socket(realm->realm_listen);
if (retval)
goto net_init_error;
retval = loop_add_tcp_address(KRB5_DEFAULT_PORT,
hostspec = hostlist[i];
Tprintf("entry %d is '%s'\n", i, hostspec);
+#ifndef _WIN32
+ if (hostspec[0] == '/') {
+ struct sockaddr_un sun = { 0 };
+
+ sun.sun_family = AF_UNIX;
+ if (strlcpy(sun.sun_path, hostspec, sizeof(sun.sun_path)) >=
+ sizeof(sun.sun_path)) {
+ code = ENAMETOOLONG;
+ goto cleanup;
+ }
+ code = add_addr_to_list(serverlist, UNIXSOCK, AF_UNIX, sizeof(sun),
+ (struct sockaddr *)&sun);
+ if (code)
+ goto cleanup;
+ continue;
+ }
+#endif
parse_uri_if_https(hostspec, &this_transport, &hostspec, &uri_path);
default_port = (this_transport == HTTPS) ? 443 : udpport;
TCP,
UDP,
HTTPS,
+ UNIXSOCK,
} k5_transport;
typedef enum {
return SOCK_DGRAM;
case TCP:
case HTTPS:
+ case UNIXSOCK:
return SOCK_STREAM;
default:
return 0;
if (message == NULL || message->length == 0)
return 0;
- if (state->addr.transport == TCP) {
+ if (state->addr.transport == TCP || state->addr.transport == UNIXSOCK) {
store_32_be(message->length, out->msg_len_buf);
SG_SET(&out->sgbuf[0], out->msg_len_buf, 4);
SG_SET(&out->sgbuf[1], message->data, message->length);
state->fd = INVALID_SOCKET;
state->server_index = server_index;
SG_SET(&state->out.sgbuf[1], NULL, 0);
- if (transport == TCP) {
+ if (transport == TCP || transport == UNIXSOCK) {
state->service_connect = service_tcp_connect;
state->service_write = service_tcp_write;
state->service_read = service_tcp_read;
return 0;
transport = (strategy == UDP_FIRST || strategy == ONLY_UDP) ? UDP : TCP;
- if (entry->hostname == NULL) {
- /* Added by a module, so transport is either TCP or UDP. */
- ai.ai_socktype = socktype_for_transport(entry->transport);
- ai.ai_family = entry->family;
- ai.ai_addrlen = entry->addrlen;
- ai.ai_addr = (struct sockaddr *)&entry->addr;
- defer = (entry->transport != transport);
- return add_connection(conns, entry->transport, defer, &ai, ind, realm,
- NULL, NULL, entry->uri_path, udpbufp);
- }
/* If the entry has a specified transport, use it, but possibly defer the
* addresses we add based on the strategy. */
(entry->transport == UDP && strategy == UDP_LAST);
}
+ if (entry->hostname == NULL) {
+ /* The entry contains an address; skip name resolution. */
+ ai.ai_socktype = socktype_for_transport(entry->transport);
+ ai.ai_family = entry->family;
+ ai.ai_addrlen = entry->addrlen;
+ ai.ai_addr = ss2sa(&entry->addr);
+ return add_connection(conns, entry->transport, defer, &ai, ind, realm,
+ NULL, NULL, entry->uri_path, udpbufp);
+ }
+
memset(&hint, 0, sizeof(hint));
hint.ai_family = entry->family;
hint.ai_socktype = socktype_for_transport(transport);
k5_buf_add(&buf, "stream");
else if (ra->transport == HTTPS)
k5_buf_add(&buf, "https");
+ else if (ra->transport == UNIXSOCK)
+ k5_buf_add(&buf, "UNIX domain socket");
else
k5_buf_add_fmt(&buf, "transport%d", ra->transport);
from k5test import *
-realm = K5Realm(create_host=False, get_creds=False, start_kadmind=True)
+# Also listen on a UNIX domain sockets for kpasswd.
+unix_conf = {'realms': {'$realm': {
+ 'kdc_listen': '$port0, $testdir/krb5.sock',
+ 'kadmind_listen': '$port1, $testdir/kadmin.sock',
+ 'kpasswd_listen': '$port2, $testdir/kpasswd.sock'}}}
+realm = K5Realm(create_host=False,get_creds=False, kdc_conf=unix_conf)
+realm.start_kadmind()
realm.prep_kadmin()
# Mark a principal as expired and change its password through kinit.
realm.run([kdestroy])
realm.run([kadminl, 'delprinc', 'testprinc'])
+mark('password change over UNIX domain socket')
+
+unix_cli_conf = {'realms': {'$realm': {
+ 'kdc': '$testdir/krb5.sock',
+ 'admin_server': '$testdir/kadmin.sock',
+ 'kpasswd_server': '$testdir/kpasswd.sock'}}}
+unix_cli = realm.special_env('unix_cli', False, krb5_conf=unix_cli_conf)
+
+realm.run([kadminl, 'addprinc', '-pw', 'pw1', 'testprinc'])
+msgs = ('Sending TCP request to UNIX domain socket',)
+realm.run([kpasswd, 'testprinc'], input='pw1\npw2\npw2\n', env=unix_cli,
+ expected_trace=msgs)
+realm.run([kadminl, 'delprinc', 'testprinc'])
+
success('Password change tests')
stop_daemon(replica_kdc)
+mark('UNIX domain socket')
+
+conf_unix = {'realms': {'$realm': {'kdc_listen': '$testdir/krb5.sock',
+ 'kdc_tcp_listen': ''}}}
+unix = realm.special_env('unix', True, kdc_conf=conf_unix)
+realm.run([kdb5_util, 'load', dumpfile], env=unix)
+realm.stop_kdc()
+realm.start_kdc(env=unix)
+
+conf_unix_cli = {'realms': {'$realm': {'kdc': '$testdir/krb5.sock'}}}
+unix_cli = realm.special_env('unix_cli', False, krb5_conf=conf_unix_cli)
+
+# Do a kinit and check if we send the packet via a UNIX domain socket.
+msgs = ('Sending TCP request to UNIX domain socket',)
+realm.kinit(realm.user_princ, password('user'), env=unix_cli,
+ expected_trace=msgs)
+
success('sendto_kdc')