source: trunk/third/moira/update/auth_003.c @ 23740

Revision 23740, 3.9 KB checked in by broder, 15 years ago (diff)
In moira: * New CVS snapshot (Trac: #195) * Drop patches that have been incorporated upstream. * Update to build without krb4 on systems that no longer have it. This doesn't build yet on squeeze, which lacks a krb4 library, but I'm committing now before I start hacking away at a patch to fix that.
Line 
1/* $Id: auth_003.c,v 1.2 2006-08-22 17:36:26 zacheiss Exp $
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
21RCSID("$Header: /afs/athena.mit.edu/astaff/project/moiradev/repository/moira/update/auth_003.c,v 1.2 2006-08-22 17:36:26 zacheiss Exp $");
22
23static char service[] = "host";
24static char master[] = "sms";
25static 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
37void 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}
Note: See TracBrowser for help on using the repository browser.