~ubuntu-branches/ubuntu/precise/xdm/precise

« back to all changes in this revision

Viewing changes to greeter/greet.c

  • Committer: Bazaar Package Importer
  • Author(s): Artur Rona
  • Date: 2011-01-30 00:53:09 UTC
  • mfrom: (9.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20110130005309-30mjjyk7div7d494
Tags: 1:1.1.10-3ubuntu1
* Merge from debian unstable.  Remaining changes: (LP: #682196)
  - debian/{rules, xdm.install, local/ubuntu*}:
    + Add Ubuntu graphics and configure xdm to use them by default.
  - debian/patches/ubuntu_no_whiteglass.diff: Don't hardcode
    the default Xcursor theme to whiteglass. Use the Ubuntu
    default x-cursor-theme instead.
* debian/patches/ftbfs_binutils-gold.diff: Fix FTBFS with binutils-gold
  and ld --as-needed. (Closes: #556694)
* Dropped changes, no longer applicable:
  - debian/{xdm.postinst.in, xdm.postrm.in, xdm.preinst.in}

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Xorg: greet.c,v 1.4 2001/02/09 02:05:41 xorgcvs Exp $ */
2
 
/* $XdotOrg: app/xdm/greeter/greet.c,v 1.5 2006/06/03 01:13:44 alanc Exp $ */
3
1
/*
4
2
 
5
3
Copyright 1988, 1998  The Open Group
27
25
from The Open Group.
28
26
 
29
27
*/
30
 
/* Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 
28
/*
 
29
 * Copyright © 2006 Sun Microsystems, Inc.  All rights reserved.
31
30
 *
32
31
 * Permission is hereby granted, free of charge, to any person obtaining a
33
 
 * copy of this software and associated documentation files (the
34
 
 * "Software"), to deal in the Software without restriction, including
35
 
 * without limitation the rights to use, copy, modify, merge, publish,
36
 
 * distribute, and/or sell copies of the Software, and to permit persons
37
 
 * to whom the Software is furnished to do so, provided that the above
38
 
 * copyright notice(s) and this permission notice appear in all copies of
39
 
 * the Software and that both the above copyright notice(s) and this
40
 
 * permission notice appear in supporting documentation.
41
 
 *
42
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
43
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
45
 
 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
46
 
 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
47
 
 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
48
 
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
49
 
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
50
 
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51
 
 *
52
 
 * Except as contained in this notice, the name of a copyright holder
53
 
 * shall not be used in advertising or otherwise to promote the sale, use
54
 
 * or other dealings in this Software without prior written authorization
55
 
 * of the copyright holder.
 
32
 * copy of this software and associated documentation files (the "Software"),
 
33
 * to deal in the Software without restriction, including without limitation
 
34
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
35
 * and/or sell copies of the Software, and to permit persons to whom the
 
36
 * Software is furnished to do so, subject to the following conditions:
 
37
 *
 
38
 * The above copyright notice and this permission notice (including the next
 
39
 * paragraph) shall be included in all copies or substantial portions of the
 
40
 * Software.
 
41
 *
 
42
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
43
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
44
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
45
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
46
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
47
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
48
 * DEALINGS IN THE SOFTWARE.
56
49
 */
57
50
 
58
 
/* $XFree86: xc/programs/xdm/greeter/greet.c,v 3.16tsi Exp $ */
59
51
 
60
52
/*
61
53
 * xdm - display manager daemon
75
67
#include <X11/XKBlib.h>
76
68
 
77
69
#ifdef USE_XINERAMA
78
 
#include <X11/extensions/Xinerama.h>
 
70
# include <X11/extensions/Xinerama.h>
79
71
#endif
80
72
 
81
73
#include "dm.h"
82
74
#include "dm_error.h"
83
75
#include "greet.h"
84
 
#include "Login.h"
 
76
#include "LoginP.h"
85
77
 
86
 
#ifdef __OpenBSD__
87
 
#include <syslog.h>
 
78
#if defined(HAVE_OPENLOG) && defined(HAVE_SYSLOG_H)
 
79
# define USE_SYSLOG
 
80
# include <syslog.h>
 
81
# ifndef LOG_AUTHPRIV
 
82
#  define LOG_AUTHPRIV LOG_AUTH
 
83
# endif
 
84
# ifndef LOG_PID
 
85
#  define LOG_PID 0
 
86
# endif
88
87
#endif
89
88
 
 
89
#include <string.h>
 
90
 
90
91
#if defined(SECURE_RPC) && defined(sun)
91
92
/* Go figure, there's no getdomainname() prototype available */
92
93
extern int getdomainname(char *name, size_t len);
99
100
 
100
101
int     (*__xdm_PingServer)(struct display *d, Display *alternateDpy) = NULL;
101
102
void    (*__xdm_SessionPingFailed)(struct display *d) = NULL;
102
 
void    (*__xdm_Debug)(char * fmt, ...) = NULL;
 
103
void    (*__xdm_Debug)(const char * fmt, ...) = NULL;
103
104
void    (*__xdm_RegisterCloseOnFork)(int fd) = NULL;
104
105
void    (*__xdm_SecureDisplay)(struct display *d, Display *dpy) = NULL;
105
106
void    (*__xdm_UnsecureDisplay)(struct display *d, Display *dpy) = NULL;
106
107
void    (*__xdm_ClearCloseOnFork)(int fd) = NULL;
107
108
void    (*__xdm_SetupDisplay)(struct display *d) = NULL;
108
 
void    (*__xdm_LogError)(char * fmt, ...) = NULL;
 
109
void    (*__xdm_LogError)(const char * fmt, ...) = NULL;
109
110
void    (*__xdm_SessionExit)(struct display *d, int status, int removeAuth) = NULL;
110
111
void    (*__xdm_DeleteXloginResources)(struct display *d, Display *dpy) = NULL;
111
112
int     (*__xdm_source)(char **environ, char *file) = NULL;
115
116
char    **(*__xdm_parseArgs)(char **argv, char *string) = NULL;
116
117
void    (*__xdm_printEnv)(char **e) = NULL;
117
118
char    **(*__xdm_systemEnv)(struct display *d, char *user, char *home) = NULL;
118
 
void    (*__xdm_LogOutOfMem)(char * fmt, ...) = NULL;
 
119
void    (*__xdm_LogOutOfMem)(const char * fmt, ...) = NULL;
119
120
void    (*__xdm_setgrent)(void) = NULL;
120
121
struct group    *(*__xdm_getgrent)(void) = NULL;
121
122
void    (*__xdm_endgrent)(void) = NULL;
122
 
#ifdef USESHADOW
 
123
# ifdef USESHADOW
123
124
struct spwd   *(*__xdm_getspnam)(GETSPNAM_ARGS) = NULL;
124
 
# ifndef QNX4
 
125
#  ifndef QNX4
125
126
void   (*__xdm_endspent)(void) = NULL;
126
 
# endif /* QNX4 doesn't use endspent */
127
 
#endif
 
127
#  endif /* QNX4 doesn't use endspent */
 
128
# endif
128
129
struct passwd   *(*__xdm_getpwnam)(GETPWNAM_ARGS) = NULL;
129
 
#if defined(linux) || defined(__GLIBC__)
 
130
# if defined(linux) || defined(__GLIBC__)
130
131
void   (*__xdm_endpwent)(void) = NULL;
131
 
#endif
 
132
# endif
132
133
char     *(*__xdm_crypt)(CRYPT_ARGS) = NULL;
133
 
#ifdef USE_PAM
 
134
# ifdef USE_PAM
134
135
pam_handle_t **(*__xdm_thepamhp)(void) = NULL;
135
 
#endif
 
136
# endif
136
137
 
137
138
#endif
138
139
 
139
140
#ifdef SECURE_RPC
140
 
#include <rpc/rpc.h>
141
 
#include <rpc/key_prot.h>
 
141
# include <rpc/rpc.h>
 
142
# include <rpc/key_prot.h>
142
143
#endif
143
144
 
144
145
#ifdef K5AUTH
145
 
#include <krb5/krb5.h>
 
146
# include <krb5/krb5.h>
146
147
#endif
147
148
 
148
149
extern Display  *dpy;
158
159
 
159
160
#ifdef USE_PAM
160
161
static int pamconv(int num_msg,
161
 
#ifndef sun
 
162
# ifndef sun
162
163
                   const
163
 
#endif             
 
164
# endif
164
165
                   struct pam_message **msg,
165
166
                   struct pam_response **response, void *appdata_ptr);
166
167
 
341
342
        XSetAccessControl (dpy, DisableAccess);
342
343
    }
343
344
    XtDestroyWidget (toplevel);
 
345
    toplevel = NULL;
 
346
    login = NULL; /* child of toplevel, which we just destroyed */
344
347
    ClearCloseOnFork (XConnectionNumber (dpy));
345
348
    XCloseDisplay (dpy);
346
349
    Debug ("Greet connection closed\n");
378
381
#ifndef USE_PAM
379
382
        char *ptr;
380
383
        unsigned int c,state = WHITESPACE;
381
 
 
 
384
 
382
385
        /*
383
386
         * Process the name string to get rid of white spaces.
384
387
         */
408
411
static void
409
412
FailedLogin (struct display *d, struct greet_info *greet)
410
413
{
411
 
#ifdef __OpenBSD__
412
 
    syslog(LOG_NOTICE, "LOGIN FAILURE ON %s",
413
 
           d->name);
 
414
#ifdef USE_SYSLOG
 
415
    const char *username = greet->name;
 
416
 
 
417
    if (username == NULL)
 
418
        username = "username unavailable";
 
419
 
414
420
    syslog(LOG_AUTHPRIV|LOG_NOTICE,
415
421
           "LOGIN FAILURE ON %s, %s",
416
 
           d->name, greet->name);
 
422
           d->name, username);
417
423
#endif
418
424
    DrawFail (login);
419
425
#ifndef USE_PAM
458
464
    __xdm_setgrent = dlfuncs->_setgrent;
459
465
    __xdm_getgrent = dlfuncs->_getgrent;
460
466
    __xdm_endgrent = dlfuncs->_endgrent;
461
 
#ifdef USESHADOW
 
467
# ifdef USESHADOW
462
468
    __xdm_getspnam = dlfuncs->_getspnam;
463
 
# ifndef QNX4
 
469
#  ifndef QNX4
464
470
    __xdm_endspent = dlfuncs->_endspent;
465
 
# endif /* QNX4 doesn't use endspent */
466
 
#endif
 
471
#  endif /* QNX4 doesn't use endspent */
 
472
# endif
467
473
    __xdm_getpwnam = dlfuncs->_getpwnam;
468
 
#if defined(linux) || defined(__GLIBC__)
 
474
# if defined(linux) || defined(__GLIBC__)
469
475
    __xdm_endpwent = dlfuncs->_endpwent;
470
 
#endif
 
476
# endif
471
477
    __xdm_crypt = dlfuncs->_crypt;
472
 
#ifdef USE_PAM
 
478
# ifdef USE_PAM
473
479
    __xdm_thepamhp = dlfuncs->_thepamhp;
474
 
#endif
 
480
# endif
475
481
#endif
476
482
 
477
483
    *dpy = InitGreet (d);
485
491
        LogError ("Cannot reopen display %s for greet window\n", d->name);
486
492
        exit (RESERVER_DISPLAY);
487
493
    }
488
 
#ifdef __OpenBSD__
489
 
    openlog("xdm", LOG_ODELAY, LOG_AUTH);
490
 
#endif
491
494
 
492
495
    for (;;) {
493
496
#ifdef USE_PAM
499
502
        struct myconv_data pcd          = { d, greet, NULL };
500
503
        struct pam_conv   pc            = { pamconv, &pcd };
501
504
        const char *      pam_fname;
502
 
        char *            username;
 
505
        char *            username      = NULL;
503
506
        const char *      login_prompt;
504
507
 
505
508
 
506
 
        SetPrompt(login, 0, NULL, LOGIN_PROMPT_NOT_SHOWN, False);
 
509
        SetPrompt(login, LOGIN_PROMPT_USERNAME, NULL, LOGIN_PROMPT_NOT_SHOWN, False);
507
510
        login_prompt  = GetPrompt(login, LOGIN_PROMPT_USERNAME);
508
 
        SetPrompt(login, 1, NULL, LOGIN_PROMPT_NOT_SHOWN, False);
509
 
        
510
 
#define RUN_AND_CHECK_PAM_ERROR(function, args)                 \
 
511
        SetPrompt(login, LOGIN_PROMPT_PASSWORD, NULL, LOGIN_PROMPT_NOT_SHOWN, False);
 
512
 
 
513
# define RUN_AND_CHECK_PAM_ERROR(function, args)                        \
511
514
            do {                                                \
512
515
                pam_error = function args;                      \
513
516
                if (pam_error != PAM_SUCCESS) {                 \
514
517
                    PAM_ERROR_PRINT(#function, *pamhp);         \
515
518
                    goto pam_done;                              \
516
519
                }                                               \
517
 
            } while (0) 
518
 
            
 
520
            } while (0)
 
521
 
519
522
 
520
523
        RUN_AND_CHECK_PAM_ERROR(pam_start,
521
524
                                ("xdm", NULL, &pc, pamhp));
533
536
                LogOutOfMem("GreetUser");
534
537
            } else {
535
538
                char *colon = strrchr(hostname, ':');
536
 
                
 
539
 
537
540
                if (colon != NULL)
538
541
                    *colon = '\0';
539
 
            
 
542
 
540
543
                RUN_AND_CHECK_PAM_ERROR(pam_set_item,
541
544
                                        (*pamhp, PAM_RHOST, hostname));
542
545
                free(hostname);
543
546
            }
544
547
        } else
