2 #include <sys/socket.h>
4 Unacked *rlm_nacklist = NULL; /* not acked list for realm-realm
6 Realm *otherrealms; /* points to an array of the known
8 int nrealms = 0; /* number of other realms */
10 static void get_realm_addrs __P(());
11 static void realm_sendit __P((ZNotice_t *notice, struct sockaddr_in *who, int auth, Realm *realm, int ack_to_sender));
12 static void realm_sendit_auth __P((ZNotice_t *notice, struct sockaddr_in *who, int auth, Realm *realm, int ack_to_sender));
13 static void rlm_ack __P((ZNotice_t *notice, Unacked *nacked));
14 static void rlm_nack_cancel __P((ZNotice_t *notice, struct sockaddr_in *who));
15 static void rlm_new_ticket __P(());
16 static void rlm_rexmit __P((void *arg));
17 static Code_t realm_ulocate_dispatch __P((ZNotice_t *notice,int auth,struct sockaddr_in *who,Server *server,Realm *realm));
19 static Code_t ticket_retrieve __P((Realm *realm));
23 realm_expand_realm(realmname)
26 static char expand[REALM_SZ];
27 static char krb_realm[REALM_SZ+1];
35 /* upcase what we got */
39 *cp1++ = toupper(*cp2++);
43 sprintf(list_file, "%s/zephyr/%s", SYSCONFDIR, REALM_LIST_FILE);
45 if ((rlm_file = fopen(list_file, "r")) == (FILE *) 0) {
49 if (fgets(linebuf, BUFSIZ, rlm_file) == NULL) {
51 (void) fclose(rlm_file);
56 /* run through the file, looking for admin host */
57 if (fgets(linebuf, BUFSIZ, rlm_file) == NULL) {
58 (void) fclose(rlm_file);
62 if (sscanf(linebuf, "%s %s", krb_realm, scratch) < 2)
64 if (!strncmp(krb_realm, expand, strlen(expand))) {
65 (void) fclose(rlm_file);
70 if (!strncmp(my_realm, expand, strlen(expand)))
80 Realmname *rlm_list, *rlm;
81 int ii, nused, ntotal;
83 char buf[REALM_SZ + MAXHOSTNAMELEN + 1]; /* one for newline */
84 char realm[REALM_SZ], server[MAXHOSTNAMELEN + 1];
87 if (!(fp = fopen(file, "r")))
88 return((Realmname *)0);
90 /* start with 16, realloc if necessary */
92 rlm_list = (Realmname *)malloc(ntotal * sizeof(Realmname));
94 syslog(LOG_CRIT, "get_realm_lists malloc");
98 while (fgets(buf, REALM_SZ + MAXHOSTNAMELEN + 1, fp)) {
99 if (sscanf(buf, "%s %s", realm, server) != 2) {
100 syslog(LOG_CRIT, "bad format in %s", file);
103 for (ii = 0; ii < nused; ii++) {
104 /* look for this realm */
105 if (!strcmp(rlm_list[ii].name, realm))
110 if (rlm->nused +1 >= rlm->nservers) {
111 /* make more space */
112 rlm->servers = (char **)realloc((char *)rlm->servers,
113 (unsigned)rlm->nservers * 2 *
116 syslog(LOG_CRIT, "get_realm_lists realloc");
121 rlm->servers[rlm->nused++] = strsave(server);
124 if (nused + 1 >= ntotal) {
125 /* make more space */
126 rlm_list = (Realmname *)realloc((char *)rlm_list,
127 (unsigned)ntotal * 2 *
130 syslog(LOG_CRIT, "get_realm_lists realloc");
135 rlm = &rlm_list[nused++];
136 strcpy(rlm->name, realm);
139 rlm->servers = (char **)malloc(rlm->nservers * sizeof(char *));
141 syslog(LOG_CRIT, "get_realm_lists malloc");
144 rlm->servers[rlm->nused++] = strsave(server);
147 if (nused + 1 >= ntotal) {
148 rlm_list = (Realmname *)realloc((char *)rlm_list,
149 (unsigned)(ntotal + 1) *
152 syslog(LOG_CRIT, "get_realm_lists realloc");
156 *rlm_list[nused].name = '\0';
165 for (cnt = 0; cnt < nrealms; cnt++) {
166 if (retval = (subscr_send_realm_subs(&otherrealms[cnt])) != ZERR_NONE)
173 bound_for_local_realm(notice)
178 realm = strchr(notice->z_recipient, '@');
180 if (!realm || !strcmp(realm_expand_realm(realm + 1), ZGetRealm()))
187 sender_in_realm(notice)
192 realm = strchr(notice->z_sender, '@');
194 if (!realm || !strcmp(realm + 1, ZGetRealm()))
201 realm_which_realm(who)
202 struct sockaddr_in *who;
205 struct sockaddr_in *addr;
208 /* loop through the realms */
209 for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
210 /* loop through the addresses for the realm */
211 for (addr = realm->addrs, b = 0; b < realm->count; b++, addr++)
212 if (addr->sin_addr.s_addr == who->sin_addr.s_addr)
219 realm_get_realm_by_name(name)
225 for (realm = otherrealms, a = 0; a < nrealms; a++, realm++)
226 if (!strcmp(realm->name, name))
233 rlm_nack_cancel(notice, who)
234 register ZNotice_t *notice;
235 struct sockaddr_in *who;
237 register Realm *which = realm_which_realm(who);
238 register Unacked *nacked, *next;
243 zdbug((LOG_DEBUG, "rlm_nack_cancel: %s:%08X,%08X",
244 inet_ntoa(notice->z_uid.zuid_addr),
245 notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
248 syslog(LOG_ERR, "non-realm ack?");
252 for (nacked = rlm_nacklist; nacked; nacked = nacked->next) {
253 if (&otherrealms[nacked->dest.rlm.rlm_idx] == which) {
254 if (ZCompareUID(&nacked->uid, ¬ice->z_uid)) {
255 timer_reset(nacked->timer);
257 if (nacked->ack_addr.sin_addr.s_addr)
258 rlm_ack(notice, nacked);
261 free(nacked->packet);
269 zdbug((LOG_DEBUG,"nack_cancel: nack not found %s:%08X,%08X",
270 inet_ntoa (notice->z_uid.zuid_addr),
271 notice->z_uid.tv.tv_sec, notice->z_uid.tv.tv_usec));
277 rlm_ack(notice, nacked)
286 /* tell the original sender the result */
288 acknotice.z_message_len = strlen(acknotice.z_message) + 1;
290 packlen = sizeof(ackpack);
292 if ((retval = ZFormatSmallRawNotice(&acknotice, ackpack, &packlen)) != ZERR_NONE) {
293 syslog(LOG_ERR, "rlm_ack format: %s",
294 error_message(retval));
297 zdbug((LOG_DEBUG, "rlm_ack sending to %s/%d",
298 inet_ntoa(nacked->ack_addr.sin_addr),
299 ntohs(nacked->ack_addr.sin_port)));
300 if ((retval = ZSetDestAddr(&nacked->ack_addr)) != ZERR_NONE) {
301 syslog(LOG_WARNING, "rlm_ack set addr: %s",
302 error_message(retval));
305 if ((retval = ZSendPacket(ackpack, packlen, 0)) != ZERR_NONE) {
306 syslog(LOG_WARNING, "rlm_ack xmit: %s", error_message(retval));
313 realm_dispatch(notice, auth, who, server)
316 struct sockaddr_in *who;
320 struct sockaddr_in newwho;
321 Code_t status = ZERR_NONE;
322 char rlm_recipient[REALM_SZ + 1];
324 String *notice_class;
326 if (notice->z_kind == SERVACK || notice->z_kind == SERVNAK) {
327 rlm_nack_cancel(notice, who);
330 /* set up a who for the real origin */
331 memset((caddr_t) &newwho, 0, sizeof(newwho));
332 newwho.sin_family = AF_INET;
333 newwho.sin_addr.s_addr = notice->z_sender_addr.s_addr;
334 newwho.sin_port = hm_port;
336 /* check if it's a control message */
337 realm = realm_which_realm(who);
339 notice_class = make_string(notice->z_class,1);
341 if (class_is_admin(notice_class)) {
342 syslog(LOG_WARNING, "%s sending admin opcode %s",
343 realm->name, notice->z_opcode);
344 } else if (class_is_hm(notice_class)) {
345 syslog(LOG_WARNING, "%s sending hm opcode %s",
346 realm->name, notice->z_opcode);
347 } else if (class_is_control(notice_class)) {
348 status = realm_control_dispatch(notice, auth, who,
350 } else if (class_is_ulogin(notice_class)) {
351 /* don't need to forward this */
352 if (server == me_server) {
353 sprintf(rlm_recipient, "@%s", realm->name);
354 notice->z_recipient = rlm_recipient;
356 sendit(notice, 1, who, 0);
358 } else if (class_is_ulocate(notice_class)) {
359 status = realm_ulocate_dispatch(notice, auth, who, server, realm);
361 /* redo the recipient */
362 if (*notice->z_recipient == '\0') {
363 sprintf(rlm_recipient, "@%s", realm->name);
364 notice->z_recipient = rlm_recipient;
365 /* only send to our realm */
367 } else if (bound_for_local_realm(notice) && *notice->z_recipient
370 /* we're responsible for getting this message out */
372 notice->z_recipient = "";
375 /* otherwise, send to local subscribers */
376 sendit(notice, auth, who, external);
389 struct in_addr *addresses;
392 char rlmprinc[ANAME_SZ+INST_SZ+REALM_SZ+3];
394 sprintf(list_file, "%s/zephyr/%s", SYSCONFDIR, REALM_LIST_FILE);
395 rlmnames = get_realm_lists(list_file);
397 zdbug((LOG_DEBUG, "No other realms"));
402 for (nrealms = 0; *rlmnames[nrealms].name; nrealms++);
404 otherrealms = (Realm *)malloc(nrealms * sizeof(Realm));
406 syslog(LOG_CRIT, "malloc failed in get_realm_addrs");
410 for (ii = 0; ii < nrealms; ii++) {
411 rlm = &otherrealms[ii];
412 strcpy(rlm->name, rlmnames[ii].name);
414 addresses = (struct in_addr *)malloc(rlmnames[ii].nused * sizeof(struct in_addr));
416 syslog(LOG_CRIT, "malloc failed in get_realm_addrs");
419 /* convert names to addresses */
421 for (jj = 0; jj < rlmnames[ii].nused; jj++) {
422 hp = gethostbyname(rlmnames[ii].servers[jj]);
424 memmove((caddr_t) &addresses[found], (caddr_t)hp->h_addr, sizeof(struct in_addr));
427 syslog(LOG_WARNING, "hostname failed, %s", rlmnames[ii].servers[jj]);
428 /* free the hostname */
429 free(rlmnames[ii].servers[jj]);
432 rlm->addrs = (struct sockaddr_in *)malloc(found * sizeof (struct sockaddr_in));
434 syslog(LOG_CRIT, "malloc failed in get_realm_addrs");
437 for (jj = 0; jj < rlm->count; jj++) {
438 rlm->addrs[jj].sin_family = AF_INET;
439 /* use the server port */
440 rlm->addrs[jj].sin_port = srv_addr.sin_port;
441 rlm->addrs[jj].sin_addr = addresses[jj];
443 client = (Client *) malloc(sizeof(Client));
445 syslog(LOG_CRIT, "malloc failed in get_realm_addrs");
448 memset(&client->addr, 0, sizeof(struct sockaddr_in));
450 memset(&client->session_key, 0, sizeof(client->session_key));
452 sprintf(rlmprinc, "%s.%s@%s", SERVER_SERVICE, SERVER_INSTANCE, rlm->name);
453 client->principal = make_string(rlmprinc, 0);
454 client->last_send = 0;
455 client->last_ack = NOW;
458 client->addr.sin_family = 0;
459 client->addr.sin_port = 0;
460 client->addr.sin_addr.s_addr = 0;
462 rlm->client = client;
463 rlm->idx = random() % rlm->count;
466 free(rlmnames[ii].servers);
473 realm_ulocate_dispatch(notice, auth, who, server, realm)
476 struct sockaddr_in *who;
480 register char *opcode = notice->z_opcode;
484 syslog(LOG_WARNING, "unauth locate msg from %s",
485 inet_ntoa(who->sin_addr));
486 clt_ack(notice, who, AUTH_FAILED);
490 if (!strcmp(opcode, REALM_REQ_LOCATE)) {
492 ulogin_realm_locate(notice, who, realm);
493 } else if (!strcmp(opcode, REALM_ANS_LOCATE)) {
495 ulogin_relay_locate(notice, who);
497 syslog(LOG_WARNING, "%s unknown/illegal loc opcode %s",
498 realm->name, opcode);
507 realm_control_dispatch(notice, auth, who, server, realm)
510 struct sockaddr_in *who;
514 register char *opcode = notice->z_opcode;
518 syslog(LOG_WARNING, "unauth ctl msg from %s",
519 inet_ntoa(who->sin_addr));
520 if (server == me_server)
521 clt_ack(notice, who, AUTH_FAILED);
525 if (strcmp(notice->z_class_inst, ZEPHYR_CTL_REALM)) {
526 syslog(LOG_WARNING, "Invalid rlm_dispatch instance %s",
527 notice->z_class_inst);
531 if (!strcmp(opcode, REALM_REQ_SUBSCRIBE) || !strcmp(opcode, REALM_ADD_SUBSCRIBE)) {
532 /* try to add subscriptions */
533 /* attempts to get defaults are ignored */
534 if ((status = subscr_foreign_user(notice, who, realm)) != ZERR_NONE) {
535 clt_ack(notice, who, AUTH_FAILED);
536 } else if (server == me_server) {
537 server_forward(notice, auth, who);
540 } else if (!strcmp(opcode, REALM_UNSUBSCRIBE)) {
541 /* try to remove subscriptions */
542 if ((status = subscr_realm_cancel(who, notice, realm)) != ZERR_NONE) {
543 clt_ack(notice, who, NOT_FOUND);
544 } else if (server == me_server) {
545 server_forward(notice, auth, who);
549 syslog(LOG_WARNING, "%s unknown/illegal ctl opcode %s",
550 realm->name, opcode);
551 if (server == me_server)
559 realm_handoff(notice, auth, who, realm, ack_to_sender)
562 struct sockaddr_in *who;
570 zdbug((LOG_DEBUG, "realm_sendit unauthentic to realm %s", realm->name))
571 realm_sendit(notice, who, auth, realm, ack_to_sender);
574 if (!ticket_lookup(realm->name))
575 if ((retval = ticket_retrieve(realm)) != ZERR_NONE) {
576 syslog(LOG_WARNING, "rlm_handoff failed: %s", error_message(retval));
580 zdbug((LOG_DEBUG, "realm_sendit to realm %s auth %d", realm->name, auth));
581 /* valid ticket available now, send the message */
582 realm_sendit_auth(notice, who, auth, realm, ack_to_sender);
583 #else /* HAVE_KRB4 */
584 realm_sendit(notice, who, auth, realm, ack_to_sender);
585 #endif /* HAVE_KRB4 */
589 realm_sendit(notice, who, auth, realm, ack_to_sender)
591 struct sockaddr_in *who;
601 notice->z_auth = auth;
603 /* format the notice */
604 if ((retval = ZFormatRawNotice(notice, &pack, &packlen)) != ZERR_NONE) {
605 syslog(LOG_WARNING, "rlm_sendit format: %s",
606 error_message(retval));
611 if ((retval = ZSetDestAddr(&realm->addrs[realm->idx])) != ZERR_NONE) {
612 syslog(LOG_WARNING, "rlm_sendit set addr: %s",
613 error_message(retval));
617 if ((retval = ZSendPacket(pack, packlen, 0)) != ZERR_NONE) {
618 syslog(LOG_WARNING, "rlm_sendit xmit: %s", error_message(retval));
623 /* now we've sent it, mark it as not ack'ed */
625 if (!(nacked = (Unacked *)malloc(sizeof(Unacked)))) {
626 /* no space: just punt */
627 syslog(LOG_ERR, "rlm_sendit nack malloc");
632 nacked->client = NULL;
634 nacked->packet = pack;
635 nacked->dest.rlm.rlm_idx = realm - otherrealms;
636 nacked->dest.rlm.rlm_srv_idx = realm->idx;
637 nacked->packsz = packlen;
638 nacked->uid = notice->z_uid;
640 nacked->ack_addr = *who;
642 nacked->ack_addr.sin_addr.s_addr = 0;
644 /* set a timer to retransmit */
645 nacked->timer = timer_set_rel(rexmit_times[0], rlm_rexmit, nacked);
647 LIST_INSERT(&rlm_nacklist, nacked);
652 packet_ctl_nack(nackpacket)
657 /* extract the notice */
658 ZParseNotice(nackpacket->packet, nackpacket->packsz, ¬ice);
659 nack(¬ice, &nackpacket->ack_addr);
666 Unacked *nackpacket = (Unacked *) arg;
668 register Realm *realm;
671 zdbug((LOG_DEBUG,"rlm_rexmit"));
673 realm = &otherrealms[nackpacket->dest.rlm.rlm_idx];
675 zdbug((LOG_DEBUG, "rlm_rexmit: sending to %s", realm->name));
677 if (rexmit_times[(nackpacket->rexmits + 1)/(realm->count)] == -1) {
678 /* give a server ack that the packet is lost/realm dead */
679 packet_ctl_nack(nackpacket);
680 LIST_DELETE(nackpacket);
681 free(nackpacket->packet);
684 zdbug((LOG_DEBUG, "rlm_rexmit: %s appears dead", realm->name));
688 /* retransmit the packet, trying each server in the realm multiple times */
690 new_srv_idx = ((nackpacket->rexmits / NUM_REXMIT_TIMES)
691 + nackpacket->rlm.rlm_srv_idx) % realm->count;
693 new_srv_idx = nackpacket->rexmits % realm->count;
695 if (new_srv_idx != realm->idx)
696 realm->idx = new_srv_idx;
698 retval = ZSetDestAddr(&realm->addrs[realm->idx]);
699 if (retval != ZERR_NONE) {
700 syslog(LOG_WARNING, "rlm_rexmit set addr: %s", error_message(retval));
702 retval = ZSendPacket(nackpacket->packet, nackpacket->packsz, 0);
703 if (retval != ZERR_NONE)
704 syslog(LOG_WARNING, "rlm_rexmit xmit: %s", error_message(retval));
706 /* reset the timer */
707 if (rexmit_times[(nackpacket->rexmits + 1)/(realm->count)] != -1)
708 nackpacket->rexmits++;
710 nackpacket->timer = timer_set_rel(rexmit_times[(nackpacket->rexmits)/(realm->count)], rlm_rexmit, nackpacket);
715 realm_dump_realms(fp)
720 for (ii = 0; ii < nrealms; ii++) {
721 (void) fprintf(fp, "%d:%s\n", ii, otherrealms[ii].name);
722 for (jj = 0; jj < otherrealms[ii].count; jj++) {
723 (void) fprintf(fp, "\t%s\n",
724 inet_ntoa(otherrealms[ii].addrs[jj].sin_addr));
727 subscr_dump_subs(fp, otherrealms[ii].subs);
734 realm_sendit_auth(notice, who, auth, realm, ack_to_sender)
737 struct sockaddr_in *who;
743 int buffer_len, hdrlen, offset, fragsize, ret_len, message_len;
744 int origoffset, origlen;
747 char buf[1024], multi[64];
750 ZNotice_t partnotice, newnotice;
754 /* first, build an authent */
755 retval = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, realm->name, &cred);
756 if (retval != GC_OK) {
757 syslog(LOG_WARNING, "rlm_sendit_auth get_cred: %s",
758 error_message(retval+krb_err_base));
762 retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
764 if (retval != MK_AP_OK) {
765 syslog(LOG_WARNING, "rlm_sendit_auth mk_req: %s",
766 error_message(retval+krb_err_base));
770 retval = ZMakeAscii(buf, sizeof(buf), authent.dat, authent.length);
771 if (retval != ZERR_NONE) {
772 syslog(LOG_WARNING, "rlm_sendit_auth mk_ascii: %s",
773 error_message(retval));
777 /* set the dest addr */
778 retval = ZSetDestAddr(&realm->addrs[realm->idx]);
779 if (retval != ZERR_NONE) {
780 syslog(LOG_WARNING, "rlm_sendit_auth set addr: %s", error_message(retval));
784 /* now format the notice, refragmenting if needed */
786 newnotice.z_auth = 1;
787 newnotice.z_ascii_authent = buf;
788 newnotice.z_authent_len = authent.length;
790 buffer = (char *) malloc(sizeof(ZPacket_t));
792 syslog(LOG_ERR, "realm_sendit_auth malloc");
793 return; /* DON'T put on nack list */
796 buffer_len = sizeof(ZPacket_t);
798 retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen, &ptr,
800 if (retval != ZERR_NONE) {
801 syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
807 newnotice.z_checksum = 0;
809 newnotice.z_checksum =
810 (ZChecksum_t)des_quad_cksum(buffer, NULL, ptr - buffer, 0, cred.session);
813 retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen,
815 if (retval != ZERR_NONE) {
816 syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
821 /* This is not terribly pretty, but it does do its job.
822 * If a packet we get that needs to get sent off to another realm is
823 * too big after we slap on our authent, we refragment it further,
824 * a la Z_SendFragmentedNotice. This obliviates the need for what
825 * used to be done in ZFormatAuthenticRealmNotice, as we do it here.
826 * At some point it should be pulled back out into its own function,
827 * but only the server uses it.
830 if ((newnotice.z_message_len+hdrlen > buffer_len) ||
831 (newnotice.z_message_len+hdrlen > Z_MAXPKTLEN)){
832 /* Deallocate buffer, use a local one */
835 partnotice = *notice;
837 partnotice.z_auth = 1;
838 partnotice.z_ascii_authent = buf;
839 partnotice.z_authent_len = authent.length;
842 origlen = notice->z_message_len;
844 if (notice->z_multinotice && strcmp(notice->z_multinotice, ""))
845 if (sscanf(notice->z_multinotice, "%d/%d", &origoffset, &origlen) != 2) {
846 syslog(LOG_WARNING, "rlm_sendit_auth frag: parse failed");
851 zdbug((LOG_DEBUG,"rlm_send_auth: orig: %d-%d/%d", origoffset, notice->z_message_len, origlen));
854 fragsize = Z_MAXPKTLEN-hdrlen-Z_FRAGFUDGE;
856 while (offset < notice->z_message_len || !notice->z_message_len) {
857 (void) sprintf(multi, "%d/%d", offset+origoffset, origlen);
858 partnotice.z_multinotice = multi;
860 (void) gettimeofday(&partnotice.z_uid.tv, (struct timezone *)0);
861 partnotice.z_uid.tv.tv_sec = htonl((u_long)
862 partnotice.z_uid.tv.tv_sec);
863 partnotice.z_uid.tv.tv_usec = htonl((u_long)
864 partnotice.z_uid.tv.tv_usec);
865 (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr,
868 message_len = min(notice->z_message_len-offset, fragsize);
869 partnotice.z_message = notice->z_message+offset;
870 partnotice.z_message_len = message_len;
873 zdbug((LOG_DEBUG,"rlm_send_auth: new: %d-%d/%d", origoffset+offset, message_len, origlen));
876 buffer = (char *) malloc(sizeof(ZPacket_t));
878 syslog(LOG_ERR, "realm_sendit_auth malloc");
879 return; /* DON'T put on nack list */
882 retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len, &hdrlen,
884 if (retval != ZERR_NONE) {
885 syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
891 partnotice.z_checksum = 0;
893 partnotice.z_checksum =
894 (ZChecksum_t)des_quad_cksum(buffer, NULL, ptr - buffer, 0,
898 retval = Z_FormatRawHeader(&partnotice, buffer, buffer_len, &hdrlen,
900 if (retval != ZERR_NONE) {
901 syslog(LOG_WARNING, "rlm_sendit_auth raw: %s", error_message(retval));
908 (void) memcpy(ptr, partnotice.z_message, partnotice.z_message_len);
910 buffer_len = hdrlen+partnotice.z_message_len;
913 if ((retval = ZSendPacket(buffer, buffer_len, 0)) != ZERR_NONE) {
914 syslog(LOG_WARNING, "rlm_sendit_auth xmit: %s", error_message(retval));
921 if (!(nacked = (Unacked *)malloc(sizeof(Unacked)))) {
922 /* no space: just punt */
923 syslog(LOG_ERR, "rlm_sendit_auth nack malloc");
929 nacked->packet = buffer;
930 nacked->dest.rlm.rlm_idx = realm - otherrealms;
931 nacked->dest.rlm.rlm_srv_idx = realm->idx;
932 nacked->packsz = buffer_len;
933 nacked->uid = partnotice.z_uid;
935 /* Do the ack for the last frag, below */
937 nacked->ack_addr = *who;
939 nacked->ack_addr.sin_addr.s_addr = 0;
941 /* set a timer to retransmit */
942 nacked->timer = timer_set_rel(rexmit_times[0], rlm_rexmit, nacked);
945 LIST_INSERT(&rlm_nacklist, nacked);
947 if (!notice->z_message_len)
951 zdbug((LOG_DEBUG, "rlm_sendit_auth frag message sent"));
954 /* This is easy, no further fragmentation needed */
957 (void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len);
959 buffer_len = hdrlen+newnotice.z_message_len;
962 if ((retval = ZSendPacket(buffer, buffer_len, 0)) != ZERR_NONE) {
963 syslog(LOG_WARNING, "rlm_sendit_auth xmit: %s", error_message(retval));
969 zdbug((LOG_DEBUG, "rlm_sendit_auth message sent"));
971 /* now we've sent it, mark it as not ack'ed */
973 if (!(nacked = (Unacked *)malloc(sizeof(Unacked)))) {
974 /* no space: just punt */
975 syslog(LOG_ERR, "rlm_sendit_auth nack malloc");
981 nacked->packet = buffer;
982 nacked->dest.rlm.rlm_idx = realm - otherrealms;
983 nacked->dest.rlm.rlm_srv_idx = realm->idx;
984 nacked->packsz = buffer_len;
985 nacked->uid = notice->z_uid;
987 /* Do the ack for the last frag, below */
989 nacked->ack_addr = *who;
991 nacked->ack_addr.sin_addr.s_addr = 0;
993 /* set a timer to retransmit */
994 nacked->timer = timer_set_rel(rexmit_times[0], rlm_rexmit, nacked);
996 LIST_INSERT(&rlm_nacklist, nacked);
1000 nacked->ack_addr = *who;
1006 ticket_expired(cred)
1009 /* extra 15 minutes for safety margin */
1010 #ifdef AFS_LIFETIMES
1011 return (krb_life_to_time(cred->issue_date, cred->lifetime) < NOW + 15*60);
1012 #else /* AFS_LIFETIMES */
1013 return (cred->issue_date + cred->lifetime*5*60 < NOW + 15*60);
1014 #endif /* AFS_LIFETIMES */
1018 ticket_lookup(realm)
1025 retval = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, realm, &cred);
1026 if (retval == GC_OK && !ticket_expired(&cred))
1030 if (!strcmp(realm, ZGetRealm())) {
1034 memset(&authent.dat,0,MAX_KTXT_LEN);
1037 /* this is local, so try to contact the Kerberos server */
1038 retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
1040 if (retval != KSUCCESS) {
1041 syslog(LOG_ERR, "tkt_lookup: local: %s",
1042 krb_err_txt[retval]);
1053 ticket_retrieve(realm)
1062 memset(&authent.dat,0,MAX_KTXT_LEN);
1065 /* Don't lose by trying too often. */
1066 if (NOW - realm->tkt_try > 5 * 60) {
1067 retval = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE,
1069 realm->tkt_try = NOW;
1070 if (retval != KSUCCESS) {
1071 syslog(LOG_WARNING, "tkt_rtrv: %s: %s", realm,
1072 krb_err_txt[retval]);
1073 return (retval+krb_err_base);
1080 #endif /* HAVE_KRB4 */