Add probing from the server that the client is still there, also make
the client check that the server is probing. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@12419 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -46,6 +46,8 @@
|
|||||||
#include <util.h>
|
#include <util.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <parse_time.h>
|
||||||
|
|
||||||
#define IPROP_VERSION "iprop-0.0"
|
#define IPROP_VERSION "iprop-0.0"
|
||||||
|
|
||||||
#define KADM5_SLAVE_ACL HDB_DB_DIR "/slaves"
|
#define KADM5_SLAVE_ACL HDB_DB_DIR "/slaves"
|
||||||
@@ -62,7 +64,9 @@ enum iprop_cmd { I_HAVE = 1,
|
|||||||
FOR_YOU = 2,
|
FOR_YOU = 2,
|
||||||
TELL_YOU_EVERYTHING = 3,
|
TELL_YOU_EVERYTHING = 3,
|
||||||
ONE_PRINC = 4,
|
ONE_PRINC = 4,
|
||||||
NOW_YOU_HAVE = 5
|
NOW_YOU_HAVE = 5,
|
||||||
|
ARE_YOU_THERE = 6,
|
||||||
|
I_AM_HERE = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __IPROP_H__ */
|
#endif /* __IPROP_H__ */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997 - 2002 Kungliga Tekniska H<>gskolan
|
* Copyright (c) 1997 - 2003 Kungliga Tekniska H<>gskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -39,6 +39,11 @@ RCSID("$Id$");
|
|||||||
static krb5_log_facility *log_facility;
|
static krb5_log_facility *log_facility;
|
||||||
|
|
||||||
const char *slave_stats_file = KADM5_SLAVE_STATS;
|
const char *slave_stats_file = KADM5_SLAVE_STATS;
|
||||||
|
const char *slave_time_missing = "2 min";
|
||||||
|
const char *slave_time_gone = "5 min";
|
||||||
|
|
||||||
|
static int time_before_missing;
|
||||||
|
static int time_before_gone;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
make_signal_socket (krb5_context context)
|
make_signal_socket (krb5_context context)
|
||||||
@@ -122,6 +127,22 @@ slave_seen(slave *s)
|
|||||||
s->seen = time(NULL);
|
s->seen = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
slave_missing_p (slave *s)
|
||||||
|
{
|
||||||
|
if (time(NULL) > s->seen + time_before_missing)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
slave_gone_p (slave *s)
|
||||||
|
{
|
||||||
|
if (time(NULL) > s->seen + time_before_gone)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
slave_dead(slave *s)
|
slave_dead(slave *s)
|
||||||
{
|
{
|
||||||
@@ -316,6 +337,35 @@ send_complete (krb5_context context, slave *s,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
send_are_you_there (krb5_context context, slave *s)
|
||||||
|
{
|
||||||
|
krb5_data data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (s->flags & SLAVE_F_DEAD)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = krb5_data_alloc (&data, 4);
|
||||||
|
if (ret) {
|
||||||
|
krb5_warn (context, ret, "are_you_there: krb5_data_alloc");
|
||||||
|
slave_dead(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
_krb5_put_int(data.data, ARE_YOU_THERE, 4);
|
||||||
|
|
||||||
|
ret = krb5_write_priv_message(context, s->ac, &s->fd, &data);
|
||||||
|
krb5_data_free(&data);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
krb5_warn (context, ret, "are_you_there: krb5_write_priv_message");
|
||||||
|
slave_dead(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
send_diffs (krb5_context context, slave *s, int log_fd,
|
send_diffs (krb5_context context, slave *s, int log_fd,
|
||||||
const char *database, u_int32_t current_version)
|
const char *database, u_int32_t current_version)
|
||||||
@@ -348,7 +398,12 @@ send_diffs (krb5_context context, slave *s, int log_fd,
|
|||||||
if (left == 0)
|
if (left == 0)
|
||||||
return send_complete (context, s, database, current_version);
|
return send_complete (context, s, database, current_version);
|
||||||
}
|
}
|
||||||
krb5_data_alloc (&data, right - left + 4);
|
ret = krb5_data_alloc (&data, right - left + 4);
|
||||||
|
if (ret) {
|
||||||
|
krb5_warn (context, ret, "send_diffs: krb5_data_alloc");
|
||||||
|
slave_dead(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
krb5_storage_read (sp, (char *)data.data + 4, data.length - 4);
|
krb5_storage_read (sp, (char *)data.data + 4, data.length - 4);
|
||||||
krb5_storage_free(sp);
|
krb5_storage_free(sp);
|
||||||
|
|
||||||
@@ -358,7 +413,7 @@ send_diffs (krb5_context context, slave *s, int log_fd,
|
|||||||
krb5_data_free(&data);
|
krb5_data_free(&data);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_warn (context, ret, "krb5_write_priv_message");
|
krb5_warn (context, ret, "send_diffs: krb5_write_priv_message");
|
||||||
slave_dead(s);
|
slave_dead(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -383,13 +438,29 @@ process_msg (krb5_context context, slave *s, int log_fd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sp = krb5_storage_from_mem (out.data, out.length);
|
sp = krb5_storage_from_mem (out.data, out.length);
|
||||||
krb5_ret_int32 (sp, &tmp);
|
if (sp == NULL) {
|
||||||
|
krb5_warnx (context, "process_msg: no memory");
|
||||||
|
krb5_data_free (&out);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (krb5_ret_int32 (sp, &tmp) != 0) {
|
||||||
|
krb5_warnx (context, "process_msg: client send too short command");
|
||||||
|
krb5_data_free (&out);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
switch (tmp) {
|
switch (tmp) {
|
||||||
case I_HAVE :
|
case I_HAVE :
|
||||||
krb5_ret_int32 (sp, &tmp);
|
ret = krb5_ret_int32 (sp, &tmp);
|
||||||
|
if (ret != 0) {
|
||||||
|
krb5_warnx (context, "process_msg: client send too I_HAVE data");
|
||||||
|
break;
|
||||||
|
}
|
||||||
s->version = tmp;
|
s->version = tmp;
|
||||||
ret = send_diffs (context, s, log_fd, database, current_version);
|
ret = send_diffs (context, s, log_fd, database, current_version);
|
||||||
break;
|
break;
|
||||||
|
case I_AM_HERE :
|
||||||
|
break;
|
||||||
|
case ARE_YOU_THERE:
|
||||||
case FOR_YOU :
|
case FOR_YOU :
|
||||||
default :
|
default :
|
||||||
krb5_warnx (context, "Ignoring command %d", tmp);
|
krb5_warnx (context, "Ignoring command %d", tmp);
|
||||||
@@ -490,6 +561,8 @@ static struct getargs args[] = {
|
|||||||
"keytab to get authentication from", "kspec" },
|
"keytab to get authentication from", "kspec" },
|
||||||
{ "database", 'd', arg_string, &database, "database", "file"},
|
{ "database", 'd', arg_string, &database, "database", "file"},
|
||||||
{ "slave-stats-file", 0, arg_string, &slave_stats_file, "file"},
|
{ "slave-stats-file", 0, arg_string, &slave_stats_file, "file"},
|
||||||
|
{ "time-missing", 0, arg_string, &slave_time_missing, "time"},
|
||||||
|
{ "time-gone", 0, arg_string, &slave_time_gone, "time"},
|
||||||
{ "version", 0, arg_flag, &version_flag },
|
{ "version", 0, arg_flag, &version_flag },
|
||||||
{ "help", 0, arg_flag, &help_flag }
|
{ "help", 0, arg_flag, &help_flag }
|
||||||
};
|
};
|
||||||
@@ -519,6 +592,13 @@ main(int argc, char **argv)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_before_gone = parse_time (slave_time_gone, "s");
|
||||||
|
if (time_before_gone < 0)
|
||||||
|
krb5_errx (context, 1, "couldn't parse time: %s", slave_time_gone);
|
||||||
|
time_before_missing = parse_time (slave_time_missing, "s");
|
||||||
|
if (time_before_missing < 0)
|
||||||
|
krb5_errx (context, 1, "couldn't parse time: %s", slave_time_missing);
|
||||||
|
|
||||||
pidfile (NULL);
|
pidfile (NULL);
|
||||||
krb5_openlog (context, "ipropd-master", &log_facility);
|
krb5_openlog (context, "ipropd-master", &log_facility);
|
||||||
krb5_set_warn_dest(context, log_facility);
|
krb5_set_warn_dest(context, log_facility);
|
||||||
@@ -593,13 +673,14 @@ main(int argc, char **argv)
|
|||||||
old_version = current_version;
|
old_version = current_version;
|
||||||
kadm5_log_get_version_fd (log_fd, ¤t_version);
|
kadm5_log_get_version_fd (log_fd, ¤t_version);
|
||||||
|
|
||||||
if (current_version > old_version)
|
if (current_version > old_version) {
|
||||||
for (p = slaves; p != NULL; p = p->next) {
|
for (p = slaves; p != NULL; p = p->next) {
|
||||||
if (p->flags & SLAVE_F_DEAD)
|
if (p->flags & SLAVE_F_DEAD)
|
||||||
continue;
|
continue;
|
||||||
send_diffs (context, p, log_fd, database, current_version);
|
send_diffs (context, p, log_fd, database, current_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ret && FD_ISSET(signal_fd, &readset)) {
|
if (ret && FD_ISSET(signal_fd, &readset)) {
|
||||||
struct sockaddr_un peer_addr;
|
struct sockaddr_un peer_addr;
|
||||||
@@ -624,7 +705,10 @@ main(int argc, char **argv)
|
|||||||
--ret;
|
--ret;
|
||||||
if(process_msg (context, p, log_fd, database, current_version))
|
if(process_msg (context, p, log_fd, database, current_version))
|
||||||
slave_dead(p);
|
slave_dead(p);
|
||||||
}
|
} else if (slave_gone_p (p))
|
||||||
|
slave_dead (p);
|
||||||
|
else if (slave_missing_p (p))
|
||||||
|
send_are_you_there (context, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret && FD_ISSET(listen_fd, &readset)) {
|
if (ret && FD_ISSET(listen_fd, &readset)) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997 - 2002 Kungliga Tekniska H<>gskolan
|
* Copyright (c) 1997 - 2003 Kungliga Tekniska H<>gskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -36,6 +36,8 @@
|
|||||||
RCSID("$Id$");
|
RCSID("$Id$");
|
||||||
|
|
||||||
static krb5_log_facility *log_facility;
|
static krb5_log_facility *log_facility;
|
||||||
|
static char *server_time_lost = "5 min";
|
||||||
|
static int time_before_lost;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
connect_to_master (krb5_context context, const char *master)
|
connect_to_master (krb5_context context, const char *master)
|
||||||
@@ -191,7 +193,7 @@ receive_loop (krb5_context context,
|
|||||||
ret = kadm5_log_replay (server_context,
|
ret = kadm5_log_replay (server_context,
|
||||||
op, vers, len, sp);
|
op, vers, len, sp);
|
||||||
if (ret)
|
if (ret)
|
||||||
krb5_warn (context, ret, "kadm5_log_replay");
|
krb5_warn (context, ret, "kadm5_log_replay: %d", (int)vers);
|
||||||
else
|
else
|
||||||
server_context->log_context.version = vers;
|
server_context->log_context.version = vers;
|
||||||
krb5_storage_seek (sp, 8, SEEK_CUR);
|
krb5_storage_seek (sp, 8, SEEK_CUR);
|
||||||
@@ -218,6 +220,26 @@ receive (krb5_context context,
|
|||||||
krb5_err (context, 1, ret, "db->close");
|
krb5_err (context, 1, ret, "db->close");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_im_here (krb5_context context, int fd,
|
||||||
|
krb5_auth_context auth_context)
|
||||||
|
{
|
||||||
|
krb5_data data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = krb5_data_alloc (&data, 4);
|
||||||
|
if (ret)
|
||||||
|
krb5_err (context, 1, ret, "send_im_here");
|
||||||
|
|
||||||
|
_krb5_put_int(data.data, I_AM_HERE, 4);
|
||||||
|
|
||||||
|
ret = krb5_write_priv_message(context, auth_context, &fd, &data);
|
||||||
|
krb5_data_free(&data);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
krb5_err (context, 1, ret, "krb5_write_priv_message");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
receive_everything (krb5_context context, int fd,
|
receive_everything (krb5_context context, int fd,
|
||||||
kadm5_server_context *server_context,
|
kadm5_server_context *server_context,
|
||||||
@@ -321,6 +343,8 @@ static struct getargs args[] = {
|
|||||||
{ "realm", 'r', arg_string, &realm },
|
{ "realm", 'r', arg_string, &realm },
|
||||||
{ "keytab", 'k', arg_string, &keytab_str,
|
{ "keytab", 'k', arg_string, &keytab_str,
|
||||||
"keytab to get authentication from", "kspec" },
|
"keytab to get authentication from", "kspec" },
|
||||||
|
{ "time-lost", 0, arg_string, &server_time_lost,
|
||||||
|
"time before server is considered lost", "time" },
|
||||||
{ "version", 0, arg_flag, &version_flag },
|
{ "version", 0, arg_flag, &version_flag },
|
||||||
{ "help", 0, arg_flag, &help_flag }
|
{ "help", 0, arg_flag, &help_flag }
|
||||||
};
|
};
|
||||||
@@ -375,6 +399,10 @@ main(int argc, char **argv)
|
|||||||
if(ret)
|
if(ret)
|
||||||
krb5_err(context, 1, ret, "krb5_kt_register");
|
krb5_err(context, 1, ret, "krb5_kt_register");
|
||||||
|
|
||||||
|
time_before_lost = parse_time (server_time_lost, "s");
|
||||||
|
if (time_before_lost < 0)
|
||||||
|
krb5_errx (context, 1, "couldn't parse time: %s", server_time_lost);
|
||||||
|
|
||||||
memset(&conf, 0, sizeof(conf));
|
memset(&conf, 0, sizeof(conf));
|
||||||
if(realm) {
|
if(realm) {
|
||||||
conf.mask |= KADM5_CONFIG_REALM;
|
conf.mask |= KADM5_CONFIG_REALM;
|
||||||
@@ -420,6 +448,29 @@ main(int argc, char **argv)
|
|||||||
krb5_data out;
|
krb5_data out;
|
||||||
krb5_storage *sp;
|
krb5_storage *sp;
|
||||||
int32_t tmp;
|
int32_t tmp;
|
||||||
|
fd_set readset;
|
||||||
|
struct timeval to;
|
||||||
|
|
||||||
|
if (master_fd >= FD_SETSIZE)
|
||||||
|
krb5_errx (context, 1, "fd too large");
|
||||||
|
|
||||||
|
FD_ZERO(&readset);
|
||||||
|
FD_SET(master_fd, &readset);
|
||||||
|
|
||||||
|
to.tv_sec = time_before_lost;
|
||||||
|
to.tv_usec = 0;
|
||||||
|
|
||||||
|
ret = select (master_fd + 1,
|
||||||
|
&readset, NULL, NULL, &to);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
krb5_err (context, 1, errno, "select");
|
||||||
|
}
|
||||||
|
if (ret == 0)
|
||||||
|
krb5_errx (context, 1, "server didn't send a message "
|
||||||
|
"in %d seconds", time_before_lost);
|
||||||
|
|
||||||
ret = krb5_read_priv_message(context, auth_context, &master_fd, &out);
|
ret = krb5_read_priv_message(context, auth_context, &master_fd, &out);
|
||||||
|
|
||||||
@@ -438,9 +489,13 @@ main(int argc, char **argv)
|
|||||||
receive_everything (context, master_fd, server_context,
|
receive_everything (context, master_fd, server_context,
|
||||||
auth_context);
|
auth_context);
|
||||||
break;
|
break;
|
||||||
|
case ARE_YOU_THERE :
|
||||||
|
send_im_here (context, master_fd, auth_context);
|
||||||
|
break;
|
||||||
case NOW_YOU_HAVE :
|
case NOW_YOU_HAVE :
|
||||||
case I_HAVE :
|
case I_HAVE :
|
||||||
case ONE_PRINC :
|
case ONE_PRINC :
|
||||||
|
case I_AM_HERE :
|
||||||
default :
|
default :
|
||||||
krb5_warnx (context, "Ignoring command %d", tmp);
|
krb5_warnx (context, "Ignoring command %d", tmp);
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user