545
548
            RUN_AND_CHECK_PAM_ERROR(pam_set_item, (*pamhp, PAM_TTY, d->name));
546
 
 
 
549
 
547
550
        if (!greet->allow_null_passwd) {
548
551
            pam_flags |= PAM_DISALLOW_NULL_AUTHTOK;
549
552
        }
550
553
        RUN_AND_CHECK_PAM_ERROR(pam_authenticate,
551
554
                                (*pamhp, pam_flags));
552
 
                                
 
555
 
553
556
        /* handle expired passwords */
554
557
        pam_error = pam_acct_mgmt(*pamhp, pam_flags);
555
558
        pam_fname = "pam_acct_mgmt";
565
568
            PAM_ERROR_PRINT(pam_fname, *pamhp);
566
569
            goto pam_done;
567
570
        }
568
 
        
 
571
 
569
572
        RUN_AND_CHECK_PAM_ERROR(pam_setcred,
570
573
                                (*pamhp, 0));
571
574
        RUN_AND_CHECK_PAM_ERROR(pam_get_item,
575
578
            greet->name = username;
576
579
            greet->password = NULL;
577
580
        }
578
 
            
 
581
 
579
582
      pam_done:
580
583
        if (code != 0)
581
584
        {
587
590
            SetValue (login, 1, NULL);
588
591
            break;
589
592
        } else {
 
593
            /* Try to fill in username for failed login error log */
 
594
            if (greet->name == NULL) {
 
595
                if (username == NULL) {
 
596
                    RUN_AND_CHECK_PAM_ERROR(pam_get_item,
 
597
                                            (*pamhp, PAM_USER,
 
598
                                             (void *) &username));
 
599
                }
 
600
                greet->name = username;
 
601
            }
 
602
            FailedLogin (d, greet);
590
603
            RUN_AND_CHECK_PAM_ERROR(pam_end,
591
604
                                    (*pamhp, pam_error));
592
 
            FailedLogin (d, greet);
593
605
        }
