]>
Commit | Line | Data |
---|---|---|
b50f996d | 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 | ||
82b8c4ba | 24 | #define KRB5_DEPRECATED 1 |
25 | #define KRB5_PRIVATE 1 | |
26 | ||
b50f996d | 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> | |
b50f996d | 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; | |
4c77ba27 | 118 | kadm5_policy_ent_rec defpol; |
b50f996d | 119 | kadm5_config_params realm_params; |
120 | char admin_princ[256]; | |
4c77ba27 | 121 | long mask = 0; |
b50f996d | 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 | |
c0716da3 | 131 | strcpy(admin_princ, REG_SVR_PRINCIPAL); |
b50f996d | 132 | realm_params.mask = 0; |
133 | #endif | |
134 | ||
4c77ba27 | 135 | memset(&princ, 0, sizeof(princ)); |
136 | ||
b50f996d | 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 | ||
4c77ba27 | 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); | |
b50f996d | 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; | |
9c0c1480 | 166 | else if (status == KADM5_PASS_Q_TOOSHORT || |
167 | status == KADM5_PASS_Q_CLASS || | |
168 | status == KADM5_PASS_Q_DICT) | |
169 | return MR_QUALITY; | |
b50f996d | 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, | |
8e2c32b2 | 201 | PWSERV_NAME, KADM_SINST, 3, KEYFILE))) |
b50f996d | 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 |