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

Revision 24319, 4.0 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: auth_003.c 3956 2010-01-05 20:56:56Z zacheiss $
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#ifdef HAVE_KRB4
19#include <krb.h>
20#else
21#include <mr_krb.h>
22#endif
23#include <krb5.h>
24
25RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/update/auth_003.c $ $Id: auth_003.c 3956 2010-01-05 20:56:56Z zacheiss $");
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];
51  char *lrealm = NULL;
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, "");
151      if (!krb5_get_default_realm(context, &lrealm))
152        {
153          strcpy(arealm, lrealm);
154        }
155      else
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:
171  if (lrealm)
172    free(lrealm);
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}
Note: See TracBrowser for help on using the repository browser.