2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
22 #include <sys/types.h>
23 #include <sys/errno.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
31 #include "libadutils.h"
32 #include "locate_plugin.h"
35 #define KRB5_DEFAULT_PORT 88
36 #define DEFAULT_KADM5_PORT 749
37 #define DEFAULT_KPASSWD_PORT 464
40 * This is an "override plugin" used by libkrb5. See:
41 * lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c
43 * The interface is based on:
44 * http://web.mit.edu/~kerberos/krb5-1.12/doc/plugindev/locate.html
48 * Called by krb5int_locate_server / override_locate_server
52 _krb5_override_service_locator(
54 enum locate_service_type svc
,
58 int (*cbfunc
)(void *, int, struct sockaddr
*),
61 _NOTE(ARGUNUSED(arg0
))
62 idmap_pg_config_t
*pgcfg
;
64 int rc
= KRB5_PLUGIN_NO_HANDLE
;
68 * Is this a service we want to override?
71 case locate_service_kdc
:
72 case locate_service_master_kdc
:
73 port
= htons(KRB5_DEFAULT_PORT
);
75 case locate_service_kadmin
:
76 port
= htons(DEFAULT_KADM5_PORT
);
78 case locate_service_kpasswd
:
79 port
= htons(DEFAULT_KPASSWD_PORT
);
81 case locate_service_krb524
:
87 pgcfg
= &_idmapdstate
.cfg
->pgcfg
;
90 * Is this a realm we want to override?
92 if (pgcfg
->domain_name
== NULL
)
94 if (0 != strcasecmp(realm
, pgcfg
->domain_name
))
98 * Yes, this is our domain. Have a DC?
100 if ((ds
= pgcfg
->domain_controller
) == NULL
) {
101 rc
= KRB5_REALM_CANT_RESOLVE
;
110 if (family
== ds
->addr
.ss_family
)
112 /* else fallthrough */
114 rc
= KRB5_ERR_NO_SERVICE
;
119 * Provide the service address we have.
121 switch (ds
->addr
.ss_family
) {
123 struct sockaddr_in sin
;
124 struct sockaddr_in
*dsa
= (void *)&ds
->addr
;
125 (void) memset(&sin
, 0, sizeof (sin
));
126 sin
.sin_family
= AF_INET
;
128 (void) memcpy(&sin
.sin_addr
, &dsa
->sin_addr
,
129 sizeof (sin
.sin_addr
));
130 rc
= cbfunc(cbdata
, socktype
, (struct sockaddr
*)&sin
);
134 struct sockaddr_in6 sin6
;
135 struct sockaddr_in6
*dsa6
= (void *)&ds
->addr
;
136 (void) memset(&sin6
, 0, sizeof (sin6
));
137 sin6
.sin6_family
= AF_INET6
;
138 sin6
.sin6_port
= port
;
139 (void) memcpy(&sin6
.sin6_addr
, &dsa6
->sin6_addr
,
140 sizeof (sin6
.sin6_addr
));
141 rc
= cbfunc(cbdata
, socktype
, (struct sockaddr
*)&sin6
);
145 rc
= KRB5_ERR_NO_SERVICE
;
148 /* rc from cbfunc is special. */