(root)/
Linux-PAM-1.5.3/
modules/
pam_rootok/
pam_rootok.c
       1  /*
       2   * pam_rootok module
       3   *
       4   * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
       5   */
       6  
       7  #include "config.h"
       8  
       9  #include <stdio.h>
      10  #include <unistd.h>
      11  #include <syslog.h>
      12  #include <stdarg.h>
      13  #include <string.h>
      14  
      15  #include <security/pam_modules.h>
      16  #include <security/pam_ext.h>
      17  
      18  #ifdef WITH_SELINUX
      19  #include <selinux/selinux.h>
      20  #include <selinux/avc.h>
      21  #endif
      22  
      23  #ifdef HAVE_LIBAUDIT
      24  #include <libaudit.h>
      25  #endif
      26  
      27  /* argument parsing */
      28  
      29  #define PAM_DEBUG_ARG       01
      30  
      31  static int
      32  _pam_parse (const pam_handle_t *pamh, int argc, const char **argv)
      33  {
      34      int ctrl=0;
      35  
      36      /* step through arguments */
      37      for (ctrl=0; argc-- > 0; ++argv) {
      38  
      39  	/* generic options */
      40  
      41  	if (!strcmp(*argv,"debug"))
      42  	    ctrl |= PAM_DEBUG_ARG;
      43  	else {
      44  	    pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
      45  	}
      46      }
      47  
      48      return ctrl;
      49  }
      50  
      51  #ifdef WITH_SELINUX
      52  static int
      53  PAM_FORMAT((printf, 2, 3))
      54  log_callback (int type UNUSED, const char *fmt, ...)
      55  {
      56      va_list ap;
      57  
      58  #ifdef HAVE_LIBAUDIT
      59      int audit_fd = audit_open();
      60  
      61      if (audit_fd >= 0) {
      62  	char *buf;
      63  	int ret;
      64  
      65  	va_start(ap, fmt);
      66  	ret = vasprintf (&buf, fmt, ap);
      67  	va_end(ap);
      68  	if (ret < 0) {
      69  		return 0;
      70  	}
      71  	audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
      72  				   NULL, 0);
      73  	audit_close(audit_fd);
      74  	free(buf);
      75  	va_end(ap);
      76  	return 0;
      77      }
      78  
      79  #endif
      80      va_start(ap, fmt);
      81      vsyslog (LOG_USER | LOG_INFO, fmt, ap);
      82      va_end(ap);
      83      return 0;
      84  }
      85  
      86  static int
      87  selinux_check_root (void)
      88  {
      89      int status = -1;
      90      char *user_context_raw;
      91      union selinux_callback old_callback;
      92  
      93      if (is_selinux_enabled() < 1)
      94  	return 0;
      95  
      96      old_callback = selinux_get_callback(SELINUX_CB_LOG);
      97      /* setup callbacks */
      98      selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback);
      99      if ((status = getprevcon_raw(&user_context_raw)) < 0) {
     100  	selinux_set_callback(SELINUX_CB_LOG, old_callback);
     101  	return status;
     102      }
     103  
     104      status = selinux_check_access(user_context_raw, user_context_raw, "passwd", "rootok", NULL);
     105  
     106      selinux_set_callback(SELINUX_CB_LOG, old_callback);
     107      freecon(user_context_raw);
     108      return status;
     109  }
     110  #endif
     111  
     112  static int
     113  check_for_root (pam_handle_t *pamh, int ctrl)
     114  {
     115      int retval = PAM_AUTH_ERR;
     116  
     117      if (getuid() == 0)
     118  #ifdef WITH_SELINUX
     119        if (selinux_check_root() == 0 || security_getenforce() == 0)
     120  #endif
     121  	retval = PAM_SUCCESS;
     122  
     123      if (ctrl & PAM_DEBUG_ARG) {
     124         pam_syslog(pamh, LOG_DEBUG, "root check %s",
     125  	          (retval==PAM_SUCCESS) ? "succeeded" : "failed");
     126      }
     127  
     128      return retval;
     129  }
     130  
     131  /* --- management functions --- */
     132  
     133  int
     134  pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
     135  		     int argc, const char **argv)
     136  {
     137      int ctrl;
     138  
     139      ctrl = _pam_parse(pamh, argc, argv);
     140  
     141      return check_for_root (pamh, ctrl);
     142  }
     143  
     144  int
     145  pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
     146  		int argc UNUSED, const char **argv UNUSED)
     147  {
     148      return PAM_SUCCESS;
     149  }
     150  
     151  int
     152  pam_sm_acct_mgmt (pam_handle_t *pamh, int flags UNUSED,
     153  		  int argc, const char **argv)
     154  {
     155      int ctrl;
     156  
     157      ctrl = _pam_parse(pamh, argc, argv);
     158  
     159      return check_for_root (pamh, ctrl);
     160  }
     161  
     162  int
     163  pam_sm_chauthtok (pam_handle_t *pamh, int flags UNUSED,
     164  		  int argc, const char **argv)
     165  {
     166      int ctrl;
     167  
     168      ctrl = _pam_parse(pamh, argc, argv);
     169  
     170      return check_for_root (pamh, ctrl);
     171  }
     172  
     173  /* end of module definition */