source: trunk/third/moira/reg_svr/kerberos.c @ 23740

Revision 23740, 5.1 KB checked in by broder, 16 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: kerberos.c,v 1.8 2005-08-09 19:45:27 zacheiss Exp $
2 *
3 * Kerberos routines for registration server
4 *
5 * Copyright (C) 1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 *
9 */
10
11#include <mit-copyright.h>
12#include <moira.h>
13#include "reg_svr.h"
14
15#if !defined(KRB4) && !defined(KRB5)
16#define KRB5
17#endif
18
19#include <errno.h>
20#include <string.h>
21
22#include <com_err.h>
23
24#define KRB5_DEPRECATED 1
25#define KRB5_PRIVATE 1
26
27#ifdef KRB4
28#include <des.h>
29#include <kadm.h>
30#include <kadm_err.h>
31#include <krb.h>
32#endif
33
34#ifdef KRB5
35#include <kadm5/admin.h>
36#include <krb5.h>
37#include <krb.h>
38
39krb5_context context;
40#endif
41
42RCSID("$Header: /afs/athena.mit.edu/astaff/project/moiradev/repository/moira/reg_svr/kerberos.c,v 1.8 2005-08-09 19:45:27 zacheiss Exp $");
43
44extern char *hostname, *shorthostname;
45
46#ifdef KRB5
47long init_kerberos(void)
48{
49  krb5_error_code code;
50
51  /* Initialize Kerberos stuff. */
52  code = krb5_init_context(&context);
53  if (code)
54    return code;
55  krb_set_tkt_string("/tmp/tkt_ureg");
56  return 0;
57}
58
59/* Check the kerberos database to see if a principal exists */
60long check_kerberos(char *username)
61{
62  krb5_error_code code;
63  krb5_creds creds;
64  krb5_data *realm;
65  krb5_timestamp now;
66#ifdef KERBEROS_TEST_REALM
67  char ubuf[256];
68
69  sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM);
70  username = ubuf;
71#endif
72
73  memset(&creds, 0, sizeof(creds));
74  code = krb5_parse_name(context, username, &creds.client);
75  if (code)
76    goto cleanup;
77
78  realm = krb5_princ_realm(context, creds.client);
79  code = krb5_build_principal_ext(context, &creds.server,
80                                  realm->length, realm->data,
81                                  KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
82                                  realm->length, realm->data, 0);
83  if (code)
84    goto cleanup;
85
86  code = krb5_timeofday(context, &now);
87  if (code)
88    goto cleanup;
89
90  creds.times.starttime = 0;
91  creds.times.endtime = now + 60;
92
93  code = krb5_get_in_tkt_with_password(context,
94                                       0    /* options */,
95                                       NULL /* addrs */,
96                                       NULL /* ktypes */,
97                                       NULL /* pre_auth_types */,
98                                       "x"  /* password */,
99                                       NULL /* ccache */,
100                                       &creds,
101                                       NULL /* ret_as_reply */);
102
103cleanup:
104  krb5_free_principal(context, creds.client);
105  krb5_free_principal(context, creds.server);
106
107  if (code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN)
108    return MR_SUCCESS;
109  else
110    return MR_IN_USE;
111}
112
113/* Create a new principal in Kerberos */
114long register_kerberos(char *username, char *password)
115{
116  void *kadm_server_handle = NULL;
117  kadm5_ret_t status;
118  kadm5_principal_ent_rec princ;
119  kadm5_policy_ent_rec defpol;
120  kadm5_config_params realm_params;
121  char admin_princ[256];
122  long mask = 0;
123#ifdef KERBEROS_TEST_REALM
124  char ubuf[256];
125
126  sprintf(admin_princ, "moira/%s@%s", hostname, KERBEROS_TEST_REALM);
127  sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM);
128  username = ubuf;
129  realm_params.realm = KERBEROS_TEST_REALM;
130  realm_params.mask = KADM5_CONFIG_REALM;
131#else
132  strcpy(admin_princ, REG_SVR_PRINCIPAL);
133  realm_params.mask = 0;
134#endif
135
136  memset(&princ, 0, sizeof(princ));
137
138  status = krb5_parse_name(context, username, &(princ.principal));
139  if (status)
140    return status;
141
142
143  status = kadm5_init_with_skey(admin_princ, NULL, KADM5_ADMIN_SERVICE,
144                                &realm_params, KADM5_STRUCT_VERSION,
145                                KADM5_API_VERSION_2, &kadm_server_handle);
146  if (status)
147    goto cleanup;
148
149  /* Assign "default" policy if it exists. */
150  if (!kadm5_get_policy(kadm_server_handle, "default", &defpol))
151    {
152      princ.policy = "default";
153      mask |= KADM5_POLICY;
154      (void) kadm5_free_policy_ent(kadm_server_handle, &defpol);
155    }
156
157  mask |= KADM5_PRINCIPAL;
158  status = kadm5_create_principal(kadm_server_handle, &princ, mask, password);
159
160cleanup:
161  krb5_free_principal(context, princ.principal);
162  if (kadm_server_handle)
163    kadm5_destroy(kadm_server_handle);
164
165  if (status == KADM5_DUP)
166    return MR_IN_USE;
167  else if (status == KADM5_PASS_Q_TOOSHORT ||
168           status == KADM5_PASS_Q_CLASS ||
169           status == KADM5_PASS_Q_DICT)
170    return MR_QUALITY;
171  else return status;
172}
173#endif
174
175#ifdef KRB4
176char realm[REALM_SZ];
177
178long init_kerberos(void)
179{
180  return krb_get_lrealm(realm, 1);
181}
182
183long check_kerberos(char *username)
184{
185  long status;
186
187  status = krb_get_pw_in_tkt(username, "", realm, "krbtgt", realm, 1, "");
188  if (status == KDC_PR_UNKNOWN)
189    return MR_SUCCESS;
190  else
191    return MR_IN_USE;
192}
193
194long register_kerberos(char *username, char *password)
195{
196  long status;
197  Kadm_vals new;
198  des_cblock key;
199  unsigned long *lkey = (unsigned long *)key;
200
201  if ((status = krb_get_svc_in_tkt(MOIRA_SNAME, shorthostname, realm,
202                                   PWSERV_NAME, KADM_SINST, 3, KEYFILE)))
203    return status;
204
205  if ((status = kadm_init_link(PWSERV_NAME, KADM_SINST, realm)) !=
206      KADM_SUCCESS)
207    return status;
208
209  memset(&new, 0, sizeof(new));
210  SET_FIELD(KADM_DESKEY, new.fields);
211  SET_FIELD(KADM_NAME, new.fields);
212
213  des_string_to_key(password, key);
214  new.key_low = htonl(lkey[0]);
215  new.key_high = htonl(lkey[1]);
216  strcpy(new.name, username);
217
218  status = kadm_add(&new);
219  memset(&new, 0, sizeof(new));
220  dest_tkt();
221
222  if (status == KADM_INUSE)
223    return MR_IN_USE;
224  else
225    return status;
226}
227#endif
Note: See TracBrowser for help on using the repository browser.