1 #pragma ident	"%Z%%M%	%I%	%E% SMI"
2 
3 /*
4  * lib/krb5/os/def_realm.c
5  *
6  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
7  * All Rights Reserved.
8  *
9  * Export of this software from the United States of America may
10  *   require a specific license from the United States Government.
11  *   It is the responsibility of any person or organization contemplating
12  *   export to obtain such a license before exporting.
13  *
14  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
15  * distribute this software and its documentation for any purpose and
16  * without fee is hereby granted, provided that the above copyright
17  * notice appear in all copies and that both that copyright notice and
18  * this permission notice appear in supporting documentation, and that
19  * the name of M.I.T. not be used in advertising or publicity pertaining
20  * to distribution of the software without specific, written prior
21  * permission.  Furthermore if you modify this software you must label
22  * your software as modified software and not distribute it in such a
23  * fashion that it might be confused with the original M.I.T. software.
24  * M.I.T. makes no representations about the suitability of
25  * this software for any purpose.  It is provided "as is" without express
26  * or implied warranty.
27  *
28  *
29  * krb5_get_default_realm(), krb5_set_default_realm(),
30  * krb5_free_default_realm() functions.
31  */
32 
33 #include <k5-int.h>
34 #include "os-proto.h"
35 #include <stdio.h>
36 
37 #ifdef KRB5_DNS_LOOKUP
38 #ifdef WSHELPER
39 #include <wshelper.h>
40 #else /* WSHELPER */
41 #ifdef HAVE_NETINET_IN_H
42 #include <netinet/in.h>
43 #endif
44 #include <arpa/inet.h>
45 #include <arpa/nameser.h>
46 #include <resolv.h>
47 #include <netdb.h>
48 #endif /* WSHELPER */
49 
50 /* for old Unixes and friends ... */
51 #ifndef MAXHOSTNAMELEN
52 #define MAXHOSTNAMELEN 64
53 #endif
54 
55 #define MAX_DNS_NAMELEN (15*(MAXHOSTNAMELEN + 1)+1)
56 
57 #endif /* KRB5_DNS_LOOKUP */
58 
59 /*
60  * Retrieves the default realm to be used if no user-specified realm is
61  *  available.  [e.g. to interpret a user-typed principal name with the
62  *  realm omitted for convenience]
63  *
64  *  returns system errors, NOT_ENOUGH_SPACE, KV5M_CONTEXT
65 */
66 
67 /*
68  * Implementation:  the default realm is stored in a configuration file,
69  * named by krb5_config_file;  the first token in this file is taken as
70  * the default local realm name.
71  */
72 
73 krb5_error_code KRB5_CALLCONV
74 krb5_get_default_realm(krb5_context context, char **lrealm)
75 {
76     char *realm = 0;
77     char *cp;
78     krb5_error_code retval;
79 
80     if (!context || (context->magic != KV5M_CONTEXT))
81 	    return KV5M_CONTEXT;
82 
83     if (!context->default_realm) {
84         /*
85          * XXX should try to figure out a reasonable default based
86          * on the host's DNS domain.
87          */
88         context->default_realm = 0;
89         if (context->profile != 0) {
90             retval = profile_get_string(context->profile, "libdefaults",
91                                         "default_realm", 0, 0,
92                                         &realm);
93 
94             if (!retval && realm) {
95                 context->default_realm = malloc(strlen(realm) + 1);
96                 if (!context->default_realm) {
97                     profile_release_string(realm);
98                     return ENOMEM;
99                 }
100                 strcpy(context->default_realm, realm);
101                 profile_release_string(realm);
102             }
103         }
104 #ifndef KRB5_DNS_LOOKUP
105         else
106             return KRB5_CONFIG_CANTOPEN;
107 #else /* KRB5_DNS_LOOKUP */
108         if (context->default_realm == 0) {
109             int use_dns =  _krb5_use_dns_realm(context);
110             if ( use_dns ) {
111 		/*
112 		 * Since this didn't appear in our config file, try looking
113 		 * it up via DNS.  Look for a TXT records of the form:
114 		 *
115 		 * _kerberos.<localhost>
116 		 * _kerberos.<domainname>
117 		 * _kerberos.<searchlist>
118 		 *
119 		 */
120 		char localhost[MAX_DNS_NAMELEN+1];
121 		char * p;
122 
123 		krb5int_get_fq_local_hostname (localhost, sizeof(localhost));
124 
125 		if ( localhost[0] ) {
126 		    p = localhost;
127 		    do {
128 			retval = krb5_try_realm_txt_rr("_kerberos", p,
129 						       &context->default_realm);
130 			p = strchr(p,'.');
131 			if (p)
132 			    p++;
133 		    } while (retval && p && p[0]);
134 
135 		    if (retval)
136 			retval = krb5_try_realm_txt_rr("_kerberos", "",
137 						       &context->default_realm);
138 		} else {
139 		    retval = krb5_try_realm_txt_rr("_kerberos", "",
140 						   &context->default_realm);
141 		}
142 		if (retval) {
143 		    return(KRB5_CONFIG_NODEFREALM);
144 		}
145             }
146         }
147 #endif /* KRB5_DNS_LOOKUP */
148     }
149 
150     if (context->default_realm == 0)
151 	return(KRB5_CONFIG_NODEFREALM);
152     if (context->default_realm[0] == 0) {
153         free (context->default_realm);
154         context->default_realm = 0;
155         return KRB5_CONFIG_NODEFREALM;
156     }
157 
158     realm = context->default_realm;
159 
160     /*LINTED*/
161     if (!(*lrealm = cp = malloc((unsigned int) strlen(realm) + 1)))
162         return ENOMEM;
163     strcpy(cp, realm);
164     return(0);
165 }
166 
167 krb5_error_code KRB5_CALLCONV
168 krb5_set_default_realm(krb5_context context, const char *lrealm)
169 {
170     if (!context || (context->magic != KV5M_CONTEXT))
171 	    return KV5M_CONTEXT;
172 
173     if (context->default_realm) {
174 	    free(context->default_realm);
175 	    context->default_realm = 0;
176     }
177 
178     /* Allow the user to clear the default realm setting by passing in
179        NULL */
180     if (!lrealm) return 0;
181 
182     context->default_realm = malloc(strlen (lrealm) + 1);
183 
184     if (!context->default_realm)
185 	    return ENOMEM;
186 
187     strcpy(context->default_realm, lrealm);
188     return(0);
189 
190 }
191 
192 /*ARGSUSED*/
193 void KRB5_CALLCONV
194 krb5_free_default_realm(krb5_context context, char *lrealm)
195 {
196 	free (lrealm);
197 }
198