~jamesodhunt/ubuntu/natty/gdm/fix-for-gdm-upstart-conf-lp706842

« back to all changes in this revision

Viewing changes to daemon/verify-pam.c

  • Committer: Bazaar Package Importer
  • Author(s): Ryan Murray
  • Date: 2002-04-04 01:13:31 UTC
  • Revision ID: james.westby@ubuntu.com-20020404011331-mxbagcpsovo5j0zm
Tags: upstream-2.2.5.5
ImportĀ upstreamĀ versionĀ 2.2.5.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* GDM - The Gnome Display Manager
 
2
 * Copyright (C) 1999, 2000 Martin K. Petersen <mkp@mkp.net>
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
17
 */
 
18
 
 
19
#include <config.h>
 
20
#include <gnome.h>
 
21
#include <grp.h>
 
22
#include <sys/types.h>
 
23
#include <sys/stat.h>
 
24
#include <syslog.h>
 
25
#include <security/pam_appl.h>
 
26
#include <pwd.h>
 
27
 
 
28
#include <vicious.h>
 
29
 
 
30
#include "gdm.h"
 
31
#include "misc.h"
 
32
#include "slave.h"
 
33
#include "verify.h"
 
34
#include "errorgui.h"
 
35
 
 
36
/* Configuration option variables */
 
37
extern gboolean GdmAllowRoot;
 
38
extern gboolean GdmAllowRemoteRoot;
 
39
extern gchar *GdmTimedLogin;
 
40
extern gchar *GdmUser;
 
41
extern gboolean GdmAllowRemoteAutoLogin;
 
42
extern gint GdmRetryDelay;
 
43
 
 
44
/* Evil, but this way these things are passed to the child session */
 
45
static pam_handle_t *pamh = NULL;
 
46
 
 
47
static GdmDisplay *cur_gdm_disp = NULL;
 
48
 
 
49
 
 
50
/* Internal PAM conversation function. Interfaces between the PAM
 
51
 * authentication system and the actual greeter program */
 
52
 
 
53
static gint 
 
54
gdm_verify_pam_conv (int num_msg, const struct pam_message **msg,
 
55
                     struct pam_response **resp,
 
56
                     void *appdata_ptr)
 
57
{
 
58
    gint replies = 0;
 
59
    gchar *s;
 
60
    struct pam_response *reply = NULL;
 
61
    
 
62
    reply = malloc (sizeof (struct pam_response) * num_msg);
 
63
    
 
64
    if (!reply) 
 
65
        return PAM_CONV_ERR;
 
66
 
 
67
    memset (reply, 0, sizeof (struct pam_response) * num_msg);
 
68
    
 
69
    for (replies = 0; replies < num_msg; replies++) {
 
70
        
 
71
        switch (msg[replies]->msg_style) {
 
72
            
 
73
        case PAM_PROMPT_ECHO_ON:
 
74
            /* PAM requested textual input with echo on */
 
75
            s = gdm_slave_greeter_ctl (GDM_PROMPT, _((gchar *) msg[replies]->msg));
 
76
            if (gdm_slave_greeter_check_interruption (s)) {
 
77
                    g_free (s);
 
78
                    free (reply);
 
79
                    return PAM_CONV_ERR;
 
80
            }
 
81
            reply[replies].resp_retcode = PAM_SUCCESS;
 
82
            reply[replies].resp = strdup (ve_sure_string (s));
 
83
            g_free (s);
 
84
            break;
 
85
            
 
86
        case PAM_PROMPT_ECHO_OFF:
 
87
            /* PAM requested textual input with echo off */
 
88
            s = gdm_slave_greeter_ctl (GDM_NOECHO, _((gchar *) msg[replies]->msg));
 
89
            if (gdm_slave_greeter_check_interruption (s)) {
 
90
                    g_free (s);
 
91
                    free (reply);
 
92
                    return PAM_CONV_ERR;
 
93
            }
 
94
            reply[replies].resp_retcode = PAM_SUCCESS;
 
95
            reply[replies].resp = strdup (ve_sure_string (s));
 
96
            g_free (s);
 
97
            break;
 
98
            
 
99
        case PAM_ERROR_MSG:
 
100
            /* PAM sent a message that should displayed to the user */
 
101
            gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG, _((gchar *) msg[replies]->msg));
 
102
            reply[replies].resp_retcode = PAM_SUCCESS;
 
103
            reply[replies].resp = NULL;
 
104
            break;
 
105
        case PAM_TEXT_INFO:
 
106
            /* PAM sent a message that should displayed to the user */
 
107
            gdm_slave_greeter_ctl_no_ret (GDM_MSG, _((gchar *) msg[replies]->msg));
 
108
            reply[replies].resp_retcode = PAM_SUCCESS;
 
109
            reply[replies].resp = NULL;
 
110
            break;
 
111
            
 
112
        default:
 
113
            /* PAM has been smoking serious crack */
 
114
            free (reply);
 
115
            return PAM_CONV_ERR;
 
116
        }
 
117
        
 
118
    }
 
