]> andersk Git - moira.git/blob - server/mr_sauth.c
dcb45b23efa123a203c8010f8ab97eae9e5ffc34
[moira.git] / server / mr_sauth.c
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987 by the Massachusetts Institute of Technology
7  *      For copying and distribution information, please see the file
8  *      <mit-copyright.h>.
9  *
10  */
11
12 #ifndef lint
13 static char *rcsid_sms_sauth_c = "$Header$";
14 #endif lint
15
16 #include <mit-copyright.h>
17 #include <strings.h>
18 #include "mr_server.h"
19 #include <ctype.h>
20 #include <krb_et.h>
21
22 extern char buf1[];
23 extern char *whoami;
24
25 char *kname_unparse();
26
27 /*
28  * Handle a MOIRA_AUTH RPC request.
29  *
30  * argv[0] is a kerberos authenticator.  Decompose it, and if
31  * successful, store the name the user authenticated to in 
32  * cl->cl_name.
33  */
34
35 void
36 do_auth(cl)
37         client *cl;
38 {
39         KTEXT_ST auth;
40         AUTH_DAT ad;
41         int status, ok;
42         char buf[REALM_SZ+INST_SZ+ANAME_SZ], hostbuf[BUFSIZ], *host, *p;
43         extern int errno;
44
45         auth.length = cl->args->mr_argl[0];
46         bcopy(cl->args->mr_argv[0], (char *)auth.dat, auth.length);
47         auth.mbz = 0;
48         if (gethostname(hostbuf, sizeof(hostbuf)) < 0)
49           com_err(whoami, errno, "Unable to get local hostname");
50         host = canonicalize_hostname(strsave(hostbuf));
51         for (p = host; *p && *p != '.'; p++)
52           if (isupper(*p))
53             *p = tolower(*p);
54         *p = 0;
55
56         if ((status = krb_rd_req (&auth, MOIRA_SNAME, host, cl->haddr.sin_addr,
57                                  &ad, "")) != 0 &&
58             /* for backwards compatability with old clients */
59             (status = krb_rd_req (&auth, "sms", "sms", cl->haddr.sin_addr,
60                                  &ad, "")) != 0) {
61                 status += ERROR_TABLE_BASE_krb;
62                 cl->reply.mr_status = status;
63                 if (log_flags & LOG_RES)
64                         com_err(whoami, status, "(authentication failed)");
65                 return;
66         }
67         free(host);
68
69         bcopy(ad.pname, cl->kname.name, ANAME_SZ);
70         bcopy(ad.pinst, cl->kname.inst, INST_SZ);
71         bcopy(ad.prealm, cl->kname.realm, REALM_SZ);
72         strcpy(cl->clname, kname_unparse(ad.pname, ad.pinst, ad.prealm));
73
74         if (ad.pinst[0] == 0 && !strcmp(ad.prealm, krb_realm))
75           ok = 1;
76         else
77           ok = 0;
78         /* this is in a separate function because it accesses the database */
79         status = set_krb_mapping(cl->clname, ad.pname, ok,
80                                  &cl->client_id, &cl->users_id);
81
82         if (cl->args->mr_version_no == MR_VERSION_2) {
83             strncpy(cl->entity, cl->args->mr_argv[1], 8);
84             cl->entity[8] = 0;
85         } else {
86             strcpy(cl->entity, "???");
87         }
88         bzero(&ad, sizeof(ad)); /* Clean up session key, etc. */
89
90         if (log_flags & LOG_RES)
91             com_err(whoami, 0, "Auth to %s using %s, uid %d cid %d",
92                     cl->clname, cl->entity, cl->users_id, cl->client_id);
93         if (status != MR_SUCCESS)
94           cl->reply.mr_status = status;
95         else if (cl->users_id == 0)
96           cl->reply.mr_status = MR_USER_AUTH;
97 }
98
99
100 /* Turn a principal, instance, realm triple into a single non-ambiguous 
101  * string.  This is the inverse of kname_parse().  It returns a pointer
102  * to a static buffer, or NULL on error.
103  */
104
105 char *kname_unparse(p, i, r)
106 char *p;
107 char *i;
108 char *r;
109 {
110     static char name[MAX_K_NAME_SZ];
111     char *s;
112
113     s = name;
114     if (!p || strlen(p) > ANAME_SZ)
115       return(NULL);
116     while (*p) {
117         switch (*p) {
118         case '@':
119             *s++ = '\\';
120             *s++ = '@';
121             break;
122         case '.':
123             *s++ = '\\';
124             *s++ = '.';
125             break;
126         case '\\':
127             *s++ = '\\';
128             *s++ = '\\';
129             break;
130         default:
131             *s++ = *p;
132         }
133         p++;
134     }
135     if (i && *i) {
136         if (strlen(i) > INST_SZ)
137           return(NULL);
138         *s++ = '.';
139         while (*i) {
140             switch (*i) {
141             case '@':
142                 *s++ = '\\';
143                 *s++ = '@';
144                 break;
145             case '.':
146                 *s++ = '\\';
147                 *s++ = '.';
148                 break;
149             case '\\':
150                 *s++ = '\\';
151                 *s++ = '\\';
152                 break;
153             default:
154                 *s++ = *i;
155             }
156             i++;
157         }
158     }
159     *s++ = '@';
160     if (!r || strlen(r) > REALM_SZ)
161       return(NULL);
162     while (*r) {
163         switch (*r) {
164         case '@':
165             *s++ = '\\';
166             *s++ = '@';
167             break;
168         case '\\':
169             *s++ = '\\';
170             *s++ = '\\';
171             break;
172         default:
173             *s++ = *r;
174         }
175         r++;
176     }
177     *s = '\0';
178     return(&name[0]);
179 }
This page took 0.597265 seconds and 3 git commands to generate.