X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=zephyr%2Fserver%2Fsubscr.c;h=70aa1a8b54835eab8d81975b5ed4da3ddafe5437;hb=8d93e4ca574e7d8cdd40019b208a74f8e8ceeec6;hp=00e6ab00bcbfbaf4a2ac7cf0f901f64841b3d67f;hpb=737512fd908e00dfcba48c52a7114a47ff6338f1;p=1ts-debian.git diff --git a/zephyr/server/subscr.c b/zephyr/server/subscr.c index 00e6ab0..70aa1a8 100644 --- a/zephyr/server/subscr.c +++ b/zephyr/server/subscr.c @@ -4,7 +4,7 @@ * Created by: John T. Kohl * * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/subscr.c,v $ - * $Author: zacheiss $ + * $Author$ * * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file @@ -16,7 +16,7 @@ #ifndef lint #ifndef SABER -static const char rcsid_subscr_c[] = "$Id: subscr.c,v 1.58 2001/03/01 00:47:05 zacheiss Exp $"; +static const char rcsid_subscr_c[] = "$Id$"; #endif #endif @@ -73,33 +73,32 @@ Sched serv_ksched; #ifdef OLD_COMPAT #define OLD_ZEPHYR_VERSION "ZEPH0.0" #define OLD_CLIENT_INCOMPSUBS "INCOMP" -static void old_compat_subscr_sendlist __P((ZNotice_t *notice, int auth, - struct sockaddr_in *who)); +static void old_compat_subscr_sendlist(ZNotice_t *notice, int auth, + struct sockaddr_in *who); extern int old_compat_count_subscr; /* counter of old use */ #endif /* OLD_COMPAT */ #ifdef NEW_COMPAT #define NEW_OLD_ZEPHYR_VERSION "ZEPH0.1" -static void new_old_compat_subscr_sendlist __P((ZNotice_t *notice, int auth, - struct sockaddr_in *who)); +static void new_old_compat_subscr_sendlist(ZNotice_t *notice, int auth, + struct sockaddr_in *who); extern int new_compat_count_subscr; /* counter of old use */ #endif /* NEW_COMPAT */ -extern char *re_comp(), *re_conv(); -static Code_t add_subscriptions __P((Client *who, Destlist *subs_queue, - ZNotice_t *notice, Server *server)); -static Destlist *extract_subscriptions __P((ZNotice_t *notice)); -static void free_subscriptions __P((Destlist *subs)); -static void free_subscription __P((Destlist *sub)); -static char **subscr_marshal_subs __P((ZNotice_t *notice, int auth, - struct sockaddr_in *who, - int *found)); -static Destlist *subscr_copy_def_subs __P((char *person)); -static Code_t subscr_realm_sendit __P((Client *who, Destlist *subs, - ZNotice_t *notice, Realm *realm)); -static void subscr_unsub_realms __P((Destlist *newsubs)); -static void subscr_unsub_sendit __P((Client *who, Destlist *subs, - Realm *realm)); -static int cl_match __P((Destlist*, Client *)); +static Code_t add_subscriptions(Client *who, Destlist *subs_queue, + ZNotice_t *notice, Server *server); +static Destlist *extract_subscriptions(ZNotice_t *notice); +static void free_subscriptions(Destlist *subs); +static void free_subscription(Destlist *sub); +static char **subscr_marshal_subs(ZNotice_t *notice, int auth, + struct sockaddr_in *who, + int *found); +static Destlist *subscr_copy_def_subs(char *person); +static Code_t subscr_realm_sendit(Client *who, Destlist *subs, + ZNotice_t *notice, ZRealm *realm); +static void subscr_unsub_realms(Destlist *newsubs); +static void subscr_unsub_sendit(Client *who, Destlist *subs, + ZRealm *realm); +static int cl_match (Destlist*, Client *); static int defaults_read = 0; /* set to 1 if the default subs are in memory */ @@ -118,10 +117,9 @@ String *empty; */ Code_t -subscr_subscribe(who, notice, server) - Client *who; - ZNotice_t *notice; - Server *server; +subscr_subscribe(Client *who, + ZNotice_t *notice, + Server *server) { Destlist *subs; @@ -130,17 +128,16 @@ subscr_subscribe(who, notice, server) } static Code_t -add_subscriptions(who, subs, notice, server) - Client *who; - Destlist *subs; - ZNotice_t *notice; - Server *server; +add_subscriptions(Client *who, + Destlist *subs, + ZNotice_t *notice, + Server *server) { Destlist *next; Code_t retval; Acl *acl; String *sender; - Realm *realm = NULL; + ZRealm *realm = NULL; if (!subs) return ZERR_NONE; /* no subscr -> no error */ @@ -186,14 +183,15 @@ add_subscriptions(who, subs, notice, server) } } } - if (realm && !bdumping && server && server == me_server) { - retval = subscr_realm_sendit(who, subs, notice, realm); - if (retval != ZERR_NONE) { - free_subscriptions(subs); - free_string(sender); - return(retval); + if (realm && !bdumping) { + retval = subscr_realm_sendit(who, subs, notice, realm); + if (retval != ZERR_NONE) { + free_subscription(subs); + continue; /* the for loop */ } else { - free_subscription(subs); /* free this one, will get from ADD */ + /* Indicates we leaked traffic back to our realm */ + free_subscription(subs); /* free this one, wil get from + ADD */ } } else { retval = triplet_register(who, &subs->dest, NULL); @@ -221,8 +219,7 @@ add_subscriptions(who, subs, notice, server) */ Code_t -subscr_def_subs(who) - Client *who; +subscr_def_subs(Client *who) { Destlist *subs; @@ -231,7 +228,7 @@ subscr_def_subs(who) } void -subscr_reset() +subscr_reset(void) { #if 0 zdbug((LOG_DEBUG, "subscr_reset()")); @@ -242,8 +239,7 @@ subscr_reset() } static Destlist * -subscr_copy_def_subs(person) - char *person; +subscr_copy_def_subs(char *person) { int retval, fd; struct stat statbuf; @@ -324,11 +320,10 @@ subscr_copy_def_subs(person) */ Code_t -subscr_cancel(sin, notice) - struct sockaddr_in *sin; - ZNotice_t *notice; +subscr_cancel(struct sockaddr_in *sin, + ZNotice_t *notice) { - Realm *realm; + ZRealm *realm; Client *who; Destlist *cancel_subs, *subs, *cancel_next, *client_subs, *client_next; Code_t retval; @@ -388,10 +383,9 @@ subscr_cancel(sin, notice) } Code_t -subscr_realm_cancel(sin, notice, realm) - struct sockaddr_in *sin; - ZNotice_t *notice; - Realm *realm; +subscr_realm_cancel(struct sockaddr_in *sin, + ZNotice_t *notice, + ZRealm *realm) { Client *who; Destlist *cancel_subs, *subs, *client_subs, *next, *next2; @@ -442,12 +436,11 @@ subscr_realm_cancel(sin, notice, realm) */ void -subscr_cancel_client(client) - Client *client; +subscr_cancel_client(Client *client) { Destlist *subs, *next; Code_t retval; - Realm *realm; + ZRealm *realm; #if 0 zdbug((LOG_DEBUG,"subscr_cancel_client %s", @@ -480,10 +473,9 @@ subscr_cancel_client(client) */ void -subscr_sendlist(notice, auth, who) - ZNotice_t *notice; - int auth; - struct sockaddr_in *who; +subscr_sendlist(ZNotice_t *notice, + int auth, + struct sockaddr_in *who) { char **answer; int found; @@ -534,11 +526,10 @@ subscr_sendlist(notice, auth, who) } static char ** -subscr_marshal_subs(notice, auth, who, found) - ZNotice_t *notice; - int auth; - struct sockaddr_in *who; - int *found; +subscr_marshal_subs(ZNotice_t *notice, + int auth, + struct sockaddr_in *who, + int *found) { char **answer = NULL; unsigned short temp; @@ -552,7 +543,7 @@ subscr_marshal_subs(notice, auth, who, found) zdbug((LOG_DEBUG, "subscr_marshal")); #endif *found = 0; - + /* Note that the following code is an incredible crock! */ /* We cannot send multiple packets as acknowledgements to the client, @@ -832,15 +823,19 @@ old_compat_subscr_sendlist(notice, auth, who) /*ARGSUSED*/ Code_t -subscr_send_subs(client) - Client *client; +subscr_send_subs(Client *client) { int i = 0; Destlist *subs; +#ifdef HAVE_KRB5 + char buf[512]; + char *bufp; +#else #ifdef HAVE_KRB4 char buf[512]; C_Block cblock; #endif /* HAVE_KRB4 */ +#endif char buf2[512]; char *list[7 * NUM_FIELDS]; int num = 0; @@ -853,14 +848,45 @@ subscr_send_subs(client) list[num++] = buf2; +#ifdef HAVE_KRB5 +#ifdef HAVE_KRB4 /* XXX make this optional for server transition time */ + if (Z_enctype(client->session_keyblock) == ENCTYPE_DES_CBC_CRC) { + bufp = malloc(Z_keylen(client->session_keyblock)); + if (bufp == NULL) { + syslog(LOG_WARNING, "subscr_send_subs: cannot allocate memory for DES keyblock: %m"); + return errno; + } + des_ecb_encrypt(Z_keydata(client->session_keyblock), bufp, serv_ksched.s, DES_ENCRYPT); + retval = ZMakeAscii(buf, sizeof(buf), bufp, Z_keylen(client->session_keyblock)); + } else { +#endif + bufp = malloc(Z_keylen(client->session_keyblock) + 8); /* + enctype + + length */ + if (bufp == NULL) { + syslog(LOG_WARNING, "subscr_send_subs: cannot allocate memory for keyblock: %m"); + return errno; + } + *(krb5_enctype *)&bufp[0] = htonl(Z_enctype(client->session_keyblock)); + *(u_int32_t *)&bufp[4] = htonl(Z_keylen(client->session_keyblock)); + memcpy(&bufp[8], Z_keydata(client->session_keyblock), Z_keylen(client->session_keyblock)); + + retval = ZMakeZcode(buf, sizeof(buf), bufp, Z_keylen(client->session_keyblock) + 8); +#ifdef HAVE_KRB4 + } +#endif /* HAVE_KRB4 */ +#else /* HAVE_KRB5 */ #ifdef HAVE_KRB4 #ifdef NOENCRYPTION memcpy(cblock, client->session_key, sizeof(C_Block)); -#else +#else /* NOENCRYPTION */ des_ecb_encrypt(client->session_key, cblock, serv_ksched.s, DES_ENCRYPT); -#endif +#endif /* NOENCRYPTION */ retval = ZMakeAscii(buf, sizeof(buf), cblock, sizeof(C_Block)); +#endif /* HAVE_KRB4 */ +#endif /* HAVE_KRB5 */ + +#if defined(HAVE_KRB4) || defined(HAVE_KRB5) if (retval != ZERR_NONE) { #if 0 zdbug((LOG_DEBUG,"zmakeascii failed: %s", error_message(retval))); @@ -871,7 +897,7 @@ subscr_send_subs(client) zdbug((LOG_DEBUG, "cblock %s", buf)); #endif } -#endif /* HAVE_KRB4 */ +#endif /* HAVE_KRB4 || HAVE_KRB5*/ retval = bdump_send_list_tcp(SERVACK, &client->addr, ZEPHYR_ADMIN_CLASS, num > 1 ? "CBLOCK" : "", ADMIN_NEWCLT, client->principal->string, "", list, num); @@ -935,8 +961,7 @@ free_subscription(Destlist *sub) } static void -free_subscriptions(subs) - Destlist *subs; +free_subscriptions(Destlist *subs) { Destlist *next; @@ -959,8 +984,7 @@ free_subscriptions(subs) */ static Destlist * -extract_subscriptions(notice) - ZNotice_t *notice; +extract_subscriptions(ZNotice_t *notice) { Destlist *subs = NULL, *sub; char *recip, *class_name, *classinst; @@ -1008,9 +1032,8 @@ extract_subscriptions(notice) */ void -subscr_dump_subs(fp, subs) - FILE *fp; - Destlist *subs; +subscr_dump_subs(FILE *fp, + Destlist *subs) { char *p; @@ -1038,11 +1061,10 @@ subscr_dump_subs(fp, subs) /* As it exists, this function expects to take only the first sub from the * Destlist. At some point, it and the calling code should be replaced */ static Code_t -subscr_realm_sendit(who, subs, notice, realm) - Client *who; - Destlist *subs; - ZNotice_t *notice; - Realm *realm; +subscr_realm_sendit(Client *who, + Destlist *subs, + ZNotice_t *notice, + ZRealm *realm) { ZNotice_t snotice; char *pack; @@ -1125,10 +1147,9 @@ subscr_realm_sendit(who, subs, notice, realm) /* Called from subscr_realm and subscr_foreign_user */ static Code_t -subscr_add_raw(client, realm, newsubs) - Client *client; - Realm *realm; - Destlist *newsubs; +subscr_add_raw(Client *client, + ZRealm *realm, + Destlist *newsubs) { Destlist *subs, *subs2, *subs3, **head; Code_t retval; @@ -1157,7 +1178,7 @@ subscr_add_raw(client, realm, newsubs) } } else { if (!realm) { - Realm *remrealm = + ZRealm *remrealm = realm_get_realm_by_name(subs->dest.recip->string + 1); if (remrealm) { Destlist *sub = (Destlist *) malloc(sizeof(Destlist)); @@ -1184,9 +1205,8 @@ subscr_add_raw(client, realm, newsubs) /* Called from bdump_recv_loop to decapsulate realm subs */ Code_t -subscr_realm(realm, notice) - Realm *realm; - ZNotice_t *notice; +subscr_realm(ZRealm *realm, + ZNotice_t *notice) { Destlist *newsubs; @@ -1202,10 +1222,9 @@ subscr_realm(realm, notice) /* Like realm_sendit, this only takes one item from subs */ static void -subscr_unsub_sendit(who, subs, realm) - Client *who; - Destlist *subs; - Realm *realm; +subscr_unsub_sendit(Client *who, + Destlist *subs, + ZRealm *realm) { ZNotice_t unotice; Code_t retval; @@ -1269,8 +1288,7 @@ subscr_unsub_sendit(who, subs, realm) /* Called from bump_send_loop by way of realm_send_realms */ Code_t -subscr_send_realm_subs(realm) - Realm *realm; +subscr_send_realm_subs(ZRealm *realm) { int i = 0; Destlist *subs, *next; @@ -1336,8 +1354,7 @@ subscr_send_realm_subs(realm) } Code_t -subscr_realm_subs(realm) - Realm *realm; +subscr_realm_subs(ZRealm *realm) { int i = 0; Destlist *subs, *next; @@ -1422,12 +1439,11 @@ subscr_realm_subs(realm) /* Called from subscr_foreign_user for REALM_REQ_SUBSCRIBE */ static Code_t -subscr_check_foreign_subs(notice, who, server, realm, newsubs) - ZNotice_t *notice; - struct sockaddr_in *who; - Server *server; - Realm *realm; - Destlist *newsubs; +subscr_check_foreign_subs(ZNotice_t *notice, + struct sockaddr_in *who, + Server *server, + ZRealm *realm, + Destlist *newsubs) { Destlist *subs, *subs2, *next; Acl *acl; @@ -1465,17 +1481,27 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs) found = 0; for (subs = newsubs; subs; subs = next) { + ZRealm *rlm; next=subs->next; + if (subs->dest.recip->string[0] != '\0') { + rlm = realm_which_realm(who); + syslog(LOG_WARNING, "subscr bad recip %s by %s (%s)", + subs->dest.recip->string, + sender->string, rlm->name); + continue; + } acl = class_get_acl(subs->dest.classname); if (acl) { - Realm *rlm; rlm = realm_which_realm(who); if (rlm && server == me_server) { if (!realm_sender_in_realm(rlm->name, sender->string)) { syslog(LOG_WARNING, "subscr auth not verifiable %s (%s) class %s", sender->string, rlm->name, subs->dest.classname->string); - continue; + free_subscriptions(newsubs); + free_string(sender); + free(text); + return ZSRV_CLASSRESTRICTED; } } if (!access_check(sender->string, acl, SUBSCRIBE)) { @@ -1547,11 +1573,10 @@ subscr_check_foreign_subs(notice, who, server, realm, newsubs) } /* Called from realm_control_dispatch for REALM_REQ/ADD_SUBSCRIBE */ -Code_t subscr_foreign_user(notice, who, server, realm) - ZNotice_t *notice; - struct sockaddr_in *who; - Server *server; - Realm *realm; +Code_t subscr_foreign_user(ZNotice_t *notice, + struct sockaddr_in *who, + Server *server, + ZRealm *realm) { Destlist *newsubs, *temp; Acl *acl; @@ -1625,7 +1650,7 @@ Code_t subscr_foreign_user(notice, who, server, realm) temp->dest.recip = make_string(rlm_recipient, 0); } - status = subscr_add_raw(client, (Realm *)0, newsubs); + status = subscr_add_raw(client, (ZRealm *)0, newsubs); } else if (!strcmp(snotice.z_opcode, REALM_REQ_SUBSCRIBE)) { zdbug((LOG_DEBUG, "subscr_foreign_user REQ %s/%s", tp0, tp1)); status = subscr_check_foreign_subs(notice, who, server, realm, newsubs);