]>
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 | ||
24 | #ifdef KRB4 | |
25 | #include <des.h> | |
26 | #include <kadm.h> | |
27 | #include <kadm_err.h> | |
28 | #include <krb.h> | |
29 | #endif | |
30 | ||
31 | #ifdef KRB5 | |
32 | #include <kadm5/admin.h> | |
33 | #include <krb5.h> | |
34 | #include <krb.h> | |
35 | ||
36 | krb5_context context; | |
37 | #endif | |
38 | ||
39 | RCSID("$Header$"); | |
40 | ||
41 | extern char *hostname, *shorthostname; | |
42 | ||
43 | #ifdef KRB5 | |
44 | long init_kerberos(void) | |
45 | { | |
46 | krb5_error_code code; | |
47 | ||
48 | /* Initialize Kerberos stuff. */ | |
49 | code = krb5_init_context(&context); | |
50 | if (code) | |
51 | return code; | |
52 | krb_set_tkt_string("/tmp/tkt_ureg"); | |
53 | return 0; | |
54 | } | |
55 | ||
56 | /* Check the kerberos database to see if a principal exists */ | |
57 | long check_kerberos(char *username) | |
58 | { | |
59 | krb5_error_code code; | |
60 | krb5_creds creds; | |
61 | krb5_data *realm; | |
62 | krb5_timestamp now; | |
63 | #ifdef KERBEROS_TEST_REALM | |
64 | char ubuf[256]; | |
65 | ||
66 | sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM); | |
67 | username = ubuf; | |
68 | #endif | |
69 | ||
70 | memset(&creds, 0, sizeof(creds)); | |
71 | code = krb5_parse_name(context, username, &creds.client); | |
72 | if (code) | |
73 | goto cleanup; | |
74 | ||
75 | realm = krb5_princ_realm(context, creds.client); | |
76 | code = krb5_build_principal_ext(context, &creds.server, | |
77 | realm->length, realm->data, | |
78 | KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, | |
79 | realm->length, realm->data, 0); | |
80 | if (code) | |
81 | goto cleanup; | |
82 | ||
83 | code = krb5_timeofday(context, &now); | |
84 | if (code) | |
85 | goto cleanup; | |
86 | ||
87 | creds.times.starttime = 0; | |
88 | creds.times.endtime = now + 60; | |
89 | ||
90 | code = krb5_get_in_tkt_with_password(context, | |
91 | 0 /* options */, | |
92 | NULL /* addrs */, | |
93 | NULL /* ktypes */, | |
94 | NULL /* pre_auth_types */, | |
95 | "x" /* password */, | |
96 | NULL /* ccache */, | |
97 | &creds, | |
98 | NULL /* ret_as_reply */); | |
99 | ||
100 | cleanup: | |
101 | krb5_free_principal(context, creds.client); | |
102 | krb5_free_principal(context, creds.server); | |
103 | ||
104 | if (code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN) | |
105 | return MR_SUCCESS; | |
106 | else | |
107 | return MR_IN_USE; | |
108 | } | |
109 | ||
110 | /* Create a new principal in Kerberos */ | |
111 | long register_kerberos(char *username, char *password) | |
112 | { | |
113 | void *kadm_server_handle = NULL; | |
114 | kadm5_ret_t status; | |
115 | kadm5_principal_ent_rec princ; | |
116 | kadm5_config_params realm_params; | |
117 | char admin_princ[256]; | |
118 | #ifdef KERBEROS_TEST_REALM | |
119 | char ubuf[256]; | |
120 | ||
121 | sprintf(admin_princ, "moira/%s@%s", hostname, KERBEROS_TEST_REALM); | |
122 | sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM); | |
123 | username = ubuf; | |
124 | realm_params.realm = KERBEROS_TEST_REALM; | |
125 | realm_params.mask = KADM5_CONFIG_REALM; | |
126 | #else | |
c0716da3 | 127 | strcpy(admin_princ, REG_SVR_PRINCIPAL); |
b50f996d | 128 | realm_params.mask = 0; |
129 | #endif | |
130 | ||
131 | status = krb5_parse_name(context, username, &(princ.principal)); | |
132 | if (status) | |
133 | return status; | |
134 | ||
135 | ||
136 | status = kadm5_init_with_skey(admin_princ, NULL, KADM5_ADMIN_SERVICE, | |
137 | &realm_params, KADM5_STRUCT_VERSION, | |
138 | KADM5_API_VERSION_2, &kadm_server_handle); | |
139 | if (status) | |
140 | goto cleanup; | |
141 | ||
142 | status = kadm5_create_principal(kadm_server_handle, &princ, | |
143 | KADM5_PRINCIPAL, password); | |
144 | ||
145 | cleanup: | |
146 | krb5_free_principal(context, princ.principal); | |
147 | if (kadm_server_handle) | |
148 | kadm5_destroy(kadm_server_handle); | |
149 | ||
150 | if (status == KADM5_DUP) | |
151 | return MR_IN_USE; | |
152 | else return status; | |
153 | } | |
154 | #endif | |
155 | ||
156 | #ifdef KRB4 | |
157 | char realm[REALM_SZ]; | |
158 | ||
159 | long init_kerberos(void) | |
160 | { | |
161 | return krb_get_lrealm(realm, 1); | |
162 | } | |
163 | ||
164 | long check_kerberos(char *username) | |
165 | { | |
166 | long status; | |
167 | ||
168 | status = krb_get_pw_in_tkt(username, "", realm, "krbtgt", realm, 1, ""); | |
169 | if (status == KDC_PR_UNKNOWN) | |
170 | return MR_SUCCESS; | |
171 | else | |
172 | return MR_IN_USE; | |
173 | } | |
174 | ||
175 | long register_kerberos(char *username, char *password) | |
176 | { | |
177 | long status; | |
178 | Kadm_vals new; | |
179 | des_cblock key; | |
180 | unsigned long *lkey = (unsigned long *)key; | |
181 | ||
182 | if ((status = krb_get_svc_in_tkt(MOIRA_SNAME, shorthostname, realm, | |
183 | PWSERV_NAME, KADM_SINST, 1, KEYFILE))) | |
184 | return status; | |
185 | ||
186 | if ((status = kadm_init_link(PWSERV_NAME, KADM_SINST, realm)) != | |
187 | KADM_SUCCESS) | |
188 | return status; | |
189 | ||
190 | memset(&new, 0, sizeof(new)); | |
191 | SET_FIELD(KADM_DESKEY, new.fields); | |
192 | SET_FIELD(KADM_NAME, new.fields); | |
193 | ||
194 | des_string_to_key(password, key); | |
195 | new.key_low = htonl(lkey[0]); | |
196 | new.key_high = htonl(lkey[1]); | |
197 | strcpy(new.name, username); | |
198 | ||
199 | status = kadm_add(&new); | |
200 | memset(&new, 0, sizeof(new)); | |
201 | dest_tkt(); | |
202 | ||
203 | if (status == KADM_INUSE) | |
204 | return MR_IN_USE; | |
205 | else | |
206 | return status; | |
207 | } | |
208 | #endif |