119
 
 
120
    *resp = reply;
 
121
    return PAM_SUCCESS;
 
122
}
 
123
 
 
124
 
 
125
static struct pam_conv pamc = {
 
126
    &gdm_verify_pam_conv,
 
127
    NULL
 
128
};
 
129
 
 
130
static gint 
 
131
gdm_verify_standalone_pam_conv (int num_msg, const struct pam_message **msg,
 
132
                                struct pam_response **resp,
 
133
                                void *appdata_ptr)
 
134
{
 
135
        int replies = 0;
 
136
        char *s;
 
137
        struct pam_response *reply = NULL;
 
138
 
 
139
        reply = malloc (sizeof (struct pam_response) * num_msg);
 
140
 
 
141
        if (!reply) 
 
142
                return PAM_CONV_ERR;
 
143
 
 
144
        memset (reply, 0, sizeof (struct pam_response) * num_msg);
 
145
 
 
146
        for (replies = 0; replies < num_msg; replies++) {
 
147
 
 
148
                switch (msg[replies]->msg_style) {
 
149
 
 
150
                case PAM_PROMPT_ECHO_ON:
 
151
                        /* PAM requested textual input with echo on */
 
152
                        s = gdm_failsafe_question (cur_gdm_disp,
 
153
                                                   _((gchar *) msg[replies]->msg),
 
154
                                                   TRUE /* echo */);
 
155
                        reply[replies].resp_retcode = PAM_SUCCESS;
 
156
                        reply[replies].resp = strdup (ve_sure_string (s));
 
157
                        g_free (s);
 
158
                        break;
 
159
 
 
160
                case PAM_PROMPT_ECHO_OFF:
 
161
                        /* PAM requested textual input with echo off */
 
162
                        s = gdm_failsafe_question (cur_gdm_disp,
 
163
                                                   _((gchar *) msg[replies]->msg),
 
164
                                                   FALSE /* echo */);
 
165
                        reply[replies].resp_retcode = PAM_SUCCESS;
 
166
                        reply[replies].resp = strdup (ve_sure_string (s));
 
167
                        g_free (s);
 
168
                        break;
 
169
 
 
170
                case PAM_ERROR_MSG:
 
171
                        /* PAM sent a message that should displayed to the user */
 
172
                        gdm_error_box (cur_gdm_disp,
 
173
                                       GNOME_MESSAGE_BOX_ERROR,
 
174
                                       _((gchar *) msg[replies]->msg));
 
175
                        reply[replies].resp_retcode = PAM_SUCCESS;
 
176
                        reply[replies].resp = NULL;
 
177
                        break;
 
178
 
 
179
                case PAM_TEXT_INFO:
 
180
                        /* PAM sent a message that should displayed to the user */
 
181
                        gdm_error_box (cur_gdm_disp,
 
182
                                       GNOME_MESSAGE_BOX_INFO,
 
183
                                       _((gchar *) msg[replies]->msg));
 
184
                        reply[replies].resp_retcode = PAM_SUCCESS;
 
185
                        reply[replies].resp = NULL;
 
186
                        break;
 
187
 
 
188
                default:
 
189
                        /* PAM has been smoking serious crack */
 
190
                        free (reply);
 
191
                        return PAM_CONV_ERR;
 
192
                }
 
193
 
 
194
        }
 
195
 
 
196
        *resp = reply;
 
197
        return PAM_SUCCESS;
 
198
}
 
