~ubuntu-branches/ubuntu/natty/pam/natty-security

« back to all changes in this revision

Viewing changes to modules/pam_filter/pam_filter.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2009-08-26 00:40:14 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090826004014-qsd46mostuyljeqp
Tags: 1.1.0-1ubuntu1
* Merge from Debian, remaining changes:
  - debian/libpam-modules.postinst: Add PATH to /etc/environment if it's not
    present there or in /etc/security/pam_env.conf. (should send to Debian).
  - debian/libpam0g.postinst: only ask questions during update-manager when
    there are non-default services running.
  - debian/patches-applied/series: Ubuntu patches are as below ...
  - debian/patches-applied/ubuntu-no-error-if-missingok: add a new, magic
    module option 'missingok' which will suppress logging of errors by
    libpam if the module is not found.
  - debian/patches-applied/ubuntu-regression_fix_securetty: prompt for
    password on bad username.
  - debian/patches-applied/ubuntu-rlimit_nice_correction: Explicitly
    initialise RLIMIT_NICE rather than relying on the kernel limits.
  - Change Vcs-Bzr to point at the Ubuntu branch.
  - debian/local/common-password, debian/pam-configs/unix: switch from
    "md5" to "sha512" as password crypt default.
  - Make libpam-modules depend on base-files (>= 5.0.0ubuntu6), to ensure
    run-parts does the right thing in /etc/update-motd.d.
  - debian/patches-applied/pam_motd-legal-notice: display the contents of
    /etc/legal once, then set a flag in the user's homedir to prevent showing
    it again.
  - debian/local/common-{auth,account,password}.md5sums: include the
    Ubuntu-specific intrepid,jaunty md5sums for use during the
    common-session-noninteractive upgrade.
* Dropped changes, superseded upstream:
  - debian/patches-applied/ubuntu-fix_standard_types: Use standard u_int8_t
    type rather than __u8.
  - debian/patches-applied/ubuntu-user_defined_environment: Look at
    ~/.pam_environment too, with the same format as
    /etc/security/pam_env.conf.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * $Id: pam_filter.c,v 1.12 2005/12/12 14:45:00 ldv Exp $
 
2
 * $Id: pam_filter.c,v 1.14 2009/04/03 00:36:25 ldv Exp $
3
3
 *
4
4
 * written by Andrew Morgan <morgan@transmeta.com> with much help from
5
5
 * Richard Stevens' UNIX Network Programming book.
48
48
 
49
49
#include <stdarg.h>
50
50
 
51
 
#define TERMINAL_LEN 12
 
51
#define DEV_PTMX "/dev/ptmx"
52
52
 
53
53
static int
54
 
master (const pam_handle_t *pamh, char *terminal)
55
 
/*
56
 
 * try to open all of the terminals in sequence return first free one,
57
 
 * or -1
58
 
 */
 
54
master (void)
59
55
{
60
 
     const char ptys[] = "pqrs", *pty = ptys;
61
 
     const char hexs[] = "0123456789abcdef", *hex;
62
 
     struct stat tstat;
63
 
     int fd;
64
 
 
65
 
     strcpy(terminal, "/dev/pty??");
66
 
 
67
 
     while (*pty) {                   /* step through four types */
68
 
          terminal[8] = *pty++;
69
 
          terminal[9] = '0';
70
 
          if (stat(terminal,&tstat) < 0) {
71
 
               pam_syslog(pamh, LOG_WARNING,
72
 
                          "unknown pseudo terminal: %s", terminal);
73
 
               break;
74
 
          }
75
 
          for (hex = hexs; *hex; ) {  /* step through 16 of these */
76
 
               terminal[9] = *hex++;
77
 
               if ((fd = open(terminal, O_RDWR)) >= 0) {
78
 
                    return fd;
79
 
               }
80
 
          }
81
 
     }
82
 
 
83
 
     /* no terminal found */
84
 
 
85
 
     return -1;
 
56
    int fd;
 
57
 
 
58
    if ((fd = open(DEV_PTMX, O_RDWR)) >= 0) {
 
59
        return fd;
 
60
    }
 
61
 
 
62
    return -1;
86
63
}
87
64
 
88
65
static int process_args(pam_handle_t *pamh
279
256
            const char **evp, const char *filtername)
280
257
{
281
258
    int status=-1;
282
 
    char terminal[TERMINAL_LEN];
 
259
    char* terminal = NULL;
283
260
    struct termios stored_mode;           /* initial terminal mode settings */
284
261
    int fd[2], child=0, child2=0, aterminal;
285
262
 
299
276
 
300
277
        /* open the master pseudo terminal */
301
278
 
302
 
        fd[0] = master(pamh,terminal);
 
279
        fd[0] = master();
303
280
        if (fd[0] < 0) {
304
281
            pam_syslog(pamh, LOG_CRIT, "no master terminal");
305
282
            return PAM_AUTH_ERR;
392
369
                return PAM_ABORT;
393
370
            }
394
371
 
 
372
            /* grant slave terminal */
 
373
            if (grantpt (fd[0]) < 0) {
 
374
                pam_syslog(pamh, LOG_WARNING, "Cannot grant acccess to slave terminal");
 
375
                return PAM_ABORT;
 
376
            }
 
377
 
 
378
            /* unlock slave terminal */
 
379
            if (unlockpt (fd[0]) < 0) {
 
380
                pam_syslog(pamh, LOG_WARNING, "Cannot unlock slave terminal");
 
381
                return PAM_ABORT;
 
382
            }
 
383
 
395
384
            /* find slave's name */
396
 
            terminal[5] = 't';             /* want to open slave terminal */
 
385
            terminal = ptsname(fd[0]); /* returned value should not be freed */
 
386
 
 
387
            if (terminal == NULL) {
 
388
                pam_syslog(pamh, LOG_WARNING,
 
389
                           "Cannot get the name of the slave terminal: %m");
 
390
                return PAM_ABORT;
 
391
            }
 
392
 
397
393
            fd[1] = open(terminal, O_RDWR);
398
394
            close(fd[0]);      /* process is the child -- uses line fd[1] */
399
395
 
412
408
                close(fd[1]);
413
409
                return PAM_ABORT;
414
410
            }
415
 
 
416
411
        } else {
417
412
 
418
413
            /* nothing to do for a simple stream socket */
450
445
        return PAM_SUCCESS;
451
446
    }
452
447
 
453
 
    /*
454
 
     * process is the parent here. So we can close the application's
455
 
     * input/output
456
 
     */
457
 
 
458
 
    close(fd[1]);
459
 
 
460
448
    /* Clear out passwords... there is a security problem here in
461
449
     * that this process never executes pam_end.  Consequently, any
462
450
     * other sensitive data in this process is *not* explicitly
480
468
            pam_syslog(pamh, LOG_WARNING,
481
469
                       "unable to re-assign APPIN/OUT/ERR: %m");
482
470
            close(fd[0]);
483
 
            exit(1);
 
471
            _exit(1);
484
472
        }
485
473
 
486
474
        /* make sure that file descriptors survive 'exec's */
493
481
            close(APPIN_FILENO);
494
482
            close(APPOUT_FILENO);
495
483
            close(APPERR_FILENO);
496
 
            exit(1);
 
484
            _exit(1);
497
485
        }
498
486
 
499
487
        /* now the user input is read from the parent through filter */
503
491
        /* getting to here is an error */
504
492
 
505
493
        pam_syslog(pamh, LOG_ALERT, "filter: %s: %m", filtername);
 
494
        _exit(1);
506
495
 
507
496
    } else {           /* wait for either of the two children to exit */
508
497