source: trunk/athena/bin/discuss/libds/res_module.c @ 1934

Revision 1934, 7.0 KB checked in by srz, 35 years ago (diff)
Added standard copyright notice.
Line 
1/*
2 *
3 *      Copyright (C) 1988, 1989 by the Massachusetts Institute of Technology
4 *      Developed by the MIT Student Information Processing Board (SIPB).
5 *      For copying information, see the file mit-copyright.h in this release.
6 *
7 */
8/*
9 *
10 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/discuss/libds/res_module.c,v $
11 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/discuss/libds/res_module.c,v 1.8 1989-06-03 00:21:31 srz Exp $
12 *
13 * resolve_module () --
14 *      Can you say "Put all the configuration into one file?"  Can you
15 *      say "Concentrated kludgery?"  I knew you could.  This procedure
16 *      resolves a module name into port number, hostname, service; it
17 *      is allowed to use any trick in the book -- it can depend on hostnames,
18 *      have hard coded constants (hopefully recorded in config files, etc.).
19 *      Note that if service name contains a '/' as the first character, then
20 *      the remote function is executed as a subprocess.
21 *
22 *      $Log: not supported by cvs2svn $
23 * Revision 1.7  89/05/19  18:12:21  srz
24 * krb name changes, etc.
25 *
26 * Revision 1.6  89/05/19  17:05:18  raeburn
27 * *** empty log message ***
28 *
29 */
30
31#ifndef lint
32static char rcsid_res_module_c[] =
33    "$Header: /afs/dev.mit.edu/source/repository/athena/bin/discuss/libds/res_module.c,v 1.8 1989-06-03 00:21:31 srz Exp $";
34#endif lint
35
36#include "rpc_et.h"
37#include "config.h"
38#include "ansi.h"
39#include <netdb.h>
40#include <string.h>
41#include <ctype.h>
42
43#ifdef KERBEROS
44#include "krb.h"
45#ifndef MAX_K_NAME_SZ
46/* @#$%^$ last minute changes by jtkohl */
47#define krb_get_lrealm get_krbrlm
48#endif
49static void ExpandHost ();
50#endif /* KERBEROS */
51
52#ifndef SNAME_SZ
53#define SNAME_SZ 30
54#define REALM_SZ 30
55#define MAX_HSTNM 60
56#endif SNAME_SZ
57
58#define NULL 0
59
60char *local_host_name ();
61const char *local_realm ();
62
63static int service_port = 0;
64
65void resolve_module (modname, port, hostp, servp, result)
66    char *modname;              /* name to translate */
67    int *port;                  /* resultant port number */
68    char **hostp;               /* ptr to hostname (static) */
69    char **servp;               /* service_id */
70    int *result;                /* std error code */
71{
72    static char service_id [SNAME_SZ+REALM_SZ];
73    static char hostname [MAX_HSTNM];
74    char realm [REALM_SZ];
75
76    char *myhnamep = NULL;
77    const char *realmp = NULL;
78    struct servent *sp;
79    struct hostent *hp;
80
81    *hostp = NULL;
82    *servp = NULL;
83    *port = 0;
84    *result = 0;
85
86    /* The module name could be of the form "discuss@hostname", where
87     * hostname is the host to contact.  If the hostname is omitted,
88     * the current host is assumed */
89    if (!strncmp (modname, "discuss", 7)) {
90        if (modname [7] == '@') { /* got hostname */
91            myhnamep = &modname [8];
92            hp = gethostbyname (myhnamep); /* make it primary */
93            if (!hp) {
94                extern int h_errno;
95                int h = h_errno;
96                switch (h) {
97                case HOST_NOT_FOUND:
98                    *result = RPC_HOST_UNKNOWN;
99                    break;
100                case TRY_AGAIN:
101                    *result = RPC_NS_TIMEOUT;
102                    break;
103                case NO_RECOVERY:
104                    *result = RPC_NS_ERROR;
105                    break;
106                case NO_ADDRESS:
107                    *result = RPC_NO_ADDR;
108                    break;
109                default:
110                    *result = RPC_NS_ERROR;
111                }
112                return;
113            }
114            strcpy (hostname, hp -> h_name);
115            myhnamep = hostname;
116        } else if (modname [7] == '\0') { /* Just discuss - use current host */
117            myhnamep = local_host_name ();
118        } else {
119            *result = RPC_MOD_UNKNOWN;
120            return;
121        }
122    }
123
124#if 0
125    /* or... the module could be of the form of disname@realm, where realm
126     * is a kerberos realm.  If realm is not given, then the current realm
127     * is assumed. */
128    else if (!strncmp (modname, "disname", 7)) {
129        if (modname [7] == '@') {               /* got realm */
130            realmp = &modname [8];
131        } else if (modname [7] == '\0') {
132            /* Just disname - use current realm */
133            realmp = local_realm ();
134        } else {
135            *result = RPC_MOD_UNKNOWN;
136            return;
137        }
138
139        /* got realm -- use our static lookup. */
140        if (!strcmp (realmp, "LCS.MIT.EDU"))
141            myhnamep = "GRAPE-NEHI.LCS.MIT.EDU";
142        else if (!strcmp (realmp, "ATHENA.MIT.EDU"))
143            myhnamep = "CHARON.MIT.EDU";
144        else {
145            *result = RPC_REALM_UNKNOWN;
146            return;
147        }
148    }
149#endif
150    else {
151        *result = RPC_MOD_UNKNOWN;
152        return;
153    }
154
155    /* Now we have the host name, and all we have to do is create the
156     * service id & port number.  If this is local, we use the subprocess,
157     * for better authentication */
158    if (!namcmp (myhnamep, local_host_name ())) {
159        *port = 0;
160        *servp = SERVER;
161        *hostp = myhnamep;
162        *result = 0;
163        return;
164    }
165
166    /* otherwise, we have to generate the port number */
167    if (service_port == 0) {
168        sp = getservbyname (SERVICE_NAME, 0);
169        if (!sp) {
170            *result = RPC_SERV_UNKNOWN;
171            return;
172        }
173
174        service_port = sp -> s_port;
175    }
176
177    *port = service_port;
178
179    /* generate the service name, but concatenating "discuss.instance@realm"
180     * desired realm. */
181#ifndef KERBEROS
182    strcpy (service_id, "discuss@");
183    strcpy (&service_id[8], REALM);
184#else
185    strcpy (service_id, "discuss.");
186    ExpandHost (myhnamep, &service_id[8], realm);
187    strcat(service_id, "@");
188    if (realmp)
189        strcat (service_id, realmp);
190    else
191        strcat (service_id, realm);
192#endif KERBEROS
193    *hostp = myhnamep;
194    *servp = service_id;
195    *result = 0;
196}
197
198#ifdef KERBEROS
199/*
200 *
201 * ExpandHost -- takes a user string alias for a host, and converts it
202 *               to the official Kerberos principal name, plus the realm
203 *               that it lies in.
204 *
205 *     Warning:  There are some heuristics here.
206 *
207 */
208
209static void ExpandHost (primary_name, krb_host, krb_realm )
210    char *primary_name,*krb_realm;
211    char *krb_host;
212{
213    char *p,*sp=primary_name,*dp=krb_host;
214    /*
215     * The convention established by the Kerberos-authenticated
216     * rcmd services (rlogin, rsh, rcp) is that the principal host
217     * name is all lower case characters.  Therefore, we can get
218     * this name from an alias by taking the official, fully
219     * qualified hostname, stripping off the domain info (ie, take
220     * everything up to but excluding the '.') and translating it
221     * to lower case.  For example, if "menel" is an alias for
222     * host officially named "menelaus" (in /etc/hosts), for the
223     * host whose official name is "MENELAUS.MIT.EDU", the user
224     * could give the command "menel echo foo" and we will resolve
225     * it to "menelaus".
226     */
227    *krb_realm = '\0';          /* null for now */
228    p = index( sp, '.' );
229    if (p) {
230        char *p1;
231
232        strncpy(krb_realm,p+1,REALM_SZ);                /* Realm after '.' */
233        krb_realm[REALM_SZ-1] = NULL;
234        p1 = krb_realm;                           /* Upper case this */
235        do {
236            if (islower(*p1))
237                *p1=toupper(*p1);
238        } while (*p1++);
239    }
240    /* lower case Kerberos host name */
241    do {
242        if (isupper(*sp)) *dp=tolower(*sp);
243        else *dp = *sp;
244    } while (dp++,*sp && (*sp++ != '.'));
245    *(--dp) = NULL;
246
247    /* heuristics */
248
249    if (*krb_realm == '\0')
250        strcpy (krb_realm, local_realm());
251    if (!strcmp(krb_realm,"MIT.EDU"))
252        strcpy(krb_realm,"ATHENA.MIT.EDU");
253    return;
254}
255#endif
256
257const char *local_realm ()
258{
259#ifdef KERBEROS
260    static char realm [REALM_SZ] = "";
261
262    if (realm [0] == '\0')
263        krb_get_lrealm (realm, 1);
264
265    return (realm);
266#else KERBEROS
267    return (REALM);
268#endif KERBEROS
269}
Note: See TracBrowser for help on using the repository browser.