(make_pa_tgs_req): added comment
[heimdal.git] / kdc / kaserver.c
blobfbc75a9df79f085ef84d4bf725357273df37d246
1 /*
2 * Copyright (c) 1997 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
39 #include "kdc_locl.h"
41 RCSID("$Id$");
43 #ifdef KASERVER
45 #include "kerberos4.h"
46 #include <rx.h>
48 #define KA_AUTHENTICATION_SERVICE 731
49 #define KA_TICKET_GRANTING_SERVICE 732
50 #define KA_MAINTENANCE_SERVICE 733
52 #define AUTHENTICATE_OLD 1
53 #define CHANGEPASSWORD 2
54 #define GETTICKET_OLD 3
55 #define SETPASSWORD 4
56 #define SETFIELDS 5
57 #define CREATEUSER 6
58 #define DELETEUSER 7
59 #define GETENTRY 8
60 #define LISTENTRY 9
61 #define GETSTATS 10
62 #define DEBUG 11
63 #define GETPASSWORD 12
64 #define GETRANDOMKEY 13
65 #define AUTHENTICATE 21
66 #define AUTHENTICATE_V2 22
67 #define GETTICKET 23
69 /* XXX - Where do we get these? */
71 #define RXGEN_OPCODE (-455)
73 #define KADATABASEINCONSISTENT (180480L)
74 #define KAEXIST (180481L)
75 #define KAIO (180482L)
76 #define KACREATEFAIL (180483L)
77 #define KANOENT (180484L)
78 #define KAEMPTY (180485L)
79 #define KABADNAME (180486L)
80 #define KABADINDEX (180487L)
81 #define KANOAUTH (180488L)
82 #define KAANSWERTOOLONG (180489L)
83 #define KABADREQUEST (180490L)
84 #define KAOLDINTERFACE (180491L)
85 #define KABADARGUMENT (180492L)
86 #define KABADCMD (180493L)
87 #define KANOKEYS (180494L)
88 #define KAREADPW (180495L)
89 #define KABADKEY (180496L)
90 #define KAUBIKINIT (180497L)
91 #define KAUBIKCALL (180498L)
92 #define KABADPROTOCOL (180499L)
93 #define KANOCELLS (180500L)
94 #define KANOCELL (180501L)
95 #define KATOOMANYUBIKS (180502L)
96 #define KATOOMANYKEYS (180503L)
97 #define KABADTICKET (180504L)
98 #define KAUNKNOWNKEY (180505L)
99 #define KAKEYCACHEINVALID (180506L)
100 #define KABADSERVER (180507L)
101 #define KABADUSER (180508L)
102 #define KABADCPW (180509L)
103 #define KABADCREATE (180510L)
104 #define KANOTICKET (180511L)
105 #define KAASSOCUSER (180512L)
106 #define KANOTSPECIAL (180513L)
107 #define KACLOCKSKEW (180514L)
108 #define KANORECURSE (180515L)
109 #define KARXFAIL (180516L)
110 #define KANULLPASSWORD (180517L)
111 #define KAINTERNALERROR (180518L)
112 #define KAPWEXPIRED (180519L)
113 #define KAREUSED (180520L)
114 #define KATOOSOON (180521L)
115 #define KALOCKED (180522L)
117 static void
118 decode_rx_header (krb5_storage *sp,
119 struct rx_header *h)
121 krb5_ret_int32(sp, &h->epoch);
122 krb5_ret_int32(sp, &h->connid);
123 krb5_ret_int32(sp, &h->callid);
124 krb5_ret_int32(sp, &h->seqno);
125 krb5_ret_int32(sp, &h->serialno);
126 krb5_ret_int8(sp, &h->type);
127 krb5_ret_int8(sp, &h->flags);
128 krb5_ret_int8(sp, &h->status);
129 krb5_ret_int8(sp, &h->secindex);
130 krb5_ret_int16(sp, &h->reserved);
131 krb5_ret_int16(sp, &h->serviceid);
134 static void
135 encode_rx_header (struct rx_header *h,
136 krb5_storage *sp)
138 krb5_store_int32(sp, h->epoch);
139 krb5_store_int32(sp, h->connid);
140 krb5_store_int32(sp, h->callid);
141 krb5_store_int32(sp, h->seqno);
142 krb5_store_int32(sp, h->serialno);
143 krb5_store_int8(sp, h->type);
144 krb5_store_int8(sp, h->flags);
145 krb5_store_int8(sp, h->status);
146 krb5_store_int8(sp, h->secindex);
147 krb5_store_int16(sp, h->reserved);
148 krb5_store_int16(sp, h->serviceid);
151 static void
152 init_reply_header (struct rx_header *hdr,
153 struct rx_header *reply_hdr,
154 u_char type,
155 u_char flags)
157 reply_hdr->epoch = hdr->epoch;
158 reply_hdr->connid = hdr->connid;
159 reply_hdr->callid = hdr->callid;
160 reply_hdr->seqno = 1;
161 reply_hdr->serialno = 1;
162 reply_hdr->type = type;
163 reply_hdr->flags = flags;
164 reply_hdr->status = 0;
165 reply_hdr->secindex = 0;
166 reply_hdr->reserved = 0;
167 reply_hdr->serviceid = hdr->serviceid;
170 static void
171 make_error_reply (struct rx_header *hdr,
172 u_int32_t ret,
173 krb5_data *reply)
176 krb5_storage *sp;
177 struct rx_header reply_hdr;
179 init_reply_header (hdr, &reply_hdr, HT_ABORT, HF_LAST);
180 sp = krb5_storage_emem();
181 encode_rx_header (&reply_hdr, sp);
182 krb5_store_int32(sp, ret);
183 krb5_storage_to_data (sp, reply);
184 krb5_storage_free (sp);
187 static krb5_error_code
188 krb5_ret_xdr_data(krb5_storage *sp,
189 krb5_data *data)
191 int ret;
192 int size;
193 ret = krb5_ret_int32(sp, &size);
194 if(ret)
195 return ret;
196 data->length = size;
197 if (size) {
198 u_char foo[4];
199 size_t pad = (4 - size % 4) % 4;
201 data->data = malloc(size);
202 ret = sp->fetch(sp, data->data, size);
203 if(ret != size)
204 return (ret < 0)? errno : KRB5_CC_END;
205 if (pad) {
206 ret = sp->fetch(sp, foo, pad);
207 if (ret != pad)
208 return (ret < 0)? errno : KRB5_CC_END;
210 } else
211 data->data = NULL;
212 return 0;
215 static krb5_error_code
216 krb5_store_xdr_data(krb5_storage *sp,
217 krb5_data data)
219 u_char zero[4] = {0, 0, 0, 0};
220 int ret;
221 size_t pad;
223 ret = krb5_store_int32(sp, data.length);
224 if(ret < 0)
225 return ret;
226 ret = sp->store(sp, data.data, data.length);
227 if(ret != data.length){
228 if(ret < 0)
229 return errno;
230 return KRB5_CC_END;
232 pad = (4 - data.length % 4) % 4;
233 if (pad) {
234 ret = sp->store(sp, zero, pad);
235 if (ret != pad) {
236 if (ret < 0)
237 return errno;
238 return KRB5_CC_END;
241 return 0;
245 static krb5_error_code
246 create_reply_ticket (struct rx_header *hdr,
247 Key *skey,
248 char *name, char *instance, char *realm,
249 struct sockaddr_in *addr,
250 int life,
251 int kvno,
252 int32_t max_seq_len,
253 char *sname, char *sinstance,
254 u_int32_t challenge,
255 char *label,
256 des_cblock *key,
257 krb5_data *reply)
259 KTEXT_ST ticket;
260 des_cblock session;
261 krb5_storage *sp;
262 krb5_data enc_data;
263 des_key_schedule schedule;
264 struct rx_header reply_hdr;
265 des_cblock zero;
266 size_t pad;
267 unsigned fyrtiosjuelva;
269 /* create the ticket */
271 des_new_random_key(&session);
273 krb_create_ticket (&ticket, 0, name, instance, realm,
274 addr->sin_addr.s_addr,
275 &session, life, kdc_time,
276 sname, sinstance, skey->key.keyvalue.data);
278 /* create the encrypted part of the reply */
279 sp = krb5_storage_emem ();
280 krb5_generate_random_block(&fyrtiosjuelva, sizeof(fyrtiosjuelva));
281 fyrtiosjuelva &= 0xffffffff;
282 krb5_store_int32 (sp, fyrtiosjuelva);
283 #if 0
284 krb5_store_int32 (sp, 4711); /* XXX */
285 #endif
286 krb5_store_int32 (sp, challenge);
287 sp->store (sp, session, 8);
288 memset (&session, 0, sizeof(session));
289 krb5_store_int32 (sp, kdc_time);
290 krb5_store_int32 (sp, kdc_time + krb_life_to_time (0, life));
291 krb5_store_int32 (sp, kvno);
292 krb5_store_int32 (sp, ticket.length);
293 krb5_store_stringz (sp, name);
294 krb5_store_stringz (sp, instance);
295 #if 1 /* XXX - Why shouldn't the realm go here? */
296 krb5_store_stringz (sp, "");
297 #else
298 krb5_store_stringz (sp, realm);
299 #endif
300 krb5_store_stringz (sp, sname);
301 krb5_store_stringz (sp, sinstance);
302 sp->store (sp, ticket.dat, ticket.length);
303 sp->store (sp, label, strlen(label));
305 /* pad to DES block */
306 memset (zero, 0, sizeof(zero));
307 pad = (8 - sp->seek (sp, 0, SEEK_CUR) % 8) % 8;
308 sp->store (sp, zero, pad);
310 krb5_storage_to_data (sp, &enc_data);
311 krb5_storage_free (sp);
313 if (enc_data.length > max_seq_len) {
314 krb5_data_free (&enc_data);
315 make_error_reply (hdr, KAANSWERTOOLONG, reply);
316 return 0;
319 /* encrypt it */
320 des_set_key (key, schedule);
321 des_pcbc_encrypt ((des_cblock *)enc_data.data,
322 (des_cblock *)enc_data.data,
323 enc_data.length,
324 schedule,
325 key,
326 DES_ENCRYPT);
327 memset (&schedule, 0, sizeof(schedule));
329 /* create the reply packet */
330 init_reply_header (hdr, &reply_hdr, HT_DATA, HF_LAST);
331 sp = krb5_storage_emem ();
332 encode_rx_header (&reply_hdr, sp);
333 krb5_store_int32 (sp, max_seq_len);
334 krb5_store_xdr_data (sp, enc_data);
335 krb5_data_free (&enc_data);
336 krb5_storage_to_data (sp, reply);
337 krb5_storage_free (sp);
338 return 0;
341 static krb5_error_code
342 unparse_auth_args (krb5_storage *sp,
343 char **name,
344 char **instance,
345 time_t *start_time,
346 time_t *end_time,
347 krb5_data *request,
348 int32_t *max_seq_len)
350 krb5_data data;
351 int32_t tmp;
353 krb5_ret_xdr_data (sp, &data);
354 *name = malloc(data.length + 1);
355 if (*name == NULL)
356 return ENOMEM;
357 memcpy (*name, data.data, data.length);
358 (*name)[data.length] = '\0';
359 krb5_data_free (&data);
361 krb5_ret_xdr_data (sp, &data);
362 *instance = malloc(data.length + 1);
363 if (*instance == NULL)
364 return ENOMEM;
365 memcpy (*instance, data.data, data.length);
366 (*instance)[data.length] = '\0';
367 krb5_data_free (&data);
369 krb5_ret_int32 (sp, &tmp);
370 *start_time = tmp;
371 krb5_ret_int32 (sp, &tmp);
372 *end_time = tmp;
373 krb5_ret_xdr_data (sp, request);
374 krb5_ret_int32 (sp, max_seq_len);
375 /* ignore the rest */
376 return 0;
379 static void
380 do_authenticate (struct rx_header *hdr,
381 krb5_storage *sp,
382 struct sockaddr_in *addr,
383 krb5_data *reply)
385 krb5_error_code ret;
386 char *name = NULL;
387 char *instance = NULL;
388 time_t start_time;
389 time_t end_time;
390 krb5_data request;
391 int32_t max_seq_len;
392 hdb_entry *client_entry = NULL;
393 hdb_entry *server_entry = NULL;
394 Key *ckey = NULL;
395 Key *skey = NULL;
396 des_cblock key;
397 des_key_schedule schedule;
398 krb5_storage *reply_sp;
399 time_t max_life;
400 u_int8_t life;
401 int32_t chal;
403 krb5_data_zero (&request);
405 unparse_auth_args (sp, &name, &instance, &start_time, &end_time,
406 &request, &max_seq_len);
408 client_entry = db_fetch4 (name, instance, v4_realm);
409 if (client_entry == NULL) {
410 kdc_log(0, "Client not found in database: %s.%s@%s",
411 name, instance, v4_realm);
412 make_error_reply (hdr, KANOENT, reply);
413 goto out;
416 server_entry = db_fetch4 ("krbtgt", v4_realm, v4_realm);
417 if (server_entry == NULL) {
418 kdc_log(0, "Server not found in database: %s.%s@%s",
419 "krbtgt", v4_realm, v4_realm);
420 make_error_reply (hdr, KANOENT, reply);
421 goto out;
424 /* find a DES key */
425 ret = hdb_keytype2key(context, client_entry, KEYTYPE_DES, &ckey);
426 if(ret){
427 kdc_log(0, "%s", krb5_get_err_text(context, ret));
428 make_error_reply (hdr, KANOKEYS, reply);
429 goto out;
432 /* find a DES key */
433 ret = hdb_keytype2key(context, server_entry, KEYTYPE_DES, &skey);
434 if(ret){
435 kdc_log(0, "%s", krb5_get_err_text(context, ret));
436 make_error_reply (hdr, KANOKEYS, reply);
437 goto out;
440 /* try to decode the `request' */
441 memcpy (&key, ckey->key.keyvalue.data, sizeof(key));
442 des_set_key (&key, schedule);
443 des_pcbc_encrypt ((des_cblock *)request.data,
444 (des_cblock *)request.data,
445 request.length,
446 schedule,
447 &key,
448 DES_DECRYPT);
449 memset (&schedule, 0, sizeof(schedule));
451 /* check for the magic label */
452 if (memcmp ((char *)request.data + 4, "gTGS", 4) != 0) {
453 make_error_reply (hdr, KABADREQUEST, reply);
454 goto out;
457 reply_sp = krb5_storage_from_mem (request.data, 4);
458 krb5_ret_int32 (reply_sp, &chal);
459 krb5_storage_free (reply_sp);
461 /* life */
462 max_life = end_time - kdc_time;
463 if (client_entry->max_life)
464 max_life = min(max_life, *client_entry->max_life);
465 if (server_entry->max_life)
466 max_life = min(max_life, *server_entry->max_life);
468 life = krb_time_to_life(kdc_time, kdc_time + max_life);
470 create_reply_ticket (hdr, skey,
471 name, instance, v4_realm,
472 addr, life, client_entry->kvno,
473 max_seq_len,
474 "krbtgt", v4_realm,
475 chal + 1, "tgsT",
476 &key, reply);
477 memset (&key, 0, sizeof(key));
479 out:
480 if (request.length) {
481 memset (request.data, 0, request.length);
482 krb5_data_free (&request);
484 if (name)
485 free (name);
486 if (instance)
487 free (instance);
488 if (client_entry) {
489 hdb_free_entry (context, client_entry);
490 free (client_entry);
492 if (server_entry) {
493 hdb_free_entry (context, server_entry);
494 free (server_entry);
498 static krb5_error_code
499 unparse_getticket_args (krb5_storage *sp,
500 int *kvno,
501 char **auth_domain,
502 krb5_data *ticket,
503 char **name,
504 char **instance,
505 krb5_data *times,
506 int32_t *max_seq_len)
508 krb5_data data;
509 int32_t tmp;
511 krb5_ret_int32 (sp, &tmp);
512 *kvno = tmp;
514 krb5_ret_xdr_data (sp, &data);
515 *auth_domain = malloc(data.length + 1);
516 if (*auth_domain == NULL)
517 return ENOMEM;
518 memcpy (*auth_domain, data.data, data.length);
519 (*auth_domain)[data.length] = '\0';
520 krb5_data_free (&data);
522 krb5_ret_xdr_data (sp, ticket);
524 krb5_ret_xdr_data (sp, &data);
525 *name = malloc(data.length + 1);
526 if (*name == NULL)
527 return ENOMEM;
528 memcpy (*name, data.data, data.length);
529 (*name)[data.length] = '\0';
530 krb5_data_free (&data);
532 krb5_ret_xdr_data (sp, &data);
533 *instance = malloc(data.length + 1);
534 if (*instance == NULL)
535 return ENOMEM;
536 memcpy (*instance, data.data, data.length);
537 (*instance)[data.length] = '\0';
538 krb5_data_free (&data);
540 krb5_ret_xdr_data (sp, times);
542 krb5_ret_int32 (sp, max_seq_len);
543 /* ignore the rest */
544 return 0;
547 static void
548 do_getticket (struct rx_header *hdr,
549 krb5_storage *sp,
550 struct sockaddr_in *addr,
551 krb5_data *reply)
553 krb5_error_code ret;
554 int kvno;
555 char *auth_domain = NULL;
556 krb5_data aticket;
557 char *name = NULL;
558 char *instance = NULL;
559 krb5_data times;
560 int32_t max_seq_len;
561 hdb_entry *server_entry = NULL;
562 hdb_entry *krbtgt_entry = NULL;
563 Key *kkey = NULL;
564 Key *skey = NULL;
565 des_cblock key;
566 des_key_schedule schedule;
567 des_cblock session;
568 time_t max_life;
569 int8_t life;
570 time_t start_time, end_time;
571 char pname[ANAME_SZ];
572 char pinst[INST_SZ];
573 char prealm[REALM_SZ];
575 krb5_data_zero (&aticket);
576 krb5_data_zero (&times);
578 unparse_getticket_args (sp, &kvno, &auth_domain, &aticket,
579 &name, &instance, &times, &max_seq_len);
581 server_entry = db_fetch4 (name, instance, v4_realm);
582 if (server_entry == NULL) {
583 kdc_log(0, "Server not found in database: %s.%s@%s",
584 name, instance, v4_realm);
585 make_error_reply (hdr, KANOENT, reply);
586 goto out;
589 krbtgt_entry = db_fetch4 ("krbtgt", v4_realm, v4_realm);
590 if (krbtgt_entry == NULL) {
591 kdc_log(0, "Server not found in database: %s.%s@%s",
592 "krbtgt", v4_realm, v4_realm);
593 make_error_reply (hdr, KANOENT, reply);
594 goto out;
597 /* find a DES key */
598 ret = hdb_keytype2key(context, krbtgt_entry, KEYTYPE_DES, &kkey);
599 if(ret){
600 kdc_log(0, "%s", krb5_get_err_text(context, ret));
601 make_error_reply (hdr, KANOKEYS, reply);
602 goto out;
605 /* find a DES key */
606 ret = hdb_keytype2key(context, server_entry, KEYTYPE_DES, &skey);
607 if(ret){
608 kdc_log(0, "%s", krb5_get_err_text(context, ret));
609 make_error_reply (hdr, KANOKEYS, reply);
610 goto out;
613 /* decrypt the incoming ticket */
614 memcpy (&key, kkey->key.keyvalue.data, sizeof(key));
616 /* unpack the ticket */
618 KTEXT_ST ticket;
619 u_char flags;
620 int life;
621 u_int32_t time_sec;
622 char sname[ANAME_SZ];
623 char sinstance[SNAME_SZ];
624 u_int32_t paddress;
626 ticket.length = aticket.length;
627 memcpy (ticket.dat, aticket.data, ticket.length);
629 des_set_key (&key, schedule);
630 decomp_ticket (&ticket, &flags, pname, pinst, prealm,
631 &paddress, session, &life, &time_sec,
632 sname, sinstance,
633 &key, schedule);
635 if (strcmp (sname, "krbtgt") != 0
636 || strcmp (sinstance, v4_realm) != 0) {
637 kdc_log(0, "no TGT: %s.%s for %s.%s@%s",
638 sname, sinstance,
639 pname, pinst, prealm);
640 make_error_reply (hdr, KABADTICKET, reply);
641 goto out;
644 if (kdc_time > krb_life_to_time(time_sec, life)) {
645 kdc_log(0, "TGT expired: %s.%s@%s",
646 pname, pinst, prealm);
647 make_error_reply (hdr, KABADTICKET, reply);
648 goto out;
652 /* decrypt the times */
653 des_set_key (&session, schedule);
654 des_ecb_encrypt (times.data,
655 times.data,
656 schedule,
657 DES_DECRYPT);
658 memset (&schedule, 0, sizeof(schedule));
660 /* and extract them */
662 krb5_storage *sp;
663 int32_t tmp;
665 sp = krb5_storage_from_mem (times.data, times.length);
666 krb5_ret_int32 (sp, &tmp);
667 start_time = tmp;
668 krb5_ret_int32 (sp, &tmp);
669 end_time = tmp;
670 krb5_storage_free (sp);
673 /* life */
674 max_life = end_time - kdc_time;
675 if (krbtgt_entry->max_life)
676 max_life = min(max_life, *krbtgt_entry->max_life);
677 if (server_entry->max_life)
678 max_life = min(max_life, *server_entry->max_life);
680 life = krb_time_to_life(kdc_time, kdc_time + max_life);
682 create_reply_ticket (hdr, skey,
683 pname, pinst, prealm,
684 addr, life, server_entry->kvno,
685 max_seq_len,
686 name, instance,
687 0, "gtkt",
688 &session, reply);
689 memset (&session, 0, sizeof(session));
691 out:
692 if (aticket.length) {
693 memset (aticket.data, 0, aticket.length);
694 krb5_data_free (&aticket);
696 if (times.length) {
697 memset (times.data, 0, times.length);
698 krb5_data_free (&times);
700 if (auth_domain)
701 free (auth_domain);
702 if (name)
703 free (name);
704 if (instance)
705 free (instance);
706 if (krbtgt_entry) {
707 hdb_free_entry (context, krbtgt_entry);
708 free (krbtgt_entry);
710 if (server_entry) {
711 hdb_free_entry (context, server_entry);
712 free (server_entry);
716 krb5_error_code
717 do_kaserver(unsigned char *buf,
718 size_t len,
719 krb5_data *reply,
720 const char *from,
721 struct sockaddr_in *addr)
723 krb5_error_code ret = 0;
724 struct rx_header hdr;
725 u_int32_t op;
726 krb5_storage *sp;
728 if (len < RX_HEADER_SIZE)
729 return -1;
730 sp = krb5_storage_from_mem (buf, len);
732 decode_rx_header (sp, &hdr);
733 buf += RX_HEADER_SIZE;
734 len -= RX_HEADER_SIZE;
736 switch (hdr.type) {
737 case HT_DATA :
738 break;
739 case HT_ACK :
740 case HT_BUSY :
741 case HT_ABORT :
742 case HT_ACKALL :
743 case HT_CHAL :
744 case HT_RESP :
745 case HT_DEBUG :
746 default:
747 /* drop */
748 goto out;
752 if (hdr.serviceid != KA_AUTHENTICATION_SERVICE
753 && hdr.serviceid != KA_TICKET_GRANTING_SERVICE) {
754 ret = -1;
755 goto out;
758 krb5_ret_int32(sp, &op);
759 switch (op) {
760 case AUTHENTICATE :
761 do_authenticate (&hdr, sp, addr, reply);
762 break;
763 case GETTICKET :
764 do_getticket (&hdr, sp, addr, reply);
765 break;
766 case AUTHENTICATE_OLD :
767 case CHANGEPASSWORD :
768 case GETTICKET_OLD :
769 case SETPASSWORD :
770 case SETFIELDS :
771 case CREATEUSER :
772 case DELETEUSER :
773 case GETENTRY :
774 case LISTENTRY :
775 case GETSTATS :
776 case DEBUG :
777 case GETPASSWORD :
778 case GETRANDOMKEY :
779 case AUTHENTICATE_V2 :
780 default :
781 make_error_reply (&hdr, RXGEN_OPCODE, reply);
782 break;
785 out:
786 krb5_storage_free (sp);
787 return ret;
790 #endif /* KASERVER */