12c0338ffSzrj /*
22c0338ffSzrj * Copyright (c) 2003 Ben Lindstrom. All rights reserved.
32c0338ffSzrj *
42c0338ffSzrj * Redistribution and use in source and binary forms, with or without
52c0338ffSzrj * modification, are permitted provided that the following conditions
62c0338ffSzrj * are met:
72c0338ffSzrj * 1. Redistributions of source code must retain the above copyright
82c0338ffSzrj * notice, this list of conditions and the following disclaimer.
92c0338ffSzrj * 2. Redistributions in binary form must reproduce the above copyright
102c0338ffSzrj * notice, this list of conditions and the following disclaimer in the
112c0338ffSzrj * documentation and/or other materials provided with the distribution.
122c0338ffSzrj *
132c0338ffSzrj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
142c0338ffSzrj * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
152c0338ffSzrj * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
162c0338ffSzrj * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
172c0338ffSzrj * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
182c0338ffSzrj * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
192c0338ffSzrj * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
202c0338ffSzrj * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
212c0338ffSzrj * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
222c0338ffSzrj * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
232c0338ffSzrj */
242c0338ffSzrj
252c0338ffSzrj #include "includes.h"
262c0338ffSzrj
272c0338ffSzrj #include <sys/types.h>
282c0338ffSzrj #include <string.h>
292c0338ffSzrj #include <unistd.h>
302c0338ffSzrj #include <pwd.h>
312c0338ffSzrj
322c0338ffSzrj # if defined(HAVE_CRYPT_H) && !defined(HAVE_SECUREWARE)
332c0338ffSzrj # include <crypt.h>
342c0338ffSzrj # endif
352c0338ffSzrj
36bc9cc675SDaniel Fojt # ifdef __hpux
37bc9cc675SDaniel Fojt # include <hpsecurity.h>
38bc9cc675SDaniel Fojt # include <prot.h>
39bc9cc675SDaniel Fojt # endif
40bc9cc675SDaniel Fojt
41bc9cc675SDaniel Fojt # ifdef HAVE_SECUREWARE
42bc9cc675SDaniel Fojt # include <sys/security.h>
43bc9cc675SDaniel Fojt # include <sys/audit.h>
44bc9cc675SDaniel Fojt # include <prot.h>
45bc9cc675SDaniel Fojt # endif
46bc9cc675SDaniel Fojt
472c0338ffSzrj # if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
482c0338ffSzrj # include <shadow.h>
492c0338ffSzrj # endif
502c0338ffSzrj
512c0338ffSzrj # if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
522c0338ffSzrj # include <sys/label.h>
532c0338ffSzrj # include <sys/audit.h>
542c0338ffSzrj # include <pwdadj.h>
552c0338ffSzrj # endif
562c0338ffSzrj
572c0338ffSzrj # if defined(WITH_OPENSSL) && !defined(HAVE_CRYPT) && defined(HAVE_DES_CRYPT)
582c0338ffSzrj # include <openssl/des.h>
592c0338ffSzrj # define crypt DES_crypt
602c0338ffSzrj # endif
612c0338ffSzrj
62*2c81fb9cSAntonio Huete Jimenez #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
63*2c81fb9cSAntonio Huete Jimenez
642c0338ffSzrj /*
652c0338ffSzrj * Pick an appropriate password encryption type and salt for the running
662c0338ffSzrj * system by searching through accounts until we find one that has a valid
672c0338ffSzrj * salt. Usually this will be root unless the root account is locked out.
682c0338ffSzrj * If we don't find one we return a traditional DES-based salt.
692c0338ffSzrj */
702c0338ffSzrj static const char *
pick_salt(void)712c0338ffSzrj pick_salt(void)
722c0338ffSzrj {
732c0338ffSzrj struct passwd *pw;
742c0338ffSzrj char *passwd, *p;
752c0338ffSzrj size_t typelen;
762c0338ffSzrj static char salt[32];
772c0338ffSzrj
782c0338ffSzrj if (salt[0] != '\0')
792c0338ffSzrj return salt;
802c0338ffSzrj strlcpy(salt, "xx", sizeof(salt));
812c0338ffSzrj setpwent();
822c0338ffSzrj while ((pw = getpwent()) != NULL) {
832c0338ffSzrj if ((passwd = shadow_pw(pw)) == NULL)
842c0338ffSzrj continue;
852c0338ffSzrj if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) != NULL) {
862c0338ffSzrj typelen = p - passwd + 1;
87*2c81fb9cSAntonio Huete Jimenez strlcpy(salt, passwd, MINIMUM(typelen, sizeof(salt)));
882c0338ffSzrj explicit_bzero(passwd, strlen(passwd));
892c0338ffSzrj goto out;
902c0338ffSzrj }
912c0338ffSzrj }
922c0338ffSzrj out:
932c0338ffSzrj endpwent();
942c0338ffSzrj return salt;
952c0338ffSzrj }
962c0338ffSzrj
972c0338ffSzrj char *
xcrypt(const char * password,const char * salt)982c0338ffSzrj xcrypt(const char *password, const char *salt)
992c0338ffSzrj {
1002c0338ffSzrj char *crypted;
1012c0338ffSzrj
1022c0338ffSzrj /*
1032c0338ffSzrj * If we don't have a salt we are encrypting a fake password for
1042c0338ffSzrj * for timing purposes. Pick an appropriate salt.
1052c0338ffSzrj */
1062c0338ffSzrj if (salt == NULL)
1072c0338ffSzrj salt = pick_salt();
1082c0338ffSzrj
109*2c81fb9cSAntonio Huete Jimenez #if defined(__hpux) && !defined(HAVE_SECUREWARE)
110bc9cc675SDaniel Fojt if (iscomsec())
111bc9cc675SDaniel Fojt crypted = bigcrypt(password, salt);
112bc9cc675SDaniel Fojt else
113bc9cc675SDaniel Fojt crypted = crypt(password, salt);
114bc9cc675SDaniel Fojt # elif defined(HAVE_SECUREWARE)
115bc9cc675SDaniel Fojt crypted = bigcrypt(password, salt);
1162c0338ffSzrj # else
1172c0338ffSzrj crypted = crypt(password, salt);
1182c0338ffSzrj #endif
1192c0338ffSzrj
1202c0338ffSzrj return crypted;
1212c0338ffSzrj }
1222c0338ffSzrj
1232c0338ffSzrj /*
1242c0338ffSzrj * Handle shadowed password systems in a cleaner way for portable
1252c0338ffSzrj * version.
1262c0338ffSzrj */
1272c0338ffSzrj
1282c0338ffSzrj char *
shadow_pw(struct passwd * pw)1292c0338ffSzrj shadow_pw(struct passwd *pw)
1302c0338ffSzrj {
1312c0338ffSzrj char *pw_password = pw->pw_passwd;
1322c0338ffSzrj
1332c0338ffSzrj # if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
1342c0338ffSzrj struct spwd *spw = getspnam(pw->pw_name);
1352c0338ffSzrj
1362c0338ffSzrj if (spw != NULL)
1372c0338ffSzrj pw_password = spw->sp_pwdp;
1382c0338ffSzrj # endif
1392c0338ffSzrj
140bc9cc675SDaniel Fojt #ifdef USE_LIBIAF
141bc9cc675SDaniel Fojt return(get_iaf_password(pw));
142bc9cc675SDaniel Fojt #endif
143bc9cc675SDaniel Fojt
1442c0338ffSzrj # if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
1452c0338ffSzrj struct passwd_adjunct *spw;
1462c0338ffSzrj if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL)
1472c0338ffSzrj pw_password = spw->pwa_passwd;
148bc9cc675SDaniel Fojt # elif defined(HAVE_SECUREWARE)
149bc9cc675SDaniel Fojt struct pr_passwd *spw = getprpwnam(pw->pw_name);
150bc9cc675SDaniel Fojt
151bc9cc675SDaniel Fojt if (spw != NULL)
152bc9cc675SDaniel Fojt pw_password = spw->ufld.fd_encrypt;
1532c0338ffSzrj # endif
1542c0338ffSzrj
1552c0338ffSzrj return pw_password;
1562c0338ffSzrj }
157