2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
6 * lib/kad5/kadm_host_srv_names.c
15 #define KADM5_MASTER "admin_server"
16 #define KADM5_KPASSWD "kpasswd_server"
19 * Find the admin server for the given realm. If the realm is null or
20 * the empty string, find the admin server for the default realm.
21 * Returns 0 on succsess (KADM5_OK). It is the callers responsibility to
22 * free the storage allocated to the admin server, master.
25 kadm5_get_master(krb5_context context
, const char *realm
, char **master
)
27 /* Solaris Kerberos */
28 char *def_realm
= NULL
;
31 #ifdef KRB5_DNS_LOOKUP
32 struct sockaddr
*addrs
;
34 unsigned short dns_portno
;
35 char dns_host
[MAX_DNS_NAMELEN
];
37 krb5_error_code dns_ret
= 1;
38 #endif /* KRB5_DNS_LOOKUP */
40 if (realm
== 0 || *realm
== '\0')
41 krb5_get_default_realm(context
, &def_realm
);
43 (void) profile_get_string(context
->profile
, "realms",
44 realm
? realm
: def_realm
,
45 KADM5_MASTER
, 0, master
);
47 if ((*master
!= NULL
) && ((delim
= strchr(*master
, ':')) != NULL
))
49 #ifdef KRB5_DNS_LOOKUP
50 if (*master
== NULL
) {
52 * Initialize realm info for (possible) DNS lookups.
54 dns_realm
.data
= strdup(realm
? realm
: def_realm
);
55 dns_realm
.length
= strlen(realm
? realm
: def_realm
);
58 dns_ret
= krb5_get_servername(context
, &dns_realm
,
59 "_kerberos-adm", "_udp",
60 dns_host
, &dns_portno
);
62 *master
= strdup(dns_host
);
66 #endif /* KRB5_DNS_LOOKUP */
68 /* Solaris Kerberos */
69 if (def_realm
!= NULL
)
70 krb5_free_default_realm(context
, def_realm
);
72 return (*master
? KADM5_OK
: KADM5_NO_SRV
);
76 * Find the kpasswd server for the given realm. If the realm is null or
77 * the empty string, find the admin server for the default realm.
78 * Returns 0 on succsess (KADM5_OK). It is the callers responsibility to
79 * free the storage allocated to the admin server, master.
82 kadm5_get_kpasswd(krb5_context context
, const char *realm
, char **kpasswd
)
84 char *def_realm
= NULL
;
86 #ifdef KRB5_DNS_LOOKUP
87 struct sockaddr
*addrs
;
89 unsigned short dns_portno
;
90 char dns_host
[MAX_DNS_NAMELEN
];
92 krb5_error_code dns_ret
= 1, ret
;
93 #endif /* KRB5_DNS_LOOKUP */
95 if (realm
== 0 || *realm
== '\0') {
96 ret
= krb5_get_default_realm(context
, &def_realm
);
101 (void) profile_get_string(context
->profile
, "realms",
102 realm
? realm
: def_realm
,
103 KADM5_KPASSWD
, 0, kpasswd
);
105 if ((*kpasswd
!= NULL
) && ((delim
= strchr(*kpasswd
, ':')) != NULL
))
107 #ifdef KRB5_DNS_LOOKUP
108 if (*kpasswd
== NULL
) {
110 * Initialize realm info for (possible) DNS lookups.
112 dns_realm
.data
= strdup(realm
? realm
: def_realm
);
113 if (dns_realm
.data
== NULL
) {
117 dns_realm
.length
= strlen(realm
? realm
: def_realm
);
120 dns_ret
= krb5_get_servername(context
, &dns_realm
,
122 dns_host
, &dns_portno
);
124 *kpasswd
= strdup(dns_host
);
126 if (*kpasswd
== NULL
) {
127 free(dns_realm
.data
);
133 free(dns_realm
.data
);
135 #endif /* KRB5_DNS_LOOKUP */
138 return (*kpasswd
? KADM5_OK
: KADM5_NO_SRV
);
142 * Get the host base service name for the admin principal. Returns
143 * KADM5_OK on success. Caller must free the storage allocated for
147 kadm5_get_adm_host_srv_name(krb5_context context
,
148 const char *realm
, char **host_service_name
)
155 if (ret
= kadm5_get_master(context
, realm
, &host
))
158 name
= malloc(strlen(KADM5_ADMIN_HOST_SERVICE
)+ strlen(host
) + 2);
163 sprintf(name
, "%s@%s", KADM5_ADMIN_HOST_SERVICE
, host
);
165 *host_service_name
= name
;
171 * Get the host base service name for the changepw principal. Returns
172 * KADM5_OK on success. Caller must free the storage allocated for
176 kadm5_get_cpw_host_srv_name(krb5_context context
,
177 const char *realm
, char **host_service_name
)
184 * First try to find the kpasswd server, after all we are about to
185 * try to change our password. If this fails then try admin_server.
187 if (ret
= kadm5_get_kpasswd(context
, realm
, &host
)) {
188 if (ret
= kadm5_get_master(context
, realm
, &host
))
192 name
= malloc(strlen(KADM5_CHANGEPW_HOST_SERVICE
) + strlen(host
) + 2);
197 sprintf(name
, "%s@%s", KADM5_CHANGEPW_HOST_SERVICE
, host
);
199 *host_service_name
= name
;
205 * Get the host base service name for the kiprop principal. Returns
206 * KADM5_OK on success. Caller must free the storage allocated
207 * for host_service_name.
209 kadm5_ret_t
kadm5_get_kiprop_host_srv_name(krb5_context context
,
211 char **host_service_name
) {
217 if (ret
= kadm5_get_master(context
, realm
, &host
))
220 name
= malloc(strlen(KADM5_KIPROP_HOST_SERVICE
) + strlen(host
) + 2);
225 sprintf(name
, "%s@%s", KADM5_KIPROP_HOST_SERVICE
, host
);
227 *host_service_name
= name
;
234 * Try to determine if this is the master KDC for a given realm
236 kadm5_ret_t
kadm5_is_master(krb5_context context
, const char *realm
,
237 krb5_boolean
*is_master
) {
240 char *admin_host
= NULL
;
241 krb5_address
**tmp_addr
, **master_addr
= NULL
;
242 krb5_address
**local_addr
= NULL
;
247 return (KADM5_FAILURE
);
249 /* Locate the master KDC */
250 if (ret
= kadm5_get_master(context
, realm
, &admin_host
))
253 if (ret
= krb5_os_hostaddr(context
, admin_host
, &master_addr
)) {
258 /* Get the local addresses */
259 if (ret
= krb5_os_localaddr(context
, &local_addr
)) {
260 krb5_free_addresses(context
, master_addr
);
266 for (tmp_addr
= master_addr
; *tmp_addr
; tmp_addr
++) {
267 if (krb5_address_search(context
, *tmp_addr
, local_addr
)) {
273 krb5_free_addresses(context
, local_addr
);
274 krb5_free_addresses(context
, master_addr
);