2 * lib/krb5/os/hst_realm.c
4 * Copyright 1990,1991 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. M.I.T. makes no representations about the suitability of
20 * this software for any purpose. It is provided "as is" without express
21 * or implied warranty.
24 * krb5_get_host_realm()
29 Figures out the Kerberos realm names for host, filling in a
30 pointer to an argv[] style list of names, terminated with a null pointer.
32 If host is NULL, the local host's realms are determined.
34 If there are no known realms for the host, the filled-in pointer is set
37 The pointer array and strings pointed to are all in allocated storage,
38 and should be freed by the caller when finished.
44 * Implementation notes:
46 * this implementation only provides one realm per host, using the same
47 * mapping file used in kerberos v4.
49 * Given a fully-qualified domain-style primary host name,
50 * return the name of the Kerberos realm for the host.
51 * If the hostname contains no discernable domain, or an error occurs,
52 * return the local realm name, as supplied by krb5_get_default_realm().
53 * If the hostname contains a domain, but no translation is found,
54 * the hostname's domain is converted to upper-case and returned.
56 * The format of each line of the translation file is:
57 * domain_name kerberos_realm
59 * host_name kerberos_realm
61 * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
62 * host names should be in the usual form (e.g. FOO.BAR.BAZ)
75 /* for old Unixes and friends ... */
76 #ifndef MAXHOSTNAMELEN
77 #define MAXHOSTNAMELEN 64
80 #define DEF_REALMNAME_SIZE 256
82 extern char *krb5_trans_file;
86 * Windows DLL can't use the fscanf routine. We need fscanf to read
87 * in the host and realm. Read_2str with read_1str duplicate the needed
88 * functionality. See also realm_dom.c.
91 read_1str (FILE *fp, char *buf, int buflen) {
95 c = fgetc (fp); /* Past leading whitespace */
103 if (buflen > 0) { /* Store the character */
107 if (buflen <= 0) /* Fscanf stops scanning... */
108 break; /* ...when buffer is full */
110 c = fgetc (fp); /* Get next character */
111 if (c == EOF || isspace (c))
115 if (buflen) /* Make ASCIIZ if room */
122 read_2str (FILE *fp, char *b1, int l1, char *b2, int l2) {
125 n = read_1str (fp, b1, l1); /* Read first string */
127 n = read_1str (fp, b2, l2); /* Read second string */
132 #endif /* _WINDOWS */
134 krb5_error_code INTERFACE
135 krb5_get_host_realm(context, host, realmsp)
136 krb5_context context;
143 char trans_host[MAXHOSTNAMELEN+1];
144 char local_host[MAXHOSTNAMELEN+1];
145 char trans_realm[DEF_REALMNAME_SIZE];
146 krb5_error_code retval;
148 char scanstring[7+2*16]; /* 7 chars + 16 for each decimal
151 if (!(retrealms = (char **)calloc(2, sizeof(*retrealms))))
154 if (gethostname(local_host, sizeof(local_host)-1) == -1)
156 local_host[sizeof(local_host)-1] = '\0';
159 domain = strchr(host, '.');
161 /* prepare default */
165 if (!(retrealms[0] = malloc(strlen(&domain[1])+1))) {
166 krb5_xfree(retrealms);
169 strcpy(retrealms[0], &domain[1]);
170 /* Upper-case realm */
171 for (cp = retrealms[0]; *cp; cp++)
175 if (retval = krb5_get_default_realm(context, &retrealms[0])) {
176 krb5_xfree(retrealms);
181 krb5_find_config_files();
182 if ((trans_file = fopen(krb5_trans_file, "r")) == (FILE *) 0) {
183 krb5_xfree(retrealms[0]);
184 krb5_xfree(retrealms);
185 return KRB5_TRANS_CANTOPEN;
187 (void) sprintf(scanstring, "%%%ds %%%ds",
188 sizeof(trans_host)-1,sizeof(trans_realm)-1);
191 scanval = read_2str (trans_file, trans_host, sizeof(trans_host)-1,
192 trans_realm, sizeof(trans_realm)-1);
194 scanval = fscanf(trans_file, scanstring, trans_host, trans_realm);
197 if (scanval == EOF) {
201 continue; /* ignore broken lines */
203 trans_host[sizeof(trans_host)-1] = '\0';
204 trans_realm[sizeof(trans_realm)-1] = '\0';
205 if (!strcasecmp(trans_host, host)) {
206 /* exact match of hostname, so return the realm */
207 if (!(retrealms[0] = realloc(retrealms[0],
208 strlen(trans_realm)+1))) {
209 krb5_xfree(retrealms);
212 (void) strcpy(retrealms[0], trans_realm);
216 if ((trans_host[0] == '.') && domain) {
217 /* this is a possible domain match */
218 if (!strcasecmp(trans_host, domain)) {
219 /* domain match, save for later */
220 if (!(retrealms[0] = realloc(retrealms[0],
221 strlen(trans_realm)+1))) {
222 krb5_xfree(retrealms);
225 (void) strcpy(retrealms[0], trans_realm);
231 *realmsp = retrealms;