]> git.saurik.com Git - apple/security.git/blob - libsecurity_checkpw/lib/checkpw.c
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_checkpw / lib / checkpw.c
1 /*
2 * Copyright (c) 2000-2010 Apple Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18 #include <security/pam_appl.h>
19 #include <security/openpam.h>
20
21 #include "checkpw.h"
22 #include <syslog.h>
23
24 #define PAM_STACK_NAME "checkpw"
25
26 int checkpw_internal_pam( const char* uname, const char* password )
27 {
28 int checkpwret = CHECKPW_FAILURE;
29
30 int pamret = PAM_SUCCESS;
31 pam_handle_t *pamh;
32 struct pam_conv pamc;
33 pamc.conv = &openpam_nullconv;
34
35 pamret = pam_start(PAM_STACK_NAME, uname, &pamc, &pamh);
36 if (PAM_SUCCESS != pamret)
37 {
38 syslog(LOG_WARNING,"PAM: Unable to start pam.");
39 goto pamerr_no_end;
40 }
41
42 pamret = pam_set_item(pamh, PAM_AUTHTOK, password);
43 if (PAM_SUCCESS != pamret)
44 {
45 syslog(LOG_WARNING,"PAM: Unable to set password.");
46 goto pamerr;
47 }
48
49 pamret = pam_authenticate(pamh, 0);
50 if (PAM_SUCCESS != pamret)
51 {
52 syslog(LOG_WARNING,"PAM: Unable to authenticate.");
53 checkpwret = CHECKPW_BADPASSWORD;
54 goto pamerr;
55 }
56
57 pamret = pam_acct_mgmt(pamh, 0);
58 if (PAM_SUCCESS != pamret)
59 {
60 if (PAM_NEW_AUTHTOK_REQD == pamret)
61 {
62 syslog(LOG_WARNING,"PAM: Unable to authorize, password needs to be changed.");
63 } else {
64 syslog(LOG_WARNING,"PAM: Unable to authorize.");
65 }
66
67 goto pamerr;
68 }
69
70 checkpwret = CHECKPW_SUCCESS;
71
72 pamerr:
73 pam_end(pamh, pamret);
74 pamerr_no_end:
75 return checkpwret;
76
77 }
78
79 int checkpw_internal( const struct passwd* pw, const char* password )
80 {
81 return checkpw(pw->pw_name, password);
82 }
83
84 int checkpw( const char* userName, const char* password )
85 {
86 int siResult = CHECKPW_FAILURE;
87 // workaround for 3965234; I assume the empty string is OK...
88 const char *thePassword = password ? password : "";
89
90 if (userName == NULL)
91 return CHECKPW_UNKNOWNUSER;
92
93 siResult = checkpw_internal_pam(userName, thePassword);
94 switch (siResult) {
95 case CHECKPW_SUCCESS:
96 case CHECKPW_UNKNOWNUSER:
97 case CHECKPW_BADPASSWORD:
98 break;
99 default:
100 usleep(500000);
101 siResult = checkpw_internal_pam(userName, thePassword);
102 break;
103 }
104
105 return siResult;
106 }
107