1 /******************************************************************************
2 * A module for Linux-PAM that will set the default security context after login
3 * via PAM.
4 *
5 * Copyright (c) 2003 Red Hat, Inc.
6 * Written by Dan Walsh <dwalsh@redhat.com>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, and the entire permission notice in its entirety,
13 * including the disclaimer of warranties.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote
18 * products derived from this software without specific prior
19 * written permission.
20 *
21 * ALTERNATIVELY, this product may be distributed under the terms of
22 * the GNU Public License, in which case the provisions of the GPL are
23 * required INSTEAD OF the above restrictions. (This clause is
24 * necessary due to a potential bad interaction between the GPL and
25 * the restrictions contained in a BSD-style copyright.)
26 *
27 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
28 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
31 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
37 * OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 */
40
41 /************************************************************************
42 *
43 * All PAM code goes in this section.
44 *
45 ************************************************************************/
46
47 #include "config.h"
48
49 #include <errno.h>
50 #include <syslog.h>
51 #include <unistd.h> /* for getuid(), exit(), getopt() */
52 #include <signal.h>
53 #include <sys/wait.h> /* for wait() */
54
55 #include <security/pam_appl.h> /* for PAM functions */
56 #include <security/pam_misc.h> /* for misc_conv PAM utility function */
57
58 #define SERVICE_NAME "pam_selinux_check" /* the name of this program for PAM */
59 /* The file containing the context to run
60 * the scripts under. */
61 int authenticate_via_pam( const char *user , pam_handle_t **pamh);
62
63 /* authenticate_via_pam()
64 *
65 * in: user
66 * out: nothing
67 * return: value condition
68 * ----- ---------
69 * 1 pam thinks that the user authenticated themselves properly
70 * 0 otherwise
71 *
72 * this function uses pam to authenticate the user running this
73 * program. this is the only function in this program that makes pam
74 * calls.
75 *
76 */
77
78 int authenticate_via_pam( const char *user , pam_handle_t **pamh) {
79
80 struct pam_conv *conv;
81 int result = 0; /* our result, set to 0 (not authenticated) by default */
82
83 /* this is a jump table of functions for pam to use when it wants to *
84 * communicate with the user. we'll be using misc_conv(), which is *
85 * provided for us via pam_misc.h. */
86 struct pam_conv pam_conversation = {
87 misc_conv,
88 NULL
89 };
90 conv = &pam_conversation;
91
92
93 /* make `p_pam_handle' a valid pam handle so we can use it when *
94 * calling pam functions. */
95 if( PAM_SUCCESS != pam_start( SERVICE_NAME,
96 user,
97 conv,
98 pamh ) ) {
99 fprintf( stderr, _("failed to initialize PAM\n") );
100 exit( -1 );
101 }
102
103 if( PAM_SUCCESS != pam_set_item(*pamh, PAM_RUSER, user))
104 {
105 fprintf( stderr, _("failed to pam_set_item()\n") );
106 exit( -1 );
107 }
108
109 /* Ask PAM to authenticate the user running this program */
110 if( PAM_SUCCESS == pam_authenticate(*pamh,0) ) {
111 if ( PAM_SUCCESS == pam_open_session(*pamh, 0) )
112 result = 1; /* user authenticated OK! */
113 }
114 return( result );
115
116 } /* authenticate_via_pam() */
117
118 int
119 main (int argc, char **argv)
120 {
121 pam_handle_t *pamh;
122 int childPid;
123
124 if (argc < 1)
125 exit (-1);
126
127 if (!authenticate_via_pam(argv[1],&pamh))
128 exit(-1);
129
130 childPid = fork();
131 if (childPid < 0) {
132 /* error in fork() */
133 fprintf(stderr, _("login: failure forking: %m"));
134 pam_close_session(pamh, 0);
135 /* We're done with PAM. Free `pam_handle'. */
136 pam_end( pamh, PAM_SUCCESS );
137 exit(0);
138 }
139 if (childPid) {
140 close(0); close(1); close(2);
141 struct sigaction sa;
142 memset(&sa,0,sizeof(sa));
143 sa.sa_handler = SIG_IGN;
144 sigaction(SIGQUIT, &sa, NULL);
145 sigaction(SIGINT, &sa, NULL);
146 while(wait(NULL) == -1 && errno == EINTR) /**/ ;
147 openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
148 pam_close_session(pamh, 0);
149 /* We're done with PAM. Free `pam_handle'. */
150 pam_end( pamh, PAM_SUCCESS );
151 exit(0);
152 }
153 argv[0]=strdup ("/bin/sh");
154 argv[1]=NULL;
155
156 /* NOTE: The environment has not been sanitized. LD_PRELOAD and other fun
157 * things could be set. */
158 execv("/bin/sh",argv);
159 fprintf(stderr,"Failure\n");
160 return 0;
161 }