~vorlon/ubuntu/natty/sudo/keep_home_by_default

« back to all changes in this revision

Viewing changes to tgetpass.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-05-11 18:07:03 UTC
  • mfrom: (1.1.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090511180703-vl2t8cem14g6r61c
Tags: 1.7.0-1ubuntu1
* Merge from debian unstable, remaining changes:
 - debian/rules: Disable lecture, enable tty_tickets by default. (Ubuntu
   specific)
 - Add debian/sudo_root.8: Explanation of root handling through sudo.
   Install it in debian/rules. (Ubuntu specific)
 - sudo.c: If the user successfully authenticated and he is in the 'admin'
   group, then create a stamp ~/.sudo_as_admin_successful. Our default bash
   profile checks for this and displays a short intro about sudo if the
   flag is not present. (Ubuntu specific)
 - env.c: Add "http_proxy" to initial_keepenv_table, so that it is kept
   for "sudo apt-get ...". (Ubuntu specific EBW hack, should disappear at
   some point)
 - debian/{rules,postinst,sudo-ldap.postinst}: Disable init script
   installation. Debian reintroduced it because /var/run tmpfs is not the
   default there, but has been on Ubuntu for ages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 1996, 1998-2005 Todd C. Miller <Todd.Miller@courtesan.com>
 
2
 * Copyright (c) 1996, 1998-2005, 2007-2008
 
3
 *      Todd C. Miller <Todd.Miller@courtesan.com>
3
4
 *
4
5
 * Permission to use, copy, modify, and distribute this software for any
5
6
 * purpose with or without fee is hereby granted, provided that the above
70
71
#include "sudo.h"
71
72
 
72
73
#ifndef lint
73
 
__unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.111.2.7 2008/06/21 00:27:01 millert Exp $";
 
74
__unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.126 2008/12/09 20:55:49 millert Exp $";
74
75
#endif /* lint */
75
76
 
76
77
#ifndef TCSASOFT
114
115
 
115
116
static void handler __P((int));
116
117
static char *getln __P((int, char *, size_t));
 
118
static char *sudo_askpass __P((const char *));
117
119
 
118
120
/*
119
121
 * Like getpass(3) but with timeout and echo flags.
132
134
    int input, output, save_errno;
133
135
 
134
136
    (void) fflush(stdout);
 
137
 
 
138
    /* If using a helper program to get the password, run it instead. */
 
139
    if (ISSET(flags, TGP_ASKPASS) && user_askpass)
 
140
        return(sudo_askpass(prompt));
 
141
 
135
142
restart:
136
143
    signo = 0;
137
144
    pass = NULL;
147
154
     * Catch signals that would otherwise cause the user to end
148
155
     * up with echo turned off in the shell.
149
156
     */
 
157
    zero_bytes(&sa, sizeof(sa));
150
158
    sigemptyset(&sa.sa_mask);
151
159
    sa.sa_flags = SA_INTERRUPT; /* don't restart system calls */
152
160
    sa.sa_handler = handler;
169
177
#endif
170
178
        (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
171
179
    } else {
172
 
        memset(&term, 0, sizeof(term));
173
 
        memset(&oterm, 0, sizeof(oterm));
 
180
        zero_bytes(&term, sizeof(term));
 
181
        zero_bytes(&oterm, sizeof(oterm));
174
182
    }
175
183
 
176
184
    /* No output if we are already backgrounded. */
224
232
    return(pass);
225
233
}
226
234
 
 
235
/*
 
236
 * Fork a child and exec sudo-askpass to get the password from the user.
 
237
 */
 
238
static char *
 
239
sudo_askpass(prompt)
 
240
    const char *prompt;
 
241
{
 
242
    static char buf[SUDO_PASS_MAX + 1], *pass;
 
243
    sigaction_t sa, saved_sa_pipe;
 
244
    int pfd[2];
 
245
    pid_t pid;
 
246
 
 
247
    if (pipe(pfd) == -1)
 
248
        error(1, "unable to create pipe");
 
249
 
 
250
    if ((pid = fork()) == -1)
 
251
        error(1, "unable to fork");
 
252
 
 
253
    if (pid == 0) {
 
254
        /* child, point stdout to output side of the pipe and exec askpass */
 
255
        (void) dup2(pfd[1], STDOUT_FILENO);
 
256
        set_perms(PERM_FULL_USER);
 
257
        closefrom(STDERR_FILENO + 1);
 
258
        execl(user_askpass, user_askpass, prompt, (char *)NULL);
 
259
        warning("unable to run %s", user_askpass);
 
260
        _exit(255);
 
261
    }
 
262
 
 
263
    /* Ignore SIGPIPE in case child exits prematurely */
 
264
    zero_bytes(&sa, sizeof(sa));
 
265
    sigemptyset(&sa.sa_mask);
 
266
    sa.sa_flags = 0;
 
267
    sa.sa_handler = SIG_IGN;
 
268
    (void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
 
269
 
 
270
    /* Get response from child (askpass) and restore SIGPIPE handler */
 
271
    (void) close(pfd[1]);
 
272
    pass = getln(pfd[0], buf, sizeof(buf));
 
273
    (void) close(pfd[0]);
 
274
    (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
 
275
 
 
276
    return(pass);
 
277
}
 
278
 
227
279
static char *
228
280
getln(fd, buf, bufsiz)
229
281
    int fd;
230
282
    char *buf;
231
283
    size_t bufsiz;
232
284
{
233
 
    char c, *cp;
234
 
    ssize_t nr;
 
285
    ssize_t nr = -1;
 
286
    char *cp = buf;
 
287
    char c = '\0';
235
288
 
236
289
    if (bufsiz == 0) {
237
290
        errno = EINVAL;
238
291
        return(NULL);                   /* sanity */
239
292
    }
240
293
 
241
 
    cp = buf;
242
 
    nr = -1;
243
 
    while (--bufsiz && (nr = read(fd, &c, 1)) == 1 && c != '\n' && c != '\r')
 
294
    while (--bufsiz) {
 
295
        nr = read(fd, &c, 1);
 
296
        if (nr != 1 || c == '\n' || c == '\r')
 
297
            break;
244
298
        *cp++ = c;
 
299
    }
245
300
    *cp = '\0';
246
 
    return(nr == -1 ? NULL : buf);
 
301
 
 
302
    return(nr == 1 ? buf : NULL);
247
303
}
248
304
 
249
305
static void
253
309
    if (s != SIGALRM)
254
310
        signo = s;
255
311
}
 
312
 
 
313
int
 
314
tty_present()
 
315
{
 
316
    int fd;
 
317
 
 
318
    if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) != -1)
 
319
        close(fd);
 
320
    return(fd != -1);
 
321
}