Remove extra whitespace at the end of some lines.
[dragonfly.git] / contrib / libpam / modules / pam_wheel / pam_wheel.c
... / ...
CommitLineData
1/* pam_wheel module */
2
3/*
4 * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
5 * See the end of the file for Copyright Information
6 *
7 *
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.
16 * 0.0 - first release
17 *
18 * TODO:
19 * - try to use make_remark from pam_unix/support.c
20 * - consider returning on failure PAM_FAIL_NOW if the user is not
21 * a wheel member.
22 *
23 * $FreeBSD: src/contrib/libpam/modules/pam_wheel/pam_wheel.c,v 1.3.2.2 2001/06/11 15:28:35 markm Exp $
24 * $DragonFly: src/contrib/libpam/modules/pam_wheel/Attic/pam_wheel.c,v 1.2 2003/06/17 04:24:03 dillon Exp $
25 */
26
27#define _BSD_SOURCE
28
29#include <stdio.h>
30#include <unistd.h>
31#include <string.h>
32#include <syslog.h>
33#include <stdarg.h>
34#include <sys/types.h>
35#include <pwd.h>
36#include <grp.h>
37
38/*
39 * here, we make a definition for the externally accessible function
40 * in this file (this definition is required for static a module
41 * but strongly encouraged generally) it is used to instruct the
42 * modules include file to define the function prototypes.
43 */
44
45#define PAM_SM_AUTH
46
47#include <security/pam_modules.h>
48
49/* some syslogging */
50
51static void _pam_log(int err, const char *format, ...)
52{
53 va_list args;
54
55 va_start(args, format);
56 openlog("PAM-Wheel", LOG_CONS|LOG_PID, LOG_AUTH);
57 vsyslog(err, format, args);
58 va_end(args);
59 closelog();
60}
61
62/* checks if a user is on a list of members of the GID 0 group */
63
64static int is_on_list(char * const *list, const char *member)
65{
66 while (*list) {
67 if (strcmp(*list, member) == 0)
68 return 1;
69 list++;
70 }
71 return 0;
72}
73
74/* argument parsing */
75
76#define PAM_DEBUG_ARG 0x0001
77#define PAM_USE_UID_ARG 0x0002
78#define PAM_TRUST_ARG 0x0004
79#define PAM_DENY_ARG 0x0010
80
81static int _pam_parse(int argc, const char **argv, char *use_group)
82{
83 int ctrl=0;
84
85 /* step through arguments */
86 for (ctrl=0; argc-- > 0; ++argv) {
87
88 /* generic options */
89
90 if (!strcmp(*argv,"debug"))
91 ctrl |= PAM_DEBUG_ARG;
92 else if (!strcmp(*argv,"use_uid"))
93 ctrl |= PAM_USE_UID_ARG;
94 else if (!strcmp(*argv,"trust"))
95 ctrl |= PAM_TRUST_ARG;
96 else if (!strcmp(*argv,"deny"))
97 ctrl |= PAM_DENY_ARG;
98 else if (!strncmp(*argv,"group=",6))
99 strcpy(use_group,*argv+6);
100 else {
101 _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
102 }
103 }
104
105 return ctrl;
106}
107
108
109/* --- authentication management functions (only) --- */
110
111PAM_EXTERN
112int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
113 ,const char **argv)
114{
115 int ctrl;
116 const char *username;
117 char *fromsu;
118 struct passwd *pwd, *tpwd;
119 struct group *grp;
120 int retval = PAM_AUTH_ERR;
121 char use_group[BUFSIZ];
122
123 /* Init the optional group */
124 bzero(use_group,BUFSIZ);
125
126 ctrl = _pam_parse(argc, argv, use_group);
127 retval = pam_get_user(pamh,&username,NULL);
128 if ((retval != PAM_SUCCESS) || (!username)) {
129 if (ctrl & PAM_DEBUG_ARG)
130 _pam_log(LOG_DEBUG,"can not get the username");
131 return PAM_SERVICE_ERR;
132 }
133
134 /* su to a uid 0 account ? */
135 pwd = getpwnam(username);
136 if (!pwd) {
137 if (ctrl & PAM_DEBUG_ARG)
138 _pam_log(LOG_NOTICE,"unknown user %s",username);
139 return PAM_USER_UNKNOWN;
140 }
141
142 /* Now we know that the username exists, pass on to other modules...
143 * the call to pam_get_user made this obsolete, so is commented out
144 *
145 * pam_set_item(pamh,PAM_USER,(const void *)username);
146 */
147
148 /* is this user an UID 0 account ? */
149 if(pwd->pw_uid) {
150 /* no need to check for wheel */
151 return PAM_IGNORE;
152 }
153
154 if (ctrl & PAM_USE_UID_ARG) {
155 tpwd = getpwuid(getuid());
156 if (!tpwd) {
157 if (ctrl & PAM_DEBUG_ARG)
158 _pam_log(LOG_NOTICE,"who is running me ?!");
159 return PAM_SERVICE_ERR;
160 }
161 fromsu = tpwd->pw_name;
162 } else {
163 fromsu = getlogin();
164 if (!fromsu) {
165 if (ctrl & PAM_DEBUG_ARG)
166 _pam_log(LOG_NOTICE,"who is running me ?!");
167 return PAM_SERVICE_ERR;
168 }
169 }
170
171 if (!use_group[0]) {
172 if ((grp = getgrnam("wheel")) == NULL) {
173 grp = getgrgid(0);
174 }
175 } else
176 grp = getgrnam(use_group);
177
178 if (!grp || !grp->gr_mem) {
179 if (ctrl & PAM_DEBUG_ARG) {
180 if (!use_group[0])
181 _pam_log(LOG_NOTICE,"no members in a GID 0 group");
182 else
183 _pam_log(LOG_NOTICE,"no members in '%s' group",use_group);
184 }
185 if (ctrl & PAM_DENY_ARG)
186 /* if this was meant to deny access to the members
187 * of this group and the group does not exist, allow
188 * access
189 */
190 return PAM_IGNORE;
191 else
192 return PAM_AUTH_ERR;
193 }
194
195 if (is_on_list(grp->gr_mem, fromsu)) {
196 if (ctrl & PAM_DEBUG_ARG)
197 _pam_log(LOG_NOTICE,"Access %s to '%s' for '%s'",
198 (ctrl & PAM_DENY_ARG)?"denied":"granted",
199 fromsu,username);
200 if (ctrl & PAM_DENY_ARG)
201 return PAM_PERM_DENIED;
202 else
203 if (ctrl & PAM_TRUST_ARG)
204 return PAM_SUCCESS;
205 else
206 return PAM_IGNORE;
207 }
208
209 if (ctrl & PAM_DEBUG_ARG)
210 _pam_log(LOG_NOTICE,"Access %s for '%s' to '%s'",
211 (ctrl & PAM_DENY_ARG)?"granted":"denied",fromsu,username);
212 if (ctrl & PAM_DENY_ARG)
213 return PAM_SUCCESS;
214 else
215 return PAM_PERM_DENIED;
216}
217
218PAM_EXTERN
219int pam_sm_setcred(pam_handle_t *pamh,int flags,int argc
220 ,const char **argv)
221{
222 return PAM_SUCCESS;
223}
224
225
226/* end of module definition */
227
228PAM_MODULE_ENTRY("pam_wheel");
229
230/*
231 * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1996, 1997
232 * All rights reserved
233 *
234 * Redistribution and use in source and binary forms, with or without
235 * modification, are permitted provided that the following conditions
236 * are met:
237 * 1. Redistributions of source code must retain the above copyright
238 * notice, and the entire permission notice in its entirety,
239 * including the disclaimer of warranties.
240 * 2. Redistributions in binary form must reproduce the above copyright
241 * notice, this list of conditions and the following disclaimer in the
242 * documentation and/or other materials provided with the distribution.
243 * 3. The name of the author may not be used to endorse or promote
244 * products derived from this software without specific prior
245 * written permission.
246 *
247 * ALTERNATIVELY, this product may be distributed under the terms of
248 * the GNU Public License, in which case the provisions of the GPL are
249 * required INSTEAD OF the above restrictions. (This clause is
250 * necessary due to a potential bad interaction between the GPL and
251 * the restrictions contained in a BSD-style copyright.)
252 *
253 * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
254 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
255 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
256 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
257 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
258 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
259 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
260 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
261 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
262 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
263 * OF THE POSSIBILITY OF SUCH DAMAGE.
264 */