+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* slave/kprop.c
*
static char *kprop_version = KPROP_PROT_VERSION;
-char *progname = 0;
+char *progname = 0;
int debug = 0;
-char *srvtab = 0;
-char *slave_host;
-char *realm = 0;
-char *file = KPROP_DEFAULT_FILE;
-short port = 0;
-
-krb5_principal my_principal; /* The Kerberos principal we'll be */
- /* running under, initialized in */
- /* get_tickets() */
-krb5_ccache ccache; /* Credentials cache which we'll be using */
-krb5_creds creds;
-krb5_address sender_addr;
-krb5_address receiver_addr;
-
-void PRS
- (int, char **);
-void get_tickets
- (krb5_context);
-static void usage
- (void);
-krb5_error_code open_connection
- (char *, int *, char *, unsigned int);
-void kerberos_authenticate
- (krb5_context, krb5_auth_context *,
- int, krb5_principal, krb5_creds **);
-int open_database
- (krb5_context, char *, int *);
-void close_database
- (krb5_context, int);
-void xmit_database
- (krb5_context, krb5_auth_context, krb5_creds *,
- int, int, int);
-void send_error
- (krb5_context, krb5_creds *, int, char *, krb5_error_code);
-void update_last_prop_file
- (char *, char *);
+char *srvtab = 0;
+char *slave_host;
+char *realm = 0;
+char *file = KPROP_DEFAULT_FILE;
+short port = 0;
+
+krb5_principal my_principal; /* The Kerberos principal we'll be */
+/* running under, initialized in */
+/* get_tickets() */
+krb5_ccache ccache; /* Credentials cache which we'll be using */
+krb5_creds creds;
+krb5_address sender_addr;
+krb5_address receiver_addr;
+
+void PRS(int, char **);
+void get_tickets(krb5_context);
+static void usage(void);
+krb5_error_code open_connection(char *, int *, char *, unsigned int);
+void kerberos_authenticate(krb5_context, krb5_auth_context *,
+ int, krb5_principal, krb5_creds **);
+int open_database(krb5_context, char *, int *);
+void close_database(krb5_context, int);
+void xmit_database(krb5_context, krb5_auth_context, krb5_creds *,
+ int, int, int);
+void send_error(krb5_context, krb5_creds *, int, char *, krb5_error_code);
+void update_last_prop_file(char *, char *);
static void usage()
{
- fprintf(stderr, "\nUsage: %s [-r realm] [-f file] [-d] [-P port] [-s srvtab] slave_host\n\n",
- progname);
- exit(1);
+ fprintf(stderr, "\nUsage: %s [-r realm] [-f file] [-d] [-P port] [-s srvtab] slave_host\n\n",
+ progname);
+ exit(1);
}
int
main(argc, argv)
- int argc;
- char **argv;
+ int argc;
+ char **argv;
{
- int fd, database_fd, database_size;
- krb5_error_code retval;
- krb5_context context;
- krb5_creds *my_creds;
- krb5_auth_context auth_context;
- char Errmsg[256];
-
- retval = krb5_init_context(&context);
- if (retval) {
- com_err(argv[0], retval, "while initializing krb5");
- exit(1);
- }
- PRS(argc, argv);
- get_tickets(context);
-
- database_fd = open_database(context, file, &database_size);
- retval = open_connection(slave_host, &fd, Errmsg, sizeof(Errmsg));
- if (retval) {
- com_err(progname, retval, "%s while opening connection to %s",
- Errmsg, slave_host);
- exit(1);
- }
- if (fd < 0) {
- fprintf(stderr, "%s: %s while opening connection to %s\n",
- progname, Errmsg, slave_host);
- exit(1);
- }
- kerberos_authenticate(context, &auth_context, fd, my_principal,
- &my_creds);
- xmit_database(context, auth_context, my_creds, fd, database_fd,
- database_size);
- update_last_prop_file(slave_host, file);
- printf("Database propagation to %s: SUCCEEDED\n", slave_host);
- krb5_free_cred_contents(context, my_creds);
- close_database(context, database_fd);
- exit(0);
+ int fd, database_fd, database_size;
+ krb5_error_code retval;
+ krb5_context context;
+ krb5_creds *my_creds;
+ krb5_auth_context auth_context;
+ char Errmsg[256];
+
+ retval = krb5_init_context(&context);
+ if (retval) {
+ com_err(argv[0], retval, "while initializing krb5");
+ exit(1);
+ }
+ PRS(argc, argv);
+ get_tickets(context);
+
+ database_fd = open_database(context, file, &database_size);
+ retval = open_connection(slave_host, &fd, Errmsg, sizeof(Errmsg));
+ if (retval) {
+ com_err(progname, retval, "%s while opening connection to %s",
+ Errmsg, slave_host);
+ exit(1);
+ }
+ if (fd < 0) {
+ fprintf(stderr, "%s: %s while opening connection to %s\n",
+ progname, Errmsg, slave_host);
+ exit(1);
+ }
+ kerberos_authenticate(context, &auth_context, fd, my_principal,
+ &my_creds);
+ xmit_database(context, auth_context, my_creds, fd, database_fd,
+ database_size);
+ update_last_prop_file(slave_host, file);
+ printf("Database propagation to %s: SUCCEEDED\n", slave_host);
+ krb5_free_cred_contents(context, my_creds);
+ close_database(context, database_fd);
+ exit(0);
}
void PRS(argc, argv)
- int argc;
- char **argv;
+ int argc;
+ char **argv;
{
- register char *word, ch;
-
- progname = *argv++;
- while (--argc && (word = *argv++)) {
- if (*word == '-') {
- word++;
- while (word && (ch = *word++)) {
- switch(ch){
- case 'r':
- if (*word)
- realm = word;
- else
- realm = *argv++;
- if (!realm)
- usage();
- word = 0;
- break;
- case 'f':
- if (*word)
- file = word;
- else
- file = *argv++;
- if (!file)
- usage();
- word = 0;
- break;
- case 'd':
- debug++;
- break;
- case 'P':
- if (*word)
- port = htons(atoi(word));
- else
- port = htons(atoi(*argv++));
- if (!port)
- usage();
- word = 0;
- break;
- case 's':
- if (*word)
- srvtab = word;
- else
- srvtab = *argv++;
- if (!srvtab)
- usage();
- word = 0;
- break;
- default:
- usage();
- }
-
- }
- } else {
- if (slave_host)
- usage();
- else
- slave_host = word;
- }
- }
- if (!slave_host)
- usage();
+ register char *word, ch;
+
+ progname = *argv++;
+ while (--argc && (word = *argv++)) {
+ if (*word == '-') {
+ word++;
+ while (word && (ch = *word++)) {
+ switch(ch){
+ case 'r':
+ if (*word)
+ realm = word;
+ else
+ realm = *argv++;
+ if (!realm)
+ usage();
+ word = 0;
+ break;
+ case 'f':
+ if (*word)
+ file = word;
+ else
+ file = *argv++;
+ if (!file)
+ usage();
+ word = 0;
+ break;
+ case 'd':
+ debug++;
+ break;
+ case 'P':
+ if (*word)
+ port = htons(atoi(word));
+ else
+ port = htons(atoi(*argv++));
+ if (!port)
+ usage();
+ word = 0;
+ break;
+ case 's':
+ if (*word)
+ srvtab = word;
+ else
+ srvtab = *argv++;
+ if (!srvtab)
+ usage();
+ word = 0;
+ break;
+ default:
+ usage();
+ }
+
+ }
+ } else {
+ if (slave_host)
+ usage();
+ else
+ slave_host = word;
+ }
+ }
+ if (!slave_host)
+ usage();
}
void get_tickets(context)
krb5_context context;
{
- char buf[BUFSIZ];
- krb5_error_code retval;
- static char tkstring[] = "/tmp/kproptktXXXXXX";
- krb5_keytab keytab = NULL;
-
- /*
- * Figure out what tickets we'll be using to send stuff
- */
- retval = krb5_sname_to_principal(context, NULL, NULL,
- KRB5_NT_SRV_HST, &my_principal);
- if (retval) {
- com_err(progname, errno, "while setting client principal name");
- exit(1);
- }
- if (realm) {
- retval = krb5_set_principal_realm(context, my_principal, realm);
- if (retval) {
- com_err(progname, errno,
- "while setting client principal realm");
- exit(1);
- }
- }
+ char buf[BUFSIZ];
+ krb5_error_code retval;
+ static char tkstring[] = "/tmp/kproptktXXXXXX";
+ krb5_keytab keytab = NULL;
+
+ /*
+ * Figure out what tickets we'll be using to send stuff
+ */
+ retval = krb5_sname_to_principal(context, NULL, NULL,
+ KRB5_NT_SRV_HST, &my_principal);
+ if (retval) {
+ com_err(progname, errno, "while setting client principal name");
+ exit(1);
+ }
+ if (realm) {
+ retval = krb5_set_principal_realm(context, my_principal, realm);
+ if (retval) {
+ com_err(progname, errno,
+ "while setting client principal realm");
+ exit(1);
+ }
+ }
#if 0
- krb5_princ_type(context, my_principal) = KRB5_NT_PRINCIPAL;
+ krb5_princ_type(context, my_principal) = KRB5_NT_PRINCIPAL;
#endif
- /*
- * Initialize cache file which we're going to be using
- */
- (void) mktemp(tkstring);
- snprintf(buf, sizeof(buf), "FILE:%s", tkstring);
-
- retval = krb5_cc_resolve(context, buf, &ccache);
- if (retval) {
- com_err(progname, retval, "while opening credential cache %s",
- buf);
- exit(1);
- }
-
- retval = krb5_cc_initialize(context, ccache, my_principal);
- if (retval) {
- com_err (progname, retval, "when initializing cache %s",
- buf);
- exit(1);
- }
-
- /*
- * Get the tickets we'll need.
- *
- * Construct the principal name for the slave host.
- */
- memset(&creds, 0, sizeof(creds));
- retval = krb5_sname_to_principal(context,
- slave_host, KPROP_SERVICE_NAME,
- KRB5_NT_SRV_HST, &creds.server);
- if (retval) {
- com_err(progname, errno, "while setting server principal name");
- (void) krb5_cc_destroy(context, ccache);
- exit(1);
- }
- if (realm) {
- retval = krb5_set_principal_realm(context, creds.server, realm);
- if (retval) {
- com_err(progname, errno,
- "while setting server principal realm");
- exit(1);
- }
- }
-
- /*
- * Now fill in the client....
- */
- retval = krb5_copy_principal(context, my_principal, &creds.client);
- if (retval) {
- com_err(progname, retval, "While copying client principal");
- (void) krb5_cc_destroy(context, ccache);
- exit(1);
- }
- if (srvtab) {
- retval = krb5_kt_resolve(context, srvtab, &keytab);
- if (retval) {
- com_err(progname, retval, "while resolving keytab");
- (void) krb5_cc_destroy(context, ccache);
- exit(1);
- }
- }
-
- retval = krb5_get_in_tkt_with_keytab(context, 0, 0, NULL,
- NULL, keytab, ccache, &creds, 0);
- if (retval) {
- com_err(progname, retval, "while getting initial ticket\n");
- (void) krb5_cc_destroy(context, ccache);
- exit(1);
- }
-
- if (keytab)
- (void) krb5_kt_close(context, keytab);
-
- /*
- * Now destroy the cache right away --- the credentials we
- * need will be in my_creds.
- */
- retval = krb5_cc_destroy(context, ccache);
- if (retval) {
- com_err(progname, retval, "while destroying ticket cache");
- exit(1);
- }
+ /*
+ * Initialize cache file which we're going to be using
+ */
+ (void) mktemp(tkstring);
+ snprintf(buf, sizeof(buf), "FILE:%s", tkstring);
+
+ retval = krb5_cc_resolve(context, buf, &ccache);
+ if (retval) {
+ com_err(progname, retval, "while opening credential cache %s",
+ buf);
+ exit(1);
+ }
+
+ retval = krb5_cc_initialize(context, ccache, my_principal);
+ if (retval) {
+ com_err (progname, retval, "when initializing cache %s",
+ buf);
+ exit(1);
+ }
+
+ /*
+ * Get the tickets we'll need.
+ *
+ * Construct the principal name for the slave host.
+ */
+ memset(&creds, 0, sizeof(creds));
+ retval = krb5_sname_to_principal(context,
+ slave_host, KPROP_SERVICE_NAME,
+ KRB5_NT_SRV_HST, &creds.server);
+ if (retval) {
+ com_err(progname, errno, "while setting server principal name");
+ (void) krb5_cc_destroy(context, ccache);
+ exit(1);
+ }
+ if (realm) {
+ retval = krb5_set_principal_realm(context, creds.server, realm);
+ if (retval) {
+ com_err(progname, errno,
+ "while setting server principal realm");
+ exit(1);
+ }
+ }
+
+ /*
+ * Now fill in the client....
+ */
+ retval = krb5_copy_principal(context, my_principal, &creds.client);
+ if (retval) {
+ com_err(progname, retval, "While copying client principal");
+ (void) krb5_cc_destroy(context, ccache);
+ exit(1);
+ }
+ if (srvtab) {
+ retval = krb5_kt_resolve(context, srvtab, &keytab);
+ if (retval) {
+ com_err(progname, retval, "while resolving keytab");
+ (void) krb5_cc_destroy(context, ccache);
+ exit(1);
+ }
+ }
+
+ retval = krb5_get_in_tkt_with_keytab(context, 0, 0, NULL,
+ NULL, keytab, ccache, &creds, 0);
+ if (retval) {
+ com_err(progname, retval, "while getting initial ticket\n");
+ (void) krb5_cc_destroy(context, ccache);
+ exit(1);
+ }
+
+ if (keytab)
+ (void) krb5_kt_close(context, keytab);
+
+ /*
+ * Now destroy the cache right away --- the credentials we
+ * need will be in my_creds.
+ */
+ retval = krb5_cc_destroy(context, ccache);
+ if (retval) {
+ com_err(progname, retval, "while destroying ticket cache");
+ exit(1);
+ }
}
krb5_error_code
open_connection(host, fd, Errmsg, ErrmsgSz)
- char *host;
- int *fd;
- char *Errmsg;
- unsigned int ErrmsgSz;
+ char *host;
+ int *fd;
+ char *Errmsg;
+ unsigned int ErrmsgSz;
{
- int s;
- krb5_error_code retval;
-
- struct hostent *hp;
- register struct servent *sp;
- struct sockaddr_in my_sin;
- GETSOCKNAME_ARG3_TYPE socket_length;
-
- hp = gethostbyname(host);
- if (hp == NULL) {
- (void) snprintf(Errmsg, ErrmsgSz, "%s: unknown host", host);
- *fd = -1;
- return(0);
- }
- my_sin.sin_family = hp->h_addrtype;
- memcpy(&my_sin.sin_addr, hp->h_addr, sizeof(my_sin.sin_addr));
- if(!port) {
- sp = getservbyname(KPROP_SERVICE, "tcp");
- if (sp == 0) {
- my_sin.sin_port = htons(KPROP_PORT);
- } else {
- my_sin.sin_port = sp->s_port;
- }
- } else
- my_sin.sin_port = port;
- s = socket(AF_INET, SOCK_STREAM, 0);
-
- if (s < 0) {
- (void) snprintf(Errmsg, ErrmsgSz, "in call to socket");
- return(errno);
- }
- if (connect(s, (struct sockaddr *)&my_sin, sizeof my_sin) < 0) {
- retval = errno;
- close(s);
- (void) snprintf(Errmsg, ErrmsgSz, "in call to connect");
- return(retval);
- }
- *fd = s;
-
- /*
- * Set receiver_addr and sender_addr.
- */
- receiver_addr.addrtype = ADDRTYPE_INET;
- receiver_addr.length = sizeof(my_sin.sin_addr);
- receiver_addr.contents = (krb5_octet *) malloc(sizeof(my_sin.sin_addr));
- memcpy(receiver_addr.contents, &my_sin.sin_addr,
- sizeof(my_sin.sin_addr));
-
- socket_length = sizeof(my_sin);
- if (getsockname(s, (struct sockaddr *)&my_sin, &socket_length) < 0) {
- retval = errno;
- close(s);
- (void) snprintf(Errmsg, ErrmsgSz, "in call to getsockname");
- return(retval);
- }
- sender_addr.addrtype = ADDRTYPE_INET;
- sender_addr.length = sizeof(my_sin.sin_addr);
- sender_addr.contents = (krb5_octet *) malloc(sizeof(my_sin.sin_addr));
- memcpy(sender_addr.contents, &my_sin.sin_addr,
- sizeof(my_sin.sin_addr));
-
- return(0);
+ int s;
+ krb5_error_code retval;
+
+ struct hostent *hp;
+ register struct servent *sp;
+ struct sockaddr_in my_sin;
+ GETSOCKNAME_ARG3_TYPE socket_length;
+
+ hp = gethostbyname(host);
+ if (hp == NULL) {
+ (void) snprintf(Errmsg, ErrmsgSz, "%s: unknown host", host);
+ *fd = -1;
+ return(0);
+ }
+ my_sin.sin_family = hp->h_addrtype;
+ memcpy(&my_sin.sin_addr, hp->h_addr, sizeof(my_sin.sin_addr));
+ if(!port) {
+ sp = getservbyname(KPROP_SERVICE, "tcp");
+ if (sp == 0) {
+ my_sin.sin_port = htons(KPROP_PORT);
+ } else {
+ my_sin.sin_port = sp->s_port;
+ }
+ } else
+ my_sin.sin_port = port;
+ s = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (s < 0) {
+ (void) snprintf(Errmsg, ErrmsgSz, "in call to socket");
+ return(errno);
+ }
+ if (connect(s, (struct sockaddr *)&my_sin, sizeof my_sin) < 0) {
+ retval = errno;
+ close(s);
+ (void) snprintf(Errmsg, ErrmsgSz, "in call to connect");
+ return(retval);
+ }
+ *fd = s;
+
+ /*
+ * Set receiver_addr and sender_addr.
+ */
+ receiver_addr.addrtype = ADDRTYPE_INET;
+ receiver_addr.length = sizeof(my_sin.sin_addr);
+ receiver_addr.contents = (krb5_octet *) malloc(sizeof(my_sin.sin_addr));
+ memcpy(receiver_addr.contents, &my_sin.sin_addr,
+ sizeof(my_sin.sin_addr));
+
+ socket_length = sizeof(my_sin);
+ if (getsockname(s, (struct sockaddr *)&my_sin, &socket_length) < 0) {
+ retval = errno;
+ close(s);
+ (void) snprintf(Errmsg, ErrmsgSz, "in call to getsockname");
+ return(retval);
+ }
+ sender_addr.addrtype = ADDRTYPE_INET;
+ sender_addr.length = sizeof(my_sin.sin_addr);
+ sender_addr.contents = (krb5_octet *) malloc(sizeof(my_sin.sin_addr));
+ memcpy(sender_addr.contents, &my_sin.sin_addr,
+ sizeof(my_sin.sin_addr));
+
+ return(0);
}
void kerberos_authenticate(context, auth_context, fd, me, new_creds)
krb5_context context;
krb5_auth_context *auth_context;
- int fd;
+ int fd;
krb5_principal me;
krb5_creds ** new_creds;
{
- krb5_error_code retval;
- krb5_error *error = NULL;
- krb5_ap_rep_enc_part *rep_result;
+ krb5_error_code retval;
+ krb5_error *error = NULL;
+ krb5_ap_rep_enc_part *rep_result;
retval = krb5_auth_con_init(context, auth_context);
if (retval)
- exit(1);
+ exit(1);
krb5_auth_con_setflags(context, *auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
retval = krb5_auth_con_setaddrs(context, *auth_context, &sender_addr,
- &receiver_addr);
+ &receiver_addr);
if (retval) {
- com_err(progname, retval, "in krb5_auth_con_setaddrs");
- exit(1);
+ com_err(progname, retval, "in krb5_auth_con_setaddrs");
+ exit(1);
}
retval = krb5_sendauth(context, auth_context, (void *)&fd,
- kprop_version, me, creds.server,
- AP_OPTS_MUTUAL_REQUIRED, NULL, &creds, NULL,
- &error, &rep_result, new_creds);
+ kprop_version, me, creds.server,
+ AP_OPTS_MUTUAL_REQUIRED, NULL, &creds, NULL,
+ &error, &rep_result, new_creds);
if (retval) {
com_err(progname, retval, "while authenticating to server");
- if (error) {
- if (error->error == KRB_ERR_GENERIC) {
- if (error->text.data)
- fprintf(stderr,
- "Generic remote error: %s\n",
- error->text.data);
- } else if (error->error) {
- com_err(progname,
- (krb5_error_code) error->error + ERROR_TABLE_BASE_krb5,
- "signalled from server");
- if (error->text.data)
- fprintf(stderr,
- "Error text from server: %s\n",
- error->text.data);
- }
- krb5_free_error(context, error);
- }
- exit(1);
+ if (error) {
+ if (error->error == KRB_ERR_GENERIC) {
+ if (error->text.data)
+ fprintf(stderr,
+ "Generic remote error: %s\n",
+ error->text.data);
+ } else if (error->error) {
+ com_err(progname,
+ (krb5_error_code) error->error + ERROR_TABLE_BASE_krb5,
+ "signalled from server");
+ if (error->text.data)
+ fprintf(stderr,
+ "Error text from server: %s\n",
+ error->text.data);
+ }
+ krb5_free_error(context, error);
+ }
+ exit(1);
}
krb5_free_ap_rep_enc_part(context, rep_result);
}
open_database(context, data_fn, size)
krb5_context context;
char *data_fn;
- int *size;
+ int *size;
{
- int fd;
- int err;
- struct stat stbuf, stbuf_ok;
- char *data_ok_fn;
- static char ok[] = ".dump_ok";
-
- dbpathname = strdup(data_fn);
- if (!dbpathname) {
- com_err(progname, ENOMEM, "allocating database file name '%s'",
- data_fn);
- exit(1);
- }
- if ((fd = open(dbpathname, O_RDONLY)) < 0) {
- com_err(progname, errno, "while trying to open %s",
- dbpathname);
- exit(1);
- }
-
- err = krb5_lock_file(context, fd,
- KRB5_LOCKMODE_SHARED|KRB5_LOCKMODE_DONTBLOCK);
- if (err == EAGAIN || err == EWOULDBLOCK || errno == EACCES) {
- com_err(progname, 0, "database locked");
- exit(1);
- } else if (err) {
- com_err(progname, err, "while trying to lock '%s'", dbpathname);
- exit(1);
- }
- if (fstat(fd, &stbuf)) {
- com_err(progname, errno, "while trying to stat %s",
- data_fn);
- exit(1);
- }
- if (asprintf(&data_ok_fn, "%s%s", data_fn, ok) < 0) {
- com_err(progname, ENOMEM, "while trying to malloc data_ok_fn");
- exit(1);
- }
- if (stat(data_ok_fn, &stbuf_ok)) {
- com_err(progname, errno, "while trying to stat %s",
- data_ok_fn);
- free(data_ok_fn);
- exit(1);
- }
- if (stbuf.st_mtime > stbuf_ok.st_mtime) {
- com_err(progname, 0, "'%s' more recent than '%s'.",
- data_fn, data_ok_fn);
- exit(1);
- }
- free(data_ok_fn);
- *size = stbuf.st_size;
- return(fd);
+ int fd;
+ int err;
+ struct stat stbuf, stbuf_ok;
+ char *data_ok_fn;
+ static char ok[] = ".dump_ok";
+
+ dbpathname = strdup(data_fn);
+ if (!dbpathname) {
+ com_err(progname, ENOMEM, "allocating database file name '%s'",
+ data_fn);
+ exit(1);
+ }
+ if ((fd = open(dbpathname, O_RDONLY)) < 0) {
+ com_err(progname, errno, "while trying to open %s",
+ dbpathname);
+ exit(1);
+ }
+
+ err = krb5_lock_file(context, fd,
+ KRB5_LOCKMODE_SHARED|KRB5_LOCKMODE_DONTBLOCK);
+ if (err == EAGAIN || err == EWOULDBLOCK || errno == EACCES) {
+ com_err(progname, 0, "database locked");
+ exit(1);
+ } else if (err) {
+ com_err(progname, err, "while trying to lock '%s'", dbpathname);
+ exit(1);
+ }
+ if (fstat(fd, &stbuf)) {
+ com_err(progname, errno, "while trying to stat %s",
+ data_fn);
+ exit(1);
+ }
+ if (asprintf(&data_ok_fn, "%s%s", data_fn, ok) < 0) {
+ com_err(progname, ENOMEM, "while trying to malloc data_ok_fn");
+ exit(1);
+ }
+ if (stat(data_ok_fn, &stbuf_ok)) {
+ com_err(progname, errno, "while trying to stat %s",
+ data_ok_fn);
+ free(data_ok_fn);
+ exit(1);
+ }
+ if (stbuf.st_mtime > stbuf_ok.st_mtime) {
+ com_err(progname, 0, "'%s' more recent than '%s'.",
+ data_fn, data_ok_fn);
+ exit(1);
+ }
+ free(data_ok_fn);
+ *size = stbuf.st_size;
+ return(fd);
}
void
int err;
err = krb5_lock_file(context, fd, KRB5_LOCKMODE_UNLOCK);
if (err)
- com_err(progname, err, "while unlocking database '%s'", dbpathname);
+ com_err(progname, err, "while unlocking database '%s'", dbpathname);
free(dbpathname);
(void)close(fd);
return;
*/
void
xmit_database(context, auth_context, my_creds, fd, database_fd,
- in_database_size)
+ in_database_size)
krb5_context context;
krb5_auth_context auth_context;
krb5_creds *my_creds;
- int fd;
- int database_fd;
- int in_database_size;
+ int fd;
+ int database_fd;
+ int in_database_size;
{
- krb5_int32 sent_size, n;
- krb5_data inbuf, outbuf;
- char buf[KPROP_BUFSIZ];
- krb5_error_code retval;
- krb5_error *error;
- /* These must be 4 bytes */
- krb5_ui_4 database_size = in_database_size;
- krb5_ui_4 send_size;
-
- /*
- * Send over the size
- */
- send_size = htonl(database_size);
- inbuf.data = (char *) &send_size;
- inbuf.length = sizeof(send_size); /* must be 4, really */
- /* KPROP_CKSUMTYPE */
- retval = krb5_mk_safe(context, auth_context, &inbuf,
- &outbuf, NULL);
- if (retval) {
- com_err(progname, retval, "while encoding database size");
- send_error(context, my_creds, fd, "while encoding database size", retval);
- exit(1);
- }
-
- retval = krb5_write_message(context, (void *) &fd, &outbuf);
- if (retval) {
- krb5_free_data_contents(context, &outbuf);
- com_err(progname, retval, "while sending database size");
- exit(1);
- }
- krb5_free_data_contents(context, &outbuf);
- /*
- * Initialize the initial vector.
- */
- retval = krb5_auth_con_initivector(context, auth_context);
- if (retval) {
- send_error(context, my_creds, fd,
- "failed while initializing i_vector", retval);
- com_err(progname, retval, "while allocating i_vector");
- exit(1);
- }
-
- /*
- * Send over the file, block by block....
- */
- inbuf.data = buf;
- sent_size = 0;
- while ((n = read(database_fd, buf, sizeof(buf)))) {
- inbuf.length = n;
- retval = krb5_mk_priv(context, auth_context, &inbuf,
- &outbuf, NULL);
- if (retval) {
- snprintf(buf, sizeof(buf),
- "while encoding database block starting at %d",
- sent_size);
- com_err(progname, retval, buf);
- send_error(context, my_creds, fd, buf, retval);
- exit(1);
- }
-
- retval = krb5_write_message(context, (void *)&fd,&outbuf);
- if (retval) {
- krb5_free_data_contents(context, &outbuf);
- com_err(progname, retval,
- "while sending database block starting at %d",
- sent_size);
- exit(1);
- }
- krb5_free_data_contents(context, &outbuf);
- sent_size += n;
- if (debug)
- printf("%d bytes sent.\n", sent_size);
- }
- if (sent_size != database_size) {
- com_err(progname, 0, "Premature EOF found for database file!");
- send_error(context, my_creds, fd,"Premature EOF found for database file!",
- KRB5KRB_ERR_GENERIC);
- exit(1);
- }
-
- /*
- * OK, we've sent the database; now let's wait for a success
- * indication from the remote end.
- */
- retval = krb5_read_message(context, (void *) &fd, &inbuf);
- if (retval) {
- com_err(progname, retval,
- "while reading response from server");
- exit(1);
- }
- /*
- * If we got an error response back from the server, display
- * the error message
- */
- if (krb5_is_krb_error(&inbuf)) {
- retval = krb5_rd_error(context, &inbuf, &error);
- if (retval) {
- com_err(progname, retval,
- "while decoding error response from server");
- exit(1);
- }
- if (error->error == KRB_ERR_GENERIC) {
- if (error->text.data)
- fprintf(stderr,
- "Generic remote error: %s\n",
- error->text.data);
- } else if (error->error) {
- com_err(progname,
- (krb5_error_code) error->error +
- ERROR_TABLE_BASE_krb5,
- "signalled from server");
- if (error->text.data)
- fprintf(stderr,
- "Error text from server: %s\n",
- error->text.data);
- }
- krb5_free_error(context, error);
- exit(1);
- }
-
- retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL);
- if (retval) {
- com_err(progname, retval,
- "while decoding final size packet from server");
- exit(1);
- }
-
- memcpy(&send_size, outbuf.data, sizeof(send_size));
- send_size = ntohl(send_size);
- if (send_size != database_size) {
- com_err(progname, 0,
- "Kpropd sent database size %d, expecting %d",
- send_size, database_size);
- exit(1);
- }
- free(outbuf.data);
- /* inbuf.data points to local storage */
+ krb5_int32 sent_size, n;
+ krb5_data inbuf, outbuf;
+ char buf[KPROP_BUFSIZ];
+ krb5_error_code retval;
+ krb5_error *error;
+ /* These must be 4 bytes */
+ krb5_ui_4 database_size = in_database_size;
+ krb5_ui_4 send_size;
+
+ /*
+ * Send over the size
+ */
+ send_size = htonl(database_size);
+ inbuf.data = (char *) &send_size;
+ inbuf.length = sizeof(send_size); /* must be 4, really */
+ /* KPROP_CKSUMTYPE */
+ retval = krb5_mk_safe(context, auth_context, &inbuf,
+ &outbuf, NULL);
+ if (retval) {
+ com_err(progname, retval, "while encoding database size");
+ send_error(context, my_creds, fd, "while encoding database size", retval);
+ exit(1);
+ }
+
+ retval = krb5_write_message(context, (void *) &fd, &outbuf);
+ if (retval) {
+ krb5_free_data_contents(context, &outbuf);
+ com_err(progname, retval, "while sending database size");
+ exit(1);
+ }
+ krb5_free_data_contents(context, &outbuf);
+ /*
+ * Initialize the initial vector.
+ */
+ retval = krb5_auth_con_initivector(context, auth_context);
+ if (retval) {
+ send_error(context, my_creds, fd,
+ "failed while initializing i_vector", retval);
+ com_err(progname, retval, "while allocating i_vector");
+ exit(1);
+ }
+
+ /*
+ * Send over the file, block by block....
+ */
+ inbuf.data = buf;
+ sent_size = 0;
+ while ((n = read(database_fd, buf, sizeof(buf)))) {
+ inbuf.length = n;
+ retval = krb5_mk_priv(context, auth_context, &inbuf,
+ &outbuf, NULL);
+ if (retval) {
+ snprintf(buf, sizeof(buf),
+ "while encoding database block starting at %d",
+ sent_size);
+ com_err(progname, retval, buf);
+ send_error(context, my_creds, fd, buf, retval);
+ exit(1);
+ }
+
+ retval = krb5_write_message(context, (void *)&fd,&outbuf);
+ if (retval) {
+ krb5_free_data_contents(context, &outbuf);
+ com_err(progname, retval,
+ "while sending database block starting at %d",
+ sent_size);
+ exit(1);
+ }
+ krb5_free_data_contents(context, &outbuf);
+ sent_size += n;
+ if (debug)
+ printf("%d bytes sent.\n", sent_size);
+ }
+ if (sent_size != database_size) {
+ com_err(progname, 0, "Premature EOF found for database file!");
+ send_error(context, my_creds, fd,"Premature EOF found for database file!",
+ KRB5KRB_ERR_GENERIC);
+ exit(1);
+ }
+
+ /*
+ * OK, we've sent the database; now let's wait for a success
+ * indication from the remote end.
+ */
+ retval = krb5_read_message(context, (void *) &fd, &inbuf);
+ if (retval) {
+ com_err(progname, retval,
+ "while reading response from server");
+ exit(1);
+ }
+ /*
+ * If we got an error response back from the server, display
+ * the error message
+ */
+ if (krb5_is_krb_error(&inbuf)) {
+ retval = krb5_rd_error(context, &inbuf, &error);
+ if (retval) {
+ com_err(progname, retval,
+ "while decoding error response from server");
+ exit(1);
+ }
+ if (error->error == KRB_ERR_GENERIC) {
+ if (error->text.data)
+ fprintf(stderr,
+ "Generic remote error: %s\n",
+ error->text.data);
+ } else if (error->error) {
+ com_err(progname,
+ (krb5_error_code) error->error +
+ ERROR_TABLE_BASE_krb5,
+ "signalled from server");
+ if (error->text.data)
+ fprintf(stderr,
+ "Error text from server: %s\n",
+ error->text.data);
+ }
+ krb5_free_error(context, error);
+ exit(1);
+ }
+
+ retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL);
+ if (retval) {
+ com_err(progname, retval,
+ "while decoding final size packet from server");
+ exit(1);
+ }
+
+ memcpy(&send_size, outbuf.data, sizeof(send_size));
+ send_size = ntohl(send_size);
+ if (send_size != database_size) {
+ com_err(progname, 0,
+ "Kpropd sent database size %d, expecting %d",
+ send_size, database_size);
+ exit(1);
+ }
+ free(outbuf.data);
+ /* inbuf.data points to local storage */
}
void
send_error(context, my_creds, fd, err_text, err_code)
krb5_context context;
krb5_creds *my_creds;
- int fd;
- char *err_text;
- krb5_error_code err_code;
+ int fd;
+ char *err_text;
+ krb5_error_code err_code;
{
- krb5_error error;
- const char *text;
- krb5_data outbuf;
-
- memset(&error, 0, sizeof(error));
- krb5_us_timeofday(context, &error.ctime, &error.cusec);
- error.server = my_creds->server;
- error.client = my_principal;
- error.error = err_code - ERROR_TABLE_BASE_krb5;
- if (error.error > 127)
- error.error = KRB_ERR_GENERIC;
- if (err_text)
- text = err_text;
- else
- text = error_message(err_code);
- error.text.length = strlen(text) + 1;
- error.text.data = strdup(text);
- if (error.text.data) {
- if (!krb5_mk_error(context, &error, &outbuf)) {
- (void) krb5_write_message(context, (void *)&fd,&outbuf);
- krb5_free_data_contents(context, &outbuf);
- }
- free(error.text.data);
- }
+ krb5_error error;
+ const char *text;
+ krb5_data outbuf;
+
+ memset(&error, 0, sizeof(error));
+ krb5_us_timeofday(context, &error.ctime, &error.cusec);
+ error.server = my_creds->server;
+ error.client = my_principal;
+ error.error = err_code - ERROR_TABLE_BASE_krb5;
+ if (error.error > 127)
+ error.error = KRB_ERR_GENERIC;
+ if (err_text)
+ text = err_text;
+ else
+ text = error_message(err_code);
+ error.text.length = strlen(text) + 1;
+ error.text.data = strdup(text);
+ if (error.text.data) {
+ if (!krb5_mk_error(context, &error, &outbuf)) {
+ (void) krb5_write_message(context, (void *)&fd,&outbuf);
+ krb5_free_data_contents(context, &outbuf);
+ }
+ free(error.text.data);
+ }
}
void update_last_prop_file(hostname, file_name)
- char *hostname;
- char *file_name;
+ char *hostname;
+ char *file_name;
{
- /* handle slave locking/failure stuff */
- char *file_last_prop;
- int fd;
- static char last_prop[]=".last_prop";
-
- if (asprintf(&file_last_prop, "%s.%s%s", file_name, hostname,
- last_prop) < 0) {
- com_err(progname, ENOMEM,
- "while allocating filename for update_last_prop_file");
- return;
- }
- if ((fd = THREEPARAMOPEN(file_last_prop, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
- com_err(progname, errno,
- "while creating 'last_prop' file, '%s'",
- file_last_prop);
- free(file_last_prop);
- return;
- }
- write(fd, "", 1);
- free(file_last_prop);
- close(fd);
- return;
+ /* handle slave locking/failure stuff */
+ char *file_last_prop;
+ int fd;
+ static char last_prop[]=".last_prop";
+
+ if (asprintf(&file_last_prop, "%s.%s%s", file_name, hostname,
+ last_prop) < 0) {
+ com_err(progname, ENOMEM,
+ "while allocating filename for update_last_prop_file");
+ return;
+ }
+ if ((fd = THREEPARAMOPEN(file_last_prop, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
+ com_err(progname, errno,
+ "while creating 'last_prop' file, '%s'",
+ file_last_prop);
+ free(file_last_prop);
+ return;
+ }
+ write(fd, "", 1);
+ free(file_last_prop);
+ close(fd);
+ return;
}
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
* lib/kadm5/clnt/client_internal.h!
*/
typedef struct _kadm5_iprop_handle_t {
- krb5_ui_4 magic_number;
- krb5_ui_4 struct_version;
- krb5_ui_4 api_version;
- char *cache_name;
- int destroy_cache;
- CLIENT *clnt;
- krb5_context context;
- kadm5_config_params params;
- struct _kadm5_iprop_handle_t *lhandle;
+ krb5_ui_4 magic_number;
+ krb5_ui_4 struct_version;
+ krb5_ui_4 api_version;
+ char *cache_name;
+ int destroy_cache;
+ CLIENT *clnt;
+ krb5_context context;
+ kadm5_config_params params;
+ struct _kadm5_iprop_handle_t *lhandle;
} *kadm5_iprop_handle_t;
static char *kprop_version = KPROP_PROT_VERSION;
-char *progname;
+char *progname;
int debug = 0;
-char *srvtab = 0;
-int standalone = 0;
+char *srvtab = 0;
+int standalone = 0;
-krb5_principal server; /* This is our server principal name */
-krb5_principal client; /* This is who we're talking to */
+krb5_principal server; /* This is our server principal name */
+krb5_principal client; /* This is who we're talking to */
krb5_context kpropd_context;
krb5_auth_context auth_context;
-char *realm = NULL; /* Our realm */
-char *file = KPROPD_DEFAULT_FILE;
-char *temp_file_name;
-char *kdb5_util = KPROPD_DEFAULT_KDB5_UTIL;
-char *kerb_database = NULL;
-char *acl_file_name = KPROPD_ACL_FILE;
+char *realm = NULL; /* Our realm */
+char *file = KPROPD_DEFAULT_FILE;
+char *temp_file_name;
+char *kdb5_util = KPROPD_DEFAULT_KDB5_UTIL;
+char *kerb_database = NULL;
+char *acl_file_name = KPROPD_ACL_FILE;
-krb5_address sender_addr;
-krb5_address receiver_addr;
-short port = 0;
+krb5_address sender_addr;
+krb5_address receiver_addr;
+short port = 0;
char **db_args = NULL;
int db_args_size = 0;
-void PRS
- (char**);
-int do_standalone
- (iprop_role iproprole);
-void doit
- (int);
+void PRS(char**);
+int do_standalone(iprop_role iproprole);
+void doit(int);
krb5_error_code do_iprop(kdb_log_context *log_ctx);
-void kerberos_authenticate
- (krb5_context,
- int,
- krb5_principal *,
- krb5_enctype *,
- struct sockaddr_in);
-krb5_boolean authorized_principal
- (krb5_context,
- krb5_principal,
- krb5_enctype);
-void recv_database
- (krb5_context,
- int,
- int,
- krb5_data *);
-void load_database
- (krb5_context,
- char *,
- char *);
-void send_error
- (krb5_context,
- int,
- krb5_error_code,
- char *);
-void recv_error
- (krb5_context,
- krb5_data *);
+void kerberos_authenticate(
+ krb5_context,
+ int,
+ krb5_principal *,
+ krb5_enctype *,
+ struct sockaddr_in);
+krb5_boolean authorized_principal(krb5_context, krb5_principal, krb5_enctype);
+void recv_database(krb5_context, int, int, krb5_data *);
+void load_database(krb5_context, char *, char *);
+void send_error(krb5_context, int, krb5_error_code, char *);
+void recv_error(krb5_context, krb5_data *);
unsigned int backoff_from_master(int *);
static kadm5_ret_t
kadm5_get_kiprop_host_srv_name(krb5_context context,
- const char *realm_name,
- char **host_service_name);
+ const char *realm_name,
+ char **host_service_name);
static void usage()
{
- fprintf(stderr,
- "\nUsage: %s [-r realm] [-s srvtab] [-dS] [-f slave_file]\n",
- progname);
- fprintf(stderr, "\t[-F kerberos_db_file ] [-p kdb5_util_pathname]\n");
- fprintf(stderr, "\t[-x db_args]* [-P port] [-a acl_file]\n");
- exit(1);
+ fprintf(stderr,
+ "\nUsage: %s [-r realm] [-s srvtab] [-dS] [-f slave_file]\n",
+ progname);
+ fprintf(stderr, "\t[-F kerberos_db_file ] [-p kdb5_util_pathname]\n");
+ fprintf(stderr, "\t[-x db_args]* [-P port] [-a acl_file]\n");
+ exit(1);
}
int
main(argc, argv)
- int argc;
- char **argv;
+ int argc;
+ char **argv;
{
krb5_error_code retval;
int ret = 0;
{
#ifdef POSIX_SIGNALS
- struct sigaction s_action;
- memset(&s_action, 0, sizeof(s_action));
- sigemptyset(&s_action.sa_mask);
- s_action.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &s_action, NULL);
+ struct sigaction s_action;
+ memset(&s_action, 0, sizeof(s_action));
+ sigemptyset(&s_action.sa_mask);
+ s_action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &s_action, NULL);
#else
- signal(SIGPIPE, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
#endif
}
if (log_ctx && (log_ctx->iproprole == IPROP_SLAVE)) {
- /*
- * We wanna do iprop !
- */
- retval = do_iprop(log_ctx);
- if (retval) {
- com_err(progname, retval,
- _("do_iprop failed.\n"));
- exit(1);
- }
+ /*
+ * We wanna do iprop !
+ */
+ retval = do_iprop(log_ctx);
+ if (retval) {
+ com_err(progname, retval,
+ _("do_iprop failed.\n"));
+ exit(1);
+ }
} else {
- if (standalone)
- ret = do_standalone(IPROP_NULL);
- else
- doit(0);
+ if (standalone)
+ ret = do_standalone(IPROP_NULL);
+ else
+ doit(0);
}
exit(ret);
{
close (gfd);
if (debug)
- fprintf(stderr, _("resync_alarm: closing fd: %d\n"), gfd);
+ fprintf(stderr, _("resync_alarm: closing fd: %d\n"), gfd);
gfd = -1;
}
int do_standalone(iprop_role iproprole)
{
- struct sockaddr_in my_sin, frominet;
- struct servent *sp;
- int finet, s;
- GETPEERNAME_ARG3_TYPE fromlen;
- int ret;
- /*
- * Timer for accept/read calls, in case of network type errors.
- */
- int backoff_timer = INITIAL_TIMER;
+ struct sockaddr_in my_sin, frominet;
+ struct servent *sp;
+ int finet, s;
+ GETPEERNAME_ARG3_TYPE fromlen;
+ int ret;
+ /*
+ * Timer for accept/read calls, in case of network type errors.
+ */
+ int backoff_timer = INITIAL_TIMER;
retry:
- finet = socket(AF_INET, SOCK_STREAM, 0);
- if (finet < 0) {
- com_err(progname, errno, "while obtaining socket");
- exit(1);
- }
- memset(&my_sin,0, sizeof(my_sin));
- if(!port) {
- sp = getservbyname(KPROP_SERVICE, "tcp");
- if (sp == NULL) {
- com_err(progname, 0, "%s/tcp: unknown service", KPROP_SERVICE);
- my_sin.sin_port = htons(KPROP_PORT);
- }
- else my_sin.sin_port = sp->s_port;
- } else {
- my_sin.sin_port = port;
- }
- my_sin.sin_family = AF_INET;
-
- /*
- * We need to close the socket immediately if iprop is enabled,
- * since back-to-back full resyncs are possible, so we do not
- * linger around for too long
- */
- if (iproprole == IPROP_SLAVE) {
- int on = 1;
- struct linger linger;
-
- if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on)) < 0)
- com_err(progname, errno,
- _("while setting socket option (SO_REUSEADDR)"));
- linger.l_onoff = 1;
- linger.l_linger = 2;
- if (setsockopt(finet, SOL_SOCKET, SO_LINGER,
- (void *)&linger, sizeof(linger)) < 0)
- com_err(progname, errno,
- _("while setting socket option (SO_LINGER)"));
- /*
- * We also want to set a timer so that the slave is not waiting
- * until infinity for an update from the master.
- */
- gfd = finet;
- signal(SIGALRM, resync_alarm);
- if (debug) {
- fprintf(stderr, "do_standalone: setting resync alarm to %d\n",
- backoff_timer);
- }
- if (alarm(backoff_timer) != 0) {
- if (debug) {
- fprintf(stderr,
- _("%s: alarm already set\n"), progname);
- }
- }
- backoff_timer *= 2;
- }
- if ((ret = bind(finet, (struct sockaddr *) &my_sin, sizeof(my_sin))) < 0) {
- if (debug) {
- int on = 1;
- fprintf(stderr,
- "%s: attempting to rebind socket with SO_REUSEADDR\n",
- progname);
- if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on)) < 0)
- com_err(progname, errno, "in setsockopt(SO_REUSEADDR)");
- ret = bind(finet, (struct sockaddr *) &my_sin, sizeof(my_sin));
- }
- if (ret < 0) {
- perror("bind");
- com_err(progname, errno, "while binding listener socket");
- exit(1);
- }
- }
- if (!debug && iproprole != IPROP_SLAVE)
- daemon(1, 0);
+ finet = socket(AF_INET, SOCK_STREAM, 0);
+ if (finet < 0) {
+ com_err(progname, errno, "while obtaining socket");
+ exit(1);
+ }
+ memset(&my_sin,0, sizeof(my_sin));
+ if(!port) {
+ sp = getservbyname(KPROP_SERVICE, "tcp");
+ if (sp == NULL) {
+ com_err(progname, 0, "%s/tcp: unknown service", KPROP_SERVICE);
+ my_sin.sin_port = htons(KPROP_PORT);
+ }
+ else my_sin.sin_port = sp->s_port;
+ } else {
+ my_sin.sin_port = port;
+ }
+ my_sin.sin_family = AF_INET;
+
+ /*
+ * We need to close the socket immediately if iprop is enabled,
+ * since back-to-back full resyncs are possible, so we do not
+ * linger around for too long
+ */
+ if (iproprole == IPROP_SLAVE) {
+ int on = 1;
+ struct linger linger;
+
+ if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&on, sizeof(on)) < 0)
+ com_err(progname, errno,
+ _("while setting socket option (SO_REUSEADDR)"));
+ linger.l_onoff = 1;
+ linger.l_linger = 2;
+ if (setsockopt(finet, SOL_SOCKET, SO_LINGER,
+ (void *)&linger, sizeof(linger)) < 0)
+ com_err(progname, errno,
+ _("while setting socket option (SO_LINGER)"));
+ /*
+ * We also want to set a timer so that the slave is not waiting
+ * until infinity for an update from the master.
+ */
+ gfd = finet;
+ signal(SIGALRM, resync_alarm);
+ if (debug) {
+ fprintf(stderr, "do_standalone: setting resync alarm to %d\n",
+ backoff_timer);
+ }
+ if (alarm(backoff_timer) != 0) {
+ if (debug) {
+ fprintf(stderr,
+ _("%s: alarm already set\n"), progname);
+ }
+ }
+ backoff_timer *= 2;
+ }
+ if ((ret = bind(finet, (struct sockaddr *) &my_sin, sizeof(my_sin))) < 0) {
+ if (debug) {
+ int on = 1;
+ fprintf(stderr,
+ "%s: attempting to rebind socket with SO_REUSEADDR\n",
+ progname);
+ if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&on, sizeof(on)) < 0)
+ com_err(progname, errno, "in setsockopt(SO_REUSEADDR)");
+ ret = bind(finet, (struct sockaddr *) &my_sin, sizeof(my_sin));
+ }
+ if (ret < 0) {
+ perror("bind");
+ com_err(progname, errno, "while binding listener socket");
+ exit(1);
+ }
+ }
+ if (!debug && iproprole != IPROP_SLAVE)
+ daemon(1, 0);
#ifdef PID_FILE
- if ((pidfile = fopen(PID_FILE, "w")) != NULL) {
- fprintf(pidfile, "%d\n", getpid());
- fclose(pidfile);
- } else
- com_err(progname, errno,
- "while opening pid file %s for writing", PID_FILE);
+ if ((pidfile = fopen(PID_FILE, "w")) != NULL) {
+ fprintf(pidfile, "%d\n", getpid());
+ fclose(pidfile);
+ } else
+ com_err(progname, errno,
+ "while opening pid file %s for writing", PID_FILE);
#endif
- if (listen(finet, 5) < 0) {
- com_err(progname, errno, "in listen call");
- exit(1);
- }
- while (1) {
- int child_pid;
- int status;
-
- memset(&frominet, 0, sizeof(frominet));
- fromlen = sizeof(frominet);
- if (debug)
- fprintf(stderr, "waiting for a kprop connection\n");
- s = accept(finet, (struct sockaddr *) &frominet, &fromlen);
-
- if (s < 0) {
- int e = errno;
- if (e != EINTR) {
- com_err(progname, e,
- _("while accepting connection"));
- if (e != EBADF)
- backoff_timer = INITIAL_TIMER;
- }
- /*
- * If we got EBADF, an alarm signal handler closed
- * the file descriptor on us.
- */
- if (e != EBADF)
- close(finet);
- /*
- * An alarm could have been set and the fd closed, we
- * should retry in case of transient network error for
- * up to a couple of minutes.
- */
- if (backoff_timer > 120)
- return EINTR;
- goto retry;
- }
- alarm(0);
- gfd = -1;
- if (debug && iproprole != IPROP_SLAVE)
- child_pid = 0;
- else
- child_pid = fork();
- switch (child_pid) {
- case -1:
- com_err(progname, errno, "while forking");
- exit(1);
- case 0:
- (void) close(finet);
-
- doit(s);
- close(s);
- _exit(0);
- default:
- /*
- * Errors should not be considered fatal in the
- * iprop case as we could have transient type
- * errors, such as network outage, etc. Sleeping
- * 3s for 2s linger interval.
- */
- if (wait(&status) < 0) {
- com_err(progname, errno,
- _("while waiting to receive database"));
- if (iproprole != IPROP_SLAVE)
- exit(1);
- sleep(3);
- }
-
- close(s);
- if (iproprole == IPROP_SLAVE)
- close(finet);
-
- if ((ret = WEXITSTATUS(status)) != 0)
- return (ret);
- }
- if (iproprole == IPROP_SLAVE)
- break;
- }
- return 0;
+ if (listen(finet, 5) < 0) {
+ com_err(progname, errno, "in listen call");
+ exit(1);
+ }
+ while (1) {
+ int child_pid;
+ int status;
+
+ memset(&frominet, 0, sizeof(frominet));
+ fromlen = sizeof(frominet);
+ if (debug)
+ fprintf(stderr, "waiting for a kprop connection\n");
+ s = accept(finet, (struct sockaddr *) &frominet, &fromlen);
+
+ if (s < 0) {
+ int e = errno;
+ if (e != EINTR) {
+ com_err(progname, e,
+ _("while accepting connection"));
+ if (e != EBADF)
+ backoff_timer = INITIAL_TIMER;
+ }
+ /*
+ * If we got EBADF, an alarm signal handler closed
+ * the file descriptor on us.
+ */
+ if (e != EBADF)
+ close(finet);
+ /*
+ * An alarm could have been set and the fd closed, we
+ * should retry in case of transient network error for
+ * up to a couple of minutes.
+ */
+ if (backoff_timer > 120)
+ return EINTR;
+ goto retry;
+ }
+ alarm(0);
+ gfd = -1;
+ if (debug && iproprole != IPROP_SLAVE)
+ child_pid = 0;
+ else
+ child_pid = fork();
+ switch (child_pid) {
+ case -1:
+ com_err(progname, errno, "while forking");
+ exit(1);
+ case 0:
+ (void) close(finet);
+
+ doit(s);
+ close(s);
+ _exit(0);
+ default:
+ /*
+ * Errors should not be considered fatal in the
+ * iprop case as we could have transient type
+ * errors, such as network outage, etc. Sleeping
+ * 3s for 2s linger interval.
+ */
+ if (wait(&status) < 0) {
+ com_err(progname, errno,
+ _("while waiting to receive database"));
+ if (iproprole != IPROP_SLAVE)
+ exit(1);
+ sleep(3);
+ }
+
+ close(s);
+ if (iproprole == IPROP_SLAVE)
+ close(finet);
+
+ if ((ret = WEXITSTATUS(status)) != 0)
+ return (ret);
+ }
+ if (iproprole == IPROP_SLAVE)
+ break;
+ }
+ return 0;
}
void doit(fd)
- int fd;
+ int fd;
{
- struct sockaddr_in from;
- int on = 1;
- GETPEERNAME_ARG3_TYPE fromlen;
- struct hostent *hp;
- krb5_error_code retval;
- krb5_data confmsg;
- int lock_fd;
- mode_t omask;
- krb5_enctype etype;
- int database_fd;
-
- if (kpropd_context->kdblog_context &&
- kpropd_context->kdblog_context->iproprole == IPROP_SLAVE) {
- /*
- * We also want to set a timer so that the slave is not waiting
- * until infinity for an update from the master.
- */
- if (debug)
- fprintf(stderr, "doit: setting resync alarm to 5s\n");
- signal(SIGALRM, resync_alarm);
- gfd = fd;
- if (alarm(INITIAL_TIMER) != 0) {
- if (debug) {
- fprintf(stderr,
- _("%s: alarm already set\n"), progname);
- }
- }
- }
- fromlen = sizeof (from);
- if (getpeername(fd, (struct sockaddr *) &from, &fromlen) < 0) {
+ struct sockaddr_in from;
+ int on = 1;
+ GETPEERNAME_ARG3_TYPE fromlen;
+ struct hostent *hp;
+ krb5_error_code retval;
+ krb5_data confmsg;
+ int lock_fd;
+ mode_t omask;
+ krb5_enctype etype;
+ int database_fd;
+
+ if (kpropd_context->kdblog_context &&
+ kpropd_context->kdblog_context->iproprole == IPROP_SLAVE) {
+ /*
+ * We also want to set a timer so that the slave is not waiting
+ * until infinity for an update from the master.
+ */
+ if (debug)
+ fprintf(stderr, "doit: setting resync alarm to 5s\n");
+ signal(SIGALRM, resync_alarm);
+ gfd = fd;
+ if (alarm(INITIAL_TIMER) != 0) {
+ if (debug) {
+ fprintf(stderr,
+ _("%s: alarm already set\n"), progname);
+ }
+ }
+ }
+ fromlen = sizeof (from);
+ if (getpeername(fd, (struct sockaddr *) &from, &fromlen) < 0) {
#ifdef ENOTSOCK
- if (errno == ENOTSOCK && fd == 0 && !standalone) {
- fprintf(stderr,
- "%s: Standard input does not appear to be a network socket.\n"
- "\t(Not run from inetd, and missing the -S option?)\n",
- progname);
- exit(1);
- }
+ if (errno == ENOTSOCK && fd == 0 && !standalone) {
+ fprintf(stderr,
+ "%s: Standard input does not appear to be a network socket.\n"
+ "\t(Not run from inetd, and missing the -S option?)\n",
+ progname);
+ exit(1);
+ }
#endif
- fprintf(stderr, "%s: ", progname);
- perror("getpeername");
- exit(1);
- }
- if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (caddr_t) &on,
- sizeof (on)) < 0) {
- com_err(progname, errno,
- "while attempting setsockopt (SO_KEEPALIVE)");
- }
-
- if (!(hp = gethostbyaddr((char *) &(from.sin_addr.s_addr), fromlen,
- AF_INET))) {
- syslog(LOG_INFO, "Connection from %s",
- inet_ntoa(from.sin_addr));
- if (debug)
- printf("Connection from %s\n",
- inet_ntoa(from.sin_addr));
- } else {
- syslog(LOG_INFO, "Connection from %s", hp->h_name);
- if (debug)
- printf("Connection from %s\n", hp->h_name);
- }
-
- /*
- * Now do the authentication
- */
- kerberos_authenticate(kpropd_context, fd, &client, &etype, from);
-
- /*
- * Turn off alarm upon successful authentication from master.
- */
- alarm(0);
- gfd = -1;
-
- if (!authorized_principal(kpropd_context, client, etype)) {
- char *name;
-
- retval = krb5_unparse_name(kpropd_context, client, &name);
- if (retval) {
- com_err(progname, retval,
- "While unparsing client name");
- exit(1);
- }
- if (debug)
- fprintf(stderr,
- "Rejected connection from unauthorized principal %s\n",
- name);
- syslog(LOG_WARNING,
- "Rejected connection from unauthorized principal %s",
- name);
- free(name);
- exit(1);
- }
- omask = umask(077);
- lock_fd = open(temp_file_name, O_RDWR|O_CREAT, 0600);
- (void) umask(omask);
- retval = krb5_lock_file(kpropd_context, lock_fd,
- KRB5_LOCKMODE_EXCLUSIVE|KRB5_LOCKMODE_DONTBLOCK);
- if (retval) {
- com_err(progname, retval, "while trying to lock '%s'",
- temp_file_name);
- exit(1);
- }
- if ((database_fd = open(temp_file_name,
- O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
- com_err(progname, errno,
- "while opening database file, '%s'",
- temp_file_name);
- exit(1);
- }
- recv_database(kpropd_context, fd, database_fd, &confmsg);
- if (rename(temp_file_name, file)) {
- com_err(progname, errno, "While renaming %s to %s",
- temp_file_name, file);
- exit(1);
- }
- retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_SHARED);
- if (retval) {
- com_err(progname, retval, "while downgrading lock on '%s'",
- temp_file_name);
- exit(1);
- }
- load_database(kpropd_context, kdb5_util, file);
- retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_UNLOCK);
- if (retval) {
- com_err(progname, retval, "while unlocking '%s'", temp_file_name);
- exit(1);
- }
- (void)close(lock_fd);
-
- /*
- * Send the acknowledgement message generated in
- * recv_database, then close the socket.
- */
- retval = krb5_write_message(kpropd_context, (void *) &fd, &confmsg);
- if (retval) {
- krb5_free_data_contents(kpropd_context, &confmsg);
- com_err(progname, retval,
- "while sending # of received bytes");
- exit(1);
- }
- krb5_free_data_contents(kpropd_context, &confmsg);
- if (close(fd) < 0) {
- com_err(progname, errno,
- "while trying to close database file");
- exit(1);
- }
-
- exit(0);
+ fprintf(stderr, "%s: ", progname);
+ perror("getpeername");
+ exit(1);
+ }
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (caddr_t) &on,
+ sizeof (on)) < 0) {
+ com_err(progname, errno,
+ "while attempting setsockopt (SO_KEEPALIVE)");
+ }
+
+ if (!(hp = gethostbyaddr((char *) &(from.sin_addr.s_addr), fromlen,
+ AF_INET))) {
+ syslog(LOG_INFO, "Connection from %s",
+ inet_ntoa(from.sin_addr));
+ if (debug)
+ printf("Connection from %s\n",
+ inet_ntoa(from.sin_addr));
+ } else {
+ syslog(LOG_INFO, "Connection from %s", hp->h_name);
+ if (debug)
+ printf("Connection from %s\n", hp->h_name);
+ }
+
+ /*
+ * Now do the authentication
+ */
+ kerberos_authenticate(kpropd_context, fd, &client, &etype, from);
+
+ /*
+ * Turn off alarm upon successful authentication from master.
+ */
+ alarm(0);
+ gfd = -1;
+
+ if (!authorized_principal(kpropd_context, client, etype)) {
+ char *name;
+
+ retval = krb5_unparse_name(kpropd_context, client, &name);
+ if (retval) {
+ com_err(progname, retval,
+ "While unparsing client name");
+ exit(1);
+ }
+ if (debug)
+ fprintf(stderr,
+ "Rejected connection from unauthorized principal %s\n",
+ name);
+ syslog(LOG_WARNING,
+ "Rejected connection from unauthorized principal %s",
+ name);
+ free(name);
+ exit(1);
+ }
+ omask = umask(077);
+ lock_fd = open(temp_file_name, O_RDWR|O_CREAT, 0600);
+ (void) umask(omask);
+ retval = krb5_lock_file(kpropd_context, lock_fd,
+ KRB5_LOCKMODE_EXCLUSIVE|KRB5_LOCKMODE_DONTBLOCK);
+ if (retval) {
+ com_err(progname, retval, "while trying to lock '%s'",
+ temp_file_name);
+ exit(1);
+ }
+ if ((database_fd = open(temp_file_name,
+ O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
+ com_err(progname, errno,
+ "while opening database file, '%s'",
+ temp_file_name);
+ exit(1);
+ }
+ recv_database(kpropd_context, fd, database_fd, &confmsg);
+ if (rename(temp_file_name, file)) {
+ com_err(progname, errno, "While renaming %s to %s",
+ temp_file_name, file);
+ exit(1);
+ }
+ retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_SHARED);
+ if (retval) {
+ com_err(progname, retval, "while downgrading lock on '%s'",
+ temp_file_name);
+ exit(1);
+ }
+ load_database(kpropd_context, kdb5_util, file);
+ retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_UNLOCK);
+ if (retval) {
+ com_err(progname, retval, "while unlocking '%s'", temp_file_name);
+ exit(1);
+ }
+ (void)close(lock_fd);
+
+ /*
+ * Send the acknowledgement message generated in
+ * recv_database, then close the socket.
+ */
+ retval = krb5_write_message(kpropd_context, (void *) &fd, &confmsg);
+ if (retval) {
+ krb5_free_data_contents(kpropd_context, &confmsg);
+ com_err(progname, retval,
+ "while sending # of received bytes");
+ exit(1);
+ }
+ krb5_free_data_contents(kpropd_context, &confmsg);
+ if (close(fd) < 0) {
+ com_err(progname, errno,
+ "while trying to close database file");
+ exit(1);
+ }
+
+ exit(0);
}
/* Default timeout can be changed using clnt_control() */
static kdb_fullresync_result_t *
full_resync(CLIENT *clnt)
{
- static kdb_fullresync_result_t clnt_res;
- uint32_t vers = IPROPX_VERSION_1; /* max version we support */
- enum clnt_stat status;
-
- memset(&clnt_res, 0, sizeof(clnt_res));
-
- status = clnt_call (clnt, IPROP_FULL_RESYNC_EXT,
- (xdrproc_t) xdr_u_int32,
- (caddr_t) &vers,
- (xdrproc_t) xdr_kdb_fullresync_result_t,
- (caddr_t) &clnt_res,
- full_resync_timeout);
- if (status == RPC_PROCUNAVAIL) {
- status = clnt_call (clnt, IPROP_FULL_RESYNC,
- (xdrproc_t) xdr_void,
- (caddr_t *)&vers,
- (xdrproc_t) xdr_kdb_fullresync_result_t,
- (caddr_t) &clnt_res,
- full_resync_timeout);
- }
-
- return (status == RPC_SUCCESS) ? &clnt_res : NULL;
+ static kdb_fullresync_result_t clnt_res;
+ uint32_t vers = IPROPX_VERSION_1; /* max version we support */
+ enum clnt_stat status;
+
+ memset(&clnt_res, 0, sizeof(clnt_res));
+
+ status = clnt_call (clnt, IPROP_FULL_RESYNC_EXT,
+ (xdrproc_t) xdr_u_int32,
+ (caddr_t) &vers,
+ (xdrproc_t) xdr_kdb_fullresync_result_t,
+ (caddr_t) &clnt_res,
+ full_resync_timeout);
+ if (status == RPC_PROCUNAVAIL) {
+ status = clnt_call (clnt, IPROP_FULL_RESYNC,
+ (xdrproc_t) xdr_void,
+ (caddr_t *)&vers,
+ (xdrproc_t) xdr_kdb_fullresync_result_t,
+ (caddr_t) &clnt_res,
+ full_resync_timeout);
+ }
+
+ return (status == RPC_SUCCESS) ? &clnt_res : NULL;
}
/*
kadm5_config_params params;
krb5_error_code do_iprop(kdb_log_context *log_ctx)
{
- kadm5_ret_t retval;
- krb5_ccache cc;
- krb5_principal iprop_svc_principal;
- void *server_handle = NULL;
- char *iprop_svc_princstr = NULL;
- char *master_svc_princstr = NULL;
- unsigned int pollin, backoff_time;
- int backoff_cnt = 0;
- int reinit_cnt = 0;
- int ret;
- int frdone = 0;
-
- kdb_incr_result_t *incr_ret;
- static kdb_last_t mylast;
-
- kdb_fullresync_result_t *full_ret;
-
- kadm5_iprop_handle_t handle;
- kdb_hlog_t *ulog;
-
- if (!debug)
- daemon(0, 0);
-
- ulog = log_ctx->ulog;
-
- pollin = params.iprop_poll_time;
- if (pollin < 10)
- pollin = 10;
-
- /*
- * Grab the realm info and check if iprop is enabled.
- */
- if (def_realm == NULL) {
- retval = krb5_get_default_realm(kpropd_context, &def_realm);
- if (retval) {
- com_err(progname, retval,
- _("Unable to get default realm"));
- exit(1);
- }
- }
-
- params.mask |= KADM5_CONFIG_REALM;
- params.realm = def_realm;
-
- if (master_svc_princstr == NULL) {
- if ((retval = kadm5_get_kiprop_host_srv_name(kpropd_context,
- def_realm,
- &master_svc_princstr))) {
- com_err(progname, retval,
- _("%s: unable to get kiprop host based "
- "service name for realm %s\n"),
- progname, def_realm);
- exit(1);
- }
- }
-
- /*
- * Set cc to the default credentials cache
- */
- if ((retval = krb5_cc_default(kpropd_context, &cc))) {
- com_err(progname, retval,
- _("while opening default "
- "credentials cache"));
- exit(1);
- }
-
- retval = krb5_sname_to_principal(kpropd_context, NULL, KIPROP_SVC_NAME,
- KRB5_NT_SRV_HST, &iprop_svc_principal);
- if (retval) {
- com_err(progname, retval,
- _("while trying to construct host service principal"));
- exit(1);
- }
-
- /* XXX referrals? */
- if (krb5_is_referral_realm(krb5_princ_realm(kpropd_context,
- iprop_svc_principal))) {
- krb5_data *r = krb5_princ_realm(kpropd_context,
- iprop_svc_principal);
- assert(def_realm != NULL);
- r->length = strlen(def_realm);
- r->data = strdup(def_realm);
- if (r->data == NULL) {
- com_err(progname, retval,
- _("while determining local service principal name"));
- exit(1);
- }
- /* XXX Memory leak: Old r->data value. */
- }
- if ((retval = krb5_unparse_name(kpropd_context, iprop_svc_principal,
- &iprop_svc_princstr))) {
- com_err(progname, retval,
- _("while canonicalizing principal name"));
- krb5_free_principal(kpropd_context, iprop_svc_principal);
- exit(1);
- }
- krb5_free_principal(kpropd_context, iprop_svc_principal);
+ kadm5_ret_t retval;
+ krb5_ccache cc;
+ krb5_principal iprop_svc_principal;
+ void *server_handle = NULL;
+ char *iprop_svc_princstr = NULL;
+ char *master_svc_princstr = NULL;
+ unsigned int pollin, backoff_time;
+ int backoff_cnt = 0;
+ int reinit_cnt = 0;
+ int ret;
+ int frdone = 0;
+
+ kdb_incr_result_t *incr_ret;
+ static kdb_last_t mylast;
+
+ kdb_fullresync_result_t *full_ret;
+
+ kadm5_iprop_handle_t handle;
+ kdb_hlog_t *ulog;
+
+ if (!debug)
+ daemon(0, 0);
+
+ ulog = log_ctx->ulog;
+
+ pollin = params.iprop_poll_time;
+ if (pollin < 10)
+ pollin = 10;
+
+ /*
+ * Grab the realm info and check if iprop is enabled.
+ */
+ if (def_realm == NULL) {
+ retval = krb5_get_default_realm(kpropd_context, &def_realm);
+ if (retval) {
+ com_err(progname, retval,
+ _("Unable to get default realm"));
+ exit(1);
+ }
+ }
+
+ params.mask |= KADM5_CONFIG_REALM;
+ params.realm = def_realm;
+
+ if (master_svc_princstr == NULL) {
+ if ((retval = kadm5_get_kiprop_host_srv_name(kpropd_context,
+ def_realm,
+ &master_svc_princstr))) {
+ com_err(progname, retval,
+ _("%s: unable to get kiprop host based "
+ "service name for realm %s\n"),
+ progname, def_realm);
+ exit(1);
+ }
+ }
+
+ /*
+ * Set cc to the default credentials cache
+ */
+ if ((retval = krb5_cc_default(kpropd_context, &cc))) {
+ com_err(progname, retval,
+ _("while opening default "
+ "credentials cache"));
+ exit(1);
+ }
+
+ retval = krb5_sname_to_principal(kpropd_context, NULL, KIPROP_SVC_NAME,
+ KRB5_NT_SRV_HST, &iprop_svc_principal);
+ if (retval) {
+ com_err(progname, retval,
+ _("while trying to construct host service principal"));
+ exit(1);
+ }
+
+ /* XXX referrals? */
+ if (krb5_is_referral_realm(krb5_princ_realm(kpropd_context,
+ iprop_svc_principal))) {
+ krb5_data *r = krb5_princ_realm(kpropd_context,
+ iprop_svc_principal);
+ assert(def_realm != NULL);
+ r->length = strlen(def_realm);
+ r->data = strdup(def_realm);
+ if (r->data == NULL) {
+ com_err(progname, retval,
+ _("while determining local service principal name"));
+ exit(1);
+ }
+ /* XXX Memory leak: Old r->data value. */
+ }
+ if ((retval = krb5_unparse_name(kpropd_context, iprop_svc_principal,
+ &iprop_svc_princstr))) {
+ com_err(progname, retval,
+ _("while canonicalizing principal name"));
+ krb5_free_principal(kpropd_context, iprop_svc_principal);
+ exit(1);
+ }
+ krb5_free_principal(kpropd_context, iprop_svc_principal);
reinit:
- /*
- * Authentication, initialize rpcsec_gss handle etc.
- */
- retval = kadm5_init_with_skey(kpropd_context, iprop_svc_princstr,
- srvtab,
- master_svc_princstr,
- ¶ms,
- KADM5_STRUCT_VERSION,
- KADM5_API_VERSION_3,
- db_args,
- &server_handle);
-
- if (retval) {
- if (retval == KADM5_RPC_ERROR) {
- reinit_cnt++;
- if (server_handle)
- kadm5_destroy((void *) server_handle);
- server_handle = (void *)NULL;
- handle = (kadm5_iprop_handle_t)NULL;
-
- com_err(progname, retval, _(
- "while attempting to connect"
- " to master KDC ... retrying"));
- backoff_time = backoff_from_master(&reinit_cnt);
- (void) sleep(backoff_time);
- goto reinit;
- } else {
- if (retval == KADM5_BAD_CLIENT_PARAMS ||
- retval == KADM5_BAD_SERVER_PARAMS) {
- com_err(progname, retval,
- _("while initializing %s interface"),
- progname);
-
- usage();
- }
- reinit_cnt++;
- com_err(progname, retval,
- _("while initializing %s interface, retrying"),
- progname);
- backoff_time = backoff_from_master(&reinit_cnt);
- sleep(backoff_time);
- goto reinit;
+ /*
+ * Authentication, initialize rpcsec_gss handle etc.
+ */
+ retval = kadm5_init_with_skey(kpropd_context, iprop_svc_princstr,
+ srvtab,
+ master_svc_princstr,
+ ¶ms,
+ KADM5_STRUCT_VERSION,
+ KADM5_API_VERSION_3,
+ db_args,
+ &server_handle);
+
+ if (retval) {
+ if (retval == KADM5_RPC_ERROR) {
+ reinit_cnt++;
+ if (server_handle)
+ kadm5_destroy((void *) server_handle);
+ server_handle = (void *)NULL;
+ handle = (kadm5_iprop_handle_t)NULL;
+
+ com_err(progname, retval, _(
+ "while attempting to connect"
+ " to master KDC ... retrying"));
+ backoff_time = backoff_from_master(&reinit_cnt);
+ (void) sleep(backoff_time);
+ goto reinit;
+ } else {
+ if (retval == KADM5_BAD_CLIENT_PARAMS ||
+ retval == KADM5_BAD_SERVER_PARAMS) {
+ com_err(progname, retval,
+ _("while initializing %s interface"),
+ progname);
+
+ usage();
+ }
+ reinit_cnt++;
+ com_err(progname, retval,
+ _("while initializing %s interface, retrying"),
+ progname);
+ backoff_time = backoff_from_master(&reinit_cnt);
+ sleep(backoff_time);
+ goto reinit;
+ }
+ }
+
+ /*
+ * Reset re-initialization count to zero now.
+ */
+ reinit_cnt = backoff_time = 0;
+
+ /*
+ * Reset the handle to the correct type for the RPC call
+ */
+ handle = server_handle;
+
+ for (;;) {
+ incr_ret = NULL;
+ full_ret = NULL;
+
+ /*
+ * Get the most recent ulog entry sno + ts, which
+ * we package in the request to the master KDC
+ */
+ mylast.last_sno = ulog->kdb_last_sno;
+ mylast.last_time = ulog->kdb_last_time;
+
+ /*
+ * Loop continuously on an iprop_get_updates_1(),
+ * so that we can keep probing the master for updates
+ * or (if needed) do a full resync of the krb5 db.
+ */
+
+ incr_ret = iprop_get_updates_1(&mylast, handle->clnt);
+ if (incr_ret == (kdb_incr_result_t *)NULL) {
+ clnt_perror(handle->clnt,
+ "iprop_get_updates call failed");
+ if (server_handle)
+ kadm5_destroy((void *)server_handle);
+ server_handle = (void *)NULL;
+ handle = (kadm5_iprop_handle_t)NULL;
+ goto reinit;
+ }
+
+ switch (incr_ret->ret) {
+
+ case UPDATE_FULL_RESYNC_NEEDED:
+ /*
+ * We dont do a full resync again, if the last
+ * X'fer was a resync and if the master sno is
+ * still "0", i.e. no updates so far.
+ */
+ if ((frdone == 1) && (incr_ret->lastentry.last_sno
+ == 0)) {
+ break;
+ } else {
+ full_ret = full_resync(handle->clnt);
+ if (full_ret == (kdb_fullresync_result_t *)
+ NULL) {
+ clnt_perror(handle->clnt,
+ "iprop_full_resync call failed");
+ if (server_handle)
+ kadm5_destroy((void *)
+ server_handle);
+ server_handle = (void *)NULL;
+ handle = (kadm5_iprop_handle_t)NULL;
+ goto reinit;
}
- }
-
- /*
- * Reset re-initialization count to zero now.
- */
- reinit_cnt = backoff_time = 0;
-
- /*
- * Reset the handle to the correct type for the RPC call
- */
- handle = server_handle;
-
- for (;;) {
- incr_ret = NULL;
- full_ret = NULL;
-
- /*
- * Get the most recent ulog entry sno + ts, which
- * we package in the request to the master KDC
- */
- mylast.last_sno = ulog->kdb_last_sno;
- mylast.last_time = ulog->kdb_last_time;
-
- /*
- * Loop continuously on an iprop_get_updates_1(),
- * so that we can keep probing the master for updates
- * or (if needed) do a full resync of the krb5 db.
- */
-
- incr_ret = iprop_get_updates_1(&mylast, handle->clnt);
- if (incr_ret == (kdb_incr_result_t *)NULL) {
- clnt_perror(handle->clnt,
- "iprop_get_updates call failed");
- if (server_handle)
- kadm5_destroy((void *)server_handle);
- server_handle = (void *)NULL;
- handle = (kadm5_iprop_handle_t)NULL;
- goto reinit;
- }
-
- switch (incr_ret->ret) {
-
- case UPDATE_FULL_RESYNC_NEEDED:
- /*
- * We dont do a full resync again, if the last
- * X'fer was a resync and if the master sno is
- * still "0", i.e. no updates so far.
- */
- if ((frdone == 1) && (incr_ret->lastentry.last_sno
- == 0)) {
- break;
- } else {
- full_ret = full_resync(handle->clnt);
- if (full_ret == (kdb_fullresync_result_t *)
- NULL) {
- clnt_perror(handle->clnt,
- "iprop_full_resync call failed");
- if (server_handle)
- kadm5_destroy((void *)
- server_handle);
- server_handle = (void *)NULL;
- handle = (kadm5_iprop_handle_t)NULL;
- goto reinit;
- }
- }
-
- switch (full_ret->ret) {
- case UPDATE_OK:
- backoff_cnt = 0;
- /*
- * We now listen on the kprop port for
- * the full dump
- */
- ret = do_standalone(log_ctx->iproprole);
- if (debug) {
- if (ret)
- fprintf(stderr,
- _("Full resync "
- "was unsuccessful\n"));
- else
- fprintf(stderr,
- _("Full resync "
- "was successful\n"));
- }
- if (ret) {
- syslog(LOG_WARNING,
- _("kpropd: Full resync, invalid return."));
- frdone = 0;
- backoff_cnt++;
- } else
- frdone = 1;
- break;
-
- case UPDATE_BUSY:
- /*
- * Exponential backoff
- */
- backoff_cnt++;
- break;
-
- case UPDATE_FULL_RESYNC_NEEDED:
- case UPDATE_NIL:
- default:
- backoff_cnt = 0;
- frdone = 0;
- syslog(LOG_ERR, _("kpropd: Full resync,"
- " invalid return from master KDC."));
- break;
-
- case UPDATE_PERM_DENIED:
- syslog(LOG_ERR, _("kpropd: Full resync,"
- " permission denied."));
- goto error;
-
- case UPDATE_ERROR:
- syslog(LOG_ERR, _("kpropd: Full resync,"
- " error returned from master KDC."));
- goto error;
- }
- break;
-
- case UPDATE_OK:
- backoff_cnt = 0;
- frdone = 0;
-
- /*
- * ulog_replay() will convert the ulog updates to db
- * entries using the kdb conv api and will commit
- * the entries to the slave kdc database
- */
- retval = ulog_replay(kpropd_context, incr_ret,
- db_args);
-
- if (retval) {
- const char *msg =
- krb5_get_error_message(kpropd_context, retval);
- syslog(LOG_ERR,
- _("kpropd: ulog_replay failed (%s), updates not registered."), msg);
- krb5_free_error_message(kpropd_context, msg);
- break;
- }
-
- if (debug)
- fprintf(stderr, _("Update transfer "
- "from master was OK\n"));
- break;
-
- case UPDATE_PERM_DENIED:
- syslog(LOG_ERR, _("kpropd: get_updates,"
- " permission denied."));
- goto error;
-
- case UPDATE_ERROR:
- syslog(LOG_ERR, _("kpropd: get_updates, error "
- "returned from master KDC."));
- goto error;
-
- case UPDATE_BUSY:
- /*
- * Exponential backoff
- */
- backoff_cnt++;
- break;
-
- case UPDATE_NIL:
- /*
- * Master-slave are in sync
- */
- if (debug)
- fprintf(stderr, _("Master, slave KDC's "
- "are in-sync, no updates\n"));
- backoff_cnt = 0;
- frdone = 0;
- break;
-
- default:
- backoff_cnt = 0;
- syslog(LOG_ERR, _("kpropd: get_updates,"
- " invalid return from master KDC."));
- break;
- }
-
- if (runonce == 1)
- goto done;
-
- /*
- * Sleep for the specified poll interval (Default is 2 mts),
- * or do a binary exponential backoff if we get an
- * UPDATE_BUSY signal
- */
- if (backoff_cnt > 0) {
- backoff_time = backoff_from_master(&backoff_cnt);
- if (debug)
- fprintf(stderr, _("Busy signal received "
- "from master, backoff for %d secs\n"),
- backoff_time);
- (void) sleep(backoff_time);
- }
- else
- (void) sleep(pollin);
-
- }
+ }
+
+ switch (full_ret->ret) {
+ case UPDATE_OK:
+ backoff_cnt = 0;
+ /*
+ * We now listen on the kprop port for
+ * the full dump
+ */
+ ret = do_standalone(log_ctx->iproprole);
+ if (debug) {
+ if (ret)
+ fprintf(stderr,
+ _("Full resync "
+ "was unsuccessful\n"));
+ else
+ fprintf(stderr,
+ _("Full resync "
+ "was successful\n"));
+ }
+ if (ret) {
+ syslog(LOG_WARNING,
+ _("kpropd: Full resync, invalid return."));
+ frdone = 0;
+ backoff_cnt++;
+ } else
+ frdone = 1;
+ break;
+
+ case UPDATE_BUSY:
+ /*
+ * Exponential backoff
+ */
+ backoff_cnt++;
+ break;
+
+ case UPDATE_FULL_RESYNC_NEEDED:
+ case UPDATE_NIL:
+ default:
+ backoff_cnt = 0;
+ frdone = 0;
+ syslog(LOG_ERR, _("kpropd: Full resync,"
+ " invalid return from master KDC."));
+ break;
+
+ case UPDATE_PERM_DENIED:
+ syslog(LOG_ERR, _("kpropd: Full resync,"
+ " permission denied."));
+ goto error;
+
+ case UPDATE_ERROR:
+ syslog(LOG_ERR, _("kpropd: Full resync,"
+ " error returned from master KDC."));
+ goto error;
+ }
+ break;
+
+ case UPDATE_OK:
+ backoff_cnt = 0;
+ frdone = 0;
+
+ /*
+ * ulog_replay() will convert the ulog updates to db
+ * entries using the kdb conv api and will commit
+ * the entries to the slave kdc database
+ */
+ retval = ulog_replay(kpropd_context, incr_ret,
+ db_args);
+
+ if (retval) {
+ const char *msg =
+ krb5_get_error_message(kpropd_context, retval);
+ syslog(LOG_ERR,
+ _("kpropd: ulog_replay failed (%s), updates not registered."), msg);
+ krb5_free_error_message(kpropd_context, msg);
+ break;
+ }
+
+ if (debug)
+ fprintf(stderr, _("Update transfer "
+ "from master was OK\n"));
+ break;
+
+ case UPDATE_PERM_DENIED:
+ syslog(LOG_ERR, _("kpropd: get_updates,"
+ " permission denied."));
+ goto error;
+
+ case UPDATE_ERROR:
+ syslog(LOG_ERR, _("kpropd: get_updates, error "
+ "returned from master KDC."));
+ goto error;
+
+ case UPDATE_BUSY:
+ /*
+ * Exponential backoff
+ */
+ backoff_cnt++;
+ break;
+
+ case UPDATE_NIL:
+ /*
+ * Master-slave are in sync
+ */
+ if (debug)
+ fprintf(stderr, _("Master, slave KDC's "
+ "are in-sync, no updates\n"));
+ backoff_cnt = 0;
+ frdone = 0;
+ break;
+
+ default:
+ backoff_cnt = 0;
+ syslog(LOG_ERR, _("kpropd: get_updates,"
+ " invalid return from master KDC."));
+ break;
+ }
+
+ if (runonce == 1)
+ goto done;
+
+ /*
+ * Sleep for the specified poll interval (Default is 2 mts),
+ * or do a binary exponential backoff if we get an
+ * UPDATE_BUSY signal
+ */
+ if (backoff_cnt > 0) {
+ backoff_time = backoff_from_master(&backoff_cnt);
+ if (debug)
+ fprintf(stderr, _("Busy signal received "
+ "from master, backoff for %d secs\n"),
+ backoff_time);
+ (void) sleep(backoff_time);
+ }
+ else
+ (void) sleep(pollin);
+
+ }
error:
- if (debug)
- fprintf(stderr, _("ERROR returned by master, bailing\n"));
- syslog(LOG_ERR, _("kpropd: ERROR returned by master KDC,"
- " bailing.\n"));
+ if (debug)
+ fprintf(stderr, _("ERROR returned by master, bailing\n"));
+ syslog(LOG_ERR, _("kpropd: ERROR returned by master KDC,"
+ " bailing.\n"));
done:
- if(iprop_svc_princstr)
- free(iprop_svc_princstr);
- if (master_svc_princstr)
- free(master_svc_princstr);
- if ((retval = krb5_cc_close(kpropd_context, cc))) {
- com_err(progname, retval,
- _("while closing default ccache"));
- exit(1);
- }
- if (def_realm)
- free(def_realm);
- if (server_handle)
- kadm5_destroy((void *)server_handle);
- if (kpropd_context)
- krb5_free_context(kpropd_context);
-
- if (runonce == 1)
- return (0);
- else
- exit(1);
+ if(iprop_svc_princstr)
+ free(iprop_svc_princstr);
+ if (master_svc_princstr)
+ free(master_svc_princstr);
+ if ((retval = krb5_cc_close(kpropd_context, cc))) {
+ com_err(progname, retval,
+ _("while closing default ccache"));
+ exit(1);
+ }
+ if (def_realm)
+ free(def_realm);
+ if (server_handle)
+ kadm5_destroy((void *)server_handle);
+ if (kpropd_context)
+ krb5_free_context(kpropd_context);
+
+ if (runonce == 1)
+ return (0);
+ else
+ exit(1);
}
* Do exponential backoff, since master KDC is BUSY or down
*/
unsigned int backoff_from_master(int *cnt) {
- unsigned int btime;
+ unsigned int btime;
- btime = (unsigned int)(2<<(*cnt));
- if (btime > MAX_BACKOFF) {
- btime = MAX_BACKOFF;
- *cnt--;
- }
+ btime = (unsigned int)(2<<(*cnt));
+ if (btime > MAX_BACKOFF) {
+ btime = MAX_BACKOFF;
+ *cnt--;
+ }
- return (btime);
+ return (btime);
}
static void
kpropd_com_err_proc(const char *whoami,
- long code,
- const char *fmt,
- va_list args)
+ long code,
+ const char *fmt,
+ va_list args)
#if !defined(__cplusplus) && (__GNUC__ > 2)
__attribute__((__format__(__printf__, 3, 0)))
#endif
static void
kpropd_com_err_proc(const char *whoami,
- long code,
- const char *fmt,
- va_list args)
+ long code,
+ const char *fmt,
+ va_list args)
{
- char error_buf[8096];
+ char error_buf[8096];
- error_buf[0] = '\0';
- if (fmt)
- vsnprintf(error_buf, sizeof(error_buf), fmt, args);
- syslog(LOG_ERR, "%s%s%s%s%s", whoami ? whoami : "", whoami ? ": " : "",
- code ? error_message(code) : "", code ? " " : "", error_buf);
+ error_buf[0] = '\0';
+ if (fmt)
+ vsnprintf(error_buf, sizeof(error_buf), fmt, args);
+ syslog(LOG_ERR, "%s%s%s%s%s", whoami ? whoami : "", whoami ? ": " : "",
+ code ? error_message(code) : "", code ? " " : "", error_buf);
}
void PRS(argv)
- char **argv;
+ char **argv;
{
- register char *word, ch;
- krb5_error_code retval;
- static const char tmp[] = ".temp";
- kdb_log_context *log_ctx;
-
- (void) memset(¶ms, 0, sizeof (params));
-
- retval = kadm5_init_krb5_context(&kpropd_context);
- if (retval) {
- com_err(argv[0], retval, "while initializing krb5");
- exit(1);
- }
-
- progname = *argv++;
- while ((word = *argv++)) {
- if (*word == '-') {
- word++;
- while (word && (ch = *word++)) {
- switch(ch){
- case 'f':
- if (*word)
- file = word;
- else
- file = *argv++;
- if (!file)
- usage();
- word = 0;
- break;
- case 'F':
- if (*word)
- kerb_database = word;
- else
- kerb_database = *argv++;
- if (!kerb_database)
- usage();
- word = 0;
- break;
- case 'p':
- if (*word)
- kdb5_util = word;
- else
- kdb5_util = *argv++;
- if (!kdb5_util)
- usage();
- word = 0;
- break;
- case 'P':
- if (*word)
- port = htons(atoi(word));
- else
- port = htons(atoi(*argv++));
- if (!port)
- usage();
- word = 0;
- break;
- case 'r':
- if (*word)
- realm = word;
- else
- realm = *argv++;
- if (!realm)
- usage();
- word = 0;
- break;
- case 's':
- if (*word)
- srvtab = word;
- else
- srvtab = *argv++;
- if (!srvtab)
- usage();
- word = 0;
- break;
- case 'd':
- debug++;
- break;
- case 'S':
- standalone++;
- break;
- case 'a':
- if (*word)
- acl_file_name = word;
- else
- acl_file_name = *argv++;
- if (!acl_file_name)
- usage();
- word = 0;
- break;
-
- case 't':
- /*
- * Undocumented option - for testing only.
- *
- * Option to run the kpropd server exactly
- * once (this is true only if iprop is enabled).
- */
- runonce = 1;
- break;
-
- case 'x':
- {
- char **new_db_args;
- new_db_args = realloc(db_args,
- (db_args_size+2)*sizeof(*db_args));
- if (new_db_args == NULL) {
- com_err(argv[0], errno, "copying db args");
- exit(1);
- }
- db_args = new_db_args;
- if (*word)
- db_args[db_args_size] = word;
- else
- db_args[db_args_size] = *argv++;
- word = 0;
- if (db_args[db_args_size] == NULL)
- usage();
- db_args[db_args_size+1] = NULL;
- db_args_size++;
- }
-
- default:
- usage();
- }
-
- }
- } else
- /* We don't take any arguments, only options */
- usage();
- }
- /*
- * If not in debug mode, switch com_err reporting to syslog
- */
- if (! debug) {
- openlog("kpropd", LOG_PID | LOG_ODELAY, SYSLOG_CLASS);
- set_com_err_hook(kpropd_com_err_proc);
- }
- /*
- * Get my hostname, so we can construct my service name
- */
- retval = krb5_sname_to_principal(kpropd_context,
- NULL, KPROP_SERVICE_NAME,
- KRB5_NT_SRV_HST, &server);
- if (retval) {
- com_err(progname, retval,
- "While trying to construct my service name");
- exit(1);
- }
- if (realm) {
- retval = krb5_set_principal_realm(kpropd_context, server, realm);
- if (retval) {
- com_err(progname, errno,
- "while constructing my service realm");
- exit(1);
- }
- }
- /*
- * Construct the name of the temporary file.
- */
- if (asprintf(&temp_file_name, "%s%s", file, tmp) < 0) {
- com_err(progname, ENOMEM,
- "while allocating filename for temp file");
- exit(1);
- }
-
- retval = kadm5_get_config_params(kpropd_context, 1, ¶ms, ¶ms);
- if (retval) {
- com_err(progname, retval, _("while initializing"));
- exit(1);
- }
- if (params.iprop_enabled == TRUE) {
- ulog_set_role(kpropd_context, IPROP_SLAVE);
-
- if (ulog_map(kpropd_context, params.iprop_logfile,
- params.iprop_ulogsize, FKPROPD, db_args)) {
- com_err(progname, errno,
- _("Unable to map log!\n"));
- exit(1);
- }
- }
- log_ctx = kpropd_context->kdblog_context;
- if (log_ctx && (log_ctx->iproprole == IPROP_SLAVE))
- ulog_set_role(kpropd_context, IPROP_SLAVE);
+ register char *word, ch;
+ krb5_error_code retval;
+ static const char tmp[] = ".temp";
+ kdb_log_context *log_ctx;
+
+ (void) memset(¶ms, 0, sizeof (params));
+
+ retval = kadm5_init_krb5_context(&kpropd_context);
+ if (retval) {
+ com_err(argv[0], retval, "while initializing krb5");
+ exit(1);
+ }
+
+ progname = *argv++;
+ while ((word = *argv++)) {
+ if (*word == '-') {
+ word++;
+ while (word && (ch = *word++)) {
+ switch(ch){
+ case 'f':
+ if (*word)
+ file = word;
+ else
+ file = *argv++;
+ if (!file)
+ usage();
+ word = 0;
+ break;
+ case 'F':
+ if (*word)
+ kerb_database = word;
+ else
+ kerb_database = *argv++;
+ if (!kerb_database)
+ usage();
+ word = 0;
+ break;
+ case 'p':
+ if (*word)
+ kdb5_util = word;
+ else
+ kdb5_util = *argv++;
+ if (!kdb5_util)
+ usage();
+ word = 0;
+ break;
+ case 'P':
+ if (*word)
+ port = htons(atoi(word));
+ else
+ port = htons(atoi(*argv++));
+ if (!port)
+ usage();
+ word = 0;
+ break;
+ case 'r':
+ if (*word)
+ realm = word;
+ else
+ realm = *argv++;
+ if (!realm)
+ usage();
+ word = 0;
+ break;
+ case 's':
+ if (*word)
+ srvtab = word;
+ else
+ srvtab = *argv++;
+ if (!srvtab)
+ usage();
+ word = 0;
+ break;
+ case 'd':
+ debug++;
+ break;
+ case 'S':
+ standalone++;
+ break;
+ case 'a':
+ if (*word)
+ acl_file_name = word;
+ else
+ acl_file_name = *argv++;
+ if (!acl_file_name)
+ usage();
+ word = 0;
+ break;
+
+ case 't':
+ /*
+ * Undocumented option - for testing only.
+ *
+ * Option to run the kpropd server exactly
+ * once (this is true only if iprop is enabled).
+ */
+ runonce = 1;
+ break;
+
+ case 'x':
+ {
+ char **new_db_args;
+ new_db_args = realloc(db_args,
+ (db_args_size+2)*sizeof(*db_args));
+ if (new_db_args == NULL) {
+ com_err(argv[0], errno, "copying db args");
+ exit(1);
+ }
+ db_args = new_db_args;
+ if (*word)
+ db_args[db_args_size] = word;
+ else
+ db_args[db_args_size] = *argv++;
+ word = 0;
+ if (db_args[db_args_size] == NULL)
+ usage();
+ db_args[db_args_size+1] = NULL;
+ db_args_size++;
+ }
+
+ default:
+ usage();
+ }
+
+ }
+ } else
+ /* We don't take any arguments, only options */
+ usage();
+ }
+ /*
+ * If not in debug mode, switch com_err reporting to syslog
+ */
+ if (! debug) {
+ openlog("kpropd", LOG_PID | LOG_ODELAY, SYSLOG_CLASS);
+ set_com_err_hook(kpropd_com_err_proc);
+ }
+ /*
+ * Get my hostname, so we can construct my service name
+ */
+ retval = krb5_sname_to_principal(kpropd_context,
+ NULL, KPROP_SERVICE_NAME,
+ KRB5_NT_SRV_HST, &server);
+ if (retval) {
+ com_err(progname, retval,
+ "While trying to construct my service name");
+ exit(1);
+ }
+ if (realm) {
+ retval = krb5_set_principal_realm(kpropd_context, server, realm);
+ if (retval) {
+ com_err(progname, errno,
+ "while constructing my service realm");
+ exit(1);
+ }
+ }
+ /*
+ * Construct the name of the temporary file.
+ */
+ if (asprintf(&temp_file_name, "%s%s", file, tmp) < 0) {
+ com_err(progname, ENOMEM,
+ "while allocating filename for temp file");
+ exit(1);
+ }
+
+ retval = kadm5_get_config_params(kpropd_context, 1, ¶ms, ¶ms);
+ if (retval) {
+ com_err(progname, retval, _("while initializing"));
+ exit(1);
+ }
+ if (params.iprop_enabled == TRUE) {
+ ulog_set_role(kpropd_context, IPROP_SLAVE);
+
+ if (ulog_map(kpropd_context, params.iprop_logfile,
+ params.iprop_ulogsize, FKPROPD, db_args)) {
+ com_err(progname, errno,
+ _("Unable to map log!\n"));
+ exit(1);
+ }
+ }
+ log_ctx = kpropd_context->kdblog_context;
+ if (log_ctx && (log_ctx->iproprole == IPROP_SLAVE))
+ ulog_set_role(kpropd_context, IPROP_SLAVE);
}
/*
*/
void
kerberos_authenticate(context, fd, clientp, etype, my_sin)
- krb5_context context;
- int fd;
- krb5_principal * clientp;
- krb5_enctype * etype;
- struct sockaddr_in my_sin;
+ krb5_context context;
+ int fd;
+ krb5_principal * clientp;
+ krb5_enctype * etype;
+ struct sockaddr_in my_sin;
{
- krb5_error_code retval;
- krb5_ticket * ticket;
- struct sockaddr_in r_sin;
+ krb5_error_code retval;
+ krb5_ticket * ticket;
+ struct sockaddr_in r_sin;
GETSOCKNAME_ARG3_TYPE sin_length;
- krb5_keytab keytab = NULL;
+ krb5_keytab keytab = NULL;
/*
* Set recv_addr and send_addr
sin_length = sizeof(r_sin);
if (getsockname(fd, (struct sockaddr *) &r_sin, &sin_length)) {
- com_err(progname, errno, "while getting local socket address");
- exit(1);
+ com_err(progname, errno, "while getting local socket address");
+ exit(1);
}
receiver_addr.addrtype = ADDRTYPE_INET;
sizeof(r_sin.sin_addr));
if (debug) {
- char *name;
-
- retval = krb5_unparse_name(context, server, &name);
- if (retval) {
- com_err(progname, retval, "While unparsing client name");
- exit(1);
- }
- printf("krb5_recvauth(%d, %s, %s, ...)\n", fd, kprop_version, name);
- free(name);
+ char *name;
+
+ retval = krb5_unparse_name(context, server, &name);
+ if (retval) {
+ com_err(progname, retval, "While unparsing client name");
+ exit(1);
+ }
+ printf("krb5_recvauth(%d, %s, %s, ...)\n", fd, kprop_version, name);
+ free(name);
}
retval = krb5_auth_con_init(context, &auth_context);
if (retval) {
- syslog(LOG_ERR, "Error in krb5_auth_con_ini: %s",
- error_message(retval));
- exit(1);
+ syslog(LOG_ERR, "Error in krb5_auth_con_ini: %s",
+ error_message(retval));
+ exit(1);
}
retval = krb5_auth_con_setflags(context, auth_context,
- KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
if (retval) {
- syslog(LOG_ERR, "Error in krb5_auth_con_setflags: %s",
- error_message(retval));
- exit(1);
+ syslog(LOG_ERR, "Error in krb5_auth_con_setflags: %s",
+ error_message(retval));
+ exit(1);
}
retval = krb5_auth_con_setaddrs(context, auth_context, &receiver_addr,
- &sender_addr);
+ &sender_addr);
if (retval) {
- syslog(LOG_ERR, "Error in krb5_auth_con_setaddrs: %s",
- error_message(retval));
- exit(1);
+ syslog(LOG_ERR, "Error in krb5_auth_con_setaddrs: %s",
+ error_message(retval));
+ exit(1);
}
if (srvtab) {
retval = krb5_kt_resolve(context, srvtab, &keytab);
- if (retval) {
- syslog(LOG_ERR, "Error in krb5_kt_resolve: %s", error_message(retval));
- exit(1);
- }
+ if (retval) {
+ syslog(LOG_ERR, "Error in krb5_kt_resolve: %s", error_message(retval));
+ exit(1);
+ }
}
retval = krb5_recvauth(context, &auth_context, (void *) &fd,
- kprop_version, server, 0, keytab, &ticket);
+ kprop_version, server, 0, keytab, &ticket);
if (retval) {
- syslog(LOG_ERR, "Error in krb5_recvauth: %s", error_message(retval));
- exit(1);
+ syslog(LOG_ERR, "Error in krb5_recvauth: %s", error_message(retval));
+ exit(1);
}
retval = krb5_copy_principal(context, ticket->enc_part2->client, clientp);
if (retval) {
- syslog(LOG_ERR, "Error in krb5_copy_prinicpal: %s",
- error_message(retval));
- exit(1);
+ syslog(LOG_ERR, "Error in krb5_copy_prinicpal: %s",
+ error_message(retval));
+ exit(1);
}
*etype = ticket->enc_part.enctype;
if (debug) {
- char * name;
- char etypebuf[100];
-
- retval = krb5_unparse_name(context, *clientp, &name);
- if (retval) {
- com_err(progname, retval, "While unparsing client name");
- exit(1);
- }
-
- retval = krb5_enctype_to_string(*etype, etypebuf, sizeof(etypebuf));
- if (retval) {
- com_err(progname, retval, "While unparsing ticket etype");
- exit(1);
- }
-
- printf("authenticated client: %s (etype == %s)\n", name, etypebuf);
- free(name);
+ char * name;
+ char etypebuf[100];
+
+ retval = krb5_unparse_name(context, *clientp, &name);
+ if (retval) {
+ com_err(progname, retval, "While unparsing client name");
+ exit(1);
+ }
+
+ retval = krb5_enctype_to_string(*etype, etypebuf, sizeof(etypebuf));
+ if (retval) {
+ com_err(progname, retval, "While unparsing ticket etype");
+ exit(1);
+ }
+
+ printf("authenticated client: %s (etype == %s)\n", name, etypebuf);
+ free(name);
}
krb5_free_ticket(context, ticket);
krb5_principal p;
krb5_enctype auth_etype;
{
- char *name, *ptr;
- char buf[1024];
- krb5_error_code retval;
- FILE *acl_file;
- int end;
- krb5_enctype acl_etype;
+ char *name, *ptr;
+ char buf[1024];
+ krb5_error_code retval;
+ FILE *acl_file;
+ int end;
+ krb5_enctype acl_etype;
retval = krb5_unparse_name(context, p, &name);
if (retval)
- return FALSE;
+ return FALSE;
acl_file = fopen(acl_file_name, "r");
if (!acl_file)
- return FALSE;
+ return FALSE;
while (!feof(acl_file)) {
- if (!fgets(buf, sizeof(buf), acl_file))
- break;
- end = strlen(buf) - 1;
- if (buf[end] == '\n')
- buf[end] = '\0';
- if (!strncmp(name, buf, strlen(name))) {
- ptr = buf+strlen(name);
-
- /* if the next character is not whitespace or nul, then
- the match is only partial. continue on to new lines. */
- if (*ptr && !isspace((int) *ptr))
- continue;
-
- /* otherwise, skip trailing whitespace */
- for (; *ptr && isspace((int) *ptr); ptr++) ;
-
- /* now, look for an etype string. if there isn't one,
- return true. if there is an invalid string, continue.
- If there is a valid string, return true only if it
- matches the etype passed in, otherwise continue */
-
- if ((*ptr) &&
- ((retval = krb5_string_to_enctype(ptr, &acl_etype)) ||
- (acl_etype != auth_etype)))
- continue;
-
- free(name);
- fclose(acl_file);
- return TRUE;
- }
+ if (!fgets(buf, sizeof(buf), acl_file))
+ break;
+ end = strlen(buf) - 1;
+ if (buf[end] == '\n')
+ buf[end] = '\0';
+ if (!strncmp(name, buf, strlen(name))) {
+ ptr = buf+strlen(name);
+
+ /* if the next character is not whitespace or nul, then
+ the match is only partial. continue on to new lines. */
+ if (*ptr && !isspace((int) *ptr))
+ continue;
+
+ /* otherwise, skip trailing whitespace */
+ for (; *ptr && isspace((int) *ptr); ptr++) ;
+
+ /* now, look for an etype string. if there isn't one,
+ return true. if there is an invalid string, continue.
+ If there is a valid string, return true only if it
+ matches the etype passed in, otherwise continue */
+
+ if ((*ptr) &&
+ ((retval = krb5_string_to_enctype(ptr, &acl_etype)) ||
+ (acl_etype != auth_etype)))
+ continue;
+
+ free(name);
+ fclose(acl_file);
+ return TRUE;
+ }
}
free(name);
fclose(acl_file);
void
recv_database(context, fd, database_fd, confmsg)
krb5_context context;
- int fd;
- int database_fd;
+ int fd;
+ int database_fd;
krb5_data *confmsg;
{
- krb5_ui_4 database_size; /* This must be 4 bytes */
- int received_size, n;
- char buf[1024];
- krb5_data inbuf, outbuf;
- krb5_error_code retval;
-
- /*
- * Receive and decode size from client
- */
- retval = krb5_read_message(context, (void *) &fd, &inbuf);
- if (retval) {
- send_error(context, fd, retval, "while reading database size");
- com_err(progname, retval,
- "while reading size of database from client");
- exit(1);
- }
- if (krb5_is_krb_error(&inbuf))
- recv_error(context, &inbuf);
- retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL);
- if (retval) {
- send_error(context, fd, retval,
- "while decoding database size");
- krb5_free_data_contents(context, &inbuf);
- com_err(progname, retval,
- "while decoding database size from client");
- exit(1);
- }
- memcpy(&database_size, outbuf.data, sizeof(database_size));
- krb5_free_data_contents(context, &inbuf);
- krb5_free_data_contents(context, &outbuf);
- database_size = ntohl(database_size);
-
- /*
- * Initialize the initial vector.
- */
- retval = krb5_auth_con_initivector(context, auth_context);
- if (retval) {
- send_error(context, fd, retval,
- "failed while initializing i_vector");
- com_err(progname, retval, "while initializing i_vector");
- exit(1);
- }
-
- /*
- * Now start receiving the database from the net
- */
- received_size = 0;
- while (received_size < database_size) {
- retval = krb5_read_message(context, (void *) &fd, &inbuf);
- if (retval) {
- snprintf(buf, sizeof(buf),
- "while reading database block starting at offset %d",
- received_size);
- com_err(progname, retval, buf);
- send_error(context, fd, retval, buf);
- exit(1);
- }
- if (krb5_is_krb_error(&inbuf))
- recv_error(context, &inbuf);
- retval = krb5_rd_priv(context, auth_context, &inbuf,
- &outbuf, NULL);
- if (retval) {
- snprintf(buf, sizeof(buf),
- "while decoding database block starting at offset %d",
- received_size);
- com_err(progname, retval, buf);
- send_error(context, fd, retval, buf);
- krb5_free_data_contents(context, &inbuf);
- exit(1);
- }
- n = write(database_fd, outbuf.data, outbuf.length);
- krb5_free_data_contents(context, &inbuf);
- krb5_free_data_contents(context, &outbuf);
- if (n < 0) {
- snprintf(buf, sizeof(buf),
- "while writing database block starting at offset %d",
- received_size);
- send_error(context, fd, errno, buf);
- } else if (n != outbuf.length) {
- snprintf(buf, sizeof(buf),
- "incomplete write while writing database block starting at \noffset %d (%d written, %d expected)",
- received_size, n, outbuf.length);
- send_error(context, fd, KRB5KRB_ERR_GENERIC, buf);
- }
- received_size += outbuf.length;
- }
- /*
- * OK, we've seen the entire file. Did we get too many bytes?
- */
- if (received_size > database_size) {
- snprintf(buf, sizeof(buf),
- "Received %d bytes, expected %d bytes for database file",
- received_size, database_size);
- send_error(context, fd, KRB5KRB_ERR_GENERIC, buf);
- }
- /*
- * Create message acknowledging number of bytes received, but
- * don't send it until kdb5_util returns successfully.
- */
- database_size = htonl(database_size);
- inbuf.data = (char *) &database_size;
- inbuf.length = sizeof(database_size);
- retval = krb5_mk_safe(context,auth_context,&inbuf,confmsg,NULL);
- if (retval) {
- com_err(progname, retval,
- "while encoding # of receieved bytes");
- send_error(context, fd, retval,
- "while encoding # of received bytes");
- exit(1);
- }
+ krb5_ui_4 database_size; /* This must be 4 bytes */
+ int received_size, n;
+ char buf[1024];
+ krb5_data inbuf, outbuf;
+ krb5_error_code retval;
+
+ /*
+ * Receive and decode size from client
+ */
+ retval = krb5_read_message(context, (void *) &fd, &inbuf);
+ if (retval) {
+ send_error(context, fd, retval, "while reading database size");
+ com_err(progname, retval,
+ "while reading size of database from client");
+ exit(1);
+ }
+ if (krb5_is_krb_error(&inbuf))
+ recv_error(context, &inbuf);
+ retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL);
+ if (retval) {
+ send_error(context, fd, retval,
+ "while decoding database size");
+ krb5_free_data_contents(context, &inbuf);
+ com_err(progname, retval,
+ "while decoding database size from client");
+ exit(1);
+ }
+ memcpy(&database_size, outbuf.data, sizeof(database_size));
+ krb5_free_data_contents(context, &inbuf);
+ krb5_free_data_contents(context, &outbuf);
+ database_size = ntohl(database_size);
+
+ /*
+ * Initialize the initial vector.
+ */
+ retval = krb5_auth_con_initivector(context, auth_context);
+ if (retval) {
+ send_error(context, fd, retval,
+ "failed while initializing i_vector");
+ com_err(progname, retval, "while initializing i_vector");
+ exit(1);
+ }
+
+ /*
+ * Now start receiving the database from the net
+ */
+ received_size = 0;
+ while (received_size < database_size) {
+ retval = krb5_read_message(context, (void *) &fd, &inbuf);
+ if (retval) {
+ snprintf(buf, sizeof(buf),
+ "while reading database block starting at offset %d",
+ received_size);
+ com_err(progname, retval, buf);
+ send_error(context, fd, retval, buf);
+ exit(1);
+ }
+ if (krb5_is_krb_error(&inbuf))
+ recv_error(context, &inbuf);
+ retval = krb5_rd_priv(context, auth_context, &inbuf,
+ &outbuf, NULL);
+ if (retval) {
+ snprintf(buf, sizeof(buf),
+ "while decoding database block starting at offset %d",
+ received_size);
+ com_err(progname, retval, buf);
+ send_error(context, fd, retval, buf);
+ krb5_free_data_contents(context, &inbuf);
+ exit(1);
+ }
+ n = write(database_fd, outbuf.data, outbuf.length);
+ krb5_free_data_contents(context, &inbuf);
+ krb5_free_data_contents(context, &outbuf);
+ if (n < 0) {
+ snprintf(buf, sizeof(buf),
+ "while writing database block starting at offset %d",
+ received_size);
+ send_error(context, fd, errno, buf);
+ } else if (n != outbuf.length) {
+ snprintf(buf, sizeof(buf),
+ "incomplete write while writing database block starting at \noffset %d (%d written, %d expected)",
+ received_size, n, outbuf.length);
+ send_error(context, fd, KRB5KRB_ERR_GENERIC, buf);
+ }
+ received_size += outbuf.length;
+ }
+ /*
+ * OK, we've seen the entire file. Did we get too many bytes?
+ */
+ if (received_size > database_size) {
+ snprintf(buf, sizeof(buf),
+ "Received %d bytes, expected %d bytes for database file",
+ received_size, database_size);
+ send_error(context, fd, KRB5KRB_ERR_GENERIC, buf);
+ }
+ /*
+ * Create message acknowledging number of bytes received, but
+ * don't send it until kdb5_util returns successfully.
+ */
+ database_size = htonl(database_size);
+ inbuf.data = (char *) &database_size;
+ inbuf.length = sizeof(database_size);
+ retval = krb5_mk_safe(context,auth_context,&inbuf,confmsg,NULL);
+ if (retval) {
+ com_err(progname, retval,
+ "while encoding # of receieved bytes");
+ send_error(context, fd, retval,
+ "while encoding # of received bytes");
+ exit(1);
+ }
}
void
send_error(context, fd, err_code, err_text)
krb5_context context;
- int fd;
- krb5_error_code err_code;
- char *err_text;
+ int fd;
+ krb5_error_code err_code;
+ char *err_text;
{
- krb5_error error;
- const char *text;
- krb5_data outbuf;
- char buf[1024];
-
- memset(&error, 0, sizeof(error));
- krb5_us_timeofday(context, &error.stime, &error.susec);
- error.server = server;
- error.client = client;
-
- if (err_text)
- text = err_text;
- else
- text = error_message(err_code);
-
- error.error = err_code - ERROR_TABLE_BASE_krb5;
- if (error.error > 127) {
- error.error = KRB_ERR_GENERIC;
- if (err_text) {
- snprintf(buf, sizeof(buf), "%s %s",
- error_message(err_code), err_text);
- text = buf;
- }
- }
- error.text.length = strlen(text) + 1;
- error.text.data = strdup(text);
- if (error.text.data) {
- if (!krb5_mk_error(context, &error, &outbuf)) {
- (void) krb5_write_message(context, (void *)&fd,&outbuf);
- krb5_free_data_contents(context, &outbuf);
- }
- free(error.text.data);
- }
+ krb5_error error;
+ const char *text;
+ krb5_data outbuf;
+ char buf[1024];
+
+ memset(&error, 0, sizeof(error));
+ krb5_us_timeofday(context, &error.stime, &error.susec);
+ error.server = server;
+ error.client = client;
+
+ if (err_text)
+ text = err_text;
+ else
+ text = error_message(err_code);
+
+ error.error = err_code - ERROR_TABLE_BASE_krb5;
+ if (error.error > 127) {
+ error.error = KRB_ERR_GENERIC;
+ if (err_text) {
+ snprintf(buf, sizeof(buf), "%s %s",
+ error_message(err_code), err_text);
+ text = buf;
+ }
+ }
+ error.text.length = strlen(text) + 1;
+ error.text.data = strdup(text);
+ if (error.text.data) {
+ if (!krb5_mk_error(context, &error, &outbuf)) {
+ (void) krb5_write_message(context, (void *)&fd,&outbuf);
+ krb5_free_data_contents(context, &outbuf);
+ }
+ free(error.text.data);
+ }
}
void
recv_error(context, inbuf)
krb5_context context;
- krb5_data *inbuf;
+ krb5_data *inbuf;
{
- krb5_error *error;
- krb5_error_code retval;
-
- retval = krb5_rd_error(context, inbuf, &error);
- if (retval) {
- com_err(progname, retval,
- "while decoding error packet from client");
- exit(1);
- }
- if (error->error == KRB_ERR_GENERIC) {
- if (error->text.data)
- fprintf(stderr,
- "Generic remote error: %s\n",
- error->text.data);
- } else if (error->error) {
- com_err(progname,
- (krb5_error_code) error->error + ERROR_TABLE_BASE_krb5,
- "signaled from server");
- if (error->text.data)
- fprintf(stderr,
- "Error text from client: %s\n",
- error->text.data);
- }
- krb5_free_error(context, error);
- exit(1);
+ krb5_error *error;
+ krb5_error_code retval;
+
+ retval = krb5_rd_error(context, inbuf, &error);
+ if (retval) {
+ com_err(progname, retval,
+ "while decoding error packet from client");
+ exit(1);
+ }
+ if (error->error == KRB_ERR_GENERIC) {
+ if (error->text.data)
+ fprintf(stderr,
+ "Generic remote error: %s\n",
+ error->text.data);
+ } else if (error->error) {
+ com_err(progname,
+ (krb5_error_code) error->error + ERROR_TABLE_BASE_krb5,
+ "signaled from server");
+ if (error->text.data)
+ fprintf(stderr,
+ "Error text from client: %s\n",
+ error->text.data);
+ }
+ krb5_free_error(context, error);
+ exit(1);
}
void
char *kdb_util;
char *database_file_name;
{
- static char *edit_av[10];
- int error_ret, save_stderr = -1;
- int child_pid;
- int count;
+ static char *edit_av[10];
+ int error_ret, save_stderr = -1;
+ int child_pid;
+ int count;
- /* <sys/param.h> has been included, so BSD will be defined on
- BSD systems */
+ /* <sys/param.h> has been included, so BSD will be defined on
+ BSD systems */
#if BSD > 0 && BSD <= 43
#ifndef WEXITSTATUS
-#define WEXITSTATUS(w) (w).w_retcode
+#define WEXITSTATUS(w) (w).w_retcode
#endif
- union wait waitb;
+ union wait waitb;
#else
- int waitb;
+ int waitb;
#endif
- krb5_error_code retval;
- kdb_log_context *log_ctx;
-
- if (debug)
- printf("calling kdb5_util to load database\n");
-
- log_ctx = context->kdblog_context;
-
- edit_av[0] = kdb_util;
- count = 1;
- if (realm) {
- edit_av[count++] = "-r";
- edit_av[count++] = realm;
- }
- edit_av[count++] = "load";
- if (kerb_database) {
- edit_av[count++] = "-d";
- edit_av[count++] = kerb_database;
- }
- if (log_ctx && log_ctx->iproprole == IPROP_SLAVE) {
- edit_av[count++] = "-i";
- }
- edit_av[count++] = database_file_name;
- edit_av[count++] = NULL;
-
- switch(child_pid = fork()) {
- case -1:
- com_err(progname, errno, "while trying to fork %s",
- kdb_util);
- exit(1);
- case 0:
- if (!debug) {
- save_stderr = dup(2);
- close(0);
- close(1);
- close(2);
- open("/dev/null", O_RDWR);
- dup(0);
- dup(0);
- }
-
- if (execv(kdb_util, edit_av) < 0)
- retval = errno;
- else
- retval = 0;
- if (!debug)
- dup2(save_stderr, 2);
- com_err(progname, retval, "while trying to exec %s",
- kdb_util);
- _exit(1);
- /*NOTREACHED*/
- default:
- if (debug)
- printf("Child PID is %d\n", child_pid);
- if (wait(&waitb) < 0) {
- com_err(progname, errno, "while waiting for %s",
- kdb_util);
- exit(1);
- }
- }
-
- error_ret = WEXITSTATUS(waitb);
- if (error_ret) {
- com_err(progname, 0, "%s returned a bad exit status (%d)",
- kdb_util, error_ret);
- exit(1);
- }
- return;
+ krb5_error_code retval;
+ kdb_log_context *log_ctx;
+
+ if (debug)
+ printf("calling kdb5_util to load database\n");
+
+ log_ctx = context->kdblog_context;
+
+ edit_av[0] = kdb_util;
+ count = 1;
+ if (realm) {
+ edit_av[count++] = "-r";
+ edit_av[count++] = realm;
+ }
+ edit_av[count++] = "load";
+ if (kerb_database) {
+ edit_av[count++] = "-d";
+ edit_av[count++] = kerb_database;
+ }
+ if (log_ctx && log_ctx->iproprole == IPROP_SLAVE) {
+ edit_av[count++] = "-i";
+ }
+ edit_av[count++] = database_file_name;
+ edit_av[count++] = NULL;
+
+ switch(child_pid = fork()) {
+ case -1:
+ com_err(progname, errno, "while trying to fork %s",
+ kdb_util);
+ exit(1);
+ case 0:
+ if (!debug) {
+ save_stderr = dup(2);
+ close(0);
+ close(1);
+ close(2);
+ open("/dev/null", O_RDWR);
+ dup(0);
+ dup(0);
+ }
+
+ if (execv(kdb_util, edit_av) < 0)
+ retval = errno;
+ else
+ retval = 0;
+ if (!debug)
+ dup2(save_stderr, 2);
+ com_err(progname, retval, "while trying to exec %s",
+ kdb_util);
+ _exit(1);
+ /*NOTREACHED*/
+ default:
+ if (debug)
+ printf("Child PID is %d\n", child_pid);
+ if (wait(&waitb) < 0) {
+ com_err(progname, errno, "while waiting for %s",
+ kdb_util);
+ exit(1);
+ }
+ }
+
+ error_ret = WEXITSTATUS(waitb);
+ if (error_ret) {
+ com_err(progname, 0, "%s returned a bad exit status (%d)",
+ kdb_util, error_ret);
+ exit(1);
+ }
+ return;
}
/*
*/
static kadm5_ret_t
kadm5_get_kiprop_host_srv_name(krb5_context context,
- const char *realm_name,
- char **host_service_name)
+ const char *realm_name,
+ char **host_service_name)
{
- char *name;
- char *host;
+ char *name;
+ char *host;
- host = params.admin_server; /* XXX */
+ host = params.admin_server; /* XXX */
- if (asprintf(&name, "%s/%s", KADM5_KIPROP_HOST_SERVICE, host) < 0) {
- free(host);
- return (ENOMEM);
- }
- *host_service_name = name;
+ if (asprintf(&name, "%s/%s", KADM5_KIPROP_HOST_SERVICE, host) < 0) {
+ free(host);
+ return (ENOMEM);
+ }
+ *host_service_name = name;
- return (KADM5_OK);
+ return (KADM5_OK);
}