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
);
67 #endif /* KRB5_DNS_LOOKUP */
69 /* Solaris Kerberos */
70 if (def_realm
!= NULL
)
71 krb5_free_default_realm(context
, def_realm
);
73 return (*master
? KADM5_OK
: KADM5_NO_SRV
);
77 * Find the kpasswd server for the given realm. If the realm is null or
78 * the empty string, find the admin server for the default realm.
79 * Returns 0 on succsess (KADM5_OK). It is the callers responsibility to
80 * free the storage allocated to the admin server, master.
83 kadm5_get_kpasswd(krb5_context context
, const char *realm
, char **kpasswd
)
85 char *def_realm
= NULL
;
87 #ifdef KRB5_DNS_LOOKUP
88 struct sockaddr
*addrs
;
90 unsigned short dns_portno
;
91 char dns_host
[MAX_DNS_NAMELEN
];
93 krb5_error_code dns_ret
= 1, ret
;
94 #endif /* KRB5_DNS_LOOKUP */
96 if (realm
== 0 || *realm
== '\0') {
97 ret
= krb5_get_default_realm(context
, &def_realm
);
102 (void) profile_get_string(context
->profile
, "realms",
103 realm
? realm
: def_realm
,
104 KADM5_KPASSWD
, 0, kpasswd
);
106 if ((*kpasswd
!= NULL
) && ((delim
= strchr(*kpasswd
, ':')) != NULL
))
108 #ifdef KRB5_DNS_LOOKUP
109 if (*kpasswd
== NULL
) {
111 * Initialize realm info for (possible) DNS lookups.
113 dns_realm
.data
= strdup(realm
? realm
: def_realm
);
114 if (dns_realm
.data
== NULL
) {
115 if (def_realm
!= NULL
)
119 dns_realm
.length
= strlen(realm
? realm
: def_realm
);
122 dns_ret
= krb5_get_servername(context
, &dns_realm
,
124 dns_host
, &dns_portno
);
126 *kpasswd
= strdup(dns_host
);
128 if (*kpasswd
== NULL
) {
129 free(dns_realm
.data
);
130 if (def_realm
!= NULL
)
136 free(dns_realm
.data
);
138 #endif /* KRB5_DNS_LOOKUP */
140 if (def_realm
!= NULL
)
142 return (*kpasswd
? KADM5_OK
: KADM5_NO_SRV
);
146 * Get the host base service name for the admin principal. Returns
147 * KADM5_OK on success. Caller must free the storage allocated for
151 kadm5_get_adm_host_srv_name(krb5_context context
,
152 const char *realm
, char **host_service_name
)
159 if (ret
= kadm5_get_master(context
, realm
, &host
))
162 name
= malloc(strlen(KADM5_ADMIN_HOST_SERVICE
)+ strlen(host
) + 2);
167 sprintf(name
, "%s@%s", KADM5_ADMIN_HOST_SERVICE
, host
);
169 *host_service_name
= name
;
175 * Get the host base service name for the changepw principal. Returns
176 * KADM5_OK on success. Caller must free the storage allocated for
180 kadm5_get_cpw_host_srv_name(krb5_context context
,
181 const char *realm
, char **host_service_name
)
188 * First try to find the kpasswd server, after all we are about to
189 * try to change our password. If this fails then try admin_server.
191 if (ret
= kadm5_get_kpasswd(context
, realm
, &host
)) {
192 if (ret
= kadm5_get_master(context
, realm
, &host
))
196 name
= malloc(strlen(KADM5_CHANGEPW_HOST_SERVICE
) + strlen(host
) + 2);
201 sprintf(name
, "%s@%s", KADM5_CHANGEPW_HOST_SERVICE
, host
);
203 *host_service_name
= name
;
209 * Get the host base service name for the kiprop principal. Returns
210 * KADM5_OK on success. Caller must free the storage allocated
211 * for host_service_name.
213 kadm5_ret_t
kadm5_get_kiprop_host_srv_name(krb5_context context
,
215 char **host_service_name
) {
221 if (ret
= kadm5_get_master(context
, realm
, &host
))
224 name
= malloc(strlen(KADM5_KIPROP_HOST_SERVICE
) + strlen(host
) + 2);
229 sprintf(name
, "%s@%s", KADM5_KIPROP_HOST_SERVICE
, host
);
231 *host_service_name
= name
;
238 * Try to determine if this is the master KDC for a given realm
240 kadm5_ret_t
kadm5_is_master(krb5_context context
, const char *realm
,
241 krb5_boolean
*is_master
) {
244 char *admin_host
= NULL
;
245 krb5_address
**tmp_addr
, **master_addr
= NULL
;
246 krb5_address
**local_addr
= NULL
;
251 return (KADM5_FAILURE
);
253 /* Locate the master KDC */
254 if (ret
= kadm5_get_master(context
, realm
, &admin_host
))
257 if (ret
= krb5_os_hostaddr(context
, admin_host
, &master_addr
)) {
262 /* Get the local addresses */
263 if (ret
= krb5_os_localaddr(context
, &local_addr
)) {
264 krb5_free_addresses(context
, master_addr
);
270 for (tmp_addr
= master_addr
; *tmp_addr
; tmp_addr
++) {
271 if (krb5_address_search(context
, *tmp_addr
, local_addr
)) {
277 krb5_free_addresses(context
, local_addr
);
278 krb5_free_addresses(context
, master_addr
);