]> andersk Git - moira.git/blob - reg_svr/kerberos.c
Build without krb4 if it's unavailable.
[moira.git] / reg_svr / kerberos.c
1 /* $Id$
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
38 krb5_context context;
39 #endif
40
41 RCSID("$Header$");
42
43 extern char *hostname, *shorthostname;
44
45 #ifdef KRB5
46 long 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 */
59 long 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
102 cleanup:
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 */
113 long 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, &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
159 cleanup:
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
175 char realm[REALM_SZ];
176
177 long init_kerberos(void)
178 {
179   return krb_get_lrealm(realm, 1);
180 }
181
182 long 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
193 long 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
This page took 0.120954 seconds and 5 git commands to generate.