4 * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
5 * See the end of the file for Copyright Information
8 * 1.2 - added 'deny' and 'group=' options
9 * 1.1 - added 'trust' option
10 * 1.0 - the code is working for at least another person, so... :-)
11 * 0.1 - use vsyslog instead of vfprintf/syslog in _pam_log
12 * - return PAM_IGNORE on success (take care of sloppy sysadmins..)
13 * - use pam_get_user instead of pam_get_item(...,PAM_USER,...)
14 * - a new arg use_uid to auth the current uid instead of the
15 * initial (logged in) one.
19 * - try to use make_remark from pam_unix/support.c
20 * - consider returning on failure PAM_FAIL_NOW if the user is not
23 * $FreeBSD: src/contrib/libpam/modules/pam_wheel/pam_wheel.c,v 1.3.2.2 2001/06/11 15:28:35 markm Exp $
33 #include <sys/types.h>
38 * here, we make a definition for the externally accessible function
39 * in this file (this definition is required for static a module
40 * but strongly encouraged generally) it is used to instruct the
41 * modules include file to define the function prototypes.
46 #include <security/pam_modules.h>
50 static void _pam_log(int err, const char *format, ...)
54 va_start(args, format);
55 openlog("PAM-Wheel", LOG_CONS|LOG_PID, LOG_AUTH);
56 vsyslog(err, format, args);
61 /* checks if a user is on a list of members of the GID 0 group */
63 static int is_on_list(char * const *list, const char *member)
66 if (strcmp(*list, member) == 0)
73 /* argument parsing */
75 #define PAM_DEBUG_ARG 0x0001
76 #define PAM_USE_UID_ARG 0x0002
77 #define PAM_TRUST_ARG 0x0004
78 #define PAM_DENY_ARG 0x0010
80 static int _pam_parse(int argc, const char **argv, char *use_group)
84 /* step through arguments */
85 for (ctrl=0; argc-- > 0; ++argv) {
89 if (!strcmp(*argv,"debug"))
90 ctrl |= PAM_DEBUG_ARG;
91 else if (!strcmp(*argv,"use_uid"))
92 ctrl |= PAM_USE_UID_ARG;
93 else if (!strcmp(*argv,"trust"))
94 ctrl |= PAM_TRUST_ARG;
95 else if (!strcmp(*argv,"deny"))
97 else if (!strncmp(*argv,"group=",6))
98 strcpy(use_group,*argv+6);
100 _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
108 /* --- authentication management functions (only) --- */
111 int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
115 const char *username;
117 struct passwd *pwd, *tpwd;
119 int retval = PAM_AUTH_ERR;
120 char use_group[BUFSIZ];
122 /* Init the optional group */
123 bzero(use_group,BUFSIZ);
125 ctrl = _pam_parse(argc, argv, use_group);
126 retval = pam_get_user(pamh,&username,NULL);
127 if ((retval != PAM_SUCCESS) || (!username)) {
128 if (ctrl & PAM_DEBUG_ARG)
129 _pam_log(LOG_DEBUG,"can not get the username");
130 return PAM_SERVICE_ERR;
133 /* su to a uid 0 account ? */
134 pwd = getpwnam(username);
136 if (ctrl & PAM_DEBUG_ARG)
137 _pam_log(LOG_NOTICE,"unknown user %s",username);
138 return PAM_USER_UNKNOWN;
141 /* Now we know that the username exists, pass on to other modules...
142 * the call to pam_get_user made this obsolete, so is commented out
144 * pam_set_item(pamh,PAM_USER,(const void *)username);
147 /* is this user an UID 0 account ? */
149 /* no need to check for wheel */
153 if (ctrl & PAM_USE_UID_ARG) {
154 tpwd = getpwuid(getuid());
156 if (ctrl & PAM_DEBUG_ARG)
157 _pam_log(LOG_NOTICE,"who is running me ?!");
158 return PAM_SERVICE_ERR;
160 fromsu = tpwd->pw_name;
164 if (ctrl & PAM_DEBUG_ARG)
165 _pam_log(LOG_NOTICE,"who is running me ?!");
166 return PAM_SERVICE_ERR;
171 if ((grp = getgrnam("wheel")) == NULL) {
175 grp = getgrnam(use_group);
177 if (!grp || !grp->gr_mem) {
178 if (ctrl & PAM_DEBUG_ARG) {
180 _pam_log(LOG_NOTICE,"no members in a GID 0 group");
182 _pam_log(LOG_NOTICE,"no members in '%s' group",use_group);
184 if (ctrl & PAM_DENY_ARG)
185 /* if this was meant to deny access to the members
186 * of this group and the group does not exist, allow
194 if (is_on_list(grp->gr_mem, fromsu)) {
195 if (ctrl & PAM_DEBUG_ARG)
196 _pam_log(LOG_NOTICE,"Access %s to '%s' for '%s'",
197 (ctrl & PAM_DENY_ARG)?"denied":"granted",
199 if (ctrl & PAM_DENY_ARG)
200 return PAM_PERM_DENIED;
202 if (ctrl & PAM_TRUST_ARG)
208 if (ctrl & PAM_DEBUG_ARG)
209 _pam_log(LOG_NOTICE,"Access %s for '%s' to '%s'",
210 (ctrl & PAM_DENY_ARG)?"granted":"denied",fromsu,username);
211 if (ctrl & PAM_DENY_ARG)
214 return PAM_PERM_DENIED;
218 int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
225 /* end of module definition */
227 PAM_MODULE_ENTRY("pam_wheel");
230 * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1996, 1997
231 * All rights reserved
233 * Redistribution and use in source and binary forms, with or without
234 * modification, are permitted provided that the following conditions
236 * 1. Redistributions of source code must retain the above copyright
237 * notice, and the entire permission notice in its entirety,
238 * including the disclaimer of warranties.
239 * 2. Redistributions in binary form must reproduce the above copyright
240 * notice, this list of conditions and the following disclaimer in the
241 * documentation and/or other materials provided with the distribution.
242 * 3. The name of the author may not be used to endorse or promote
243 * products derived from this software without specific prior
244 * written permission.
246 * ALTERNATIVELY, this product may be distributed under the terms of
247 * the GNU Public License, in which case the provisions of the GPL are
248 * required INSTEAD OF the above restrictions. (This clause is
249 * necessary due to a potential bad interaction between the GPL and
250 * the restrictions contained in a BSD-style copyright.)
252 * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
253 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
254 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
255 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
256 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
257 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
258 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
259 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
260 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
261 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
262 * OF THE POSSIBILITY OF SUCH DAMAGE.