4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <security/pam_appl.h>
30 #include <security/pam_modules.h>
34 #include <sys/types.h>
39 #include "sample_utils.h"
43 * Sample module for pam_sm_authenticate.
50 * first_pass_good (first password is always good when used with use/try)
51 * first_pass_bad (first password is always bad when used with use/try)
52 * pass=foobar (set good password to "foobar". default good password
54 * always_fail always return PAM_AUTH_ERR
55 * always_succeed always return PAM_SUCCESS
62 * pam_sm_authenticate - Authenticate user
73 struct pam_conv
*pam_convp
;
74 int err
, result
= PAM_AUTH_ERR
;
75 struct pam_response
*ret_resp
= (struct pam_response
*)0;
76 char messages
[PAM_MAX_NUM_MSG
][PAM_MAX_MSG_SIZE
];
78 int try_first_pass
= 0;
79 int use_first_pass
= 0;
80 int first_pass_good
= 0;
81 int first_pass_bad
= 0;
83 char *firstpass
, *password
;
84 char the_password
[64];
87 syslog(LOG_DEBUG
, "Sample Authentication\n");
89 (void) strcpy(the_password
, "test");
91 for (i
= 0; i
< argc
; i
++) {
92 if (strcmp(argv
[i
], "debug") == 0)
94 else if (strcmp(argv
[i
], "try_first_pass") == 0)
96 else if (strcmp(argv
[i
], "first_pass_good") == 0)
98 else if (strcmp(argv
[i
], "first_pass_bad") == 0)
100 else if (strcmp(argv
[i
], "use_first_pass") == 0)
102 else if (strcmp(argv
[i
], "always_fail") == 0)
103 return (PAM_AUTH_ERR
);
104 else if (strcmp(argv
[i
], "always_succeed") == 0)
105 return (PAM_SUCCESS
);
106 else if (strcmp(argv
[i
], "always_ignore") == 0)
108 else if (sscanf(argv
[i
], "pass=%64s", the_password
) == 1) {
112 syslog(LOG_DEBUG
, "illegal scheme option %s", argv
[i
]);
115 err
= pam_get_user(pamh
, &user
, NULL
);
116 if (err
!= PAM_SUCCESS
)
119 err
= pam_get_item(pamh
, PAM_CONV
, (void**) &pam_convp
);
120 if (err
!= PAM_SUCCESS
)
123 (void) pam_get_item(pamh
, PAM_AUTHTOK
, (void **) &firstpass
);
125 if (firstpass
&& (use_first_pass
|| try_first_pass
)) {
127 if ((first_pass_good
||
128 strncmp(firstpass
, the_password
,
129 strlen(the_password
)) == 0) &&
131 result
= PAM_SUCCESS
;
134 if (use_first_pass
) goto out
;
138 * Get the password from the user
141 (void) snprintf(messages
[0], sizeof (messages
[0]),
142 dgettext(TEXT_DOMAIN
, "TEST Password: "));
144 (void) snprintf(messages
[0], sizeof (messages
[0]),
145 dgettext(TEXT_DOMAIN
, "Password: "));
148 err
= __get_authtok(pam_convp
->conv
,
149 num_msg
, messages
, NULL
, &ret_resp
);
151 if (err
!= PAM_SUCCESS
) {
156 password
= ret_resp
->resp
;
158 if (password
== NULL
) {
159 result
= PAM_AUTH_ERR
;
163 /* one last ditch attempt to "login" to TEST */
165 if (strncmp(password
, the_password
, strlen(the_password
)) == 0) {
166 result
= PAM_SUCCESS
;
167 if (firstpass
== NULL
) {
168 /* this is the first password, stash it away */
169 (void) pam_set_item(pamh
, PAM_AUTHTOK
, password
);
176 if (ret_resp
->resp
!= 0) {
177 /* avoid leaving password cleartext around */
178 (void) memset(ret_resp
->resp
, 0,
179 strlen(ret_resp
->resp
));
181 __free_resp(num_msg
, ret_resp
);