1 /*
2 * Copyright 2006,2008,2012,2014 Red Hat, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, and the entire permission notice in its entirety,
9 * including the disclaimer of warranties.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 * products derived from this software without specific prior
15 * written permission.
16 *
17 * ALTERNATIVELY, this product may be distributed under the terms of the
18 * GNU Lesser General Public License, in which case the provisions of the
19 * LGPL are required INSTEAD OF the above restrictions.
20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
24 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "../config.h"
34
35 #ifdef HAVE_SECURITY_PAM_APPL_H
36 #include <security/pam_appl.h>
37 #endif
38
39 #ifdef HAVE_SECURITY_PAM_MODULES_H
40 #define PAM_SM_SESSION
41 #include <security/pam_modules.h>
42 #endif
43
44 #include <limits.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <unistd.h>
49
50 #include KRB5_H
51
52 #include "init.h"
53 #include "log.h"
54 #include "minikafs.h"
55 #include "options.h"
56 #include "prompter.h"
57 #include "shmem.h"
58 #include "stash.h"
59 #include "tokens.h"
60 #include "userinfo.h"
61 #include "v5.h"
62 #include "xstr.h"
63
64 static int
maybe_setpag(const char * fn,pam_handle_t * pamh,int flags,int argc,PAM_KRB5_MAYBE_CONST char ** argv)65 maybe_setpag(const char *fn, pam_handle_t *pamh, int flags,
66 int argc, PAM_KRB5_MAYBE_CONST char **argv)
67 {
68 krb5_context ctx;
69 struct _pam_krb5_options *options;
70 int i, ret;
71
72 /* Initialize Kerberos. */
73 if (_pam_krb5_init_ctx(&ctx, argc, argv) != 0) {
74 warn("error initializing Kerberos");
75 return PAM_SERVICE_ERR;
76 }
77
78 /* Read our options. */
79 options = _pam_krb5_options_init(pamh, argc, argv, ctx,
80 _pam_krb5_option_role_general);
81 if (options == NULL) {
82 warn("error parsing options (shouldn't happen)");
83 _pam_krb5_free_ctx(ctx);
84 return PAM_SERVICE_ERR;
85 }
86
87 if (options->ignore_afs) {
88 /* Do what we were told. */
89 ret = PAM_IGNORE;
90 } else {
91 if (!minikafs_has_afs()) {
92 /* Do nothing. */
93 if (options->debug) {
94 debug("%s did not detect AFS, "
95 "not creating new PAG", fn);
96 }
97 ret = PAM_IGNORE;
98 } else {
99 /* Create a PAG. */
100 if (options->debug) {
101 debug("%s detects AFS, creating new PAG", fn);
102 }
103 i = minikafs_setpag();
104 if (i != 0) {
105 if (options->debug) {
106 debug("error creating new PAG: %s",
107 strerror(i));
108 }
109 ret = PAM_SERVICE_ERR;
110 } else {
111 ret = PAM_SUCCESS;
112 }
113 }
114 }
115
116 if (options->debug) {
117 debug("%s returning %d (%s)",
118 fn,
119 ret,
120 pam_strerror(pamh, ret));
121 }
122 _pam_krb5_options_free(pamh, ctx, options);
123 _pam_krb5_free_ctx(ctx);
124 return ret;
125 }
126
127 int
pam_sm_authenticate(pam_handle_t * pamh,int flags,int argc,PAM_KRB5_MAYBE_CONST char ** argv)128 pam_sm_authenticate(pam_handle_t *pamh, int flags,
129 int argc, PAM_KRB5_MAYBE_CONST char **argv)
130 {
131 return PAM_IGNORE;
132 }
133
134 int
pam_sm_setcred(pam_handle_t * pamh,int flags,int argc,PAM_KRB5_MAYBE_CONST char ** argv)135 pam_sm_setcred(pam_handle_t *pamh, int flags,
136 int argc, PAM_KRB5_MAYBE_CONST char **argv)
137 {
138 if (flags & PAM_ESTABLISH_CRED) {
139 return maybe_setpag("pam_setcred", pamh, flags, argc, argv);
140 }
141 return PAM_IGNORE;
142 }
143
144 int
pam_sm_open_session(pam_handle_t * pamh,int flags,int argc,PAM_KRB5_MAYBE_CONST char ** argv)145 pam_sm_open_session(pam_handle_t *pamh, int flags,
146 int argc, PAM_KRB5_MAYBE_CONST char **argv)
147 {
148 return maybe_setpag("pam_open_session", pamh, flags, argc, argv);
149 }
150
151 int
pam_sm_close_session(pam_handle_t * pamh,int flags,int argc,PAM_KRB5_MAYBE_CONST char ** argv)152 pam_sm_close_session(pam_handle_t *pamh, int flags,
153 int argc, PAM_KRB5_MAYBE_CONST char **argv)
154 {
155 return PAM_SUCCESS;
156 }
157