199
 
 
200
static struct pam_conv standalone_pamc = {
 
201
    &gdm_verify_standalone_pam_conv,
 
202
    NULL
 
203
};
 
204
 
 
205
/* Creates a pam handle for the auto login */
 
206
static gboolean
 
207
create_pamh (GdmDisplay *d,
 
208
             const char *service,
 
209
             const char *login,
 
210
             struct pam_conv *conv,
 
211
             const char *display,
 
212
             int *pamerr)
 
213
{
 
214
        if (login == NULL ||
 
215
            display == NULL) {
 
216
                gdm_error (_("Cannot setup pam handle with null login "
 
217
                             "and/or display"));
 
218
                return FALSE;
 
219
        }
 
220
 
 
221
        if (pamh != NULL) {
 
222
                gdm_error ("create_pamh: Stale pamh around, cleaning up");
 
223
                pam_end (pamh, PAM_SUCCESS);
 
224
        }
 
225
        pamh = NULL;
 
226
 
 
227
        /* Initialize a PAM session for the user */
 
228
        if ((*pamerr = pam_start (service, login, conv, &pamh)) != PAM_SUCCESS) {
 
229
                if (gdm_slave_should_complain ())
 
230
                        gdm_error (_("Can't find /etc/pam.d/%s!"), service);
 
231
                return FALSE;
 
232
        }
 
233
 
 
234
        /* Inform PAM of the user's tty */
 
235
        if ((*pamerr = pam_set_item (pamh, PAM_TTY, display)) != PAM_SUCCESS) {
 
236
                if (gdm_slave_should_complain ())
 
237
                        gdm_error (_("Can't set PAM_TTY=%s"), display);
 
238
                return FALSE;
 
239
        }
 
240
 
 
241
        /* gdm is requesting the login */
 
242
        if ((*pamerr = pam_set_item (pamh, PAM_RUSER, GdmUser)) != PAM_SUCCESS) {
 
243
                if (gdm_slave_should_complain ())
 
244
                        gdm_error (_("Can't set PAM_RUSER=%s"), GdmUser);
 
245
                return FALSE;
 
246
        }
 
247
 
 
248
        /* From the host of the display */
 
249
        if ((*pamerr = pam_set_item (pamh, PAM_RHOST,
 
250
                                     d->console ? "localhost" : d->hostname)) != PAM_SUCCESS) {
 
251
                if (gdm_slave_should_complain ())
 
252
                        gdm_error (_("Can't set PAM_RHOST=%s"),
 
253
                                   d->console ? "localhost" : d->hostname);
 
254
                return FALSE;
 
255
        }
 
256
 
 
257
        return TRUE;
 
258
}
 
259
 
 
260
 
 
261
/**
 
262
 * gdm_verify_user:
 
263
 * @username: Name of user or NULL if we should ask
 
264
 * @display: Name of display to register with the authentication system
 
265
 * @local: boolean if local
 
266
 *
 
267
 * Provides a communication layer between the operating system's
 
268
 * authentication functions and the gdmgreeter. 
 
269
 *
 
270
 * Returns the user's login on success and NULL on failure.
 
271
 */
 
272
 
 
273
gchar *
 
274
gdm_verify_user (GdmDisplay *d,
 
275
                 const char *username,
 
276
                 const gchar *display,
 
277
                 gboolean local) 
 
