+
+Wed Jul 12 12:19:44 EDT 1995 Paul Park (pjpark@mit.edu)
+ * main.c - Reorganize KDC profile handling so that the hierarchy for
+ locating per-realm data is [realms]->realm->tag. Add
+ [kdcdefaults] section with primary_ports and secondary_ports
+ to list ports to listen on. Consolidate all port location here
+ from network.c. Add -s flag and change meaning of -p flag to
+ be the default if none specified in KDC or Kerberos profile.
+ * network.c - Open list of primary ports and then per-realm ports.
+ Handle secondary ports just like primary ports except that
+ bind failures are only warnings. Support more than one
+ secondary port.
+ * extern,kdc_util.h - Add supporting definitions.
+ * krb5kdc.M - update description of -p and add description of -s.
+
Tue Jul 11 07:35:12 1995 Ezra Peisach <epeisach@kangaroo.mit.edu>
* kerberos_v4.c: Add prototype for set_tgtkey
*/
char * realm_name; /* Realm name */
krb5_context realm_context; /* Context to be used for realm */
+ char * realm_profile; /* Profile file for this realm */
/*
* Database per-realm data.
*/
*/
krb5_encrypt_block realm_encblock; /* Per-realm master encryption block*/
krb5_int32 realm_pport; /* Per-realm primary KDC port. */
+ krb5_int32 realm_sport; /* Per-realm secondary KDC port. */
/*
* Per-realm parameters.
*/
/* network.c */
krb5_error_code listen_and_process PROTOTYPE((const char *));
-krb5_error_code setup_network PROTOTYPE((const char *));
+krb5_error_code setup_network PROTOTYPE((const char *,
+ int *,
+ int *));
krb5_error_code closedown_network PROTOTYPE((const char *));
void process_packet PROTOTYPE((int, const char *, int));
.B \-p
.I portnum
] [
+.B \-s
+.I portnum
+] [
.B \-m
] [
.B \-r
The
.B \-p
.I portnum
-option specifies the UDP port number which the KDC should listen on for
-requests. If none is specified, then the value in /etc/services is used,
-with an ultimate default value of KRB5_DEFAULT_PORT, or 88.
+option specifies the default UDP port number which the KDC should listen on for
+Kerberos version 5 requests. This value is used when no port is specified in
+the KDC profile and when no port is specified in the Kerberos configuration
+file.
+If no value is available, then the value in /etc/services for service
+"kerberos" is used.
+.PP
+The
+.B \-s
+.I portnum
+option specifies the default UDP port number which the KDC should listen on for
+Kerberos version 4 requests. This value is used when no port is specified in
+the kdc profile and when no port is specified in the Kerberos configuration
+file.
+If no value is available, then the value in /etc/services for service
+"kerberos-sec" is used.
.PP
The
.B \-m
#include <syslog.h>
#include <signal.h>
#include <errno.h>
+#include <netdb.h>
#include "com_err.h"
#include "k5-int.h"
#define KRB5_KDC_MAX_REALMS 32
+/*
+ * Get port information for a realm. The precedence is:
+ * [realms]-><realm>-><name> in profile (if our hostname and has a port)
+ * defport
+ * /etc/services entry matching <service>
+ */
+static krb5_int32
+get_realm_port(ctx, realm, name, defport, service)
+ krb5_context ctx;
+ char *realm;
+ char *name;
+ krb5_int32 defport;
+ char *service;
+{
+ krb5_error_code kret;
+ char our_host_name[MAXHOSTNAMELEN];
+ struct hostent *our_hostent;
+ struct servent *our_servent;
+ krb5_int32 retval;
+ krb5_boolean found;
+
+ /*
+ * Some preliminaries here. Get our hostname and our host entry.
+ */
+ found = 0;
+ if (!gethostname(our_host_name, sizeof(our_host_name)) &&
+ (our_hostent = gethostbyname(our_host_name))) {
+ const char *hierarchy[4];
+ char **hostlist;
+
+ hostlist = (char **) NULL;
+ hierarchy[0] = "realms";
+ hierarchy[1] = realm;
+ hierarchy[2] = name;
+ hierarchy[3] = (char *) NULL;
+ if (!(kret = profile_get_values(ctx->profile, hierarchy, &hostlist))) {
+ int hi;
+ char *cport;
+ char *cp;
+ int ai;
+ krb5_int32 pport;
+
+ cport = (char *) NULL;
+ for (hi=0; hostlist[hi]; hi++) {
+ /*
+ * This knows a little too much about the format of profile
+ * entries. Shouldn't it just be some sort of tuple?
+ *
+ * The form is assumed to be:
+ * <name> = <hostname>[:<portname>[<whitespace>]]
+ */
+ pport = -1;
+ cp = strchr(hostlist[hi], ' ');
+ if (cp)
+ *cp = '\0';
+ cp = strchr(hostlist[hi], '\t');
+ if (cp)
+ *cp = '\0';
+ cport = strchr(hostlist[hi], ':');
+ if (cport) {
+ *cport = '\0';
+ cport++;
+ if (sscanf(cport, "%d", &pport) == 1) {
+ pport = -1;
+ }
+ }
+ /*
+ * We've stripped away the crud. Now check to see if the
+ * profile entry matches our hostname. If so, then this
+ * is the one to use. Additionally, check the host alias
+ * list.
+ */
+ if (!strcmp(hostlist[hi], our_hostent->h_name)) {
+ if (pport != -1) {
+ retval = pport;
+ found = 1;
+ }
+ }
+ else {
+ for (ai=0; our_hostent->h_aliases[ai]; ai++) {
+ if (!strcmp(hostlist[hi],
+ our_hostent->h_aliases[ai])) {
+ if (pport != -1) {
+ retval = pport;
+ found = 1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ krb5_xfree(hostlist);
+ }
+ }
+ /*
+ * If we didn't find an entry in the profile, then use the default.
+ * If it's no good, then attempt to find it in /etc/services.
+ */
+ if (!found) {
+ retval = defport;
+ /* Get the service entry out of /etc/services */
+ if (retval <= 0) {
+ if (our_servent = getservbyname(service, "udp"))
+ retval = ntohs(our_servent->s_port);
+ }
+ }
+ return(retval);
+}
+
+/*
+ * Convert a string of the form <int>[,<int>]* to a list of ints.
+ */
+static int *
+string2intlist(string)
+ char *string;
+{
+ int nints, i;
+ char *cp;
+ int *intlist;
+
+ for ((nints=1, cp=string); *cp; cp++)
+ if (*cp == ',')
+ nints++;
+ if (intlist = (int *) malloc((nints+1) * sizeof(int))) {
+ cp = string;
+ for (i=0; i<nints; i++) {
+ if (sscanf(cp, "%d", &intlist[i]) != 1) {
+ free(intlist);
+ intlist = (int *) NULL;
+ break;
+ }
+ while ((*cp != ',') && (*cp != '\0'))
+ cp++;
+ cp++;
+ }
+ if (intlist)
+ intlist[nints] = -1;
+ }
+ return(intlist);
+}
+
+/*
+ * Get default portlists.
+ */
+static void
+get_default_portlists(aprof, plistp, slistp)
+ krb5_pointer aprof;
+ int **plistp;
+ int **slistp;
+{
+ int *plist;
+ int *slist;
+ const char *hierarchy[3];
+ char *liststring;
+
+ plist = slist = (int *) NULL;
+ if (aprof) {
+ hierarchy[0] = "kdcdefaults";
+ hierarchy[1] = "primary_ports";
+ hierarchy[2] = (char *) NULL;
+ if (!krb5_aprof_get_string(aprof, hierarchy, TRUE, &liststring)) {
+ plist = string2intlist(liststring);
+ krb5_xfree(liststring);
+ }
+ hierarchy[1] = "secondary_ports";
+ if (!krb5_aprof_get_string(aprof, hierarchy, TRUE, &liststring)) {
+ slist = string2intlist(liststring);
+ krb5_xfree(liststring);
+ }
+ }
+ *plistp = plist;
+ *slistp = slist;
+}
+
/*
* initialize the replay cache.
*/
*/
static krb5_error_code
init_realm(progname, rdp, altp, realm, def_dbname, def_mpname,
- def_keytype, def_port, def_enctype, def_manual)
+ def_keytype, def_port, def_sport, def_enctype, def_manual)
char *progname;
kdc_realm_t *rdp;
krb5_pointer altp;
char *def_mpname;
krb5_keytype def_keytype;
krb5_int32 def_port;
+ krb5_int32 def_sport;
krb5_enctype def_enctype;
krb5_boolean def_manual;
{
if (realm) {
rdp->realm_name = realm;
if (!(kret = krb5_init_context(&rdp->realm_context))) {
- hierarchy[0] = realm;
- hierarchy[1] = "database_name";
- hierarchy[2] = (char *) NULL;
+ hierarchy[0] = "realms";
+ hierarchy[1] = realm;
+ hierarchy[2] = "profile";
+ hierarchy[3] = (char *) NULL;
+ /*
+ * Before any more per-realm initialization goes on, get the
+ * per-realm profile, if any.
+ */
+ if (altp && !(kret = krb5_aprof_get_string(altp,
+ hierarchy,
+ TRUE,
+ &rdp->realm_profile))) {
+ const char *filenames[2];
+
+ /*
+ * XXX - this knows too much about contexts.
+ */
+ filenames[0] = rdp->realm_profile;
+ filenames[1] = (char *) NULL;
+ if (rdp->realm_context->profile)
+ profile_release(rdp->realm_context->profile);
+ if (kret = profile_init(filenames,
+ &rdp->realm_context->profile)) {
+ com_err(progname, kret,
+ "while loading profile %s for realm %s",
+ rdp->realm_profile, realm);
+ goto whoops;
+ }
+ }
+
/*
* Attempt to get the real value for the database file.
*/
+ hierarchy[2] = "database_name";
if (!altp || (kret = krb5_aprof_get_string(altp,
hierarchy,
TRUE,
/*
* Attempt to get the real value for the master key name.
*/
- hierarchy[1] = "master_key_name";
+ hierarchy[2] = "master_key_name";
if (!altp || (kret = krb5_aprof_get_string(altp,
hierarchy,
TRUE,
/*
* Attempt to get the real value for the master key type.
*/
- hierarchy[1] = "master_key_type";
+ hierarchy[2] = "master_key_type";
if (!altp || (kret = krb5_aprof_get_int32(altp,
hierarchy,
TRUE,
/*
* Attempt to get the real value for the primary port.
*/
- hierarchy[1] = "port";
+ hierarchy[2] = "port";
if (!altp || (kret = krb5_aprof_get_int32(altp,
hierarchy,
TRUE,
- &rdp->realm_pport)))
- rdp->realm_pport = (def_port) ? def_port : KRB5_DEFAULT_PORT;
+ &rdp->realm_pport))) {
+ rdp->realm_pport = get_realm_port(rdp->realm_context,
+ realm,
+ "kdc",
+ def_port,
+ KDC_PORTNAME);
+ }
+
+ /*
+ * Attempt to get the real value for the secondary port.
+ */
+ hierarchy[2] = "secondary_port";
+ if (!altp || (kret = krb5_aprof_get_int32(altp,
+ hierarchy,
+ TRUE,
+ &rdp->realm_sport))) {
+ rdp->realm_sport = get_realm_port(rdp->realm_context,
+ realm,
+ "v4kdc",
+ def_sport,
+ KDC_SECONDARY_PORTNAME);
+ }
/*
* Attempt to get the real value for the encryption type.
*/
- hierarchy[1] = "encryption_type";
+ hierarchy[2] = "encryption_type";
if (!altp || (kret = krb5_aprof_get_int32(altp,
hierarchy,
TRUE,
/*
* Attempt to get the real value for the stash file.
*/
- hierarchy[1] = "key_stash_file";
+ hierarchy[2] = "key_stash_file";
if (!altp || (kret = krb5_aprof_get_string(altp,
hierarchy,
TRUE,
/*
* Attempt to get the real value for the maximum ticket life.
*/
- hierarchy[1] = "max_life";
+ hierarchy[2] = "max_life";
if (!altp || (kret = krb5_aprof_get_deltat(altp,
hierarchy,
TRUE,
* Attempt to get the real value for the maximum renewable ticket
* life.
*/
- hierarchy[1] = "max_renewable_life";
+ hierarchy[2] = "max_renewable_life";
if (!altp || (kret = krb5_aprof_get_deltat(altp,
hierarchy,
TRUE,
krb5_enctype kdc_etype = DEFAULT_KDC_ETYPE;
kdc_realm_t *rdatap;
krb5_boolean manual = FALSE;
- krb5_int32 pport;
+ krb5_int32 pport, sport;
extern char *optarg;
+ pport = sport = -1;
/*
* Loop through the option list. Each time we encounter a realm name,
* use the previously scanned options to fill in for defaults.
*/
- while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:n")) != EOF) {
+ while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n")) != EOF) {
switch(c) {
case 'r': /* realm name for db */
if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
mkey_name,
mkeytype,
pport,
+ sport,
kdc_etype,
manual)) {
fprintf(stderr,"%s: cannot initialize realm %s\n",
case 'p':
pport = atoi(optarg);
break;
+ case 's':
+ sport = atoi(optarg);
+ break;
case 'e':
kdc_etype = atoi(optarg);
break;
mkey_name,
mkeytype,
pport,
+ sport,
kdc_etype,
manual)) {
fprintf(stderr,"%s: cannot initialize realm %s\n",
krb5_error_code retval;
krb5_context kcontext;
krb5_pointer alt_profile;
+ int *primaries, *secondaries;
int errout = 0;
if (strrchr(argv[0], '/'))
}
memset((char *) kdc_realmlist, 0,
(size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS));
+ primaries = secondaries = (int *) NULL;
/*
* A note about Kerberos contexts: This context, "kcontext", is used
*/
initialize_realms(kcontext, alt_profile, argc, argv);
+ /*
+ * Get the default port lists.
+ */
+ get_default_portlists(alt_profile, &primaries, &secondaries);
+
if (alt_profile)
krb5_aprof_finish(alt_profile);
setup_signal_handlers();
- if ((retval = setup_network(argv[0]))) {
+ if ((retval = setup_network(argv[0], primaries, secondaries))) {
com_err(argv[0], retval, "while initializing network");
finish_realms(argv[0]);
return 1;
krb5_klog_syslog(LOG_INFO, "shutting down");
krb5_klog_close(kdc_context);
finish_realms(argv[0]);
+ if (primaries)
+ free(primaries);
+ if (secondaries)
+ free(secondaries);
return errout;
}
#include <sys/select.h>
#endif
#include <arpa/inet.h>
-#include <netdb.h>
extern int errno;
static int *udp_port_fds = (int *) NULL;
static u_short *udp_port_nums = (u_short *) NULL;
-static int sec_udp_port_fd = -1;
+static int n_udp_ports = 0;
+static int *sec_udp_port_fds = (int *) NULL;
+static u_short *sec_udp_port_nums = (u_short *) NULL;
+static int n_sec_udp_ports = 0;
static fd_set select_fds;
static int select_nfds;
krb5_error_code
-setup_network(prog)
+setup_network(prog, p_ports, s_ports)
const char *prog;
+int *p_ports;
+int *s_ports;
{
struct servent *sp;
struct sockaddr_in sin;
krb5_error_code retval;
- u_short default_port;
int i, j, found;
+ int npports, nsports;
FD_ZERO(&select_fds);
select_nfds = 0;
memset((char *)&sin, 0, sizeof(sin));
- sp = getservbyname(KDC_PORTNAME, "udp");
- default_port = (sp) ? ntohs(sp->s_port) : KRB5_DEFAULT_PORT;
- if ((udp_port_fds = (int *) malloc(kdc_numrealms * sizeof(int))) &&
- (udp_port_nums = (u_short *) malloc(kdc_numrealms * sizeof(u_short)))
- ) {
- for (i=0; i<kdc_numrealms; i++) {
+
+ /*
+ * Count the number of primary and secondary ports supplied to us.
+ */
+ npports = 0;
+ if (p_ports)
+ for (npports=0; p_ports[npports] > 0; npports++);
+ nsports = 0;
+ if (s_ports)
+ for (nsports=0; s_ports[nsports] > 0; nsports++);
+
+ /*
+ * Now handle the primary ports.
+ */
+ if ((udp_port_fds = (int *) malloc((kdc_numrealms+npports)
+ * sizeof(int))) &&
+ (udp_port_nums = (u_short *) malloc((kdc_numrealms+npports)
+ * sizeof(u_short)))) {
+ /* Zero it out */
+ for (i=0; i<(kdc_numrealms+npports); i++) {
udp_port_fds[i] = -1;
udp_port_nums[i] = 0;
}
- for (i=0; i<kdc_numrealms; i++) {
+ /*
+ * First handle any explicitly named primary ports.
+ */
+ for (i=0; i<npports; i++) {
found = 0;
for (j=0; j<i; j++) {
- if (udp_port_nums[j] == kdc_realmlist[i]->realm_pport) {
+ if (udp_port_nums[j] == p_ports[i]) {
found = 1;
break;
}
if ((udp_port_fds[i] = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
retval = errno;
com_err(prog, 0, "Cannot create server socket on port %d",
- kdc_realmlist[i]->realm_pport);
+ p_ports[i]);
return(retval);
}
- udp_port_nums[i] = kdc_realmlist[i]->realm_pport;
- sin.sin_port = htons(kdc_realmlist[i]->realm_pport);
+ udp_port_nums[i] = p_ports[i];
+ sin.sin_port = htons(p_ports[i]);
if (bind(udp_port_fds[i],
(struct sockaddr *) &sin,
sizeof(sin)) == -1) {
retval = errno;
com_err(prog, 0, "Cannot bind server socket on port %d",
- kdc_realmlist[i]->realm_pport);
+ p_ports[i]);
return(retval);
}
FD_SET(udp_port_fds[i], &select_fds);
udp_port_nums[i] = udp_port_nums[j];
}
}
+
+ /* Now handle each realm */
+ for (i=0; i<kdc_numrealms; i++) {
+ found = 0;
+ for (j=0; j<(npports+i); j++) {
+ if (udp_port_nums[j] == kdc_realmlist[i]->realm_pport) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ if ((udp_port_fds[npports+i] =
+ socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
+ retval = errno;
+ com_err(prog, 0, "Cannot create server socket on port %d",
+ kdc_realmlist[i]->realm_pport);
+ return(retval);
+ }
+ udp_port_nums[npports+i] = kdc_realmlist[i]->realm_pport;
+ sin.sin_port = htons(kdc_realmlist[i]->realm_pport);
+ if (bind(udp_port_fds[npports+i],
+ (struct sockaddr *) &sin,
+ sizeof(sin)) == -1) {
+ retval = errno;
+ com_err(prog, 0, "Cannot bind server socket on port %d",
+ kdc_realmlist[i]->realm_pport);
+ return(retval);
+ }
+ FD_SET(udp_port_fds[npports+i], &select_fds);
+ if (udp_port_fds[npports+i]+1 > select_nfds)
+ select_nfds = udp_port_fds[npports+i]+1;
+ }
+ else {
+ udp_port_fds[npports+i] = udp_port_fds[j];
+ udp_port_nums[npports+i] = udp_port_nums[j];
+ }
+ }
+ n_udp_ports = kdc_numrealms + npports;
}
/*
- * Now we set up the secondary listening port
+ * Now we set up the secondary listening ports. Special case here.
+ * If the first secondary port is -1, then we don't listen on secondary
+ * ports.
*/
+ if ((!s_ports || (s_ports[0] != -1)) &&
+ (sec_udp_port_fds = (int *) malloc((kdc_numrealms+nsports)
+ * sizeof(int))) &&
+ (sec_udp_port_nums = (u_short *) malloc((kdc_numrealms+nsports)
+ * sizeof(u_short)))) {
+ /* Zero it out */
+ for (i=0; i<(kdc_numrealms+nsports); i++) {
+ sec_udp_port_fds[i] = -1;
+ sec_udp_port_nums[i] = 0;
+ }
- sp = getservbyname(KDC_SECONDARY_PORTNAME, "udp");
- if (!sp && sin.sin_port == htons(KRB5_DEFAULT_SEC_PORT)) {
- com_err(prog, 0, "%s/udp service unknown\n",
- KDC_SECONDARY_PORTNAME);
- return 0; /* Don't give an error if we can't */
- /* find it */
- }
- if ((sec_udp_port_fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
- com_err(prog, errno, "while trying to create secondary server socket");
- return 0; /* Don't give an error we we can't do this */
- }
- memset((char *)&sin, 0, sizeof(sin));
- sin.sin_port = sp ? sp->s_port : htons(KRB5_DEFAULT_SEC_PORT);
- if (bind(sec_udp_port_fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
- com_err(prog, errno, "while trying to bind secondary server socket");
- return 0; /* Don't give an error if we can't do this */
+ /*
+ * First handle any explicitly named secondary ports.
+ */
+ for (i=0; i<nsports; i++) {
+ found = 0;
+ for (j=0; j<i; j++) {
+ if (sec_udp_port_nums[j] == s_ports[i]) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ if ((sec_udp_port_fds[i] =
+ socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
+ retval = errno;
+ com_err(prog, 0,
+ "Cannot create secondary server socket on port %d",
+ s_ports[i]);
+ return(retval);
+ }
+ sec_udp_port_nums[i] = s_ports[i];
+ sin.sin_port = htons(s_ports[i]);
+ if (bind(sec_udp_port_fds[i],
+ (struct sockaddr *) &sin,
+ sizeof(sin)) == -1) {
+ retval = errno;
+ com_err(prog, 0,
+ "Cannot bind secondary server socket on port %d",
+ s_ports[i]);
+ close(sec_udp_port_fds[i]);
+ sec_udp_port_fds[i] = -1;
+ continue;
+ }
+ FD_SET(sec_udp_port_fds[i], &select_fds);
+ if (sec_udp_port_fds[i]+1 > select_nfds)
+ select_nfds = sec_udp_port_fds[i]+1;
+ }
+ else {
+ sec_udp_port_fds[i] = sec_udp_port_fds[j];
+ sec_udp_port_nums[i] = sec_udp_port_nums[j];
+ }
+ }
+
+ /* Now handle each realm */
+ for (i=0; i<kdc_numrealms; i++) {
+ if (kdc_realmlist[i]->realm_sport > 0) {
+ found = 0;
+ for (j=0; j<(nsports+i); j++) {
+ if (sec_udp_port_nums[j] ==
+ kdc_realmlist[i]->realm_sport) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found && (kdc_realmlist[i]->realm_sport > 0)) {
+ if ((sec_udp_port_fds[nsports+i] =
+ socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
+ retval = errno;
+ com_err(prog, 0,
+ "Cannot create secondary server socket on port %d",
+ kdc_realmlist[i]->realm_sport);
+ return(retval);
+ }
+ sec_udp_port_nums[nsports+i] =
+ kdc_realmlist[i]->realm_sport;
+ sin.sin_port = htons(kdc_realmlist[i]->realm_sport);
+ if (bind(sec_udp_port_fds[nsports+i],
+ (struct sockaddr *) &sin,
+ sizeof(sin)) == -1) {
+ retval = errno;
+ com_err(prog, 0,
+ "Cannot bind secondary server socket on port %d",
+ kdc_realmlist[i]->realm_sport);
+ close(sec_udp_port_fds[nsports+i]);
+ sec_udp_port_fds[nsports+i] = -1;
+ continue;
+ }
+ FD_SET(sec_udp_port_fds[nsports+i], &select_fds);
+ if (sec_udp_port_fds[nsports+i]+1 > select_nfds)
+ select_nfds = sec_udp_port_fds[nsports+i]+1;
+ }
+ else {
+ if (kdc_realmlist[i]->realm_sport > 0) {
+ sec_udp_port_fds[nsports+i] = sec_udp_port_fds[j];
+ sec_udp_port_nums[nsports+i] = sec_udp_port_nums[j];
+ }
+ else {
+ sec_udp_port_fds[nsports+i] = -1;
+ sec_udp_port_nums[nsports+i] = -1;
+ }
+ }
+ }
+ }
+ n_sec_udp_ports = kdc_numrealms + nsports;
}
- FD_SET(sec_udp_port_fd, &select_fds);
- if (sec_udp_port_fd+1 > select_nfds)
- select_nfds = sec_udp_port_fd+1;
-
return 0;
}
int nfound;
fd_set readfds;
int i;
+ int fdfound;
if (udp_port_fds == (int *) NULL)
return KDC5_NONET;
com_err(prog, errno, "while selecting for network input");
continue;
}
- for (i=0; i<kdc_numrealms; i++) {
- if (FD_ISSET(udp_port_fds[i], &readfds))
+ fdfound = 0;
+ for (i=0; i<n_udp_ports; i++) {
+ if (FD_ISSET(udp_port_fds[i], &readfds)) {
process_packet(udp_port_fds[i], prog, 0);
+ fdfound = 1;
+ break;
+ }
}
- if ((sec_udp_port_fd > 0) && FD_ISSET(sec_udp_port_fd, &readfds))
- process_packet(sec_udp_port_fd, prog, 1);
+ if (!fdfound) {
+ for (i=0; i<n_sec_udp_ports; i++) {
+ if (FD_ISSET(sec_udp_port_fds[i], &readfds)) {
+ process_packet(sec_udp_port_fds[i], prog, 1);
+ fdfound = 1;
+ break;
+ }
+ }
+ }
}
return 0;
}
if (udp_port_fds == (int *) NULL)
return KDC5_NONET;
- for (i=0; i<kdc_numrealms; i++)
- (void) close(udp_port_fds[i]);
+ for (i=0; i<n_udp_ports; i++) {
+ if (udp_port_fds[i] >= 0)
+ (void) close(udp_port_fds[i]);
+ }
free(udp_port_fds);
free(udp_port_nums);
- if (sec_udp_port_fd != -1)
- (void) close(sec_udp_port_fd);
- sec_udp_port_fd = -1;
+ for (i=0; i<n_sec_udp_ports; i++) {
+ if (sec_udp_port_fds[i] >= 0)
+ (void) close(sec_udp_port_fds[i]);
+ }
+ free(sec_udp_port_fds);
+ free(sec_udp_port_nums);
+
return 0;
}