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

« back to all changes in this revision

Viewing changes to modules/pam_selinux/pam_selinux.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:
2
2
 * A module for Linux-PAM that will set the default security context after login
3
3
 * via PAM.
4
4
 *
5
 
 * Copyright (c) 2003 Red Hat, Inc.
 
5
 * Copyright (c) 2003-2008 Red Hat, Inc.
6
6
 * Written by Dan Walsh <dwalsh@redhat.com>
 
7
 * Additional improvements by Tomas Mraz <tmraz@redhat.com>
7
8
 *
8
9
 * Redistribution and use in source and binary forms, with or without
9
10
 * modification, are permitted provided that the following conditions
138
139
 */
139
140
static int
140
141
query_response (pam_handle_t *pamh, const char *text, const char *def,
141
 
                char **responses, int debug)
 
142
                char **response, int debug)
142
143
{
143
144
  int rc;
144
145
  if (def) 
145
 
    rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, responses, "%s [%s] ", text, def);
 
146
    rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, response, "%s [%s] ", text, def);
146
147
  else
147
 
    rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, responses, "%s ", text);
148
 
  if (debug)
149
 
    pam_syslog(pamh, LOG_NOTICE, "%s %s", text, responses[0]);
 
148
    rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, response, "%s ", text);
 
149
 
 
150
  if (*response == NULL) {
 
151
    rc = PAM_CONV_ERR;
 
152
  }
 
153
  
 
154
  if (rc != PAM_SUCCESS) {
 
155
    pam_syslog(pamh, LOG_WARNING, "No response to query: %s", text);
 
156
  } else  if (debug)
 
157
    pam_syslog(pamh, LOG_NOTICE, "%s %s", text, *response);
150
158
  return rc;
151
159
}
152
160
 
157
165
  context_t new_context;
158
166
  int mls_enabled = is_selinux_mls_enabled();
159
167
  char *type=NULL;
160
 
  char *responses=NULL;
 
168
  char *response=NULL;
161
169
 
162
170
  while (1) {
163
 
    query_response(pamh,
164
 
                   _("Would you like to enter a security context? [N] "), NULL, 
165
 
                   &responses,debug);
166
 
    if ((responses[0] == 'y') || (responses[0] == 'Y'))
 
171
    if (query_response(pamh,
 
172
                   _("Would you like to enter a security context? [N] "), NULL,
 
173
                   &response, debug) != PAM_SUCCESS)
 
174
        return NULL;
 
175
 
 
176
    if ((response[0] == 'y') || (response[0] == 'Y'))
167
177
      {
168
178
        if (mls_enabled)
169
179
          new_context = context_new ("user:role:type:level");
176
186
        if (context_user_set (new_context, user))
177
187
              goto fail_set;
178
188
 
179
 
        _pam_drop(responses);
 
189
        _pam_drop(response);
180
190
        /* Allow the user to enter each field of the context individually */
181
 
        query_response(pamh,_("role:"), NULL, &responses,debug);
182
 
        if (responses[0] != '\0') {
183
 
           if (context_role_set (new_context, responses)) 
 
191
        if (query_response(pamh, _("role:"), NULL, &response, debug) == PAM_SUCCESS &&
 
192
            response[0] != '\0') {
 
193
           if (context_role_set (new_context, response)) 
184
194
              goto fail_set;
185
 
           if (get_default_type(responses, &type)) 
 
195
           if (get_default_type(response, &type)) 
186
196
              goto fail_set;
187
197
           if (context_type_set (new_context, type)) 
188
198
              goto fail_set;
189
199
        }
190
 
        _pam_drop(responses);
 
200
        _pam_drop(response);
 
201
 
191
202
        if (mls_enabled)
192
203
          {
193
 
            query_response(pamh,_("level:"), NULL, &responses,debug);
194
 
            if (responses[0] != '\0') {
195
 
              if (context_range_set (new_context, responses))
 
204
            if (query_response(pamh, _("level:"), NULL, &response, debug) == PAM_SUCCESS &&
 
205
                response[0] != '\0') {
 
206
              if (context_range_set (new_context, response))
196
207
                goto fail_set;
197
208
            }
 
209
            _pam_drop(response);
198
210
          }
 
211
 
199
212
        /* Get the string value of the context and see if it is valid. */
200
213
        if (!security_check_context(context_str(new_context))) {
201
214
          newcon = strdup(context_str(new_context));
204
217
        }
205
218
        else
206
219
          send_text(pamh,_("Not a valid security context"),debug);
207
 
        context_free (new_context);
 
220
 
 
221
        context_free (new_context);
208
222
      }
209
223
    else {
210
 
      _pam_drop(responses);
 
224
      _pam_drop(response);
211
225
      return NULL;
212
226
    }
213
227
  } /* end while */
214
228
 fail_set:
215
229
  free(type);
216
 
  _pam_drop(responses);
 
230
  _pam_drop(response);
217
231
  context_free (new_context);
218
232
  return NULL;
219
233
}
239
253
}
240
254
 
