1 | /* |
---|
2 | * kadm_cli_wrap.c |
---|
3 | * |
---|
4 | * Copyright 1988 by the Massachusetts Institute of Technology. |
---|
5 | * |
---|
6 | * For copying and distribution information, please see the file |
---|
7 | * <mit-copyright.h>. |
---|
8 | * |
---|
9 | * Kerberos administration server client-side routines |
---|
10 | * The client side wrapping of the calls to the admin server. |
---|
11 | */ |
---|
12 | |
---|
13 | #include <mit-copyright.h> |
---|
14 | |
---|
15 | #include <string.h> |
---|
16 | |
---|
17 | #define DEFINE_SOCKADDR /* Ask krb.h for struct sockaddr, netdb, etc */ |
---|
18 | #include "krb.h" |
---|
19 | |
---|
20 | #include <kadm.h> |
---|
21 | #include <kadm_err.h> |
---|
22 | #include <krb_err.h> |
---|
23 | #include <krbports.h> |
---|
24 | |
---|
25 | #ifndef NULL |
---|
26 | #define NULL 0 |
---|
27 | #endif |
---|
28 | |
---|
29 | #ifndef KRB_INT32 |
---|
30 | #define KRB_INT32 KRB4_32 |
---|
31 | #endif |
---|
32 | |
---|
33 | Kadm_Client client_parm; |
---|
34 | int default_client_port = 1; |
---|
35 | |
---|
36 | /* Macros for use in returning data... used in kadm_cli_send */ |
---|
37 | #define RET_N_FREE(r) {clear_secrets(); free((char *)act_st); free((char *)priv_pak); return r;} |
---|
38 | |
---|
39 | /* Keys for use in the transactions */ |
---|
40 | static des_cblock sess_key; /* to be filled in by kadm_cli_keyd */ |
---|
41 | static Key_schedule sess_sched; |
---|
42 | |
---|
43 | static void |
---|
44 | clear_secrets() |
---|
45 | { |
---|
46 | memset((char *)sess_key, 0, sizeof(sess_key)); |
---|
47 | memset((char *)sess_sched, 0, sizeof(sess_sched)); |
---|
48 | return; |
---|
49 | } |
---|
50 | |
---|
51 | /* |
---|
52 | * kadm_init_link |
---|
53 | * receives : name, inst, realm |
---|
54 | * |
---|
55 | * initializes client parm, the Kadm_Client structure which holds the |
---|
56 | * data about the connection between the server and client, the services |
---|
57 | * used, the locations and other fun things |
---|
58 | */ |
---|
59 | int INTERFACE |
---|
60 | kadm_init_link(n, i, r) |
---|
61 | char n[]; |
---|
62 | char i[]; |
---|
63 | char r[]; |
---|
64 | { |
---|
65 | struct servent *sep; /* service we will talk to */ |
---|
66 | u_short sep_port; |
---|
67 | struct hostent *hop; /* host we will talk to */ |
---|
68 | char adm_hostname[MAXHOSTNAMELEN]; |
---|
69 | char *scol = 0; |
---|
70 | |
---|
71 | #ifdef GLOBAL_ERROR_HANDLING |
---|
72 | (void) init_kadm_err_tbl(); |
---|
73 | (void) init_krb_err_tbl(); |
---|
74 | #endif |
---|
75 | |
---|
76 | (void) strcpy(client_parm.sname, n); |
---|
77 | (void) strcpy(client_parm.sinst, i); |
---|
78 | (void) strcpy(client_parm.krbrlm, r); |
---|
79 | client_parm.admin_fd = -1; |
---|
80 | |
---|
81 | /* set up the admin_addr - fetch name of admin host */ |
---|
82 | if (krb_get_admhst(adm_hostname, client_parm.krbrlm, 1) != KSUCCESS) |
---|
83 | return KADM_NO_HOST; |
---|
84 | scol = strchr(adm_hostname,':'); |
---|
85 | if (scol) *scol = 0; |
---|
86 | if ((hop = gethostbyname(adm_hostname)) == NULL) |
---|
87 | return KADM_UNK_HOST; /* couldnt find the admin servers |
---|
88 | * address */ |
---|
89 | if (scol) { |
---|
90 | sep_port = htons(atoi(scol+1)+1); |
---|
91 | default_client_port = 0; |
---|
92 | } |
---|
93 | else if (sep = getservbyname(KADM_SNAME, "tcp")) |
---|
94 | sep_port = sep->s_port; |
---|
95 | else |
---|
96 | sep_port = htons(KADM_PORT); /* KADM_SNAME = kerberos_master/tcp */ |
---|
97 | memset((char *) &client_parm.admin_addr, 0, |
---|
98 | sizeof(client_parm.admin_addr)); |
---|
99 | client_parm.admin_addr.sin_family = hop->h_addrtype; |
---|
100 | memcpy((char *) &client_parm.admin_addr.sin_addr, (char *) hop->h_addr, |
---|
101 | hop->h_length); |
---|
102 | client_parm.admin_addr.sin_port = sep_port; |
---|
103 | |
---|
104 | return KADM_SUCCESS; |
---|
105 | } /* procedure kadm_init_link */ |
---|
106 | |
---|
107 | /* |
---|
108 | * kadm_change_pw |
---|
109 | * receives : key |
---|
110 | * |
---|
111 | * Replaces the password (i.e. des key) of the caller with that specified in |
---|
112 | * key. Returns no actual data from the master server, since this is called |
---|
113 | * by a user |
---|
114 | */ |
---|
115 | int INTERFACE |
---|
116 | kadm_change_pw(newkey) |
---|
117 | des_cblock newkey; /* The DES form of the users key */ |
---|
118 | { |
---|
119 | u_char *ret_st; |
---|
120 | int retval; |
---|
121 | |
---|
122 | retval = kadm_change_pw2(newkey, (char *)0, &ret_st); |
---|
123 | if (ret_st) |
---|
124 | free(ret_st); |
---|
125 | return(retval); |
---|
126 | } |
---|
127 | |
---|
128 | /* |
---|
129 | * kadm_change_pw2 |
---|
130 | * recieves : key, pw_string, ret_string |
---|
131 | * |
---|
132 | * Replaces the password (i.e. des key) of the caller with that specified in |
---|
133 | * key. Returns no actual data from the master server, since this is called |
---|
134 | * by a user |
---|
135 | */ |
---|
136 | int INTERFACE |
---|
137 | kadm_change_pw2(newkey, pwstring, retstring) |
---|
138 | des_cblock newkey; /* The DES form of the users key */ |
---|
139 | char *pwstring; |
---|
140 | u_char **retstring; |
---|
141 | { |
---|
142 | int stsize, retc; /* stream size and return code */ |
---|
143 | u_char *send_st; /* send stream */ |
---|
144 | u_char *ret_st; |
---|
145 | int ret_sz; |
---|
146 | unsigned KRB_INT32 keytmp; |
---|
147 | extern char *malloc(); |
---|
148 | |
---|
149 | *retstring = (u_char *) 0; |
---|
150 | |
---|
151 | if ((retc = kadm_cli_conn()) != KADM_SUCCESS) |
---|
152 | return(retc); |
---|
153 | /* possible problem with vts_long on a non-multiple of four boundary */ |
---|
154 | |
---|
155 | stsize = 0; /* start of our output packet */ |
---|
156 | send_st = (u_char *) malloc(1);/* to make it reallocable */ |
---|
157 | send_st[stsize++] = (u_char) CHANGE_PW; |
---|
158 | |
---|
159 | /* change key to stream */ |
---|
160 | |
---|
161 | memcpy((char *) &keytmp, (char *) (((KRB_INT32 *) newkey) + 1), sizeof(KRB_INT32)); |
---|
162 | keytmp = htonl(keytmp); |
---|
163 | stsize += vts_long(keytmp, &send_st, stsize); |
---|
164 | |
---|
165 | memcpy((char *) &keytmp, (char *) newkey, sizeof(KRB_INT32)); |
---|
166 | keytmp = htonl(keytmp); |
---|
167 | stsize += vts_long(keytmp, &send_st, stsize); |
---|
168 | |
---|
169 | if (pwstring) { |
---|
170 | stsize += vts_string(pwstring, &send_st, stsize); |
---|
171 | } |
---|
172 | |
---|
173 | retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz); |
---|
174 | free((char *)send_st); |
---|
175 | if (ret_sz) |
---|
176 | *retstring = ret_st; |
---|
177 | else { |
---|
178 | *retstring = 0; |
---|
179 | free(ret_st); |
---|
180 | } |
---|
181 | kadm_cli_disconn(); |
---|
182 | return(retc); |
---|
183 | } |
---|
184 | |
---|
185 | /* |
---|
186 | * kadm_add |
---|
187 | * receives : vals |
---|
188 | * returns : vals |
---|
189 | * |
---|
190 | * Adds an entry containing values to the database returns the values of the |
---|
191 | * entry, so if you leave certain fields blank you will be able to determine |
---|
192 | * the default values they are set to |
---|
193 | */ |
---|
194 | kadm_add(vals) |
---|
195 | Kadm_vals *vals; |
---|
196 | { |
---|
197 | u_char *st, *st2; /* st will hold the stream of values */ |
---|
198 | int st_len; /* st2 the final stream with opcode */ |
---|
199 | int retc; /* return code from call */ |
---|
200 | u_char *ret_st; |
---|
201 | int ret_sz; |
---|
202 | extern char *malloc(); |
---|
203 | |
---|
204 | if ((retc = kadm_cli_conn()) != KADM_SUCCESS) |
---|
205 | return(retc); |
---|
206 | st_len = vals_to_stream(vals, &st); |
---|
207 | st2 = (u_char *) malloc((unsigned)(1 + st_len)); |
---|
208 | *st2 = (u_char) ADD_ENT; /* here's the opcode */ |
---|
209 | memcpy((char *) st2 + 1, (char *) st, st_len); /* append st on */ |
---|
210 | retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz); |
---|
211 | free((char *)st); |
---|
212 | free((char *)st2); |
---|
213 | if (retc == KADM_SUCCESS) { |
---|
214 | /* ret_st has vals */ |
---|
215 | if (stream_to_vals(ret_st, vals, ret_sz) < 0) |
---|
216 | retc = KADM_LENGTH_ERROR; |
---|
217 | free((char *)ret_st); |
---|
218 | } |
---|
219 | kadm_cli_disconn(); |
---|
220 | return(retc); |
---|
221 | } |
---|
222 | |
---|
223 | /* |
---|
224 | * kadm_delete |
---|
225 | * receives : vals |
---|
226 | * returns : vals |
---|
227 | * |
---|
228 | * Deletes an entry containing values from the database. |
---|
229 | */ |
---|
230 | kadm_delete(vals) |
---|
231 | Kadm_vals *vals; |
---|
232 | { |
---|
233 | u_char *st, *st2; /* st will hold the stream of values */ |
---|
234 | int st_len; /* st2 the final stream with opcode */ |
---|
235 | int retc; /* return code from call */ |
---|
236 | u_char *ret_st; |
---|
237 | int ret_sz; |
---|
238 | extern char *malloc(); |
---|
239 | |
---|
240 | if ((retc = kadm_cli_conn()) != KADM_SUCCESS) |
---|
241 | return(retc); |
---|
242 | st_len = vals_to_stream(vals, &st); |
---|
243 | st2 = (u_char *) malloc((unsigned)(1 + st_len)); |
---|
244 | *st2 = (u_char) DEL_ENT; /* here's the opcode */ |
---|
245 | memcpy((char *) st2 + 1, (char *) st, st_len); /* append st on */ |
---|
246 | retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz); |
---|
247 | free((char *)st); |
---|
248 | free((char *)st2); |
---|
249 | if (retc == KADM_SUCCESS) { |
---|
250 | /* ret_st has vals */ |
---|
251 | if (stream_to_vals(ret_st, vals, ret_sz) < 0) |
---|
252 | retc = KADM_LENGTH_ERROR; |
---|
253 | free((char *)ret_st); |
---|
254 | } |
---|
255 | kadm_cli_disconn(); |
---|
256 | return(retc); |
---|
257 | } |
---|
258 | /* |
---|
259 | * kadm_mod |
---|
260 | * receives : KTEXT, {values, values} |
---|
261 | * returns : CKSUM, RETCODE, {values} |
---|
262 | * acl : su, sms (as register or dealloc) |
---|
263 | * |
---|
264 | * Modifies all entries corresponding to the first values so they match the |
---|
265 | * second values. returns the values for the changed entries in vals2 |
---|
266 | */ |
---|
267 | int kadm_mod(vals1, vals2) |
---|
268 | Kadm_vals *vals1; |
---|
269 | Kadm_vals *vals2; |
---|
270 | { |
---|
271 | u_char *st, *st2; /* st will hold the stream of values */ |
---|
272 | int st_len, nlen; /* st2 the final stream with opcode */ |
---|
273 | u_char *ret_st; |
---|
274 | int ret_sz; |
---|
275 | extern char *malloc(); |
---|
276 | extern char *realloc(); |
---|
277 | |
---|
278 | /* nlen is the length of second vals */ |
---|
279 | int retc; /* return code from call */ |
---|
280 | |
---|
281 | if ((retc = kadm_cli_conn()) != KADM_SUCCESS) |
---|
282 | return(retc); |
---|
283 | |
---|
284 | st_len = vals_to_stream(vals1, &st); |
---|
285 | st2 = (u_char *) malloc((unsigned)(1 + st_len)); |
---|
286 | *st2 = (u_char) MOD_ENT; /* here's the opcode */ |
---|
287 | memcpy((char *) st2 + 1, (char *) st, st_len++); /* append st on */ |
---|
288 | free((char *)st); |
---|
289 | nlen = vals_to_stream(vals2, &st); |
---|
290 | st2 = (u_char *) realloc((char *) st2, (unsigned)(st_len + nlen)); |
---|
291 | memcpy((char *) st2 + st_len, (char *) st, nlen); /* append st on */ |
---|
292 | retc = kadm_cli_send(st2, st_len + nlen, &ret_st, &ret_sz); |
---|
293 | free((char *)st); |
---|
294 | free((char *)st2); |
---|
295 | if (retc == KADM_SUCCESS) { |
---|
296 | /* ret_st has vals */ |
---|
297 | if (stream_to_vals(ret_st, vals2, ret_sz) < 0) |
---|
298 | retc = KADM_LENGTH_ERROR; |
---|
299 | free((char *)ret_st); |
---|
300 | } |
---|
301 | kadm_cli_disconn(); |
---|
302 | return(retc); |
---|
303 | } |
---|
304 | |
---|
305 | /* |
---|
306 | * kadm_get |
---|
307 | * receives : KTEXT, {values, flags} |
---|
308 | * returns : CKSUM, RETCODE, {count, values, values, values} |
---|
309 | * acl : su |
---|
310 | * |
---|
311 | * gets the fields requested by flags from all entries matching values returns |
---|
312 | * this data for each matching recipient, after a count of how many such |
---|
313 | * matches there were |
---|
314 | */ |
---|
315 | int kadm_get(vals, fl) |
---|
316 | Kadm_vals *vals; |
---|
317 | u_char fl[4]; |
---|
318 | { |
---|
319 | int loop; /* for copying the fields data */ |
---|
320 | u_char *st, *st2; /* st will hold the stream of values */ |
---|
321 | int st_len; /* st2 the final stream with opcode */ |
---|
322 | int retc; /* return code from call */ |
---|
323 | u_char *ret_st; |
---|
324 | int ret_sz; |
---|
325 | extern char *malloc(); |
---|
326 | |
---|
327 | if ((retc = kadm_cli_conn()) != KADM_SUCCESS) |
---|
328 | return(retc); |
---|
329 | st_len = vals_to_stream(vals, &st); |
---|
330 | st2 = (u_char *) malloc((unsigned)(1 + st_len + FLDSZ)); |
---|
331 | *st2 = (u_char) GET_ENT; /* here's the opcode */ |
---|
332 | memcpy((char *) st2 + 1, (char *) st, st_len); /* append st on */ |
---|
333 | for (loop = FLDSZ - 1; loop >= 0; loop--) |
---|
334 | *(st2 + st_len + FLDSZ - loop) = fl[loop]; /* append the flags */ |
---|
335 | retc = kadm_cli_send(st2, st_len + 1 + FLDSZ, &ret_st, &ret_sz); |
---|
336 | free((char *)st); |
---|
337 | free((char *)st2); |
---|
338 | if (retc == KADM_SUCCESS) { |
---|
339 | /* ret_st has vals */ |
---|
340 | if (stream_to_vals(ret_st, vals, ret_sz) < 0) |
---|
341 | retc = KADM_LENGTH_ERROR; |
---|
342 | free((char *)ret_st); |
---|
343 | } |
---|
344 | kadm_cli_disconn(); |
---|
345 | return(retc); |
---|
346 | } |
---|
347 | |
---|
348 | /* |
---|
349 | * kadm_check_pw |
---|
350 | * recieves : key, pw_string, ret_string |
---|
351 | * |
---|
352 | * Sends the password to the server and asks it if the password is a |
---|
353 | * "secure" password or not. Returns the error KADM_INSECURE_PW and |
---|
354 | * optionally returns a message if the password is not considered secure. |
---|
355 | */ |
---|
356 | int kadm_check_pw(newkey, pwstring, retstring) |
---|
357 | des_cblock newkey; /* The DES form of the users key */ |
---|
358 | char *pwstring; |
---|
359 | u_char **retstring; |
---|
360 | { |
---|
361 | int stsize, retc; /* stream size and return code */ |
---|
362 | u_char *send_st; /* send stream */ |
---|
363 | u_char *ret_st; |
---|
364 | int ret_sz; |
---|
365 | unsigned KRB_INT32 keytmp; |
---|
366 | extern char *malloc(); |
---|
367 | |
---|
368 | if ((retc = kadm_cli_conn()) != KADM_SUCCESS) |
---|
369 | return(retc); |
---|
370 | /* possible problem with vts_long on a non-multiple of four boundary */ |
---|
371 | |
---|
372 | stsize = 0; /* start of our output packet */ |
---|
373 | send_st = (u_char *) malloc(1);/* to make it reallocable */ |
---|
374 | send_st[stsize++] = (u_char) CHECK_PW; |
---|
375 | |
---|
376 | /* change key to stream */ |
---|
377 | |
---|
378 | memcpy((char *) &keytmp, (char *) (((KRB_INT32 *) newkey) + 1), sizeof(KRB_INT32)); |
---|
379 | keytmp = htonl(keytmp); |
---|
380 | stsize += vts_long(keytmp, &send_st, stsize); |
---|
381 | |
---|
382 | memcpy((char *) &keytmp, (char *) newkey, sizeof(KRB_INT32)); |
---|
383 | keytmp = htonl(keytmp); |
---|
384 | stsize += vts_long(keytmp, &send_st, stsize); |
---|
385 | |
---|
386 | if (pwstring) { |
---|
387 | stsize += vts_string(pwstring, &send_st, stsize); |
---|
388 | } |
---|
389 | |
---|
390 | retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz); |
---|
391 | free((char *)send_st); |
---|
392 | if (ret_sz) |
---|
393 | *retstring = ret_st; |
---|
394 | else { |
---|
395 | *retstring = 0; |
---|
396 | free(ret_st); |
---|
397 | } |
---|
398 | kadm_cli_disconn(); |
---|
399 | return(retc); |
---|
400 | } |
---|
401 | |
---|
402 | /* |
---|
403 | * kadm_change_srvtab |
---|
404 | * receives : name, instance |
---|
405 | * returns : values |
---|
406 | * |
---|
407 | * Asks the admin server to change the srvtab key for the specified |
---|
408 | * name, instance pair. The name, instance pair must be a valid |
---|
409 | * server principal. |
---|
410 | */ |
---|
411 | int kadm_change_srvtab(name, instance, values) |
---|
412 | char *name, *instance; |
---|
413 | Kadm_vals *values; |
---|
414 | { |
---|
415 | u_char *st, *st2; /* st will hold the stream of values */ |
---|
416 | int st_len; /* st2 the final stream with opcode */ |
---|
417 | int retc; /* return code from call */ |
---|
418 | u_char *ret_st; |
---|
419 | int ret_sz; |
---|
420 | Kadm_vals vals; |
---|
421 | extern char *malloc(); |
---|
422 | |
---|
423 | memset((char *) &vals, 0, sizeof(vals)); |
---|
424 | strncpy(vals.name, name, sizeof(vals.name)); |
---|
425 | strncpy(vals.instance, instance, sizeof(vals.instance)); |
---|
426 | SET_FIELD(KADM_NAME,vals.fields); |
---|
427 | SET_FIELD(KADM_INST,vals.fields); |
---|
428 | |
---|
429 | if ((retc = kadm_cli_conn()) != KADM_SUCCESS) |
---|
430 | return(retc); |
---|
431 | st_len = vals_to_stream(&vals, &st); |
---|
432 | st2 = (u_char *) malloc((unsigned)(1 + st_len)); |
---|
433 | *st2 = (u_char) CHG_STAB; /* here's the opcode */ |
---|
434 | memcpy((char *) st2 + 1, (char *) st, st_len); /* append st on */ |
---|
435 | retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz); |
---|
436 | free((char *)st); |
---|
437 | free((char *)st2); |
---|
438 | if (retc == KADM_SUCCESS) { |
---|
439 | /* ret_st has vals */ |
---|
440 | if (stream_to_vals(ret_st, values, ret_sz) < 0) |
---|
441 | retc = KADM_LENGTH_ERROR; |
---|
442 | free((char *)ret_st); |
---|
443 | } |
---|
444 | kadm_cli_disconn(); |
---|
445 | return(retc); |
---|
446 | } |
---|
447 | |
---|
448 | /* |
---|
449 | * kadm_cli_send |
---|
450 | * recieves : opcode, packet, packet length, serv_name, serv_inst |
---|
451 | * returns : return code from the packet build, the server, or |
---|
452 | * something else |
---|
453 | * |
---|
454 | * It assembles a packet as follows: |
---|
455 | * 8 bytes : VERSION STRING |
---|
456 | * 4 bytes : LENGTH OF MESSAGE DATA and OPCODE |
---|
457 | * : KTEXT |
---|
458 | * : OPCODE \ |
---|
459 | * : DATA > Encrypted (with make priv) |
---|
460 | * : ...... / |
---|
461 | * |
---|
462 | * If it builds the packet and it is small enough, then it attempts to open the |
---|
463 | * connection to the admin server. If the connection is succesfully open |
---|
464 | * then it sends the data and waits for a reply. |
---|
465 | */ |
---|
466 | int kadm_cli_send(st_dat, st_siz, ret_dat, ret_siz) |
---|
467 | u_char *st_dat; /* the actual data */ |
---|
468 | int st_siz; /* length of said data */ |
---|
469 | u_char **ret_dat; /* to give return info */ |
---|
470 | int *ret_siz; /* length of returned info */ |
---|
471 | { |
---|
472 | int act_len; /* current offset into packet, return */ |
---|
473 | KRB_INT32 retdat; /* data */ |
---|
474 | KTEXT_ST authent; /* the authenticator we will build */ |
---|
475 | u_char *act_st; /* the pointer to the complete packet */ |
---|
476 | u_char *priv_pak; /* private version of the packet */ |
---|
477 | int priv_len; /* length of private packet */ |
---|
478 | u_long cksum; /* checksum of the packet */ |
---|
479 | MSG_DAT mdat; |
---|
480 | u_char *return_dat; |
---|
481 | extern char *malloc(); |
---|
482 | extern char *realloc(); |
---|
483 | |
---|
484 | act_st = (u_char *) malloc(KADM_VERSIZE); /* verstr stored first */ |
---|
485 | (void) strncpy((char *)act_st, KADM_VERSTR, KADM_VERSIZE); |
---|
486 | act_len = KADM_VERSIZE; |
---|
487 | |
---|
488 | if ((retdat = kadm_cli_keyd(sess_key, sess_sched)) != KADM_SUCCESS) { |
---|
489 | free((char *)act_st); |
---|
490 | return retdat; /* couldnt get key working */ |
---|
491 | } |
---|
492 | priv_pak = (u_char *) malloc((unsigned)(st_siz + 200)); |
---|
493 | /* 200 bytes for extra info case */ |
---|
494 | if ((priv_len = krb_mk_priv(st_dat, priv_pak, (u_long)st_siz, |
---|
495 | sess_sched, &sess_key, &client_parm.my_addr, |
---|
496 | &client_parm.admin_addr)) < 0) |
---|
497 | RET_N_FREE(KADM_NO_ENCRYPT); /* whoops... we got a lose |
---|
498 | * here */ |
---|
499 | /* here is the length of priv data. receiver calcs |
---|
500 | size of authenticator by subtracting vno size, priv size, and |
---|
501 | sizeof(u_long) (for the size indication) from total size */ |
---|
502 | |
---|
503 | act_len += vts_long((unsigned KRB_INT32) priv_len, &act_st, act_len); |
---|
504 | #ifdef NOENCRYPTION |
---|
505 | cksum = 0; |
---|
506 | #else |
---|
507 | cksum = quad_cksum(priv_pak, (unsigned KRB_INT32 *)0, (long)priv_len, |
---|
508 | 0, &sess_key); |
---|
509 | #endif |
---|
510 | if (retdat = krb_mk_req(&authent, client_parm.sname, client_parm.sinst, |
---|
511 | client_parm.krbrlm, (long)cksum)) { |
---|
512 | /* authenticator? */ |
---|
513 | RET_N_FREE(retdat + krb_err_base); |
---|
514 | } |
---|
515 | |
---|
516 | act_st = (u_char *) realloc((char *) act_st, |
---|
517 | (unsigned) (act_len + authent.length |
---|
518 | + priv_len)); |
---|
519 | if (!act_st) { |
---|
520 | clear_secrets(); |
---|
521 | free((char *)priv_pak); |
---|
522 | return(KADM_NOMEM); |
---|
523 | } |
---|
524 | memcpy((char *)act_st + act_len, (char *)authent.dat, authent.length); |
---|
525 | memcpy((char *)act_st + act_len + authent.length, (char *)priv_pak, |
---|
526 | priv_len); |
---|
527 | free((char *)priv_pak); |
---|
528 | if ((retdat = kadm_cli_out(act_st, |
---|
529 | act_len + authent.length + priv_len, |
---|
530 | ret_dat, ret_siz)) != KADM_SUCCESS) |
---|
531 | RET_N_FREE(retdat); |
---|
532 | free((char *)act_st); |
---|
533 | #define RET_N_FREE2(r) {free((char *)*ret_dat); *ret_dat = 0; *ret_siz = 0; clear_secrets(); return(r);} |
---|
534 | |
---|
535 | /* first see if it's a YOULOUSE */ |
---|
536 | if ((*ret_siz >= KADM_VERSIZE) && |
---|
537 | !strncmp(KADM_ULOSE, (char *)*ret_dat, KADM_VERSIZE)) |
---|
538 | { |
---|
539 | unsigned KRB_INT32 errcode; |
---|
540 | /* it's a youlose packet */ |
---|
541 | if (*ret_siz < KADM_VERSIZE + sizeof(unsigned KRB_INT32)) |
---|
542 | RET_N_FREE2(KADM_BAD_VER); |
---|
543 | memcpy((char *)&errcode, (char *)(*ret_dat) + KADM_VERSIZE, |
---|
544 | sizeof(unsigned KRB_INT32)); |
---|
545 | retdat = (int) ntohl(errcode); |
---|
546 | RET_N_FREE2(retdat); |
---|
547 | } |
---|
548 | /* need to decode the ret_dat */ |
---|
549 | if (retdat = krb_rd_priv(*ret_dat, (u_long)*ret_siz, sess_sched, |
---|
550 | &sess_key, &client_parm.admin_addr, |
---|
551 | &client_parm.my_addr, &mdat)) |
---|
552 | RET_N_FREE2(retdat+krb_err_base); |
---|
553 | if (mdat.app_length < KADM_VERSIZE + 4) |
---|
554 | /* too short! */ |
---|
555 | RET_N_FREE2(KADM_BAD_VER); |
---|
556 | if (strncmp((char *)mdat.app_data, KADM_VERSTR, KADM_VERSIZE)) |
---|
557 | /* bad version */ |
---|
558 | RET_N_FREE2(KADM_BAD_VER); |
---|
559 | memcpy((char *)&retdat, (char *)mdat.app_data+KADM_VERSIZE, |
---|
560 | sizeof(unsigned KRB_INT32)); |
---|
561 | retdat = ntohl((u_long)retdat); |
---|
562 | if ((mdat.app_length - KADM_VERSIZE - sizeof(unsigned KRB_INT32)) != 0) { |
---|
563 | if (!(return_dat = (u_char *) |
---|
564 | malloc((unsigned)(mdat.app_length - KADM_VERSIZE - |
---|
565 | sizeof(unsigned KRB_INT32))))) |
---|
566 | RET_N_FREE2(KADM_NOMEM); |
---|
567 | memcpy((char *)return_dat, |
---|
568 | (char *) mdat.app_data + KADM_VERSIZE + sizeof(unsigned KRB_INT32), |
---|
569 | (int)mdat.app_length - KADM_VERSIZE - sizeof(unsigned KRB_INT32)); |
---|
570 | } else { |
---|
571 | /* If it's zero length, still need to malloc a 1 byte string; */ |
---|
572 | /* malloc's of zero will return NULL on AIX & A/UX */ |
---|
573 | if (!(return_dat = (u_char *) malloc((unsigned) 1))) |
---|
574 | RET_N_FREE2(KADM_NOMEM); |
---|
575 | *return_dat = '\0'; |
---|
576 | } |
---|
577 | free((char *)*ret_dat); |
---|
578 | clear_secrets(); |
---|
579 | *ret_dat = return_dat; |
---|
580 | *ret_siz = mdat.app_length - KADM_VERSIZE - sizeof(unsigned KRB_INT32); |
---|
581 | return retdat; |
---|
582 | } |
---|
583 | |
---|
584 | /* takes in the sess_key and key_schedule and sets them appropriately */ |
---|
585 | int kadm_cli_keyd(s_k, s_s) |
---|
586 | des_cblock s_k; /* session key */ |
---|
587 | des_key_schedule s_s; /* session key schedule */ |
---|
588 | { |
---|
589 | CREDENTIALS cred; /* to get key data */ |
---|
590 | int stat; |
---|
591 | |
---|
592 | /* want .sname and .sinst here.... */ |
---|
593 | if (stat = krb_get_cred(client_parm.sname, client_parm.sinst, |
---|
594 | client_parm.krbrlm, &cred)) |
---|
595 | return stat + krb_err_base; |
---|
596 | memcpy((char *) s_k, (char *) cred.session, sizeof(des_cblock)); |
---|
597 | memset((char *) cred.session, 0, sizeof(des_cblock)); |
---|
598 | #ifdef NOENCRYPTION |
---|
599 | memset(s_s, 0, sizeof(des_key_schedule)); |
---|
600 | #else |
---|
601 | if (stat = key_sched(s_k, s_s)) |
---|
602 | return stat + krb_err_base; |
---|
603 | #endif |
---|
604 | return KADM_SUCCESS; |
---|
605 | } /* This code "works" */ |
---|
606 | |
---|
607 | /* Networking-specific routines have been moved out to kadm_net.c. */ |
---|