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