1/* 2 * Copyright (c) 1999-2005, 2010 3 * Todd C. Miller <Todd.Miller@courtesan.com> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * 17 * Sponsored in part by the Defense Advanced Research Projects 18 * Agency (DARPA) and Air Force Research Laboratory, Air Force 19 * Materiel Command, USAF, under agreement number F39502-99-1-0512. 20 */ 21 22#include <config.h> 23 24#include <sys/types.h> 25#include <sys/param.h> 26#include <stdio.h> 27#ifdef STDC_HEADERS 28# include <stdlib.h> 29# include <stddef.h> 30#else 31# ifdef HAVE_STDLIB_H 32# include <stdlib.h> 33# endif 34#endif /* STDC_HEADERS */ 35#ifdef HAVE_STRING_H 36# include <string.h> 37#endif /* HAVE_STRING_H */ 38#ifdef HAVE_STRINGS_H 39# include <strings.h> 40#endif /* HAVE_STRINGS_H */ 41#ifdef HAVE_UNISTD_H 42# include <unistd.h> 43#endif /* HAVE_UNISTD_H */ 44#include <pwd.h> 45 46#include "sudo.h" 47#include "sudo_auth.h" 48 49#define DESLEN 13 50#define HAS_AGEINFO(p, l) (l == 18 && p[DESLEN] == ',') 51 52int 53passwd_init(pw, auth) 54 struct passwd *pw; 55 sudo_auth *auth; 56{ 57#ifdef HAVE_SKEYACCESS 58 if (skeyaccess(pw, user_tty, NULL, NULL) == 0) 59 return AUTH_FAILURE; 60#endif 61 sudo_setspent(); 62 auth->data = sudo_getepw(pw); 63 sudo_endspent(); 64 return AUTH_SUCCESS; 65} 66 67int 68passwd_verify(pw, pass, auth) 69 struct passwd *pw; 70 char *pass; 71 sudo_auth *auth; 72{ 73 char sav, *epass; 74 char *pw_epasswd = auth->data; 75 size_t pw_len; 76 int error; 77 78 pw_len = strlen(pw_epasswd); 79 80#ifdef HAVE_GETAUTHUID 81 /* Ultrix shadow passwords may use crypt16() */ 82 error = strcmp(pw_epasswd, (char *) crypt16(pass, pw_epasswd)); 83 if (!error) 84 return AUTH_SUCCESS; 85#endif /* HAVE_GETAUTHUID */ 86 87 /* 88 * Truncate to 8 chars if standard DES since not all crypt()'s do this. 89 * If this turns out not to be safe we will have to use OS #ifdef's (sigh). 90 */ 91 sav = pass[8]; 92 if (pw_len == DESLEN || HAS_AGEINFO(pw_epasswd, pw_len)) 93 pass[8] = '\0'; 94 95 /* 96 * Normal UN*X password check. 97 * HP-UX may add aging info (separated by a ',') at the end so 98 * only compare the first DESLEN characters in that case. 99 */ 100 epass = (char *) crypt(pass, pw_epasswd); 101 pass[8] = sav; 102 if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN) 103 error = strncmp(pw_epasswd, epass, DESLEN); 104 else 105 error = strcmp(pw_epasswd, epass); 106 107 return error ? AUTH_FAILURE : AUTH_SUCCESS; 108} 109 110int 111passwd_cleanup(pw, auth) 112 struct passwd *pw; 113 sudo_auth *auth; 114{ 115 char *pw_epasswd = auth->data; 116 117 if (pw_epasswd != NULL) { 118 zero_bytes(pw_epasswd, strlen(pw_epasswd)); 119 efree(pw_epasswd); 120 } 121 return AUTH_SUCCESS; 122} 123