]>
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> | |
37 | #include <krb.h> | |
38 | ||
39 | krb5_context context; | |
40 | #endif | |
41 | ||
42 | RCSID("$Header$"); | |
43 | ||
44 | extern char *hostname, *shorthostname; | |
45 | ||
46 | #ifdef KRB5 | |
47 | long 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 */ | |
60 | long 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 | ||
103 | cleanup: | |
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 */ | |
114 | long register_kerberos(char *username, char *password) | |
115 | { | |
116 | void *kadm_server_handle = NULL; | |
117 | kadm5_ret_t status; | |
118 | kadm5_principal_ent_rec princ; | |
4c77ba27 | 119 | kadm5_policy_ent_rec defpol; |
b50f996d | 120 | kadm5_config_params realm_params; |
121 | char admin_princ[256]; | |
4c77ba27 | 122 | long mask = 0; |
b50f996d | 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 | |
c0716da3 | 132 | strcpy(admin_princ, REG_SVR_PRINCIPAL); |
b50f996d | 133 | realm_params.mask = 0; |
134 | #endif | |
135 | ||
4c77ba27 | 136 | memset(&princ, 0, sizeof(princ)); |
137 | ||
b50f996d | 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 | ||
4c77ba27 | 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); | |
b50f996d | 159 | |
160 | cleanup: | |
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; | |
9c0c1480 | 167 | else if (status == KADM5_PASS_Q_TOOSHORT || |
168 | status == KADM5_PASS_Q_CLASS || | |
169 | status == KADM5_PASS_Q_DICT) | |
170 | return MR_QUALITY; | |
b50f996d | 171 | else return status; |
172 | } | |
173 | #endif | |
174 | ||
175 | #ifdef KRB4 | |
176 | char realm[REALM_SZ]; | |
177 | ||
178 | long init_kerberos(void) | |
179 | { | |
180 | return krb_get_lrealm(realm, 1); | |
181 | } | |
182 | ||
183 | long 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 | ||
194 | long 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, 1, 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 |