8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / krb5 / kadm5 / kadm_host_srv_names.c
blob1fb2031e35171b956761e9fd56f4ad9a6dfe11cb
1 /*
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
3 */
5 /*
6 * lib/kad5/kadm_host_srv_names.c
7 */
9 #include <k5-int.h>
10 #include "admin.h"
11 #include <stdio.h>
12 #include <os-proto.h>
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.
24 kadm5_ret_t
25 kadm5_get_master(krb5_context context, const char *realm, char **master)
27 /* Solaris Kerberos */
28 char *def_realm = NULL;
30 char *delim;
31 #ifdef KRB5_DNS_LOOKUP
32 struct sockaddr *addrs;
33 int naddrs;
34 unsigned short dns_portno;
35 char dns_host[MAX_DNS_NAMELEN];
36 krb5_data dns_realm;
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))
48 *delim = '\0';
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);
56 dns_realm.magic = 0;
58 dns_ret = krb5_get_servername(context, &dns_realm,
59 "_kerberos-adm", "_udp",
60 dns_host, &dns_portno);
61 if (dns_ret == 0)
62 *master = strdup(dns_host);
64 if (dns_realm.data)
65 free(dns_realm.data);
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.
82 kadm5_ret_t
83 kadm5_get_kpasswd(krb5_context context, const char *realm, char **kpasswd)
85 char *def_realm = NULL;
86 char *delim;
87 #ifdef KRB5_DNS_LOOKUP
88 struct sockaddr *addrs;
89 int naddrs;
90 unsigned short dns_portno;
91 char dns_host[MAX_DNS_NAMELEN];
92 krb5_data dns_realm;
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);
98 if (ret != 0)
99 return (ret);
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))
107 *delim = '\0';
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)
116 free(def_realm);
117 return (ENOMEM);
119 dns_realm.length = strlen(realm ? realm : def_realm);
120 dns_realm.magic = 0;
122 dns_ret = krb5_get_servername(context, &dns_realm,
123 "_kpasswd", "_tcp",
124 dns_host, &dns_portno);
125 if (dns_ret == 0) {
126 *kpasswd = strdup(dns_host);
128 if (*kpasswd == NULL) {
129 free(dns_realm.data);
130 if (def_realm != NULL)
131 free(def_realm);
132 return (ENOMEM);
136 free(dns_realm.data);
138 #endif /* KRB5_DNS_LOOKUP */
140 if (def_realm != NULL)
141 free(def_realm);
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
148 * host_service_name.
150 kadm5_ret_t
151 kadm5_get_adm_host_srv_name(krb5_context context,
152 const char *realm, char **host_service_name)
154 kadm5_ret_t ret;
155 char *name;
156 char *host;
159 if (ret = kadm5_get_master(context, realm, &host))
160 return (ret);
162 name = malloc(strlen(KADM5_ADMIN_HOST_SERVICE)+ strlen(host) + 2);
163 if (name == NULL) {
164 free(host);
165 return (ENOMEM);
167 sprintf(name, "%s@%s", KADM5_ADMIN_HOST_SERVICE, host);
168 free(host);
169 *host_service_name = name;
171 return (KADM5_OK);
175 * Get the host base service name for the changepw principal. Returns
176 * KADM5_OK on success. Caller must free the storage allocated for
177 * host_service_name.
179 kadm5_ret_t
180 kadm5_get_cpw_host_srv_name(krb5_context context,
181 const char *realm, char **host_service_name)
183 kadm5_ret_t ret;
184 char *name;
185 char *host;
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))
193 return (ret);
196 name = malloc(strlen(KADM5_CHANGEPW_HOST_SERVICE) + strlen(host) + 2);
197 if (name == NULL) {
198 free(host);
199 return (ENOMEM);
201 sprintf(name, "%s@%s", KADM5_CHANGEPW_HOST_SERVICE, host);
202 free(host);
203 *host_service_name = name;
205 return (KADM5_OK);
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,
214 const char *realm,
215 char **host_service_name) {
216 kadm5_ret_t ret;
217 char *name;
218 char *host;
221 if (ret = kadm5_get_master(context, realm, &host))
222 return (ret);
224 name = malloc(strlen(KADM5_KIPROP_HOST_SERVICE) + strlen(host) + 2);
225 if (name == NULL) {
226 free(host);
227 return (ENOMEM);
229 sprintf(name, "%s@%s", KADM5_KIPROP_HOST_SERVICE, host);
230 free(host);
231 *host_service_name = name;
233 return (KADM5_OK);
237 * Solaris Kerberos:
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) {
243 kadm5_ret_t ret;
244 char *admin_host = NULL;
245 krb5_address **tmp_addr, **master_addr = NULL;
246 krb5_address **local_addr = NULL;
248 if (is_master)
249 *is_master = FALSE;
250 else
251 return (KADM5_FAILURE);
253 /* Locate the master KDC */
254 if (ret = kadm5_get_master(context, realm, &admin_host))
255 return (ret);
257 if (ret = krb5_os_hostaddr(context, admin_host, &master_addr)) {
258 free(admin_host);
259 return (ret);
262 /* Get the local addresses */
263 if (ret = krb5_os_localaddr(context, &local_addr)) {
264 krb5_free_addresses(context, master_addr);
265 free(admin_host);
266 return (ret);
269 /* Compare them */
270 for (tmp_addr = master_addr; *tmp_addr; tmp_addr++) {
271 if (krb5_address_search(context, *tmp_addr, local_addr)) {
272 *is_master = TRUE;
273 break;
277 krb5_free_addresses(context, local_addr);
278 krb5_free_addresses(context, master_addr);
279 free(admin_host);
281 return (KADM5_OK);