1/*
2 * Copyright (C) 2009 Apple Inc.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms of pam_self, with
5 * or without modification, are permitted provided that the following
6 * conditions are met:
7 *
8 * 1. Redistributions of source code must retain any existing copyright
9 * notice, and this entire permission notice in its entirety,
10 * including the disclaimer of warranties.
11 *
12 * 2. Redistributions in binary form must reproduce all prior and current
13 * copyright notices, this list of conditions, and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 *
17 * 3. The name of any author may not be used to endorse or promote
18 * products derived from this software without their specific prior
19 * written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
29 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
30 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 * DAMAGE.
32 */
33
34#include <security/pam_modules.h>
35#include <security/pam_appl.h>
36#include <pwd.h>
37#include <sys/syslimits.h>
38
39PAM_EXTERN int
40pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
41{
42	const char *user = NULL, *ruser = NULL;
43	struct passwd *pwd, *rpwd;
44	struct passwd pwdbuf;
45	char pwbuffer[2 * PATH_MAX];
46	uid_t uid, ruid;
47
48	/* get target account */
49	if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS ||
50	    NULL == user || 0 != getpwnam_r(user, &pwdbuf, pwbuffer, sizeof(pwbuffer), &pwd) || NULL == pwd) {
51		openpam_log(PAM_LOG_DEBUG, "Invalid user.");
52		return PAM_AUTH_ERR;
53	}
54	uid = pwd->pw_uid;
55
56	/* get applicant */
57	if (pam_get_item(pamh, PAM_RUSER, (const void **)&ruser) != PAM_SUCCESS ||
58	    NULL == ruser || 0 != getpwnam_r(ruser, &pwdbuf, pwbuffer, sizeof(pwbuffer), &rpwd) || NULL == rpwd) {
59		openpam_log(PAM_LOG_DEBUG, "Invalid remote user.");
60		return PAM_AUTH_ERR;
61	}
62	ruid = rpwd->pw_uid;
63
64	/* compare */
65	if (uid != ruid) {
66		openpam_log(PAM_LOG_DEBUG, "The provided user and remote user do not match.");
67		return PAM_AUTH_ERR;
68	}
69
70	return PAM_SUCCESS;
71}
72