278
{
 
279
    gint pamerr = 0;
 
280
    gchar *login;
 
281
    struct passwd *pwent;
 
282
    gboolean error_msg_given = FALSE;
 
283
    gboolean credentials_set = FALSE;
 
284
    gboolean started_timer = FALSE;
 
285
    gchar *auth_errmsg;
 
286
 
 
287
    /* start the timer for timed logins */
 
288
    if ( ! ve_string_empty (GdmTimedLogin) &&
 
289
        (local || GdmAllowRemoteAutoLogin)) {
 
290
            gdm_slave_greeter_ctl_no_ret (GDM_STARTTIMER, "");
 
291
            started_timer = TRUE;
 
292
    }
 
293
 
 
294
    if (username == NULL) {
 
295
            /* Ask gdmgreeter for the user's login. Just for good measure */
 
296
            gdm_slave_greeter_ctl_no_ret (GDM_MSG, _("Please enter your username"));
 
297
            login = gdm_slave_greeter_ctl (GDM_LOGIN, _("Username:"));
 
298
            if (login == NULL ||
 
299
                gdm_slave_greeter_check_interruption (login)) {
 
300
                    if (started_timer)
 
301
                            gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
 
302
                    g_free (login);
 
303
                    return NULL;
 
304
            }
 
305
    } else {
 
306
            login = g_strdup (username);
 
307
    }
 
308
 
 
309
    cur_gdm_disp = d;
 
310
 
 
311
    /* Initialize a PAM session for the user */
 
312
    if ( ! create_pamh (d, "gdm", login, &pamc, display, &pamerr)) {
 
313
            if (started_timer)
 
314
                    gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
 
315
            goto pamerr;
 
316
    }
 
317
            
 
318
#ifdef PAM_FAIL_DELAY
 
319
    pam_fail_delay (pamh, GdmRetryDelay * 1000);
 
320
#endif /* PAM_FAIL_DELAY */
 
321
 
 
322
    /* Start authentication session */
 
323
    if ((pamerr = pam_authenticate (pamh, 0)) != PAM_SUCCESS) {
 
324
#ifndef PAM_FAIL_DELAY
 
325
            sleep (GdmRetryDelay);
 
326
#endif /* PAM_FAIL_DELAY */
 
327
            if (started_timer)
 
328
                    gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
 
329
            if (gdm_slave_should_complain ())
 
330
                    gdm_error (_("Couldn't authenticate user"));
 
331
            goto pamerr;
 
332
    }
 
333
 
 
334
    /* stop the timer for timed logins */
 
335
    if (started_timer)
 
336
            gdm_slave_greeter_ctl_no_ret (GDM_STOPTIMER, "");
 
337
    
 
338
    pwent = getpwnam (login);
 
339
    if ( ( ! GdmAllowRoot ||
 
340
          ( ! GdmAllowRemoteRoot && ! local) ) &&
 
341
        pwent != NULL &&
 
342
        pwent->pw_uid == 0) {
 
343
            gdm_error (_("Root login disallowed on display '%s'"),
 
344
                       display);
 
345
            gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
 
346
                                          _("\nThe system administrator"
 
347
                                            " is not allowed to login "
 
348
                                            "from this screen"));
 
349
            /*gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG,
 
350
              _("Root login disallowed"));*/
 
351
            error_msg_given = TRUE;
 
352
            goto pamerr;
 
353
    }
 
354
 
 
355
    /* Check if the user's account is healthy. */
 
356
    pamerr = pam_acct_mgmt (pamh, 0);
 
357
    switch (pamerr) {
 
358
    case PAM_SUCCESS :
 
359
        break;
 
360
    case PAM_NEW_AUTHTOK_REQD :
 
361
        if ((pamerr = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK)) != PAM_SUCCESS) {
 
362
            gdm_error (_("Authentication token change failed for user %s"), login);
 
363
            gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, 
 
364
                    _("\nThe change of the authentication token failed. "
 
365
                      "Please try again later or contact the system administrator."));
 
366
            error_msg_given = TRUE;
 
367
            goto pamerr;
 
368
        }
 
369
        break;
 
370
    case PAM_ACCT_EXPIRED :
 
371
        gdm_error (_("User %s no longer permitted to access the system"), login);
 
372
        gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, 
 
373
                _("\nThe system administrator has disabled your account."));
 
374
        error_msg_given = TRUE;
 
375
        goto pamerr;
 
376
    case PAM_PERM_DENIED :
 
377
        gdm_error (_("User %s not permitted to gain access at this time"), login);
 
378
        gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, 
 
379
                _("\nThe system administrator has disabled access to the system temporary."));
 
380
        error_msg_given = TRUE;
 
381
        goto pamerr;
 
382
    default :
 
383
        if (gdm_slave_should_complain ())
 
384
            gdm_error (_("Couldn't set acct. mgmt for %s"), login);
 
385
        goto pamerr;
 
386
    }
 
387
 
 
388
    pwent = getpwnam (login);
 
