Magellan Linux

Contents of /trunk/pam/patches/pam-1.1.4-pam-console.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1461 - (show annotations) (download)
Tue Aug 2 09:12:06 2011 UTC (12 years, 9 months ago) by niro
File size: 136951 byte(s)
-added RH pam_console patch
1 Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
2 Date: 2007-01-21
3 Initial Package Version: 0.99.7.0
4 Origin: http://redhat.download.fedoraproject.org/pub/fedora/linux/core/updates/6/SRPMS/pam-0.99.6.2-3.9.fc6.src.rpm
5 Upstream Status: From Fedora/Redhat
6 Description: Adds pam_console module
7 Rediffed against 1.1.0 by Joe Ciccone <jciccone@gmail.com> on 2009-07-09
8 Rediffed against 1.1.3 by Joe Ciccone <jciccone@gmail.com> on 2011-01-26
9
10 diff -Naur Linux-PAM-1.1.3.orig/configure.in Linux-PAM-1.1.3/configure.in
11 --- Linux-PAM-1.1.3.orig/configure.in 2010-10-27 09:19:13.000000000 -0400
12 +++ Linux-PAM-1.1.3/configure.in 2011-01-26 22:14:52.059406906 -0500
13 @@ -568,7 +568,7 @@
14 AC_CONFIG_FILES([Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile \
15 libpam_misc/Makefile conf/Makefile conf/pam_conv1/Makefile \
16 po/Makefile.in \
17 - modules/Makefile \
18 + modules/Makefile modules/pam_console/Makefile \
19 modules/pam_access/Makefile modules/pam_cracklib/Makefile \
20 modules/pam_debug/Makefile modules/pam_deny/Makefile \
21 modules/pam_echo/Makefile modules/pam_env/Makefile \
22 diff -Naur Linux-PAM-1.1.3.orig/modules/Makefile.am Linux-PAM-1.1.3/modules/Makefile.am
23 --- Linux-PAM-1.1.3.orig/modules/Makefile.am 2008-11-28 09:29:12.000000000 -0500
24 +++ Linux-PAM-1.1.3/modules/Makefile.am 2011-01-26 22:14:52.059406906 -0500
25 @@ -2,7 +2,7 @@
26 # Copyright (c) 2005, 2006, 2008 Thorsten Kukuk <kukuk@thkukuk.de>
27 #
28
29 -SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
30 +SUBDIRS = pam_access pam_cracklib pam_console pam_debug pam_deny pam_echo \
31 pam_env pam_exec pam_faildelay pam_filter pam_ftp \
32 pam_group pam_issue pam_keyinit pam_lastlog pam_limits \
33 pam_listfile pam_localuser pam_loginuid pam_mail \
34 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/.cvsignore Linux-PAM-1.1.3/modules/pam_console/.cvsignore
35 --- Linux-PAM-1.1.3.orig/modules/pam_console/.cvsignore 1969-12-31 19:00:00.000000000 -0500
36 +++ Linux-PAM-1.1.3/modules/pam_console/.cvsignore 2011-01-26 22:14:52.062657563 -0500
37 @@ -0,0 +1,3 @@
38 +configfile.tab.c
39 +configfile.tab.h
40 +configfile.lex.c
41 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/50-default.perms Linux-PAM-1.1.3/modules/pam_console/50-default.perms
42 --- Linux-PAM-1.1.3.orig/modules/pam_console/50-default.perms 1969-12-31 19:00:00.000000000 -0500
43 +++ Linux-PAM-1.1.3/modules/pam_console/50-default.perms 2011-01-26 22:14:52.059406906 -0500
44 @@ -0,0 +1,61 @@
45 +# device classes -- these are shell-style globs
46 +<floppy>=/dev/fd[0-1]* \
47 + /dev/floppy* /mnt/floppy*
48 +<sound>=/dev/dsp* /dev/audio* /dev/midi* \
49 + /dev/mixer* /dev/sequencer* \
50 + /dev/sound/* /dev/beep \
51 + /dev/snd/*
52 +<cdrom>=/dev/cdrom* /dev/cdroms/* /dev/cdwriter* /mnt/cdrom*
53 +<pilot>=/dev/pilot
54 +<jaz>=/mnt/jaz*
55 +<zip>=/mnt/pocketzip* /mnt/zip* /dev/zip*
56 +<ls120>=/dev/ls120 /mnt/ls120*
57 +<scanner>=/dev/scanner* /dev/usb/scanner*
58 +<rio500>=/dev/usb/rio500
59 +<camera>=/mnt/camera* /dev/usb/dc2xx* /dev/usb/mdc800*
60 +<memstick>=/mnt/memstick*
61 +<flash>=/mnt/flash* /dev/flash*
62 +<diskonkey>=/mnt/diskonkey*
63 +<rem_ide>=/mnt/microdrive*
64 +<fb>=/dev/fb /dev/fb[0-9]* \
65 + /dev/fb/*
66 +<kbd>=/dev/kbd
67 +<joystick>=/dev/js[0-9]*
68 +<v4l>=/dev/video* /dev/radio* /dev/winradio* /dev/vtx* /dev/vbi* \
69 + /dev/video/*
70 +<gpm>=/dev/gpmctl
71 +<dri>=/dev/nvidia* /dev/3dfx* /dev/dri/card*
72 +<mainboard>=/dev/apm_bios
73 +<pmu>=/dev/pmu
74 +<bluetooth>=/dev/rfcomm*
75 +<raw1394>=/dev/raw1394
76 +<irda>=/dev/ircomm*
77 +
78 +# permission definitions
79 +<console> 0660 <floppy> 0660 root.floppy
80 +<console> 0600 <sound> 0600 root
81 +<console> 0600 <cdrom> 0660 root.disk
82 +<console> 0600 <pilot> 0660 root.uucp
83 +<console> 0600 <jaz> 0660 root.disk
84 +<console> 0600 <zip> 0660 root.disk
85 +<console> 0600 <ls120> 0660 root.disk
86 +<console> 0600 <scanner> 0600 root
87 +<console> 0600 <camera> 0600 root.disk
88 +<console> 0600 <memstick> 0600 root.disk
89 +<console> 0600 <flash> 0600 root.disk
90 +<console> 0600 <diskonkey> 0660 root.disk
91 +<console> 0600 <rem_ide> 0660 root.disk
92 +<console> 0600 <fb> 0600 root
93 +<console> 0600 <kbd> 0600 root
94 +<console> 0600 <joystick> 0600 root
95 +<console> 0600 <v4l> 0600 root
96 +<console> 0700 <gpm> 0700 root
97 +<console> 0600 <mainboard> 0600 root
98 +<console> 0600 <rio500> 0600 root
99 +<console> 0600 <pmu> 0600 root
100 +<console> 0600 <bluetooth> 0600 root
101 +<console> 0600 <raw1394> 0600 root
102 +<console> 0600 <irda> 0600 root
103 +
104 +<xconsole> 0600 /dev/console 0600 root.root
105 +<console> 0600 <dri> 0600 root
106 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/COPYING Linux-PAM-1.1.3/modules/pam_console/COPYING
107 --- Linux-PAM-1.1.3.orig/modules/pam_console/COPYING 1969-12-31 19:00:00.000000000 -0500
108 +++ Linux-PAM-1.1.3/modules/pam_console/COPYING 2011-01-26 22:14:52.062657563 -0500
109 @@ -0,0 +1,340 @@
110 + GNU GENERAL PUBLIC LICENSE
111 + Version 2, June 1991
112 +
113 + Copyright (C) 1989, 1991 Free Software Foundation, Inc.
114 + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
115 + Everyone is permitted to copy and distribute verbatim copies
116 + of this license document, but changing it is not allowed.
117 +
118 + Preamble
119 +
120 + The licenses for most software are designed to take away your
121 +freedom to share and change it. By contrast, the GNU General Public
122 +License is intended to guarantee your freedom to share and change free
123 +software--to make sure the software is free for all its users. This
124 +General Public License applies to most of the Free Software
125 +Foundation's software and to any other program whose authors commit to
126 +using it. (Some other Free Software Foundation software is covered by
127 +the GNU Library General Public License instead.) You can apply it to
128 +your programs, too.
129 +
130 + When we speak of free software, we are referring to freedom, not
131 +price. Our General Public Licenses are designed to make sure that you
132 +have the freedom to distribute copies of free software (and charge for
133 +this service if you wish), that you receive source code or can get it
134 +if you want it, that you can change the software or use pieces of it
135 +in new free programs; and that you know you can do these things.
136 +
137 + To protect your rights, we need to make restrictions that forbid
138 +anyone to deny you these rights or to ask you to surrender the rights.
139 +These restrictions translate to certain responsibilities for you if you
140 +distribute copies of the software, or if you modify it.
141 +
142 + For example, if you distribute copies of such a program, whether
143 +gratis or for a fee, you must give the recipients all the rights that
144 +you have. You must make sure that they, too, receive or can get the
145 +source code. And you must show them these terms so they know their
146 +rights.
147 +
148 + We protect your rights with two steps: (1) copyright the software, and
149 +(2) offer you this license which gives you legal permission to copy,
150 +distribute and/or modify the software.
151 +
152 + Also, for each author's protection and ours, we want to make certain
153 +that everyone understands that there is no warranty for this free
154 +software. If the software is modified by someone else and passed on, we
155 +want its recipients to know that what they have is not the original, so
156 +that any problems introduced by others will not reflect on the original
157 +authors' reputations.
158 +
159 + Finally, any free program is threatened constantly by software
160 +patents. We wish to avoid the danger that redistributors of a free
161 +program will individually obtain patent licenses, in effect making the
162 +program proprietary. To prevent this, we have made it clear that any
163 +patent must be licensed for everyone's free use or not licensed at all.
164 +
165 + The precise terms and conditions for copying, distribution and
166 +modification follow.
167 +
168 + GNU GENERAL PUBLIC LICENSE
169 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
170 +
171 + 0. This License applies to any program or other work which contains
172 +a notice placed by the copyright holder saying it may be distributed
173 +under the terms of this General Public License. The "Program", below,
174 +refers to any such program or work, and a "work based on the Program"
175 +means either the Program or any derivative work under copyright law:
176 +that is to say, a work containing the Program or a portion of it,
177 +either verbatim or with modifications and/or translated into another
178 +language. (Hereinafter, translation is included without limitation in
179 +the term "modification".) Each licensee is addressed as "you".
180 +
181 +Activities other than copying, distribution and modification are not
182 +covered by this License; they are outside its scope. The act of
183 +running the Program is not restricted, and the output from the Program
184 +is covered only if its contents constitute a work based on the
185 +Program (independent of having been made by running the Program).
186 +Whether that is true depends on what the Program does.
187 +
188 + 1. You may copy and distribute verbatim copies of the Program's
189 +source code as you receive it, in any medium, provided that you
190 +conspicuously and appropriately publish on each copy an appropriate
191 +copyright notice and disclaimer of warranty; keep intact all the
192 +notices that refer to this License and to the absence of any warranty;
193 +and give any other recipients of the Program a copy of this License
194 +along with the Program.
195 +
196 +You may charge a fee for the physical act of transferring a copy, and
197 +you may at your option offer warranty protection in exchange for a fee.
198 +
199 + 2. You may modify your copy or copies of the Program or any portion
200 +of it, thus forming a work based on the Program, and copy and
201 +distribute such modifications or work under the terms of Section 1
202 +above, provided that you also meet all of these conditions:
203 +
204 + a) You must cause the modified files to carry prominent notices
205 + stating that you changed the files and the date of any change.
206 +
207 + b) You must cause any work that you distribute or publish, that in
208 + whole or in part contains or is derived from the Program or any
209 + part thereof, to be licensed as a whole at no charge to all third
210 + parties under the terms of this License.
211 +
212 + c) If the modified program normally reads commands interactively
213 + when run, you must cause it, when started running for such
214 + interactive use in the most ordinary way, to print or display an
215 + announcement including an appropriate copyright notice and a
216 + notice that there is no warranty (or else, saying that you provide
217 + a warranty) and that users may redistribute the program under
218 + these conditions, and telling the user how to view a copy of this
219 + License. (Exception: if the Program itself is interactive but
220 + does not normally print such an announcement, your work based on
221 + the Program is not required to print an announcement.)
222 +
223 +These requirements apply to the modified work as a whole. If
224 +identifiable sections of that work are not derived from the Program,
225 +and can be reasonably considered independent and separate works in
226 +themselves, then this License, and its terms, do not apply to those
227 +sections when you distribute them as separate works. But when you
228 +distribute the same sections as part of a whole which is a work based
229 +on the Program, the distribution of the whole must be on the terms of
230 +this License, whose permissions for other licensees extend to the
231 +entire whole, and thus to each and every part regardless of who wrote it.
232 +
233 +Thus, it is not the intent of this section to claim rights or contest
234 +your rights to work written entirely by you; rather, the intent is to
235 +exercise the right to control the distribution of derivative or
236 +collective works based on the Program.
237 +
238 +In addition, mere aggregation of another work not based on the Program
239 +with the Program (or with a work based on the Program) on a volume of
240 +a storage or distribution medium does not bring the other work under
241 +the scope of this License.
242 +
243 + 3. You may copy and distribute the Program (or a work based on it,
244 +under Section 2) in object code or executable form under the terms of
245 +Sections 1 and 2 above provided that you also do one of the following:
246 +
247 + a) Accompany it with the complete corresponding machine-readable
248 + source code, which must be distributed under the terms of Sections
249 + 1 and 2 above on a medium customarily used for software interchange; or,
250 +
251 + b) Accompany it with a written offer, valid for at least three
252 + years, to give any third party, for a charge no more than your
253 + cost of physically performing source distribution, a complete
254 + machine-readable copy of the corresponding source code, to be
255 + distributed under the terms of Sections 1 and 2 above on a medium
256 + customarily used for software interchange; or,
257 +
258 + c) Accompany it with the information you received as to the offer
259 + to distribute corresponding source code. (This alternative is
260 + allowed only for noncommercial distribution and only if you
261 + received the program in object code or executable form with such
262 + an offer, in accord with Subsection b above.)
263 +
264 +The source code for a work means the preferred form of the work for
265 +making modifications to it. For an executable work, complete source
266 +code means all the source code for all modules it contains, plus any
267 +associated interface definition files, plus the scripts used to
268 +control compilation and installation of the executable. However, as a
269 +special exception, the source code distributed need not include
270 +anything that is normally distributed (in either source or binary
271 +form) with the major components (compiler, kernel, and so on) of the
272 +operating system on which the executable runs, unless that component
273 +itself accompanies the executable.
274 +
275 +If distribution of executable or object code is made by offering
276 +access to copy from a designated place, then offering equivalent
277 +access to copy the source code from the same place counts as
278 +distribution of the source code, even though third parties are not
279 +compelled to copy the source along with the object code.
280 +
281 + 4. You may not copy, modify, sublicense, or distribute the Program
282 +except as expressly provided under this License. Any attempt
283 +otherwise to copy, modify, sublicense or distribute the Program is
284 +void, and will automatically terminate your rights under this License.
285 +However, parties who have received copies, or rights, from you under
286 +this License will not have their licenses terminated so long as such
287 +parties remain in full compliance.
288 +
289 + 5. You are not required to accept this License, since you have not
290 +signed it. However, nothing else grants you permission to modify or
291 +distribute the Program or its derivative works. These actions are
292 +prohibited by law if you do not accept this License. Therefore, by
293 +modifying or distributing the Program (or any work based on the
294 +Program), you indicate your acceptance of this License to do so, and
295 +all its terms and conditions for copying, distributing or modifying
296 +the Program or works based on it.
297 +
298 + 6. Each time you redistribute the Program (or any work based on the
299 +Program), the recipient automatically receives a license from the
300 +original licensor to copy, distribute or modify the Program subject to
301 +these terms and conditions. You may not impose any further
302 +restrictions on the recipients' exercise of the rights granted herein.
303 +You are not responsible for enforcing compliance by third parties to
304 +this License.
305 +
306 + 7. If, as a consequence of a court judgment or allegation of patent
307 +infringement or for any other reason (not limited to patent issues),
308 +conditions are imposed on you (whether by court order, agreement or
309 +otherwise) that contradict the conditions of this License, they do not
310 +excuse you from the conditions of this License. If you cannot
311 +distribute so as to satisfy simultaneously your obligations under this
312 +License and any other pertinent obligations, then as a consequence you
313 +may not distribute the Program at all. For example, if a patent
314 +license would not permit royalty-free redistribution of the Program by
315 +all those who receive copies directly or indirectly through you, then
316 +the only way you could satisfy both it and this License would be to
317 +refrain entirely from distribution of the Program.
318 +
319 +If any portion of this section is held invalid or unenforceable under
320 +any particular circumstance, the balance of the section is intended to
321 +apply and the section as a whole is intended to apply in other
322 +circumstances.
323 +
324 +It is not the purpose of this section to induce you to infringe any
325 +patents or other property right claims or to contest validity of any
326 +such claims; this section has the sole purpose of protecting the
327 +integrity of the free software distribution system, which is
328 +implemented by public license practices. Many people have made
329 +generous contributions to the wide range of software distributed
330 +through that system in reliance on consistent application of that
331 +system; it is up to the author/donor to decide if he or she is willing
332 +to distribute software through any other system and a licensee cannot
333 +impose that choice.
334 +
335 +This section is intended to make thoroughly clear what is believed to
336 +be a consequence of the rest of this License.
337 +
338 + 8. If the distribution and/or use of the Program is restricted in
339 +certain countries either by patents or by copyrighted interfaces, the
340 +original copyright holder who places the Program under this License
341 +may add an explicit geographical distribution limitation excluding
342 +those countries, so that distribution is permitted only in or among
343 +countries not thus excluded. In such case, this License incorporates
344 +the limitation as if written in the body of this License.
345 +
346 + 9. The Free Software Foundation may publish revised and/or new versions
347 +of the General Public License from time to time. Such new versions will
348 +be similar in spirit to the present version, but may differ in detail to
349 +address new problems or concerns.
350 +
351 +Each version is given a distinguishing version number. If the Program
352 +specifies a version number of this License which applies to it and "any
353 +later version", you have the option of following the terms and conditions
354 +either of that version or of any later version published by the Free
355 +Software Foundation. If the Program does not specify a version number of
356 +this License, you may choose any version ever published by the Free Software
357 +Foundation.
358 +
359 + 10. If you wish to incorporate parts of the Program into other free
360 +programs whose distribution conditions are different, write to the author
361 +to ask for permission. For software which is copyrighted by the Free
362 +Software Foundation, write to the Free Software Foundation; we sometimes
363 +make exceptions for this. Our decision will be guided by the two goals
364 +of preserving the free status of all derivatives of our free software and
365 +of promoting the sharing and reuse of software generally.
366 +
367 + NO WARRANTY
368 +
369 + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
370 +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
371 +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
372 +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
373 +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
374 +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
375 +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
376 +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
377 +REPAIR OR CORRECTION.
378 +
379 + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
380 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
381 +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
382 +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
383 +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
384 +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
385 +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
386 +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
387 +POSSIBILITY OF SUCH DAMAGES.
388 +
389 + END OF TERMS AND CONDITIONS
390 +
391 + How to Apply These Terms to Your New Programs
392 +
393 + If you develop a new program, and you want it to be of the greatest
394 +possible use to the public, the best way to achieve this is to make it
395 +free software which everyone can redistribute and change under these terms.
396 +
397 + To do so, attach the following notices to the program. It is safest
398 +to attach them to the start of each source file to most effectively
399 +convey the exclusion of warranty; and each file should have at least
400 +the "copyright" line and a pointer to where the full notice is found.
401 +
402 + <one line to give the program's name and a brief idea of what it does.>
403 + Copyright (C) 19yy <name of author>
404 +
405 + This program is free software; you can redistribute it and/or modify
406 + it under the terms of the GNU General Public License as published by
407 + the Free Software Foundation; either version 2 of the License, or
408 + (at your option) any later version.
409 +
410 + This program is distributed in the hope that it will be useful,
411 + but WITHOUT ANY WARRANTY; without even the implied warranty of
412 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
413 + GNU General Public License for more details.
414 +
415 + You should have received a copy of the GNU General Public License
416 + along with this program; if not, write to the Free Software
417 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
418 +
419 +
420 +Also add information on how to contact you by electronic and paper mail.
421 +
422 +If the program is interactive, make it output a short notice like this
423 +when it starts in an interactive mode:
424 +
425 + Gnomovision version 69, Copyright (C) 19yy name of author
426 + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
427 + This is free software, and you are welcome to redistribute it
428 + under certain conditions; type `show c' for details.
429 +
430 +The hypothetical commands `show w' and `show c' should show the appropriate
431 +parts of the General Public License. Of course, the commands you use may
432 +be called something other than `show w' and `show c'; they could even be
433 +mouse-clicks or menu items--whatever suits your program.
434 +
435 +You should also get your employer (if you work as a programmer) or your
436 +school, if any, to sign a "copyright disclaimer" for the program, if
437 +necessary. Here is a sample; alter the names:
438 +
439 + Yoyodyne, Inc., hereby disclaims all copyright interest in the program
440 + `Gnomovision' (which makes passes at compilers) written by James Hacker.
441 +
442 + <signature of Ty Coon>, 1 April 1989
443 + Ty Coon, President of Vice
444 +
445 +This General Public License does not permit incorporating your program into
446 +proprietary programs. If your program is a subroutine library, you may
447 +consider it more useful to permit linking proprietary applications with the
448 +library. If this is what you want to do, use the GNU Library General
449 +Public License instead of this License.
450 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/Makefile.am Linux-PAM-1.1.3/modules/pam_console/Makefile.am
451 --- Linux-PAM-1.1.3.orig/modules/pam_console/Makefile.am 1969-12-31 19:00:00.000000000 -0500
452 +++ Linux-PAM-1.1.3/modules/pam_console/Makefile.am 2011-01-26 22:14:52.062657563 -0500
453 @@ -0,0 +1,64 @@
454 +#
455 +# Copyright (c) 2005 Thorsten Kukuk <kukuk@suse.de>
456 +# Copyright (c) 2005 Red Hat, Inc.
457 +#
458 +
459 +CLEANFILES = *~
460 +
461 +CONFFILES = console.perms console.handlers 50-default.perms
462 +MAN5 = console.apps.5 console.perms.5 console.handlers.5
463 +MAN8 = pam_console.8 pam_console_apply.8
464 +
465 +man_MANS = $(MAN5) $(MAN8)
466 +
467 +EXTRA_DIST = README $(man_MANS) $(CONFFILES) sed-static configfile.y configfile.l
468 +
469 +LOCKDIR = /var/run/console
470 +LOCKMODE = 755
471 +
472 +securelibdir = $(SECUREDIR)
473 +secureconfdir = $(SCONFIGDIR)
474 +permsddir = $(SCONFIGDIR)/console.perms.d
475 +
476 +noinst_HEADERS = chmod.h configfile.h configfile.tab.h handlers.h modechange.h pam_console.h
477 +
478 +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
479 + $(GLIB_CFLAGS) -DLOCKDIR=\"$(LOCKDIR)\"
480 +
481 +pam_console_la_LDFLAGS = -no-undefined -avoid-version -module
482 +if HAVE_VERSIONING
483 + pam_console_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
484 +endif
485 +pam_console_la_LIBADD = -L$(top_builddir)/libpam -lpam
486 +
487 +pam_console_apply_LDADD = -L$(top_builddir)/libpam -lpam
488 +
489 +securelib_LTLIBRARIES = pam_console.la
490 +sbin_PROGRAMS = pam_console_apply
491 +
492 +
493 +secureconf_DATA = console.perms console.handlers
494 +
495 +FLEX_OPTS = -Cr
496 +BISON_OPTS = -d
497 +
498 +pam_console_la_SOURCES = pam_console.c pam_console.h regerr.c handlers.c handlers.h
499 +pam_console_apply_SOURCES = pam_console_apply.c pam_console.h chmod.c modechange.c regerr.c \
500 + configfile.c configfile.h hashtable.c hashtable.h hashtable_private.h
501 +
502 +pam_console_la_CFLAGS = $(AM_CFLAGS)
503 +pam_console_apply_CFLAGS = $(AM_CFLAGS)
504 +
505 +configfile.tab.c: configfile.y
506 + $(YACC) $(BISON_OPTS) -o $@ -p _pc_yy $<
507 + sh $(srcdir)/sed-static $@
508 +
509 +configfile.lex.c: configfile.l configfile.tab.c
510 + $(LEX) $(FLEX_OPTS) -o$@ -P_pc_yy $<
511 + sh $(srcdir)/sed-static $@
512 +
513 +configfile.c: configfile.tab.c configfile.lex.c
514 +
515 +install-data-local:
516 + mkdir -p $(DESTDIR)$(secureconfdir)/console.apps
517 + mkdir -m $(LOCKMODE) -p -p $(DESTDIR)$(LOCKDIR)
518 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/README Linux-PAM-1.1.3/modules/pam_console/README
519 --- Linux-PAM-1.1.3.orig/modules/pam_console/README 1969-12-31 19:00:00.000000000 -0500
520 +++ Linux-PAM-1.1.3/modules/pam_console/README 2011-01-26 22:14:52.062657563 -0500
521 @@ -0,0 +1,45 @@
522 +README for pam_console
523 +======================
524 +
525 +NOTE: This software is very powerful. Incautious use could leave your
526 +system open to attack, or difficult to use.
527 +
528 +pam_console is distributed in the hope that it will be useful,
529 +but WITHOUT ANY WARRANTY; without even the implied warranty of
530 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
531 +
532 +Because pam_console integrates GPL-licensed code, all of pam_console
533 +is licensed only under the GPL, unlike most PAM modules. See the
534 +file COPYING for the license terms under which this software is
535 +licensed.
536 +
537 +(If this software breaks your system, you get to keep all the pieces.)
538 +
539 +The pam_console module exists to change file permissions when users
540 +log on at the console, and to change them back when they log out of
541 +the console. It also cooperates with the pam_listfile module to
542 +make it possible to allow users who are at the console to run
543 +various programs that would otherwise be restricted to root only.
544 +
545 +The pam_console.8 and pam_console_apply.8 man pages explain this
546 +software in more detail.
547 +
548 +Please note: the current version depends on too many external tools
549 +and libraries, making it big and hard to evaluate for security.
550 +This is only a bootstrap stage; I'll be fixing it later. I'm using
551 +lex/yacc right now so that it is trivial to change the grammar, and
552 +I'm using glib because I didn't want to write my own hashtables
553 +while I was busy thinking about file locking. Don't report those
554 +as bugs, I'll fix them later once I've ironed out the important
555 +details...
556 +
557 +Michael K. Johnson
558 +Red Hat Software, Inc.
559 +
560 +Additional note: the current version is improved so that the functionality
561 +of changing the ownership and permissions of the devices is split out
562 +of the pam_console.so module to the pam_console_apply executable,
563 +which is called from the pam_console module when the lock is obtained.
564 +Thus the module doesn't depend on the glib.
565 +
566 +Copyright 1999, 2005 Red Hat, Inc.
567 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/chmod.c Linux-PAM-1.1.3/modules/pam_console/chmod.c
568 --- Linux-PAM-1.1.3.orig/modules/pam_console/chmod.c 1969-12-31 19:00:00.000000000 -0500
569 +++ Linux-PAM-1.1.3/modules/pam_console/chmod.c 2011-01-26 22:14:52.059406906 -0500
570 @@ -0,0 +1,240 @@
571 +/* This file is derived from chmod.c and stpcpy.c, included
572 + in the GNU fileutils distribution. It has been changed to be a
573 + library specifically for use within the Red Hat pam_console module.
574 + Changes Copyright 1999,2001 Red Hat, Inc.
575 + */
576 +
577 +/* chmod -- change permission modes of files
578 + Copyright (C) 89, 90, 91, 95, 1996 Free Software Foundation, Inc.
579 +
580 + This program is free software; you can redistribute it and/or modify
581 + it under the terms of the GNU General Public License as published by
582 + the Free Software Foundation; either version 2, or (at your option)
583 + any later version.
584 +
585 + This program is distributed in the hope that it will be useful,
586 + but WITHOUT ANY WARRANTY; without even the implied warranty of
587 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
588 + GNU General Public License for more details.
589 +
590 + You should have received a copy of the GNU General Public License
591 + along with this program; if not, write to the Free Software Foundation,
592 + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
593 +
594 +#include "config.h"
595 +#include <errno.h>
596 +#include <glob.h>
597 +#include <fnmatch.h>
598 +#include <stdio.h>
599 +#include <stdlib.h>
600 +#include <string.h>
601 +#include <sys/stat.h>
602 +#include <sys/types.h>
603 +#include <unistd.h>
604 +#include <dirent.h>
605 +#include <mntent.h>
606 +#define NAMLEN(dirent) strlen((dirent)->d_name)
607 +
608 +#include "configfile.h"
609 +#include "chmod.h"
610 +#include "modechange.h"
611 +
612 +#define CLOSEDIR(d) closedir (d)
613 +
614 +#ifdef _D_NEED_STPCPY
615 +/* stpcpy.c -- copy a string and return pointer to end of new string
616 + Copyright (C) 1989, 1990 Free Software Foundation.
617 +
618 + This program is free software; you can redistribute it and/or modify
619 + it under the terms of the GNU General Public License as published by
620 + the Free Software Foundation; either version 2, or (at your option)
621 + any later version.
622 +
623 + This program is distributed in the hope that it will be useful,
624 + but WITHOUT ANY WARRANTY; without even the implied warranty of
625 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
626 + GNU General Public License for more details.
627 +
628 + You should have received a copy of the GNU General Public License
629 + along with this program; if not, write to the Free Software Foundation,
630 + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
631 +
632 +/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
633 +
634 +static char *
635 +stpcpy (char *dest, const char *src)
636 +{
637 + while ((*dest++ = *src++) != '\0')
638 + /* Do nothing. */ ;
639 + return dest - 1;
640 +}
641 +#endif /* _D_NEED_STPCPY */
642 +
643 +/* end included files */
644 +
645 +static const char *fstab_filename = "/etc/fstab";
646 +
647 +static int change_via_fstab __P ((const char *dir,
648 + const struct mode_change *changes,
649 + uid_t user, gid_t group));
650 +
651 +/* Change the mode of FILE according to the list of operations CHANGES.
652 + If DEREF_SYMLINK is nonzero and FILE is a symbolic link, change the
653 + mode of the referenced file. If DEREF_SYMLINK is zero, ignore symbolic
654 + links. Return 0 if successful, 1 if errors occurred. */
655 +
656 +static int
657 +change_file (const char *file, const struct mode_change *changes,
658 + const int deref_symlink, uid_t user, gid_t group)
659 +{
660 + struct stat file_stats;
661 + unsigned short newmode;
662 + int errors = 0;
663 +
664 + if (lstat (file, &file_stats) == -1)
665 + {
666 + if (errno == ENOENT)
667 + {
668 + /* doesn't exist, check fstab */
669 + errors |= change_via_fstab (file, changes, user, group);
670 + return errors;
671 + }
672 + else
673 + {
674 + return 1;
675 + }
676 + }
677 +
678 + if (S_ISLNK (file_stats.st_mode))
679 + {
680 + /* don't bother with dangling symlinks */
681 + if (stat (file, &file_stats))
682 + {
683 + return 1;
684 + }
685 + }
686 +
687 + newmode = mode_adjust (file_stats.st_mode, changes);
688 +
689 + if (S_ISDIR (file_stats.st_mode))
690 + errors |= change_via_fstab (file, changes, user, group);
691 + else
692 + {
693 + if (newmode != (file_stats.st_mode & 07777))
694 + {
695 + if (chmod (file, (int) newmode) == -1)
696 + {
697 + errors = 1;
698 + }
699 + }
700 + errors |= chown (file, user, group);
701 + }
702 +
703 + return errors;
704 +}
705 +
706 +void
707 +chmod_set_fstab(const char *fstab)
708 +{
709 + fstab_filename = strdup(fstab);
710 +}
711 +
712 +
713 +/* If the directory spec given matches a filesystem listed in /etc/fstab,
714 + * modify the device special associated with that filesystem. */
715 +static int
716 +change_via_fstab (const char *dir, const struct mode_change *changes,
717 + uid_t user, gid_t group)
718 +{
719 + int errors = 0;
720 + FILE *fstab;
721 + struct mntent *mntent;
722 +
723 + fstab = setmntent(fstab_filename, "r");
724 +
725 + if (fstab == NULL)
726 + {
727 + return 1;
728 + }
729 +
730 + for(mntent = getmntent(fstab); mntent != NULL; mntent = getmntent(fstab))
731 + {
732 + if(mntent->mnt_dir &&
733 + mntent->mnt_fsname &&
734 + (fnmatch(dir, mntent->mnt_dir, 0) == 0))
735 + {
736 + errors |= change_file(mntent->mnt_fsname, changes, TRUE, user, group);
737 + }
738 + }
739 +
740 + endmntent(fstab);
741 +
742 + return errors;
743 +}
744 +
745 +/* Parse the ASCII mode into a linked list
746 + of `struct mode_change' and apply that to each file argument. */
747 +
748 +
749 +static int
750 +glob_errfn(const char *pathname, int theerr) {
751 + /* silently ignore inaccessible files */
752 + return 0;
753 +}
754 +
755 +#define DIE(n) {fprintf(stderr, "chmod failure\n"); return (n);}
756 +
757 +static int
758 +match_files(GSList *files, const char *filename) {
759 +
760 + if (!files)
761 + return 0; /* empty list matches */
762 + for (; files; files = files->next) {
763 + if (!fnmatch(files->data, filename, FNM_PATHNAME))
764 + return 0;
765 + }
766 + return -1;
767 +}
768 +
769 +int
770 +chmod_files (const char *mode, uid_t user, gid_t group,
771 + char *single_file, GSList *filelist, GSList *constraints)
772 +{
773 + struct mode_change *changes;
774 + int errors = 0;
775 + glob_t result;
776 + char *filename = NULL;
777 + int flags = GLOB_NOCHECK;
778 + int i, rc;
779 +
780 + changes = mode_compile (mode,
781 + MODE_MASK_EQUALS | MODE_MASK_PLUS | MODE_MASK_MINUS);
782 + if (changes == MODE_INVALID) DIE(1)
783 + else if (changes == MODE_MEMORY_EXHAUSTED) DIE(1)
784 +
785 + for (; filelist; filelist = filelist->next)
786 + {
787 + filename = filelist->data;
788 + rc = glob(filename, flags, glob_errfn, &result);
789 + if (rc == GLOB_NOSPACE) DIE(1)
790 + flags |= GLOB_APPEND;
791 + }
792 + if(single_file) {
793 + rc = glob(single_file, flags, glob_errfn, &result);
794 + if (rc == GLOB_NOSPACE) DIE(1)
795 + }
796 +
797 + for (i = 0; i < result.gl_pathc; i++) {
798 + if (!match_files(constraints, result.gl_pathv[i])) {
799 + errors |= change_file (result.gl_pathv[i], changes, 1, user, group);
800 +#if 0
801 + _pam_log(LOG_DEBUG, TRUE,
802 + "file %s (%d): mode %s\n", result.gl_pathv[i], user, mode);
803 +#endif
804 + }
805 + }
806 +
807 + globfree(&result);
808 +
809 + return (errors);
810 +}
811 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/chmod.h Linux-PAM-1.1.3/modules/pam_console/chmod.h
812 --- Linux-PAM-1.1.3.orig/modules/pam_console/chmod.h 1969-12-31 19:00:00.000000000 -0500
813 +++ Linux-PAM-1.1.3/modules/pam_console/chmod.h 2011-01-26 22:14:52.059406906 -0500
814 @@ -0,0 +1,11 @@
815 +#include <unistd.h>
816 +
817 +#ifndef _CHMOD_H
818 +#define _CHMOD_H
819 +
820 +int
821 +chmod_files(const char *mode, uid_t user, gid_t group, char *fname, GSList *filelist, GSList *constraints);
822 +void
823 +chmod_set_fstab(const char *fstab);
824 +
825 +#endif /* _CHMOD_H */
826 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/configfile.c Linux-PAM-1.1.3/modules/pam_console/configfile.c
827 --- Linux-PAM-1.1.3.orig/modules/pam_console/configfile.c 1969-12-31 19:00:00.000000000 -0500
828 +++ Linux-PAM-1.1.3/modules/pam_console/configfile.c 2011-01-26 22:14:52.062657563 -0500
829 @@ -0,0 +1,58 @@
830 +#include <string.h>
831 +#include <stdlib.h>
832 +#include "configfile.h"
833 +
834 +void *
835 +_do_malloc(size_t req)
836 +{
837 + void *ret;
838 + ret = malloc(req);
839 + if (!ret) abort();
840 + return ret;
841 +}
842 +
843 +GSList *
844 +g_slist_prepend(GSList *l, void *d)
845 +{
846 + GSList *memb;
847 + memb = _do_malloc(sizeof(*memb));
848 + memb->next = l;
849 + memb->data = d;
850 + return memb;
851 +}
852 +
853 +GSList *
854 +g_slist_append(GSList *l, void *d)
855 +{
856 + GSList *memb, *n;
857 + memb = _do_malloc(sizeof(*memb));
858 + memb->next = NULL;
859 + memb->data = d;
860 +
861 + if (l == NULL) {
862 + return memb;
863 + }
864 +
865 + n = l;
866 + while (n->next != NULL) {
867 + n = n->next;
868 + }
869 + n->next = memb;
870 +
871 + return l;
872 +}
873 +
874 +void
875 +g_slist_free(GSList *l)
876 +{
877 + GSList *n;
878 + while (l != NULL) {
879 + n = l->next;
880 + free(l);
881 + l = n;
882 + }
883 +}
884 +
885 +#include "configfile.lex.c"
886 +#include "configfile.tab.c"
887 +
888 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/configfile.h Linux-PAM-1.1.3/modules/pam_console/configfile.h
889 --- Linux-PAM-1.1.3.orig/modules/pam_console/configfile.h 1969-12-31 19:00:00.000000000 -0500
890 +++ Linux-PAM-1.1.3/modules/pam_console/configfile.h 2011-01-26 22:14:52.062657563 -0500
891 @@ -0,0 +1,64 @@
892 +/* Copyright 1999, 2005 Red Hat, Inc.
893 + * This software may be used under the terms of the GNU General Public
894 + * License, available in the file COPYING accompanying this file.
895 + */
896 +#ifndef _CONFIGFILE_H
897 +#define _CONFIGFILE_H
898 +#define STATIC static
899 +
900 +#ifndef FALSE
901 +#define FALSE 0
902 +#endif
903 +#ifndef TRUE
904 +#define TRUE (!FALSE)
905 +#endif
906 +
907 +/* GSList reimplementation */
908 +
909 +typedef struct GSList_s GSList;
910 +struct GSList_s {
911 + void *data;
912 + GSList *next;
913 +};
914 +
915 +typedef struct class_s class;
916 +struct class_s {
917 + char* name;
918 + GSList* list;
919 +};
920 +
921 +typedef struct config_s config;
922 +struct config_s {
923 + class* console_class;
924 + char* mode;
925 + class* device_class;
926 + char* revert_mode;
927 + char* revert_owner;
928 + char* revert_group;
929 +};
930 +
931 +GSList *
932 +g_slist_prepend(GSList *l, void *d);
933 +
934 +GSList *
935 +g_slist_append(GSList *l, void *d);
936 +
937 +void
938 +g_slist_free(GSList *l);
939 +
940 +void
941 +parse_file(const char *name);
942 +
943 +int
944 +check_console_name (const char *consolename);
945 +
946 +int
947 +set_permissions(const char *consolename, const char *username, GSList *files);
948 +
949 +int
950 +reset_permissions(const char *consolename, GSList *files);
951 +
952 +void *
953 +_do_malloc(size_t req);
954 +
955 +#endif /* _CONFIGFILE_H */
956 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/configfile.l Linux-PAM-1.1.3/modules/pam_console/configfile.l
957 --- Linux-PAM-1.1.3.orig/modules/pam_console/configfile.l 1969-12-31 19:00:00.000000000 -0500
958 +++ Linux-PAM-1.1.3/modules/pam_console/configfile.l 2011-01-26 22:14:52.062657563 -0500
959 @@ -0,0 +1,66 @@
960 +%option noyywrap
961 +%{
962 +/* Copyright 1999,2000 Red Hat, Inc.
963 + * This software may be used under the terms of the GNU General Public
964 + * License, available in the file COPYING accompanying this file
965 + */
966 +/* get around an apparant bug in bison; YYSTYPE not copied into config.tab.h */
967 +#define YYSTYPE void *
968 +#include "configfile.h"
969 +#include "configfile.tab.h"
970 +#include <stdio.h>
971 +#include <string.h>
972 +#include <syslog.h>
973 +
974 +#include "pam_console.h"
975 +
976 +static int lineno;
977 +static const char *filename;
978 +
979 +STATIC char *
980 +strip_slash(const char *);
981 +%}
982 +%%
983 +\n { lineno++; return EOL; }
984 +\\\n { lineno++; }
985 + /* do not return EOL, eat up escaped newline */
986 +[ \t]+ /* ignore whitespace */
987 +\< { return OBRACKET; }
988 +\>= { return CBEQUALS; }
989 +\> { return CBRACKET; }
990 +([^\t\n #\<\>]|(\\#|\\\<|\\\>))+ { _pc_yylval=strip_slash(yytext); return STRING; }
991 +#.*\n { lineno++; return EOL; } /* ignore comments */
992 +%%
993 +
994 +static void
995 +lex_file (FILE *in) {
996 + /* yy_flex_debug = 1; */
997 + yyin = in;
998 + lineno = 1;
999 +}
1000 +
1001 +static void
1002 +lex_set_filename(const char *name) {
1003 + filename = name;
1004 +}
1005 +
1006 +static int
1007 +_pc_yyerror (const char *s) {
1008 + _pam_log(NULL, LOG_ERR, 0, "%s line %d: %s: at `%s'\n",
1009 + filename, lineno, s, (char *)_pc_yylval);
1010 + return 0;
1011 +}
1012 +
1013 +STATIC char *
1014 +strip_slash(const char *s) {
1015 + char *r, *t;
1016 +
1017 + t = r = strdup(s);
1018 + while ((t = strchr(t, '\\')) != NULL) {
1019 + if (t[1] == '#' || t[1] == '<' || t[1] == '>') {
1020 + memmove(t, t+1, strlen(t));
1021 + }
1022 + t++;
1023 + }
1024 + return r;
1025 +}
1026 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/configfile.y Linux-PAM-1.1.3/modules/pam_console/configfile.y
1027 --- Linux-PAM-1.1.3.orig/modules/pam_console/configfile.y 1969-12-31 19:00:00.000000000 -0500
1028 +++ Linux-PAM-1.1.3/modules/pam_console/configfile.y 2011-01-26 22:14:52.062657563 -0500
1029 @@ -0,0 +1,336 @@
1030 +%{
1031 +/* Copyright 1999,2000 Red Hat, Inc.
1032 + * This software may be used under the terms of the GNU General Public
1033 + * License, available in the file COPYING accompanying this file
1034 + */
1035 +#define YYSTYPE void *
1036 +
1037 +#include <errno.h>
1038 +#include <grp.h>
1039 +#include <limits.h>
1040 +#include <regex.h>
1041 +#include <stdio.h>
1042 +#include <stdarg.h>
1043 +#include <sys/types.h>
1044 +#include <sys/stat.h>
1045 +#include <pwd.h>
1046 +#include <chmod.h>
1047 +#include <hashtable.h>
1048 +
1049 +#include <security/pam_modules.h>
1050 +#include <security/pam_modutil.h>
1051 +
1052 +typedef struct hashtable GHashTable;
1053 +
1054 +static GHashTable *namespace = NULL;
1055 +static GSList *configList = NULL;
1056 +static GSList *configListEnd = NULL;
1057 +static GSList *consoleClassList = NULL;
1058 +static GSList *consoleClassListEnd = NULL;
1059 +static const char *consoleNameCache = NULL;
1060 +static GHashTable *consoleHash = NULL;
1061 +
1062 +static void
1063 +do_yyerror(const char *format, ...);
1064 +
1065 +static void
1066 +empty_class(class *c);
1067 +
1068 +static unsigned int
1069 +str_hash(unsigned char *s)
1070 +{
1071 + unsigned int hash = 5381;
1072 + int c;
1073 +
1074 + while ((c = *s++))
1075 + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
1076 +
1077 + return hash;
1078 +}
1079 +
1080 +static int
1081 +str_equal(void *a, void *b)
1082 +{
1083 + return strcmp(a, b) == 0;
1084 +}
1085 +
1086 +static unsigned int
1087 +ptr_hash(void *p)
1088 +{
1089 + return (unsigned long)p >> 3;
1090 +}
1091 +
1092 +static int
1093 +ptr_equal(void *a, void *b)
1094 +{
1095 + return a == b;
1096 +}
1097 +
1098 +%}
1099 +
1100 +%token EOL
1101 +%token OBRACKET
1102 +%token CBEQUALS
1103 +%token CBRACKET
1104 +%token STRING
1105 +
1106 +%%
1107 +lines: lines line
1108 + | /* empty */
1109 + ;
1110 +
1111 +line: config
1112 + | classdef
1113 + | EOL
1114 + | error
1115 + ;
1116 +
1117 +classdef:
1118 + OBRACKET string CBEQUALS stringlist EOL {
1119 + class *c;
1120 +
1121 + c = hashtable_search(namespace, $2);
1122 + if (c) {
1123 + empty_class(c);
1124 + } else {
1125 + c = malloc(sizeof(class));
1126 + hashtable_insert(namespace, strdup($2), c);
1127 + }
1128 + c->name = $2;
1129 + c->list = $4;
1130 + }
1131 + ;
1132 +
1133 +config: classlist STRING classlist optstring optstring EOL {
1134 + config *conf = malloc(sizeof(config));
1135 + conf->console_class = $1;
1136 + conf->mode = $2;
1137 + conf->device_class = $3;
1138 + conf->revert_mode = $4;
1139 + conf->revert_owner = $5;
1140 + if (conf->revert_owner != NULL) {
1141 + conf->revert_group = strchr (conf->revert_owner, ':');
1142 + if (conf->revert_group == NULL)
1143 + conf->revert_group = strchr (conf->revert_owner, '.');
1144 + if (conf->revert_group != NULL) {
1145 + *(conf->revert_group) = '\0';
1146 + conf->revert_group++;
1147 + if (*(conf->revert_group) == '\0')
1148 + conf->revert_group = NULL;
1149 + if (*(conf->revert_owner) == '\0')
1150 + conf->revert_owner = NULL;
1151 + }
1152 + } else {
1153 + conf->revert_group = NULL;
1154 + }
1155 + configListEnd = g_slist_append(configListEnd, conf);
1156 + if (configListEnd->next) configListEnd = configListEnd->next;
1157 + if (!configList) configList = configListEnd;
1158 + consoleClassListEnd =
1159 + g_slist_append(consoleClassListEnd, conf->console_class);
1160 + if (consoleClassListEnd->next)
1161 + consoleClassListEnd = consoleClassListEnd->next;
1162 + if (!consoleClassList) consoleClassList = consoleClassListEnd;
1163 + }
1164 + ;
1165 +
1166 +classlist: OBRACKET string CBRACKET {
1167 + class *c = hashtable_search(namespace, $2);
1168 + if(!c) {
1169 + _pam_log(NULL, LOG_ERR, FALSE,
1170 + "unknown class \"%s\" at line %d in %s\n",
1171 + (const char *)$2, lineno, filename);
1172 + YYERROR;
1173 + }
1174 + $$ = c;
1175 + }
1176 + | string {
1177 + class *c = malloc(sizeof(class));
1178 + c->name = $1;
1179 + c->list = NULL;
1180 + $$ = c;
1181 + }
1182 + ;
1183 +
1184 +
1185 +stringlist: string {$$ = g_slist_append(NULL, $1);}
1186 + | stringlist string {$$ = g_slist_append($1, $2);}
1187 + ;
1188 +
1189 +optstring: string {$$=$1;}
1190 + | /* empty */ {$$=NULL;}
1191 + ;
1192 +
1193 +string: STRING {$$=$1;} ;
1194 +
1195 +%%
1196 +
1197 +/* exported functions */
1198 +
1199 +/* parse a file given by a name */
1200 +void
1201 +parse_file(const char *name) {
1202 + FILE *infile;
1203 +
1204 + _pam_log(NULL, LOG_DEBUG, TRUE, "parsing config file %s", name);
1205 + infile = fopen(name, "r");
1206 + if (!infile) {
1207 + _pam_log(NULL, LOG_ERR, FALSE, "could not parse required file %s", name);
1208 + return;
1209 + }
1210 +
1211 + if (!namespace) namespace = create_hashtable(128, (unsigned int (*)(void *))str_hash, str_equal);
1212 +
1213 + lex_set_filename(name);
1214 + lex_file(infile);
1215 +
1216 + yyparse();
1217 + fclose(infile);
1218 +}
1219 +
1220 +static int
1221 +check_one_console_name (const char *name, char *classComponent) {
1222 + regex_t p;
1223 + int r_err;
1224 + char *class_exp;
1225 +
1226 + class_exp = _do_malloc(strlen(classComponent) + 3);
1227 + sprintf(class_exp, "^%s$", classComponent);
1228 + r_err = regcomp(&p, class_exp, REG_EXTENDED|REG_NOSUB);
1229 + if (r_err) do_regerror(r_err, &p);
1230 + r_err = regexec(&p, name, 0, NULL, 0);
1231 + regfree(&p);
1232 + free (class_exp);
1233 + return !r_err;
1234 +}
1235 +
1236 +int
1237 +check_console_name (const char *consolename) {
1238 + GSList *this_class;
1239 + GSList *this_list;
1240 + class *c;
1241 + int found = 0;
1242 +
1243 + _pam_log(NULL, LOG_DEBUG, TRUE, "check console %s", consolename);
1244 + if (consoleNameCache != consolename) {
1245 + consoleNameCache = consolename;
1246 + if (consoleHash) hashtable_destroy(consoleHash, 0);
1247 + consoleHash = create_hashtable(128, ptr_hash, ptr_equal);
1248 + }
1249 + for (this_class = consoleClassList; this_class;
1250 + this_class = this_class->next) {
1251 + c = this_class->data;
1252 + if (c->list) {
1253 + for (this_list = c->list; this_list; this_list = this_list->next) {
1254 + if (check_one_console_name(consolename, this_list->data)) {
1255 + hashtable_insert(consoleHash, c, c);
1256 + found = 1;
1257 + }
1258 + }
1259 + } else {
1260 + if (check_one_console_name(consolename, c->name)) {
1261 + hashtable_insert(consoleHash, c, c);
1262 + found = 1;
1263 + }
1264 + }
1265 + }
1266 +
1267 + if (found)
1268 + return 1;
1269 +
1270 + /* not found */
1271 + _pam_log(NULL, LOG_INFO, TRUE, "did not find console %s", consolename);
1272 + if (consoleHash) {
1273 + hashtable_destroy(consoleHash, 0);
1274 + consoleHash = NULL;
1275 + }
1276 + return 0;
1277 +}
1278 +
1279 +int
1280 +set_permissions(const char *consolename, const char *username, GSList *files) {
1281 + struct passwd *pwd;
1282 + config *c;
1283 + GSList *cl;
1284 +
1285 + if (!consoleNameCache || strcmp(consolename, consoleNameCache)) {
1286 + if (!check_console_name(consolename)) return -1;
1287 + }
1288 +
1289 + pwd = getpwnam(username);
1290 + if (pwd == NULL) {
1291 + _pam_log(NULL, LOG_ERR, FALSE, "getpwnam failed for \"%s\"", username);
1292 + return -1;
1293 + }
1294 +
1295 + for (cl = configList; cl; cl = cl->next) {
1296 + c = cl->data;
1297 + if (hashtable_search(consoleHash, c->console_class)) {
1298 + if (c->device_class->list)
1299 + chmod_files(c->mode, pwd->pw_uid, -1, NULL, c->device_class->list, files);
1300 + else
1301 + chmod_files(c->mode, pwd->pw_uid, -1, c->device_class->name, NULL, files);
1302 + }
1303 + }
1304 + return 0;
1305 +}
1306 +
1307 +int
1308 +reset_permissions(const char *consolename, GSList *files) {
1309 + struct passwd *pwd;
1310 + struct group *grp;
1311 + config *c;
1312 + GSList *cl;
1313 +
1314 + if (!consoleNameCache || strcmp(consolename, consoleNameCache)) {
1315 + if (!check_console_name(consolename)) return -1;
1316 + }
1317 +
1318 + for (cl = configList; cl; cl = cl->next) {
1319 + c = cl->data;
1320 + if (hashtable_search(consoleHash, c->console_class)) {
1321 + pwd = getpwnam(c->revert_owner ? c->revert_owner : "root");
1322 + if (pwd == NULL) {
1323 + _pam_log(NULL, LOG_ERR, FALSE, "getpwnam failed for %s",
1324 + c->revert_owner ? c->revert_owner : "root");
1325 + return -1;
1326 + }
1327 + grp = getgrnam(c->revert_group ? c->revert_group : "root");
1328 + if (grp == NULL) {
1329 + _pam_log(NULL, LOG_ERR, FALSE, "getgrnam failed for %s",
1330 + c->revert_group ? c->revert_group : "root");
1331 + return -1;
1332 + }
1333 + if (c->device_class->list)
1334 + chmod_files(c->revert_mode ? c->revert_mode : "0600",
1335 + pwd->pw_uid, grp->gr_gid, NULL, c->device_class->list, files);
1336 + else
1337 + chmod_files(c->revert_mode ? c->revert_mode : "0600",
1338 + pwd->pw_uid, grp->gr_gid, c->device_class->name, NULL, files);
1339 + }
1340 + }
1341 + return 0;
1342 +}
1343 +
1344 +
1345 +
1346 +
1347 +/* local, static functions */
1348 +
1349 +static void
1350 +do_yyerror(const char *format, ...) {
1351 + va_list ap;
1352 +
1353 + va_start(ap, format);
1354 + openlog("pam_console", LOG_CONS|LOG_PID, LOG_AUTHPRIV);
1355 + vsyslog(LOG_PID|LOG_AUTHPRIV|LOG_ERR, format, ap);
1356 + va_end(ap);
1357 +}
1358 +
1359 +static void
1360 +empty_class(class *c) {
1361 + free(c->name);
1362 + c->name = NULL;
1363 + g_slist_free(c->list);
1364 + c->list = NULL;
1365 +}
1366 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/console.apps.5 Linux-PAM-1.1.3/modules/pam_console/console.apps.5
1367 --- Linux-PAM-1.1.3.orig/modules/pam_console/console.apps.5 1969-12-31 19:00:00.000000000 -0500
1368 +++ Linux-PAM-1.1.3/modules/pam_console/console.apps.5 2011-01-26 22:14:52.062657563 -0500
1369 @@ -0,0 +1,18 @@
1370 +.\" Copyright 1999 Red Hat Software, Inc.
1371 +.\" Written by Michael K. Johnson <johnsonm@redhat.com>
1372 +.TH console.apps 5 1999/2/4 "Red Hat Software" "System Administrator's Manual"
1373 +.SH NAME
1374 +console.apps \- specify console-accessible privileged applications
1375 +.SH DESCRIPTION
1376 +The /etc/security/console.apps/ directory should contain one file
1377 +per application that wishes to allow access to console users.
1378 +The filename should be the same as the servicename, and the
1379 +contents are irrelevant; the file may be a zero-length file.
1380 +The application that the file is used by is free to specify the
1381 +contents in any way that is useful for it.
1382 +.SH "SEE ALSO"
1383 +.BR pam_console (8)
1384 +.br
1385 +.BR console.perms (5)
1386 +.SH AUTHOR
1387 +Michael K. Johnson <johnsonm@redhat.com>
1388 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/console.handlers Linux-PAM-1.1.3/modules/pam_console/console.handlers
1389 --- Linux-PAM-1.1.3.orig/modules/pam_console/console.handlers 1969-12-31 19:00:00.000000000 -0500
1390 +++ Linux-PAM-1.1.3/modules/pam_console/console.handlers 2011-01-26 22:14:52.062657563 -0500
1391 @@ -0,0 +1,22 @@
1392 +# /etc/security/console.handlers
1393 +#
1394 +# This file is provided for configuration of handlers which will be
1395 +# executed when user obtains console lock and when he loses it.
1396 +# Additionally it is used for a configuration of console device names.
1397 +#
1398 +# Format:
1399 +# name consoledevs regex regex ...
1400 +# binary lock|unlock flag flag ...
1401 +# See man console.handlers
1402 +#
1403 +# Example:
1404 +# console consoledevs tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
1405 +# echo lock wait Locking console for user on tty
1406 +# touch unlock wait /var/run/console-unlocked
1407 +
1408 +console consoledevs tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
1409 +/sbin/pam_console_apply lock logfail wait -t tty -s
1410 +/sbin/pam_console_apply unlock logfail wait -r -t tty -s
1411 +# initialize dmix for alsa sound
1412 +/usr/bin/ainit lock user start
1413 +/usr/bin/ainit unlock user stop
1414 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/console.handlers.5 Linux-PAM-1.1.3/modules/pam_console/console.handlers.5
1415 --- Linux-PAM-1.1.3.orig/modules/pam_console/console.handlers.5 1969-12-31 19:00:00.000000000 -0500
1416 +++ Linux-PAM-1.1.3/modules/pam_console/console.handlers.5 2011-01-26 22:14:52.062657563 -0500
1417 @@ -0,0 +1,46 @@
1418 +.\" Copyright 2005 Red Hat Software, Inc.
1419 +.\" Written by Tomas Mraz <tmraz@redhat.com>
1420 +.TH console.handlers 5 2005/3/18 "Red Hat" "System Administrator's Manual"
1421 +.SH NAME
1422 +console.handlers \- file specifying handlers of console lock and unlock events
1423 +.SH DESCRIPTION
1424 +/etc/security/console.handlers determines which programs will be run when an
1425 +user obtains the console lock at login time, and when the user loses it
1426 +on log out. It is read by the pam_console module.
1427 +
1428 +The format is:
1429 +
1430 +\fBhandler-filename\fP \fBlock\fP\fI|\fP\fBunlock\fP \fI[\fP\fBflag ...\fP\fI]\fP
1431 +
1432 +Where \fBhandler-filename\fP is a name of the executable to be run, \fBlock\fP or
1433 +\fBunlock\fP specifies on which event it should be run, and flags specify how
1434 +should pam_console call it.
1435 +
1436 +Additionally there should be a line which specifies glob patterns of console devices.
1437 +
1438 +The format of this line is:
1439 +\fBconsole-name\fP \fBconsoledevs\fP \fBregex\fP \fI[\fP\fBregex ...\fP\fI]\fP
1440 +
1441 +Where \fBconsole-name\fP is a name of the console class - currently ignored - and
1442 +regexes are regular expression patterns which specify the name of the tty device.
1443 +Only the first such line is consulted.
1444 +
1445 +.SH FLAGS
1446 +.IP logfail
1447 +The pam_console module should log error to the system log if the return value of the
1448 +handler is not zero or if the handler can not be executed.
1449 +.IP wait
1450 +The pam_console should wait for the handler to exit before continuing.
1451 +.IP setuid
1452 +The handler should be executed with uid/gid of the user which obtained the
1453 +console lock.
1454 +.IP tty
1455 +The handler will get a tty name as obtained from PAM as a parameter.
1456 +.IP user
1457 +The handler will get an user name as obtained from PAM as a parameter.
1458 +.PP
1459 +Anything else will be added directly as a parameter to the handler executable.
1460 +.SH "SEE ALSO"
1461 +.BR pam_console (8)
1462 +.SH AUTHOR
1463 +Tomas Mraz <tmraz@redhat.com>
1464 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/console.perms Linux-PAM-1.1.3/modules/pam_console/console.perms
1465 --- Linux-PAM-1.1.3.orig/modules/pam_console/console.perms 1969-12-31 19:00:00.000000000 -0500
1466 +++ Linux-PAM-1.1.3/modules/pam_console/console.perms 2011-01-26 22:14:52.062657563 -0500
1467 @@ -0,0 +1,25 @@
1468 +# /etc/security/console.perms
1469 +#
1470 +# This file determines the permissions that will be given to priviledged
1471 +# users of the console at login time, and the permissions to which to
1472 +# revert when the users log out.
1473 +
1474 +# format is:
1475 +# <class>=list of regexps specifying consoles or globs specifying files
1476 +# file-glob|<class> perm dev-regex|<dev-class> \
1477 +# revert-mode revert-owner[.revert-group]
1478 +# the revert-mode, revert-owner, and revert-group are optional, and default
1479 +# to 0600, root, and root, respectively.
1480 +#
1481 +# For more information:
1482 +# man 5 console.perms
1483 +#
1484 +# This file should not be modified.
1485 +# Rather a new file in the console.perms.d directory should be created.
1486 +
1487 +# file classes -- these are regular expressions
1488 +<console>=tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
1489 +<xconsole>=:[0-9]\.[0-9] :[0-9]
1490 +
1491 +# device classes -- see console.perms.d/50-default.perms
1492 +# permission definitions -- see console.perms.d/50-default.perms
1493 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/console.perms.5 Linux-PAM-1.1.3/modules/pam_console/console.perms.5
1494 --- Linux-PAM-1.1.3.orig/modules/pam_console/console.perms.5 1969-12-31 19:00:00.000000000 -0500
1495 +++ Linux-PAM-1.1.3/modules/pam_console/console.perms.5 2011-01-26 22:14:52.062657563 -0500
1496 @@ -0,0 +1,50 @@
1497 +.\" Copyright 1999,2005 Red Hat Software, Inc.
1498 +.\" Written by Michael K. Johnson <johnsonm@redhat.com>
1499 +.TH console.perms 5 2005/5/2 "Red Hat Software" "System Administrator's Manual"
1500 +.SH NAME
1501 +console.perms \- permissions control file for users at the system console
1502 +.SH DESCRIPTION
1503 +/etc/security/console.perms and .perms files in the
1504 +/etc/security/console.perms.d directory determine the permissions that will be
1505 +given to priviledged users of the console at login time, and the
1506 +permissions to which to revert when the users log out. They are
1507 +read by the pam_console_apply helper executable.
1508 +
1509 +The format is:
1510 +
1511 +\f(CR<\fBclass\fR\f(CR>=\fBspace-separated list of words\fR
1512 +
1513 +\fBlogin-regexp\fR\fI|\fR\f(CR<\fBlogin-class\fR\f(CR> \fBperm dev-glob\fR\fI|\fR\f(CR<\fBdev-class\fR\f(CR> \e
1514 +.br
1515 +\f(CR \fBrevert-mode revert-owner\fR\fI[\fR\fP.revert-group\fI]\fR
1516 +
1517 +The \fBrevert-mode\fP, \fBrevert-owner\fP, and revert-group fields are optional,
1518 +and default to \fB0600\fP, \fBroot\fP, and \fBroot\fP, respectively.
1519 +
1520 +The words in a class definition are evaluated as globs if they
1521 +refer to files, but as regular expressions if they apply to a
1522 +console definition. Do not mix them.
1523 +
1524 +Any line can be broken and continued on the next line by using a
1525 +\e character as the last character on the line.
1526 +
1527 +The \fBlogin-class\fP class and the \fBlogin-regexp\fP word are evaluated as
1528 +regular expressions.
1529 +The \fBdev-class\fP and the \fBdev-glob\fP word are evaluated as
1530 +shell-style globs. If a name given corresponds to a directory, and
1531 +if it is a mount point listed in \fI/etc/fstab\fP, the device node
1532 +associated with the filesystem mounted at that point will be
1533 +substituted in its place.
1534 +
1535 +Classes are denoted by being contained in \f(CR<\fR angle bracket \f(CR>\fR
1536 +characters; a lack of \f(CR<\fR angle brackets \f(CR>\fR indicates that
1537 +the string is to be taken literally as a \fBlogin-regexp\fP or a
1538 +\fBdev-glob\fP, depending on its input position.
1539 +.SH "SEE ALSO"
1540 +.BR pam_console (8)
1541 +.br
1542 +.BR pam_console_apply (8)
1543 +.br
1544 +.BR console.apps (5)
1545 +.SH AUTHOR
1546 +Michael K. Johnson <johnsonm@redhat.com>
1547 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/handlers.c Linux-PAM-1.1.3/modules/pam_console/handlers.c
1548 --- Linux-PAM-1.1.3.orig/modules/pam_console/handlers.c 1969-12-31 19:00:00.000000000 -0500
1549 +++ Linux-PAM-1.1.3/modules/pam_console/handlers.c 2011-01-26 22:14:52.062657563 -0500
1550 @@ -0,0 +1,312 @@
1551 +/* handlers.c -- execute handlers specified in handlers configuration file
1552 + Copyright (c) 2005 Red Hat, Inc.
1553 + Written by Tomas Mraz <tmraz@redhat.com>
1554 +
1555 + This program is free software; you can redistribute it and/or modify
1556 + it under the terms of the GNU General Public License as published by
1557 + the Free Software Foundation; either version 2, or (at your option)
1558 + any later version.
1559 +
1560 + This program is distributed in the hope that it will be useful,
1561 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1562 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1563 + GNU General Public License for more details.
1564 +
1565 + You should have received a copy of the GNU General Public License
1566 + along with this program; if not, write to the Free Software Foundation,
1567 + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
1568 +
1569 +#include "config.h"
1570 +#include <errno.h>
1571 +#include <stdio.h>
1572 +#include <stdlib.h>
1573 +#include <string.h>
1574 +#include <ctype.h>
1575 +#include <unistd.h>
1576 +#include <signal.h>
1577 +#include <sys/wait.h>
1578 +#include <sys/types.h>
1579 +#include <pwd.h>
1580 +#include <syslog.h>
1581 +
1582 +#include "handlers.h"
1583 +#include "pam_console.h"
1584 +
1585 +enum types { UNKNOWN, LOCK, UNLOCK, CONSOLEDEVS };
1586 +enum flags { HF_LOGFAIL, HF_WAIT, HF_SETUID, HF_TTY, HF_USER, HF_PARAM };
1587 +
1588 +struct console_handler {
1589 + char *executable;
1590 + enum types type;
1591 + char *flags; /* this is a double zero terminated array
1592 + allocated in one blob with executable */
1593 + struct console_handler *next;
1594 +};
1595 +
1596 +static struct console_handler *first_handler;
1597 +
1598 +static void
1599 +console_free_handlers (struct console_handler *handler) {
1600 + if (handler != NULL) {
1601 + console_free_handlers(handler->next);
1602 + free(handler->executable);
1603 + free(handler);
1604 + }
1605 +}
1606 +
1607 +int
1608 +console_parse_handlers (pam_handle_t *pamh, const char *handlers_name) {
1609 + FILE *fh;
1610 + char linebuf[HANDLERS_MAXLINELEN+1];
1611 + int forget;
1612 + int skip = 0;
1613 + int rv = PAM_SESSION_ERR;
1614 + struct console_handler **previous_handler_ptr;
1615 +
1616 + fh = fopen(handlers_name, "r");
1617 + if (fh == NULL) {
1618 + _pam_log(pamh, LOG_ERR, FALSE, "cannot open file %s for reading", handlers_name);
1619 + return rv;
1620 + }
1621 +
1622 + previous_handler_ptr = &first_handler;
1623 +
1624 + while (fgets(linebuf, sizeof(linebuf), fh) != NULL)
1625 + {
1626 + int len;
1627 + char *ptr;
1628 + char *tokptr;
1629 + char *temp;
1630 + char *destptr = NULL; /* needed to silence warning */
1631 + struct console_handler *handler;
1632 + enum states { EXECUTABLE, TYPE, FLAGS } state;
1633 +
1634 + len = strlen(linebuf);
1635 + if (linebuf[len-1] != '\n') {
1636 + _pam_log(pamh, LOG_INFO, FALSE, "line too long or not ending with new line char - will be ignored");
1637 + skip = 1;
1638 + continue;
1639 + }
1640 + if (skip) {
1641 + skip = 0;
1642 + continue;
1643 + }
1644 + linebuf[len-1] = '\0';
1645 + if ((ptr=strchr(linebuf, '#')) != NULL) {
1646 + *ptr = '\0';
1647 + }
1648 + for (ptr = linebuf; isspace(*ptr); ptr++);
1649 + if (*ptr == '\0')
1650 + continue;
1651 +
1652 + /* something on the line */
1653 + if ((handler=calloc(sizeof(*handler), 1)) == NULL)
1654 + goto fail_exit;
1655 + *previous_handler_ptr = handler;
1656 + previous_handler_ptr = &handler->next;
1657 +
1658 + if ((handler->executable=malloc(len-(ptr-linebuf)+1)) == NULL) {
1659 + goto fail_exit;
1660 + }
1661 +
1662 + state = EXECUTABLE;
1663 + handler->type = UNKNOWN;
1664 + while ((tokptr=strtok_r(ptr, " \t", &temp)) != NULL) {
1665 + if (state == EXECUTABLE) {
1666 + strcpy(handler->executable, tokptr);
1667 + ptr = NULL;
1668 + handler->flags = destptr = handler->executable + strlen(handler->executable) + 1;
1669 + }
1670 + else if (state == TYPE) {
1671 + if (strcmp(tokptr, "lock") == 0) {
1672 + handler->type = LOCK;
1673 + }
1674 + else if (strcmp(tokptr, "unlock") == 0) {
1675 + handler->type = UNLOCK;
1676 + }
1677 + else if (strcmp(tokptr, "consoledevs") == 0) {
1678 + handler->type = CONSOLEDEVS;
1679 + }
1680 + }
1681 +
1682 + if (state == FLAGS) {
1683 + strcpy(destptr, tokptr);
1684 + destptr += strlen(destptr) + 1;
1685 + }
1686 + else {
1687 + state++;
1688 + }
1689 + }
1690 + *destptr = '\0';
1691 + }
1692 + forget = fclose(fh);
1693 +
1694 + return PAM_SUCCESS;
1695 +
1696 +fail_exit:
1697 + console_free_handlers(first_handler);
1698 + return rv;
1699 +}
1700 +
1701 +static enum flags testflag(const char *flag) {
1702 + if (strcmp(flag, "logfail") == 0) {
1703 + return HF_LOGFAIL;
1704 + }
1705 + if (strcmp(flag, "wait") == 0) {
1706 + return HF_WAIT;
1707 + }
1708 + if (strcmp(flag, "setuid") == 0) {
1709 + return HF_SETUID;
1710 + }
1711 + if (strcmp(flag, "tty") == 0) {
1712 + return HF_TTY;
1713 + }
1714 + if (strcmp(flag, "user") == 0) {
1715 + return HF_USER;
1716 + }
1717 + return HF_PARAM;
1718 +}
1719 +
1720 +static void
1721 +call_exec(struct console_handler *handler, int nparams, const char *user, const char *tty) {
1722 + const char *flagptr;
1723 + const char **argv;
1724 + int i = 0;
1725 + argv = malloc(sizeof(*argv)*nparams+2);
1726 +
1727 + if (argv == NULL)
1728 + return;
1729 +
1730 + argv[i++] = handler->executable;
1731 +
1732 + for (flagptr = handler->flags; *flagptr != '\0'; flagptr += strlen(flagptr)+1) {
1733 + switch (testflag(flagptr)) {
1734 + case HF_LOGFAIL:
1735 + case HF_WAIT:
1736 + case HF_SETUID:
1737 + break;
1738 + case HF_TTY:
1739 + argv[i++] = tty;
1740 + break;
1741 + case HF_USER:
1742 + argv[i++] = user;
1743 + break;
1744 + case HF_PARAM:
1745 + argv[i++] = flagptr;
1746 + }
1747 + }
1748 + argv[i] = NULL;
1749 + execvp(handler->executable, (char * const *)argv);
1750 +}
1751 +
1752 +static int
1753 +execute_handler(pam_handle_t *pamh, struct console_handler *handler, const char *user, const char *tty) {
1754 + const char *flagptr;
1755 + int nparams = 0;
1756 + int logfail = 0;
1757 + int wait_exit = 0;
1758 + int set_uid = 0;
1759 + int child;
1760 + int rv = 0;
1761 + int max_fd;
1762 + int fd;
1763 + sighandler_t sighandler;
1764 +
1765 + for (flagptr = handler->flags; *flagptr != '\0'; flagptr += strlen(flagptr)+1) {
1766 + switch (testflag(flagptr)) {
1767 + case HF_LOGFAIL:
1768 + logfail = 1;
1769 + break;
1770 + case HF_WAIT:
1771 + wait_exit = 1;
1772 + break;
1773 + case HF_SETUID:
1774 + set_uid = 1;
1775 + break;
1776 + case HF_TTY:
1777 + case HF_USER:
1778 + case HF_PARAM:
1779 + nparams++;
1780 + }
1781 + }
1782 +
1783 + sighandler = signal(SIGCHLD, SIG_DFL);
1784 +
1785 + child = fork();
1786 + switch (child) {
1787 + case -1:
1788 + _pam_log(pamh, LOG_ERR, !logfail, "fork failed when executing handler '%s'",
1789 + handler->executable);
1790 + return -1;
1791 + case 0:
1792 + /* close all descriptors except std* */
1793 + max_fd = getdtablesize();
1794 + for(fd = 3; fd < max_fd; fd++)
1795 + rv = close(fd); /* rv will be ignored */
1796 + if (!wait_exit) {
1797 + switch(fork()) {
1798 + case 0:
1799 + exit(0);
1800 + case -1:
1801 + exit(255);
1802 + default:
1803 + if(setsid() == -1) {
1804 + exit(255);
1805 + }
1806 + }
1807 + }
1808 + if (set_uid) {
1809 + struct passwd *pw;
1810 + pw = getpwnam(user);
1811 + if (pw == NULL)
1812 + exit(255);
1813 + if (setgid(pw->pw_gid) == -1 ||
1814 + setuid(pw->pw_uid) == -1)
1815 + exit(255);
1816 + }
1817 + call_exec(handler, nparams, user, tty);
1818 + exit(255);
1819 + default:
1820 + break;
1821 + }
1822 +
1823 + waitpid(child, &rv, 0);
1824 +
1825 + if (sighandler != SIG_ERR)
1826 + signal(SIGCHLD, sighandler);
1827 +
1828 + if (WIFEXITED(rv) && WEXITSTATUS(rv) != 0)
1829 + _pam_log(pamh, LOG_ERR, !logfail, "handler '%s' returned %d on exit",
1830 + handler->executable, (int)WEXITSTATUS(rv));
1831 + else if (WIFSIGNALED(rv))
1832 + _pam_log(pamh, LOG_ERR, !logfail, "handler '%s' caught a signal %d",
1833 + handler->executable, (int)WTERMSIG(rv));
1834 +
1835 + return 0;
1836 +}
1837 +
1838 +void
1839 +console_run_handlers(pam_handle_t *pamh, int lock, const char *user, const char *tty) {
1840 + struct console_handler *handler;
1841 +
1842 + for (handler = first_handler; handler != NULL; handler = handler->next) {
1843 + if (lock && handler->type == LOCK) {
1844 + execute_handler(pamh, handler, user, tty);
1845 + }
1846 + else if (!lock && handler->type == UNLOCK) {
1847 + execute_handler(pamh, handler, user, tty);
1848 + }
1849 + }
1850 +}
1851 +
1852 +const char *
1853 +console_get_regexes(void) {
1854 + struct console_handler *handler;
1855 +
1856 + for (handler = first_handler; handler != NULL; handler = handler->next) {
1857 + if (handler->type == CONSOLEDEVS) {
1858 + return handler->flags;
1859 + }
1860 + }
1861 + return NULL;
1862 +}
1863 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/handlers.h Linux-PAM-1.1.3/modules/pam_console/handlers.h
1864 --- Linux-PAM-1.1.3.orig/modules/pam_console/handlers.h 1969-12-31 19:00:00.000000000 -0500
1865 +++ Linux-PAM-1.1.3/modules/pam_console/handlers.h 2011-01-26 22:14:52.062657563 -0500
1866 @@ -0,0 +1,16 @@
1867 +/* Copyright 2005 Red Hat, Inc.
1868 + * This software may be used under the terms of the GNU General Public
1869 + * License, available in the file COPYING accompanying this file.
1870 + */
1871 +#ifndef _HANDLERS_H
1872 +#define _HANDLERS_H
1873 +
1874 +#include <security/pam_modules.h>
1875 +
1876 +#define HANDLERS_MAXLINELEN 2000
1877 +
1878 +int console_parse_handlers (pam_handle_t *pamh, const char *filename);
1879 +void console_run_handlers(pam_handle_t *pamh, int lock, const char *user, const char *tty);
1880 +const char *console_get_regexes(void);
1881 +
1882 +#endif /* _HANDLERS_H */
1883 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/hashtable.c Linux-PAM-1.1.3/modules/pam_console/hashtable.c
1884 --- Linux-PAM-1.1.3.orig/modules/pam_console/hashtable.c 1969-12-31 19:00:00.000000000 -0500
1885 +++ Linux-PAM-1.1.3/modules/pam_console/hashtable.c 2011-01-26 22:14:52.062657563 -0500
1886 @@ -0,0 +1,255 @@
1887 +/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
1888 +
1889 +#include "hashtable.h"
1890 +#include "hashtable_private.h"
1891 +#include <stdlib.h>
1892 +#include <stdio.h>
1893 +#include <string.h>
1894 +#include <math.h>
1895 +
1896 +/*
1897 +Credit for primes table: Aaron Krowne
1898 + http://br.endernet.org/~akrowne/
1899 + http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
1900 +*/
1901 +static const unsigned int primes[] = {
1902 +53, 97, 193, 389,
1903 +769, 1543, 3079, 6151,
1904 +12289, 24593, 49157, 98317,
1905 +196613, 393241, 786433, 1572869,
1906 +3145739, 6291469, 12582917, 25165843,
1907 +50331653, 100663319, 201326611, 402653189,
1908 +805306457, 1610612741
1909 +};
1910 +const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
1911 +const float max_load_factor = 0.65;
1912 +
1913 +/*****************************************************************************/
1914 +struct hashtable *
1915 +create_hashtable(unsigned int minsize,
1916 + unsigned int (*hashf) (void*),
1917 + int (*eqf) (void*,void*))
1918 +{
1919 + struct hashtable *h;
1920 + unsigned int pindex, size = primes[0];
1921 + /* Check requested hashtable isn't too large */
1922 + if (minsize > (1u << 30)) return NULL;
1923 + /* Enforce size as prime */
1924 + for (pindex=0; pindex < prime_table_length; pindex++) {
1925 + if (primes[pindex] > minsize) { size = primes[pindex]; break; }
1926 + }
1927 + h = (struct hashtable *)malloc(sizeof(struct hashtable));
1928 + if (NULL == h) return NULL; /*oom*/
1929 + h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
1930 + if (NULL == h->table) { free(h); return NULL; } /*oom*/
1931 + memset(h->table, 0, size * sizeof(struct entry *));
1932 + h->tablelength = size;
1933 + h->primeindex = pindex;
1934 + h->entrycount = 0;
1935 + h->hashfn = hashf;
1936 + h->eqfn = eqf;
1937 + h->loadlimit = (unsigned int)(size * max_load_factor) + 1;
1938 + return h;
1939 +}
1940 +
1941 +/*****************************************************************************/
1942 +
1943 +#define hash(h, k) h->hashfn(k)
1944 +
1945 +/*****************************************************************************/
1946 +static int
1947 +hashtable_expand(struct hashtable *h)
1948 +{
1949 + /* Double the size of the table to accomodate more entries */
1950 + struct entry **newtable;
1951 + struct entry *e;
1952 + struct entry **pE;
1953 + unsigned int newsize, i, index;
1954 + /* Check we're not hitting max capacity */
1955 + if (h->primeindex == (prime_table_length - 1)) return 0;
1956 + newsize = primes[++(h->primeindex)];
1957 +
1958 + newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
1959 + if (NULL != newtable)
1960 + {
1961 + memset(newtable, 0, newsize * sizeof(struct entry *));
1962 + /* This algorithm is not 'stable'. ie. it reverses the list
1963 + * when it transfers entries between the tables */
1964 + for (i = 0; i < h->tablelength; i++) {
1965 + while (NULL != (e = h->table[i])) {
1966 + h->table[i] = e->next;
1967 + index = indexFor(newsize,e->h);
1968 + e->next = newtable[index];
1969 + newtable[index] = e;
1970 + }
1971 + }
1972 + free(h->table);
1973 + h->table = newtable;
1974 + }
1975 + /* Plan B: realloc instead */
1976 + else
1977 + {
1978 + newtable = (struct entry **)
1979 + realloc(h->table, newsize * sizeof(struct entry *));
1980 + if (NULL == newtable) { (h->primeindex)--; return 0; }
1981 + h->table = newtable;
1982 + memset(newtable[h->tablelength], 0, newsize - h->tablelength);
1983 + for (i = 0; i < h->tablelength; i++) {
1984 + for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
1985 + index = indexFor(newsize,e->h);
1986 + if (index == i)
1987 + {
1988 + pE = &(e->next);
1989 + }
1990 + else
1991 + {
1992 + *pE = e->next;
1993 + e->next = newtable[index];
1994 + newtable[index] = e;
1995 + }
1996 + }
1997 + }
1998 + }
1999 + h->tablelength = newsize;
2000 + h->loadlimit = (unsigned int)(newsize * max_load_factor) + 1;
2001 + return -1;
2002 +}
2003 +
2004 +/*****************************************************************************/
2005 +unsigned int
2006 +hashtable_count(struct hashtable *h)
2007 +{
2008 + return h->entrycount;
2009 +}
2010 +
2011 +/*****************************************************************************/
2012 +int
2013 +hashtable_insert(struct hashtable *h, void *k, void *v)
2014 +{
2015 + /* This method allows duplicate keys - but they shouldn't be used */
2016 + unsigned int index;
2017 + struct entry *e;
2018 + if (++(h->entrycount) > h->loadlimit)
2019 + {
2020 + /* Ignore the return value. If expand fails, we should
2021 + * still try cramming just this value into the existing table
2022 + * -- we may not have memory for a larger table, but one more
2023 + * element may be ok. Next time we insert, we'll try expanding again.*/
2024 + hashtable_expand(h);
2025 + }
2026 + e = (struct entry *)malloc(sizeof(struct entry));
2027 + if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
2028 + e->h = hash(h,k);
2029 + index = indexFor(h->tablelength,e->h);
2030 + e->k = k;
2031 + e->v = v;
2032 + e->next = h->table[index];
2033 + h->table[index] = e;
2034 + return -1;
2035 +}
2036 +
2037 +/*****************************************************************************/
2038 +void * /* returns value associated with key */
2039 +hashtable_search(struct hashtable *h, void *k)
2040 +{
2041 + struct entry *e;
2042 + unsigned int hashvalue, index;
2043 + hashvalue = hash(h,k);
2044 + index = indexFor(h->tablelength,hashvalue);
2045 + e = h->table[index];
2046 + while (NULL != e)
2047 + {
2048 + /* Check hash value to short circuit heavier comparison */
2049 + if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
2050 + e = e->next;
2051 + }
2052 + return NULL;
2053 +}
2054 +
2055 +/*****************************************************************************/
2056 +void * /* returns value associated with key */
2057 +hashtable_remove(struct hashtable *h, void *k, int free_key)
2058 +{
2059 + /* TODO: consider compacting the table when the load factor drops enough,
2060 + * or provide a 'compact' method. */
2061 +
2062 + struct entry *e;
2063 + struct entry **pE;
2064 + void *v;
2065 + unsigned int hashvalue, index;
2066 +
2067 + hashvalue = hash(h,k);
2068 + index = indexFor(h->tablelength,hash(h,k));
2069 + pE = &(h->table[index]);
2070 + e = *pE;
2071 + while (NULL != e)
2072 + {
2073 + /* Check hash value to short circuit heavier comparison */
2074 + if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
2075 + {
2076 + *pE = e->next;
2077 + h->entrycount--;
2078 + v = e->v;
2079 + if (free_key) freekey(e->k);
2080 + free(e);
2081 + return v;
2082 + }
2083 + pE = &(e->next);
2084 + e = e->next;
2085 + }
2086 + return NULL;
2087 +}
2088 +
2089 +/*****************************************************************************/
2090 +/* destroy */
2091 +void
2092 +hashtable_destroy(struct hashtable *h, int free_kv)
2093 +{
2094 + unsigned int i;
2095 + struct entry *e, *f;
2096 + struct entry **table = h->table;
2097 + if (free_kv)
2098 + {
2099 + for (i = 0; i < h->tablelength; i++)
2100 + {
2101 + e = table[i];
2102 + while (NULL != e)
2103 + { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
2104 + }
2105 + }
2106 + free(h->table);
2107 + free(h);
2108 +}
2109 +
2110 +/*
2111 + * Copyright (c) 2002, Christopher Clark
2112 + * All rights reserved.
2113 + *
2114 + * Redistribution and use in source and binary forms, with or without
2115 + * modification, are permitted provided that the following conditions
2116 + * are met:
2117 + *
2118 + * * Redistributions of source code must retain the above copyright
2119 + * notice, this list of conditions and the following disclaimer.
2120 + *
2121 + * * Redistributions in binary form must reproduce the above copyright
2122 + * notice, this list of conditions and the following disclaimer in the
2123 + * documentation and/or other materials provided with the distribution.
2124 + *
2125 + * * Neither the name of the original author; nor the names of any contributors
2126 + * may be used to endorse or promote products derived from this software
2127 + * without specific prior written permission.
2128 + *
2129 + *
2130 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2131 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2132 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2133 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
2134 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2135 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2136 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2137 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2138 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2139 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2140 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2141 +*/
2142 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/hashtable.h Linux-PAM-1.1.3/modules/pam_console/hashtable.h
2143 --- Linux-PAM-1.1.3.orig/modules/pam_console/hashtable.h 1969-12-31 19:00:00.000000000 -0500
2144 +++ Linux-PAM-1.1.3/modules/pam_console/hashtable.h 2011-01-26 22:14:52.062657563 -0500
2145 @@ -0,0 +1,199 @@
2146 +/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
2147 +
2148 +#ifndef __HASHTABLE_CWC22_H__
2149 +#define __HASHTABLE_CWC22_H__
2150 +
2151 +struct hashtable;
2152 +
2153 +/* Example of use:
2154 + *
2155 + * struct hashtable *h;
2156 + * struct some_key *k;
2157 + * struct some_value *v;
2158 + *
2159 + * static unsigned int hash_from_key_fn( void *k );
2160 + * static int keys_equal_fn ( void *key1, void *key2 );
2161 + *
2162 + * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
2163 + * k = (struct some_key *) malloc(sizeof(struct some_key));
2164 + * v = (struct some_value *) malloc(sizeof(struct some_value));
2165 + *
2166 + * (initialise k and v to suitable values)
2167 + *
2168 + * if (! hashtable_insert(h,k,v) )
2169 + * { exit(-1); }
2170 + *
2171 + * if (NULL == (found = hashtable_search(h,k) ))
2172 + * { printf("not found!"); }
2173 + *
2174 + * if (NULL == (found = hashtable_remove(h,k) ))
2175 + * { printf("Not found\n"); }
2176 + *
2177 + */
2178 +
2179 +/* Macros may be used to define type-safe(r) hashtable access functions, with
2180 + * methods specialized to take known key and value types as parameters.
2181 + *
2182 + * Example:
2183 + *
2184 + * Insert this at the start of your file:
2185 + *
2186 + * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
2187 + * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
2188 + * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
2189 + *
2190 + * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
2191 + * These operate just like hashtable_insert etc., with the same parameters,
2192 + * but their function signatures have 'struct some_key *' rather than
2193 + * 'void *', and hence can generate compile time errors if your program is
2194 + * supplying incorrect data as a key (and similarly for value).
2195 + *
2196 + * Note that the hash and key equality functions passed to create_hashtable
2197 + * still take 'void *' parameters instead of 'some key *'. This shouldn't be
2198 + * a difficult issue as they're only defined and passed once, and the other
2199 + * functions will ensure that only valid keys are supplied to them.
2200 + *
2201 + * The cost for this checking is increased code size and runtime overhead
2202 + * - if performance is important, it may be worth switching back to the
2203 + * unsafe methods once your program has been debugged with the safe methods.
2204 + * This just requires switching to some simple alternative defines - eg:
2205 + * #define insert_some hashtable_insert
2206 + *
2207 + */
2208 +
2209 +/*****************************************************************************
2210 + * create_hashtable
2211 +
2212 + * @name create_hashtable
2213 + * @param minsize minimum initial size of hashtable
2214 + * @param hashfunction function for hashing keys
2215 + * @param key_eq_fn function for determining key equality
2216 + * @return newly created hashtable or NULL on failure
2217 + */
2218 +
2219 +struct hashtable *
2220 +create_hashtable(unsigned int minsize,
2221 + unsigned int (*hashfunction) (void*),
2222 + int (*key_eq_fn) (void*,void*));
2223 +
2224 +/*****************************************************************************
2225 + * hashtable_insert
2226 +
2227 + * @name hashtable_insert
2228 + * @param h the hashtable to insert into
2229 + * @param k the key - hashtable claims ownership and will free on removal
2230 + * @param v the value - does not claim ownership
2231 + * @return non-zero for successful insertion
2232 + *
2233 + * This function will cause the table to expand if the insertion would take
2234 + * the ratio of entries to table size over the maximum load factor.
2235 + *
2236 + * This function does not check for repeated insertions with a duplicate key.
2237 + * The value returned when using a duplicate key is undefined -- when
2238 + * the hashtable changes size, the order of retrieval of duplicate key
2239 + * entries is reversed.
2240 + * If in doubt, remove before insert.
2241 + */
2242 +
2243 +int
2244 +hashtable_insert(struct hashtable *h, void *k, void *v);
2245 +
2246 +#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
2247 +int fnname (struct hashtable *h, keytype *k, valuetype *v) \
2248 +{ \
2249 + return hashtable_insert(h,k,v); \
2250 +}
2251 +
2252 +/*****************************************************************************
2253 + * hashtable_search
2254 +
2255 + * @name hashtable_search
2256 + * @param h the hashtable to search
2257 + * @param k the key to search for - does not claim ownership
2258 + * @return the value associated with the key, or NULL if none found
2259 + */
2260 +
2261 +void *
2262 +hashtable_search(struct hashtable *h, void *k);
2263 +
2264 +#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
2265 +valuetype * fnname (struct hashtable *h, keytype *k) \
2266 +{ \
2267 + return (valuetype *) (hashtable_search(h,k)); \
2268 +}
2269 +
2270 +/*****************************************************************************
2271 + * hashtable_remove
2272 +
2273 + * @name hashtable_remove
2274 + * @param h the hashtable to remove the item from
2275 + * @param k the key to search for - does not claim ownership
2276 + * @return the value associated with the key, or NULL if none found
2277 + */
2278 +
2279 +void * /* returns value */
2280 +hashtable_remove(struct hashtable *h, void *k, int free_key);
2281 +
2282 +#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
2283 +valuetype * fnname (struct hashtable *h, keytype *k) \
2284 +{ \
2285 + return (valuetype *) (hashtable_remove(h,k)); \
2286 +}
2287 +
2288 +
2289 +/*****************************************************************************
2290 + * hashtable_count
2291 +
2292 + * @name hashtable_count
2293 + * @param h the hashtable
2294 + * @return the number of items stored in the hashtable
2295 + */
2296 +unsigned int
2297 +hashtable_count(struct hashtable *h);
2298 +
2299 +
2300 +/*****************************************************************************
2301 + * hashtable_destroy
2302 +
2303 + * @name hashtable_destroy
2304 + * @param h the hashtable
2305 + * @param free_values whether to call 'free' on the remaining values
2306 + */
2307 +
2308 +void
2309 +hashtable_destroy(struct hashtable *h, int free_values);
2310 +
2311 +#endif /* __HASHTABLE_CWC22_H__ */
2312 +
2313 +/*
2314 + * Copyright (c) 2002, Christopher Clark
2315 + * All rights reserved.
2316 + *
2317 + * Redistribution and use in source and binary forms, with or without
2318 + * modification, are permitted provided that the following conditions
2319 + * are met:
2320 + *
2321 + * * Redistributions of source code must retain the above copyright
2322 + * notice, this list of conditions and the following disclaimer.
2323 + *
2324 + * * Redistributions in binary form must reproduce the above copyright
2325 + * notice, this list of conditions and the following disclaimer in the
2326 + * documentation and/or other materials provided with the distribution.
2327 + *
2328 + * * Neither the name of the original author; nor the names of any contributors
2329 + * may be used to endorse or promote products derived from this software
2330 + * without specific prior written permission.
2331 + *
2332 + *
2333 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2334 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2335 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2336 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
2337 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2338 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2339 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2340 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2341 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2342 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2343 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2344 +*/
2345 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/hashtable_private.h Linux-PAM-1.1.3/modules/pam_console/hashtable_private.h
2346 --- Linux-PAM-1.1.3.orig/modules/pam_console/hashtable_private.h 1969-12-31 19:00:00.000000000 -0500
2347 +++ Linux-PAM-1.1.3/modules/pam_console/hashtable_private.h 2011-01-26 22:14:52.062657563 -0500
2348 @@ -0,0 +1,85 @@
2349 +/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
2350 +
2351 +#ifndef __HASHTABLE_PRIVATE_CWC22_H__
2352 +#define __HASHTABLE_PRIVATE_CWC22_H__
2353 +
2354 +#include "hashtable.h"
2355 +
2356 +/*****************************************************************************/
2357 +struct entry
2358 +{
2359 + void *k, *v;
2360 + unsigned int h;
2361 + struct entry *next;
2362 +};
2363 +
2364 +struct hashtable {
2365 + unsigned int tablelength;
2366 + struct entry **table;
2367 + unsigned int entrycount;
2368 + unsigned int loadlimit;
2369 + unsigned int primeindex;
2370 + unsigned int (*hashfn) (void *k);
2371 + int (*eqfn) (void *k1, void *k2);
2372 +};
2373 +
2374 +/*****************************************************************************/
2375 +unsigned int
2376 +hash(struct hashtable *h, void *k);
2377 +
2378 +/*****************************************************************************/
2379 +/* indexFor */
2380 +static inline unsigned int
2381 +indexFor(unsigned int tablelength, unsigned int hashvalue) {
2382 + return (hashvalue % tablelength);
2383 +};
2384 +
2385 +/* Only works if tablelength == 2^N */
2386 +/*static inline unsigned int
2387 +indexFor(unsigned int tablelength, unsigned int hashvalue)
2388 +{
2389 + return (hashvalue & (tablelength - 1u));
2390 +}
2391 +*/
2392 +
2393 +/*****************************************************************************/
2394 +#define freekey(X) free(X)
2395 +/*define freekey(X) ; */
2396 +
2397 +
2398 +/*****************************************************************************/
2399 +
2400 +#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
2401 +
2402 +/*
2403 + * Copyright (c) 2002, Christopher Clark
2404 + * All rights reserved.
2405 + *
2406 + * Redistribution and use in source and binary forms, with or without
2407 + * modification, are permitted provided that the following conditions
2408 + * are met:
2409 + *
2410 + * * Redistributions of source code must retain the above copyright
2411 + * notice, this list of conditions and the following disclaimer.
2412 + *
2413 + * * Redistributions in binary form must reproduce the above copyright
2414 + * notice, this list of conditions and the following disclaimer in the
2415 + * documentation and/or other materials provided with the distribution.
2416 + *
2417 + * * Neither the name of the original author; nor the names of any contributors
2418 + * may be used to endorse or promote products derived from this software
2419 + * without specific prior written permission.
2420 + *
2421 + *
2422 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2423 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2424 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2425 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
2426 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2427 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2428 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2429 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2430 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2431 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2432 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2433 +*/
2434 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/modechange.c Linux-PAM-1.1.3/modules/pam_console/modechange.c
2435 --- Linux-PAM-1.1.3.orig/modules/pam_console/modechange.c 1969-12-31 19:00:00.000000000 -0500
2436 +++ Linux-PAM-1.1.3/modules/pam_console/modechange.c 2011-01-26 22:14:52.062657563 -0500
2437 @@ -0,0 +1,324 @@
2438 +/* This file is derived from modechange.c included in the GNU fileutils
2439 + distribution. It has been changed to be a library specifically
2440 + for use within pam_console
2441 + Changes Copyright 1999 Red Hat Software, Inc.
2442 + */
2443 +
2444 +/* modechange.c -- file mode manipulation
2445 + Copyright (C) 1989, 1990 Free Software Foundation, Inc.
2446 +
2447 + This program is free software; you can redistribute it and/or modify
2448 + it under the terms of the GNU General Public License as published by
2449 + the Free Software Foundation; either version 2, or (at your option)
2450 + any later version.
2451 +
2452 + This program is distributed in the hope that it will be useful,
2453 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2454 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2455 + GNU General Public License for more details.
2456 +
2457 + You should have received a copy of the GNU General Public License
2458 + along with this program; if not, write to the Free Software Foundation,
2459 + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2460 +
2461 +/* Written by David MacKenzie <djm@ai.mit.edu> */
2462 +
2463 +/* The ASCII mode string is compiled into a linked list of `struct
2464 + modechange', which can then be applied to each file to be changed.
2465 + We do this instead of re-parsing the ASCII string for each file
2466 + because the compiled form requires less computation to use; when
2467 + changing the mode of many files, this probably results in a
2468 + performance gain. */
2469 +
2470 +#include "config.h"
2471 +#include <sys/types.h>
2472 +#include <sys/stat.h>
2473 +#include "modechange.h"
2474 +
2475 +#include <stdlib.h>
2476 +
2477 +/* Return newly allocated memory to hold one element of type TYPE. */
2478 +#define talloc(type) ((type *) malloc (sizeof (type)))
2479 +
2480 +#define isodigit(c) ((c) >= '0' && (c) <= '7')
2481 +
2482 +/* Return a positive integer containing the value of the ASCII
2483 + octal number S. If S is not an octal number, return -1. */
2484 +
2485 +static int
2486 +oatoi (const char *s)
2487 +{
2488 + register int i;
2489 +
2490 + if (*s == 0)
2491 + return -1;
2492 + for (i = 0; isodigit (*s); ++s)
2493 + i = i * 8 + *s - '0';
2494 + if (*s)
2495 + return -1;
2496 + return i;
2497 +}
2498 +
2499 +/* Return a linked list of file mode change operations created from
2500 + MODE_STRING, an ASCII string that contains either an octal number
2501 + specifying an absolute mode, or symbolic mode change operations with
2502 + the form:
2503 + [ugoa...][[+-=][rwxXstugo...]...][,...]
2504 + MASKED_OPS is a bitmask indicating which symbolic mode operators (=+-)
2505 + should not affect bits set in the umask when no users are given.
2506 + Operators not selected in MASKED_OPS ignore the umask.
2507 +
2508 + Return MODE_INVALID if `mode_string' does not contain a valid
2509 + representation of file mode change operations;
2510 + return MODE_MEMORY_EXHAUSTED if there is insufficient memory. */
2511 +
2512 +STATIC struct mode_change *
2513 +mode_compile (mode_string, masked_ops)
2514 + const char *mode_string;
2515 + unsigned masked_ops;
2516 +{
2517 + struct mode_change *head; /* First element of the linked list. */
2518 + struct mode_change *change; /* An element of the linked list. */
2519 + int i; /* General purpose temporary. */
2520 + int umask_value; /* The umask value (surprise). */
2521 + unsigned short affected_bits; /* Which bits in the mode are operated on. */
2522 + unsigned short affected_masked; /* `affected_bits' modified by umask. */
2523 + unsigned ops_to_mask; /* Operators to actually use umask on. */
2524 +
2525 + i = oatoi (mode_string);
2526 + if (i >= 0)
2527 + {
2528 + if (i > 07777)
2529 + return MODE_INVALID;
2530 + head = talloc (struct mode_change);
2531 + if (head == NULL)
2532 + return MODE_MEMORY_EXHAUSTED;
2533 + head->next = NULL;
2534 + head->op = '=';
2535 + head->flags = 0;
2536 + head->value = i;
2537 + head->affected = 07777; /* Affect all permissions. */
2538 + return head;
2539 + }
2540 +
2541 + umask_value = umask (0);
2542 + umask (umask_value); /* Restore the old value. */
2543 +
2544 + head = NULL;
2545 + change = NULL;
2546 + --mode_string;
2547 +
2548 + /* One loop iteration for each "ugoa...=+-rwxXstugo...[=+-rwxXstugo...]". */
2549 + do
2550 + {
2551 + affected_bits = 0;
2552 + ops_to_mask = 0;
2553 + /* Turn on all the bits in `affected_bits' for each group given. */
2554 + for (++mode_string;; ++mode_string)
2555 + switch (*mode_string)
2556 + {
2557 + case 'u':
2558 + affected_bits |= 04700;
2559 + break;
2560 + case 'g':
2561 + affected_bits |= 02070;
2562 + break;
2563 + case 'o':
2564 + affected_bits |= 01007;
2565 + break;
2566 + case 'a':
2567 + affected_bits |= 07777;
2568 + break;
2569 + default:
2570 + goto no_more_affected;
2571 + }
2572 +
2573 + no_more_affected:
2574 + /* If none specified, affect all bits, except perhaps those
2575 + set in the umask. */
2576 + if (affected_bits == 0)
2577 + {
2578 + affected_bits = 07777;
2579 + ops_to_mask = masked_ops;
2580 + }
2581 +
2582 + while (*mode_string == '=' || *mode_string == '+' || *mode_string == '-')
2583 + {
2584 + /* Add the element to the tail of the list, so the operations
2585 + are performed in the correct order. */
2586 + if (head == NULL)
2587 + {
2588 + head = talloc (struct mode_change);
2589 + if (head == NULL)
2590 + return MODE_MEMORY_EXHAUSTED;
2591 + change = head;
2592 + }
2593 + else
2594 + {
2595 + change->next = talloc (struct mode_change);
2596 + if (change->next == NULL)
2597 + {
2598 + mode_free (change);
2599 + return MODE_MEMORY_EXHAUSTED;
2600 + }
2601 + change = change->next;
2602 + }
2603 +
2604 + change->next = NULL;
2605 + change->op = *mode_string; /* One of "=+-". */
2606 + affected_masked = affected_bits;
2607 + if (ops_to_mask & (*mode_string == '=' ? MODE_MASK_EQUALS
2608 + : *mode_string == '+' ? MODE_MASK_PLUS
2609 + : MODE_MASK_MINUS))
2610 + affected_masked &= ~umask_value;
2611 + change->affected = affected_masked;
2612 + change->value = 0;
2613 + change->flags = 0;
2614 +
2615 + /* Set `value' according to the bits set in `affected_masked'. */
2616 + for (++mode_string;; ++mode_string)
2617 + switch (*mode_string)
2618 + {
2619 + case 'r':
2620 + change->value |= 00444 & affected_masked;
2621 + break;
2622 + case 'w':
2623 + change->value |= 00222 & affected_masked;
2624 + break;
2625 + case 'X':
2626 + change->flags |= MODE_X_IF_ANY_X;
2627 + /* Fall through. */
2628 + case 'x':
2629 + change->value |= 00111 & affected_masked;
2630 + break;
2631 + case 's':
2632 + /* Set the setuid/gid bits if `u' or `g' is selected. */
2633 + change->value |= 06000 & affected_masked;
2634 + break;
2635 + case 't':
2636 + /* Set the "save text image" bit if `o' is selected. */
2637 + change->value |= 01000 & affected_masked;
2638 + break;
2639 + case 'u':
2640 + /* Set the affected bits to the value of the `u' bits
2641 + on the same file. */
2642 + if (change->value)
2643 + goto invalid;
2644 + change->value = 00700;
2645 + change->flags |= MODE_COPY_EXISTING;
2646 + break;
2647 + case 'g':
2648 + /* Set the affected bits to the value of the `g' bits
2649 + on the same file. */
2650 + if (change->value)
2651 + goto invalid;
2652 + change->value = 00070;
2653 + change->flags |= MODE_COPY_EXISTING;
2654 + break;
2655 + case 'o':
2656 + /* Set the affected bits to the value of the `o' bits
2657 + on the same file. */
2658 + if (change->value)
2659 + goto invalid;
2660 + change->value = 00007;
2661 + change->flags |= MODE_COPY_EXISTING;
2662 + break;
2663 + default:
2664 + goto no_more_values;
2665 + }
2666 + no_more_values:;
2667 + }
2668 + } while (*mode_string == ',');
2669 + if (*mode_string == 0)
2670 + return head;
2671 +invalid:
2672 + mode_free (head);
2673 + return MODE_INVALID;
2674 +}
2675 +
2676 +/* Return file mode OLDMODE, adjusted as indicated by the list of change
2677 + operations CHANGES. If OLDMODE is a directory, the type `X'
2678 + change affects it even if no execute bits were set in OLDMODE.
2679 + The returned value has the S_IFMT bits cleared. */
2680 +
2681 +STATIC unsigned short
2682 +mode_adjust (oldmode, changes)
2683 + unsigned oldmode;
2684 + const struct mode_change *changes;
2685 +{
2686 + unsigned short newmode; /* The adjusted mode and one operand. */
2687 + unsigned short value; /* The other operand. */
2688 +
2689 + newmode = oldmode & 07777;
2690 +
2691 + for (; changes; changes = changes->next)
2692 + {
2693 + if (changes->flags & MODE_COPY_EXISTING)
2694 + {
2695 + /* Isolate in `value' the bits in `newmode' to copy, given in
2696 + the mask `changes->value'. */
2697 + value = newmode & changes->value;
2698 +
2699 + if (changes->value & 00700)
2700 + /* Copy `u' permissions onto `g' and `o'. */
2701 + value |= (value >> 3) | (value >> 6);
2702 + else if (changes->value & 00070)
2703 + /* Copy `g' permissions onto `u' and `o'. */
2704 + value |= (value << 3) | (value >> 3);
2705 + else
2706 + /* Copy `o' permissions onto `u' and `g'. */
2707 + value |= (value << 3) | (value << 6);
2708 +
2709 + /* In order to change only `u', `g', or `o' permissions,
2710 + or some combination thereof, clear unselected bits.
2711 + This can not be done in mode_compile because the value
2712 + to which the `changes->affected' mask is applied depends
2713 + on the old mode of each file. */
2714 + value &= changes->affected;
2715 + }
2716 + else
2717 + {
2718 + value = changes->value;
2719 + /* If `X', do not affect the execute bits if the file is not a
2720 + directory and no execute bits are already set. */
2721 + if ((changes->flags & MODE_X_IF_ANY_X)
2722 + && !S_ISDIR (oldmode)
2723 + && (newmode & 00111) == 0)
2724 + value &= ~00111; /* Clear the execute bits. */
2725 + }
2726 +
2727 + switch (changes->op)
2728 + {
2729 + case '=':
2730 + /* Preserve the previous values in `newmode' of bits that are
2731 + not affected by this change operation. */
2732 + newmode = (newmode & ~changes->affected) | value;
2733 + break;
2734 + case '+':
2735 + newmode |= value;
2736 + break;
2737 + case '-':
2738 + newmode &= ~value;
2739 + break;
2740 + }
2741 + }
2742 + return newmode;
2743 +}
2744 +
2745 +/* Free the memory used by the list of file mode change operations
2746 + CHANGES. */
2747 +
2748 +STATIC void
2749 +mode_free (changes)
2750 + register struct mode_change *changes;
2751 +{
2752 + register struct mode_change *next;
2753 +
2754 + while (changes)
2755 + {
2756 + next = changes->next;
2757 + free (changes);
2758 + changes = next;
2759 + }
2760 +}
2761 +
2762 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/modechange.h Linux-PAM-1.1.3/modules/pam_console/modechange.h
2763 --- Linux-PAM-1.1.3.orig/modules/pam_console/modechange.h 1969-12-31 19:00:00.000000000 -0500
2764 +++ Linux-PAM-1.1.3/modules/pam_console/modechange.h 2011-01-26 22:14:52.062657563 -0500
2765 @@ -0,0 +1,67 @@
2766 +/* modechange.h -- definitions for file mode manipulation
2767 + Copyright (C) 1989, 1990 Free Software Foundation, Inc.
2768 +
2769 + This program is free software; you can redistribute it and/or modify
2770 + it under the terms of the GNU General Public License as published by
2771 + the Free Software Foundation; either version 2, or (at your option)
2772 + any later version.
2773 +
2774 + This program is distributed in the hope that it will be useful,
2775 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2776 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2777 + GNU General Public License for more details.
2778 +
2779 + You should have received a copy of the GNU General Public License
2780 + along with this program; if not, write to the Free Software Foundation,
2781 + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2782 +
2783 +#ifndef _MODECHANGE_H
2784 +#define _MODECHANGE_H
2785 +
2786 +#ifndef STATIC
2787 +#define STATIC
2788 +#endif
2789 +
2790 +
2791 +/* Masks for the `flags' field in a `struct mode_change'. */
2792 +
2793 +/* Affect the execute bits only if at least one execute bit is set already,
2794 + or if the file is a directory. */
2795 +#define MODE_X_IF_ANY_X 01
2796 +
2797 +/* If set, copy some existing permissions for u, g, or o onto the other two.
2798 + Which of u, g, or o is copied is determined by which bits are set in the
2799 + `value' field. */
2800 +#define MODE_COPY_EXISTING 02
2801 +
2802 +struct mode_change
2803 +{
2804 + char op; /* One of "=+-". */
2805 + char flags; /* Special operations. */
2806 + unsigned short affected; /* Set for u/g/o/s/s/t, if to be affected. */
2807 + unsigned short value; /* Bits to add/remove. */
2808 + struct mode_change *next; /* Link to next change in list. */
2809 +};
2810 +
2811 +/* Masks for mode_compile argument. */
2812 +#define MODE_MASK_EQUALS 1
2813 +#define MODE_MASK_PLUS 2
2814 +#define MODE_MASK_MINUS 4
2815 +
2816 +/* Error return values for mode_compile. */
2817 +#define MODE_INVALID (struct mode_change *) 0
2818 +#define MODE_MEMORY_EXHAUSTED (struct mode_change *) 1
2819 +
2820 +#ifndef __P
2821 +# if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
2822 +# define __P(Args) Args
2823 +# else
2824 +# define __P(Args) ()
2825 +# endif
2826 +#endif
2827 +
2828 +STATIC struct mode_change *mode_compile __P ((const char *, unsigned));
2829 +STATIC unsigned short mode_adjust __P ((unsigned, const struct mode_change *));
2830 +STATIC void mode_free __P ((struct mode_change *));
2831 +
2832 +#endif /* _MODECHANGE_H */
2833 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/pam_console.8 Linux-PAM-1.1.3/modules/pam_console/pam_console.8
2834 --- Linux-PAM-1.1.3.orig/modules/pam_console/pam_console.8 1969-12-31 19:00:00.000000000 -0500
2835 +++ Linux-PAM-1.1.3/modules/pam_console/pam_console.8 2011-01-26 22:14:52.062657563 -0500
2836 @@ -0,0 +1,105 @@
2837 +.\" Copyright 1999 Red Hat Software, Inc.
2838 +.\" Written by Michael K. Johnson <johnsonm@redhat.com>
2839 +.TH pam_console 8 2005/10/4 "Red Hat" "System Administrator's Manual"
2840 +.SH NAME
2841 +pam_console \- determine user owning the system console
2842 +.SH SYNOPSIS
2843 +.B session optional pam_console.so
2844 +.br
2845 +.B auth required pam_console.so
2846 +.SH DESCRIPTION
2847 +pam_console.so is designed to give users at the physical console
2848 +(virtual terminals and local xdm-managed X sessions by default, but
2849 +that is configurable) capabilities that they would not otherwise have,
2850 +and to take those capabilities away when the are no longer logged in at
2851 +the console. It provides two main kinds of capabilities: file permissions
2852 +and authentication.
2853 +
2854 +When a user logs in at the console and \fBno other user is currently
2855 +logged in at the console\fP, pam_console.so will run handler programs
2856 +specified in the file /etc/security/console.handlers such as
2857 +pam_console_apply which changes permissions and ownership of files as
2858 +described in the file /etc/security/console.perms.
2859 +That user may then log in on other terminals that are considered part
2860 +of the console, and as long as the user is still logged in at any one
2861 +of those terminals, that user will own those devices. When the user
2862 +logs out of the last terminal, the console may be taken by the next
2863 +user to log in. Other users who have logged in at the console during
2864 +the time that the first user was logged in will not be given ownership
2865 +of the devices unless they log in on one of the terminals; having done
2866 +so on any one terminal, the next user will own those devices until
2867 +he or she has logged out of every terminal that is part of the physical
2868 +console. Then the race can start for the next user. In practice, this
2869 +is not a problem; the physical console is not generally in use by many
2870 +people at the same time, and pam_console.so just tries to do the right
2871 +thing in weird cases.
2872 +
2873 +When an application attempts to authenticate the user \fBand this user
2874 +is already logged in at the console\fP, pam_console.so checks whether
2875 +there is a file in /etc/security/console.apps/ directory with the same name
2876 +as the application servicename, and if such a file exists, authentication
2877 +succeeds. This way pam_console may be utilized to run some system
2878 +applications (reboots, config tools) without root password,
2879 +or to enter user password on the first system login only.
2880 +
2881 +.SH ARGUMENTS
2882 +.IP debug
2883 +turns on debugging
2884 +.IP allow_nonroot_tty
2885 +gain console locks and change permissions even if the TTY's owner is not root.
2886 +.IP handlersfile=\fIfilename\fP
2887 +tells pam_console.so to get the list of the handlers from a different
2888 +file than /etc/security/console.handlers
2889 +.\" .IP glob
2890 +.\" \fBnot yet implemented\fP interpret strings as globs instead of
2891 +.\" regexp expressions.
2892 +.SH EXAMPLE
2893 +\fB/etc/pam.d/some-system-tool\fP:
2894 +.br
2895 +auth sufficient pam_rootok.so
2896 +.br
2897 +auth required pam_console.so
2898 +.br
2899 +
2900 +.br
2901 +\fB/etc/pam.d/some-login-service\fP:
2902 +.br
2903 +auth sufficient pam_console.so
2904 +.br
2905 +auth required pam_unix.so
2906 +.br
2907 +session required pam_unix.so
2908 +.br
2909 +session optional pam_console.so
2910 +.br
2911 +.SH FILES
2912 +\fI/var/run/console/\fP
2913 +.br
2914 +\fI/var/run/console/console.lock\fP
2915 +.br
2916 +\fI/etc/security/console.apps\fP
2917 +.br
2918 +\fI/etc/security/console.handlers\fP
2919 +.SH SECURITY NOTES
2920 +When pam_console "auth" is used for login services which provide
2921 +possibility of remote login, it is necessary to make sure the application
2922 +correctly sets PAM_RHOST variable, or to deny remote logins completely.
2923 +Currently, /bin/login (invoked from telnetd) and gdm is OK, others may be not.
2924 +.SH "SEE ALSO"
2925 +.BR console.perms (5)
2926 +.br
2927 +.BR console.apps (5)
2928 +.br
2929 +.BR console.handlers (5)
2930 +.br
2931 +.BR pam_console_apply (8)
2932 +.br
2933 +\fI/usr/share/doc/pam*/html/index.html\fP
2934 +.SH BUGS
2935 +Let's hope not, but if you find any, please report them via the "Bug Track"
2936 +link at http://bugzilla.redhat.com/bugzilla/
2937 +.SH AUTHORS
2938 +Michael K. Johnson <johnsonm@redhat.com>
2939 +.br
2940 +Support of console.handlers and other improvements by
2941 +Tomas Mraz <tmraz@redhat.com>
2942 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/pam_console.c Linux-PAM-1.1.3/modules/pam_console/pam_console.c
2943 --- Linux-PAM-1.1.3.orig/modules/pam_console/pam_console.c 1969-12-31 19:00:00.000000000 -0500
2944 +++ Linux-PAM-1.1.3/modules/pam_console/pam_console.c 2011-01-26 22:14:52.062657563 -0500
2945 @@ -0,0 +1,669 @@
2946 +/* Copyright 1999, 2005 Red Hat, Inc.
2947 + * This software may be used under the terms of the GNU General Public
2948 + * License, available in the file COPYING accompanying this file.
2949 + *
2950 + * /var/run/console/console.lock is the file used to control access to
2951 + * devices. It is created when the first console user logs in,
2952 + * and that user has the control of the console until they have
2953 + * logged out of all concurrent login sessions. That is,
2954 + * user A logs in on console 1 (gets access to console devices)
2955 + * user B logs in on console 2 (does not get access)
2956 + * user A logs in on console 3 (already has access)
2957 + * user A logs out of console 1 (still has access on console 3)
2958 + * user A logs out of console 3 (access revoked; user B does NOT get access)
2959 + * Note that all console users (both A and B in this situation)
2960 + * should be able to run console access programs (that is,
2961 + * pam_sm_authenticate() should return PAM_SUCCESS) even if
2962 + * console access to files/devices is not available to any one of
2963 + * the users (B in this case).
2964 + *
2965 + * /var/run/console/<username> is used for reference counting
2966 + * and to make console authentication easy -- if it exists, then
2967 + * <username> has console access.
2968 + *
2969 + * A system startup script should remove /var/run/console/console.lock
2970 + * and everything in /var/run/console/
2971 + */
2972 +
2973 +#include "config.h"
2974 +#include <errno.h>
2975 +#include <pwd.h>
2976 +#include <stdlib.h>
2977 +#include <string.h>
2978 +#include <syslog.h>
2979 +#include <sys/types.h>
2980 +#include <sys/stat.h>
2981 +#include <sys/param.h>
2982 +#include <fcntl.h>
2983 +#include <unistd.h>
2984 +#include <stdio.h>
2985 +#include <regex.h>
2986 +#include "pam_console.h"
2987 +#include "handlers.h"
2988 +#include <security/pam_modules.h>
2989 +#include <security/_pam_macros.h>
2990 +#include <security/pam_modutil.h>
2991 +#include <security/pam_ext.h>
2992 +
2993 +/* In order to avoid errors in pam_get_item(), we need a very
2994 + * unfortunate cast. This is a terrible design error in PAM
2995 + * that Linux-PAM slavishly follows. :-(
2996 + */
2997 +#define CAST_ME_HARDER (const void**)
2998 +
2999 +static char consolelock[] = LOCKDIR "/" LOCKFILE;
3000 +static char consolerefs[] = LOCKDIR "/";
3001 +static char consoleapps[] = "/etc/security/console.apps/";
3002 +static char consolehandlers[PATH_MAX] = "/etc/security/console.handlers";
3003 +static int configfileparsed = 0;
3004 +static int debug = 0;
3005 +static int allow_nonroot_tty = 0;
3006 +
3007 +/* some syslogging */
3008 +
3009 +void
3010 +_pam_log(pam_handle_t *pamh, int err, int debug_p, const char *format, ...)
3011 +{
3012 + va_list args;
3013 +
3014 + if (debug_p && !debug) return;
3015 +
3016 + va_start(args, format);
3017 + pam_vsyslog(pamh, err, format, args);
3018 + closelog();
3019 +}
3020 +
3021 +static void *
3022 +_do_malloc(size_t req)
3023 +{
3024 + void *ret;
3025 +
3026 + ret = malloc(req);
3027 + if (!ret) abort();
3028 + return ret;
3029 +}
3030 +
3031 +static void
3032 +_args_parse(pam_handle_t *pamh, int argc, const char **argv)
3033 +{
3034 + for (; argc-- > 0; ++argv) {
3035 + if (!strcmp(*argv,"debug"))
3036 + debug = 1;
3037 + else if (!strcmp(*argv,"allow_nonroot_tty"))
3038 + allow_nonroot_tty = 1;
3039 + else if (!strncmp(*argv,"handlersfile=",13))
3040 + if (strlen(*argv+13) < PATH_MAX)
3041 + strcpy(consolehandlers,*argv+13);
3042 + else
3043 + _pam_log(pamh, LOG_ERR, FALSE,
3044 + "_args_parse: handlersfile filename too long");
3045 + else {
3046 + _pam_log(pamh, LOG_ERR, FALSE,
3047 + "_args_parse: unknown option; %s",*argv);
3048 + }
3049 + }
3050 +}
3051 +
3052 +static int
3053 +is_root(pam_handle_t *pamh, const char *username) {
3054 + /* this should correspond to suser() in the kernel, since the
3055 + * whole point of this is to avoid doing unnecessary file ops
3056 + */
3057 + struct passwd *pwd;
3058 +
3059 + pwd = pam_modutil_getpwnam(pamh, username);
3060 + if (pwd == NULL) {
3061 + _pam_log(pamh, LOG_ERR, FALSE, "getpwnam failed for %s", username);
3062 + return 0;
3063 + }
3064 + return !pwd->pw_uid;
3065 +}
3066 +
3067 +static int
3068 +check_one_console_name(const char *name, const char *cregex) {
3069 + regex_t p;
3070 + int r_err;
3071 + char *class_exp;
3072 +
3073 + class_exp = _do_malloc(strlen(cregex) + 3);
3074 + sprintf(class_exp, "^%s$", cregex);
3075 + r_err = regcomp(&p, class_exp, REG_EXTENDED|REG_NOSUB);
3076 + if (r_err) do_regerror(r_err, &p);
3077 + r_err = regexec(&p, name, 0, NULL, 0);
3078 + regfree(&p);
3079 + free (class_exp);
3080 + return !r_err;
3081 +}
3082 +
3083 +static int
3084 +check_console_name(pam_handle_t *pamh, const char *consolename, int nonroot_ok, int on_set) {
3085 + int found = 0;
3086 + int statted = 0;
3087 + struct stat st;
3088 + char full_path[PATH_MAX];
3089 + const char *consoleregex;
3090 +
3091 + _pam_log(pamh, LOG_DEBUG, TRUE, "check console %s", consolename);
3092 +
3093 + if ((consoleregex = console_get_regexes()) == NULL) {
3094 + /* probably a broken configuration */
3095 + _pam_log(pamh, LOG_INFO, FALSE, "no console regexes in console.handlers config");
3096 + return 0;
3097 + }
3098 + for (; *consoleregex != '\0'; consoleregex += strlen(consoleregex)+1) {
3099 + if (check_one_console_name(consolename, consoleregex)) {
3100 + found = 1;
3101 + break;
3102 + }
3103 + }
3104 +
3105 + if (!found) {
3106 + /* not found */
3107 + _pam_log(pamh, LOG_INFO, TRUE, "no matching console regex found");
3108 + return 0;
3109 + }
3110 +
3111 + /* add some policy here -- not really the PAM way of doing things, but
3112 + it gives us an extra measure of security in case of misconfiguration */
3113 + memset(&st, 0, sizeof(st));
3114 + statted = 0;
3115 +
3116 + _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible console \"%s\"", consolename);
3117 + if (lstat(consolename, &st) != -1) {
3118 + statted = 1;
3119 + }
3120 + if (!statted) {
3121 + strcpy(full_path, "/dev/");
3122 + strncat(full_path, consolename,
3123 + sizeof(full_path) - 1 - strlen(full_path));
3124 + full_path[sizeof(full_path) - 1] = '\0';
3125 + _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible console \"%s\"",
3126 + full_path);
3127 + if (lstat(full_path, &st) != -1) {
3128 + statted = 1;
3129 + }
3130 + }
3131 + if (!statted && (consolename[0] == ':')) {
3132 + int l;
3133 + char *dot = NULL;
3134 + strcpy(full_path, "/tmp/.X11-unix/X");
3135 + l = sizeof(full_path) - 1 - strlen(full_path);
3136 + dot = strchr(consolename + 1, '.');
3137 + if (dot != NULL) {
3138 + l = (l < dot - consolename - 1) ? l : dot - consolename - 1;
3139 + }
3140 + strncat(full_path, consolename + 1, l);
3141 + full_path[sizeof(full_path) - 1] = '\0';
3142 + _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible console \"%s\"",
3143 + full_path);
3144 + if (lstat(full_path, &st) != -1) {
3145 + statted = 1;
3146 + }
3147 + else if (!on_set) { /* there is no X11 socket in case of X11 crash */
3148 + _pam_log(pamh, LOG_DEBUG, TRUE, "can't find X11 socket to examine for %s probably due to X crash", consolename);
3149 + statted = 1; /* this will work because st.st_uid is 0 */
3150 + }
3151 + }
3152 +
3153 + if (statted) {
3154 + int ok = 0;
3155 + if (st.st_uid == 0) {
3156 + _pam_log(pamh, LOG_DEBUG, TRUE, "console %s is owned by UID 0", consolename);
3157 + ok = 1;
3158 + }
3159 + if (S_ISCHR(st.st_mode)) {
3160 + _pam_log(pamh, LOG_DEBUG, TRUE, "console %s is a character device", consolename);
3161 + ok = 1;
3162 + }
3163 + if (!ok && !nonroot_ok) {
3164 + _pam_log(pamh, LOG_INFO, TRUE, "%s is not a valid console device because it is owned by UID %d and the allow_nonroot flag was not set", consolename, st.st_uid);
3165 + found = 0;
3166 + }
3167 + } else {
3168 + _pam_log(pamh, LOG_INFO, TRUE, "can't find device or X11 socket to examine for %s", consolename);
3169 + found = 0;
3170 + }
3171 +
3172 + if (found)
3173 + return 1;
3174 +
3175 + /* not found */
3176 + _pam_log(pamh, LOG_INFO, TRUE, "did not find console %s", consolename);
3177 + return 0;
3178 +}
3179 +
3180 +static int
3181 +lock_console(pam_handle_t *pamh, const char *id)
3182 +{
3183 + int fd, ret_val;
3184 +
3185 + fd = open(consolelock, O_RDWR|O_CREAT|O_EXCL, 0600);
3186 + if (fd < 0) {
3187 + _pam_log(pamh, LOG_INFO, TRUE,
3188 + "console file lock already in place %s", consolelock);
3189 + return -1;
3190 + }
3191 + ret_val = pam_modutil_write (fd, id, strlen(id));
3192 + if (ret_val == -1) {
3193 + close(fd);
3194 + }
3195 + else {
3196 + ret_val = close(fd);
3197 + }
3198 + if (ret_val == -1) {
3199 + unlink(consolelock);
3200 + return -1;
3201 + }
3202 + return 0;
3203 +}
3204 +
3205 +/* warning, the following function uses goto for error recovery.
3206 + * If you can't stand goto, don't read this function. :-P
3207 + */
3208 +static int
3209 +use_count(pam_handle_t *pamh, char *filename, int increment, int delete)
3210 +{
3211 + int fd, err, val;
3212 + static int cache_fd = 0;
3213 + struct stat st;
3214 + struct flock lockinfo;
3215 + char *buf = NULL;
3216 +
3217 + if (cache_fd) {
3218 + fd = cache_fd;
3219 + cache_fd = 0;
3220 + /* the cached fd is always already locked */
3221 + } else {
3222 +top:
3223 + fd = open(filename, O_RDWR|O_CREAT, 0600);
3224 + if (fd < 0) {
3225 + _pam_log(pamh, LOG_ERR, FALSE,
3226 + "Could not open lock file %s, disallowing console access",
3227 + filename);
3228 + return -1;
3229 + }
3230 +
3231 + lockinfo.l_type = F_WRLCK;
3232 + lockinfo.l_whence = SEEK_SET;
3233 + lockinfo.l_start = 0;
3234 + lockinfo.l_len = 0;
3235 + alarm(20); /* FIXME: what if caller has sigalrm masked? */
3236 + err = fcntl(fd, F_SETLKW, &lockinfo);
3237 + alarm(0);
3238 + if (err == EAGAIN) {
3239 + /* if someone has locked the file and not written to it in
3240 + * at least 20 seconds, we assume they either forgot to unlock
3241 + * it or are catatonic -- chances are slim that they are in
3242 + * the middle of a read-write cycle and I don't want to make
3243 + * us lock users out. Perhaps I should just return PAM_SUCCESS
3244 + * instead and log the event? Kill the process holding the
3245 + * lock? Options abound... For now, we ignore it.
3246 + */
3247 + fcntl(fd, F_GETLK, &lockinfo);
3248 + /* now lockinfo.l_pid == 0 implies that the lock was released
3249 + * by the other process between returning from the 20 second
3250 + * wait and calling fcntl again, not likely to ever happen, and
3251 + * not a problem other than cosmetics even if it does.
3252 + */
3253 + _pam_log(pamh, LOG_ERR, FALSE,
3254 + "ignoring stale lock on file %s by process %d",
3255 + lockinfo.l_pid, filename);
3256 + }
3257 +
3258 + /* it is possible at this point that the file has been removed
3259 + * by a previous login; if this happens, we need to start over.
3260 + * Unfortunately, the only way to do this without potential stack
3261 + * trashing is a goto.
3262 + */
3263 + if (access (filename, F_OK) < 0) {
3264 + close (fd);
3265 + goto top;
3266 + }
3267 + }
3268 +
3269 +
3270 + if (fstat (fd, &st)) {
3271 + _pam_log(pamh, LOG_ERR, FALSE,
3272 + "\"impossible\" fstat error on open fd for %s", filename);
3273 + err = -1; goto return_error;
3274 + }
3275 + buf = _do_malloc(st.st_size+2); /* size will never grow by more than one */
3276 + if (st.st_size) {
3277 + buf[0] = '\0'; /* if read returns eof, need atoi to give us 0 */
3278 + if (pam_modutil_read (fd, buf, st.st_size) == -1) {
3279 + _pam_log(pamh, LOG_ERR, FALSE,
3280 + "\"impossible\" read error on %s", filename);
3281 + err = -1; goto return_error;
3282 + }
3283 + if (lseek(fd, 0, SEEK_SET) == -1) {
3284 + _pam_log(pamh, LOG_ERR, FALSE,
3285 + "\"impossible\" lseek error on %s", filename);
3286 + err = -1; goto return_error;
3287 + }
3288 + buf[st.st_size] = '\0';
3289 + val = atoi(buf);
3290 + } else {
3291 + val = 0;
3292 + }
3293 +
3294 + if (increment) { /* increment == 0 implies query */
3295 + val += increment;
3296 + if (val <= 0 && delete) {
3297 + if (unlink (filename)) {
3298 + _pam_log(pamh, LOG_ERR, FALSE,
3299 + "\"impossible\" unlink error on %s", filename);
3300 + err = -1; goto return_error;
3301 + }
3302 + err = 0; goto return_error;
3303 + }
3304 +
3305 + sprintf(buf, "%d", val);
3306 + if (pam_modutil_write(fd, buf, strlen(buf)) == -1) {
3307 + _pam_log(pamh, LOG_ERR, FALSE,
3308 + "\"impossible\" write error on %s", filename);
3309 + err = -1; goto return_error;
3310 + }
3311 + }
3312 +
3313 + err = val;
3314 +
3315 + if (!increment) {
3316 + cache_fd = fd;
3317 + } else {
3318 +return_error:
3319 + close (fd);
3320 + }
3321 + if (buf) free (buf);
3322 + return err;
3323 +}
3324 +
3325 +PAM_EXTERN int
3326 +pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
3327 +{
3328 + /* getuid() must return an id that maps to a username as a filename in
3329 + * /var/run/console/
3330 + * and the service name must be listed in
3331 + * /etc/security/console-apps
3332 + */
3333 + struct passwd *pwd;
3334 + char *lockfile = NULL;
3335 + char *appsfile = NULL;
3336 + const char *service;
3337 + int ret = PAM_AUTH_ERR;
3338 +
3339 + D(("called."));
3340 + _args_parse(pamh, argc, argv);
3341 +
3342 + if (getuid() == 0) {
3343 + /* Obtain user name by pam_get_user() .
3344 + * We must make sure that the user sits on the local console
3345 + */
3346 + const char *user = NULL;
3347 + const char *host = NULL;
3348 + const char *user_prompt;
3349 +
3350 + D(("invoked under root."));
3351 +
3352 + ret = pam_get_item(pamh, PAM_RHOST, (const void **) &host);
3353 + if (ret == PAM_SUCCESS && host && *host) {
3354 + _pam_log(pamh, LOG_ERR, TRUE,
3355 + "PAM_RHOST is set - not invoked from console.");
3356 + return PAM_AUTH_ERR;
3357 + }
3358 +
3359 + D(("Obtain user name."));
3360 + if (pam_get_item(pamh, PAM_USER_PROMPT, (const void **) &user_prompt)
3361 + != PAM_SUCCESS) {
3362 + user_prompt = "login: ";
3363 + }
3364 + ret = pam_get_user(pamh, &user, user_prompt);
3365 + if (ret != PAM_SUCCESS) {
3366 + _pam_log(pamh, LOG_ERR, FALSE, "could not obtain user name");
3367 + return ret;
3368 + }
3369 +
3370 + pwd = pam_modutil_getpwnam(pamh, user);
3371 + if (pwd == NULL) {
3372 + _pam_log(pamh, LOG_ERR, FALSE, "user '%s' unknown for this system", user);
3373 + return PAM_AUTH_ERR;
3374 + }
3375 +
3376 + if (pwd->pw_uid == 0) {
3377 + _pam_log(pamh, LOG_ERR, TRUE, "user '%s' is not allowed to "
3378 + "authenticate by pam_console", pwd->pw_name);
3379 + return PAM_AUTH_ERR;
3380 + }
3381 +
3382 + } else {
3383 + pwd = pam_modutil_getpwuid(pamh, getuid());
3384 + if (pwd == NULL) {
3385 + _pam_log(pamh, LOG_ERR, FALSE, "user with id %d not found", getuid());
3386 + return PAM_AUTH_ERR;
3387 + }
3388 + }
3389 +
3390 + lockfile = _do_malloc(strlen(consolerefs) + strlen(pwd->pw_name) + 2);
3391 + sprintf(lockfile, "%s%s", consolerefs, pwd->pw_name); /* trusted data */
3392 +
3393 + pam_get_item(pamh, PAM_SERVICE, CAST_ME_HARDER &service);
3394 + appsfile = _do_malloc(strlen(consoleapps) + strlen(service) + 2);
3395 + sprintf(appsfile, "%s%s", consoleapps, service); /* trusted data */
3396 +
3397 + if (access(lockfile, F_OK) < 0) {
3398 + _pam_log(pamh, LOG_ERR, TRUE,
3399 + "user %s not a console user", pwd->pw_name);
3400 + ret = PAM_AUTH_ERR; goto error_return;
3401 + }
3402 +
3403 + if (access(appsfile, F_OK) < 0) {
3404 + _pam_log(pamh, LOG_ERR, TRUE,
3405 + "console access disallowed for service %s", service);
3406 + ret = PAM_AUTH_ERR; goto error_return;
3407 + }
3408 +
3409 + /* all checks OK, must be OK */
3410 + ret = PAM_SUCCESS;
3411 +
3412 +error_return:
3413 + if (lockfile) free (lockfile);
3414 + if (appsfile) free (appsfile);
3415 + return ret;
3416 +}
3417 +
3418 +PAM_EXTERN int
3419 +pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
3420 +{
3421 + return PAM_SUCCESS;
3422 +}
3423 +
3424 +PAM_EXTERN int
3425 +pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
3426 +{
3427 + /* Create /var/run/console/console.lock if it does not exist
3428 + * Create /var/run/console/<username> if it does not exist
3429 + * Increment its use count
3430 + * Change file ownerships and permissions as given in
3431 + * /etc/security/console.perms IFF returned use count was 0
3432 + * and we created /var/run/console/console.lock
3433 + */
3434 + int got_console = 0;
3435 + int count = 0;
3436 + int ret = PAM_SESSION_ERR;
3437 + const char *username = NULL, *user_prompt;
3438 + char *lockfile;
3439 + const char *tty = NULL;
3440 +
3441 + D(("called."));
3442 + _pam_log(pamh, LOG_ERR, TRUE, "pam_console open_session");
3443 + _args_parse(pamh, argc, argv);
3444 + if(pam_get_item(pamh, PAM_USER_PROMPT, (const void **) &user_prompt)
3445 + != PAM_SUCCESS) {
3446 + user_prompt = "user name: ";
3447 + }
3448 + username = NULL;
3449 + pam_get_user(pamh, &username, user_prompt);
3450 + _pam_log(pamh, LOG_DEBUG, TRUE, "user is \"%s\"",
3451 + username ? username : "(null)");
3452 + if (!username || !username[0]) {
3453 + _pam_log(pamh, LOG_DEBUG, TRUE, "user is \"%s\"",
3454 + username ? username : "(null)");
3455 + return PAM_SESSION_ERR;
3456 + }
3457 + if (is_root(pamh, username)) {
3458 + _pam_log(pamh, LOG_DEBUG, TRUE, "user \"%s\" is root", username);
3459 + return PAM_SUCCESS;
3460 + }
3461 + pam_get_item(pamh, PAM_TTY, CAST_ME_HARDER &tty);
3462 + if (!tty || !tty[0]) {
3463 + _pam_log(pamh, LOG_ERR, TRUE, "TTY not defined");
3464 + return PAM_SESSION_ERR;
3465 + }
3466 +
3467 + /* get configuration */
3468 + if (!configfileparsed) {
3469 + console_parse_handlers(pamh, consolehandlers);
3470 + configfileparsed = 1;
3471 + }
3472 +
3473 + /* return success quietly if not a terminal login */
3474 + if (!check_console_name(pamh, tty, allow_nonroot_tty, TRUE)) return PAM_SUCCESS;
3475 +
3476 + if (!lock_console(pamh, username)) got_console = 1;
3477 +
3478 + lockfile = _do_malloc(strlen(consolerefs) + strlen(username) + 2);
3479 + sprintf(lockfile, "%s%s", consolerefs, username); /* trusted data */
3480 + count = use_count(pamh, lockfile , 1, 0);
3481 + if (count < 0) {
3482 + ret = PAM_SESSION_ERR;
3483 + }
3484 + else if (got_console) {
3485 + _pam_log(pamh, LOG_DEBUG, TRUE, "%s is console user", username);
3486 + /* errors will be logged and are not critical */
3487 + console_run_handlers(pamh, TRUE, username, tty);
3488 + }
3489 +
3490 + free(lockfile);
3491 + return ret;
3492 +}
3493 +
3494 +PAM_EXTERN int
3495 +pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
3496 +{
3497 + /* Get /var/run/console/<username> use count, leave it locked
3498 + * If use count is now 1:
3499 + * If /var/run/console/console.lock contains <username>"
3500 + * Revert file ownerships and permissions as given in
3501 + * /etc/security/console.perms
3502 + * Decrement /var/run/console/<username>, removing both it and
3503 + * /var/run/console/console.lock if 0, unlocking /var/run/console/<username>
3504 + * in any case.
3505 + */
3506 + int fd;
3507 + int count = 0;
3508 + int err;
3509 + int delete_consolelock = 0;
3510 + const char *username = NULL, *user_prompt;
3511 + char *lockfile = NULL;
3512 + char *consoleuser = NULL;
3513 + const char *tty = NULL;
3514 + struct stat st;
3515 +
3516 + D(("called."));
3517 + _args_parse(pamh, argc, argv);
3518 + if(pam_get_item(pamh, PAM_USER_PROMPT, (const void **) &user_prompt)
3519 + != PAM_SUCCESS) {
3520 + user_prompt = "user name: ";
3521 + }
3522 + pam_get_user(pamh, &username, user_prompt);
3523 +
3524 + if (!username || !username[0]) return PAM_SESSION_ERR;
3525 + if (is_root(pamh, username)) return PAM_SUCCESS;
3526 + pam_get_item(pamh, PAM_TTY, CAST_ME_HARDER &tty);
3527 + if (!tty || !tty[0]) return PAM_SESSION_ERR;
3528 +
3529 + /* get configuration */
3530 + if (!configfileparsed) {
3531 + console_parse_handlers(pamh, consolehandlers);
3532 + configfileparsed = 1;
3533 + }
3534 +
3535 + /* return success quietly if not a terminal login */
3536 + if (!check_console_name(pamh, tty, allow_nonroot_tty, FALSE)) return PAM_SUCCESS;
3537 +
3538 + lockfile = _do_malloc(strlen(consolerefs) + strlen(username) + 2);
3539 + sprintf(lockfile, "%s%s", consolerefs, username); /* trusted data */
3540 + count = use_count(pamh, lockfile, 0, 0);
3541 + if (count < 0) {
3542 + err = PAM_SESSION_ERR;
3543 + goto return_error;
3544 + }
3545 +
3546 + if (count == 1) {
3547 + fd = open(consolelock, O_RDONLY);
3548 + if (fd != -1) {
3549 + if (fstat (fd, &st)) {
3550 + _pam_log(pamh, LOG_ERR, FALSE,
3551 + "\"impossible\" fstat error on %s", consolelock);
3552 + close(fd);
3553 + err = PAM_SESSION_ERR; goto return_error;
3554 + }
3555 + consoleuser = _do_malloc(st.st_size+1);
3556 + if (st.st_size) {
3557 + if (pam_modutil_read (fd, consoleuser, st.st_size) == -1) {
3558 + _pam_log(pamh, LOG_ERR, FALSE,
3559 + "\"impossible\" read error on %s", consolelock);
3560 + err = PAM_SESSION_ERR;
3561 + close(fd);
3562 + goto return_error;
3563 + }
3564 + consoleuser[st.st_size] = '\0';
3565 + }
3566 + close (fd);
3567 +
3568 + if (!strcmp(username, consoleuser)) {
3569 + delete_consolelock = 1;
3570 + /* errors will be logged and at this stage we cannot do
3571 + * anything about them...
3572 + */
3573 + console_run_handlers(pamh, FALSE, username, tty);
3574 + }
3575 + } else {
3576 + /* didn't open file */
3577 + err = PAM_SESSION_ERR;
3578 + goto return_error;
3579 + }
3580 + }
3581 +
3582 + count = use_count(pamh, lockfile, -1, 1);
3583 + if (count < 1 && delete_consolelock) {
3584 + if (unlink(consolelock)) {
3585 + _pam_log(pamh, LOG_ERR, FALSE,
3586 + "\"impossible\" unlink error on %s", consolelock);
3587 + err = PAM_SESSION_ERR; goto return_error;
3588 + }
3589 + }
3590 +
3591 + err = PAM_SUCCESS;
3592 +return_error:
3593 + if (lockfile) free(lockfile);
3594 + if (consoleuser) free (consoleuser);
3595 + return err;
3596 +}
3597 +
3598 +#ifdef PAM_STATIC
3599 +
3600 +/* static module data */
3601 +
3602 +struct pam_module _pam_console_modstruct = {
3603 + "pam_console",
3604 + pam_sm_authenticate,
3605 + pam_sm_setcred,
3606 + NULL,
3607 + pam_sm_open_session,
3608 + pam_sm_close_session,
3609 + NULL,
3610 +};
3611 +
3612 +#endif
3613 +
3614 +/* end of module definition */
3615 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/pam_console.h Linux-PAM-1.1.3/modules/pam_console/pam_console.h
3616 --- Linux-PAM-1.1.3.orig/modules/pam_console/pam_console.h 1969-12-31 19:00:00.000000000 -0500
3617 +++ Linux-PAM-1.1.3/modules/pam_console/pam_console.h 2011-01-26 22:14:52.062657563 -0500
3618 @@ -0,0 +1,25 @@
3619 +/* Copyright 1999, 2005 Red Hat, Inc.
3620 + * This software may be used under the terms of the GNU General Public
3621 + * License, available in the file COPYING accompanying this file.
3622 + */
3623 +#ifndef _PAM_CONSOLE_H
3624 +#define _PAM_CONSOLE_H
3625 +#include <security/pam_modules.h>
3626 +#include <regex.h>
3627 +
3628 +#define LOCKFILE "console.lock"
3629 +
3630 +#ifndef FALSE
3631 +#define FALSE 0
3632 +#endif
3633 +#ifndef TRUE
3634 +#define TRUE (!FALSE)
3635 +#endif
3636 +
3637 +void
3638 +_pam_log(pam_handle_t *pamh, int err, int debug_p, const char *format, ...);
3639 +
3640 +void
3641 +do_regerror(int errcode, const regex_t *preg);
3642 +
3643 +#endif /* _PAM_CONSOLE_H */
3644 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/pam_console_apply.8 Linux-PAM-1.1.3/modules/pam_console/pam_console_apply.8
3645 --- Linux-PAM-1.1.3.orig/modules/pam_console/pam_console_apply.8 1969-12-31 19:00:00.000000000 -0500
3646 +++ Linux-PAM-1.1.3/modules/pam_console/pam_console_apply.8 2011-01-26 22:14:52.062657563 -0500
3647 @@ -0,0 +1,62 @@
3648 +.\" Copyright 2001 Red Hat, Inc.
3649 +.TH pam_console_apply 8 2005/5/2 "Red Hat" "System Administrator's Manual"
3650 +.SH NAME
3651 +pam_console_apply \- set or revoke permissions for users at the system console
3652 +.SH SYNOPSIS
3653 +.B pam_console_apply
3654 +[-f <fstab file>] [-c <console.perms file>] [-r] [-t <tty>] [-s] [-d] [<device file> ...]
3655 +.SH DESCRIPTION
3656 +\fBpam_console_apply\fP is a helper executable which sets or resets permissions
3657 +on device nodes.
3658 +.br
3659 +If \fI/var/run/console.lock\fP exists, \fBpam_console_apply\fP will grant
3660 +permissions to the user listed therein. If the lock file does not exist,
3661 +permissions are reset according to defaults set in \fIconsole.perms\fP files,
3662 +normally configured to set permissions on devices so that \fBroot\fP
3663 +owns them.
3664 +
3665 +When initializing its configuration it first parses
3666 +the \fI/etc/security/console.perms\fP file and then it searches for files
3667 +ending with the \fI.perms\fP suffix in the \fI/etc/security/console.perms.d\fP
3668 +directory. These files are parsed in the lexical order in "C" locale.
3669 +Permission rules are appended to a global list, console and device class
3670 +definitions override previous definitions of the same class.
3671 +.SH ARGUMENTS
3672 +.IP -c
3673 +Load other console.perms file than the default one.
3674 +.IP -f
3675 +Load other fstab file than the default one (\fI/etc/fstab\fP).
3676 +.IP -r
3677 +Signals \fBpam_console_apply\fP to reset permissions. The default is to set
3678 +permissions so that the user listed in \fI/var/run/console.lock\fP has access
3679 +to the devices, and to reset permissions if no such file exists.
3680 +.IP -t
3681 +Use <tty> to match console class in console.perms file. The default is tty0.
3682 +.IP -s
3683 +Write error messages to the system log instead of stderr.
3684 +.IP -d
3685 +Log/display messages useful for debugging.
3686 +.PP
3687 +The optional <device file> arguments constrain what files should be affected
3688 +by \fBpam_console_apply\fP. If they aren't specified permissions are
3689 +changed on all files specified in the \fIconsole.perms\fP file.
3690 +.SH FILES
3691 +\fI/var/run/console.lock\fP
3692 +.br
3693 +\fI/etc/security/console.perms\fP
3694 +.br
3695 +\fI/etc/security/console.perms.d/50-default.perms\fP
3696 +.SH "SEE ALSO"
3697 +.BR pam_console(8)
3698 +.br
3699 +.BR console.perms(5)
3700 +.br
3701 +.SH BUGS
3702 +Let's hope not, but if you find any, please report them via the "Bug Track"
3703 +link at http://bugzilla.redhat.com/bugzilla/
3704 +.SH AUTHORS
3705 +Nalin Dahyabhai <nalin@redhat.com>, using code shamelessly stolen from parts of
3706 +pam_console.
3707 +.br
3708 +Support of console.perms.d and other improvements by
3709 +Tomas Mraz <tmraz@redhat.com>.
3710 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/pam_console_apply.c Linux-PAM-1.1.3/modules/pam_console/pam_console_apply.c
3711 --- Linux-PAM-1.1.3.orig/modules/pam_console/pam_console_apply.c 1969-12-31 19:00:00.000000000 -0500
3712 +++ Linux-PAM-1.1.3/modules/pam_console/pam_console_apply.c 2011-01-26 22:14:52.062657563 -0500
3713 @@ -0,0 +1,175 @@
3714 +/*
3715 + * Read in the file, and grant ownerships to whoever has the lock.
3716 + */
3717 +
3718 +#include "config.h"
3719 +#include <errno.h>
3720 +#include <pwd.h>
3721 +#include <stdlib.h>
3722 +#include <string.h>
3723 +#include <syslog.h>
3724 +#include <sys/types.h>
3725 +#include <sys/stat.h>
3726 +#include <sys/param.h>
3727 +#include <fcntl.h>
3728 +#include <unistd.h>
3729 +#include <stdio.h>
3730 +#include <stdarg.h>
3731 +#include <glob.h>
3732 +#include <locale.h>
3733 +#define STATIC static
3734 +#include "configfile.h"
3735 +#include "chmod.h"
3736 +#include "pam_console.h"
3737 +
3738 +#include <security/_pam_macros.h>
3739 +
3740 +#define CAST_ME_HARDER (const void**)
3741 +#define DEFAULT_PERMSFILE "/etc/security/console.perms"
3742 +#define PERMS_GLOB "/etc/security/console.perms.d/*.perms"
3743 +
3744 +static const char consolelock[] = LOCKDIR "/" LOCKFILE;
3745 +static char consoleperms[PATH_MAX];
3746 +static char tty[PATH_MAX] = "tty0";
3747 +static int debug = 0;
3748 +static int syslogging = 0;
3749 +
3750 +void
3751 +_pam_log(pam_handle_t *pamh, int err, int debug_p, const char *format, ...)
3752 +{
3753 + va_list args;
3754 + if (debug_p && !debug) return;
3755 + va_start(args, format);
3756 + if (syslogging) {
3757 + openlog("pam_console_apply", LOG_CONS|LOG_PID, LOG_AUTHPRIV);
3758 + vsyslog(err, format, args);
3759 + closelog();
3760 + }
3761 + else {
3762 + vfprintf(stderr, format, args);
3763 + fprintf(stderr, "\n");
3764 + }
3765 + va_end(args);
3766 +}
3767 +
3768 +static int
3769 +pf_glob_errorfn(const char *epath, int eerrno)
3770 +{
3771 + return 0;
3772 +}
3773 +
3774 +static void
3775 +parse_files(void)
3776 +{
3777 + int rc;
3778 + glob_t globbuf;
3779 + int i;
3780 + const char *oldlocale;
3781 +
3782 + /* first we parse the console.perms file */
3783 + parse_file(DEFAULT_PERMSFILE);
3784 +
3785 + /* set the LC_COLLATE so the sorting order doesn't depend
3786 + on system locale */
3787 + oldlocale = setlocale(LC_COLLATE, "C");
3788 +
3789 + rc = glob(PERMS_GLOB, GLOB_NOCHECK, pf_glob_errorfn, &globbuf);
3790 + setlocale(LC_COLLATE, oldlocale);
3791 + if (rc == GLOB_NOSPACE) {
3792 + return;
3793 + }
3794 +
3795 + for (i = 0; globbuf.gl_pathv[i] != NULL; i++) {
3796 + parse_file(globbuf.gl_pathv[i]);
3797 + }
3798 + globfree(&globbuf);
3799 +}
3800 +
3801 +int
3802 +main(int argc, char **argv)
3803 +{
3804 + int fd;
3805 + int i, c;
3806 + struct stat st;
3807 + char *consoleuser = NULL;
3808 + enum {Set, Reset} sense = Set;
3809 + GSList *files = NULL;
3810 +
3811 + while((c = getopt(argc, argv, "c:f:t:rsd")) != -1) {
3812 + switch(c) {
3813 + case 'c': if (strlen(optarg) >= sizeof(consoleperms)) {
3814 + fprintf(stderr, "Console.perms filename too long\n");
3815 + exit(1);
3816 + }
3817 + strncpy(consoleperms, optarg, sizeof(consoleperms) - 1);
3818 + consoleperms[sizeof(consoleperms) - 1] = '\0';
3819 + break;
3820 + case 'f': chmod_set_fstab(optarg);
3821 + break;
3822 + case 't': if (strlen(optarg) >= sizeof(tty)) {
3823 + fprintf(stderr, "TTY name too long\n");
3824 + exit(1);
3825 + }
3826 + strncpy(tty, optarg, sizeof(tty) - 1);
3827 + tty[sizeof(tty) - 1] = '\0';
3828 + break;
3829 + case 'r':
3830 + sense = Reset;
3831 + break;
3832 + case 's':
3833 + syslogging = TRUE;
3834 + break;
3835 + case 'd':
3836 + debug = TRUE;
3837 + break;
3838 + default:
3839 + fprintf(stderr, "usage: %s [-f /etc/fstab] "
3840 + "[-c %s] [-t tty] [-r] [-s] [-d] [<device file> ...]\n", argv[0],
3841 + consoleperms);
3842 + exit(1);
3843 + }
3844 + }
3845 +
3846 + for (i = argc-1; i >= optind; i--) {
3847 + files = g_slist_prepend(files, argv[i]);
3848 + }
3849 +
3850 + if (*consoleperms == '\0')
3851 + parse_files();
3852 + else
3853 + parse_file(consoleperms);
3854 +
3855 + fd = open(consolelock, O_RDONLY);
3856 + if (fd != -1) {
3857 + if (fstat (fd, &st)) {
3858 + _pam_log(NULL, LOG_ERR, FALSE,
3859 + "\"impossible\" fstat error on %s", consolelock);
3860 + close(fd);
3861 + goto return_error;
3862 + }
3863 + if (st.st_size) {
3864 + consoleuser = _do_malloc(st.st_size+1);
3865 + memset(consoleuser, '\0', st.st_size);
3866 + if ((i = read (fd, consoleuser, st.st_size)) == -1) {
3867 + _pam_log(NULL, LOG_ERR, FALSE,
3868 + "\"impossible\" read error on %s",
3869 + consolelock);
3870 + goto return_error;
3871 + }
3872 + consoleuser[i] = '\0';
3873 + }
3874 + close(fd);
3875 + } else {
3876 + sense = Reset;
3877 + }
3878 + if((sense == Set) && (consoleuser != NULL)) {
3879 + set_permissions(tty, consoleuser, files);
3880 + }
3881 + if(sense == Reset) {
3882 + reset_permissions(tty, files);
3883 + }
3884 + return 0;
3885 +
3886 +return_error:
3887 + return 1;
3888 +}
3889 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/regerr.c Linux-PAM-1.1.3/modules/pam_console/regerr.c
3890 --- Linux-PAM-1.1.3.orig/modules/pam_console/regerr.c 1969-12-31 19:00:00.000000000 -0500
3891 +++ Linux-PAM-1.1.3/modules/pam_console/regerr.c 2011-01-26 22:14:52.062657563 -0500
3892 @@ -0,0 +1,32 @@
3893 +/* Copyright 1999 Red Hat Software, Inc.
3894 + * This software may be used under the terms of the GNU General Public
3895 + * License, available in the file COPYING accompanying this file
3896 + */
3897 +#include "config.h"
3898 +#include <stdio.h>
3899 +#include <alloca.h>
3900 +#include <sys/types.h>
3901 +#include <syslog.h>
3902 +#include <security/pam_ext.h>
3903 +#include "pam_console.h"
3904 +
3905 +#ifndef STATIC
3906 +#define STATIC
3907 +#endif
3908 +
3909 +STATIC void
3910 +do_regerror(int errcode, const regex_t *preg) {
3911 + char *errbuf;
3912 + size_t errbuf_size;
3913 +
3914 + errbuf_size = regerror(errcode, preg, NULL, 0); /* missing ; */
3915 + errbuf = alloca(errbuf_size);
3916 + if(!errbuf) {
3917 + perror("alloca");
3918 + return;
3919 + }
3920 +
3921 + regerror(errcode, preg, errbuf, errbuf_size);
3922 + pam_syslog(NULL, LOG_ERR,
3923 + "regular expression error %s", errbuf);
3924 +}
3925 diff -Naur Linux-PAM-1.1.3.orig/modules/pam_console/sed-static Linux-PAM-1.1.3/modules/pam_console/sed-static
3926 --- Linux-PAM-1.1.3.orig/modules/pam_console/sed-static 1969-12-31 19:00:00.000000000 -0500
3927 +++ Linux-PAM-1.1.3/modules/pam_console/sed-static 2011-01-26 22:14:52.062657563 -0500
3928 @@ -0,0 +1,19 @@
3929 +#!/bin/sh
3930 +
3931 +[ -n "$1" ] || { echo $0: 'sed what file?' 1>&2 ; exit 1 ; }
3932 +
3933 +sed '
3934 +/^YY_BUFFER_STATE yy_create_buffer/s/^/STATIC /
3935 +/^void yy_delete_buffer/s/^/STATIC /
3936 +/^void yy_flush_buffer/s/^/STATIC /
3937 +/^void yy_init_buffer/s/^/STATIC /
3938 +/^void yy_load_buffer_state/s/^/STATIC /
3939 +/^void YY_BUFFER_STATE yy_scan_buffer/s/^/STATIC /
3940 +/^YY_BUFFER_STATE yy_scan_bytes/s/^/STATIC /
3941 +/^YY_BUFFER_STATE yy_scan_buffer/s/^/STATIC /
3942 +/^YY_BUFFER_STATE yy_scan_string/s/^/STATIC /
3943 +/^void yy_switch_to_buffer/s/^/STATIC /
3944 +/define YY_DECL int yylex/s/YY_DECL /YY_DECL STATIC /
3945 +/^int yyparse/s/^/STATIC /
3946 +/^void yyrestart/s/^/STATIC /
3947 +' < $1 > sedtmp.$$ && mv sedtmp.$$ $1