594
606
#else /* not PAM */
595
607
        /*
635
647
            XHostAddress        addr;
636
648
            char                netname[MAXNETNAMELEN+1];
637
649
            char                domainname[MAXNETNAMELEN+1];
638
 
    
 
650
 
639
651
            getdomainname(domainname, sizeof domainname);
640
652
            user2netname (netname, verify->uid, domainname);
641
653
            addr.family = FamilyNetname;
659
671
            d->authorizations[i] =
660
672
                Krb5GetAuthFor(14, "MIT-KERBEROS-5", d->name);
661
673
            SaveServerAuthorizations (d, d->authorizations, d->authNum);
662
 
        } 
 
674
        }
663
675
#endif
664
676
    }
665
677
 
669
681
 
670
682
#ifdef USE_PAM
671
683
static int pamconv(int num_msg,
672
 
#ifndef sun
 
684
# ifndef sun
673
685
                   const
674
 
#endif             
 
686
# endif
675
687
                   struct pam_message **msg,
676
688
                   struct pam_response **response, void *appdata_ptr)
677
689
{
682
694
        = { "<invalid pam msg style>",
683
695
            "PAM_PROMPT_ECHO_OFF", "PAM_PROMPT_ECHO_ON",
684
696
            "PAM_ERROR_MSG", "PAM_TEXT_INFO" } ;
685
 
    
 
697
 
686
698
    struct pam_message      *m;
687
699
    struct pam_response     *r;
688
700
 
689
701
    struct myconv_data      *d = (struct myconv_data *) appdata_ptr;
690
702
 
691
703
    pam_handle_t            **pamhp = thepamhp();
692
 
    
 
704
 
693
705
    *response = calloc(num_msg, sizeof (struct pam_response));
694
706
    if (*response == NULL)
695
707
        return (PAM_BUF_ERR);
696
708
 
697
 
    m = *msg;
 
709
    m = (struct pam_message *)*msg;
698
710
    r = *response;
699
711
 
 
712
    if (login == NULL) {
 
713
        status = PAM_CONV_ERR;
 
714
        goto pam_error;
 
715
    }
 
716
 
700
717
    for (i = 0; i < num_msg; i++ , m++ , r++) {
701
718
        char *username;
702
719
        int promptId = 0;
708
725
                      NULL, LOGIN_TEXT_INFO, False);
709
726
            SetValue(login, LOGIN_PROMPT_USERNAME, username);
710
727
            promptId = 1;
711
 
        } 
712
 
        
 
728
        }
 
729
 
713
730
        Debug("pam_msg: %s (%d): '%s'\n",
714
731
              ((m->msg_style > 0) && (m->msg_style <= 4)) ?
715
732
               pam_msg_styles[m->msg_style] : pam_msg_styles[0],
724
741
              SetPrompt (login, promptId, m->msg, LOGIN_TEXT_INFO, True);
725
742
              SetValue (login, promptId, NULL);
726
743
              break;
727
 
              
 
744
 
728
745
          case PAM_PROMPT_ECHO_ON:
729
746
              pStyle = LOGIN_PROMPT_ECHO_ON;
730
747
              /* FALLTHROUGH */
750
767
              LogError("Unknown PAM msg_style: %d\n", m->msg_style);
751
768
        }
752
769
    }
753
 
  pam_error:    
 
770
  pam_error:
754
771
    if (status != PAM_SUCCESS) {
755
772
        /* free responses */
756
773
        r = *response;