389
    if (/* paranoia */ pwent == NULL ||
 
390
        ! gdm_setup_gids (login, pwent->pw_gid)) {
 
391
            gdm_error (_("Cannot set user group for %s"), login);
 
392
            gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX,
 
393
                                          _("\nCannot set your user group, "
 
394
                                            "you will not be able to log in, "
 
395
                                            "please contact your system administrator."));
 
396
            goto pamerr;
 
397
    }
 
398
 
 
399
    /* Set credentials */
 
400
    pamerr = pam_setcred (pamh, PAM_ESTABLISH_CRED);
 
401
    if (pamerr != PAM_SUCCESS) {
 
402
        if (gdm_slave_should_complain ())
 
403
            gdm_error (_("Couldn't set credentials for %s"), login);
 
404
        goto pamerr;
 
405
    }
 
406
 
 
407
    credentials_set = TRUE;
 
408
 
 
409
    /* Register the session */
 
410
    pamerr = pam_open_session (pamh, 0);
 
411
    if (pamerr != PAM_SUCCESS) {
 
412
            if (gdm_slave_should_complain ())
 
413
                    gdm_error (_("Couldn't open session for %s"), login);
 
414
            goto pamerr;
 
415
    }
 
416
 
 
417
    /* Workaround to avoid gdm messages being logged as PAM_pwdb */
 
418
    closelog ();
 
419
    openlog ("gdm", LOG_PID, LOG_DAEMON);
 
420
 
 
421
    cur_gdm_disp = NULL;
 
422
    
 
423
    return login;
 
424
    
 
425
 pamerr:
 
426
    
 
427
    /* The verbose authentication is turned on, output the error
 
428
     * message from the PAM subsystem */
 
429
    if ( ! error_msg_given &&
 
430
        gdm_slave_should_complain ()) {
 
431
            /* I'm not sure yet if I should display this message for any other issues - heeten */
 
432
            if (pamerr == PAM_AUTH_ERR ||
 
433
                pamerr == PAM_USER_UNKNOWN) {
 
434
                    /* FIXME: Hmm, how are we sure that the login is username
 
435
                     * and password.  That is the most common case but not
 
436
                     * neccessairly true, this message needs to be changed
 
437
                     * to allow for such cases */
 
438
                    auth_errmsg = g_strdup_printf
 
439
                            (_("\nIncorrect username or password.  "
 
440
                               "Letters must be typed in the correct case.  "  
 
441
                               "Please be sure the Caps Lock key is not enabled"));
 
442
                    gdm_slave_greeter_ctl_no_ret (GDM_ERRBOX, auth_errmsg);
 
443
                    g_free (auth_errmsg);
 
444
            } else {
 
445
                    gdm_slave_greeter_ctl_no_ret (GDM_ERRDLG, _("Authentication failed"));
 
446
            }
 
447
    }
 
448
 
 
449
    if (pamh != NULL) {
 
450
            /* Throw away the credentials */
 
451
            if (credentials_set)
 
452
                    pam_setcred (pamh, PAM_DELETE_CRED);
 
453
            pam_end (pamh, pamerr);
 
454
    }
 
455
    pamh = NULL;
 
456
    
 
457
    /* Workaround to avoid gdm messages being logged as PAM_pwdb */
 
458
    closelog ();
 
459
    openlog ("gdm", LOG_PID, LOG_DAEMON);
 
460
 
 
461
    g_free (login);
 
462
    
 
463
    cur_gdm_disp = NULL;
 
464
 
 
465
    return NULL;
 
466
}
 
467
 
 
468
/**
 
469
 * gdm_verify_setup_user:
 
470
 * @login: The name of the user
 
471
 * @display: The name of the display
 
472
 *
 
473
 * This is used for auto loging in.  This just sets up the login
 
474
 * session for this user
 
475
 */
 
476
 
 
477
gboolean
 
478
gdm_verify_setup_user (GdmDisplay *d, const gchar *login, const gchar *display) 
 
