Contents of /trunk/pam/patches/pam-1.1.4-pam-console.patch
Parent Directory | Revision Log
Revision 1461 -
(show annotations)
(download)
Tue Aug 2 09:12:06 2011 UTC (13 years, 1 month ago) by niro
File size: 136951 byte(s)
Tue Aug 2 09:12:06 2011 UTC (13 years, 1 month 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 |