summaryrefslogtreecommitdiffstats
path: root/src/kadmin
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2008-06-24 05:04:29 +0000
committerKen Raeburn <raeburn@mit.edu>2008-06-24 05:04:29 +0000
commit5661d1290f74312a405db970aea097da77706f71 (patch)
tree0ab69c8078ef3275b99a3ad27f3592b607e43f70 /src/kadmin
parent6879f371402854465e5276d36e4792938906097f (diff)
downloadkrb5-5661d1290f74312a405db970aea097da77706f71.tar.gz
krb5-5661d1290f74312a405db970aea097da77706f71.tar.xz
krb5-5661d1290f74312a405db970aea097da77706f71.zip
Merge from branch sun-iprop
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20465 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kadmin')
-rw-r--r--src/kadmin/cli/kadmin.M14
-rw-r--r--src/kadmin/cli/kadmin.c13
-rw-r--r--src/kadmin/dbutil/Makefile.in42
-rw-r--r--src/kadmin/dbutil/dump.c193
-rw-r--r--src/kadmin/dbutil/kadm5_create.c1
-rw-r--r--src/kadmin/dbutil/kdb5_create.c39
-rw-r--r--src/kadmin/dbutil/kdb5_destroy.c6
-rw-r--r--src/kadmin/dbutil/kdb5_util.c7
-rw-r--r--src/kadmin/dbutil/kdb5_util.h5
-rw-r--r--src/kadmin/server/Makefile.in35
-rw-r--r--src/kadmin/server/ipropd_svc.c615
-rw-r--r--src/kadmin/server/kadm_rpc_svc.c9
-rw-r--r--src/kadmin/server/kadmind.M19
-rw-r--r--src/kadmin/server/misc.h4
-rw-r--r--src/kadmin/server/ovsec_kadmd.c269
-rw-r--r--src/kadmin/server/server_stubs.c5
16 files changed, 1198 insertions, 78 deletions
diff --git a/src/kadmin/cli/kadmin.M b/src/kadmin/cli/kadmin.M
index 76dee5c48a..165bf0c736 100644
--- a/src/kadmin/cli/kadmin.M
+++ b/src/kadmin/cli/kadmin.M
@@ -71,6 +71,20 @@ except for database dump and load, which is now provided by the
utility.
.PP
If the database is LDAP, kadmin.local need not be run on the KDC.
+.PP
+kadmin.local can be configured to log updates for incremental database
+propagation. Incremental propagation allows slave KDC servers to
+receive principal and policy updates incrementally instead of
+receiving full dumps of the database. This facility can be enabled in
+the
+.I kdc.conf
+file with the
+.I iprop_enable
+option. See the
+.I kdc.conf
+documentation for other options for tuning incremental propagation
+parameters.
+
.SH OPTIONS
.TP
\fB\-r\fP \fIrealm\fP
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
index 98ff995008..02394e7f02 100644
--- a/src/kadmin/cli/kadmin.c
+++ b/src/kadmin/cli/kadmin.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1994 by the Massachusetts Institute of Technology.
+ * Copyright 1994, 2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -24,7 +24,13 @@
* kadmin.c: base functions for a kadmin command line interface using
* the OVSecure library
*/
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/* for "_" macro */
+#include "k5-platform.h"
#include <krb5.h>
#include <kadm5/admin.h>
#include <adm_proto.h>
@@ -551,6 +557,11 @@ char *kadmin_startup(argc, argv)
krb5_defkeyname = DEFAULT_KEYTAB;
}
+ if ((retval = kadm5_init_iprop(handle)) != 0) {
+ com_err(whoami, retval, _("while mapping update log"));
+ exit(1);
+ }
+
return query;
}
diff --git a/src/kadmin/dbutil/Makefile.in b/src/kadmin/dbutil/Makefile.in
index a7fa1778e9..5d480df4c3 100644
--- a/src/kadmin/dbutil/Makefile.in
+++ b/src/kadmin/dbutil/Makefile.in
@@ -4,7 +4,7 @@ mydir=kadmin/dbutil
BUILDTOP=$(REL)..$(S)..
DEFINES = -DKDB4_DISABLE
DEFS=
-LOCALINCLUDES = -I. @KRB4_INCLUDES@
+LOCALINCLUDES = -I. @KRB4_INCLUDES@
PROG_LIBPATH=-L$(TOPLIBD) $(KRB4_LIBPATH)
PROG_RPATH=$(KRB5_LIBDIR)
KDB_DEP_LIB=$(DL_LIB) $(THREAD_LINKOPTS)
@@ -50,13 +50,15 @@ $(OUTPRE)kdb5_util.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/gssrpc/clnt.h $(SRCTOP)/include/gssrpc/rename.h \
$(SRCTOP)/include/gssrpc/rpc.h $(SRCTOP)/include/gssrpc/rpc_msg.h \
$(SRCTOP)/include/gssrpc/svc.h $(SRCTOP)/include/gssrpc/svc_auth.h \
- $(SRCTOP)/include/gssrpc/xdr.h $(SRCTOP)/include/k5-err.h \
+ $(SRCTOP)/include/gssrpc/xdr.h $(SRCTOP)/include/iprop.h \
+ $(SRCTOP)/include/iprop_hdr.h $(SRCTOP)/include/k5-err.h \
$(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
$(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
$(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/kdb.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
- $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h kdb5_util.c kdb5_util.h
+ $(SRCTOP)/include/kdb_log.h $(SRCTOP)/include/krb5.h \
+ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ kdb5_util.c kdb5_util.h
$(OUTPRE)kdb5_create.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/admin_internal.h \
@@ -68,13 +70,15 @@ $(OUTPRE)kdb5_create.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/gssrpc/clnt.h $(SRCTOP)/include/gssrpc/rename.h \
$(SRCTOP)/include/gssrpc/rpc.h $(SRCTOP)/include/gssrpc/rpc_msg.h \
$(SRCTOP)/include/gssrpc/svc.h $(SRCTOP)/include/gssrpc/svc_auth.h \
- $(SRCTOP)/include/gssrpc/xdr.h $(SRCTOP)/include/k5-err.h \
+ $(SRCTOP)/include/gssrpc/xdr.h $(SRCTOP)/include/iprop.h \
+ $(SRCTOP)/include/iprop_hdr.h $(SRCTOP)/include/k5-err.h \
$(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
$(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
$(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/kdb.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
- $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h kdb5_create.c kdb5_util.h
+ $(SRCTOP)/include/kdb_log.h $(SRCTOP)/include/krb5.h \
+ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ kdb5_create.c kdb5_util.h
$(OUTPRE)kadm5_create.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
@@ -86,10 +90,12 @@ $(OUTPRE)kadm5_create.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/gssrpc/rename.h $(SRCTOP)/include/gssrpc/rpc.h \
$(SRCTOP)/include/gssrpc/rpc_msg.h $(SRCTOP)/include/gssrpc/svc.h \
$(SRCTOP)/include/gssrpc/svc_auth.h $(SRCTOP)/include/gssrpc/xdr.h \
+ $(SRCTOP)/include/iprop.h $(SRCTOP)/include/iprop_hdr.h \
$(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-int-pkinit.h \
$(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
$(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/kdb.h $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
+ $(SRCTOP)/include/kdb.h $(SRCTOP)/include/kdb_log.h \
+ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
$(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
$(SRCTOP)/include/socket-utils.h kadm5_create.c kdb5_util.h \
string_table.h
@@ -104,10 +110,12 @@ $(OUTPRE)kdb5_destroy.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/gssrpc/rename.h $(SRCTOP)/include/gssrpc/rpc.h \
$(SRCTOP)/include/gssrpc/rpc_msg.h $(SRCTOP)/include/gssrpc/svc.h \
$(SRCTOP)/include/gssrpc/svc_auth.h $(SRCTOP)/include/gssrpc/xdr.h \
+ $(SRCTOP)/include/iprop.h $(SRCTOP)/include/iprop_hdr.h \
$(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-int-pkinit.h \
$(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
$(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/kdb.h $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
+ $(SRCTOP)/include/kdb.h $(SRCTOP)/include/kdb_log.h \
+ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
$(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
$(SRCTOP)/include/socket-utils.h kdb5_destroy.c kdb5_util.h
$(OUTPRE)kdb5_stash.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
@@ -120,10 +128,12 @@ $(OUTPRE)kdb5_stash.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/gssrpc/rename.h $(SRCTOP)/include/gssrpc/rpc.h \
$(SRCTOP)/include/gssrpc/rpc_msg.h $(SRCTOP)/include/gssrpc/svc.h \
$(SRCTOP)/include/gssrpc/svc_auth.h $(SRCTOP)/include/gssrpc/xdr.h \
+ $(SRCTOP)/include/iprop.h $(SRCTOP)/include/iprop_hdr.h \
$(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-int-pkinit.h \
$(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
$(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/kdb.h $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
+ $(SRCTOP)/include/kdb.h $(SRCTOP)/include/kdb_log.h \
+ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
$(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
$(SRCTOP)/include/socket-utils.h kdb5_stash.c kdb5_util.h
$(OUTPRE)import_err.$(OBJEXT): $(COM_ERR_DEPS) import_err.c
@@ -139,10 +149,12 @@ $(OUTPRE)dump.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/gssrpc/rename.h $(SRCTOP)/include/gssrpc/rpc.h \
$(SRCTOP)/include/gssrpc/rpc_msg.h $(SRCTOP)/include/gssrpc/svc.h \
$(SRCTOP)/include/gssrpc/svc_auth.h $(SRCTOP)/include/gssrpc/xdr.h \
+ $(SRCTOP)/include/iprop.h $(SRCTOP)/include/iprop_hdr.h \
$(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-int-pkinit.h \
$(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
$(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/kdb.h $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
+ $(SRCTOP)/include/kdb.h $(SRCTOP)/include/kdb_log.h \
+ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
$(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
$(SRCTOP)/include/socket-utils.h dump.c kdb5_util.h
$(OUTPRE)ovload.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
@@ -156,10 +168,12 @@ $(OUTPRE)ovload.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/gssrpc/rename.h $(SRCTOP)/include/gssrpc/rpc.h \
$(SRCTOP)/include/gssrpc/rpc_msg.h $(SRCTOP)/include/gssrpc/svc.h \
$(SRCTOP)/include/gssrpc/svc_auth.h $(SRCTOP)/include/gssrpc/xdr.h \
+ $(SRCTOP)/include/iprop.h $(SRCTOP)/include/iprop_hdr.h \
$(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-int-pkinit.h \
$(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
$(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/kdb.h $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
+ $(SRCTOP)/include/kdb.h $(SRCTOP)/include/kdb_log.h \
+ $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
$(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
$(SRCTOP)/include/socket-utils.h import_err.h kdb5_util.h \
nstrtok.h ovload.c
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index 44675a6b2c..8fcb56e5ac 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -26,6 +26,10 @@
*
* Dump a KDC database
*/
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include <stdio.h>
#include <k5-int.h>
@@ -77,6 +81,8 @@ static krb5_error_code dump_k5beta6_iterator (krb5_pointer,
static krb5_error_code dump_k5beta6_iterator_ext (krb5_pointer,
krb5_db_entry *,
int);
+static krb5_error_code dump_iprop_iterator (krb5_pointer,
+ krb5_db_entry *);
static krb5_error_code dump_k5beta7_princ (krb5_pointer,
krb5_db_entry *);
static krb5_error_code dump_k5beta7_princ_ext (krb5_pointer,
@@ -84,6 +90,8 @@ static krb5_error_code dump_k5beta7_princ_ext (krb5_pointer,
int);
static krb5_error_code dump_k5beta7_princ_withpolicy
(krb5_pointer, krb5_db_entry *);
+static krb5_error_code dump_iprop_princ (krb5_pointer,
+ krb5_db_entry *);
static krb5_error_code dump_ov_princ (krb5_pointer,
krb5_db_entry *);
static void dump_k5beta7_policy (void *, osa_policy_ent_t);
@@ -139,6 +147,15 @@ dump_version beta7_version = {
dump_k5beta7_policy,
process_k5beta7_record,
};
+dump_version iprop_version = {
+ "Kerberos iprop version",
+ "iprop",
+ 0,
+ 0,
+ dump_iprop_princ,
+ dump_k5beta7_policy,
+ process_k5beta7_record,
+};
dump_version ov_version = {
"OpenV*Secure V1.0",
"OpenV*Secure V1.0\t",
@@ -237,6 +254,7 @@ static const char null_mprinc_name[] = "kdb5_dump@MISSING";
static const char oldoption[] = "-old";
static const char b6option[] = "-b6";
static const char b7option[] = "-b7";
+static const char ipropoption[] = "-i";
static const char verboseoption[] = "-verbose";
static const char updateoption[] = "-update";
static const char hashoption[] = "-hash";
@@ -826,6 +844,17 @@ dump_k5beta6_iterator_ext(ptr, entry, kadm)
}
/*
+ * dump_iprop_iterator() - Output a dump record in iprop format.
+ */
+static krb5_error_code
+dump_iprop_iterator(ptr, entry)
+ krb5_pointer ptr;
+ krb5_db_entry *entry;
+{
+ return dump_k5beta6_iterator_ext(ptr, entry, 1);
+}
+
+/*
* dump_k5beta7_iterator() - Output a dump record in krb5b7 format.
*/
static krb5_error_code
@@ -887,6 +916,51 @@ dump_k5beta7_princ_withpolicy(ptr, entry)
return dump_k5beta7_princ_ext(ptr, entry, 1);
}
+/*
+ * dump_iprop_princ() - Output a dump record in iprop format.
+ * This was created in order to dump more data, such as kadm5 tl
+ */
+static krb5_error_code
+dump_iprop_princ(ptr, entry)
+ krb5_pointer ptr;
+ krb5_db_entry *entry;
+{
+ krb5_error_code retval;
+ struct dump_args *arg;
+ char *name;
+ int tmp_nnames;
+
+ /* Initialize */
+ arg = (struct dump_args *) ptr;
+ name = (char *) NULL;
+
+ /*
+ * Flatten the principal name.
+ */
+ if ((retval = krb5_unparse_name(arg->kcontext,
+ entry->princ,
+ &name))) {
+ fprintf(stderr, _(pname_unp_err),
+ arg->programname, error_message(retval));
+ return(retval);
+ }
+ /*
+ * If we don't have any match strings, or if our name matches, then
+ * proceed with the dump, otherwise, just forget about it.
+ */
+ if (!arg->nnames || name_matches(name, arg)) {
+ fprintf(arg->ofile, "princ\t");
+
+ /* save the callee from matching the name again */
+ tmp_nnames = arg->nnames;
+ arg->nnames = 0;
+ retval = dump_iprop_iterator(ptr, entry);
+ arg->nnames = tmp_nnames;
+ }
+ free(name);
+ return (retval);
+}
+
void dump_k5beta7_policy(void *data, osa_policy_ent_t entry)
{
struct dump_args *arg;
@@ -1024,7 +1098,10 @@ dump_db(argc, argv)
int aindex;
krb5_boolean locked;
char *new_mkey_file = 0;
-
+ bool_t dump_sno = FALSE;
+ kdb_log_context *log_ctx;
+ char **db_args = 0; /* XXX */
+
/*
* Parse the arguments.
*/
@@ -1038,6 +1115,7 @@ dump_db(argc, argv)
mkey_convert = 0;
backwards = 0;
recursive = 0;
+ log_ctx = util_context->kdblog_context;
/*
* Parse the qualifiers.
@@ -1051,7 +1129,22 @@ dump_db(argc, argv)
dump = &beta7_version;
else if (!strcmp(argv[aindex], ovoption))
dump = &ov_version;
- else if (!strcmp(argv[aindex], verboseoption))
+ else if (!strcmp(argv[aindex], ipropoption)) {
+ if (log_ctx && log_ctx->iproprole) {
+ dump = &iprop_version;
+ /*
+ * dump_sno is used to indicate if the serial
+ * # should be populated in the output
+ * file to be used later by iprop for updating
+ * the slave's update log when loading
+ */
+ dump_sno = TRUE;
+ } else {
+ fprintf(stderr, _("Iprop not enabled\n"));
+ exit_status++;
+ return;
+ }
+ } else if (!strcmp(argv[aindex], verboseoption))
arglist.verbose++;
else if (!strcmp(argv[aindex], "-mkey_convert"))
mkey_convert = 1;
@@ -1172,6 +1265,32 @@ dump_db(argc, argv)
arglist.ofile = f;
arglist.kcontext = util_context;
fprintf(arglist.ofile, "%s", dump->header);
+
+ if (dump_sno) {
+ if (ulog_map(util_context, global_params.iprop_logfile,
+ global_params.iprop_ulogsize, FKCOMMAND, db_args)) {
+ fprintf(stderr,
+ _("%s: Could not map log\n"), programname);
+ exit_status++;
+ goto unlock_and_return;
+ }
+
+ /*
+ * We grab the lock twice (once again in the iterator call),
+ * but that's ok since the lock func handles incr locks held.
+ */
+ if (krb5_db_lock(util_context, KRB5_LOCKMODE_SHARED)) {
+ fprintf(stderr,
+ _("%s: Couldn't grab lock\n"), programname);
+ exit_status++;
+ goto unlock_and_return;
+ }
+
+ fprintf(f, " %u", log_ctx->ulog->kdb_last_sno);
+ fprintf(f, " %u", log_ctx->ulog->kdb_last_time.seconds);
+ fprintf(f, " %u", log_ctx->ulog->kdb_last_time.useconds);
+ }
+
if (dump->header[strlen(dump->header)-1] != '\n')
fputc('\n', arglist.ofile);
@@ -1182,6 +1301,8 @@ dump_db(argc, argv)
fprintf(stderr, dumprec_err,
programname, dump->name, error_message(kret));
exit_status++;
+ if (dump_sno)
+ (void) krb5_db_unlock(util_context);
}
if (dump->dump_policy &&
(kret = krb5_db_iter_policy( util_context, "*", dump->dump_policy,
@@ -1199,6 +1320,7 @@ dump_db(argc, argv)
update_ok_file(ofile);
}
}
+unlock_and_return:
if (locked)
(void) krb5_lock_file(util_context, fileno(f), KRB5_LOCKMODE_UNLOCK);
}
@@ -2137,6 +2259,10 @@ load_db(argc, argv)
krb5_int32 crflags;
int aindex;
int db_locked = 0;
+ char iheader[MAX_HEADER];
+ kdb_log_context *log_ctx;
+ int add_update = 1;
+ uint32_t caller, last_sno, last_seconds, last_useconds;
/*
* Parse the arguments.
@@ -2152,6 +2278,8 @@ load_db(argc, argv)
crflags = KRB5_KDB_CREATE_BTREE;
exit_status = 0;
dbname_tmp = (char *) NULL;
+ log_ctx = util_context->kdblog_context;
+
for (aindex = 1; aindex < argc; aindex++) {
if (!strcmp(argv[aindex], oldoption))
load = &old_version;
@@ -2161,7 +2289,16 @@ load_db(argc, argv)
load = &beta7_version;
else if (!strcmp(argv[aindex], ovoption))
load = &ov_version;
- else if (!strcmp(argv[aindex], verboseoption))
+ else if (!strcmp(argv[aindex], ipropoption)) {
+ if (log_ctx && log_ctx->iproprole) {
+ load = &iprop_version;
+ add_update = FALSE;
+ } else {
+ fprintf(stderr, _("Iprop not enabled\n"));
+ exit_status++;
+ return;
+ }
+ } else if (!strcmp(argv[aindex], verboseoption))
verbose = 1;
else if (!strcmp(argv[aindex], updateoption))
update = 1;
@@ -2206,6 +2343,9 @@ load_db(argc, argv)
return;
}
+ if (log_ctx && log_ctx->iproprole)
+ kcontext->kdblog_context = log_ctx;
+
/*
* Open the dumpfile
*/
@@ -2358,6 +2498,53 @@ load_db(argc, argv)
else
db_locked = 1;
+ if (log_ctx && log_ctx->iproprole) {
+ if (add_update)
+ caller = FKCOMMAND;
+ else
+ caller = FKPROPD;
+
+ if (ulog_map(kcontext, global_params.iprop_logfile,
+ global_params.iprop_ulogsize, caller, db5util_db_args)) {
+ fprintf(stderr, _("%s: Could not map log\n"),
+ programname);
+ exit_status++;
+ goto error;
+ }
+
+ /*
+ * We don't want to take out the ulog out from underneath
+ * kadmind so we reinit the header log.
+ *
+ * We also don't want to add to the update log since we
+ * are doing a whole sale replace of the db, because:
+ * we could easily exceed # of update entries
+ * we could implicity delete db entries during a replace
+ * no advantage in incr updates when entire db is replaced
+ */
+ if (!update) {
+ memset(log_ctx->ulog, 0, sizeof (kdb_hlog_t));
+
+ log_ctx->ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
+ log_ctx->ulog->db_version_num = KDB_VERSION;
+ log_ctx->ulog->kdb_state = KDB_STABLE;
+ log_ctx->ulog->kdb_block = ULOG_BLOCK;
+
+ log_ctx->iproprole = IPROP_NULL;
+
+ if (!add_update) {
+ sscanf(buf, "%s %u %u %u", iheader, &last_sno,
+ &last_seconds, &last_useconds);
+
+ log_ctx->ulog->kdb_last_sno = last_sno;
+ log_ctx->ulog->kdb_last_time.seconds =
+ last_seconds;
+ log_ctx->ulog->kdb_last_time.useconds =
+ last_useconds;
+ }
+ }
+ }
+
if (restore_dump(programname, kcontext, (dumpfile) ? dumpfile : stdin_name,
f, verbose, load)) {
fprintf(stderr, restfail_fmt,
diff --git a/src/kadmin/dbutil/kadm5_create.c b/src/kadmin/dbutil/kadm5_create.c
index 3f6f6557f6..c02b402876 100644
--- a/src/kadmin/dbutil/kadm5_create.c
+++ b/src/kadmin/dbutil/kadm5_create.c
@@ -242,6 +242,7 @@ static int add_admin_princs(void *handle, krb5_context context, char *realm)
goto clean_and_exit;
clean_and_exit:
+ free(service_name);
return ret;
}
diff --git a/src/kadmin/dbutil/kdb5_create.c b/src/kadmin/dbutil/kdb5_create.c
index da192256ea..b8959e102a 100644
--- a/src/kadmin/dbutil/kdb5_create.c
+++ b/src/kadmin/dbutil/kdb5_create.c
@@ -1,7 +1,7 @@
/*
* kadmin/dbutil/kdb5_create.c
*
- * Copyright 1990,1991,2001, 2002 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2001, 2002, 2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -52,6 +52,10 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include <stdio.h>
#include <k5-int.h>
@@ -161,6 +165,7 @@ void kdb5_create(argc, argv)
unsigned int pw_size = 0;
int do_stash = 0;
krb5_data pwd, seed;
+ kdb_log_context *log_ctx;
if (strrchr(argv[0], '/'))
argv[0] = strrchr(argv[0], '/')+1;
@@ -190,6 +195,8 @@ void kdb5_create(argc, argv)
rblock.nkslist = global_params.num_keysalts;
rblock.kslist = global_params.keysalts;
+ log_ctx = util_context->kdblog_context;
+
printf ("Loading random data\n");
retval = krb5_c_random_os_entropy (util_context, 1, NULL);
if (retval) {
@@ -274,6 +281,36 @@ master key name '%s'\n",
/* global_params.dbname); */
/* exit_status++; return; */
/* } */
+
+ if (log_ctx && log_ctx->iproprole) {
+ if (retval = ulog_map(util_context, global_params.iprop_logfile,
+ global_params.iprop_ulogsize, FKCOMMAND,
+ db5util_db_args)) {
+ com_err(argv[0], retval,
+ _("while creating update log"));
+ exit_status++;
+ return;
+ }
+
+ /*
+ * We're reinitializing the update log in case one already
+ * existed, but this should never happen.
+ */
+ (void) memset(log_ctx->ulog, 0, sizeof (kdb_hlog_t));
+
+ log_ctx->ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
+ log_ctx->ulog->db_version_num = KDB_VERSION;
+ log_ctx->ulog->kdb_state = KDB_STABLE;
+ log_ctx->ulog->kdb_block = ULOG_BLOCK;
+
+ /*
+ * Since we're creating a new db we shouldn't worry about
+ * adding the initial principals since any slave might as well
+ * do full resyncs from this newly created db.
+ */
+ log_ctx->iproprole = IPROP_NULL;
+ }
+
if ((retval = add_principal(util_context, master_princ, MASTER_KEY, &rblock)) ||
(retval = add_principal(util_context, &tgt_princ, TGT_KEY, &rblock))) {
(void) krb5_db_fini(util_context);
diff --git a/src/kadmin/dbutil/kdb5_destroy.c b/src/kadmin/dbutil/kdb5_destroy.c
index 22b75eef68..160268f24e 100644
--- a/src/kadmin/dbutil/kdb5_destroy.c
+++ b/src/kadmin/dbutil/kdb5_destroy.c
@@ -1,7 +1,7 @@
/*
* admin/destroy/kdb5_destroy.c
*
- * Copyright 1990 by the Massachusetts Institute of Technology.
+ * Copyright 1990, 2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -106,6 +106,10 @@ kdb5_destroy(argc, argv)
exit_status++; return;
}
+ if (global_params.iprop_enabled) {
+ (void) unlink(global_params.iprop_logfile);
+ }
+
dbactive = FALSE;
printf("** Database '%s' destroyed.\n", dbname);
return;
diff --git a/src/kadmin/dbutil/kdb5_util.c b/src/kadmin/dbutil/kdb5_util.c
index 1807d1ad00..1b2aa60c57 100644
--- a/src/kadmin/dbutil/kdb5_util.c
+++ b/src/kadmin/dbutil/kdb5_util.c
@@ -1,7 +1,7 @@
/*
* admin/edit/kdb5_edit.c
*
- * (C) Copyright 1990,1991, 1996 by the Massachusetts Institute of Technology.
+ * (C) Copyright 1990,1991, 1996, 2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -308,6 +308,11 @@ int main(argc, argv)
if (cmd->opendb && open_db_and_mkey())
return exit_status;
+ if (global_params.iprop_enabled == TRUE)
+ ulog_set_role(util_context, IPROP_MASTER);
+ else
+ ulog_set_role(util_context, IPROP_NULL);
+
(*cmd->func)(cmd_argc, cmd_argv);
if( db_name_tmp )
diff --git a/src/kadmin/dbutil/kdb5_util.h b/src/kadmin/dbutil/kdb5_util.h
index 90b7b43ef3..69dfba9862 100644
--- a/src/kadmin/dbutil/kdb5_util.h
+++ b/src/kadmin/dbutil/kdb5_util.h
@@ -1,7 +1,7 @@
/*
* admin/edit/kdb5_edit.h
*
- * Copyright 1992 by the Massachusetts Institute of Technology.
+ * Copyright 1992, 2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -25,6 +25,9 @@
*
*/
+#include <kdb_log.h>
+
+#define MAX_HEADER 1024
#define REALM_SEP '@'
#define REALM_SEP_STR "@"
diff --git a/src/kadmin/server/Makefile.in b/src/kadmin/server/Makefile.in
index bc3052b25c..63b4941b4d 100644
--- a/src/kadmin/server/Makefile.in
+++ b/src/kadmin/server/Makefile.in
@@ -6,14 +6,15 @@ KDB_DEP_LIB=$(DL_LIB) $(THREAD_LINKOPTS)
DEFS=
LOCALINCLUDES = -I$(SRCTOP)/lib/gssapi/generic -I$(SRCTOP)/lib/gssapi/krb5 \
- -I$(BUILDTOP)/lib/gssapi/generic -I$(BUILDTOP)/lib/gssapi/krb5
+ -I$(BUILDTOP)/lib/gssapi/generic -I$(BUILDTOP)/lib/gssapi/krb5 \
+ -I$(SRCTOP)/lib/kadm5/srv
PROG_LIBPATH=-L$(TOPLIBD)
PROG_RPATH=$(KRB5_LIBDIR)
PROG = kadmind
-OBJS = kadm_rpc_svc.o server_stubs.o ovsec_kadmd.o schpw.o misc.o server_glue_v1.o
-SRCS = kadm_rpc_svc.c server_stubs.c ovsec_kadmd.c schpw.c misc.c server_glue_v1.c
+OBJS = kadm_rpc_svc.o server_stubs.o ovsec_kadmd.o schpw.o misc.o server_glue_v1.o ipropd_svc.o
+SRCS = kadm_rpc_svc.c server_stubs.c ovsec_kadmd.c schpw.c misc.c server_glue_v1.c ipropd_svc.c
all:: $(PROG)
@@ -75,15 +76,16 @@ $(OUTPRE)ovsec_kadmd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/gssrpc/rename.h $(SRCTOP)/include/gssrpc/rpc.h \
$(SRCTOP)/include/gssrpc/rpc_msg.h $(SRCTOP)/include/gssrpc/svc.h \
$(SRCTOP)/include/gssrpc/svc_auth.h $(SRCTOP)/include/gssrpc/xdr.h \
+ $(SRCTOP)/include/iprop.h $(SRCTOP)/include/iprop_hdr.h \
$(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-int-pkinit.h \
$(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
$(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
$(SRCTOP)/include/kdb.h $(SRCTOP)/include/kdb_kt.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
- $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h $(SRCTOP)/lib/gssapi/generic/gssapiP_generic.h \
- $(SRCTOP)/lib/gssapi/generic/gssapi_generic.h $(SRCTOP)/lib/gssapi/krb5/gssapiP_krb5.h \
- misc.h ovsec_kadmd.c
+ $(SRCTOP)/include/kdb_log.h $(SRCTOP)/include/krb5.h \
+ $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
+ $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+ $(SRCTOP)/lib/gssapi/generic/gssapiP_generic.h $(SRCTOP)/lib/gssapi/generic/gssapi_generic.h \
+ $(SRCTOP)/lib/gssapi/krb5/gssapiP_krb5.h misc.h ovsec_kadmd.c
$(OUTPRE)schpw.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \
@@ -130,3 +132,20 @@ $(OUTPRE)server_glue_v1.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
$(SRCTOP)/include/kdb.h $(SRCTOP)/include/krb5.h misc.h \
server_glue_v1.c
+$(OUTPRE)ipropd_svc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
+ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/admin_internal.h \
+ $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \
+ $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/kadm5/server_internal.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/lib/gssapi/krb5/gssapi_krb5.h $(COM_ERR_DEPS) \
+ $(SRCTOP)/include/adm_proto.h $(SRCTOP)/include/gssrpc/auth.h \
+ $(SRCTOP)/include/gssrpc/auth_gss.h $(SRCTOP)/include/gssrpc/auth_unix.h \
+ $(SRCTOP)/include/gssrpc/clnt.h $(SRCTOP)/include/gssrpc/rename.h \
+ $(SRCTOP)/include/gssrpc/rpc.h $(SRCTOP)/include/gssrpc/rpc_msg.h \
+ $(SRCTOP)/include/gssrpc/svc.h $(SRCTOP)/include/gssrpc/svc_auth.h \
+ $(SRCTOP)/include/gssrpc/xdr.h $(SRCTOP)/include/iprop.h \
+ $(SRCTOP)/include/iprop_hdr.h $(SRCTOP)/include/k5-platform.h \
+ $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/kdb.h \
+ $(SRCTOP)/include/kdb_log.h $(SRCTOP)/include/krb5.h \
+ $(SRCTOP)/lib/kadm5/srv/server_acl.h ipropd_svc.c misc.h
diff --git a/src/kadmin/server/ipropd_svc.c b/src/kadmin/server/ipropd_svc.c
new file mode 100644
index 0000000000..673d2a9af0
--- /dev/null
+++ b/src/kadmin/server/ipropd_svc.c
@@ -0,0 +1,615 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* #pragma ident "@(#)ipropd_svc.c 1.2 04/02/20 SMI" */
+
+
+#include <stdio.h>
+#include <stdlib.h> /* getenv, exit */
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/resource.h> /* rlimit */
+#include <syslog.h>
+
+#include "k5-platform.h"
+#include <kadm5/admin.h>
+#include <kadm5/kadm_rpc.h>
+#include <kadm5/server_internal.h>
+#include <server_acl.h>
+#include <adm_proto.h>
+#include <string.h>
+#include <gssapi_krb5.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <kdb_log.h>
+#include "misc.h"
+#include "osconf.h"
+
+extern gss_name_t rqst2name(struct svc_req *rqstp);
+
+extern int setup_gss_names(struct svc_req *, gss_buffer_desc *,
+ gss_buffer_desc *);
+extern char *client_addr(struct svc_req *, char *);
+extern void *global_server_handle;
+extern int nofork;
+extern short l_port;
+static char abuf[33];
+
+char *client_addr(struct svc_req *svc, char *buf) {
+ return strcpy(buf, inet_ntoa(svc->rq_xprt->xp_raddr.sin_addr));
+}
+
+static char *reply_ok_str = "UPDATE_OK";
+static char *reply_err_str = "UPDATE_ERROR";
+static char *reply_fr_str = "UPDATE_FULL_RESYNC_NEEDED";
+static char *reply_busy_str = "UPDATE_BUSY";
+static char *reply_nil_str = "UPDATE_NIL";
+static char *reply_perm_str = "UPDATE_PERM_DENIED";
+static char *reply_unknown_str = "<UNKNOWN_CODE>";
+
+#define LOG_UNAUTH _("Unauthorized request: %s, %s, " \
+ "client=%s, service=%s, addr=%s")
+#define LOG_DONE _("Request: %s, %s, %s, client=%s, " \
+ "service=%s, addr=%s")
+
+#ifdef DPRINT
+#undef DPRINT
+#endif
+#define DPRINT(i) if (nofork) printf i
+
+
+static void
+debprret(char *w, update_status_t ret, kdb_sno_t sno)
+{
+ switch (ret) {
+ case UPDATE_OK:
+ printf("%s: end (OK, sno=%u)\n",
+ w, sno);
+ break;
+ case UPDATE_ERROR:
+ printf("%s: end (ERROR)\n", w);
+ break;
+ case UPDATE_FULL_RESYNC_NEEDED:
+ printf("%s: end (FR NEEDED)\n", w);
+ break;
+ case UPDATE_BUSY:
+ printf("%s: end (BUSY)\n", w);
+ break;
+ case UPDATE_NIL:
+ printf("%s: end (NIL)\n", w);
+ break;
+ case UPDATE_PERM_DENIED:
+ printf("%s: end (PERM)\n", w);
+ break;
+ default:
+ printf("%s: end (UNKNOWN return code (%d))\n", w, ret);
+ }
+}
+
+static char *
+replystr(update_status_t ret)
+{
+ switch (ret) {
+ case UPDATE_OK:
+ return (reply_ok_str);
+ case UPDATE_ERROR:
+ return (reply_err_str);
+ case UPDATE_FULL_RESYNC_NEEDED:
+ return (reply_fr_str);
+ case UPDATE_BUSY:
+ return (reply_busy_str);
+ case UPDATE_NIL:
+ return (reply_nil_str);
+ case UPDATE_PERM_DENIED:
+ return (reply_perm_str);
+ default:
+ return (reply_unknown_str);
+ }
+}
+
+/* Returns null on allocation failure.
+ Regardless of success or failure, frees the input buffer. */
+static char *
+buf_to_string(gss_buffer_desc *b)
+{
+ OM_uint32 min_stat;
+ char *s = malloc(b->length+1);
+
+ if (s) {
+ memcpy(s, b->value, b->length);
+ s[b->length] = 0;
+ }
+ (void) gss_release_buffer(&min_stat, b);
+ return s;
+}
+
+kdb_incr_result_t *
+iprop_get_updates_1_svc(kdb_last_t *arg, struct svc_req *rqstp)
+{
+ static kdb_incr_result_t ret;
+ char *whoami = "iprop_get_updates_1";
+ int kret;
+ kadm5_server_handle_t handle = global_server_handle;
+ char *client_name = 0, *service_name = 0;
+ char obuf[256] = {0};
+
+ /* default return code */
+ ret.ret = UPDATE_ERROR;
+
+ DPRINT(("%s: start, last_sno=%lu\n", whoami,
+ (unsigned long) arg->last_sno));
+
+ if (!handle) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: server handle is NULL"),
+ whoami);
+ goto out;
+ }
+
+ {
+ gss_buffer_desc client_desc, service_desc;
+
+ if (setup_gss_names(rqstp, &client_desc, &service_desc) < 0) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: setup_gss_names failed"),
+ whoami);
+ goto out;
+ }
+ client_name = buf_to_string(&client_desc);
+ service_name = buf_to_string(&service_desc);
+ if (client_name == NULL || service_name == NULL) {
+ free(client_name);
+ free(service_name);
+ krb5_klog_syslog(LOG_ERR,
+ "%s: out of memory recording principal names",
+ whoami);
+ goto out;
+ }
+ }
+
+ DPRINT(("%s: clprinc=`%s'\n\tsvcprinc=`%s'\n",
+ whoami, client_name, service_name));
+
+ if (!kadm5int_acl_check(handle->context,
+ rqst2name(rqstp),
+ ACL_IPROP,
+ NULL,
+ NULL)) {
+ ret.ret = UPDATE_PERM_DENIED;
+
+ krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, whoami,
+ "<null>", client_name, service_name,
+ client_addr(rqstp, abuf));
+ goto out;
+ }
+
+ kret = ulog_get_entries(handle->context, *arg, &ret);
+
+ if (ret.ret == UPDATE_OK) {
+ (void) snprintf(obuf, sizeof (obuf),
+ _("%s; Incoming SerialNo=%lu; Outgoing SerialNo=%lu"),
+ replystr(ret.ret),
+ (unsigned long)arg->last_sno,
+ (unsigned long)ret.lastentry.last_sno);
+ } else {
+ (void) snprintf(obuf, sizeof (obuf),
+ _("%s; Incoming SerialNo=%lu; Outgoing SerialNo=N/A"),
+ replystr(ret.ret),
+ (unsigned long)arg->last_sno);
+ }
+
+ krb5_klog_syslog(LOG_NOTICE, LOG_DONE, whoami,
+ obuf,
+ ((kret == 0) ? "success" : error_message(kret)),
+ client_name, service_name,
+ client_addr(rqstp, abuf));
+
+out:
+ if (nofork)
+ debprret(whoami, ret.ret, ret.lastentry.last_sno);
+ free(client_name);
+ free(service_name);
+ return (&ret);
+}
+
+
+/*
+ * Given a client princ (foo/fqdn@R), copy (in arg cl) the fqdn substring.
+ * Return arg cl str ptr on success, else NULL.
+ */
+static char *
+getclhoststr(char *clprinc, char *cl, int len)
+{
+ char *s;
+ if ((s = strchr(clprinc, '/')) != NULL) {
+ /* XXX "!++s"? */
+ if (!++s)
+ return NULL;
+ if (strlen(s) >= len)
+ return NULL;
+ strcpy(cl, s);
+ /* XXX Copy with @REALM first, with bounds check, then
+ chop off the realm?? */
+ if ((s = strchr(cl, '@')) != NULL) {
+ *s = '\0';
+ return (cl); /* success */
+ }
+ }
+
+ return (NULL);
+}
+
+kdb_fullresync_result_t *
+iprop_full_resync_1_svc(/* LINTED */ void *argp, struct svc_req *rqstp)
+{
+ static kdb_fullresync_result_t ret;
+ char *tmpf = 0;
+ char *ubuf = 0;
+ char clhost[MAXHOSTNAMELEN] = {0};
+ int pret, fret;
+ kadm5_server_handle_t handle = global_server_handle;
+ OM_uint32 min_stat;
+ gss_name_t name = NULL;
+ char *client_name = NULL, *service_name = NULL;
+ char *whoami = "iprop_full_resync_1";
+
+ /* default return code */
+ ret.ret = UPDATE_ERROR;
+
+ if (!handle) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: server handle is NULL"),
+ whoami);
+ goto out;
+ }
+
+ DPRINT(("%s: start\n", whoami));
+
+ {
+ gss_buffer_desc client_desc, service_desc;
+
+ if (setup_gss_names(rqstp, &client_desc, &service_desc) < 0) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: setup_gss_names failed"),
+ whoami);
+ goto out;
+ }
+ client_name = buf_to_string(&client_desc);
+ service_name = buf_to_string(&service_desc);
+ if (client_name == NULL || service_name == NULL) {
+ free(client_name);
+ free(service_name);
+ krb5_klog_syslog(LOG_ERR,
+ "%s: out of memory recording principal names",
+ whoami);
+ goto out;
+ }
+ }
+
+ DPRINT(("%s: clprinc=`%s'\n\tsvcprinc=`%s'\n",
+ whoami, client_name, service_name));
+
+ if (!kadm5int_acl_check(handle->context,
+ rqst2name(rqstp),
+ ACL_IPROP,
+ NULL,
+ NULL)) {
+ ret.ret = UPDATE_PERM_DENIED;
+
+ krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, whoami,
+ "<null>", client_name, service_name,
+ client_addr(rqstp, abuf));
+ goto out;
+ }
+
+ if (!getclhoststr(client_name, clhost, sizeof (clhost))) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: getclhoststr failed"),
+ whoami);
+ goto out;
+ }
+
+ /*
+ * construct db dump file name; kprop style name + clnt fqdn
+ */
+ if (asprintf(&tmpf, "%s_%s", KPROP_DEFAULT_FILE, clhost) < 0) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: unable to construct db dump file name; out of memory"),
+ whoami);
+ goto out;
+ }
+
+ /*
+ * note the -i; modified version of kdb5_util dump format
+ * to include sno (serial number)
+ */
+ if (asprintf(&ubuf, "%s dump -i %s", KPROPD_DEFAULT_KDB5_UTIL,
+ tmpf) < 0) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: cannot construct kdb5 util dump string too long; out of memory"),
+ whoami);
+ goto out;
+ }
+
+ /*
+ * Fork to dump the db and xfer it to the slave.
+ * (the fork allows parent to return quickly and the child
+ * acts like a callback to the slave).
+ */
+ fret = fork();
+ DPRINT(("%s: fork=%d (%d)\n", whoami, fret, getpid()));
+
+ switch (fret) {
+ case -1: /* error */
+ if (nofork) {
+ perror(whoami);
+ }
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: fork failed: %s"),
+ whoami,
+ error_message(errno));
+ goto out;
+
+ case 0: /* child */
+ DPRINT(("%s: run `%s' ...\n", whoami, ubuf));
+ (void) signal(SIGCHLD, SIG_DFL);
+ /* run kdb5_util(1M) dump for IProp */
+ /* XXX popen can return NULL; is pclose(NULL) okay? */
+ pret = pclose(popen(ubuf, "w"));
+ DPRINT(("%s: pclose=%d\n", whoami, pret));
+ if (pret != 0) {
+ /* XXX popen/pclose may not set errno
+ properly, and the error could be from the
+ subprocess anyways. */
+ if (nofork) {
+ perror(whoami);
+ }
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: pclose(popen) failed: %s"),
+ whoami,
+ error_message(errno));
+ goto out;
+ }
+
+ DPRINT(("%s: exec `kprop -f %s %s' ...\n",
+ whoami, tmpf, clhost));
+ /* XXX Yuck! */
+ if (getenv("KPROP_PORT"))
+ pret = execl(KPROPD_DEFAULT_KPROP, "kprop", "-f", tmpf,
+ "-P", getenv("KPROP_PORT"),
+ clhost, NULL);
+ else
+ pret = execl(KPROPD_DEFAULT_KPROP, "kprop", "-f", tmpf,
+ clhost, NULL);
+ if (pret == -1) {
+ if (nofork) {
+ perror(whoami);
+ }
+ krb5_klog_syslog(LOG_ERR,
+ _("%s: exec failed: %s"),
+ whoami,
+ error_message(errno));
+ goto out;
+ }
+
+ default: /* parent */
+ ret.ret = UPDATE_OK;
+ /* not used by slave (sno is retrieved from kdb5_util dump) */
+ ret.lastentry.last_sno = 0;
+ ret.lastentry.last_time.seconds = 0;
+ ret.lastentry.last_time.useconds = 0;
+
+ krb5_klog_syslog(LOG_NOTICE, LOG_DONE, whoami,
+ "<null>",
+ "success",
+ client_name, service_name,
+ client_addr(rqstp, abuf));
+
+ goto out;
+ }
+
+out:
+ if (nofork)
+ debprret(whoami, ret.ret, 0);
+ free(client_name);
+ free(service_name);
+ if (name)
+ gss_release_name(&min_stat, &name);
+ free(tmpf);
+ free(ubuf);
+ return (&ret);
+}
+
+static int
+check_iprop_rpcsec_auth(struct svc_req *rqstp)
+{
+ /* XXX Since the client can authenticate against any principal in
+ the database, we need to do a sanity check. Only checking for
+ "kiprop" now, but that means theoretically the client could be
+ authenticating to kiprop on some other machine. */
+ /* Code taken from kadm_rpc_svc.c, tweaked. */
+
+ gss_ctx_id_t ctx;
+ krb5_context kctx;
+ OM_uint32 maj_stat, min_stat;
+ gss_name_t name;
+ krb5_principal princ;
+ int ret, success;
+ krb5_data *c1, *c2, *realm;
+ gss_buffer_desc gss_str;
+ kadm5_server_handle_t handle;
+ size_t slen;
+ char *sdots;
+
+ success = 0;
+ handle = (kadm5_server_handle_t)global_server_handle;
+
+ if (rqstp->rq_cred.oa_flavor != RPCSEC_GSS)
+ return 0;
+
+ ctx = rqstp->rq_svccred;
+
+ maj_stat = gss_inquire_context(&min_stat, ctx, NULL, &name,
+ NULL, NULL, NULL, NULL, NULL);
+ if (maj_stat != GSS_S_COMPLETE) {
+ krb5_klog_syslog(LOG_ERR, "check_rpcsec_auth: "
+ "failed inquire_context, stat=%u", maj_stat);
+ log_badauth(maj_stat, min_stat,
+ &rqstp->rq_xprt->xp_raddr, NULL);
+ goto fail_name;
+ }
+
+ kctx = handle->context;
+ ret = gss_to_krb5_name_1(rqstp, kctx, name, &princ, &gss_str);
+ if (ret == 0)
+ goto fail_name;
+
+ slen = gss_str.length;
+ trunc_name(&slen, &sdots);
+ /*
+ * Since we accept with GSS_C_NO_NAME, the client can authenticate
+ * against the entire kdb. Therefore, ensure that the service
+ * name is something reasonable.
+ */
+ if (krb5_princ_size(kctx, princ) != 2)
+ goto fail_princ;
+
+ c1 = krb5_princ_component(kctx, princ, 0);
+ c2 = krb5_princ_component(kctx, princ, 1);
+ realm = krb5_princ_realm(kctx, princ);
+ if (strncmp(handle->params.realm, realm->data, realm->length) == 0
+ && strncmp("kiprop", c1->data, c1->length) == 0) {
+ success = 1;
+ }
+
+fail_princ:
+ if (!success) {
+ krb5_klog_syslog(LOG_ERR, "bad service principal %.*s%s",
+ (int) slen, (char *) gss_str.value, sdots);
+ }
+ gss_release_buffer(&min_stat, &gss_str);
+ krb5_free_principal(kctx, princ);
+fail_name:
+ gss_release_name(&min_stat, &name);
+ return success;
+}
+
+void
+krb5_iprop_prog_1(struct svc_req *rqstp,
+ register SVCXPRT *transp)
+{
+ union {
+ kdb_last_t iprop_get_updates_1_arg;
+ } argument;
+ char *result;
+ bool_t (*_xdr_argument)(), (*_xdr_result)();
+ char *(*local)(/* union XXX *, struct svc_req * */);
+ char *whoami = "krb5_iprop_prog_1";
+
+ if (!check_iprop_rpcsec_auth(rqstp)) {
+ krb5_klog_syslog(LOG_ERR,
+ "authentication attempt failed: %s, RPC authentication flavor %d",
+ inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr),
+ rqstp->rq_cred.oa_flavor);
+ svcerr_weakauth(transp);
+ return;
+ }
+
+ switch (rqstp->rq_proc) {
+ case NULLPROC:
+ (void) svc_sendreply(transp, xdr_void,
+ (char *)NULL);
+ return;
+
+ case IPROP_GET_UPDATES:
+ _xdr_argument = xdr_kdb_last_t;
+ _xdr_result = xdr_kdb_incr_result_t;
+ local = (char *(*)()) iprop_get_updates_1_svc;
+ break;
+
+ case IPROP_FULL_RESYNC:
+ _xdr_argument = xdr_void;
+ _xdr_result = xdr_kdb_fullresync_result_t;
+ local = (char *(*)()) iprop_full_resync_1_svc;
+ break;
+
+ default:
+ krb5_klog_syslog(LOG_ERR,
+ _("RPC unknown request: %d (%s)"),
+ rqstp->rq_proc, whoami);
+ svcerr_noproc(transp);
+ return;
+ }
+ (void) memset((char *)&argument, 0, sizeof (argument));
+ if (!svc_getargs(transp, _xdr_argument, (caddr_t)&argument)) {
+ krb5_klog_syslog(LOG_ERR,
+ _("RPC svc_getargs failed (%s)"),
+ whoami);
+ svcerr_decode(transp);
+ return;
+ }
+ result = (*local)(&argument, rqstp);
+
+ if (_xdr_result && result != NULL &&
+ !svc_sendreply(transp, _xdr_result, result)) {
+ krb5_klog_syslog(LOG_ERR,
+ _("RPC svc_sendreply failed (%s)"),
+ whoami);
+ svcerr_systemerr(transp);
+ }
+ if (!svc_freeargs(transp, _xdr_argument, (caddr_t)&argument)) {
+ krb5_klog_syslog(LOG_ERR,
+ _("RPC svc_freeargs failed (%s)"),
+ whoami);
+
+ exit(1);
+ }
+
+ if (rqstp->rq_proc == IPROP_GET_UPDATES) {
+ /* LINTED */
+ kdb_incr_result_t *r = (kdb_incr_result_t *)result;
+
+ if (r->ret == UPDATE_OK) {
+ ulog_free_entries(r->updates.kdb_ulog_t_val,
+ r->updates.kdb_ulog_t_len);
+ r->updates.kdb_ulog_t_val = NULL;
+ r->updates.kdb_ulog_t_len = 0;
+ }
+ }
+
+}
+
+#if 0
+/*
+ * Get the host base service name for the kiprop principal. Returns
+ * KADM5_OK on success. Caller must free the storage allocated for
+ * host_service_name.
+ */
+kadm5_ret_t
+kiprop_get_adm_host_srv_name(krb5_context context,
+ const char *realm,
+ char **host_service_name)
+{
+ kadm5_ret_t ret;
+ char *name;
+ char *host;
+
+ if (ret = kadm5_get_master(context, realm, &host))
+ return (ret);
+
+ name = malloc(strlen(KIPROP_SVC_NAME)+ strlen(host) + 2);
+ if (name == NULL) {
+ free(host);
+ return (ENOMEM);
+ }
+ (void) sprintf(name, "%s@%s", KIPROP_SVC_NAME, host);
+ free(host);
+ *host_service_name = name;
+
+ return (KADM5_OK);
+}
+#endif
diff --git a/src/kadmin/server/kadm_rpc_svc.c b/src/kadmin/server/kadm_rpc_svc.c
index 733602052a..c56eedd0b8 100644
--- a/src/kadmin/server/kadm_rpc_svc.c
+++ b/src/kadmin/server/kadm_rpc_svc.c
@@ -24,7 +24,6 @@
extern void *global_server_handle;
static int check_rpcsec_auth(struct svc_req *);
-static int gss_to_krb5_name(struct svc_req *, krb5_context, gss_name_t, krb5_principal *, gss_buffer_t);
void log_badauth(OM_uint32 major, OM_uint32 minor,
struct sockaddr_in *addr, char *data);
@@ -272,7 +271,7 @@ check_rpcsec_auth(struct svc_req *rqstp)
}
kctx = handle->context;
- ret = gss_to_krb5_name(rqstp, kctx, name, &princ, &gss_str);
+ ret = gss_to_krb5_name_1(rqstp, kctx, name, &princ, &gss_str);
if (ret == 0)
goto fail_name;
@@ -310,9 +309,9 @@ fail_name:
return success;
}
-static int
-gss_to_krb5_name(struct svc_req *rqstp, krb5_context ctx, gss_name_t gss_name,
- krb5_principal *princ, gss_buffer_t gss_str)
+int
+gss_to_krb5_name_1(struct svc_req *rqstp, krb5_context ctx, gss_name_t gss_name,
+ krb5_principal *princ, gss_buffer_t gss_str)
{
OM_uint32 status, minor_stat;
gss_OID gss_type;
diff --git a/src/kadmin/server/kadmind.M b/src/kadmin/server/kadmind.M
index ad810e6f2d..2a227fb4e4 100644
--- a/src/kadmin/server/kadmind.M
+++ b/src/kadmin/server/kadmind.M
@@ -54,6 +54,21 @@ section below.
.PP
After the server begins running, it puts itself in the background and
disassociates itself from its controlling terminal.
+.PP
+kadmind can be configured for incremental database propagation.
+Incremental propagation allows slave KDC servers to receive principal
+and policy updates incrementally instead of receiving full dumps of
+the database. This facility can be enabled in the
+.I kdc.conf
+file with the
+.I iprop_enable
+option. See the
+.I kdc.conf
+documentation for other options for tuning incremental propagation
+parameters. Incremental propagation requires the principal
+"kiprop/MASTER@REALM" (where MASTER is the master KDC's canonical host
+name, and REALM the realm name) to be registered in the database.
+
.SH OPTIONS
.TP
\fB\-x\fP \fIdb_args\fP
@@ -199,6 +214,10 @@ character is lower-case, then the operation is permitted.
[Dis]allows the listing of principals or policies in the database.
.sp -1v
.TP
+.B p
+[Dis]allows the propagation of the principal database.
+.sp -1v
+.TP
.B x
Short for
.IR admcil .
diff --git a/src/kadmin/server/misc.h b/src/kadmin/server/misc.h
index a020874fda..74d703c4ad 100644
--- a/src/kadmin/server/misc.h
+++ b/src/kadmin/server/misc.h
@@ -47,3 +47,7 @@ void kadm_1(struct svc_req *, SVCXPRT *);
#endif
void trunc_name(size_t *len, char **dots);
+
+int
+gss_to_krb5_name_1(struct svc_req *rqstp, krb5_context ctx, gss_name_t gss_name,
+ krb5_principal *princ, gss_buffer_t gss_str);
diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c
index 659ebfba38..88a60e026d 100644
--- a/src/kadmin/server/ovsec_kadmd.c
+++ b/src/kadmin/server/ovsec_kadmd.c
@@ -53,6 +53,7 @@
#include "kdb_kt.h" /* for krb5_ktkdb_set_context */
#include <string.h>
#include "kadm5/server_internal.h" /* XXX for kadm5_server_handle_t */
+#include <kdb_log.h>
#include "misc.h"
@@ -71,7 +72,7 @@ extern int daemon(int, int);
volatile int signal_request_exit = 0;
volatile int signal_request_hup = 0;
-void setup_signal_handlers(void);
+void setup_signal_handlers(iprop_role iproprole);
void request_exit(int);
void request_hup(int);
void reset_db(void);
@@ -114,10 +115,18 @@ void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
int schpw;
void do_schpw(int s, kadm5_config_params *params);
+int ipropfd;
+
#ifdef USE_PASSWORD_SERVER
void kadm5_set_use_password_server (void);
#endif
+extern void krb5_iprop_prog_1();
+extern kadm5_ret_t kiprop_get_adm_host_srv_name(
+ krb5_context,
+ const char *,
+ char **);
+
/*
* Function: usage
*
@@ -199,12 +208,14 @@ static krb5_context context;
static krb5_context hctx;
+int nofork = 0;
+
int main(int argc, char *argv[])
{
- register SVCXPRT *transp;
+ register SVCXPRT *transp, *iproptransp;
extern char *optarg;
extern int optind, opterr;
- int ret, nofork, oldnames = 0;
+ int ret, oldnames = 0;
OM_uint32 OMret, major_status, minor_status;
char *whoami;
gss_buffer_desc in_buf;
@@ -218,6 +229,9 @@ int main(int argc, char *argv[])
int db_args_size = 0;
char *errmsg;
+ char *kiprop_name = NULL; /* iprop svc name */
+ kdb_log_context *log_ctx;
+
setvbuf(stderr, NULL, _IONBF, 0);
/* This is OID value the Krb5_Name NameType */
@@ -316,11 +330,6 @@ int main(int argc, char *argv[])
exit(1);
}
- if( db_args )
- {
- free(db_args), db_args=NULL;
- }
-
if ((ret = kadm5_get_config_params(context, 1, &params,
&params))) {
const char *e_txt = krb5_get_error_message (context, ret);
@@ -353,19 +362,23 @@ int main(int argc, char *argv[])
addr.sin_port = htons(params.kadmind_port);
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- const char *e_txt = krb5_get_error_message (context, ret);
- krb5_klog_syslog(LOG_ERR, "Cannot create TCP socket: %s",
- e_txt);
- fprintf(stderr, "Cannot create TCP socket: %s",
- e_txt);
- kadm5_destroy(global_server_handle);
- krb5_klog_close(context);
- exit(1);
+ const char *e_txt;
+ ret = SOCKET_ERRNO;
+ e_txt = krb5_get_error_message (context, ret);
+ krb5_klog_syslog(LOG_ERR, "Cannot create TCP socket: %s",
+ e_txt);
+ fprintf(stderr, "Cannot create TCP socket: %s",
+ e_txt);
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
}
set_cloexec_fd(s);
if ((schpw = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- const char *e_txt = krb5_get_error_message (context, ret);
+ const char *e_txt;
+ ret = SOCKET_ERRNO;
+ e_txt = krb5_get_error_message (context, ret);
krb5_klog_syslog(LOG_ERR,
"cannot create simple chpw socket: %s",
e_txt);
@@ -377,6 +390,21 @@ int main(int argc, char *argv[])
}
set_cloexec_fd(schpw);
+ if ((ipropfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ const char *e_txt;
+ ret = SOCKET_ERRNO;
+ e_txt = krb5_get_error_message (context, ret);
+ krb5_klog_syslog(LOG_ERR,
+ "cannot create iprop listening socket: %s",
+ e_txt);
+ fprintf(stderr, "cannot create iprop listening socket: %s",
+ e_txt);
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+ set_cloexec_fd(ipropfd);
+
#ifdef SO_REUSEADDR
/* the old admin server turned on SO_REUSEADDR for non-default
port numbers. this was necessary, on solaris, for the tests
@@ -390,12 +418,16 @@ int main(int argc, char *argv[])
int allowed;
allowed = 1;
- if (setsockopt(s,
- SOL_SOCKET,
- SO_REUSEADDR,
- (char *) &allowed,
- sizeof(allowed)) < 0) {
- const char *e_txt = krb5_get_error_message (context, ret);
+ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &allowed, sizeof(allowed)) < 0 ||
+ setsockopt(schpw, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &allowed, sizeof(allowed)) < 0 ||
+ setsockopt(ipropfd, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &allowed, sizeof(allowed)) < 0
+ ) {
+ const char *e_txt;
+ ret = SOCKET_ERRNO;
+ e_txt = krb5_get_error_message (context, ret);
krb5_klog_syslog(LOG_ERR, "Cannot set SO_REUSEADDR: %s",
e_txt);
fprintf(stderr, "Cannot set SO_REUSEADDR: %s", e_txt);
@@ -403,19 +435,6 @@ int main(int argc, char *argv[])
krb5_klog_close(context);
exit(1);
}
- if (setsockopt(schpw, SOL_SOCKET, SO_REUSEADDR,
- (char *) &allowed, sizeof(allowed)) < 0) {
- const char *e_txt = krb5_get_error_message (context, ret);
- krb5_klog_syslog(LOG_ERR,
- "cannot set SO_REUSEADDR on simple chpw socket: %s",
- e_txt);
- fprintf(stderr,
- "Cannot set SO_REUSEADDR on simple chpw socket: %s",
- e_txt);
- kadm5_destroy(global_server_handle);
- krb5_klog_close(context);
- }
-
}
#endif /* SO_REUSEADDR */
memset(&addr, 0, sizeof(addr));
@@ -456,6 +475,7 @@ int main(int argc, char *argv[])
krb5_klog_close(context);
exit(1);
}
+
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
@@ -491,7 +511,41 @@ int main(int argc, char *argv[])
krb5_klog_close(context);
exit(1);
}
-
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_port = htons(params.iprop_port);
+ if (bind(ipropfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ char portbuf[32];
+ int oerrno = errno;
+ const char *e_txt = krb5_get_error_message (context, errno);
+ fprintf(stderr, "%s: Cannot bind socket.\n", whoami);
+ fprintf(stderr, "bind: %s\n", e_txt);
+ errno = oerrno;
+ snprintf(portbuf, sizeof(portbuf), "%d", ntohs(addr.sin_port));
+ krb5_klog_syslog(LOG_ERR, "cannot bind iprop socket: %s",
+ e_txt);
+ if(oerrno == EADDRINUSE) {
+ char *w = strrchr(whoami, '/');
+ if (w) {
+ w++;
+ }
+ else {
+ w = whoami;
+ }
+ fprintf(stderr,
+"This probably means that another %s process is already\n"
+"running, or that another program is using the server port (number %d).\n"
+"If another %s is already running, you should kill it before\n"
+"restarting the server.\n",
+ w, ntohs(addr.sin_port), w);
+ }
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+
transp = svctcp_create(s, 0, 0);
if(transp == NULL) {
fprintf(stderr, "%s: Cannot create RPC service.\n", whoami);
@@ -508,6 +562,25 @@ int main(int argc, char *argv[])
exit(1);
}
+ iproptransp = svctcp_create(ipropfd, 0, 0);
+ if (iproptransp == NULL) {
+ fprintf(stderr, "%s: Cannot create RPC service.\n", whoami);
+ krb5_klog_syslog(LOG_ERR, "Cannot create RPC service: %m");
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+ if (!svc_register(iproptransp, KRB5_IPROP_PROG, KRB5_IPROP_VERS, krb5_iprop_prog_1, IPPROTO_TCP)) {
+ fprintf(stderr, "%s: Cannot register RPC service.\n", whoami);
+ krb5_klog_syslog(LOG_ERR, "Cannot register RPC service, continuing.");
+#if 0
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+#endif
+ }
+
+
names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
names[2].name = build_princ_name(OVSEC_KADM_ADMIN_SERVICE, params.realm);
@@ -643,8 +716,108 @@ kterr:
exit(1);
}
- setup_signal_handlers();
- krb5_klog_syslog(LOG_INFO, "starting");
+ if (params.iprop_enabled == TRUE)
+ ulog_set_role(hctx, IPROP_MASTER);
+ else
+ ulog_set_role(hctx, IPROP_NULL);
+
+ log_ctx = hctx->kdblog_context;
+
+ if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
+ /*
+ * IProp is enabled, so let's map in the update log
+ * and setup the service.
+ */
+ if ((ret = ulog_map(hctx, params.iprop_logfile,
+ params.iprop_ulogsize, FKADMIND, db_args)) != 0) {
+ fprintf(stderr,
+ _("%s: %s while mapping update log (`%s.ulog')\n"),
+ whoami, error_message(ret), params.dbname);
+ krb5_klog_syslog(LOG_ERR,
+ _("%s while mapping update log (`%s.ulog')"),
+ error_message(ret), params.dbname);
+ krb5_klog_close(context);
+ exit(1);
+ }
+
+
+ if (nofork)
+ fprintf(stderr,
+ "%s: create IPROP svc (PROG=%d, VERS=%d)\n",
+ whoami, KRB5_IPROP_PROG, KRB5_IPROP_VERS);
+
+#if 0
+ if (!svc_create(krb5_iprop_prog_1,
+ KRB5_IPROP_PROG, KRB5_IPROP_VERS,
+ "circuit_v")) {
+ fprintf(stderr,
+ _("%s: Cannot create IProp RPC service (PROG=%d, VERS=%d)\n"),
+ whoami,
+ KRB5_IPROP_PROG, KRB5_IPROP_VERS);
+ krb5_klog_syslog(LOG_ERR,
+ _("Cannot create IProp RPC service (PROG=%d, VERS=%d), failing."),
+ KRB5_IPROP_PROG, KRB5_IPROP_VERS);
+ krb5_klog_close(context);
+ exit(1);
+ }
+#endif
+
+#if 0 /* authgss only? */
+ if ((ret = kiprop_get_adm_host_srv_name(context,
+ params.realm,
+ &kiprop_name)) != 0) {
+ krb5_klog_syslog(LOG_ERR,
+ _("%s while getting IProp svc name, failing"),
+ error_message(ret));
+ fprintf(stderr,
+ _("%s: %s while getting IProp svc name, failing\n"),
+ whoami, error_message(ret));
+ krb5_klog_close(context);
+ exit(1);
+ }
+
+ auth_gssapi_name iprop_name;
+ iprop_name.name = build_princ_name(foo, bar);
+ if (iprop_name.name == NULL) {
+ foo error;
+ }
+ iprop_name.type = nt_krb5_name_oid;
+ if (svcauth_gssapi_set_names(&iprop_name, 1) == FALSE) {
+ foo error;
+ }
+ if (!rpc_gss_set_svc_name(kiprop_name, "kerberos_v5", 0,
+ KRB5_IPROP_PROG, KRB5_IPROP_VERS)) {
+ rpc_gss_error_t err;
+ (void) rpc_gss_get_error(&err);
+
+ krb5_klog_syslog(LOG_ERR,
+ _("Unable to set RPCSEC_GSS service name (`%s'), failing."),
+ kiprop_name ? kiprop_name : "<null>");
+
+ fprintf(stderr,
+ _("%s: Unable to set RPCSEC_GSS service name (`%s'), failing.\n"),
+ whoami,
+ kiprop_name ? kiprop_name : "<null>");
+
+ if (nofork) {
+ fprintf(stderr,
+ "%s: set svc name (rpcsec err=%d, sys err=%d)\n",
+ whoami,
+ err.rpc_gss_error,
+ err.system_error);
+ }
+
+ exit(1);
+ }
+ free(kiprop_name);
+#endif
+ }
+
+ setup_signal_handlers(log_ctx->iproprole);
+ krb5_klog_syslog(LOG_INFO, _("starting"));
+ if (nofork)
+ fprintf(stderr, "%s: starting...\n", whoami);
+
kadm_svc_run(&params);
krb5_klog_syslog(LOG_INFO, "finished, exiting");
@@ -677,7 +850,7 @@ kterr:
* if possible, otherwise with System V's signal().
*/
-void setup_signal_handlers(void) {
+void setup_signal_handlers(iprop_role iproprole) {
#ifdef POSIX_SIGNALS
(void) sigemptyset(&s_action.sa_mask);
s_action.sa_handler = request_exit;
@@ -694,6 +867,15 @@ void setup_signal_handlers(void) {
s_action.sa_handler = request_pure_clear;
(void) sigaction(SIGUSR2, &s_action, (struct sigaction *) NULL);
#endif /* PURIFY */
+
+ /*
+ * IProp will fork for a full-resync, we don't want to
+ * wait on it and we don't want the living dead procs either.
+ */
+ if (iproprole == IPROP_MASTER) {
+ s_action.sa_handler = SIG_IGN;
+ (void) sigaction(SIGCHLD, &s_action, (struct sigaction *) NULL);
+ }
#else /* POSIX_SIGNALS */
signal(SIGINT, request_exit);
signal(SIGTERM, request_exit);
@@ -704,6 +886,13 @@ void setup_signal_handlers(void) {
signal(SIGUSR1, request_pure_report);
signal(SIGUSR2, request_pure_clear);
#endif /* PURIFY */
+
+ /*
+ * IProp will fork for a full-resync, we don't want to
+ * wait on it and we don't want the living dead procs either.
+ */
+ if (iproprole == IPROP_MASTER)
+ (void) signal(SIGCHLD, SIG_IGN);
#endif /* POSIX_SIGNALS */
}
diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c
index 5e50971f1e..cf93e86676 100644
--- a/src/kadmin/server/server_stubs.c
+++ b/src/kadmin/server/server_stubs.c
@@ -37,7 +37,7 @@ static int gss_name_to_string(gss_name_t gss_name, gss_buffer_desc *str);
static gss_name_t acceptor_name(gss_ctx_id_t context);
-static gss_name_t rqst2name(struct svc_req *rqstp);
+gss_name_t rqst2name(struct svc_req *rqstp);
static int cmp_gss_names(gss_name_t n1, gss_name_t n2)
{
@@ -158,7 +158,6 @@ static void free_server_handle(kadm5_server_handle_t handle)
* server_name, both of which must be freed by the caller. Returns 0
* on success and -1 on failure.
*/
-static
int setup_gss_names(struct svc_req *rqstp,
gss_buffer_desc *client_name,
gss_buffer_desc *server_name)
@@ -1657,7 +1656,7 @@ exit_func:
return(&ret);
}
-static gss_name_t
+gss_name_t
rqst2name(struct svc_req *rqstp)
{