]> andersk Git - moira.git/blob - update/auth_003.c
Use krb5_error_code for return value of krb5 library functions.
[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   krb5_init_ets(context);
72
73   code = krb5_auth_con_init(context, &auth_con);
74   if (code)
75     {
76       com_err(whoami, code, "Initializing auth context");
77       send_int(conn, code);
78       goto out;
79     }
80
81   if (uname(&uts) < 0)
82     {
83       com_err(whoami, errno, "Unable to get local hostname");
84       send_int(conn, errno);
85       goto out;
86     }
87
88   code = krb5_sname_to_principal(context, uts.nodename, service,
89                                  KRB5_NT_SRV_HST, &server);
90
91   if (code)
92     {
93       com_err(whoami, code, "(krb5_sname_to_principal failed)");
94       send_int(conn, code);
95       goto out;
96     }
97
98   code = krb5_rd_req(context, &auth_con, &auth, server, NULL, NULL, &ticket);
99
100   if (code)
101     {
102       strcpy(name, qmark);
103       strcpy(inst, qmark);
104       strcpy(realm, qmark);
105       com_err(whoami, code, "auth for %s.%s@%s failed", name, inst, realm);
106       send_int(conn, code);
107       goto out;
108     }
109
110   code = krb5_copy_principal(context, ticket->enc_part2->client, &client);
111   if (code)
112     {
113       com_err(whoami, code, "(krb5_copy_principal failed)");
114       send_int(conn, code);
115       goto out;
116     }
117
118   code = krb5_524_conv_principal(context, client, name, inst, realm);
119   if (code)
120     {
121       com_err(whoami, code, "(krb5_524_conv_principal_failed)");
122       send_int(conn, code);
123       goto out;
124     }
125
126   /* If there is an auth record in the config file matching the
127    * authenticator we received, then accept it.  If there's no
128    * auth record, assume [master]@[local realm].
129    */
130   if ((first = p = config_lookup("auth")))
131     {
132       do
133         {
134           kname_parse(aname, ainst, arealm, p);
135           if (strcmp(aname, name) ||
136               strcmp(ainst, inst) ||
137               strcmp(arealm, realm))
138             p = config_lookup("auth");
139           else
140             p = first;
141         }
142       while (p != first);
143     }
144   else 
145     {
146       strcpy(aname, master);
147       strcpy(ainst, "");
148       if (krb_get_lrealm(arealm, 1))
149         strcpy(arealm, KRB_REALM);
150     }
151   code = EPERM;
152   if (strcmp(aname, name) ||
153       strcmp(ainst, inst) ||
154       strcmp(arealm, realm))
155     {
156       com_err(whoami, code, "auth for %s.%s@%s failed", name, inst, realm);
157       send_int(conn, code);
158       goto out;
159     }
160   send_ok(conn);
161   have_authorization = 1;
162
163  out:
164   if (client)
165     krb5_free_principal(context, client);
166   if (server)
167     krb5_free_principal(context, server);
168   if (ticket)
169     krb5_free_ticket(context, ticket);
170   krb5_free_data_contents(context, &auth);
171   if (auth_con)
172     krb5_auth_con_free(context, auth_con);
173   return;
174 }
This page took 0.050119 seconds and 5 git commands to generate.