]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_checkpw/lib/checkpw.c
Security-57740.31.2.tar.gz
[apple/security.git] / OSX / libsecurity_checkpw / lib / checkpw.c
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2000-2012 Apple Inc. All Rights Reserved.
b1ab9ed8
A
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>
427c49bc 23#include <unistd.h>
b1ab9ed8
A
24
25#define PAM_STACK_NAME "checkpw"
26
427c49bc 27static
b1ab9ed8
A
28int 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
74pamerr:
75 pam_end(pamh, pamret);
76pamerr_no_end:
77 return checkpwret;
78
79}
80
427c49bc 81int checkpw_internal( const struct passwd* pw, const char* password );
b1ab9ed8
A
82int checkpw_internal( const struct passwd* pw, const char* password )
83{
84 return checkpw(pw->pw_name, password);
85}
86
87int checkpw( const char* userName, const char* password )
88{
89 int siResult = CHECKPW_FAILURE;
90 // workaround for 3965234; I assume the empty string is OK...
91 const char *thePassword = password ? password : "";
92
93 if (userName == NULL)
94 return CHECKPW_UNKNOWNUSER;
95
96 siResult = checkpw_internal_pam(userName, thePassword);
97 switch (siResult) {
98 case CHECKPW_SUCCESS:
99 case CHECKPW_UNKNOWNUSER:
100 case CHECKPW_BADPASSWORD:
101 break;
102 default:
103 usleep(500000);
104 siResult = checkpw_internal_pam(userName, thePassword);
105 break;
106 }
107
108 return siResult;
109}
110