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

Revision 24319, 5.1 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: kerberos.c 3956 2010-01-05 20:56:56Z zacheiss $
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
38krb5_context context;
39#endif
40
41RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/reg_svr/kerberos.c $ $Id: kerberos.c 3956 2010-01-05 20:56:56Z zacheiss $");
42
43extern char *hostname, *shorthostname;
44
45#ifdef KRB5
46long init_kerberos(void)
47{
48  krb5_error_code code;
49
50  /* Initialize Kerberos stuff. */
51  code = krb5_init_context(&context);
52  if (code)
53    return code;
54  krb_set_tkt_string("/tmp/tkt_ureg");
55  return 0;
56}
57
58/* Check the kerberos database to see if a principal exists */
59long check_kerberos(char *username)
60{
61  krb5_error_code code;
62  krb5_creds creds;
63  krb5_data *realm;
64  krb5_timestamp now;
65#ifdef KERBEROS_TEST_REALM
66  char ubuf[256];
67
68  sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM);
69  username = ubuf;
70#endif
71
72  memset(&creds, 0, sizeof(creds));
73  code = krb5_parse_name(context, username, &creds.client);
74  if (code)
75    goto cleanup;
76
77  realm = krb5_princ_realm(context, creds.client);
78  code = krb5_build_principal_ext(context, &creds.server,
79                                  realm->length, realm->data,
80                                  KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
81                                  realm->length, realm->data, 0);
82  if (code)
83    goto cleanup;
84
85  code = krb5_timeofday(context, &now);
86  if (code)
87    goto cleanup;
88
89  creds.times.starttime = 0;
90  creds.times.endtime = now + 60;
91
92  code = krb5_get_in_tkt_with_password(context,
93                                       0    /* options */,
94                                       NULL /* addrs */,
95                                       NULL /* ktypes */,
96                                       NULL /* pre_auth_types */,
97                                       "x"  /* password */,
98                                       NULL /* ccache */,
99                                       &creds,
100                                       NULL /* ret_as_reply */);
101
102cleanup:
103  krb5_free_principal(context, creds.client);
104  krb5_free_principal(context, creds.server);
105
106  if (code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN)
107    return MR_SUCCESS;
108  else
109    return MR_IN_USE;
110}
111
112/* Create a new principal in Kerberos */
113long register_kerberos(char *username, char *password)
114{
115  void *kadm_server_handle = NULL;
116  kadm5_ret_t status;
117  kadm5_principal_ent_rec princ;
118  kadm5_policy_ent_rec defpol;
119  kadm5_config_params realm_params;
120  char admin_princ[256];
121  long mask = 0;
122#ifdef KERBEROS_TEST_REALM
123  char ubuf[256];
124
125  sprintf(admin_princ, "moira/%s@%s", hostname, KERBEROS_TEST_REALM);
126  sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM);
127  username = ubuf;
128  realm_params.realm = KERBEROS_TEST_REALM;
129  realm_params.mask = KADM5_CONFIG_REALM;
130#else
131  strcpy(admin_princ, REG_SVR_PRINCIPAL);
132  realm_params.mask = 0;
133#endif
134
135  memset(&princ, 0, sizeof(princ));
136
137  status = krb5_parse_name(context, username, &(princ.principal));
138  if (status)
139    return status;
140
141
142  status = kadm5_init_with_skey(admin_princ, NULL, KADM5_ADMIN_SERVICE,
143                                &realm_params, KADM5_STRUCT_VERSION,
144                                KADM5_API_VERSION_2, NULL, &kadm_server_handle);
145  if (status)
146    goto cleanup;
147
148  /* Assign "default" policy if it exists. */
149  if (!kadm5_get_policy(kadm_server_handle, "default", &defpol))
150    {
151      princ.policy = "default";
152      mask |= KADM5_POLICY;
153      (void) kadm5_free_policy_ent(kadm_server_handle, &defpol);
154    }
155
156  mask |= KADM5_PRINCIPAL;
157  status = kadm5_create_principal(kadm_server_handle, &princ, mask, password);
158
159cleanup:
160  krb5_free_principal(context, princ.principal);
161  if (kadm_server_handle)
162    kadm5_destroy(kadm_server_handle);
163
164  if (status == KADM5_DUP)
165    return MR_IN_USE;
166  else if (status == KADM5_PASS_Q_TOOSHORT ||
167           status == KADM5_PASS_Q_CLASS ||
168           status == KADM5_PASS_Q_DICT)
169    return MR_QUALITY;
170  else return status;
171}
172#endif
173
174#ifdef KRB4
175char realm[REALM_SZ];
176
177long init_kerberos(void)
178{
179  return krb_get_lrealm(realm, 1);
180}
181
182long check_kerberos(char *username)
183{
184  long status;
185
186  status = krb_get_pw_in_tkt(username, "", realm, "krbtgt", realm, 1, "");
187  if (status == KDC_PR_UNKNOWN)
188    return MR_SUCCESS;
189  else
190    return MR_IN_USE;
191}
192
193long register_kerberos(char *username, char *password)
194{
195  long status;
196  Kadm_vals new;
197  des_cblock key;
198  unsigned long *lkey = (unsigned long *)key;
199
200  if ((status = krb_get_svc_in_tkt(MOIRA_SNAME, shorthostname, realm,
201                                   PWSERV_NAME, KADM_SINST, 3, KEYFILE)))
202    return status;
203
204  if ((status = kadm_init_link(PWSERV_NAME, KADM_SINST, realm)) !=
205      KADM_SUCCESS)
206    return status;
207
208  memset(&new, 0, sizeof(new));
209  SET_FIELD(KADM_DESKEY, new.fields);
210  SET_FIELD(KADM_NAME, new.fields);
211
212  des_string_to_key(password, key);
213  new.key_low = htonl(lkey[0]);
214  new.key_high = htonl(lkey[1]);
215  strcpy(new.name, username);
216
217  status = kadm_add(&new);
218  memset(&new, 0, sizeof(new));
219  dest_tkt();
220
221  if (status == KADM_INUSE)
222    return MR_IN_USE;
223  else
224    return status;
225}
226#endif
Note: See TracBrowser for help on using the repository browser.