.B kadmind
[\fB\-x\fP \fIdb_args\fP] [\fB-r\fP \fIrealm\fP] [\fB\-m\fP] [\fB\-nofork\fP] [\fB\-port\fP
\fIport-number\fP]
+ [\fB\-P\fP \fIpid_file\fP]
.SH DESCRIPTION
This command starts the KADM5 administration server. If the database is db2,
the administration server runs on the master Kerberos server, which stores the KDC
connections. The default is is controlled by the
.I kadmind_port
configuration variable (see below).
+.TP
+\fB\-P\fP \fIpid_file\fP
+specifies the file to which the PID of
+.B kadmind
+process should be written to after it starts up. This can be used to
+identify whether
+.B kadmind
+is still running and to allow init scripts to stop the correct process.
.SH CONFIGURATION VALUES
.PP
In addition to the relations defined in kdc.conf(5), kadmind
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <syslog.h>
"[-passwordserver] "
#endif
"[-port port-number]\n"
+ "\t\t[-P pid_file]\n"
"\nwhere,\n\t[-x db_args]* - any number of database specific arguments.\n"
"\t\t\tLook at each database documentation for supported arguments\n"
);
}
}
+/*
+ * Function: write_pid_file
+ *
+ * Purpose: writes the current process PID to a file
+ *
+ * Arguments:
+ *
+ * pid_file path to output file
+ * <return value> 0 on success, error code on failure
+ *
+ * Effects:
+ *
+ * The current process PID, obtained from getpid(), is written to the path
+ * given in pid_file, overwriting the existing contents if the file already
+ * exists. The PID will be followed by a newline.
+ */
+static int
+write_pid_file(const char *pid_file)
+{
+ FILE *file;
+ unsigned long pid;
+
+ file = fopen(pid_file, "w");
+ if (file == NULL)
+ return errno;
+ pid = (unsigned long) getpid();
+ if (fprintf(file, "%ld\n", pid) < 0 || fclose(file) == EOF)
+ return errno;
+ return 0;
+}
/* XXX yuck. the signal handlers need this */
static krb5_context context;
char *errmsg;
int i;
int strong_random = 1;
+ const char *pid_file = NULL;
kdb_log_context *log_ctx;
usage();
params.kadmind_port = atoi(*argv);
params.mask |= KADM5_CONFIG_KADMIND_PORT;
+ } else if (strcmp(*argv, "-P") == 0) {
+ argc--; argv++;
+ if (!argc)
+ usage();
+ pid_file = *argv;
} else if (strcmp(*argv, "-W") == 0) {
strong_random = 0;
} else
krb5_klog_close(context);
exit(1);
}
+ if (pid_file != NULL) {
+ ret = write_pid_file(pid_file);
+ if (ret) {
+ errmsg = krb5_get_error_message(context, ret);
+ krb5_klog_syslog(LOG_ERR, "Cannot create PID file %s: %s",
+ pid_file, errmsg);
+ svcauth_gssapi_unset_names();
+ kadm5_destroy(global_server_handle);
+ krb5_klog_close(context);
+ exit(1);
+ }
+ }
krb5_klog_syslog(LOG_INFO, "Seeding random number generator");
ret = krb5_c_random_os_entropy(context, strong_random, NULL);
.I realm
] [
.B \-n
+] [
+.B \-P
+.I pid_file
]
.br
.SH DESCRIPTION
operation, you should always allow the KDC to place itself in
the background.
.PP
+The
+.B \-P
+.I pid_file
+option tells the KDC to write its PID (followed by a newline) into
+.I pid_file
+after it starts up. This can be used to identify whether the KDC is still
+running and to allow init scripts to stop the correct process.
+.PP
The KDC may service requests for multiple realms (maximum 32 realms). The
realms are listed on the command line. Per-realm options that can be
specified on the command line pertain for each realm that follows it and are
#include <signal.h>
#include <errno.h>
#include <netdb.h>
+#include <unistd.h>
#include "k5-int.h"
#include "com_err.h"
void finish_realms (void);
static int nofork = 0;
+static const char *pid_file = NULL;
static int rkey_init_done = 0;
#ifdef POSIX_SIGNALS
void
usage(char *name)
{
- fprintf(stderr, "usage: %s [-x db_args]* [-d dbpathname] [-r dbrealmname]\n\t\t[-R replaycachename] [-m] [-k masterenctype] [-M masterkeyname]\n\t\t[-p port] [/]\n"
+ fprintf(stderr, "usage: %s [-x db_args]* [-d dbpathname] [-r dbrealmname]\n\t\t[-R replaycachename] [-m] [-k masterenctype] [-M masterkeyname]\n\t\t[-p port] [-P pid_file] [/]\n"
"\nwhere,\n\t[-x db_args]* - Any number of database specific arguments. Look at\n"
"\t\t\teach database module documentation for supported\n\t\t\targuments\n",
name);
* Loop through the option list. Each time we encounter a realm name,
* use the previously scanned options to fill in for defaults.
*/
- while ((c = getopt(argc, argv, "x:r:d:mM:k:R:e:p:s:n4:X3")) != -1) {
+ while ((c = getopt(argc, argv, "x:r:d:mM:k:R:e:P:p:s:n4:X3")) != -1) {
switch(c) {
case 'x':
db_args_size++;
case 'R':
rcname = optarg;
break;
+ case 'P':
+ pid_file = optarg;
case 'p':
if (default_udp_ports)
free(default_udp_ports);
return;
}
+static krb5_error_code
+write_pid_file(const char *path)
+{
+ FILE *file;
+ unsigned long pid;
+
+ file = fopen(path, "w");
+ if (file == NULL)
+ return errno;
+ pid = (unsigned long) getpid();
+ if (fprintf(file, "%ld\n", pid) < 0 || fclose(file) == EOF)
+ return errno;
+ return 0;
+}
+
void
finish_realms()
{
finish_realms();
return 1;
}
+ if (pid_file != NULL) {
+ retval = write_pid_file(pid_file);
+ if (retval) {
+ kdc_err(kcontext, retval, "while creating PID file");
+ finish_realms();
+ return 1;
+ }
+ }
krb5_klog_syslog(LOG_INFO, "commencing operation");
if (nofork)
fprintf(stderr, "%s: starting...\n", kdc_progname);