241
255
static security_context_t
242
 
config_context (pam_handle_t *pamh, security_context_t puser_context, int debug)
 
256
config_context (pam_handle_t *pamh, security_context_t defaultcon, int use_current_range, int debug)
243
257
{
244
258
  security_context_t newcon=NULL;
245
259
  context_t new_context;
246
260
  int mls_enabled = is_selinux_mls_enabled();
247
 
  char *responses=NULL;
 
261
  char *response=NULL;
248
262
  char *type=NULL;
249
263
  char resp_val = 0;
250
264
 
251
 
  pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), puser_context);
 
265
  pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), defaultcon);
252
266
 
253
267
  while (1) {
254
 
    query_response(pamh,
 
268
    if (query_response(pamh,
255
269
                   _("Would you like to enter a different role or level?"), "n", 
256
 
                   &responses,debug);
257
 
 
258
 
    resp_val = responses[0];
259
 
    _pam_drop(responses);
 
270
                   &response, debug) == PAM_SUCCESS) {
 
271
        resp_val = response[0];
 
272
        _pam_drop(response);
 
273
    } else {
 
274
        resp_val = 'N';
 
275
    }
260
276
    if ((resp_val == 'y') || (resp_val == 'Y'))
261
277
      {
262
 
        new_context = context_new(puser_context);
263
 
        
 
278
        if ((new_context = context_new(defaultcon)) == NULL)
 
279
            goto fail_set;
 
280
 
264
281
        /* Allow the user to enter role and level individually */
265
 
        query_response(pamh,_("role:"), context_role_get(new_context), 
266
 
                       &responses, debug);
267
 
        if (responses[0]) {
268
 
          if (get_default_type(responses, &type)) {
269
 
            pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("No default type for role %s\n"), responses);
270
 
            _pam_drop(responses);
 
282
        if (query_response(pamh, _("role:"), context_role_get(new_context), 
 
283
                       &response, debug) == PAM_SUCCESS && response[0]) {
 
284
          if (get_default_type(response, &type)) {
 
285
            pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("No default type for role %s\n"), response);
 
286
            _pam_drop(response);
271
287
            continue;
272
288
          } else {
273
 
            if (context_role_set(new_context, responses)) 
 
289
            if (context_role_set(new_context, response)) 
274
290
              goto fail_set;
275
291
            if (context_type_set (new_context, type))
276
292
              goto fail_set;
277
293
          } 
278
294
        }
279
 
        _pam_drop(responses);
 
295
        _pam_drop(response);
 
296
 
280
297
        if (mls_enabled)
281
298
          {
282
 
            query_response(pamh,_("level:"), context_range_get(new_context), 
283
 
                           &responses, debug);
284
 
            if (responses[0]) {
285
 
              if (context_range_set(new_context, responses))
286
 
                goto fail_set;
 
299
            if (use_current_range) {
 
300
                security_context_t mycon = NULL;
 
301
                context_t my_context;
 
302
 
 
303
                if (getcon(&mycon) != 0)
 
304
                    goto fail_set;
 
305
                my_context = context_new(mycon);
 
306
                if (my_context == NULL) {
 
307
                    freecon(mycon);
 
308
                    goto fail_set;
 
309
                }
 
310
                freecon(mycon);
 
311
                if (context_range_set(new_context, context_range_get(my_context))) {
 
312
                    context_free(my_context);
 
313
                    goto fail_set;
 
314
                }
 
315
                context_free(my_context);
 
316
            } else if (query_response(pamh, _("level:"), context_range_get(new_context), 
 
317
                           &response, debug) == PAM_SUCCESS && response[0]) {
 
318
                if (context_range_set(new_context, response))
 
319
                    goto fail_set;
287
320
            } 
288
 
            _pam_drop(responses);
 
321
            _pam_drop(response);
289
322
          }
 
323
 
290
324
        if (debug)
291
325
          pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", context_str(new_context));
292
326
 
293
327
        /* Get the string value of the context and see if it is valid. */
294
328
        if (!security_check_context(context_str(new_context))) {
295
329
          newcon = strdup(context_str(new_context));
296
 
          context_free (new_context);
 
330
          if (newcon == NULL)
 
331
            goto fail_set;
 
332
          context_free(new_context);
297
333
 
298
334
          /* we have to check that this user is allowed to go into the
299
335
             range they have specified ... role is tied to an seuser, so that'll
300
336
             be checked at setexeccon time */
301
 
          if (mls_enabled && !mls_range_allowed(pamh, puser_context, newcon, debug)) {
302
 
            pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", puser_context, newcon);
 
337
          if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
 
338
            pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
303
339
 
304
 
            send_audit_message(pamh, 0, puser_context, newcon);
 
340
            send_audit_message(pamh, 0, defaultcon, newcon);
305
341
 
306
342
            free(newcon);
307
343
            goto fail_range;
309
345
          return newcon;
310
346
        }
311
347
        else {
312
 
          send_audit_message(pamh, 0, puser_context, context_str(new_context));
 
348
          send_audit_message(pamh, 0, defaultcon, context_str(new_context));
313
349
          send_text(pamh,_("Not a valid security context"),debug);
314
350
        }
315
351
        context_free(new_context); /* next time around allocates another */
316
352
      }
317
353
    else
318
 
      return strdup(puser_context);
 
354
      return strdup(defaultcon);
319
355
  } /* end while */
320
356
 
321
357
  return NULL;
322
358
 
323
359
 fail_set:
324
360
  free(type);
325
 
  _pam_drop(responses);
 
361
  _pam_drop(response);
326
362
  context_free (new_context);
327
 
  send_audit_message(pamh, 0, puser_context, NULL);
 
363
  send_audit_message(pamh, 0, defaultcon, NULL);
328
364
 fail_range:
329
365
  return NULL;  
330
366
}
331
367
 
 
368
static security_context_t
 
369
context_from_env (pam_handle_t *pamh, security_context_t defaultcon, int env_params, int use_current_range, int debug)
 
370
{
 
371
  security_context_t newcon = NULL;
 
372
  context_t new_context;
 
373
  context_t my_context = NULL;
 
374
  int mls_enabled = is_selinux_mls_enabled();
 
375
  const char *env = NULL;
 
376
  char *type = NULL;
 
377
 
 
378
  if ((new_context = context_new(defaultcon)) == NULL)
 
379
    goto fail_set;
 
380
 
 
381
  if (env_params && (env = pam_getenv(pamh, "SELINUX_ROLE_REQUESTED")) != NULL && env[0] != '\0') {
 
382
    if (debug)
 
383
        pam_syslog(pamh, LOG_NOTICE, "Requested role: %s", env);
 
384
 
 
385
    if (get_default_type(env, &type)) {
 
386
        pam_syslog(pamh, LOG_NOTICE, "No default type for role %s", env);
 
387
        goto fail_set;
 
388
    } else {
 
389
        if (context_role_set(new_context, env)) 
 
390
            goto fail_set;
 
391
        if (context_type_set(new_context, type))
 
392
            goto fail_set;
 
393
    }
 
394
  }
 
395
 
 
396
  if (mls_enabled) {
 
397
    if ((env = pam_getenv(pamh, "SELINUX_USE_CURRENT_RANGE")) != NULL && env[0] == '1') {
 
398
        if (debug)
 
399
            pam_syslog(pamh, LOG_NOTICE, "SELINUX_USE_CURRENT_RANGE is set");
 
400
        use_current_range = 1;
 
401
    }
 
402
 
 
403
    if (use_current_range) {
 
404
        security_context_t mycon = NULL;
 
405
 
 
406
        if (getcon(&mycon) != 0)
 
407
            goto fail_set;
 
408
        my_context = context_new(mycon);
 
409
        if (my_context == NULL) {
 
410
            freecon(mycon);
 
411
            goto fail_set;
 
412
        }
 
413
        freecon(mycon);
 
414
        env = context_range_get(my_context);
 
415
    } else {
 
416
        env = pam_getenv(pamh, "SELINUX_LEVEL_REQUESTED");
 
417
    }
 
418
 
 
419
    if (env != NULL && env[0] != '\0') {
 
420
        if (debug)
 
421
            pam_syslog(pamh, LOG_NOTICE, "Requested level: %s", env);
 
422
        if (context_range_set(new_context, env))
 
423
            goto fail_set;
 
424
    }
 
425
  }
 
426
 
 
427
  newcon = strdup(context_str(new_context));
 
428
  if (newcon == NULL)
 
429
    goto fail_set;
 
430
 
 
431
  if (debug)
 
432
    pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", newcon);
 
433
  
 
434
  /* Get the string value of the context and see if it is valid. */
 
435
  if (security_check_context(newcon)) {
 
436
    pam_syslog(pamh, LOG_NOTICE, "Not a valid security context %s", newcon);
 
437
    send_audit_message(pamh, 0, defaultcon, newcon);
 
438
    freecon(newcon);
 
439
    newcon = NULL;
 
440
 
 
441
    goto fail_set;
 
442
  }
 
443
 
 
444
  /* we have to check that this user is allowed to go into the
 
445
     range they have specified ... role is tied to an seuser, so that'll
 
446
     be checked at setexeccon time */
 
447
  if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
 
448
    pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
 
449
    send_audit_message(pamh, 0, defaultcon, newcon);
 
450
    freecon(newcon);
 
451
    newcon = NULL;
 
452
  }
 
453
 
 
454
 fail_set:
 
455
  free(type);
 
456
  context_free(my_context);
 
457
  context_free(new_context);
 
458
  send_audit_message(pamh, 0, defaultcon, NULL);
 
459
  return newcon;
 
460
}
 