479
{
 
480
    gint pamerr = 0;
 
481
    struct passwd *pwent;
 
482
 
 
483
    if (login == NULL)
 
484
            return FALSE;
 
485
 
 
486
    cur_gdm_disp = d;
 
487
 
 
488
    /* Initialize a PAM session for the user */
 
489
    if ( ! create_pamh (d, "gdm-autologin", login, &standalone_pamc,
 
490
                        display, &pamerr)) {
 
491
            goto setup_pamerr;
 
492
    }
 
493
 
 
494
    /* Start authentication session */
 
495
    if ((pamerr = pam_authenticate (pamh, 0)) != PAM_SUCCESS) {
 
496
            if (gdm_slave_should_complain ()) {
 
497
                    gdm_error (_("Couldn't authenticate user"));
 
498
                    gdm_error_box (cur_gdm_disp,
 
499
                                   GNOME_MESSAGE_BOX_ERROR,
 
500
                                   _("Authentication failed"));
 
501
            }
 
502
            goto setup_pamerr;
 
503
    }
 
504
 
 
505
    /* Check if the user's account is healthy. */
 
506
    pamerr = pam_acct_mgmt (pamh, 0);
 
507
    switch (pamerr) {
 
508
    case PAM_SUCCESS :
 
509
        break;
 
510
    case PAM_NEW_AUTHTOK_REQD :
 
511
        /* XXX: this is for automatic and timed logins,
 
512
         * we shouldn't be asking for new pw since we never
 
513
         * authenticated the user.  I suppose just ignoring
 
514
         * this would be OK */
 
515
        /*
 
516
        if ((pamerr = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK)) != PAM_SUCCESS) {
 
517
            gdm_error (_("Authentication token change failed for user %s"), login);
 
518
            gdm_error_box (cur_gdm_disp,
 
519
                           GNOME_MESSAGE_BOX_ERROR,
 
520
                    _("\nThe change of the authentication token failed. "
 
521
                      "Please try again later or cantact the system administrator."));
 
522
            goto setup_pamerr;
 
523
        }
 
524
        */
 
525
        break;
 
526
    case PAM_ACCT_EXPIRED :
 
527
        gdm_error (_("User %s no longer permitted to access the system"), login);
 
528
        gdm_error_box (cur_gdm_disp,
 
529
                       GNOME_MESSAGE_BOX_ERROR,
 
530
                       _("\nThe system administrator has disabled your account."));
 
531
        goto setup_pamerr;
 
532
    case PAM_PERM_DENIED :
 
533
        gdm_error (_("User %s not permitted to gain access at this time"), login);
 
534
        gdm_error_box (cur_gdm_disp,
 
535
                       GNOME_MESSAGE_BOX_ERROR,
 
536
                       _("\nThe system administrator has disabled your access to the system temporary."));
 
537
        goto setup_pamerr;
 
538
    default :
 
539
        if (gdm_slave_should_complain ())
 
540
            gdm_error (_("Couldn't set acct. mgmt for %s"), login);
 
541
        goto setup_pamerr;
 
542
    }
 
543
 
 
544
    pwent = getpwnam (login);
 
545
    if (/* paranoia */ pwent == NULL ||
 
546
        ! gdm_setup_gids (login, pwent->pw_gid)) {
 
547
            gdm_error (_("Cannot set user group for %s"), login);
 
548
            gdm_error_box (cur_gdm_disp,
 
549
                           GNOME_MESSAGE_BOX_ERROR,
 
550
                           _("\nCannot set your user group, "
 
551
                             "you will not be able to log in, "
 
552
                             "please contact your system administrator."));
 
553
            goto setup_pamerr;
 
554
    }
 
555
 
 
556
    /* Register the session */
 
557
    pamerr = pam_open_session (pamh, 0);
 
558
    if (pamerr != PAM_SUCCESS) {
 
559
            if (gdm_slave_should_complain ())
 
560
                    gdm_error (_("Couldn't open session for %s"), login);
 
561
            goto setup_pamerr;
 
562
    }
 
563
 
 
564
    /* Set credentials */
 
565
    pamerr = pam_setcred (pamh, PAM_ESTABLISH_CRED);
 
566
    if (pamerr != PAM_SUCCESS) {
 
567
            if (gdm_slave_should_complain ())
 
568
                    gdm_error (_("Couldn't set credentials for %s"), login);
 
569
            goto setup_pamerr;
 
570
    }
 
571
 
 
572
    /* Workaround to avoid gdm messages being logged as PAM_pwdb */
 
573
    closelog ();
 
574
    openlog ("gdm", LOG_PID, LOG_DAEMON);
 
575
 
 
576
    cur_gdm_disp = NULL;
 
577
    
 
578
    return TRUE;
 
579
    
 
580
 setup_pamerr:
 
581
    
 
582
    if (pamh != NULL)
 
583
            pam_end (pamh, pamerr);
 
584
    pamh = NULL;
 
585
    
 
586
    /* Workaround to avoid gdm messages being logged as PAM_pwdb */
 
587
    closelog ();
 
588
    openlog ("gdm", LOG_PID, LOG_DAEMON);
 
589
 
 
590
    cur_gdm_disp = NULL;
 
591
 
 
592
    return FALSE;
 
593
}
 
