diff options
author | Ken Raeburn <raeburn@mit.edu> | 2008-06-24 05:04:29 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@mit.edu> | 2008-06-24 05:04:29 +0000 |
commit | 5661d1290f74312a405db970aea097da77706f71 (patch) | |
tree | 0ab69c8078ef3275b99a3ad27f3592b607e43f70 /src/kadmin | |
parent | 6879f371402854465e5276d36e4792938906097f (diff) | |
download | krb5-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.M | 14 | ||||
-rw-r--r-- | src/kadmin/cli/kadmin.c | 13 | ||||
-rw-r--r-- | src/kadmin/dbutil/Makefile.in | 42 | ||||
-rw-r--r-- | src/kadmin/dbutil/dump.c | 193 | ||||
-rw-r--r-- | src/kadmin/dbutil/kadm5_create.c | 1 | ||||
-rw-r--r-- | src/kadmin/dbutil/kdb5_create.c | 39 | ||||
-rw-r--r-- | src/kadmin/dbutil/kdb5_destroy.c | 6 | ||||
-rw-r--r-- | src/kadmin/dbutil/kdb5_util.c | 7 | ||||
-rw-r--r-- | src/kadmin/dbutil/kdb5_util.h | 5 | ||||
-rw-r--r-- | src/kadmin/server/Makefile.in | 35 | ||||
-rw-r--r-- | src/kadmin/server/ipropd_svc.c | 615 | ||||
-rw-r--r-- | src/kadmin/server/kadm_rpc_svc.c | 9 | ||||
-rw-r--r-- | src/kadmin/server/kadmind.M | 19 | ||||
-rw-r--r-- | src/kadmin/server/misc.h | 4 | ||||
-rw-r--r-- | src/kadmin/server/ovsec_kadmd.c | 269 | ||||
-rw-r--r-- | src/kadmin/server/server_stubs.c | 5 |
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, ¶ms, ¶ms))) { 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(¶ms); 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) { |