2 * This program is designed to run with sufficient privilege
3 * to read and write all of the unix password databases.
4 * Its purpose is to allow updating the databases when
5 * SELinux confinement of the caller domain prevents them to
8 * The password is read from the standard input. The exit status of
9 * this program indicates whether the password was updated or not.
11 * Copyright information is located at the end of the file.
23 #include <sys/types.h>
31 #include <security/_pam_types.h>
32 #include <security/_pam_macros.h>
34 #include "passverify.h"
37 set_password(const char *forwho, const char *shadow, const char *remember)
39 struct passwd *pwd = NULL;
41 char pass[MAXPASS + 1];
42 char towhat[MAXPASS + 1];
44 /* we don't care about number format errors because the helper
45 should be called internally only */
46 int doshadow = atoi(shadow);
47 int nremember = atoi(remember);
48 char *passwords[] = { pass, towhat };
50 /* read the password from stdin (a pipe from the pam_unix module) */
52 npass = read_passwords(STDIN_FILENO, 2, passwords);
54 if (npass != 2) { /* is it a valid password? */
56 helper_log_err(LOG_DEBUG, "no new password supplied");
57 memset(pass, '\0', MAXPASS);
59 helper_log_err(LOG_DEBUG, "no valid passwords supplied");
61 return PAM_AUTHTOK_ERR;
64 if (lock_pwdf() != PAM_SUCCESS)
65 return PAM_AUTHTOK_LOCK_BUSY;
67 pwd = getpwnam(forwho);
70 retval = PAM_USER_UNKNOWN;
74 /* does pass agree with the official one?
75 we always allow change from null pass */
76 retval = helper_verify_password(forwho, pass, 1);
77 if (retval != PAM_SUCCESS) {
81 /* first, save old password */
82 if (save_old_password(forwho, pass, nremember)) {
83 retval = PAM_AUTHTOK_ERR;
87 if (doshadow || is_pwd_shadowed(pwd)) {
88 retval = unix_update_shadow(forwho, towhat);
89 if (retval == PAM_SUCCESS)
90 if (!is_pwd_shadowed(pwd))
91 retval = unix_update_passwd(forwho, "x");
93 retval = unix_update_passwd(forwho, towhat);
97 memset(pass, '\0', MAXPASS);
98 memset(towhat, '\0', MAXPASS);
102 if (retval == PAM_SUCCESS) {
105 return PAM_AUTHTOK_ERR;
109 int main(int argc, char *argv[])
114 * Catch or ignore as many signal as possible.
119 * we establish that this program is running with non-tty stdin.
120 * this is to discourage casual use. It does *NOT* prevent an
121 * intruder from repeatadly running this program to determine the
122 * password of the current user (brute force attack, but one for
123 * which the attacker must already have gained access to the user's
127 if (isatty(STDIN_FILENO) || argc != 5 ) {
128 helper_log_err(LOG_NOTICE
129 ,"inappropriate use of Unix helper binary [UID=%d]"
132 ,"This binary is not designed for running in this way\n"
133 "-- the system administrator has been informed\n");
134 sleep(10); /* this should discourage/annoy the user */
135 return PAM_SYSTEM_ERR;
138 /* We must be root to read/update shadow.
140 if (geteuid() != 0) {
141 return PAM_CRED_INSUFFICIENT;
146 if (strcmp(option, "update") == 0) {
147 /* Attempting to change the password */
148 return set_password(argv[1], argv[3], argv[4]);
151 return PAM_SYSTEM_ERR;
155 * Copyright (c) Andrew G. Morgan, 1996. All rights reserved
156 * Copyright (c) Red Hat, Inc., 2007, 2008. All rights reserved
158 * Redistribution and use in source and binary forms, with or without
159 * modification, are permitted provided that the following conditions
161 * 1. Redistributions of source code must retain the above copyright
162 * notice, and the entire permission notice in its entirety,
163 * including the disclaimer of warranties.
164 * 2. Redistributions in binary form must reproduce the above copyright
165 * notice, this list of conditions and the following disclaimer in the
166 * documentation and/or other materials provided with the distribution.
167 * 3. The name of the author may not be used to endorse or promote
168 * products derived from this software without specific prior
169 * written permission.
171 * ALTERNATIVELY, this product may be distributed under the terms of
172 * the GNU Public License, in which case the provisions of the GPL are
173 * required INSTEAD OF the above restrictions. (This clause is
174 * necessary due to a potential bad interaction between the GPL and
175 * the restrictions contained in a BSD-style copyright.)
177 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
178 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
179 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
180 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
181 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
182 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
183 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
184 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
185 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
186 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
187 * OF THE POSSIBILITY OF SUCH DAMAGE.