/*
- * $Source$
- * $Author$
+ * slave/kprop.c
*
* Copyright 1990,1991 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
- * For copying and distribution information, please see the file
- * <krb5/copyright.h>.
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
*
*/
-#if !defined(lint) && !defined(SABER)
-static char rcsid_kprop_c[] =
-"$Id$";
-#endif /* !lint && !SABER */
-
-#include <krb5/krb5.h>
-#include <krb5/asn1.h>
-#include <krb5/osconf.h>
-#include <krb5/kdb.h>
-#include <krb5/kdb_dbm.h>
-#include <krb5/ext-proto.h>
-#include <krb5/los-proto.h>
-#include <com_err.h>
-#include <errno.h>
+#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <netdb.h>
+#include <fcntl.h>
+#include "k5-int.h"
+#include "com_err.h"
#include "kprop.h"
static char *kprop_version = KPROP_PROT_VERSION;
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 my_creds; /* My credentials */
-krb5_int32 my_seq_num; /* Sequence number to use for connection */
-krb5_int32 his_seq_num; /* Remote sequence number */
+/* krb5_creds my_creds; /* My credentials */
+krb5_creds creds;
krb5_address sender_addr;
krb5_address receiver_addr;
-void PRS();
-void get_tickets();
-void usage();
-krb5_error_code open_connection();
-void kerberos_authenticate();
-int open_database();
-void xmit_database();
-void send_error();
-void update_last_prop_file();
+void PRS
+ PROTOTYPE((int, char **));
+void get_tickets
+ PROTOTYPE((krb5_context));
+static void usage
+ PROTOTYPE((void));
+krb5_error_code open_connection
+ PROTOTYPE((char *, int *, char *, int));
+void kerberos_authenticate
+ PROTOTYPE((krb5_context, krb5_auth_context *,
+ int, krb5_principal, krb5_creds **));
+int open_database
+ PROTOTYPE((krb5_context, char *, int *));
+void close_database
+ PROTOTYPE((krb5_context, int));
+void xmit_database
+ PROTOTYPE((krb5_context, krb5_auth_context, krb5_creds *,
+ int, int, int));
+void send_error
+ PROTOTYPE((krb5_context, krb5_creds *, int, char *, krb5_error_code));
+void update_last_prop_file
+ PROTOTYPE((char *, char *));
static void usage()
{
- fprintf(stderr, "\nUsage: %s [-r realm] [-f file] [-d] slave_host\n\n",
+ fprintf(stderr, "\nUsage: %s [-r realm] [-f file] [-d] [-P port] [-s srvtab] slave_host\n\n",
progname);
exit(1);
}
-void
+int
main(argc, 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];
- PRS(argv);
- get_tickets();
+ 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(file, &database_size);
- if (retval = open_connection(slave_host, &fd, Errmsg)) {
+ database_fd = open_database(context, file, &database_size);
+ if (retval = open_connection(slave_host, &fd, Errmsg, sizeof(Errmsg))) {
com_err(progname, retval, "%s while opening connection to %s",
Errmsg, slave_host);
exit(1);
progname, Errmsg, slave_host);
exit(1);
}
- kerberos_authenticate(fd, my_principal);
- if (debug) {
- printf("My sequence number: %d\n", my_seq_num);
- printf("His sequence number: %d\n", his_seq_num);
- }
- xmit_database(fd, database_fd, database_size);
+ 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(argv)
+void PRS(argc, argv)
+ int argc;
char **argv;
{
register char *word, ch;
- krb5_init_ets();
progname = *argv++;
- while (word = *argv++) {
+ while (--argc && (word = *argv++)) {
if (*word == '-') {
word++;
while (word && (ch = *word++)) {
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();
}
usage();
}
-void get_tickets()
+void get_tickets(context)
+ krb5_context context;
{
char my_host_name[MAXHOSTNAMELEN];
char buf[BUFSIZ];
- char *cp, *strcpy(), *krb_get_phost();
+ char *cp;
struct hostent *hp;
- krb5_address **my_addresses;
krb5_error_code retval;
static char tkstring[] = "/tmp/kproptktXXXXXX";
+ krb5_keytab keytab = NULL;
/*
* Figure out what tickets we'll be using to send stuff
*/
- if (gethostname (my_host_name, sizeof(my_host_name)) != 0) {
- com_err(progname, errno, "while getting my hostname");
- exit(1);
- }
- /* get canonicalized service instance name */
- if (!(hp = gethostbyname(my_host_name))) {
- fprintf(stderr, "Couldn't get my cannonicalized host name!\n");
- exit(1);
+ 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);
}
- for (cp=hp->h_name; *cp; cp++)
- if (isupper(*cp))
- *cp = tolower(*cp);
- if (realm)
- sprintf(buf, "rcmd/%s@%s", hp->h_name, realm);
- else
- sprintf(buf, "rcmd/%s", hp->h_name);
- if (retval = krb5_parse_name(buf, &my_principal)) {
- com_err (progname, retval, "when parsing name %s",buf);
- exit(1);
+ if (realm) {
+ (void) krb5_xfree(krb5_princ_realm(context, my_principal)->data);
+ krb5_princ_set_realm_length(context, my_principal, strlen(realm));
+ krb5_princ_set_realm_data(context, my_principal, strdup(realm));
}
+#if 0
+ krb5_princ_type(context, my_principal) = KRB5_NT_PRINCIPAL;
+#endif
/*
* Initialize cache file which we're going to be using
*/
(void) mktemp(tkstring);
sprintf(buf, "FILE:%s", tkstring);
- if (retval = krb5_cc_resolve(buf, &ccache)) {
- com_err(progname, retval, "while opening crednetials cache %s",
+ if (retval = krb5_cc_resolve(context, buf, &ccache)) {
+ com_err(progname, retval, "while opening credential cache %s",
buf);
exit(1);
}
- if (retval = krb5_cc_initialize(ccache, my_principal)) {
+ if (retval = krb5_cc_initialize(context, ccache, my_principal)) {
com_err (progname, retval, "when initializing cache %s",
buf);
exit(1);
*
* Construct the principal name for the slave host.
*/
- memset((char *)&my_creds, 0, sizeof(my_creds));
- if (!(hp = gethostbyname(slave_host))) {
- fprintf(stderr,
- "Couldn't get cannonicalized name for slave\n");
- exit(1);
- }
- for (cp=hp->h_name; *cp; cp++)
- if (isupper(*cp))
- *cp = tolower(*cp);
- if (!(slave_host = malloc(strlen(hp->h_name) + 1))) {
- com_err(progname, ENOMEM,
- "while allocate space for canonicalized slave host");
- exit(1);
+ memset((char *)&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);
}
- strcpy(slave_host, hp->h_name);
- if (realm)
- sprintf(buf, "%s/%s@%s", KPROP_SERVICE_NAME, slave_host,
- realm);
- else
- sprintf(buf, "%s/%s", KPROP_SERVICE_NAME, hp->h_name);
- if (retval = krb5_parse_name(buf, &my_creds.server)) {
- com_err(progname, retval,
- "while parsing slave principal name");
- exit(1);
+ if (realm) {
+ (void) krb5_xfree(krb5_princ_realm(context, creds.server)->data);
+ krb5_princ_set_realm_length(context, creds.server, strlen(realm));
+ krb5_princ_set_realm_data(context, creds.server, strdup(realm));
}
+
/*
* Now fill in the client....
*/
- if (retval = krb5_copy_principal(my_principal, &my_creds.client)) {
+ if (retval = krb5_copy_principal(context, my_principal, &creds.client)) {
com_err(progname, retval, "While copying client principal");
+ (void) krb5_cc_destroy(context, ccache);
exit(1);
}
- /*
- * Get my addresses
- */
- retval = krb5_os_localaddr(&my_addresses);
- if (retval != 0) {
- com_err(progname, retval,
- "when getting my address");
- exit(1);
+ if (srvtab) {
+ if (retval = krb5_kt_resolve(context, srvtab, &keytab)) {
+ com_err(progname, retval, "while resolving keytab");
+ (void) krb5_cc_destroy(context, ccache);
+ exit(1);
+ }
}
- retval = krb5_get_in_tkt_with_skey(0, my_addresses,
- ETYPE_DES_CBC_CRC,
- 0, ccache, &my_creds);
+
+ 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");
+ 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.
*/
- if (retval = krb5_cc_destroy(ccache)) {
+ if (retval = krb5_cc_destroy(context, ccache)) {
com_err(progname, retval, "while destroying ticket cache");
exit(1);
}
}
krb5_error_code
-open_connection(host, fd, Errmsg)
+open_connection(host, fd, Errmsg, ErrmsgSz)
char *host;
int *fd;
char *Errmsg;
+ int ErrmsgSz;
{
int s;
krb5_error_code retval;
*fd = -1;
return(0);
}
- sp = getservbyname(KPROP_SERVICE, "tcp");
- if (sp == 0) {
- (void) strcpy(Errmsg, KPROP_SERVICE);
- (void) strcat(Errmsg, "/tcp: unknown service");
- *fd = -1;
- return(0);
- }
sin.sin_family = hp->h_addrtype;
- bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
- sin.sin_port = sp->s_port;
+ memcpy((char *)&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
+ if(!port) {
+ sp = getservbyname(KPROP_SERVICE, "tcp");
+ if (sp == 0) {
+ (void) strncpy(Errmsg, KPROP_SERVICE, ErrmsgSz - 1);
+ Errmsg[ErrmsgSz - 1] = '\0';
+ (void) strncat(Errmsg, "/tcp: unknown service", ErrmsgSz - 1 - strlen(Errmsg));
+ *fd = -1;
+ return(0);
+ }
+ sin.sin_port = sp->s_port;
+ } else
+ sin.sin_port = port;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
sizeof(sin.sin_addr));
socket_length = sizeof(sin);
- if (getpeername(s, (struct sockaddr *)&sin, &socket_length) < 0) {
+ if (getsockname(s, (struct sockaddr *)&sin, &socket_length) < 0) {
retval = errno;
close(s);
- (void) sprintf(Errmsg, "in call to getpeername");
+ (void) sprintf(Errmsg, "in call to getsockname");
return(retval);
}
sender_addr.addrtype = ADDRTYPE_INET;
}
-void kerberos_authenticate(fd, me)
- int fd;
- krb5_principal me;
+void kerberos_authenticate(context, auth_context, fd, me, new_creds)
+ krb5_context context;
+ krb5_auth_context *auth_context;
+ int fd;
+ krb5_principal me;
+ krb5_creds ** new_creds;
{
krb5_error_code retval;
krb5_error *error = NULL;
krb5_ap_rep_enc_part *rep_result;
- if (retval = krb5_sendauth((void *)&fd, kprop_version, me,
- my_creds.server, AP_OPTS_MUTUAL_REQUIRED,
- NULL, &my_creds, NULL, &my_seq_num, NULL,
- &error, &rep_result)) {
+ if (retval = krb5_auth_con_init(context, auth_context))
+ exit(1);
+
+ krb5_auth_con_setflags(context, *auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+
+ if (retval = krb5_auth_con_setaddrs(context, *auth_context, &sender_addr,
+ &receiver_addr)) {
+ com_err(progname, retval, "in krb5_auth_con_setaddrs");
+ exit(1);
+ }
+
+ if (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)) {
com_err(progname, retval, "while authenticating to server");
if (error) {
if (error->error == KRB_ERR_GENERIC) {
"Error text from server: %s\n",
error->text.data);
}
- krb5_free_error(error);
+ krb5_free_error(context, error);
}
exit(1);
}
- his_seq_num = rep_result->seq_number;
- krb5_free_ap_rep_enc_part(rep_result);
+ krb5_free_ap_rep_enc_part(context, rep_result);
}
+char * dbpathname;
/*
* Open the Kerberos database dump file. Takes care of locking it
* and making sure that the .ok file is more recent that the database
* in the size of the database file.
*/
int
-open_database(data_fn, size)
- char *data_fn;
- int *size;
+open_database(context, data_fn, size)
+ krb5_context context;
+ char *data_fn;
+ int *size;
{
int fd;
+ int err;
struct stat stbuf, stbuf_ok;
char *data_ok_fn;
static char ok[] = ".dump_ok";
-
- if ((fd = open(data_fn, O_RDONLY)) < 0) {
- com_err(progname, 0, "While trying to open %s",
- data_fn);
- exit(1);
- }
- if (flock(fd, LOCK_SH | LOCK_NB)) {
- com_err(progname, errno, "while trying to flock %s",
- data_fn);
+
+ 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);
}
- if (stat(data_fn, &stbuf)) {
+
+ 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);
com_err(progname, ENOMEM, "while trying to malloc data_ok_fn");
exit(1);
}
- strcat(strcpy(data_ok_fn, data_fn), ok);
+ strcpy(data_ok_fn, data_fn);
+ strcat(data_ok_fn, ok);
if (stat(data_ok_fn, &stbuf_ok)) {
com_err(progname, errno, "while trying to stat %s",
data_ok_fn);
return(fd);
}
+void
+close_database(context, fd)
+ krb5_context context;
+ int fd;
+{
+ int err;
+ if (err = krb5_lock_file(context, fd, KRB5_LOCKMODE_UNLOCK))
+ com_err(progname, err, "while unlocking database '%s'", dbpathname);
+ free(dbpathname);
+ (void)close(fd);
+ return;
+}
+
/*
* Now we send over the database. We use the following protocol:
* Send over a KRB_SAFE message with the size. Then we send over the
* will abort the entire operation.
*/
void
-xmit_database(fd, database_fd, database_size)
- int fd;
- int database_fd;
- int database_size;
+xmit_database(context, auth_context, my_creds, fd, database_fd, database_size)
+ krb5_context context;
+ krb5_auth_context auth_context;
+ krb5_creds *my_creds;
+ int fd;
+ int database_fd;
+ int database_size;
{
- int send_size, sent_size, n, eblock_size;
+ krb5_int32 send_size, sent_size, n;
krb5_data inbuf, outbuf;
char buf[KPROP_BUFSIZ];
- char *i_vector;
krb5_error_code retval;
krb5_error *error;
send_size = htonl(database_size);
inbuf.data = (char *) &send_size;
inbuf.length = sizeof(send_size); /* must be 4, really */
- if (retval = krb5_mk_safe(&inbuf, KPROP_CKSUMTYPE,
- &my_creds.keyblock,
- &sender_addr, &receiver_addr,
- my_seq_num++,
- KRB5_PRIV_DOSEQUENCE|KRB5_SAFE_NOTIME,
- 0, /* no rcache when NOTIME */
- &outbuf)) {
+ /* KPROP_CKSUMTYPE */
+ if (retval = krb5_mk_safe(context, auth_context, &inbuf,
+ &outbuf, NULL)) {
com_err(progname, retval, "while encoding database size");
- send_error(fd, "while encoding database size", retval);
+ send_error(context, my_creds, fd, "while encoding database size", retval);
exit(1);
}
- if (retval = krb5_write_message((void *) &fd, &outbuf)) {
- xfree(outbuf.data);
+ if (retval = krb5_write_message(context, (void *) &fd, &outbuf)) {
+ krb5_free_data_contents(context, &outbuf);
com_err(progname, retval, "while sending database size");
exit(1);
}
- xfree(outbuf.data);
- /*
- * Initialize the initial vector.
- */
- eblock_size = krb5_keytype_array[my_creds.keyblock.keytype]->
- system->block_length;
- if (!(i_vector=malloc(eblock_size))) {
- com_err(progname, ENOMEM, "while allocating i_vector");
- send_error(fd, "malloc failed while allocating i_vector",
- ENOMEM);
- exit(1);
- }
- memset(i_vector, 0, eblock_size);
+ krb5_free_data_contents(context, &outbuf);
+ /*
+ * Initialize the initial vector.
+ */
+ if (retval = krb5_auth_con_initivector(context, auth_context)) {
+ 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....
*/
sent_size = 0;
while (n = read(database_fd, buf, sizeof(buf))) {
inbuf.length = n;
- if (retval = krb5_mk_priv(&inbuf, ETYPE_DES_CBC_CRC,
- &my_creds.keyblock,
- &sender_addr,
- &receiver_addr,
- my_seq_num++,
- KRB5_PRIV_DOSEQUENCE|KRB5_PRIV_NOTIME,
- 0, /* again, no rcache */
- i_vector,
- &outbuf)) {
+ if (retval = krb5_mk_priv(context, auth_context, &inbuf,
+ &outbuf, NULL)) {
sprintf(buf,
"while encoding database block starting at %d",
sent_size);
com_err(progname, retval, buf);
- send_error(fd, buf, retval);
+ send_error(context, my_creds, fd, buf, retval);
exit(1);
}
- if (retval = krb5_write_message((void *) &fd, &outbuf)) {
- xfree(outbuf.data);
+ if (retval = krb5_write_message(context, (void *)&fd,&outbuf)) {
+ krb5_free_data_contents(context, &outbuf);
com_err(progname, retval,
"while sending database block starting at %d",
sent_size);
exit(1);
}
- xfree(outbuf.data);
+ 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(fd, "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.
*/
- if (retval = krb5_read_message((void *) &fd, &inbuf)) {
+ if (retval = krb5_read_message(context, (void *) &fd, &inbuf)) {
com_err(progname, retval,
"while reading response from server");
exit(1);
* the error message
*/
if (krb5_is_krb_error(&inbuf)) {
- if (retval = krb5_rd_error(&inbuf, &error)) {
+ if (retval = krb5_rd_error(context, &inbuf, &error)) {
com_err(progname, retval,
"while decoding error response from server");
exit(1);
"Error text from server: %s\n",
error->text.data);
}
- krb5_free_error(error);
+ krb5_free_error(context, error);
exit(1);
}
- if (retval = krb5_rd_safe(&inbuf, &my_creds.keyblock, &receiver_addr,
- &sender_addr, his_seq_num++,
- KRB5_SAFE_DOSEQUENCE|KRB5_SAFE_NOTIME,
- 0, &outbuf)) {
+ if (retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL)) {
com_err(progname, retval,
"while decoding final size packet from server");
exit(1);
}
void
-send_error(fd, err_text, err_code)
- int fd;
- char *err_text;
- krb5_error_code err_code;
+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;
{
krb5_error error;
const char *text;
krb5_data outbuf;
memset((char *)&error, 0, sizeof(error));
- krb5_us_timeofday(&error.ctime, &error.cusec);
- error.server = my_creds.server;
+ 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.text.length = strlen(text) + 1;
if (error.text.data = malloc(error.text.length)) {
strcpy(error.text.data, text);
- if (!krb5_mk_error(&error, &outbuf)) {
- (void) krb5_write_message((void *) &fd, &outbuf);
- xfree(outbuf.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);
}
strcat(file_last_prop, ".");
strcat(file_last_prop, hostname);
strcat(file_last_prop, last_prop);
- if ((fd = open(file_last_prop, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
+ 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;