594
 
 
595
 
 
596
/**
 
597
 * gdm_verify_cleanup:
 
598
 *
 
599
 * Unregister the user's session
 
600
 */
 
601
 
 
602
void 
 
603
gdm_verify_cleanup (GdmDisplay *d)
 
604
{
 
605
        gid_t groups[1] = { 0 };
 
606
        cur_gdm_disp = d;
 
607
 
 
608
        if (pamh != NULL) {
 
609
                gint pamerr;
 
610
 
 
611
                /* Close the users session */
 
612
                pamerr = pam_close_session (pamh, 0);
 
613
 
 
614
                /* Throw away the credentials */
 
615
                pamerr = pam_setcred (pamh, PAM_DELETE_CRED);
 
616
 
 
617
                if (pamh != NULL)
 
618
                        pam_end (pamh, pamerr);
 
619
                pamh = NULL;
 
620
 
 
621
                /* Workaround to avoid gdm messages being logged as PAM_pwdb */
 
622
                closelog ();
 
623
                openlog ("gdm", LOG_PID, LOG_DAEMON);
 
624
        }
 
625
 
 
626
        /* Clear the group setup */
 
627
        setgid (0);
 
628
        /* this will get rid of any suplementary groups etc... */
 
629
        setgroups (1, groups);
 
630
 
 
631
        cur_gdm_disp = NULL;
 
632
}
 
633
 
 
634
 
 
635
/**
 
636
 * gdm_verify_check:
 
637
 *
 
638
 * Check that the authentication system is correctly configured.
 
639
 * Not very smart, perhaps we should just whack this.
 
640
 *
 
641
 * Aborts daemon on error 
 
642
 */
 
643
 
 
644
void
 
645
gdm_verify_check (void)
 
646
{
 
647
        /* FIXME: this is somewhat evil */
 
648
        if (access (PAM_PREFIX "/pam.d/gdm", F_OK) != 0 &&
 
649
            access ("/etc/pam.d/gdm", F_OK) != 0 &&
 
650
            access (PAM_PREFIX "/pam.conf", F_OK) != 0 &&
 
651
            access ("/etc/pam.conf", F_OK) != 0) {
 
652
                char *s;
 
653
                s = g_strdup_printf (_("Can't find PAM configuration file for gdm. "
 
654
                                       "I've tried %s, %s, %s and %s"),
 
655
                                     PAM_PREFIX "/pam.d/gdm",
 
656
                                     "/etc/pam.d/gdm",
 
657
                                     PAM_PREFIX "/pam.conf",
 
658
                                     "/etc/pam.conf");
 
659
                gdm_text_message_dialog (s);
 
660
                gdm_fail ("gdm_verify_check: %s", s);
 
661
                g_free (s); /* I'm an anal wanker */
 
662
        }
 
663
}
 
664
 
 
665
/* used in pam */
 
666
gboolean
 
667
gdm_verify_setup_env (GdmDisplay *d)
 
668
{
 
669
        gchar **pamenv;
 
670
 
 
671
        if (pamh == NULL)
 
672
                return FALSE;
 
673
 
 
674
        /* Migrate any PAM env. variables to the user's environment */
 
675
        /* This leaks, oh well */
 
676
        if ((pamenv = pam_getenvlist (pamh))) {
 
677
                gint i;
 
678
 
 
679
                for (i = 0 ; pamenv[i] ; i++) {
 
680
                        putenv (g_strdup (pamenv[i]));
 
681
                }
 
682
        }
 
683
 
 
684
        return TRUE;
 
685
}
 
686
 
 
687
/* EOF */