]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_checkpw/lib/checkpw.c
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_checkpw / lib / checkpw.c
1 /*
2 * Copyright (c) 2000-2012 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 #include <unistd.h>
24
25 #define PAM_STACK_NAME "checkpw"
26
27 static
28 int checkpw_internal_pam( const char* uname, const char* password )
29 {
30 int checkpwret = CHECKPW_FAILURE;
31
32 int pamret = PAM_SUCCESS;
33 pam_handle_t *pamh;
34 struct pam_conv pamc;
35 pamc.conv = &openpam_nullconv;
36
37 pamret = pam_start(PAM_STACK_NAME, uname, &pamc, &pamh);
38 if (PAM_SUCCESS != pamret)
39 {
40 syslog(LOG_WARNING,"PAM: Unable to start pam.");
41 goto pamerr_no_end;
42 }
43
44 pamret = pam_set_item(pamh, PAM_AUTHTOK, password);
45 if (PAM_SUCCESS != pamret)
46 {
47 syslog(LOG_WARNING,"PAM: Unable to set password.");
48 goto pamerr;
49 }
50
51 pamret = pam_authenticate(pamh, 0);
52 if (PAM_SUCCESS != pamret)
53 {
54 syslog(LOG_WARNING,"PAM: Unable to authenticate.");
55 checkpwret = CHECKPW_BADPASSWORD;
56 goto pamerr;
57 }
58
59 pamret = pam_acct_mgmt(pamh, 0);
60 if (PAM_SUCCESS != pamret)
61 {
62 if (PAM_NEW_AUTHTOK_REQD == pamret)
63 {
64 syslog(LOG_WARNING,"PAM: Unable to authorize, password needs to be changed.");
65 } else {
66 syslog(LOG_WARNING,"PAM: Unable to authorize.");
67 }
68
69 goto pamerr;
70 }
71
72 checkpwret = CHECKPW_SUCCESS;
73
74 pamerr:
75 pam_end(pamh, pamret);
76 pamerr_no_end:
77 return checkpwret;
78
79 }
80
81 #warning TODO: this should be declared in some header.
82 int checkpw_internal( const struct passwd* pw, const char* password );
83 int checkpw_internal( const struct passwd* pw, const char* password )
84 {
85 return checkpw(pw->pw_name, password);
86 }
87
88 int checkpw( const char* userName, const char* password )
89 {
90 int siResult = CHECKPW_FAILURE;
91 // workaround for 3965234; I assume the empty string is OK...
92 const char *thePassword = password ? password : "";
93
94 if (userName == NULL)
95 return CHECKPW_UNKNOWNUSER;
96
97 siResult = checkpw_internal_pam(userName, thePassword);
98 switch (siResult) {
99 case CHECKPW_SUCCESS:
100 case CHECKPW_UNKNOWNUSER:
101 case CHECKPW_BADPASSWORD:
102 break;
103 default:
104 usleep(500000);
105 siResult = checkpw_internal_pam(userName, thePassword);
106 break;
107 }
108
109 return siResult;
110 }
111