From: Todd C. Miller <Todd.Miller@courtesan.com> Date: Thu, 18 Mar 2010 10:42:17 +0000 (-0400) Subject: Pass in output function to lbuf_init() instead of writing to stdout. X-Git-Tag: SUDO_1_8_0~795 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b4f4afdf6931732227370e2827ca68bd3a4a4cd3;p=sudo Pass in output function to lbuf_init() instead of writing to stdout. A side effect is that the usage info can now go to stderr as it should. --- diff --git a/include/lbuf.h b/include/lbuf.h index 302918aad..1a8e6dfda 100644 --- a/include/lbuf.h +++ b/include/lbuf.h @@ -23,18 +23,19 @@ * Line buffer struct. */ struct lbuf { + int (*output)(const char *); char *buf; - int continuation; + const char *continuation; int indent; int len; int size; int cols; }; -void lbuf_init (struct lbuf *, char *, int, int, int); -void lbuf_destroy (struct lbuf *); -void lbuf_append (struct lbuf *, ...); -void lbuf_append_quoted (struct lbuf *, const char *, ...); -void lbuf_print (struct lbuf *); +void lbuf_init(struct lbuf *, int (*)(const char *), int, const char *, int); +void lbuf_destroy(struct lbuf *); +void lbuf_append(struct lbuf *, ...); +void lbuf_append_quoted(struct lbuf *, const char *, ...); +void lbuf_print(struct lbuf *); #endif /* _SUDO_LBUF_H */ diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c index 707c5cc87..94ca3bb35 100644 --- a/plugins/sudoers/auth/sudo_auth.c +++ b/plugins/sudoers/auth/sudo_auth.c @@ -52,8 +52,6 @@ #include "sudo_auth.h" #include "insults.h" -sudo_conv_t sudo_conv; - sudo_auth auth_switch[] = { #ifdef AUTH_STANDALONE AUTH_STANDALONE diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c index f913ff667..161d86e5d 100644 --- a/plugins/sudoers/check.c +++ b/plugins/sudoers/check.c @@ -75,8 +75,6 @@ static char *expand_prompt(char *, char *, char *); static void lecture(int); static void update_timestamp(char *, char *); -extern sudo_conv_t sudo_conv; - /* * This function only returns if the user can successfully * verify who he/she is. diff --git a/plugins/sudoers/sudo_nss.c b/plugins/sudoers/sudo_nss.c index c6e905a4e..df8509c1a 100644 --- a/plugins/sudoers/sudo_nss.c +++ b/plugins/sudoers/sudo_nss.c @@ -224,10 +224,27 @@ reset_groups(pw) #endif } +static int +output(const char *buf) +{ + struct sudo_conv_message msg; + struct sudo_conv_reply repl; + + /* Call conversation function */ + memset(&msg, 0, sizeof(msg)); + msg.msg_type = SUDO_CONV_INFO_MSG; + msg.msg = buf; + memset(&repl, 0, sizeof(repl)); + if (sudo_conv(1, &msg, &repl) == -1) + return 0; + return (int)strlen(buf); +} + /* * Print out privileges for the specified user. * We only get here if the user is allowed to run something on this host. */ +/* XXX - conversation function or newlines in lbuf */ void display_privs(snl, pw) struct sudo_nss_list *snl; @@ -240,7 +257,7 @@ display_privs(snl, pw) /* Reset group vector so group matching works correctly. */ reset_groups(pw); - lbuf_init(&lbuf, NULL, 4, 0, sudo_user.cols); + lbuf_init(&lbuf, output, 4, NULL, sudo_user.cols); /* Display defaults from all sources. */ count = 0; diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 7820135a2..986cef6cd 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -152,6 +152,8 @@ login_cap_t *lc; char *login_style; #endif /* HAVE_BSD_AUTH_H */ sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp; +sudo_conv_t sudo_conv; + static char *runas_user; static char *runas_group; static struct sudo_nss_list *snl; diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 46a3c7847..19ac90131 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -307,6 +307,7 @@ extern struct passwd *auth_pw, *list_pw; extern int tgetpass_flags; /* XXX */ extern int long_list; extern uid_t timestamp_uid; +extern sudo_conv_t sudo_conv; #endif #ifndef errno extern int errno; diff --git a/src/lbuf.c b/src/lbuf.c index 148278ded..4a7437ebe 100644 --- a/src/lbuf.c +++ b/src/lbuf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2009 Todd C. Miller <Todd.Miller@courtesan.com> + * Copyright (c) 2007-2010 Todd C. Miller <Todd.Miller@courtesan.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -58,8 +58,10 @@ */ void -lbuf_init(struct lbuf *lbuf, char *buf, int indent, int continuation, int cols) +lbuf_init(struct lbuf *lbuf, int (*output)(const char *), + int indent, const char *continuation, int cols) { + lbuf->output = output; lbuf->continuation = continuation; lbuf->indent = indent; lbuf->cols = cols; @@ -163,10 +165,10 @@ lbuf_append(struct lbuf *lbuf, ...) void lbuf_print(struct lbuf *lbuf) { - char *cp; + char *cp, save; int i, have, contlen; - contlen = lbuf->continuation ? 2 : 0; + contlen = lbuf->continuation ? strlen(lbuf->continuation) : 0; /* For very small widths just give up... */ if (lbuf->cols <= lbuf->indent + contlen + 20) { @@ -198,9 +200,13 @@ lbuf_print(struct lbuf *lbuf) if (cp != lbuf->buf) { /* indent continued lines */ for (i = 0; i < lbuf->indent; i++) - putchar(' '); + lbuf->output(" "); } - fwrite(cp, need, 1, stdout); + /* NUL-terminate cp for the output function and restore afterwards */ + save = cp[need]; + cp[need] = '\0'; + lbuf->output(cp); + cp[need] = save; cp = ep; /* @@ -212,12 +218,10 @@ lbuf_print(struct lbuf *lbuf) do { cp++; } while (isspace((unsigned char)*cp)); - if (lbuf->continuation) { - putchar(' '); - putchar(lbuf->continuation); - } + if (contlen) + lbuf->output(lbuf->continuation); } - putchar('\n'); + lbuf->output("\n"); } done: diff --git a/src/parse_args.c b/src/parse_args.c index 41d0ed5cd..e970a9f04 100644 --- a/src/parse_args.c +++ b/src/parse_args.c @@ -373,6 +373,12 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp, return(mode | flags); } +static int +usage_out(const char *buf) +{ + return fputs(buf, stderr); +} + /* * Give usage message and exit. * The actual usage strings are in sudo_usage.h for configure substitution. @@ -404,7 +410,7 @@ usage(int exit_val) * tty width. */ ulen = (int)strlen(getprogname()) + 8; - lbuf_init(&lbuf, NULL, ulen, 0, user_details.ts_cols); + lbuf_init(&lbuf, usage_out, ulen, NULL, user_details.ts_cols); for (i = 0; uvec[i] != NULL; i++) { lbuf_append(&lbuf, "usage: ", getprogname(), uvec[i], NULL); lbuf_print(&lbuf);