From 28d474b23d9abe9b6d06fdeecae9ea934abfc6c9 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 7 Dec 2001 04:22:42 +0000 Subject: o Use writev() to send status on the backchannel instead of fdopen()ing fd 3 and using stdio. o Add SIGINT/SIGQUIT signal handler for yp_chpass() now that getpass() is interuptible. o Block SIGINT/SIGQUIT in krb_chpass() until it is made to clean up after itself properly. --- libexec/login_chpass/login_chpass.c | 49 ++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'libexec/login_chpass') diff --git a/libexec/login_chpass/login_chpass.c b/libexec/login_chpass/login_chpass.c index 72e8ed93829..76b148444eb 100644 --- a/libexec/login_chpass/login_chpass.c +++ b/libexec/login_chpass/login_chpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: login_chpass.c,v 1.3 2001/12/06 05:37:03 millert Exp $ */ +/* $OpenBSD: login_chpass.c,v 1.4 2001/12/07 04:22:41 millert Exp $ */ /*- * Copyright (c) 1995,1996 Berkeley Software Design, Inc. All rights reserved. @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -70,10 +71,15 @@ #define _PATH_LOGIN_LCHPASS "/usr/libexec/auth/login_lchpass" +#define BACK_CHANNEL 3 + +struct iovec iov[2] = { { BI_SILENT, sizeof(BI_SILENT) - 1 }, { "\n", 1 } }; + #ifdef YP int _yp_check __P((char **)); char *ypgetnewpasswd __P((struct passwd *, char **)); struct passwd *ypgetpwnam __P((char *)); +void kbintr __P((int)); #endif #ifdef KERBEROS @@ -166,7 +172,6 @@ void yp_chpass(username) char *username; { - FILE *back; char *master; int r, rpcport, status; struct yppasswd yppasswd; @@ -175,10 +180,8 @@ yp_chpass(username) CLIENT *client; extern char *domain; - if (!(back = fdopen(3, "a"))) { - syslog(LOG_ERR, "reopening back channel: %m"); - exit(1); - } + (void)signal(SIGINT, kbintr); + (void)signal(SIGQUIT, kbintr); if ((r = yp_get_default_domain(&domain)) != 0) { warnx("can't get local YP domain. Reason: %s", yperr_string(r)); @@ -219,7 +222,7 @@ yp_chpass(username) if (*pw->pw_passwd == '\0') { syslog(LOG_ERR, "%s attempting to add password", username); - fprintf(back, BI_SILENT "\n"); + (void)writev(BACK_CHANNEL, iov, 2); exit(0); } @@ -256,9 +259,27 @@ yp_chpass(username) printf("The YP password has been changed on %s, the master YP passwd server.\n", master); free(yppasswd.newpw.pw_passwd); - fprintf(back, BI_SILENT "\n"); + (void)writev(BACK_CHANNEL, iov, 2); exit(0); } + +void kbintr(signo) + int signo; +{ + char msg[] = "YP passwd database unchanged.\n"; + struct iovec iv[3]; + extern char *__progname; + + iv[0].iov_base = __progname; + iv[0].iov_len = strlen(__progname); + iv[1].iov_base = ": "; + iv[1].iov_len = 2; + iv[2].iov_base = msg; + iv[2].iov_len = sizeof(msg) - 1; + writev(STDERR_FILENO, iv, 3); + + _exit(1); +} #endif #ifdef KERBEROS @@ -268,16 +289,16 @@ krb_chpass(username, instance, argv) char *instance; char *argv[]; { - FILE *back; int rval; char pword[MAX_KPW_LEN]; char tktstring[MAXPATHLEN]; krb_principal principal; + sigset_t set; - if (!(back = fdopen(3, "a"))) { - syslog(LOG_ERR, "reopening back channel: %m"); - exit(1); - } + sigemptyset(&set); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGQUIT); + (void)sigprocmask(SIG_BLOCK, &set, NULL); memset(&principal, 0, sizeof(principal)); krb_get_default_principal(principal.name, @@ -320,7 +341,7 @@ krb_chpass(username, instance, argv) dest_tkt(); if (rval == 0) - fprintf(back, BI_SILENT "\n"); + (void)writev(BACK_CHANNEL, iov, 2); exit(rval); } #endif -- cgit v1.2.3