]> andersk Git - moira.git/blob - update/auth_003.c
acea5d6908271d4704141cb6a97fc7513db34aaf
[moira.git] / update / auth_003.c
1 /* $Id$
2  *
3  * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
4  * For copying and distribution information, please see the file
5  * <mit-copyright.h>.
6  */
7
8 #include <mit-copyright.h>
9 #include <moira.h>
10 #include "update_server.h"
11
12 #include <sys/utsname.h>
13
14 #include <errno.h>
15 #include <stdio.h>
16 #include <string.h>
17
18 #include <krb.h>
19 #include <krb5.h>
20
21 RCSID("$Header$");
22
23 static char service[] = "host";
24 static char master[] = "sms";
25 static char qmark[] = "???";
26
27 /*
28  * authentication request auth_003:
29  *
30  * >>> (STRING) "auth_003"
31  * <<< (int) 0
32  * >>> (STRING) ticket
33  * <<< (int) code
34  *
35  */
36
37 void auth_003(int conn, char *str)
38 {
39   krb5_context context = NULL;
40   krb5_auth_context auth_con = NULL;
41   krb5_data auth;
42   krb5_principal server = NULL, client = NULL;
43   krb5_ticket *ticket;
44   char *p, *first, *data;
45   char name[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
46   char aname[ANAME_SZ], ainst[INST_SZ], arealm[REALM_SZ];
47   size_t size;
48   long code;
49   struct utsname uts;
50
51   ticket = NULL;
52
53   send_ok(conn);
54
55   recv_string(conn, &data, &size);
56   auth.data = malloc(size);
57   if (!auth.data)
58     goto out;
59   memcpy(auth.data, data, size);
60   free(data);
61   auth.length = size;
62
63   code = krb5_init_context(&context);
64   if (code)
65     {
66       com_err(whoami, code, "Initializing context");
67       send_int(conn, code);
68       goto out;
69     }
70
71   code = krb5_auth_con_init(context, &auth_con);
72   if (code)
73     {
74       com_err(whoami, code, "Initializing auth context");
75       send_int(conn, code);
76       goto out;
77     }
78
79   if (uname(&uts) < 0)
80     {
81       com_err(whoami, errno, "Unable to get local hostname");
82       send_int(conn, errno);
83       goto out;
84     }
85
86   code = krb5_sname_to_principal(context, uts.nodename, service,
87                                  KRB5_NT_SRV_HST, &server);
88
89   if (code)
90     {
91       com_err(whoami, code, "(krb5_sname_to_principal failed)");
92       send_int(conn, code);
93       goto out;
94     }
95
96   code = krb5_rd_req(context, &auth_con, &auth, server, NULL, NULL, &ticket);
97
98   if (code)
99     {
100       strcpy(name, qmark);
101       strcpy(inst, qmark);
102       strcpy(realm, qmark);
103       com_err(whoami, code, "auth for %s.%s@%s failed", name, inst, realm);
104       send_int(conn, code);
105       goto out;
106     }
107
108   code = krb5_copy_principal(context, ticket->enc_part2->client, &client);
109   if (code)
110     {
111       com_err(whoami, code, "(krb5_copy_principal failed)");
112       send_int(conn, code);
113       goto out;
114     }
115
116   code = krb5_524_conv_principal(context, client, name, inst, realm);
117   if (code)
118     {
119       com_err(whoami, code, "(krb5_524_conv_principal_failed)");
120       send_int(conn, code);
121       goto out;
122     }
123
124   /* If there is an auth record in the config file matching the
125    * authenticator we received, then accept it.  If there's no
126    * auth record, assume [master]@[local realm].
127    */
128   if ((first = p = config_lookup("auth")))
129     {
130       do
131         {
132           kname_parse(aname, ainst, arealm, p);
133           if (strcmp(aname, name) ||
134               strcmp(ainst, inst) ||
135               strcmp(arealm, realm))
136             p = config_lookup("auth");
137           else
138             p = first;
139         }
140       while (p != first);
141     }
142   else 
143     {
144       strcpy(aname, master);
145       strcpy(ainst, "");
146       if (krb_get_lrealm(arealm, 1))
147         strcpy(arealm, KRB_REALM);
148     }
149   code = EPERM;
150   if (strcmp(aname, name) ||
151       strcmp(ainst, inst) ||
152       strcmp(arealm, realm))
153     {
154       com_err(whoami, code, "auth for %s.%s@%s failed", name, inst, realm);
155       send_int(conn, code);
156       goto out;
157     }
158   send_ok(conn);
159   have_authorization = 1;
160
161  out:
162   if (client)
163     krb5_free_principal(context, client);
164   if (server)
165     krb5_free_principal(context, server);
166   if (ticket)
167     krb5_free_ticket(context, ticket);
168   krb5_free_data_contents(context, &auth);
169   if (auth_con)
170     krb5_auth_con_free(context, auth_con);
171   return;
172 }
This page took 0.100423 seconds and 3 git commands to generate.