461
 
332
462
static void
333
463
security_restorelabel_tty(const pam_handle_t *pamh,
334
464
                          const char *tty, security_context_t context)
439
569
pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
440
570
                    int argc, const char **argv)
441
571
{
442
 
  int i, debug = 0, ttys=1, has_tty=isatty(0);
 
572
  int i, debug = 0, ttys=1;
443
573
  int verbose=0, close_session=0;
444
574
  int select_context = 0;
445
575
  int use_current_range = 0;
446
576
  int ret = 0;
447
577
  security_context_t* contextlist = NULL;
448
578
  int num_contexts = 0;
449
 
  const char *username = NULL;
 
579
  int env_params = 0;
 
580
  const char *username;
 
581
  const void *void_username;
450
582
  const void *tty = NULL;
451
583
  char *seuser=NULL;
452
584
  char *level=NULL;
453
585
  security_context_t default_user_context=NULL;
 
586
#ifdef HAVE_GETSEUSER
 
587
  const void *void_service;
 
588
  const char *service;
 
589
#endif
454
590
 
455
591
  /* Parse arguments. */
456
592
  for (i = 0; i < argc; i++) {
472
608
    if (strcmp(argv[i], "use_current_range") == 0) {
473
609
      use_current_range = 1;
474
610
    }
 
611
    if (strcmp(argv[i], "env_params") == 0) {
 
612
      env_params = 1;
 
613
    }
475
614
  }
476
615
  
477
616
  if (debug)
478
617
    pam_syslog(pamh, LOG_NOTICE, "Open Session");
479
618
 
480
 
  if (select_context && use_current_range) {
481
 
    pam_syslog(pamh, LOG_ERR, "select_context cannot be used with use_current_range");
 
619
  if (select_context && env_params) {
 
620
    pam_syslog(pamh, LOG_ERR, "select_context cannot be used with env_params");
482
621
    select_context = 0;
483
622
  }
484
623
 
489
628
  if (!(selinux_enabled = is_selinux_enabled()>0) )
490
629
      return PAM_SUCCESS;
491
630
 
492
 
  if (pam_get_item(pamh, PAM_USER, (void *) &username) != PAM_SUCCESS ||
493
 
                   username == NULL) {
 
631
  if (pam_get_item(pamh, PAM_USER, &void_username) != PAM_SUCCESS ||
 
632
                   void_username == NULL) {
494
633
    return PAM_USER_UNKNOWN;
495
634
  }
496
 
 
497
 
  if (getseuserbyname(username, &seuser, &level)==0) {
 
635
  username = void_username;
 
636
 
 
637
#ifdef HAVE_GETSEUSER
 
638
  if (pam_get_item(pamh, PAM_SERVICE, (void *) &void_service) != PAM_SUCCESS ||
 
639
                   void_service == NULL) {
 
640
    return PAM_SESSION_ERR;
 
641
  }
 
642
  service = void_service;
 
643
 
 
644
  if (getseuser(username, service, &seuser, &level) == 0) {
 
645
#else
 
646
  if (getseuserbyname(username, &seuser, &level) == 0) {
 
647
#endif
498
648
          num_contexts = get_ordered_context_list_with_level(seuser, 
499
649
                                                             level,
500
650
                                                             NULL, 
510
660
    freeconary(contextlist);
511
661
    if (default_user_context == NULL) {
512
662
          pam_syslog(pamh, LOG_ERR, "Out of memory");
513
 
          return PAM_AUTH_ERR;
 
663
          return PAM_BUF_ERR;
514
664
    }
 
665
 
515
666
    user_context = default_user_context;
516
 
    if (select_context && has_tty) {
517
 
      user_context = config_context(pamh, default_user_context, debug);
518
 
      if (user_context == NULL) {
 
667
    if (select_context) {
 
668
        user_context = config_context(pamh, default_user_context, use_current_range, debug);
 
669
    } else if (env_params || use_current_range) {
 
670
        user_context = context_from_env(pamh, default_user_context, env_params, use_current_range, debug);
 
671
    }
 
672
 
 
673
    if (user_context == NULL) {
519
674
        freecon(default_user_context);
520
675
        pam_syslog(pamh, LOG_ERR, "Unable to get valid context for %s",
521
676
                    username);
524
679
          return PAM_AUTH_ERR;
525
680
        else
526
681
          return PAM_SUCCESS;
527
 
      }
528
 
    } 
 
682
    }
529
683
  }
530
684
  else { 
531
 
    if (has_tty) {
532
685
      user_context = manual_context(pamh,seuser,debug);
533
686
      if (user_context == NULL) {
534
687
        pam_syslog (pamh, LOG_ERR, "Unable to get valid context for %s",
538
691
        else
539
692
          return PAM_SUCCESS;
540
693
      }
541
 
    } else {
542
 
        pam_syslog (pamh, LOG_ERR,
543
 
                    "Unable to get valid context for %s, No valid tty",
544
 
                    username);
545
 
        if (security_getenforce() == 1)
546
 
          return PAM_AUTH_ERR;
547
 
        else
548
 
          return PAM_SUCCESS;
549
 
    }
550
 
  }
551
 
 
552
 
  if (use_current_range && is_selinux_mls_enabled()) {
553
 
    security_context_t process_context=NULL;    
554
 
    if (getcon(&process_context) == 0) {
555
 
      context_t pcon, ucon;
556
 
      char *process_level=NULL;
557
 
      security_context_t orig_context;
558
 
      
559
 
      if (user_context)
560
 
        orig_context = user_context;
561
 
      else
562
 
        orig_context = default_user_context;
563
 
 
564
 
      pcon = context_new(process_context);
565
 
      freecon(process_context);
566
 
      process_level = strdup(context_range_get(pcon));
567
 
      context_free(pcon);
568
 
 
569
 
      if (debug)
570
 
        pam_syslog (pamh, LOG_DEBUG, "process level=%s", process_level);
571
 
 
572
 
      ucon = context_new(orig_context);
573
 
 
574
 
      context_range_set(ucon, process_level);
575
 
      free(process_level);
576
 
 
577
 
      if (!mls_range_allowed(pamh, orig_context, context_str(ucon), debug)) {
578
 
        send_text(pamh, _("Requested MLS level not in permitted range"), debug);
579
 
        /* even if default_user_context is NULL audit that anyway */
580
 
        send_audit_message(pamh, 0, default_user_context, context_str(ucon));
581
 
        context_free(ucon);
582
 
        return PAM_AUTH_ERR;
583
 
      }
584
 
 
585
 
      if (debug)
586
 
        pam_syslog (pamh, LOG_DEBUG, "adjusted context=%s", context_str(ucon));
587
 
 
588
 
      /* replace the user context with the level adjusted one */
589
 
      freecon(user_context);
590
 
      user_context = strdup(context_str(ucon));
591
 
 
592
 
      context_free(ucon);
593
 
    }
594
694
  }
595
695
 
596
696
  if (getexeccon(&prev_user_context)<0) {
613
713
      }
614
714
    }
615
715
  }
616
 
  if(ttys && tty ) {
 
716
  if (ttys && tty) {
617
717
    ttyn=strdup(tty);
618
718
    ttyn_context=security_label_tty(pamh,ttyn,user_context);
619
719
  }
702
802
    free(ttyn);
703
803
    ttyn=NULL;
704
804
  }
705
 
  if (prev_user_context) {
706
 
    if (setexeccon(prev_user_context)) {
 
805
 
 
806
  if (setexeccon(prev_user_context)) {
707
807
      pam_syslog(pamh, LOG_ERR, "Unable to restore executable context %s.",
708
 
               prev_user_context);
 
808
               prev_user_context ? prev_user_context : "");
709
809
      if (security_getenforce() == 1)
710
810
         status = PAM_AUTH_ERR;
711
811
      else
712
812
         status = PAM_SUCCESS;
713
 
    }
 
813
  } else if (debug)
 
814
      pam_syslog(pamh, LOG_NOTICE, "Executable context back to original");
 
815
 
 
816
  if (prev_user_context) {
714
817
    freecon(prev_user_context);
715
818
    prev_user_context = NULL;
716
819
  }
717
820
 
718
 
  if (debug)
719
 
    pam_syslog(pamh, LOG_NOTICE, "setcontext back to orginal");
720
 
 
721
821
  return status;
722
822
}