aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb4/realmofhost.c
blob: 1e4b78601a62311b6eec5922054d8fb374d5b4a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * realmofhost.c
 *
 * Copyright 1988 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 *
 * routine to convert hostname into realm name.
 */

#include "mit-copyright.h"
#define	DEFINE_SOCKADDR		/* Ask for MAXHOSTNAMELEN */
#include "krb.h"

#include <string.h>
#include <stdio.h>
#include <ctype.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern char *malloc();
#endif

/*
 * krb_realmofhost.
 * Given a fully-qualified domain-style primary host name,
 * return the name of the Kerberos realm for the host.
 * If the hostname contains no discernable domain, or an error occurs,
 * return the local realm name, as supplied by get_krbrlm().
 * If the hostname contains a domain, but no translation is found,
 * the hostname's domain is converted to upper-case and returned.
 *
 * The format of each line of the translation file is:
 * domain_name kerberos_realm
 * -or-
 * host_name kerberos_realm
 *
 * domain_name should be of the form .XXX.YYY (e.g. .LCS.MIT.EDU)
 * host names should be in the usual form (e.g. FOO.BAR.BAZ)
 */

static char ret_realm[REALM_SZ+1];

KRB5_DLLIMP char FAR * KRB5_CALLCONV
krb_realmofhost(host)
    char FAR *host;
{
	char *domain;
	FILE *trans_file;
	FILE *krb__get_realmsfile();
	/*
	 * This used to be MAXHOSTNAMELEN, but we don't know how big
	 * that will necessarily be on all systems, so assume 1024.
	 */
	char trans_host[1024];
	char trans_realm[REALM_SZ+1];
	int retval;
	struct hostent *h;
	char *lhost;

	/* First, canonicalize it.  This is in case the caller
	   didn't have a fully qualified domain name.  */
	if ((h=gethostbyname(host)) == NULL)
		lhost = host;
	else {
		lhost = h->h_name;
#ifdef DO_REVERSE_RESOLVE
		if (h->h_addr_list != NULL && h->h_addr_list[0] != NULL) {
			char *rev_addr; int rev_type, rev_len;

			rev_type = h->h_addrtype;
			rev_len = h->h_length;
			rev_addr = malloc(rev_len);
			if (rev_addr != NULL) {
				memcpy(rev_addr, h->h_addr_list[0], rev_len);
				h = gethostbyaddr(rev_addr, rev_len, rev_type);
				free(rev_addr);
				if (h == NULL)
					lhost = host;
				else
					lhost = h->h_name;
			}
		}
#endif
	}

	domain = strchr(lhost, '.');

	/* prepare default */
	if (domain) {
		char *cp;

		/* If the domain is just below the top, e.g., CYGNUS.COM,
		   then we special-case it; if someone really wants a
		   realm called COM they will just have to specify it
		   properly. */
		if (((cp = strchr(domain+1, '.')) == (char *) 0)
		    /* Handle root domain properly (COM.): */
		    || (*(cp + 1) == '\0'))
		  domain = lhost - 1;	/* -1 fakes "period" before domain */

		strncpy(ret_realm, domain+1, REALM_SZ);
		ret_realm[REALM_SZ] = '\0';
		/* Upper-case realm */
		for (cp = ret_realm; *cp; cp++)
			if (islower(*cp))
				*cp = toupper(*cp);
	} else {
		krb_get_lrealm(ret_realm, 1);
	}

	if ((trans_file = krb__get_realmsfile()) == (FILE *) 0)
		/* krb_errno = KRB_NO_TRANS */
		return(ret_realm);

	/* loop while not exact match, and more entries to read */
	while (1) {
	        /* XXX REALM_SZ == 40 */
		if ((retval = fscanf(trans_file, "%1023s %40s",
				     trans_host, trans_realm)) != 2) {
			if (retval == EOF)
			  break;
			continue;	/* ignore broken lines */
		}
		trans_host[(MAXHOSTNAMELEN <= 1023) ? MAXHOSTNAMELEN : 1023]
			= '\0';
		trans_realm[REALM_SZ] = '\0';
		if (trans_host[0] == '.') {
		  /* want domain match only */
		  if (domain && (strlen(trans_host) == strlen(domain))
		      && !strcasecmp (trans_host, domain)) {
		    /* got domain match, save for later */
		    (void) strncpy (ret_realm, trans_realm,
				    sizeof(ret_realm) - 1);
		    ret_realm[sizeof(ret_realm) - 1] = '\0';
		    continue;
		  }
		} else {
		  /* want exact match of hostname */
		  if ((strlen(lhost) == strlen(trans_host)) &&
		      !strcasecmp (trans_host, lhost)) {
		    (void) strncpy (ret_realm, trans_realm,
				    sizeof(ret_realm) - 1);
		    ret_realm[sizeof(ret_realm) - 1] = '\0';
		    break;
		  }
		}
	}
	fclose (trans_file);
	return ret_realm;
}