summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyutils-1.5.6/.gitignore10
-rw-r--r--keyutils-1.5.6/LICENCE.GPL339
-rw-r--r--keyutils-1.5.6/LICENCE.LGPL504
-rw-r--r--keyutils-1.5.6/Makefile281
-rw-r--r--keyutils-1.5.6/README15
-rw-r--r--keyutils-1.5.6/key.dns_resolver.830
-rw-r--r--keyutils-1.5.6/key.dns_resolver.c752
-rw-r--r--keyutils-1.5.6/keyctl.1729
-rw-r--r--keyutils-1.5.6/keyctl.398
-rw-r--r--keyutils-1.5.6/keyctl.c1762
-rw-r--r--keyutils-1.5.6/keyctl_chown.388
-rw-r--r--keyutils-1.5.6/keyctl_clear.373
-rw-r--r--keyutils-1.5.6/keyctl_describe.3110
-rw-r--r--keyutils-1.5.6/keyctl_get_keyring_ID.396
-rw-r--r--keyutils-1.5.6/keyctl_get_security.3100
-rw-r--r--keyutils-1.5.6/keyctl_instantiate.3192
-rw-r--r--keyutils-1.5.6/keyctl_invalidate.376
-rw-r--r--keyutils-1.5.6/keyctl_join_session_keyring.382
-rw-r--r--keyutils-1.5.6/keyctl_link.3108
-rw-r--r--keyutils-1.5.6/keyctl_read.3109
-rw-r--r--keyutils-1.5.6/keyctl_revoke.373
-rw-r--r--keyutils-1.5.6/keyctl_search.3138
-rw-r--r--keyutils-1.5.6/keyctl_session_to_parent.375
-rw-r--r--keyutils-1.5.6/keyctl_set_reqkey_keyring.398
-rw-r--r--keyutils-1.5.6/keyctl_set_timeout.381
-rw-r--r--keyutils-1.5.6/keyctl_setperm.3130
-rw-r--r--keyutils-1.5.6/keyctl_update.396
-rw-r--r--keyutils-1.5.6/keyutils.c616
-rw-r--r--keyutils-1.5.6/keyutils.h166
-rw-r--r--keyutils-1.5.6/keyutils.spec242
-rw-r--r--keyutils-1.5.6/recursive_key_scan.387
-rwxr-xr-xkeyutils-1.5.6/request-key-debug.sh33
-rw-r--r--keyutils-1.5.6/request-key.834
-rw-r--r--keyutils-1.5.6/request-key.c870
-rw-r--r--keyutils-1.5.6/request-key.conf41
-rw-r--r--keyutils-1.5.6/request-key.conf.5141
-rw-r--r--keyutils-1.5.6/tests/Makefile75
-rw-r--r--keyutils-1.5.6/tests/PURPOSE82
-rw-r--r--keyutils-1.5.6/tests/keyctl/add/bad-args/runtest.sh68
-rw-r--r--keyutils-1.5.6/tests/keyctl/add/noargs/runtest.sh35
-rw-r--r--keyutils-1.5.6/tests/keyctl/add/useradd/runtest.sh53
-rw-r--r--keyutils-1.5.6/tests/keyctl/clear/bad-args/runtest.sh39
-rw-r--r--keyutils-1.5.6/tests/keyctl/clear/noargs/runtest.sh23
-rw-r--r--keyutils-1.5.6/tests/keyctl/clear/valid/runtest.sh96
-rw-r--r--keyutils-1.5.6/tests/keyctl/describing/bad-args/runtest.sh38
-rw-r--r--keyutils-1.5.6/tests/keyctl/describing/noargs/runtest.sh25
-rw-r--r--keyutils-1.5.6/tests/keyctl/describing/valid/runtest.sh71
-rw-r--r--keyutils-1.5.6/tests/keyctl/instantiating/bad-args/runtest.sh55
-rw-r--r--keyutils-1.5.6/tests/keyctl/instantiating/noargs/runtest.sh36
-rw-r--r--keyutils-1.5.6/tests/keyctl/link/bad-args/runtest.sh47
-rw-r--r--keyutils-1.5.6/tests/keyctl/link/noargs/runtest.sh27
-rw-r--r--keyutils-1.5.6/tests/keyctl/link/recursion/runtest.sh183
-rw-r--r--keyutils-1.5.6/tests/keyctl/link/valid/runtest.sh139
-rw-r--r--keyutils-1.5.6/tests/keyctl/listing/bad-args/runtest.sh38
-rw-r--r--keyutils-1.5.6/tests/keyctl/listing/noargs/runtest.sh23
-rw-r--r--keyutils-1.5.6/tests/keyctl/listing/valid/runtest.sh109
-rw-r--r--keyutils-1.5.6/tests/keyctl/newring/bad-args/runtest.sh42
-rw-r--r--keyutils-1.5.6/tests/keyctl/newring/noargs/runtest.sh27
-rw-r--r--keyutils-1.5.6/tests/keyctl/newring/valid/runtest.sh61
-rw-r--r--keyutils-1.5.6/tests/keyctl/noargs/runtest.sh24
-rw-r--r--keyutils-1.5.6/tests/keyctl/padd/bad-args/runtest.sh67
-rw-r--r--keyutils-1.5.6/tests/keyctl/padd/noargs/runtest.sh31
-rw-r--r--keyutils-1.5.6/tests/keyctl/padd/useradd/runtest.sh48
-rw-r--r--keyutils-1.5.6/tests/keyctl/permitting/bad-args/runtest.sh49
-rw-r--r--keyutils-1.5.6/tests/keyctl/permitting/noargs/runtest.sh30
-rw-r--r--keyutils-1.5.6/tests/keyctl/permitting/valid/runtest.sh99
-rw-r--r--keyutils-1.5.6/tests/keyctl/pupdate/bad-args/runtest.sh39
-rw-r--r--keyutils-1.5.6/tests/keyctl/pupdate/noargs/runtest.sh23
-rw-r--r--keyutils-1.5.6/tests/keyctl/pupdate/userupdate/runtest.sh38
-rw-r--r--keyutils-1.5.6/tests/keyctl/reading/bad-args/runtest.sh42
-rw-r--r--keyutils-1.5.6/tests/keyctl/reading/noargs/runtest.sh25
-rw-r--r--keyutils-1.5.6/tests/keyctl/reading/valid/runtest.sh96
-rw-r--r--keyutils-1.5.6/tests/keyctl/requesting/bad-args/runtest.sh113
-rw-r--r--keyutils-1.5.6/tests/keyctl/requesting/noargs/runtest.sh35
-rw-r--r--keyutils-1.5.6/tests/keyctl/requesting/piped/runtest.sh98
-rw-r--r--keyutils-1.5.6/tests/keyctl/requesting/valid/runtest.sh98
-rw-r--r--keyutils-1.5.6/tests/keyctl/revoke/bad-args/runtest.sh25
-rw-r--r--keyutils-1.5.6/tests/keyctl/revoke/noargs/runtest.sh22
-rw-r--r--keyutils-1.5.6/tests/keyctl/revoke/valid/runtest.sh75
-rw-r--r--keyutils-1.5.6/tests/keyctl/search/bad-args/runtest.sh80
-rw-r--r--keyutils-1.5.6/tests/keyctl/search/noargs/runtest.sh31
-rw-r--r--keyutils-1.5.6/tests/keyctl/search/valid/runtest.sh173
-rw-r--r--keyutils-1.5.6/tests/keyctl/session/bad-args/runtest.sh25
-rw-r--r--keyutils-1.5.6/tests/keyctl/session/valid/runtest.sh42
-rw-r--r--keyutils-1.5.6/tests/keyctl/show/noargs/runtest.sh51
-rw-r--r--keyutils-1.5.6/tests/keyctl/timeout/bad-args/runtest.sh34
-rw-r--r--keyutils-1.5.6/tests/keyctl/timeout/noargs/runtest.sh26
-rw-r--r--keyutils-1.5.6/tests/keyctl/timeout/valid/runtest.sh118
-rw-r--r--keyutils-1.5.6/tests/keyctl/unlink/all/runtest.sh103
-rw-r--r--keyutils-1.5.6/tests/keyctl/unlink/bad-args/runtest.sh47
-rw-r--r--keyutils-1.5.6/tests/keyctl/unlink/noargs/runtest.sh30
-rw-r--r--keyutils-1.5.6/tests/keyctl/unlink/valid/runtest.sh99
-rw-r--r--keyutils-1.5.6/tests/keyctl/update/bad-args/runtest.sh39
-rw-r--r--keyutils-1.5.6/tests/keyctl/update/noargs/runtest.sh27
-rw-r--r--keyutils-1.5.6/tests/keyctl/update/userupdate/runtest.sh38
-rw-r--r--keyutils-1.5.6/tests/prepare.inc.sh43
-rw-r--r--keyutils-1.5.6/tests/runtest.sh25
-rw-r--r--keyutils-1.5.6/tests/toolbox.inc.sh1101
-rw-r--r--keyutils-1.5.6/version.lds54
-rw-r--r--pax_global_header1
100 files changed, 13131 insertions, 0 deletions
diff --git a/keyutils-1.5.6/.gitignore b/keyutils-1.5.6/.gitignore
new file mode 100644
index 0000000..1caa791
--- /dev/null
+++ b/keyutils-1.5.6/.gitignore
@@ -0,0 +1,10 @@
+*~
+*.o
+*.os
+*.so
+*.a
+*.so.*
+keyctl
+request-key
+key.dns_resolver
+rpmbuild
diff --git a/keyutils-1.5.6/LICENCE.GPL b/keyutils-1.5.6/LICENCE.GPL
new file mode 100644
index 0000000..4505352
--- /dev/null
+++ b/keyutils-1.5.6/LICENCE.GPL
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. <http://fsf.org/>
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/keyutils-1.5.6/LICENCE.LGPL b/keyutils-1.5.6/LICENCE.LGPL
new file mode 100644
index 0000000..519334a
--- /dev/null
+++ b/keyutils-1.5.6/LICENCE.LGPL
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc. <http://fsf.org/>
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/keyutils-1.5.6/Makefile b/keyutils-1.5.6/Makefile
new file mode 100644
index 0000000..2adcfba
--- /dev/null
+++ b/keyutils-1.5.6/Makefile
@@ -0,0 +1,281 @@
+CPPFLAGS := -I.
+CFLAGS := -g -Wall -Werror
+INSTALL := install
+DESTDIR :=
+SPECFILE := keyutils.spec
+NO_GLIBC_KEYERR := 0
+NO_ARLIB := 0
+ETCDIR := /etc
+BINDIR := /bin
+SBINDIR := /sbin
+SHAREDIR := /usr/share/keyutils
+MAN1 := /usr/share/man/man1
+MAN3 := /usr/share/man/man3
+MAN5 := /usr/share/man/man5
+MAN8 := /usr/share/man/man8
+INCLUDEDIR := /usr/include
+LNS := ln -sf
+
+###############################################################################
+#
+# Determine the current package version from the specfile
+#
+###############################################################################
+vermajor := $(shell grep "%define vermajor" $(SPECFILE))
+verminor := $(shell grep "%define verminor" $(SPECFILE))
+MAJOR := $(word 3,$(vermajor))
+MINOR := $(word 3,$(verminor))
+VERSION := $(MAJOR).$(MINOR)
+
+TARBALL := keyutils-$(VERSION).tar
+ZTARBALL := $(TARBALL).bz2
+
+###############################################################################
+#
+# Determine the current library version from the version script
+#
+###############################################################################
+libversion := $(filter KEYUTILS_%,$(shell grep ^KEYUTILS_ version.lds))
+libversion := $(lastword $(libversion))
+libversion := $(lastword $(libversion))
+APIVERSION := $(subst KEYUTILS_,,$(libversion))
+vernumbers := $(subst ., ,$(APIVERSION))
+APIMAJOR := $(firstword $(vernumbers))
+
+ARLIB := libkeyutils.a
+DEVELLIB := libkeyutils.so
+SONAME := libkeyutils.so.$(APIMAJOR)
+LIBNAME := libkeyutils.so.$(APIVERSION)
+
+###############################################################################
+#
+# Guess at the appropriate lib directory and word size
+#
+###############################################################################
+LIBDIR := $(shell ldd /usr/bin/make | grep '\(/libc\)' | sed -e 's!.*\(/.*\)/libc[.].*!\1!')
+USRLIBDIR := $(patsubst /lib/%,/usr/lib/%,$(LIBDIR))
+BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit
+
+LNS := ln -sf
+
+ifeq ($(BUILDFOR),32-bit)
+CFLAGS += -m32
+LIBDIR := /lib
+USRLIBDIR := /usr/lib
+else
+ifeq ($(BUILDFOR),64-bit)
+CFLAGS += -m64
+LIBDIR := /lib64
+USRLIBDIR := /usr/lib64
+endif
+endif
+
+###############################################################################
+#
+# This is necessary if glibc doesn't know about the key management error codes
+#
+###############################################################################
+ifeq ($(NO_GLIBC_KEYERR),1)
+CFLAGS += -DNO_GLIBC_KEYERR
+LIBLIBS := -ldl -lc
+else
+LIBLIBS :=
+endif
+
+###############################################################################
+#
+# Normal build rule
+#
+###############################################################################
+all: $(DEVELLIB) keyctl request-key key.dns_resolver
+
+###############################################################################
+#
+# Build the libraries
+#
+###############################################################################
+#RPATH = -Wl,-rpath,$(LIBDIR)
+
+ifeq ($(NO_ARLIB),0)
+all: $(ARLIB)
+$(ARLIB): keyutils.o
+ $(AR) rcs $@ $<
+endif
+
+VCPPFLAGS := -DPKGBUILD="\"$(shell date -u +%F)\""
+VCPPFLAGS += -DPKGVERSION="\"keyutils-$(VERSION)\""
+VCPPFLAGS += -DAPIVERSION="\"libkeyutils-$(APIVERSION)\""
+
+keyutils.o: keyutils.c keyutils.h Makefile
+ $(CC) $(CPPFLAGS) $(VCPPFLAGS) $(CFLAGS) -UNO_GLIBC_KEYERR -o $@ -c $<
+
+
+$(DEVELLIB): $(SONAME)
+ ln -sf $< $@
+
+$(SONAME): $(LIBNAME)
+ ln -sf $< $@
+
+LIBVERS := -shared -Wl,-soname,$(SONAME) -Wl,--version-script,version.lds
+
+$(LIBNAME): keyutils.os version.lds Makefile
+ $(CC) $(CFLAGS) -fPIC $(LDFLAGS) $(LIBVERS) -o $@ keyutils.os $(LIBLIBS)
+
+keyutils.os: keyutils.c keyutils.h Makefile
+ $(CC) $(CPPFLAGS) $(VCPPFLAGS) $(CFLAGS) -fPIC -o $@ -c $<
+
+###############################################################################
+#
+# Build the programs
+#
+###############################################################################
+%.o: %.c keyutils.h Makefile
+ $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
+
+keyctl: keyctl.o $(DEVELLIB)
+ $(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ $< -lkeyutils
+
+request-key: request-key.o $(DEVELLIB)
+ $(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ $< -lkeyutils
+
+key.dns_resolver: key.dns_resolver.o $(DEVELLIB)
+ $(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ $< -lkeyutils -lresolv
+
+###############################################################################
+#
+# Install everything
+#
+###############################################################################
+install: all
+ifeq ($(NO_ARLIB),0)
+ $(INSTALL) -D -m 0644 $(ARLIB) $(DESTDIR)$(USRLIBDIR)/$(ARLIB)
+endif
+ $(INSTALL) -D $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
+ $(LNS) $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME)
+ mkdir -p $(DESTDIR)$(USRLIBDIR)
+ $(LNS) $(LIBDIR)/$(SONAME) $(DESTDIR)$(USRLIBDIR)/$(DEVELLIB)
+ $(INSTALL) -D keyctl $(DESTDIR)$(BINDIR)/keyctl
+ $(INSTALL) -D request-key $(DESTDIR)$(SBINDIR)/request-key
+ $(INSTALL) -D request-key-debug.sh $(DESTDIR)$(SHAREDIR)/request-key-debug.sh
+ $(INSTALL) -D key.dns_resolver $(DESTDIR)$(SBINDIR)/key.dns_resolver
+ $(INSTALL) -D -m 0644 request-key.conf $(DESTDIR)$(ETCDIR)/request-key.conf
+ mkdir -p $(DESTDIR)$(ETCDIR)/request-key.d
+ $(INSTALL) -D -m 0644 keyctl.1 $(DESTDIR)$(MAN1)/keyctl.1
+ $(INSTALL) -D -m 0644 keyctl.3 $(DESTDIR)$(MAN3)/keyctl.3
+ $(INSTALL) -D -m 0644 keyctl_chown.3 $(DESTDIR)$(MAN3)/keyctl_chown.3
+ $(INSTALL) -D -m 0644 keyctl_clear.3 $(DESTDIR)$(MAN3)/keyctl_clear.3
+ $(INSTALL) -D -m 0644 keyctl_describe.3 $(DESTDIR)$(MAN3)/keyctl_describe.3
+ $(LNS) keyctl_describe.3 $(DESTDIR)$(MAN3)/keyctl_describe_alloc.3
+ $(INSTALL) -D -m 0644 keyctl_get_keyring_ID.3 $(DESTDIR)$(MAN3)/keyctl_get_keyring_ID.3
+ $(INSTALL) -D -m 0644 keyctl_get_security.3 $(DESTDIR)$(MAN3)/keyctl_get_security.3
+ $(LNS) keyctl_get_security.3 $(DESTDIR)$(MAN3)/keyctl_get_security_alloc.3
+ $(INSTALL) -D -m 0644 keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_instantiate.3
+ $(LNS) keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_instantiate_iov.3
+ $(LNS) keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_reject.3
+ $(LNS) keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_negate.3
+ $(LNS) keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_assume_authority.3
+ $(INSTALL) -D -m 0644 keyctl_invalidate.3 $(DESTDIR)$(MAN3)/keyctl_invalidate.3
+ $(INSTALL) -D -m 0644 keyctl_join_session_keyring.3 $(DESTDIR)$(MAN3)/keyctl_join_session_keyring.3
+ $(INSTALL) -D -m 0644 keyctl_link.3 $(DESTDIR)$(MAN3)/keyctl_link.3
+ $(LNS) keyctl_link.3 $(DESTDIR)$(MAN3)/keyctl_unlink.3
+ $(INSTALL) -D -m 0644 keyctl_read.3 $(DESTDIR)$(MAN3)/keyctl_read.3
+ $(LNS) keyctl_read.3 $(DESTDIR)$(MAN3)/keyctl_read_alloc.3
+ $(INSTALL) -D -m 0644 keyctl_revoke.3 $(DESTDIR)$(MAN3)/keyctl_revoke.3
+ $(INSTALL) -D -m 0644 keyctl_search.3 $(DESTDIR)$(MAN3)/keyctl_search.3
+ $(INSTALL) -D -m 0644 keyctl_session_to_parent.3 $(DESTDIR)$(MAN3)/keyctl_session_to_parent.3
+ $(INSTALL) -D -m 0644 keyctl_setperm.3 $(DESTDIR)$(MAN3)/keyctl_setperm.3
+ $(INSTALL) -D -m 0644 keyctl_set_reqkey_keyring.3 $(DESTDIR)$(MAN3)/keyctl_set_reqkey_keyring.3
+ $(INSTALL) -D -m 0644 keyctl_set_timeout.3 $(DESTDIR)$(MAN3)/keyctl_set_timeout.3
+ $(INSTALL) -D -m 0644 keyctl_update.3 $(DESTDIR)$(MAN3)/keyctl_update.3
+ $(INSTALL) -D -m 0644 recursive_key_scan.3 $(DESTDIR)$(MAN3)/recursive_key_scan.3
+ $(LNS) recursive_key_scan.3 $(DESTDIR)$(MAN3)/recursive_session_key_scan.3
+ $(INSTALL) -D -m 0644 request-key.conf.5 $(DESTDIR)$(MAN5)/request-key.conf.5
+ $(INSTALL) -D -m 0644 request-key.8 $(DESTDIR)$(MAN8)/request-key.8
+ $(INSTALL) -D -m 0644 key.dns_resolver.8 $(DESTDIR)$(MAN8)/key.dns_resolver.8
+ $(INSTALL) -D -m 0644 keyutils.h $(DESTDIR)$(INCLUDEDIR)/keyutils.h
+
+###############################################################################
+#
+# Run tests
+#
+###############################################################################
+test:
+ $(MAKE) -C tests run
+
+###############################################################################
+#
+# Clean up
+#
+###############################################################################
+clean:
+ $(MAKE) -C tests clean
+ $(RM) libkeyutils*
+ $(RM) keyctl request-key key.dns_resolver
+ $(RM) *.o *.os *~
+ $(RM) debugfiles.list debugsources.list
+
+distclean: clean
+ $(RM) -r rpmbuild
+
+###############################################################################
+#
+# Generate a tarball
+#
+###############################################################################
+$(ZTARBALL):
+ git archive --prefix=keyutils-$(VERSION)/ --format tar -o $(TARBALL) HEAD
+ bzip2 -9 $(TARBALL)
+
+tarball: $(ZTARBALL)
+
+###############################################################################
+#
+# Generate an RPM
+#
+###############################################################################
+SRCBALL := rpmbuild/SOURCES/$(TARBALL)
+
+BUILDID := .local
+dist := $(word 2,$(shell grep "%dist" /etc/rpm/macros.dist))
+release := $(word 2,$(shell grep ^Release: $(SPECFILE)))
+release := $(subst %{?dist},$(dist),$(release))
+release := $(subst %{?buildid},$(BUILDID),$(release))
+rpmver := $(VERSION)-$(release)
+SRPM := rpmbuild/SRPMS/keyutils-$(rpmver).src.rpm
+
+RPMBUILDDIRS := \
+ --define "_srcrpmdir $(CURDIR)/rpmbuild/SRPMS" \
+ --define "_rpmdir $(CURDIR)/rpmbuild/RPMS" \
+ --define "_sourcedir $(CURDIR)/rpmbuild/SOURCES" \
+ --define "_specdir $(CURDIR)/rpmbuild/SPECS" \
+ --define "_builddir $(CURDIR)/rpmbuild/BUILD" \
+ --define "_buildrootdir $(CURDIR)/rpmbuild/BUILDROOT"
+
+RPMFLAGS := \
+ --define "buildid $(BUILDID)"
+
+rpm:
+ mkdir -p rpmbuild
+ chmod ug-s rpmbuild
+ mkdir -p rpmbuild/{SPECS,SOURCES,BUILD,BUILDROOT,RPMS,SRPMS}
+ git archive --prefix=keyutils-$(VERSION)/ --format tar -o $(SRCBALL) HEAD
+ bzip2 -9 $(SRCBALL)
+ rpmbuild -ts $(SRCBALL).bz2 --define "_srcrpmdir rpmbuild/SRPMS" $(RPMFLAGS)
+ rpmbuild --rebuild $(SRPM) $(RPMBUILDDIRS) $(RPMFLAGS)
+
+rpmlint: rpm
+ rpmlint $(SRPM) $(CURDIR)/rpmbuild/RPMS/*/keyutils-{,libs-,libs-devel-,debuginfo-}$(rpmver).*.rpm
+
+###############################################################################
+#
+# Build debugging
+#
+###############################################################################
+show_vars:
+ @echo VERSION=$(VERSION)
+ @echo APIVERSION=$(APIVERSION)
+ @echo LIBDIR=$(LIBDIR)
+ @echo USRLIBDIR=$(USRLIBDIR)
+ @echo BUILDFOR=$(BUILDFOR)
+ @echo SONAME=$(SONAME)
+ @echo LIBNAME=$(LIBNAME)
diff --git a/keyutils-1.5.6/README b/keyutils-1.5.6/README
new file mode 100644
index 0000000..5c3d94d
--- /dev/null
+++ b/keyutils-1.5.6/README
@@ -0,0 +1,15 @@
+These tools are used to control the key management system built into the Linux
+kernel.
+
+To build and install the tools and manual pages, run:
+
+ make
+ make install
+
+If your glibc does not contain definitions for the new error codes and system
+calls, then try:
+
+ make NO_GLIBC_KEYERR=1
+
+The tools are licensed under the GPL and the utility library under the LGPL.
+Copies of these are included in this tarball.
diff --git a/keyutils-1.5.6/key.dns_resolver.8 b/keyutils-1.5.6/key.dns_resolver.8
new file mode 100644
index 0000000..8347a0d
--- /dev/null
+++ b/keyutils-1.5.6/key.dns_resolver.8
@@ -0,0 +1,30 @@
+.\"
+.\" Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEY.DNS_RESOLVER 8 "04 Mar 2011" Linux "Linux Key Management Utilities"
+.SH NAME
+key.dns_resolver - Upcall for request-key to handle dns_resolver keys
+.SH SYNOPSIS
+\fB/sbin/key.dns_resolver \fR<key>
+.br
+\fB/sbin/key.dns_resolver \fR-D [-v] [-v] <keydesc> <calloutinfo>
+.SH DESCRIPTION
+This program is invoked by request-key on behalf of the kernel when kernel
+services (such as NFS, CIFS and AFS) want to perform a hostname lookup and the
+kernel does not have the key cached. It is not ordinarily intended to be
+called directly.
+.P
+It can be called in debugging mode to test its functionality by passing a
+\fB-D\fR flag on the command line. For this to work, the key description and
+the callout information must be supplied. Verbosity can be increased by
+supplying one or more \fB-v\fR flags.
+.SH ERRORS
+All errors will be logged to the syslog.
+.SH SEE ALSO
+\fBrequest-key\fR(8), \fBrequest-key.conf\fR(5)
diff --git a/keyutils-1.5.6/key.dns_resolver.c b/keyutils-1.5.6/key.dns_resolver.c
new file mode 100644
index 0000000..249dcf3
--- /dev/null
+++ b/keyutils-1.5.6/key.dns_resolver.c
@@ -0,0 +1,752 @@
+/*
+ * DNS Resolver Module User-space Helper for AFSDB records
+ *
+ * Copyright (C) Wang Lei (wang840925@gmail.com) 2010
+ * Authors: Wang Lei (wang840925@gmail.com)
+ * David Howells (dhowells@redhat.com)
+ *
+ * This is a userspace tool for querying AFSDB RR records in the DNS on behalf
+ * of the kernel, and converting the VL server addresses to IPv4 format so that
+ * they can be used by the kAFS filesystem.
+ *
+ * Compile with:
+ *
+ * cc -o key.dns_resolver key.dns_resolver.c -lresolv -lkeyutils
+ *
+ * As some function like res_init() should use the static liberary, which is a
+ * bug of libresolv, that is the reason for cifs.upcall to reimplement.
+ *
+ * To use this program, you must tell /sbin/request-key how to invoke it. You
+ * need to have the keyutils package installed and something like the following
+ * lines added to your /etc/request-key.conf file:
+ *
+ * #OP TYPE DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ...
+ * ====== ============ =========== ============ ==========================
+ * create dns_resolver afsdb:* * /sbin/key.dns_resolver %k
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#define _GNU_SOURCE
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <syslog.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <keyutils.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+static const char *DNS_PARSE_VERSION = "1.0";
+static const char prog[] = "key.dns_resolver";
+static const char key_type[] = "dns_resolver";
+static const char a_query_type[] = "a";
+static const char aaaa_query_type[] = "aaaa";
+static const char afsdb_query_type[] = "afsdb";
+static key_serial_t key;
+static int verbose;
+static int debug_mode;
+
+
+#define MAX_VLS 15 /* Max Volume Location Servers Per-Cell */
+#define DNS_EXPIRY_PREFIX "expiry_time="
+#define DNS_EXPIRY_TIME_LEN 10 /* 2^32 - 1 = 4294967295 */
+#define AFSDB_MAX_DATA_LEN \
+ ((MAX_VLS * (INET6_ADDRSTRLEN + 1)) + sizeof(DNS_EXPIRY_PREFIX) + \
+ DNS_EXPIRY_TIME_LEN + 1 /* '#'*/ + 1 /* end 0 */)
+
+#define INET_IP4_ONLY 0x1
+#define INET_IP6_ONLY 0x2
+#define INET_ALL 0xFF
+#define ONE_ADDR_ONLY 0x100
+#define LIST_MULTIPLE_ADDRS 0x200
+
+/*
+ * segmental payload
+ */
+#define N_PAYLOAD 256
+struct iovec payload[N_PAYLOAD];
+int payload_index;
+
+/*
+ * Print an error to stderr or the syslog, negate the key being created and
+ * exit
+ */
+static __attribute__((format(printf, 1, 2), noreturn))
+void error(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ if (isatty(2)) {
+ vfprintf(stderr, fmt, va);
+ fputc('\n', stderr);
+ } else {
+ vsyslog(LOG_ERR, fmt, va);
+ }
+ va_end(va);
+
+ /*
+ * on error, negatively instantiate the key ourselves so that we can
+ * make sure the kernel doesn't hang it off of a searchable keyring
+ * and interfere with the next attempt to instantiate the key.
+ */
+ if (!debug_mode)
+ keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);
+
+ exit(1);
+}
+
+#define error(FMT, ...) error("Error: " FMT, ##__VA_ARGS__);
+
+/*
+ * Just print an error to stderr or the syslog
+ */
+static __attribute__((format(printf, 1, 2)))
+void _error(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ if (isatty(2)) {
+ vfprintf(stderr, fmt, va);
+ fputc('\n', stderr);
+ } else {
+ vsyslog(LOG_ERR, fmt, va);
+ }
+ va_end(va);
+}
+
+/*
+ * Print status information
+ */
+static __attribute__((format(printf, 1, 2)))
+void info(const char *fmt, ...)
+{
+ va_list va;
+
+ if (verbose < 1)
+ return;
+
+ va_start(va, fmt);
+ if (isatty(1)) {
+ fputs("I: ", stdout);
+ vfprintf(stdout, fmt, va);
+ fputc('\n', stdout);
+ } else {
+ vsyslog(LOG_INFO, fmt, va);
+ }
+ va_end(va);
+}
+
+/*
+ * Print a nameserver error and exit
+ */
+static const int ns_errno_map[] = {
+ [0] = ECONNREFUSED,
+ [HOST_NOT_FOUND] = ENODATA,
+ [TRY_AGAIN] = EAGAIN,
+ [NO_RECOVERY] = ECONNREFUSED,
+ [NO_DATA] = ENODATA,
+};
+
+static __attribute__((noreturn))
+void nsError(int err, const char *domain)
+{
+ unsigned timeout = 1 * 60;
+ int ret;
+
+ if (isatty(2))
+ fprintf(stderr, "%s: %s.\n", domain, hstrerror(err));
+ else
+ syslog(LOG_INFO, "%s: %s", domain, hstrerror(err));
+
+ if (err >= sizeof(ns_errno_map) / sizeof(ns_errno_map[0]))
+ err = ECONNREFUSED;
+ else
+ err = ns_errno_map[err];
+
+ info("Reject the key with error %d", err);
+
+ if (err == EAGAIN)
+ timeout = 1;
+ else if (err == ECONNREFUSED)
+ timeout = 10;
+
+ if (!debug_mode) {
+ ret = keyctl_reject(key, timeout, err, KEY_REQKEY_DEFL_DEFAULT);
+ if (ret == -1)
+ error("%s: keyctl_reject: %m", __func__);
+ }
+ exit(0);
+}
+
+/*
+ * Print debugging information
+ */
+static __attribute__((format(printf, 1, 2)))
+void debug(const char *fmt, ...)
+{
+ va_list va;
+
+ if (verbose < 2)
+ return;
+
+ va_start(va, fmt);
+ if (isatty(1)) {
+ fputs("D: ", stdout);
+ vfprintf(stdout, fmt, va);
+ fputc('\n', stdout);
+ } else {
+ vsyslog(LOG_DEBUG, fmt, va);
+ }
+ va_end(va);
+}
+
+/*
+ * Append an address to the payload segment list
+ */
+static void append_address_to_payload(char *p, size_t sz)
+{
+ int loop;
+
+ debug("append '%*.*s'", (int)sz, (int)sz, p);
+
+ /* discard duplicates */
+ for (loop = 0; loop < payload_index; loop++)
+ if (payload[loop].iov_len == sz &&
+ memcmp(payload[loop].iov_base, p, sz) == 0)
+ return;
+
+ if (payload_index != 0) {
+ if (payload_index + 2 > N_PAYLOAD - 1)
+ return;
+ payload[payload_index ].iov_base = ",";
+ payload[payload_index++].iov_len = 1;
+ } else {
+ if (payload_index + 1 > N_PAYLOAD - 1)
+ return;
+ }
+
+ payload[payload_index ].iov_base = p;
+ payload[payload_index++].iov_len = sz;
+}
+
+/*
+ * Dump the payload when debugging
+ */
+static void dump_payload(void)
+{
+ size_t plen, n;
+ char *buf, *p;
+ int loop;
+
+ if (debug_mode)
+ verbose = 1;
+ if (verbose < 1)
+ return;
+
+ plen = 0;
+ for (loop = 0; loop < payload_index; loop++) {
+ n = payload[loop].iov_len;
+ debug("seg[%d]: %zu", loop, n);
+ plen += n;
+ }
+ if (plen == 0) {
+ info("The key instantiation data is empty");
+ return;
+ }
+
+ debug("total: %zu", plen);
+ buf = malloc(plen + 1);
+ if (!buf)
+ return;
+
+ p = buf;
+ for (loop = 0; loop < payload_index; loop++) {
+ n = payload[loop].iov_len;
+ memcpy(p, payload[loop].iov_base, n);
+ p += n;
+ }
+
+ info("The key instantiation data is '%s'", buf);
+ free(buf);
+}
+
+/*
+ * Perform address resolution on a hostname and add the resulting address as a
+ * string to the list of payload segments.
+ */
+static int
+dns_resolver(const char *server_name, unsigned mask)
+{
+ struct addrinfo hints, *addr, *ai;
+ size_t slen;
+ char buf[INET6_ADDRSTRLEN + 1], *seg;
+ int ret, len;
+ void *sa;
+
+ debug("Resolve '%s' with %x", server_name, mask);
+
+ memset(&hints, 0, sizeof(hints));
+ switch (mask & INET_ALL) {
+ case INET_IP4_ONLY: hints.ai_family = AF_INET; debug("IPv4"); break;
+ case INET_IP6_ONLY: hints.ai_family = AF_INET6; debug("IPv6"); break;
+ default: break;
+ }
+
+ /* resolve name to ip */
+ ret = getaddrinfo(server_name, NULL, &hints, &addr);
+ if (ret) {
+ info("unable to resolve hostname: %s [%s]",
+ server_name, gai_strerror(ret));
+ return -1;
+ }
+
+ debug("getaddrinfo = %d", ret);
+
+ for (ai = addr; ai; ai = ai->ai_next) {
+ debug("RR: %x,%x,%x,%x,%x,%s",
+ ai->ai_flags, ai->ai_family,
+ ai->ai_socktype, ai->ai_protocol,
+ ai->ai_addrlen, ai->ai_canonname);
+
+ /* convert address to string */
+ switch (ai->ai_family) {
+ case AF_INET:
+ if (!(mask & INET_IP4_ONLY))
+ continue;
+ sa = &(((struct sockaddr_in *)ai->ai_addr)->sin_addr);
+ len = INET_ADDRSTRLEN;
+ break;
+ case AF_INET6:
+ if (!(mask & INET_IP6_ONLY))
+ continue;
+ sa = &(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr);
+ len = INET6_ADDRSTRLEN;
+ break;
+ default:
+ debug("Address of unknown family %u", addr->ai_family);
+ continue;
+ }
+
+ if (!inet_ntop(ai->ai_family, sa, buf, len))
+ error("%s: inet_ntop: %m", __func__);
+
+ slen = strlen(buf);
+ seg = malloc(slen);
+ if (!seg)
+ error("%s: inet_ntop: %m", __func__);
+ memcpy(seg, buf, slen);
+ append_address_to_payload(seg, slen);
+ if (mask & ONE_ADDR_ONLY)
+ break;
+ }
+
+ freeaddrinfo(addr);
+ return 0;
+}
+
+/*
+ *
+ */
+static void afsdb_hosts_to_addrs(char *vllist[],
+ int *vlsnum,
+ ns_msg handle,
+ ns_sect section,
+ unsigned mask,
+ unsigned long *_ttl)
+{
+ int rrnum;
+ ns_rr rr;
+ int subtype, i, ret;
+ unsigned int ttl = UINT_MAX, rr_ttl;
+
+ debug("AFSDB RR count is %d", ns_msg_count(handle, section));
+
+ /* Look at all the resource records in this section. */
+ for (rrnum = 0; rrnum < ns_msg_count(handle, section); rrnum++) {
+ /* Expand the resource record number rrnum into rr. */
+ if (ns_parserr(&handle, section, rrnum, &rr)) {
+ _error("ns_parserr failed : %m");
+ continue;
+ }
+
+ /* We're only interested in AFSDB records */
+ if (ns_rr_type(rr) == ns_t_afsdb) {
+ vllist[*vlsnum] = malloc(MAXDNAME);
+ if (!vllist[*vlsnum])
+ error("Out of memory");
+
+ subtype = ns_get16(ns_rr_rdata(rr));
+
+ /* Expand the name server's domain name */
+ if (ns_name_uncompress(ns_msg_base(handle),
+ ns_msg_end(handle),
+ ns_rr_rdata(rr) + 2,
+ vllist[*vlsnum],
+ MAXDNAME) < 0)
+ error("ns_name_uncompress failed");
+
+ rr_ttl = ns_rr_ttl(rr);
+ if (ttl > rr_ttl)
+ ttl = rr_ttl;
+
+ /* Check the domain name we've just unpacked and add it to
+ * the list of VL servers if it is not a duplicate.
+ * If it is a duplicate, just ignore it.
+ */
+ for (i = 0; i < *vlsnum; i++)
+ if (strcasecmp(vllist[i], vllist[*vlsnum]) == 0)
+ goto next_one;
+
+ /* Turn the hostname into IP addresses */
+ ret = dns_resolver(vllist[*vlsnum], mask);
+ if (ret) {
+ debug("AFSDB RR can't resolve."
+ "subtype:%d, server name:%s, netmask:%u",
+ subtype, vllist[*vlsnum], mask);
+ goto next_one;
+ }
+
+ info("AFSDB RR subtype:%d, server name:%s, ip:%*.*s, ttl:%u",
+ subtype, vllist[*vlsnum],
+ (int)payload[payload_index - 1].iov_len,
+ (int)payload[payload_index - 1].iov_len,
+ (char *)payload[payload_index - 1].iov_base,
+ ttl);
+
+ /* prepare for the next record */
+ *vlsnum += 1;
+ continue;
+
+ next_one:
+ free(vllist[*vlsnum]);
+ }
+ }
+
+ *_ttl = ttl;
+ info("ttl: %u", ttl);
+}
+
+/*
+ * Look up an AFSDB record to get the VL server addresses.
+ *
+ * The callout_info is parsed for request options. For instance, "ipv4" to
+ * request only IPv4 addresses and "ipv6" to request only IPv6 addresses.
+ */
+static __attribute__((noreturn))
+int dns_query_afsdb(key_serial_t key, const char *cell, char *options)
+{
+ int ret;
+ char *vllist[MAX_VLS]; /* list of name servers */
+ int vlsnum = 0; /* number of name servers in list */
+ unsigned mask = INET_ALL;
+ int response_len; /* buffer length */
+ ns_msg handle; /* handle for response message */
+ unsigned long ttl = ULONG_MAX;
+ union {
+ HEADER hdr;
+ u_char buf[NS_PACKETSZ];
+ } response; /* response buffers */
+
+ debug("Get AFSDB RR for cell name:'%s', options:'%s'", cell, options);
+
+ /* query the dns for an AFSDB resource record */
+ response_len = res_query(cell,
+ ns_c_in,
+ ns_t_afsdb,
+ response.buf,
+ sizeof(response));
+
+ if (response_len < 0)
+ /* negative result */
+ nsError(h_errno, cell);
+
+ if (ns_initparse(response.buf, response_len, &handle) < 0)
+ error("ns_initparse: %m");
+
+ /* Is the IP address family limited? */
+ if (strcmp(options, "ipv4") == 0)
+ mask = INET_IP4_ONLY;
+ else if (strcmp(options, "ipv6") == 0)
+ mask = INET_IP6_ONLY;
+
+ /* look up the hostnames we've obtained to get the actual addresses */
+ afsdb_hosts_to_addrs(vllist, &vlsnum, handle, ns_s_an, mask, &ttl);
+
+ info("DNS query AFSDB RR results:%u ttl:%lu", payload_index, ttl);
+
+ /* set the key's expiry time from the minimum TTL encountered */
+ if (!debug_mode) {
+ ret = keyctl_set_timeout(key, ttl);
+ if (ret == -1)
+ error("%s: keyctl_set_timeout: %m", __func__);
+ }
+
+ /* handle a lack of results */
+ if (payload_index == 0)
+ nsError(NO_DATA, cell);
+
+ /* must include a NUL char at the end of the payload */
+ payload[payload_index].iov_base = "";
+ payload[payload_index++].iov_len = 1;
+ dump_payload();
+
+ /* load the key with data key */
+ if (!debug_mode) {
+ ret = keyctl_instantiate_iov(key, payload, payload_index, 0);
+ if (ret == -1)
+ error("%s: keyctl_instantiate: %m", __func__);
+ }
+
+ exit(0);
+}
+
+/*
+ * Look up a A and/or AAAA records to get host addresses
+ *
+ * The callout_info is parsed for request options. For instance, "ipv4" to
+ * request only IPv4 addresses, "ipv6" to request only IPv6 addresses and
+ * "list" to get multiple addresses.
+ */
+static __attribute__((noreturn))
+int dns_query_a_or_aaaa(key_serial_t key, const char *hostname, char *options)
+{
+ unsigned mask;
+ int ret;
+
+ debug("Get A/AAAA RR for hostname:'%s', options:'%s'",
+ hostname, options);
+
+ if (!options[0]) {
+ /* legacy mode */
+ mask = INET_IP4_ONLY | ONE_ADDR_ONLY;
+ } else {
+ char *key, *val;
+
+ mask = INET_ALL | ONE_ADDR_ONLY;
+
+ do {
+ key = options;
+ options = strchr(options, ' ');
+ if (!options)
+ options = key + strlen(key);
+ else
+ *options++ = '\0';
+ if (!*key)
+ continue;
+ if (strchr(key, ','))
+ error("Option name '%s' contains a comma", key);
+
+ val = strchr(key, '=');
+ if (val)
+ *val++ = '\0';
+
+ debug("Opt %s", key);
+
+ if (strcmp(key, "ipv4") == 0) {
+ mask &= ~INET_ALL;
+ mask |= INET_IP4_ONLY;
+ } else if (strcmp(key, "ipv6") == 0) {
+ mask &= ~INET_ALL;
+ mask |= INET_IP6_ONLY;
+ } else if (strcmp(key, "list") == 0) {
+ mask &= ~ONE_ADDR_ONLY;
+ mask |= LIST_MULTIPLE_ADDRS;
+ }
+
+ } while (*options);
+ }
+
+ /* Turn the hostname into IP addresses */
+ ret = dns_resolver(hostname, mask);
+ if (ret)
+ nsError(NO_DATA, hostname);
+
+ /* handle a lack of results */
+ if (payload_index == 0)
+ nsError(NO_DATA, hostname);
+
+ /* must include a NUL char at the end of the payload */
+ payload[payload_index].iov_base = "";
+ payload[payload_index++].iov_len = 1;
+ dump_payload();
+
+ /* load the key with data key */
+ if (!debug_mode) {
+ ret = keyctl_instantiate_iov(key, payload, payload_index, 0);
+ if (ret == -1)
+ error("%s: keyctl_instantiate: %m", __func__);
+ }
+
+ exit(0);
+}
+
+/*
+ * Print usage details,
+ */
+static __attribute__((noreturn))
+void usage(void)
+{
+ if (isatty(2)) {
+ fprintf(stderr,
+ "Usage: %s [-vv] key_serial\n",
+ prog);
+ fprintf(stderr,
+ "Usage: %s -D [-vv] <desc> <calloutinfo>\n",
+ prog);
+ } else {
+ info("Usage: %s [-vv] key_serial", prog);
+ }
+ if (!debug_mode)
+ keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);
+ exit(2);
+}
+
+const struct option long_options[] = {
+ { "debug", 0, NULL, 'D' },
+ { "verbose", 0, NULL, 'v' },
+ { "version", 0, NULL, 'V' },
+ { NULL, 0, NULL, 0 }
+};
+
+/*
+ *
+ */
+int main(int argc, char *argv[])
+{
+ int ktlen, qtlen, ret;
+ char *keyend, *p;
+ char *callout_info = NULL;
+ char *buf = NULL, *name;
+
+ openlog(prog, 0, LOG_DAEMON);
+
+ while ((ret = getopt_long(argc, argv, "vD", long_options, NULL)) != -1) {
+ switch (ret) {
+ case 'D':
+ debug_mode = 1;
+ continue;
+ case 'V':
+ printf("version: %s from %s (%s)\n",
+ DNS_PARSE_VERSION,
+ keyutils_version_string,
+ keyutils_build_string);
+ exit(0);
+ case 'v':
+ verbose++;
+ continue;
+ default:
+ if (!isatty(2))
+ syslog(LOG_ERR, "unknown option: %c", ret);
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (!debug_mode) {
+ if (argc != 1)
+ usage();
+
+ /* get the key ID */
+ errno = 0;
+ key = strtol(*argv, NULL, 10);
+ if (errno != 0)
+ error("Invalid key ID format: %m");
+
+ /* get the key description (of the form "x;x;x;x;<query_type>:<name>") */
+ if (!buf) {
+ ret = keyctl_describe_alloc(key, &buf);
+ if (ret == -1)
+ error("keyctl_describe_alloc failed: %m");
+ }
+
+ /* get the callout_info (which can supply options) */
+ if (!callout_info) {
+ ret = keyctl_read_alloc(KEY_SPEC_REQKEY_AUTH_KEY,
+ (void **)&callout_info);
+ if (ret == -1)
+ error("Invalid key callout_info read: %m");
+ }
+ } else {
+ if (argc != 2)
+ usage();
+
+ ret = asprintf(&buf, "%s;-1;-1;0;%s", key_type, argv[0]);
+ if (ret < 0)
+ error("Error %m");
+ callout_info = argv[1];
+ }
+
+ ret = 1;
+ info("Key description: '%s'", buf);
+ info("Callout info: '%s'", callout_info);
+
+ p = strchr(buf, ';');
+ if (!p)
+ error("Badly formatted key description '%s'", buf);
+ ktlen = p - buf;
+
+ /* make sure it's the type we are expecting */
+ if (ktlen != sizeof(key_type) - 1 ||
+ memcmp(buf, key_type, ktlen) != 0)
+ error("Key type is not supported: '%*.*s'", ktlen, ktlen, buf);
+
+ keyend = buf + ktlen + 1;
+
+ /* the actual key description follows the last semicolon */
+ keyend = rindex(keyend, ';');
+ if (!keyend)
+ error("Invalid key description: %s", buf);
+ keyend++;
+
+ name = index(keyend, ':');
+ if (!name)
+ dns_query_a_or_aaaa(key, keyend, callout_info);
+
+ qtlen = name - keyend;
+ name++;
+
+ if ((qtlen == sizeof(a_query_type) - 1 &&
+ memcmp(keyend, a_query_type, sizeof(a_query_type) - 1) == 0) ||
+ (qtlen == sizeof(aaaa_query_type) - 1 &&
+ memcmp(keyend, aaaa_query_type, sizeof(aaaa_query_type) - 1) == 0)
+ ) {
+ info("Do DNS query of A/AAAA type for:'%s' mask:'%s'",
+ name, callout_info);
+ dns_query_a_or_aaaa(key, name, callout_info);
+ }
+
+ if (qtlen == sizeof(afsdb_query_type) - 1 &&
+ memcmp(keyend, afsdb_query_type, sizeof(afsdb_query_type) - 1) == 0
+ ) {
+ info("Do DNS query of AFSDB type for:'%s' mask:'%s'",
+ name, callout_info);
+ dns_query_afsdb(key, name, callout_info);
+ }
+
+ error("Query type: \"%*.*s\" is not supported", qtlen, qtlen, keyend);
+}
diff --git a/keyutils-1.5.6/keyctl.1 b/keyutils-1.5.6/keyctl.1
new file mode 100644
index 0000000..21559da
--- /dev/null
+++ b/keyutils-1.5.6/keyctl.1
@@ -0,0 +1,729 @@
+.\"
+.\" Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL 1 "17 Nov 2005" Linux "Linux Key Management Utilities"
+.SH NAME
+keyctl - Key management facility control
+.SH SYNOPSIS
+\fBkeyctl\fR --version
+.br
+\fBkeyctl\fR show [-x] [<keyring>]
+.br
+\fBkeyctl\fR add <type> <desc> <data> <keyring>
+.br
+\fBkeyctl\fR padd <type> <desc> <keyring>
+.br
+\fBkeyctl\fR request <type> <desc> [<dest_keyring>]
+.br
+\fBkeyctl\fR request2 <type> <desc> <info> [<dest_keyring>]
+.br
+\fBkeyctl\fR prequest2 <type> <desc> [<dest_keyring>]
+.br
+\fBkeyctl\fR update <key> <data>
+.br
+\fBkeyctl\fR pupdate <key>
+.br
+\fBkeyctl\fR newring <name> <keyring>
+.br
+\fBkeyctl\fR revoke <key>
+.br
+\fBkeyctl\fR clear <keyring>
+.br
+\fBkeyctl\fR link <key> <keyring>
+.br
+\fBkeyctl\fR unlink <key> [<keyring>]
+.br
+\fBkeyctl\fR search <keyring> <type> <desc> [<dest_keyring>]
+.br
+\fBkeyctl\fR read <key>
+.br
+\fBkeyctl\fR pipe <key>
+.br
+\fBkeyctl\fR print <key>
+.br
+\fBkeyctl\fR list <keyring>
+.br
+\fBkeyctl\fR rlist <keyring>
+.br
+\fBkeyctl\fR describe <keyring>
+.br
+\fBkeyctl\fR rdescribe <keyring> [sep]
+.br
+\fBkeyctl\fR chown <key> <uid>
+.br
+\fBkeyctl\fR chgrp <key> <gid>
+.br
+\fBkeyctl\fR setperm <key> <mask>
+.br
+\fBkeyctl\fR session
+.br
+\fBkeyctl\fR session - [<prog> <arg1> <arg2> ...]
+.br
+\fBkeyctl\fR session <name> [<prog> <arg1> <arg2> ...]
+.br
+\fBkeyctl\fR instantiate <key> <data> <keyring>
+.br
+\fBkeyctl\fR pinstantiate <key> <keyring>
+.br
+\fBkeyctl\fR negate <key> <timeout> <keyring>
+.br
+\fBkeyctl\fR reject <key> <timeout> <error> <keyring>
+.br
+\fBkeyctl\fR timeout <key> <timeout>
+.br
+\fBkeyctl\fR security <key>
+.br
+\fBkeyctl\fR reap [-v]
+.br
+\fBkeyctl\fR purge <type>
+.br
+\fBkeyctl\fR purge [-i] [-p] <type> <desc>
+.br
+\fBkeyctl\fR purge -s <type> <desc>
+.SH DESCRIPTION
+This program is used to control the key management facility in various ways
+using a variety of subcommands.
+.SH KEY IDENTIFIERS
+.P
+The key identifiers passed to or returned from keyctl are, in general, positive
+integers. There are, however, some special values with special meanings that
+can be passed as arguments:
+.P
+(*) No key: \fB0\fR
+.P
+(*) Thread keyring: \fB@t\fR or \fB-1\fR
+.P
+Each thread may have its own keyring. This is searched first, before all
+others. The thread keyring is replaced by (v)fork, exec and clone.
+.P
+(*) Process keyring: \fB@p\fR or \fB-2\fR
+.P
+Each process (thread group) may have its own keyring. This is shared between
+all members of a group and will be searched after the thread keyring. The
+process keyring is replaced by (v)fork and exec.
+.P
+(*) Session keyring: \fB@s\fR or \fB-3\fR
+.P
+Each process subscribes to a session keyring that is inherited across (v)fork,
+exec and clone. This is searched after the process keyring. Session keyrings
+can be named and an extant keyring can be joined in place of a process's
+current session keyring.
+.P
+(*) User specific keyring: \fB@u\fR or \fB-4\fR
+.P
+This keyring is shared between all the processes owned by a particular user. It
+isn't searched directly, but is normally linked to from the session keyring.
+.P
+(*) User default session keyring: \fB@us\fR or \fB-5\fR
+.P
+This is the default session keyring for a particular user. Login processes that
+change to a particular user will bind to this session until another session is
+set.
+.P
+(*) Group specific keyring: \fB@g\fR or \fB-6\fR
+.P
+This is a place holder for a group specific keyring, but is not actually
+implemented yet in the kernel.
+.P
+(*) Assumed request_key authorisation key: \fB@a\fR or \fB-7\fR
+.P
+This selects the authorisation key provided to the request_key() helper to
+permit it to access the callers keyrings and instantiate the target key.
+.SH COMMAND SYNTAX
+Any non-ambiguous shortening of a command name may be used in lieu of the full
+command name. This facility should not be used in scripting as new commands may
+be added in future that then cause ambiguity.
+.P
+(*) \fBDisplay the package version number\fR
+.P
+\fBkeyctl --version\fR
+.P
+This command prints the package version number and build date and exits:
+.P
+.RS
+testbox>keyctl --version
+.br
+keyctl from keyutils-1.5.3 (Built 2011-08-24)
+.RE
+.P
+(*) \fBShow process keyrings\fR
+.P
+\fBkeyctl show [-x] [<keyring>]\fR
+.P
+By default this command recursively shows what keyrings a process is subscribed
+to and what keys and keyrings they contain. If a keyring is specified then
+that keyring will be dumped instead. If \fB-x\fR is specified then the keyring
+IDs will be dumped in hex instead of decimal.
+.P
+(*) \fBAdd a key to a keyring\fR
+.P
+\fBkeyctl add\fR <type> <desc> <data> <keyring>
+.br
+\fBkeyctl padd\fR <type> <desc> <keyring>
+.P
+This command creates a key of the specified type and description; instantiates
+it with the given data and attaches it to the specified keyring. It then prints
+the new key's ID on stdout:
+.P
+.RS
+testbox>keyctl add user mykey stuff @u
+.br
+26
+.RE
+.P
+The \fBpadd\fR variant of the command reads the data from stdin rather than
+taking it from the command line:
+.P
+.RS
+testbox>echo -n stuff | keyctl padd user mykey @u
+.br
+26
+.RE
+.P
+(*) \fBRequest a key\fR
+.P
+\fBkeyctl request\fR <type> <desc> [<dest_keyring>]
+.br
+\fBkeyctl request2\fR <type> <desc> <info> [<dest_keyring>]
+.br
+\fBkeyctl prequest2\fR <type> <desc> [<dest_keyring>]
+.P
+These three commands request the lookup of a key of the given type and
+description. The process's keyrings will be searched, and if a match is found
+the matching key's ID will be printed to stdout; and if a destination keyring
+is given, the key will be added to that keyring also.
+.P
+If there is no key, the first command will simply return the error ENOKEY and
+fail. The second and third commands will create a partial key with the type and
+description, and call out to \fB/sbin/request-key\fR with that key and the
+extra information supplied. This will then attempt to instantiate the key in
+some manner, such that a valid key is obtained.
+.P
+The third command is like the second, except that the callout information is
+read from stdin rather than being passed on the command line.
+.P
+If a valid key is obtained, the ID will be printed and the key attached as if
+the original search had succeeded.
+.P
+If there wasn't a valid key obtained, a temporary negative key will be attached
+to the destination keyring if given and the error "Requested key not available"
+will be given.
+.P
+.RS
+testbox>keyctl request2 user debug:hello wibble
+.br
+23
+.br
+testbox>echo -n wibble | keyctl prequest2 user debug:hello
+.br
+23
+.br
+testbox>keyctl request user debug:hello
+.br
+23
+.RE
+.P
+(*) \fBUpdate a key\fR
+.P
+\fBkeyctl update\fR <key> <data>
+.br
+\fBkeyctl pupdate\fR <key>
+.P
+This command replaces the data attached to a key with a new set of data. If the
+type of the key doesn't support update then error "Operation not supported"
+will be returned.
+.P
+.RS
+testbox>keyctl update 23 zebra
+.RE
+.P
+The \fBpupdate\fR variant of the command reads the data from stdin rather than
+taking it from the command line:
+.P
+.RS
+testbox>echo -n zebra | keyctl pupdate 23
+.RE
+.P
+(*) \fBCreate a keyring\fR
+.P
+\fBkeyctl newring\fR <name> <keyring>
+.P
+This command creates a new keyring of the specified name and attaches it to the
+specified keyring. The ID of the new keyring will be printed to stdout if
+successful.
+.P
+.RS
+testbox>keyctl newring squelch @us
+.br
+27
+.RE
+.P
+(*) \fBRevoke a key\fR
+.P
+\fBkeyctl revoke\fR <key>
+.P
+This command marks a key as being revoked. Any further operations on that key
+(apart from unlinking it) will return error "Key has been revoked".
+.P
+.RS
+testbox>keyctl revoke 26
+.br
+testbox>keyctl describe 26
+.br
+keyctl_describe: Key has been revoked
+.RE
+.P
+(*) \fBClear a keyring\fR
+.P
+\fBkeyctl clear\fR <keyring>
+.P
+This command unlinks all the keys attached to the specified keyring. Error
+"Not a directory" will be returned if the key specified is not a keyring.
+.P
+.RS
+testbox>keyctl clear 27
+.RE
+.P
+(*) \fBLink a key to a keyring\fR
+.P
+\fBkeyctl link\fR <key> <keyring>
+.P
+This command makes a link from the key to the keyring if there's enough
+capacity to do so. Error "Not a directory" will be returned if the destination
+is not a keyring. Error "Permission denied" will be returned if the key doesn't
+have link permission or the keyring doesn't have write permission. Error "File
+table overflow" will be returned if the keyring is full. Error "Resource
+deadlock avoided" will be returned if an attempt was made to introduce a
+recursive link.
+.P
+.RS
+testbox>keyctl link 23 27
+.br
+testbox>keyctl link 27 27
+.br
+keyctl_link: Resource deadlock avoided
+.RE
+.P
+(*) \fBUnlink a key from a keyring or the session keyring tree\fR
+.P
+\fBkeyctl unlink\fR <key> [<keyring>]
+.P
+If the keyring is specified, this command removes a link to the key from the
+keyring. Error "Not a directory" will be returned if the destination is not a
+keyring. Error "Permission denied" will be returned if the keyring doesn't have
+write permission. Error "No such file or directory" will be returned if the key
+is not linked to by the keyring.
+.P
+If the keyring is not specified, this command performs a depth-first search of
+the session keyring tree and removes all the links to the nominated key that it
+finds (and that it is permitted to remove). It prints the number of successful
+unlinks before exiting.
+.P
+.RS
+testbox>keyctl unlink 23 27
+.RE
+.P
+(*) \fBSearch a keyring\fR
+.P
+\fBkeyctl search\fR <keyring> <type> <desc> [<dest_keyring>]
+.P
+This command non-recursively searches a keyring for a key of a particular type
+and description. If found, the ID of the key will be printed on stdout and the
+key will be attached to the destination keyring if present. Error "Requested
+key not available" will be returned if the key is not found.
+.P
+.RS
+testbox>keyctl search @us user debug:hello
+.br
+23
+.br
+testbox>keyctl search @us user debug:bye
+.br
+keyctl_search: Requested key not available
+.RE
+.P
+(*) \fBRead a key\fR
+.P
+\fBkeyctl read\fR <key>
+.br
+\fBkeyctl pipe\fR <key>
+.br
+\fBkeyctl print\fR <key>
+.P
+These commands read the payload of a key. "read" prints it on stdout as a hex
+dump, "pipe" dumps the raw data to stdout and "print" dumps it to stdout
+directly if it's entirely printable or as a hexdump preceded by ":hex:" if not.
+.P
+If the key type does not support reading of the payload, then error "Operation
+not supported" will be returned.
+.P
+.RS
+testbox>keyctl read 26
+.br
+1 bytes of data in key:
+.br
+62
+.br
+testbox>keyctl print 26
+.br
+b
+.br
+testbox>keyctl pipe 26
+.br
+btestbox>
+.RE
+.P
+(*) \fBList a keyring\fR
+.P
+\fBkeyctl list\fR <keyring>
+.br
+\fBkeyctl rlist\fR <keyring>
+.P
+These commands list the contents of a key as a keyring. "list" pretty prints
+the contents and "rlist" just produces a space-separated list of key IDs.
+.P
+No attempt is made to check that the specified keyring is a keyring.
+.P
+.RS
+testbox>keyctl list @us
+.br
+2 keys in keyring:
+.br
+ 22: vrwsl---------- 4043 -1 keyring: _uid.4043
+.br
+ 23: vrwsl---------- 4043 4043 user: debug:hello
+.br
+testbox>keyctl rlist @us
+.br
+22 23
+.RE
+.P
+(*) \fBDescribe a key\fR
+.P
+\fBkeyctl describe\fR <keyring>
+.br
+\fBkeyctl rdescribe\fR <keyring> [sep]
+.P
+These commands fetch a description of a keyring. "describe" pretty prints the
+description in the same fashion as the "list" command; "rdescribe" prints the
+raw data returned from the kernel.
+.P
+.RS
+testbox>keyctl describe @us
+ -5: vrwsl---------- 4043 -1 keyring: _uid_ses.4043
+testbox>keyctl rdescribe @us
+keyring;4043;-1;3f1f0000;_uid_ses.4043
+.RE
+.P
+The raw string is "<type>;<uid>;<gid>;<perms>;<description>", where \fIuid\fR
+and \fIgid\fR are the decimal user and group IDs, \fIperms\fR is the
+permissions mask in hex, \fItype\fR and \fIdescription\fR are the type name and
+description strings (neither of which will contain semicolons).
+.P
+(*) \fBChange the access controls on a key\fR
+.P
+\fBkeyctl chown\fR <key> <uid>
+.br
+\fBkeyctl chgrp\fR <key> <gid>
+.P
+These two commands change the UID and GID associated with evaluating a key's
+permissions mask. The UID also governs which quota a key is taken out of.
+.P
+The chown command is not currently supported; attempting it will earn the error
+"Operation not supported" at best.
+.P
+For non-superuser users, the GID may only be set to the process's GID or a GID
+in the process's groups list. The superuser may set any GID it likes.
+.P
+.RS
+testbox>sudo keyctl chown 27 0
+.br
+keyctl_chown: Operation not supported
+.br
+testbox>sudo keyctl chgrp 27 0
+.RE
+.P
+(*) \fBSet the permissions mask on a key\fR
+.P
+\fBkeyctl setperm\fR <key> <mask>
+.P
+This command changes the permission control mask on a key. The mask may be
+specified as a hex number if it begins "0x", an octal number if it begins "0"
+or a decimal number otherwise.
+.P
+The hex numbers are a combination of:
+.P
+.RS
+Possessor UID GID Other Permission Granted
+.br
+======== ======== ======== ======== ==================
+.br
+01000000 00010000 00000100 00000001 View
+.br
+02000000 00020000 00000200 00000002 Read
+.br
+04000000 00040000 00000400 00000004 Write
+.br
+08000000 00080000 00000800 00000008 Search
+.br
+10000000 00100000 00001000 00000010 Link
+.br
+20000000 00200000 00002000 00000020 Set Attribute
+.br
+3f000000 003f0000 00003f00 0000003f All
+.RE
+.P
+\fIView\fR permits the type, description and other parameters of a key to be
+viewed.
+.P
+\fIRead\fR permits the payload (or keyring list) to be read if supported by the
+type.
+.P
+\fIWrite\fR permits the payload (or keyring list) to be modified or updated.
+.P
+\fISearch\fR on a key permits it to be found when a keyring to which it is
+linked is searched.
+.P
+\fILink\fR permits a key to be linked to a keyring.
+.P
+\fISet Attribute\fR permits a key to have its owner, group membership,
+permissions mask and timeout changed.
+.P
+.RS
+testbox>keyctl setperm 27 0x1f1f1f00
+.RE
+.P
+(*) \fBStart a new session with fresh keyrings\fR
+.P
+\fBkeyctl session\fR
+.br
+\fBkeyctl session\fR - [<prog> <arg1> <arg2> ...]
+.br
+\fBkeyctl session\fR <name> [<prog> <arg1> <arg2> ...]
+.P
+These commands join or create a new keyring and then run a shell or other
+program with that keyring as the session key.
+.P
+The variation with no arguments just creates an anonymous session keyring and
+attaches that as the session keyring; it then exec's $SHELL.
+.P
+The variation with a dash in place of a name creates an anonymous session
+keyring and attaches that as the session keyring; it then exec's the supplied
+command, or $SHELL if one isn't supplied.
+.P
+The variation with a name supplied creates or joins the named keyring and
+attaches that as the session keyring; it then exec's the supplied command, or
+$SHELL if one isn't supplied.
+.P
+.RS
+testbox>keyctl rdescribe @s
+.br
+keyring;4043;-1;3f1f0000;_uid_ses.4043
+.P
+testbox>keyctl session
+.br
+Joined session keyring: 28
+.br
+testbox>keyctl rdescribe @s
+.br
+keyring;4043;4043;3f1f0000;_ses.24082
+.P
+testbox>keyctl session -
+.br
+Joined session keyring: 29
+.br
+testbox>keyctl rdescribe @s
+.br
+keyring;4043;4043;3f1f0000;_ses.24139
+.P
+testbox>keyctl session - keyctl rdescribe @s
+.br
+Joined session keyring: 30
+.br
+keyring;4043;4043;3f1f0000;_ses.24185
+.P
+testbox>keyctl session fish
+.br
+Joined session keyring: 34
+.br
+testbox>keyctl rdescribe @s
+.br
+keyring;4043;4043;3f1f0000;fish
+.P
+testbox>keyctl session fish keyctl rdesc @s
+.br
+Joined session keyring: 35
+.br
+keyring;4043;4043;3f1f0000;fish
+.RE
+.P
+(*) \fBInstantiate a key\fR
+.P
+\fBkeyctl instantiate\fR <key> <data> <keyring>
+.br
+\fBkeyctl pinstantiate\fR <key> <keyring>
+.br
+\fBkeyctl negate\fR <key> <timeout> <keyring>
+.br
+\fBkeyctl reject\fR <key> <timeout> <error> <keyring>
+.P
+These commands are used to attach data to a partially set up key (as created by
+the kernel and passed to /sbin/request-key). "instantiate" marks a key as
+being valid and attaches the data as the payload. "negate" and "reject" mark a
+key as invalid and sets a timeout on it so that it'll go away after a while.
+This prevents a lot of quickly sequential requests from slowing the system down
+overmuch when they all fail, as all subsequent requests will then fail with
+error "Requested key not found" (if negated) or the specified error (if
+rejected) until the negative key has expired.
+.P
+Reject's error argument can either be a UNIX error number or one of
+.BR "" "'" rejected "', '" expired "' or '" revoked "'."
+.P
+The newly instantiated key will be attached to the specified keyring.
+.P
+These commands may only be run from the program run by request-key - a special
+authorisation key is set up by the kernel and attached to the request-key's
+session keyring. This special key is revoked once the key to which it refers
+has been instantiated one way or another.
+.P
+.RS
+testbox>keyctl instantiate $1 "Debug $3" $4
+.br
+testbox>keyctl negate $1 30 $4
+.br
+testbox>keyctl reject $1 30 64 $4
+.RE
+.P
+The \fBpinstantiate\fR variant of the command reads the data from stdin rather
+than taking it from the command line:
+.P
+.RS
+testbox>echo -n "Debug $3" | keyctl pinstantiate $1 $4
+.RE
+.P
+(*) \fBSet the expiry time on a key\fR
+.P
+\fBkeyctl timeout\fR <key> <timeout>
+.P
+This command is used to set the timeout on a key, or clear an existing timeout
+if the value specified is zero. The timeout is given as a number of seconds
+into the future.
+.P
+.RS
+testbox>keyctl timeout $1 45
+.RE
+.P
+(*) \fBRetrieve a key's security context\fR
+.P
+\fBkeyctl security\fR <key>
+.P
+This command is used to retrieve a key's LSM security context. The label is
+printed on stdout.
+.P
+.RS
+testbox>keyctl security @s
+.br
+unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+.RE
+.P
+(*) \fBGive the parent process a new session keyring\fR
+.P
+\fBkeyctl new_session\fR
+.P
+This command is used to give the invoking process (typically a shell) a new
+session keyring, discarding its old session keyring.
+.P
+.RS
+testbox> keyctl session foo
+.br
+Joined session keyring: 723488146
+.br
+testbox> keyctl show
+.br
+Session Keyring
+.br
+ -3 --alswrv 0 0 keyring: foo
+.br
+testbox> keyctl new_session
+.br
+490511412
+.br
+testbox> keyctl show
+.br
+Session Keyring
+.br
+ -3 --alswrv 0 0 keyring: _ses
+.RE
+.P
+Note that this affects the \fIparent\fP of the process that invokes the system
+call, and so may only affect processes with matching credentials.
+Furthermore, the change does not take effect till the parent process next
+transitions from kernel space to user space - typically when the \fBwait\fP()
+system call returns.
+.P
+(*) \fBRemove dead keys from the session keyring tree\fR
+.P
+\fBkeyctl reap\fR
+.P
+This command performs a depth-first search of the caller's session keyring tree
+and attempts to unlink any key that it finds that is inaccessible due to
+expiry, revocation, rejection or negation. It does not attempt to remove live
+keys that are unavailable simply due to a lack of granted permission.
+.P
+A key that is designated reapable will only be removed from a keyring if the
+caller has Write permission on that keyring, and only keyrings that grant
+Search permission to the caller will be searched.
+.P
+The command prints the number of keys reaped before it exits. If the \fB-v\fR
+flag is passed then the reaped keys are listed as they're being reaped,
+together with the success or failure of the unlink.
+.P
+(*) \fBRemove matching keys from the session keyring tree\fR
+.P
+\fBkeyctl\fR purge <type>
+.br
+\fBkeyctl\fR purge [-i] [-p] <type> <desc>
+.br
+\fBkeyctl\fR purge -s <type> <desc>
+.P
+These commands perform a depth-first search to find matching keys in the
+caller's session keyring tree and attempts to unlink them. The number of
+keys successfully unlinked is printed at the end.
+.P
+The keyrings must grant Read and View permission to the caller to be searched,
+and the keys to be removed must also grant View permission. Keys can only be
+removed from keyrings that grant Write permission.
+.P
+The first variant purges all keys of the specified type.
+.P
+The second variant purges all keys of the specified type that also match the
+given description literally. The -i flag allows a case-independent match and
+the -p flag allows a prefix match.
+.P
+The third variant purges all keys of the specified type and matching
+description using the key type's comparator in the kernel to match the
+description. This permits the key type to match a key with a variety of
+descriptions.
+.P
+.SH ERRORS
+.P
+There are a number of common errors returned by this program:
+.P
+"Not a directory" - a key wasn't a keyring.
+.P
+"Requested key not found" - the looked for key isn't available.
+.P
+"Key has been revoked" - a revoked key was accessed.
+.P
+"Key has expired" - an expired key was accessed.
+.P
+"Permission denied" - permission was denied by a UID/GID/mask combination.
+
+.SH SEE ALSO
+\fBkeyctl\fR(1), \fBrequest-key.conf\fR(5)
diff --git a/keyutils-1.5.6/keyctl.3 b/keyutils-1.5.6/keyctl.3
new file mode 100644
index 0000000..35bac2f
--- /dev/null
+++ b/keyutils-1.5.6/keyctl.3
@@ -0,0 +1,98 @@
+.\"
+.\" Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public Licence
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the Licence, or (at your option) any later version.
+.\"
+.TH KEYCTL 3 "29 Aug 2013" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_*() \- Key management function wrappers
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+The
+.BR keyctl ()
+system call is a multiplexor for a number of key management functions. These
+should be called via the wrappers in the libkeyutils library.
+.P
+The functions can be compiled in by including the keyutils header file:
+.sp
+.RS
+.nf
+.B #include <keyutils.h>
+.RE
+.P
+and then telling the linker it should link in the library:
+.sp
+.RS
+.nf
+.B -lkeyutils
+.RE
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH KEYCTL FUNCTIONS
+.BR keyctl_assume_authority (3)
+.br
+.BR keyctl_clear (3)
+.br
+.BR keyctl_describe (3)
+.br
+.BR keyctl_describe_alloc (3)
+.br
+.BR keyctl_get_keyring_ID (3)
+.br
+.BR keyctl_instantiate (3)
+.br
+.BR keyctl_instantiate_iov (3)
+.br
+.BR keyctl_invalidate (3)
+.br
+.BR keyctl_join_session_keyring (3)
+.br
+.BR keyctl_link (3)
+.br
+.BR keyctl_negate (3)
+.br
+.BR keyctl_read (3)
+.br
+.BR keyctl_read_alloc (3)
+.br
+.BR keyctl_reject (3)
+.br
+.BR keyctl_revoke (3)
+.br
+.BR keyctl_search (3)
+.br
+.BR keyctl_security (3)
+.br
+.BR keyctl_security_alloc (3)
+.br
+.BR keyctl_session_to_parent (3)
+.br
+.BR keyctl_set_reqkey_keyring (3)
+.br
+.BR keyctl_set_timeout (3)
+.br
+.BR keyctl_setperm (3)
+.br
+.BR keyctl_unlink (3)
+.br
+.BR keyctl_update (3)
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH UTILITY FUNCTIONS
+.BR recursive_key_scan (3)
+.br
+.BR recursive_session_key_scan (3)
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl.c b/keyutils-1.5.6/keyctl.c
new file mode 100644
index 0000000..a137e08
--- /dev/null
+++ b/keyutils-1.5.6/keyctl.c
@@ -0,0 +1,1762 @@
+/* keyctl.c: key control program
+ *
+ * Copyright (C) 2005, 2011 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <asm/unistd.h>
+#include "keyutils.h"
+
+struct command {
+ int (*action)(int argc, char *argv[]);
+ const char *name;
+ const char *format;
+};
+
+static int act_keyctl___version(int argc, char *argv[]);
+static int act_keyctl_show(int argc, char *argv[]);
+static int act_keyctl_add(int argc, char *argv[]);
+static int act_keyctl_padd(int argc, char *argv[]);
+static int act_keyctl_request(int argc, char *argv[]);
+static int act_keyctl_request2(int argc, char *argv[]);
+static int act_keyctl_prequest2(int argc, char *argv[]);
+static int act_keyctl_update(int argc, char *argv[]);
+static int act_keyctl_pupdate(int argc, char *argv[]);
+static int act_keyctl_newring(int argc, char *argv[]);
+static int act_keyctl_revoke(int argc, char *argv[]);
+static int act_keyctl_clear(int argc, char *argv[]);
+static int act_keyctl_link(int argc, char *argv[]);
+static int act_keyctl_unlink(int argc, char *argv[]);
+static int act_keyctl_search(int argc, char *argv[]);
+static int act_keyctl_read(int argc, char *argv[]);
+static int act_keyctl_pipe(int argc, char *argv[]);
+static int act_keyctl_print(int argc, char *argv[]);
+static int act_keyctl_list(int argc, char *argv[]);
+static int act_keyctl_rlist(int argc, char *argv[]);
+static int act_keyctl_describe(int argc, char *argv[]);
+static int act_keyctl_rdescribe(int argc, char *argv[]);
+static int act_keyctl_chown(int argc, char *argv[]);
+static int act_keyctl_chgrp(int argc, char *argv[]);
+static int act_keyctl_setperm(int argc, char *argv[]);
+static int act_keyctl_session(int argc, char *argv[]);
+static int act_keyctl_instantiate(int argc, char *argv[]);
+static int act_keyctl_pinstantiate(int argc, char *argv[]);
+static int act_keyctl_negate(int argc, char *argv[]);
+static int act_keyctl_timeout(int argc, char *argv[]);
+static int act_keyctl_security(int argc, char *argv[]);
+static int act_keyctl_new_session(int argc, char *argv[]);
+static int act_keyctl_reject(int argc, char *argv[]);
+static int act_keyctl_reap(int argc, char *argv[]);
+static int act_keyctl_purge(int argc, char *argv[]);
+static int act_keyctl_invalidate(int argc, char *argv[]);
+
+const struct command commands[] = {
+ { act_keyctl___version, "--version", "" },
+ { act_keyctl_add, "add", "<type> <desc> <data> <keyring>" },
+ { act_keyctl_chgrp, "chgrp", "<key> <gid>" },
+ { act_keyctl_chown, "chown", "<key> <uid>" },
+ { act_keyctl_clear, "clear", "<keyring>" },
+ { act_keyctl_describe, "describe", "<keyring>" },
+ { act_keyctl_instantiate, "instantiate","<key> <data> <keyring>" },
+ { act_keyctl_invalidate,"invalidate", "<key>" },
+ { act_keyctl_link, "link", "<key> <keyring>" },
+ { act_keyctl_list, "list", "<keyring>" },
+ { act_keyctl_negate, "negate", "<key> <timeout> <keyring>" },
+ { act_keyctl_new_session, "new_session", "" },
+ { act_keyctl_newring, "newring", "<name> <keyring>" },
+ { act_keyctl_padd, "padd", "<type> <desc> <keyring>" },
+ { act_keyctl_pinstantiate, "pinstantiate","<key> <keyring>" },
+ { act_keyctl_pipe, "pipe", "<key>" },
+ { act_keyctl_prequest2, "prequest2", "<type> <desc> [<dest_keyring>]" },
+ { act_keyctl_print, "print", "<key>" },
+ { act_keyctl_pupdate, "pupdate", "<key>" },
+ { act_keyctl_purge, "purge", "<type>" },
+ { NULL, "purge", "[-p] [-i] <type> <desc>" },
+ { NULL, "purge", "-s <type> <desc>" },
+ { act_keyctl_rdescribe, "rdescribe", "<keyring> [sep]" },
+ { act_keyctl_read, "read", "<key>" },
+ { act_keyctl_reap, "reap", "[-v]" },
+ { act_keyctl_reject, "reject", "<key> <timeout> <error> <keyring>" },
+ { act_keyctl_request, "request", "<type> <desc> [<dest_keyring>]" },
+ { act_keyctl_request2, "request2", "<type> <desc> <info> [<dest_keyring>]" },
+ { act_keyctl_revoke, "revoke", "<key>" },
+ { act_keyctl_rlist, "rlist", "<keyring>" },
+ { act_keyctl_search, "search", "<keyring> <type> <desc> [<dest_keyring>]" },
+ { act_keyctl_security, "security", "<key>" },
+ { act_keyctl_session, "session", "" },
+ { NULL, "session", "- [<prog> <arg1> <arg2> ...]" },
+ { NULL, "session", "<name> [<prog> <arg1> <arg2> ...]" },
+ { act_keyctl_setperm, "setperm", "<key> <mask>" },
+ { act_keyctl_show, "show", "[-x] [<keyring>]" },
+ { act_keyctl_timeout, "timeout", "<key> <timeout>" },
+ { act_keyctl_unlink, "unlink", "<key> [<keyring>]" },
+ { act_keyctl_update, "update", "<key> <data>" },
+ { NULL, NULL, NULL }
+};
+
+static int dump_key_tree(key_serial_t keyring, const char *name, int hex_key_IDs);
+static void format(void) __attribute__((noreturn));
+static void error(const char *msg) __attribute__((noreturn));
+static key_serial_t get_key_id(const char *arg);
+
+static uid_t myuid;
+static gid_t mygid, *mygroups;
+static int myngroups;
+static int verbose;
+
+/*****************************************************************************/
+/*
+ * handle an error
+ */
+static inline void error(const char *msg)
+{
+ perror(msg);
+ exit(1);
+
+} /* end error() */
+
+/*****************************************************************************/
+/*
+ * execute the appropriate subcommand
+ */
+int main(int argc, char *argv[])
+{
+ const struct command *cmd, *best;
+ int n;
+
+ argv++;
+ argc--;
+
+ if (argc == 0)
+ format();
+
+ /* find the best fit command */
+ best = NULL;
+ n = strlen(*argv);
+
+ for (cmd = commands; cmd->name; cmd++) {
+ if (!cmd->action)
+ continue;
+ if (memcmp(cmd->name, *argv, n) != 0)
+ continue;
+
+ if (cmd->name[n] == 0) {
+ /* exact match */
+ best = cmd;
+ break;
+ }
+
+ /* partial match */
+ if (best) {
+ fprintf(stderr, "Ambiguous command\n");
+ exit(2);
+ }
+
+ best = cmd;
+ }
+
+ if (!best) {
+ fprintf(stderr, "Unknown command\n");
+ exit(2);
+ }
+
+ /* grab my UID, GID and groups */
+ myuid = geteuid();
+ mygid = getegid();
+ myngroups = getgroups(0, NULL);
+
+ if (myuid == -1 || mygid == -1 || myngroups == -1)
+ error("Unable to get UID/GID/#Groups\n");
+
+ mygroups = calloc(myngroups, sizeof(gid_t));
+ if (!mygroups)
+ error("calloc");
+
+ myngroups = getgroups(myngroups, mygroups);
+ if (myngroups < 0)
+ error("Unable to get Groups\n");
+
+ return best->action(argc, argv);
+
+} /* end main() */
+
+/*****************************************************************************/
+/*
+ * display command format information
+ */
+static void format(void)
+{
+ const struct command *cmd;
+
+ fprintf(stderr, "Format:\n");
+
+ for (cmd = commands; cmd->name; cmd++)
+ fprintf(stderr, " keyctl %s %s\n", cmd->name, cmd->format);
+
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Key/keyring ID:\n");
+ fprintf(stderr, " <nnn> numeric keyring ID\n");
+ fprintf(stderr, " @t thread keyring\n");
+ fprintf(stderr, " @p process keyring\n");
+ fprintf(stderr, " @s session keyring\n");
+ fprintf(stderr, " @u user keyring\n");
+ fprintf(stderr, " @us user default session keyring\n");
+ fprintf(stderr, " @g group keyring\n");
+ fprintf(stderr, " @a assumed request_key authorisation key\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "<type> can be \"user\" for a user-defined keyring\n");
+ fprintf(stderr, "If you do this, prefix the description with \"<subtype>:\"\n");
+
+ exit(2);
+
+} /* end format() */
+
+/*****************************************************************************/
+/*
+ * Display version information
+ */
+static int act_keyctl___version(int argc, char *argv[])
+{
+ printf("keyctl from %s (Built %s)\n",
+ keyutils_version_string, keyutils_build_string);
+ return 0;
+}
+
+/*****************************************************************************/
+/*
+ * grab data from stdin
+ */
+static char *grab_stdin(size_t *_size)
+{
+ static char input[1024 * 1024 + 1];
+ int n, tmp;
+
+ n = 0;
+ do {
+ tmp = read(0, input + n, sizeof(input) - 1 - n);
+ if (tmp < 0)
+ error("stdin");
+
+ if (tmp == 0)
+ break;
+
+ n += tmp;
+
+ } while (n < sizeof(input));
+
+ if (n >= sizeof(input)) {
+ fprintf(stderr, "Too much data read on stdin\n");
+ exit(1);
+ }
+
+ input[n] = '\0';
+ *_size = n;
+
+ return input;
+
+} /* end grab_stdin() */
+
+/*****************************************************************************/
+/*
+ * convert the permissions mask to a string representing the permissions we
+ * have actually been granted
+ */
+static void calc_perms(char *pretty, key_perm_t perm, uid_t uid, gid_t gid)
+{
+ unsigned perms;
+ gid_t *pg;
+ int loop;
+
+ perms = (perm & KEY_POS_ALL) >> 24;
+
+ if (uid == myuid) {
+ perms |= (perm & KEY_USR_ALL) >> 16;
+ goto write_mask;
+ }
+
+ if (gid != -1) {
+ if (gid == mygid) {
+ perms |= (perm & KEY_GRP_ALL) >> 8;
+ goto write_mask;
+ }
+
+ pg = mygroups;
+ for (loop = myngroups; loop > 0; loop--, pg++) {
+ if (gid == *pg) {
+ perms |= (perm & KEY_GRP_ALL) >> 8;
+ goto write_mask;
+ }
+ }
+ }
+
+ perms |= (perm & KEY_OTH_ALL);
+
+write_mask:
+ sprintf(pretty, "--%c%c%c%c%c%c",
+ perms & KEY_OTH_SETATTR ? 'a' : '-',
+ perms & KEY_OTH_LINK ? 'l' : '-',
+ perms & KEY_OTH_SEARCH ? 's' : '-',
+ perms & KEY_OTH_WRITE ? 'w' : '-',
+ perms & KEY_OTH_READ ? 'r' : '-',
+ perms & KEY_OTH_VIEW ? 'v' : '-');
+
+} /* end calc_perms() */
+
+/*****************************************************************************/
+/*
+ * show the parent process's session keyring
+ */
+static int act_keyctl_show(int argc, char *argv[])
+{
+ key_serial_t keyring = KEY_SPEC_SESSION_KEYRING;
+ int hex_key_IDs = 0;
+
+ if (argc >= 2 && strcmp(argv[1], "-x") == 0) {
+ hex_key_IDs = 1;
+ argc--;
+ argv++;
+ }
+
+ if (argc > 2)
+ format();
+
+ if (argc == 2)
+ keyring = get_key_id(argv[1]);
+
+ dump_key_tree(keyring, argc == 2 ? "Keyring" : "Session Keyring", hex_key_IDs);
+ return 0;
+
+} /* end act_keyctl_show() */
+
+/*****************************************************************************/
+/*
+ * add a key
+ */
+static int act_keyctl_add(int argc, char *argv[])
+{
+ key_serial_t dest;
+ int ret;
+
+ if (argc != 5)
+ format();
+
+ dest = get_key_id(argv[4]);
+
+ ret = add_key(argv[1], argv[2], argv[3], strlen(argv[3]), dest);
+ if (ret < 0)
+ error("add_key");
+
+ /* print the resulting key ID */
+ printf("%d\n", ret);
+ return 0;
+
+} /* end act_keyctl_add() */
+
+/*****************************************************************************/
+/*
+ * add a key, reading from a pipe
+ */
+static int act_keyctl_padd(int argc, char *argv[])
+{
+ key_serial_t dest;
+ size_t datalen;
+ void *data;
+ int ret;
+
+
+ if (argc != 4)
+ format();
+
+ dest = get_key_id(argv[3]);
+
+ data = grab_stdin(&datalen);
+
+ ret = add_key(argv[1], argv[2], data, datalen, dest);
+ if (ret < 0)
+ error("add_key");
+
+ /* print the resulting key ID */
+ printf("%d\n", ret);
+ return 0;
+
+} /* end act_keyctl_padd() */
+
+/*****************************************************************************/
+/*
+ * request a key
+ */
+static int act_keyctl_request(int argc, char *argv[])
+{
+ key_serial_t dest;
+ int ret;
+
+ if (argc != 3 && argc != 4)
+ format();
+
+ dest = 0;
+ if (argc == 4)
+ dest = get_key_id(argv[3]);
+
+ ret = request_key(argv[1], argv[2], NULL, dest);
+ if (ret < 0)
+ error("request_key");
+
+ /* print the resulting key ID */
+ printf("%d\n", ret);
+ return 0;
+
+} /* end act_keyctl_request() */
+
+/*****************************************************************************/
+/*
+ * request a key, with recourse to /sbin/request-key
+ */
+static int act_keyctl_request2(int argc, char *argv[])
+{
+ key_serial_t dest;
+ int ret;
+
+ if (argc != 4 && argc != 5)
+ format();
+
+ dest = 0;
+ if (argc == 5)
+ dest = get_key_id(argv[4]);
+
+ ret = request_key(argv[1], argv[2], argv[3], dest);
+ if (ret < 0)
+ error("request_key");
+
+ /* print the resulting key ID */
+ printf("%d\n", ret);
+ return 0;
+
+} /* end act_keyctl_request2() */
+
+/*****************************************************************************/
+/*
+ * request a key, with recourse to /sbin/request-key, reading the callout info
+ * from a pipe
+ */
+static int act_keyctl_prequest2(int argc, char *argv[])
+{
+ char *args[6];
+ size_t datalen;
+
+ if (argc != 3 && argc != 4)
+ format();
+
+ args[0] = argv[0];
+ args[1] = argv[1];
+ args[2] = argv[2];
+ args[3] = grab_stdin(&datalen);
+ args[4] = argv[3];
+ args[5] = NULL;
+
+ return act_keyctl_request2(argc + 1, args);
+
+} /* end act_keyctl_prequest2() */
+
+/*****************************************************************************/
+/*
+ * update a key
+ */
+static int act_keyctl_update(int argc, char *argv[])
+{
+ key_serial_t key;
+
+ if (argc != 3)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ if (keyctl_update(key, argv[2], strlen(argv[2])) < 0)
+ error("keyctl_update");
+
+ return 0;
+
+} /* end act_keyctl_update() */
+
+/*****************************************************************************/
+/*
+ * update a key, reading from a pipe
+ */
+static int act_keyctl_pupdate(int argc, char *argv[])
+{
+ key_serial_t key;
+ size_t datalen;
+ void *data;
+
+ if (argc != 2)
+ format();
+
+ key = get_key_id(argv[1]);
+ data = grab_stdin(&datalen);
+
+ if (keyctl_update(key, data, datalen) < 0)
+ error("keyctl_update");
+
+ return 0;
+
+} /* end act_keyctl_pupdate() */
+
+/*****************************************************************************/
+/*
+ * create a new keyring
+ */
+static int act_keyctl_newring(int argc, char *argv[])
+{
+ key_serial_t dest;
+ int ret;
+
+ if (argc != 3)
+ format();
+
+ dest = get_key_id(argv[2]);
+
+ ret = add_key("keyring", argv[1], NULL, 0, dest);
+ if (ret < 0)
+ error("add_key");
+
+ printf("%d\n", ret);
+ return 0;
+
+} /* end act_keyctl_newring() */
+
+/*****************************************************************************/
+/*
+ * revoke a key
+ */
+static int act_keyctl_revoke(int argc, char *argv[])
+{
+ key_serial_t key;
+
+ if (argc != 2)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ if (keyctl_revoke(key) < 0)
+ error("keyctl_revoke");
+
+ return 0;
+
+} /* end act_keyctl_revoke() */
+
+/*****************************************************************************/
+/*
+ * clear a keyring
+ */
+static int act_keyctl_clear(int argc, char *argv[])
+{
+ key_serial_t keyring;
+
+ if (argc != 2)
+ format();
+
+ keyring = get_key_id(argv[1]);
+
+ if (keyctl_clear(keyring) < 0)
+ error("keyctl_clear");
+
+ return 0;
+
+} /* end act_keyctl_clear() */
+
+/*****************************************************************************/
+/*
+ * link a key to a keyring
+ */
+static int act_keyctl_link(int argc, char *argv[])
+{
+ key_serial_t keyring, key;
+
+ if (argc != 3)
+ format();
+
+ key = get_key_id(argv[1]);
+ keyring = get_key_id(argv[2]);
+
+ if (keyctl_link(key, keyring) < 0)
+ error("keyctl_link");
+
+ return 0;
+
+} /* end act_keyctl_link() */
+
+/*
+ * Attempt to unlink a key matching the ID
+ */
+static int act_keyctl_unlink_func(key_serial_t parent, key_serial_t key,
+ char *desc, int desc_len, void *data)
+{
+ key_serial_t *target = data;
+
+ if (key == *target)
+ return keyctl_unlink(key, parent) < 0 ? 0 : 1;
+ return 0;
+}
+
+/*
+ * Unlink a key from a keyring or from the session keyring tree.
+ */
+static int act_keyctl_unlink(int argc, char *argv[])
+{
+ key_serial_t keyring, key;
+ int n;
+
+ if (argc != 2 && argc != 3)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ if (argc == 3) {
+ keyring = get_key_id(argv[2]);
+ if (keyctl_unlink(key, keyring) < 0)
+ error("keyctl_unlink");
+ } else {
+ n = recursive_session_key_scan(act_keyctl_unlink_func, &key);
+ printf("%d links removed\n", n);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/*
+ * search a keyring for a key
+ */
+static int act_keyctl_search(int argc, char *argv[])
+{
+ key_serial_t keyring, dest;
+ int ret;
+
+ if (argc != 4 && argc != 5)
+ format();
+
+ keyring = get_key_id(argv[1]);
+
+ dest = 0;
+ if (argc == 5)
+ dest = get_key_id(argv[4]);
+
+ ret = keyctl_search(keyring, argv[2], argv[3], dest);
+ if (ret < 0)
+ error("keyctl_search");
+
+ /* print the ID of the key we found */
+ printf("%d\n", ret);
+ return 0;
+
+} /* end act_keyctl_search() */
+
+/*****************************************************************************/
+/*
+ * read a key
+ */
+static int act_keyctl_read(int argc, char *argv[])
+{
+ key_serial_t key;
+ void *buffer;
+ char *p;
+ int ret, sep, col;
+
+ if (argc != 2)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ /* read the key payload data */
+ ret = keyctl_read_alloc(key, &buffer);
+ if (ret < 0)
+ error("keyctl_read_alloc");
+
+ if (ret == 0) {
+ printf("No data in key\n");
+ return 0;
+ }
+
+ /* hexdump the contents */
+ printf("%u bytes of data in key:\n", ret);
+
+ sep = 0;
+ col = 0;
+ p = buffer;
+
+ do {
+ if (sep) {
+ putchar(sep);
+ sep = 0;
+ }
+
+ printf("%02hhx", *p);
+ p++;
+
+ col++;
+ if (col % 32 == 0)
+ sep = '\n';
+ else if (col % 4 == 0)
+ sep = ' ';
+
+ } while (--ret > 0);
+
+ printf("\n");
+ return 0;
+
+} /* end act_keyctl_read() */
+
+/*****************************************************************************/
+/*
+ * read a key and dump raw to stdout
+ */
+static int act_keyctl_pipe(int argc, char *argv[])
+{
+ key_serial_t key;
+ void *buffer;
+ int ret;
+
+ if (argc != 2)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ /* read the key payload data */
+ ret = keyctl_read_alloc(key, &buffer);
+ if (ret < 0)
+ error("keyctl_read_alloc");
+
+ if (ret > 0 && write(1, buffer, ret) < 0)
+ error("write");
+ return 0;
+
+} /* end act_keyctl_pipe() */
+
+/*****************************************************************************/
+/*
+ * read a key and dump to stdout in printable form
+ */
+static int act_keyctl_print(int argc, char *argv[])
+{
+ key_serial_t key;
+ void *buffer;
+ char *p;
+ int loop, ret;
+
+ if (argc != 2)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ /* read the key payload data */
+ ret = keyctl_read_alloc(key, &buffer);
+ if (ret < 0)
+ error("keyctl_read_alloc");
+
+ /* see if it's printable */
+ p = buffer;
+ for (loop = ret; loop > 0; loop--, p++)
+ if (!isprint(*p))
+ goto not_printable;
+
+ /* it is */
+ printf("%s\n", (char *) buffer);
+ return 0;
+
+not_printable:
+ /* it isn't */
+ printf(":hex:");
+ p = buffer;
+ for (loop = ret; loop > 0; loop--, p++)
+ printf("%02hhx", *p);
+ printf("\n");
+ return 0;
+
+} /* end act_keyctl_print() */
+
+/*****************************************************************************/
+/*
+ * list a keyring
+ */
+static int act_keyctl_list(int argc, char *argv[])
+{
+ key_serial_t keyring, key, *pk;
+ key_perm_t perm;
+ void *keylist;
+ char *buffer, pretty_mask[9];
+ uid_t uid;
+ gid_t gid;
+ int count, tlen, dpos, n, ret;
+
+ if (argc != 2)
+ format();
+
+ keyring = get_key_id(argv[1]);
+
+ /* read the key payload data */
+ count = keyctl_read_alloc(keyring, &keylist);
+ if (count < 0)
+ error("keyctl_read_alloc");
+
+ count /= sizeof(key_serial_t);
+
+ if (count == 0) {
+ printf("keyring is empty\n");
+ return 0;
+ }
+
+ /* list the keys in the keyring */
+ if (count == 1)
+ printf("1 key in keyring:\n");
+ else
+ printf("%u keys in keyring:\n", count);
+
+ pk = keylist;
+ do {
+ key = *pk++;
+
+ ret = keyctl_describe_alloc(key, &buffer);
+ if (ret < 0) {
+ printf("%9d: key inaccessible (%m)\n", key);
+ continue;
+ }
+
+ uid = 0;
+ gid = 0;
+ perm = 0;
+
+ tlen = -1;
+ dpos = -1;
+
+ n = sscanf((char *) buffer, "%*[^;]%n;%d;%d;%x;%n",
+ &tlen, &uid, &gid, &perm, &dpos);
+ if (n != 3) {
+ fprintf(stderr, "Unparseable description obtained for key %d\n", key);
+ exit(3);
+ }
+
+ calc_perms(pretty_mask, perm, uid, gid);
+
+ printf("%9d: %s %5d %5d %*.*s: %s\n",
+ key,
+ pretty_mask,
+ uid, gid,
+ tlen, tlen, buffer,
+ buffer + dpos);
+
+ free(buffer);
+
+ } while (--count);
+
+ return 0;
+
+} /* end act_keyctl_list() */
+
+/*****************************************************************************/
+/*
+ * produce a raw list of a keyring
+ */
+static int act_keyctl_rlist(int argc, char *argv[])
+{
+ key_serial_t keyring, key, *pk;
+ void *keylist;
+ int count;
+
+ if (argc != 2)
+ format();
+
+ keyring = get_key_id(argv[1]);
+
+ /* read the key payload data */
+ count = keyctl_read_alloc(keyring, &keylist);
+ if (count < 0)
+ error("keyctl_read_alloc");
+
+ count /= sizeof(key_serial_t);
+
+ /* list the keys in the keyring */
+ if (count <= 0) {
+ printf("\n");
+ }
+ else {
+ pk = keylist;
+ for (; count > 0; count--) {
+ key = *pk++;
+ printf("%d%c", key, count == 1 ? '\n' : ' ');
+ }
+ }
+
+ return 0;
+
+} /* end act_keyctl_rlist() */
+
+/*****************************************************************************/
+/*
+ * describe a key
+ */
+static int act_keyctl_describe(int argc, char *argv[])
+{
+ key_serial_t key;
+ key_perm_t perm;
+ char *buffer;
+ uid_t uid;
+ gid_t gid;
+ int tlen, dpos, n, ret;
+
+ if (argc != 2)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ /* get key description */
+ ret = keyctl_describe_alloc(key, &buffer);
+ if (ret < 0)
+ error("keyctl_describe");
+
+ /* parse it */
+ uid = 0;
+ gid = 0;
+ perm = 0;
+
+ tlen = -1;
+ dpos = -1;
+
+ n = sscanf(buffer, "%*[^;]%n;%d;%d;%x;%n",
+ &tlen, &uid, &gid, &perm, &dpos);
+ if (n != 3) {
+ fprintf(stderr, "Unparseable description obtained for key %d\n", key);
+ exit(3);
+ }
+
+ /* display it */
+ printf("%9d:"
+ " %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c"
+ " %5d %5d %*.*s: %s\n",
+ key,
+ perm & KEY_POS_SETATTR ? 'a' : '-',
+ perm & KEY_POS_LINK ? 'l' : '-',
+ perm & KEY_POS_SEARCH ? 's' : '-',
+ perm & KEY_POS_WRITE ? 'w' : '-',
+ perm & KEY_POS_READ ? 'r' : '-',
+ perm & KEY_POS_VIEW ? 'v' : '-',
+
+ perm & KEY_USR_SETATTR ? 'a' : '-',
+ perm & KEY_USR_LINK ? 'l' : '-',
+ perm & KEY_USR_SEARCH ? 's' : '-',
+ perm & KEY_USR_WRITE ? 'w' : '-',
+ perm & KEY_USR_READ ? 'r' : '-',
+ perm & KEY_USR_VIEW ? 'v' : '-',
+
+ perm & KEY_GRP_SETATTR ? 'a' : '-',
+ perm & KEY_GRP_LINK ? 'l' : '-',
+ perm & KEY_GRP_SEARCH ? 's' : '-',
+ perm & KEY_GRP_WRITE ? 'w' : '-',
+ perm & KEY_GRP_READ ? 'r' : '-',
+ perm & KEY_GRP_VIEW ? 'v' : '-',
+
+ perm & KEY_OTH_SETATTR ? 'a' : '-',
+ perm & KEY_OTH_LINK ? 'l' : '-',
+ perm & KEY_OTH_SEARCH ? 's' : '-',
+ perm & KEY_OTH_WRITE ? 'w' : '-',
+ perm & KEY_OTH_READ ? 'r' : '-',
+ perm & KEY_OTH_VIEW ? 'v' : '-',
+ uid, gid,
+ tlen, tlen, buffer,
+ buffer + dpos);
+
+ return 0;
+
+} /* end act_keyctl_describe() */
+
+/*****************************************************************************/
+/*
+ * get raw key description
+ */
+static int act_keyctl_rdescribe(int argc, char *argv[])
+{
+ key_serial_t key;
+ char *buffer, *q;
+ int ret;
+
+ if (argc != 2 && argc != 3)
+ format();
+ if (argc == 3 && !argv[2][0])
+ format();
+
+ key = get_key_id(argv[1]);
+
+ /* get key description */
+ ret = keyctl_describe_alloc(key, &buffer);
+ if (ret < 0)
+ error("keyctl_describe");
+
+ /* replace semicolon separators with requested alternative */
+ if (argc == 3) {
+ for (q = buffer; *q; q++)
+ if (*q == ';')
+ *q = argv[2][0];
+ }
+
+ /* display raw description */
+ printf("%s\n", buffer);
+ return 0;
+
+} /* end act_keyctl_rdescribe() */
+
+/*****************************************************************************/
+/*
+ * change a key's ownership
+ */
+static int act_keyctl_chown(int argc, char *argv[])
+{
+ key_serial_t key;
+ uid_t uid;
+ char *q;
+
+ if (argc != 3)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ uid = strtoul(argv[2], &q, 0);
+ if (*q) {
+ fprintf(stderr, "Unparsable uid: '%s'\n", argv[2]);
+ exit(2);
+ }
+
+ if (keyctl_chown(key, uid, -1) < 0)
+ error("keyctl_chown");
+
+ return 0;
+
+} /* end act_keyctl_chown() */
+
+/*****************************************************************************/
+/*
+ * change a key's group ownership
+ */
+static int act_keyctl_chgrp(int argc, char *argv[])
+{
+ key_serial_t key;
+ gid_t gid;
+ char *q;
+
+ if (argc != 3)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ gid = strtoul(argv[2], &q, 0);
+ if (*q) {
+ fprintf(stderr, "Unparsable gid: '%s'\n", argv[2]);
+ exit(2);
+ }
+
+ if (keyctl_chown(key, -1, gid) < 0)
+ error("keyctl_chown");
+
+ return 0;
+
+} /* end act_keyctl_chgrp() */
+
+/*****************************************************************************/
+/*
+ * set the permissions on a key
+ */
+static int act_keyctl_setperm(int argc, char *argv[])
+{
+ key_serial_t key;
+ key_perm_t perm;
+ char *q;
+
+ if (argc != 3)
+ format();
+
+ key = get_key_id(argv[1]);
+ perm = strtoul(argv[2], &q, 0);
+ if (*q) {
+ fprintf(stderr, "Unparsable permissions: '%s'\n", argv[2]);
+ exit(2);
+ }
+
+ if (keyctl_setperm(key, perm) < 0)
+ error("keyctl_setperm");
+
+ return 0;
+
+} /* end act_keyctl_setperm() */
+
+/*****************************************************************************/
+/*
+ * start a process in a new session
+ */
+static int act_keyctl_session(int argc, char *argv[])
+{
+ char *p, *q;
+ int ret;
+
+ argv++;
+ argc--;
+
+ /* no extra arguments signifies a standard shell in an anonymous
+ * session */
+ p = NULL;
+ if (argc != 0) {
+ /* a dash signifies an anonymous session */
+ p = *argv;
+ if (strcmp(p, "-") == 0)
+ p = NULL;
+
+ argv++;
+ argc--;
+ }
+
+ /* create a new session keyring */
+ ret = keyctl_join_session_keyring(p);
+ if (ret < 0)
+ error("keyctl_join_session_keyring");
+
+ fprintf(stderr, "Joined session keyring: %d\n", ret);
+
+ /* run the standard shell if no arguments */
+ if (argc == 0) {
+ q = getenv("SHELL");
+ if (!q)
+ q = "/bin/sh";
+ execl(q, q, NULL);
+ error(q);
+ }
+
+ /* run the command specified */
+ execvp(argv[0], argv);
+ error(argv[0]);
+
+} /* end act_keyctl_session() */
+
+/*****************************************************************************/
+/*
+ * instantiate a key that's under construction
+ */
+static int act_keyctl_instantiate(int argc, char *argv[])
+{
+ key_serial_t key, dest;
+
+ if (argc != 4)
+ format();
+
+ key = get_key_id(argv[1]);
+ dest = get_key_id(argv[3]);
+
+ if (keyctl_instantiate(key, argv[2], strlen(argv[2]), dest) < 0)
+ error("keyctl_instantiate");
+
+ return 0;
+
+} /* end act_keyctl_instantiate() */
+
+/*****************************************************************************/
+/*
+ * instantiate a key, reading from a pipe
+ */
+static int act_keyctl_pinstantiate(int argc, char *argv[])
+{
+ key_serial_t key, dest;
+ size_t datalen;
+ void *data;
+
+ if (argc != 3)
+ format();
+
+ key = get_key_id(argv[1]);
+ dest = get_key_id(argv[2]);
+ data = grab_stdin(&datalen);
+
+ if (keyctl_instantiate(key, data, datalen, dest) < 0)
+ error("keyctl_instantiate");
+
+ return 0;
+
+} /* end act_keyctl_pinstantiate() */
+
+/*****************************************************************************/
+/*
+ * negate a key that's under construction
+ */
+static int act_keyctl_negate(int argc, char *argv[])
+{
+ unsigned long timeout;
+ key_serial_t key, dest;
+ char *q;
+
+ if (argc != 4)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ timeout = strtoul(argv[2], &q, 10);
+ if (*q) {
+ fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]);
+ exit(2);
+ }
+
+ dest = get_key_id(argv[3]);
+
+ if (keyctl_negate(key, timeout, dest) < 0)
+ error("keyctl_negate");
+
+ return 0;
+
+} /* end act_keyctl_negate() */
+
+/*****************************************************************************/
+/*
+ * set a key's timeout
+ */
+static int act_keyctl_timeout(int argc, char *argv[])
+{
+ unsigned long timeout;
+ key_serial_t key;
+ char *q;
+
+ if (argc != 3)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ timeout = strtoul(argv[2], &q, 10);
+ if (*q) {
+ fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]);
+ exit(2);
+ }
+
+ if (keyctl_set_timeout(key, timeout) < 0)
+ error("keyctl_set_timeout");
+
+ return 0;
+
+} /* end act_keyctl_timeout() */
+
+/*****************************************************************************/
+/*
+ * get a key's security label
+ */
+static int act_keyctl_security(int argc, char *argv[])
+{
+ key_serial_t key;
+ char *buffer;
+ int ret;
+
+ if (argc != 2)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ /* get key description */
+ ret = keyctl_get_security_alloc(key, &buffer);
+ if (ret < 0)
+ error("keyctl_getsecurity");
+
+ printf("%s\n", buffer);
+ return 0;
+}
+
+/*****************************************************************************/
+/*
+ * install a new session keyring on the parent process
+ */
+static int act_keyctl_new_session(int argc, char *argv[])
+{
+ key_serial_t keyring;
+
+ if (argc != 1)
+ format();
+
+ if (keyctl_join_session_keyring(NULL) < 0)
+ error("keyctl_join_session_keyring");
+
+ if (keyctl_session_to_parent() < 0)
+ error("keyctl_session_to_parent");
+
+ keyring = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0);
+ if (keyring < 0)
+ error("keyctl_get_keyring_ID");
+
+ /* print the resulting key ID */
+ printf("%d\n", keyring);
+ return 0;
+}
+
+/*****************************************************************************/
+/*
+ * reject a key that's under construction
+ */
+static int act_keyctl_reject(int argc, char *argv[])
+{
+ unsigned long timeout;
+ key_serial_t key, dest;
+ unsigned long rejerr;
+ char *q;
+
+ if (argc != 5)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ timeout = strtoul(argv[2], &q, 10);
+ if (*q) {
+ fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]);
+ exit(2);
+ }
+
+ if (strcmp(argv[3], "rejected") == 0) {
+ rejerr = EKEYREJECTED;
+ } else if (strcmp(argv[3], "revoked") == 0) {
+ rejerr = EKEYREVOKED;
+ } else if (strcmp(argv[3], "expired") == 0) {
+ rejerr = EKEYEXPIRED;
+ } else {
+ rejerr = strtoul(argv[3], &q, 10);
+ if (*q) {
+ fprintf(stderr, "Unparsable error: '%s'\n", argv[3]);
+ exit(2);
+ }
+ }
+
+ dest = get_key_id(argv[4]);
+
+ if (keyctl_reject(key, timeout, rejerr, dest) < 0)
+ error("keyctl_negate");
+
+ return 0;
+}
+
+/*
+ * Attempt to unlink a key if we can't read it for reasons other than we don't
+ * have permission
+ */
+static int act_keyctl_reap_func(key_serial_t parent, key_serial_t key,
+ char *desc, int desc_len, void *data)
+{
+ if (desc_len < 0 && errno != EACCES) {
+ if (verbose)
+ printf("Reap %d", key);
+ if (keyctl_unlink(key, parent) < 0) {
+ if (verbose)
+ printf("... failed %m\n");
+ return 0;
+ } else {
+ if (verbose)
+ printf("\n");
+ return 1;
+ };
+ }
+ return 0;
+}
+
+/*
+ * Reap the dead keys from the session keyring tree
+ */
+static int act_keyctl_reap(int argc, char *argv[])
+{
+ int n;
+
+ if (argc > 1 && strcmp(argv[1], "-v") == 0) {
+ verbose = 1;
+ argc--;
+ argv++;
+ }
+
+ if (argc != 1)
+ format();
+
+ n = recursive_session_key_scan(act_keyctl_reap_func, NULL);
+ printf("%d keys reaped\n", n);
+ return 0;
+}
+
+struct purge_data {
+ const char *type;
+ const char *desc;
+ size_t desc_len;
+ size_t type_len;
+ char prefix_match;
+ char case_indep;
+};
+
+/*
+ * Attempt to unlink a key matching the type
+ */
+static int act_keyctl_purge_type_func(key_serial_t parent, key_serial_t key,
+ char *raw, int raw_len, void *data)
+{
+ const struct purge_data *purge = data;
+ char *p, *type;
+
+ if (parent == 0 || !raw)
+ return 0;
+
+ /* type is everything before the first semicolon */
+ type = raw;
+ p = memchr(raw, ';', raw_len);
+ if (!p)
+ return 0;
+ *p = 0;
+ if (strcmp(type, purge->type) != 0)
+ return 0;
+
+ return keyctl_unlink(key, parent) < 0 ? 0 : 1;
+}
+
+/*
+ * Attempt to unlink a key matching the type and description literally
+ */
+static int act_keyctl_purge_literal_func(key_serial_t parent, key_serial_t key,
+ char *raw, int raw_len, void *data)
+{
+ const struct purge_data *purge = data;
+ size_t tlen;
+ char *p, *type, *desc;
+
+ if (parent == 0 || !raw)
+ return 0;
+
+ /* type is everything before the first semicolon */
+ type = raw;
+ p = memchr(type, ';', raw_len);
+ if (!p)
+ return 0;
+
+ tlen = p - type;
+ if (tlen != purge->type_len)
+ return 0;
+ if (memcmp(type, purge->type, tlen) != 0)
+ return 0;
+
+ /* description is everything after the last semicolon */
+ p++;
+ desc = memrchr(p, ';', raw + raw_len - p);
+ if (!desc)
+ return 0;
+ desc++;
+
+ if (purge->prefix_match) {
+ if (raw_len - (desc - raw) < purge->desc_len)
+ return 0;
+ } else {
+ if (raw_len - (desc - raw) != purge->desc_len)
+ return 0;
+ }
+
+ if (purge->case_indep) {
+ if (strncasecmp(purge->desc, desc, purge->desc_len) != 0)
+ return 0;
+ } else {
+ if (memcmp(purge->desc, desc, purge->desc_len) != 0)
+ return 0;
+ }
+
+ printf("%*.*s '%s'\n", (int)tlen, (int)tlen, type, desc);
+
+ return keyctl_unlink(key, parent) < 0 ? 0 : 1;
+}
+
+/*
+ * Attempt to unlink a key matching the type and description literally
+ */
+static int act_keyctl_purge_search_func(key_serial_t parent, key_serial_t keyring,
+ char *raw, int raw_len, void *data)
+{
+ const struct purge_data *purge = data;
+ key_serial_t key;
+ int kcount = 0;
+
+ if (!raw || memcmp(raw, "keyring;", 8) != 0)
+ return 0;
+
+ for (;;) {
+ key = keyctl_search(keyring, purge->type, purge->desc, 0);
+ if (keyctl_unlink(key, keyring) < 0)
+ return kcount;
+ kcount++;
+ }
+ return kcount;
+}
+
+/*
+ * Purge matching keys from a keyring
+ */
+static int act_keyctl_purge(int argc, char *argv[])
+{
+ recursive_key_scanner_t func;
+ struct purge_data purge = {
+ .prefix_match = 0,
+ .case_indep = 0,
+ };
+ int n = 0, search_mode = 0;
+
+ argc--;
+ argv++;
+ while (argc > 0 && argv[0][0] == '-') {
+ if (argv[0][1] == 's')
+ search_mode = 1;
+ else if (argv[0][1] == 'p')
+ purge.prefix_match = 1;
+ else if (argv[0][1] == 'i')
+ purge.case_indep = 1;
+ else
+ format();
+ argc--;
+ argv++;
+ }
+
+ if (argc < 1)
+ format();
+
+ purge.type = argv[0];
+ purge.desc = argv[1];
+ purge.type_len = strlen(purge.type);
+ purge.desc_len = purge.desc ? strlen(purge.desc) : 0;
+
+ if (search_mode == 1) {
+ if (argc != 2 || purge.prefix_match || purge.case_indep)
+ format();
+ /* purge all keys of a specific type and description, according
+ * to the kernel's comparator */
+ func = act_keyctl_purge_search_func;
+ } else if (argc == 1) {
+ if (purge.prefix_match || purge.case_indep)
+ format();
+ /* purge all keys of a specific type */
+ func = act_keyctl_purge_type_func;
+ } else if (argc == 2) {
+ /* purge all keys of a specific type with literally matching
+ * description */
+ func = act_keyctl_purge_literal_func;
+ } else {
+ format();
+ }
+
+ n = recursive_session_key_scan(func, &purge);
+ printf("purged %d keys\n", n);
+ return 0;
+}
+
+/*****************************************************************************/
+/*
+ * Invalidate a key
+ */
+static int act_keyctl_invalidate(int argc, char *argv[])
+{
+ key_serial_t key;
+
+ if (argc != 2)
+ format();
+
+ key = get_key_id(argv[1]);
+
+ if (keyctl_invalidate(key) < 0)
+ error("keyctl_invalidate");
+
+ return 0;
+}
+
+/*****************************************************************************/
+/*
+ * parse a key identifier
+ */
+static key_serial_t get_key_id(const char *arg)
+{
+ key_serial_t id;
+ char *end;
+
+ /* handle a special keyring name */
+ if (arg[0] == '@') {
+ if (strcmp(arg, "@t" ) == 0) return KEY_SPEC_THREAD_KEYRING;
+ if (strcmp(arg, "@p" ) == 0) return KEY_SPEC_PROCESS_KEYRING;
+ if (strcmp(arg, "@s" ) == 0) return KEY_SPEC_SESSION_KEYRING;
+ if (strcmp(arg, "@u" ) == 0) return KEY_SPEC_USER_KEYRING;
+ if (strcmp(arg, "@us") == 0) return KEY_SPEC_USER_SESSION_KEYRING;
+ if (strcmp(arg, "@g" ) == 0) return KEY_SPEC_GROUP_KEYRING;
+ if (strcmp(arg, "@a" ) == 0) return KEY_SPEC_REQKEY_AUTH_KEY;
+
+ fprintf(stderr, "Unknown special key: '%s'\n", arg);
+ exit(2);
+ }
+
+ /* handle a numeric key ID */
+ id = strtoul(arg, &end, 0);
+ if (*end) {
+ fprintf(stderr, "Unparsable key: '%s'\n", arg);
+ exit(2);
+ }
+
+ return id;
+
+} /* end get_key_id() */
+
+/*****************************************************************************/
+/*
+ * recursively display a key/keyring tree
+ */
+static int dump_key_tree_aux(key_serial_t key, int depth, int more, int hex_key_IDs)
+{
+ static char dumpindent[64];
+ key_serial_t *pk;
+ key_perm_t perm;
+ size_t ringlen, desclen;
+ void *payload;
+ char *desc, type[255], pretty_mask[9];
+ int uid, gid, ret, n, dpos, rdepth, kcount = 0;
+
+ if (depth > 8 * 4)
+ return 0;
+
+ /* find out how big this key's description is */
+ ret = keyctl_describe(key, NULL, 0);
+ if (ret < 0) {
+ printf("%d: key inaccessible (%m)\n", key);
+ return 0;
+ }
+ desclen = ret + 1;
+
+ desc = malloc(desclen);
+ if (!desc)
+ error("malloc");
+
+ /* read the description */
+ ret = keyctl_describe(key, desc, desclen);
+ if (ret < 0) {
+ printf("%d: key inaccessible (%m)\n", key);
+ free(desc);
+ return 0;
+ }
+
+ desclen = ret < desclen ? ret : desclen;
+
+ desc[desclen] = 0;
+
+ /* parse */
+ type[0] = 0;
+ uid = 0;
+ gid = 0;
+ perm = 0;
+
+ n = sscanf(desc, "%[^;];%d;%d;%x;%n",
+ type, &uid, &gid, &perm, &dpos);
+
+ if (n != 4) {
+ fprintf(stderr, "Unparseable description obtained for key %d\n", key);
+ exit(3);
+ }
+
+ /* and print */
+ calc_perms(pretty_mask, perm, uid, gid);
+
+ if (hex_key_IDs)
+ printf("0x%08x %s %5d %5d %s%s%s: %s\n",
+ key,
+ pretty_mask,
+ uid, gid,
+ dumpindent,
+ depth > 0 ? "\\_ " : "",
+ type, desc + dpos);
+ else
+ printf("%10d %s %5d %5d %s%s%s: %s\n",
+ key,
+ pretty_mask,
+ uid, gid,
+ dumpindent,
+ depth > 0 ? "\\_ " : "",
+ type, desc + dpos);
+
+ /* if it's a keyring then we're going to want to recursively
+ * display it if we can */
+ if (strcmp(type, "keyring") == 0) {
+ /* find out how big the keyring is */
+ ret = keyctl_read(key, NULL, 0);
+ if (ret < 0)
+ error("keyctl_read");
+ if (ret == 0)
+ return 0;
+ ringlen = ret;
+
+ /* read its contents */
+ payload = malloc(ringlen);
+ if (!payload)
+ error("malloc");
+
+ ret = keyctl_read(key, payload, ringlen);
+ if (ret < 0)
+ error("keyctl_read");
+
+ ringlen = ret < ringlen ? ret : ringlen;
+ kcount = ringlen / sizeof(key_serial_t);
+
+ /* walk the keyring */
+ pk = payload;
+ do {
+ key = *pk++;
+
+ /* recurse into nexted keyrings */
+ if (strcmp(type, "keyring") == 0) {
+ if (depth == 0) {
+ rdepth = depth;
+ dumpindent[rdepth++] = ' ';
+ dumpindent[rdepth] = 0;
+ }
+ else {
+ rdepth = depth;
+ dumpindent[rdepth++] = ' ';
+ dumpindent[rdepth++] = ' ';
+ dumpindent[rdepth++] = ' ';
+ dumpindent[rdepth++] = ' ';
+ dumpindent[rdepth] = 0;
+ }
+
+ if (more)
+ dumpindent[depth + 0] = '|';
+
+ kcount += dump_key_tree_aux(key,
+ rdepth,
+ ringlen - 4 >= sizeof(key_serial_t),
+ hex_key_IDs);
+ }
+
+ } while (ringlen -= 4, ringlen >= sizeof(key_serial_t));
+
+ free(payload);
+ }
+
+ free(desc);
+ return kcount;
+
+} /* end dump_key_tree_aux() */
+
+/*****************************************************************************/
+/*
+ * recursively list a keyring's contents
+ */
+static int dump_key_tree(key_serial_t keyring, const char *name, int hex_key_IDs)
+{
+ printf("%s\n", name);
+
+ keyring = keyctl_get_keyring_ID(keyring, 0);
+ if (keyring == -1)
+ error("Unable to dump key");
+
+ return dump_key_tree_aux(keyring, 0, 0, hex_key_IDs);
+
+} /* end dump_key_tree() */
diff --git a/keyutils-1.5.6/keyctl_chown.3 b/keyutils-1.5.6/keyctl_chown.3
new file mode 100644
index 0000000..2492ec1
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_chown.3
@@ -0,0 +1,88 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_CHOWN 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_chown \- Change the ownership of a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_chown(key_serial_t " key ", uid_t " uid ", gid_t " gid ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_chown ()
+changes the user and group ownership details of a key.
+.P
+A setting of
+.B -1
+on either
+.I uid
+or
+.I gid
+will cause that setting to be ignored.
+.P
+A process that does not have the
+.B SysAdmin
+capability may not change a key's UID or set the key's GID to a value that
+does not match the process's GID or one of its group list.
+.P
+The caller must have
+.B setattr
+permission on a key to be able change its ownership.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_chown ()
+returns
+.B 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The specified key does not exist.
+.TP
+.B EKEYEXPIRED
+The specified key has expired.
+.TP
+.B EKEYREVOKED
+The specified key has been revoked.
+.TP
+.B EDQUOT
+Changing the UID to the one specified would run that UID out of quota.
+.TP
+.B EACCES
+The key exists, but does not grant
+.B setattr
+permission to the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_clear.3 b/keyutils-1.5.6/keyctl_clear.3
new file mode 100644
index 0000000..87e543e
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_clear.3
@@ -0,0 +1,73 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_CLEAR 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_clear \- Clear a keyring
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_clear(key_serial_t " keyring ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_clear ()
+clears the contents of a
+.IR keyring .
+.P
+The caller must have
+.B write
+permission on a keyring to be able clear it.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_clear ()
+returns
+.BR 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The keyring specified is invalid.
+.TP
+.B EKEYEXPIRED
+The keyring specified has expired.
+.TP
+.B EKEYREVOKED
+The keyring specified had been revoked.
+.TP
+.B EACCES
+The keyring exists, but is not
+.B writable
+by the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_describe.3 b/keyutils-1.5.6/keyctl_describe.3
new file mode 100644
index 0000000..e125ab8
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_describe.3
@@ -0,0 +1,110 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_DESCRIBE 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_describe \- Describe a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_describe(key_serial_t " key ", char *" buffer ,
+.BI "size_t" buflen ");"
+.sp
+.BI "long keyctl_describe_alloc(key_serial_t " key ", char **" _buffer ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_describe ()
+describes the attributes of a key as a NUL-terminated string.
+.P
+The caller must have
+.B view
+permission on a key to be able to get a description of it.
+.P
+.I buffer
+and
+.I buflen
+specify the buffer into which the key description will be placed. If the
+buffer is too small, the full size of the description will be returned, and no
+copy will take place.
+.P
+.BR keyctl_describe_alloc ()
+is similar to
+.BR keyctl_describe ()
+except that it allocates a buffer big enough to hold the description and
+places the description in it. If successful, A pointer to the buffer is
+placed in
+.IR *_buffer .
+The caller must free the buffer.
+.P
+The description will be a string of format:
+.IP
+.B "\*(lq%s;%d;%d;%08x;%s\*(rq"
+.P
+where the arguments are: key type name, key UID, key GID, key permissions mask
+and key description.
+.P
+.B NOTE!
+The key description will not contain any semicolons, so that should be
+separated out by working backwards from the end of the string. This permits
+extra information to be inserted before it by later versions of the kernel
+simply by inserting more semicolon-terminated substrings.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_describe ()
+returns the amount of data placed into the buffer. If the buffer was too
+small, then the size of buffer required will be returned, but no data will be
+transferred. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.P
+On success
+.BR keyctl_describe_alloc ()
+returns the amount of data in the buffer, less the NUL terminator. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The key specified is invalid.
+.TP
+.B EKEYEXPIRED
+The key specified has expired.
+.TP
+.B EKEYREVOKED
+The key specified had been revoked.
+.TP
+.B EACCES
+The key exists, but is not
+.B viewable
+by the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_get_keyring_ID.3 b/keyutils-1.5.6/keyctl_get_keyring_ID.3
new file mode 100644
index 0000000..be9660d
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_get_keyring_ID.3
@@ -0,0 +1,96 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_GET_KEYRING_ID 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_get_keyring_ID \- Get the ID of a special keyring
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "key_serial_t keyctl_get_keyring_ID(key_serial_t " key ","
+.BI " int " create ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_get_keyring_ID ()
+maps a special
+.I key
+or keyring ID to the serial number of the key actually representing that
+feature. The serial number will be returned if that key exists.
+.P
+If the key or keyring does not yet exist, then if
+.I create
+is non-zero, the key or keyring will be created if it is appropriate to do so.
+.P
+The following special key IDs may be specified as
+.IR key :
+.TP
+.B KEY_SPEC_THREAD_KEYRING
+This specifies the caller's thread-specific keyring.
+.TP
+.B KEY_SPEC_PROCESS_KEYRING
+This specifies the caller's process-specific keyring.
+.TP
+.B KEY_SPEC_SESSION_KEYRING
+This specifies the caller's session-specific keyring.
+.TP
+.B KEY_SPEC_USER_KEYRING
+This specifies the caller's UID-specific keyring.
+.TP
+.B KEY_SPEC_USER_SESSION_KEYRING
+This specifies the caller's UID-session keyring.
+.TP
+.B KEY_SPEC_REQKEY_AUTH_KEY
+This specifies the authorisation key created by
+.BR request_key ()
+and passed to the process it spawns to generate a key.
+.P
+If a valid keyring ID is passed in, then this will simply be returned if the
+key exists; an error will be issued if it doesn't exist.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_get_keyring_ID ()
+returns the serial number of the key it found. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+No matching key was found.
+.TP
+.B ENOMEM
+Insufficient memory to create a key.
+.TP
+.B EDQUOT
+The key quota for this user would be exceeded by creating this key or linking
+it to the keyring.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_get_security.3 b/keyutils-1.5.6/keyctl_get_security.3
new file mode 100644
index 0000000..f9a3c84
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_get_security.3
@@ -0,0 +1,100 @@
+.\"
+.\" Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_GET_SECURITY 3 "26 Feb 2010" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_get_security \- Retrieve a key's security context
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_get_security(key_serial_t " key ", char *" buffer ,
+.BI "size_t " buflen ");"
+.sp
+.BI "long keyctl_get_security_alloc(key_serial_t " key ", char **" _buffer ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_get_security ()
+retrieves the security context of a key as a NUL-terminated string. This will
+be rendered in a form appropriate to the LSM in force - for instance, with
+SELinux, it may look like
+.IP
+.B "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023"
+.P
+The caller must have
+.B view
+permission on a key to be able to get its security context.
+.P
+.I buffer
+and
+.I buflen
+specify the buffer into which the string will be placed. If the buffer is too
+small, the full size of the string will be returned, and no copy will take
+place.
+.P
+.BR keyctl_get_security_alloc ()
+is similar to
+.BR keyctl_get_security ()
+except that it allocates a buffer big enough to hold the string and copies the
+string into it. If successful, A pointer to the buffer is placed in
+.IR *_buffer .
+The caller must free the buffer.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_get_security ()
+returns the amount of data placed into the buffer. If the buffer was too
+small, then the size of buffer required will be returned, but no data will be
+transferred. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.P
+On success
+.BR keyctl_get_security_alloc ()
+returns the amount of data in the buffer, less the NUL terminator. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The key specified is invalid.
+.TP
+.B EKEYEXPIRED
+The key specified has expired.
+.TP
+.B EKEYREVOKED
+The key specified had been revoked.
+.TP
+.B EACCES
+The key exists, but is not
+.B viewable
+by the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_instantiate.3 b/keyutils-1.5.6/keyctl_instantiate.3
new file mode 100644
index 0000000..7da0b8c
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_instantiate.3
@@ -0,0 +1,192 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_INSTANTIATE 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_assume_authority \- Assume the authority to instantiate a key
+.br
+keyctl_instantiate \- Instantiate a key from flat data
+.br
+keyctl_instantiate_iov \- Instantiate a key from segmented data
+.br
+keyctl_reject \- Negatively instantiate a key specifying search error
+.br
+keyctl_negate \- Negatively instantiate a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_assume_authority(key_serial_t " key ");"
+.sp
+.BI "long keyctl_instantiate(key_serial_t " key ", const void *" payload ,
+.BI "size_t " plen ", key_serial_t " keyring ");"
+.sp
+.BI "long keyctl_instantiate_iov(key_serial_t " key ,
+.BI "const struct iovec *" payload_iov ", unsigned " ioc ,
+.BI "key_serial_t " keyring ");"
+.sp
+.BI "long keyctl_negate(key_serial_t " key ", unsigned " timeout ,
+.BI "key_serial_t " keyring ");"
+.sp
+.BI "long keyctl_reject(key_serial_t " key ", unsigned " timeout ,
+.BI "unsigned " error ", key_serial_t " keyring ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_assume_authority ()
+assumes the authority for the calling thread to deal with and instantiate the
+specified uninstantiated
+.IR key .
+.P
+The calling thread must have the appopriate authorisation key resident in one
+of its keyrings for this to succeed, and that authority must not have been
+revoked.
+.P
+The authorising key is allocated by request_key() when it needs to invoke
+userspace to generate a key for the requesting process. This is then attached
+to one of the keyrings of the userspace process to which the task of
+instantiating the key is given:
+.IP
+requester -> request_key() -> instantiator
+.P
+Calling this function modifies the way
+.BR request_key ()
+works when called thereafter by the calling (instantiator) thread; once the
+authority is assumed, the keyrings of the initial process are added to the
+search path, using the initial process's UID, GID, groups and security
+context.
+.P
+If a thread has multiple instantiations to deal with, it may call this
+function to change the authorisation key currently in effect. Supplying a
+.B zero
+.I key
+de-assumes the currently assumed authority.
+.P
+.B NOTE!
+This is a per-thread setting and not a per-process setting so that a
+multithreaded process can be used to instantiate several keys at once.
+.P
+.BR keyctl_instantiate ()
+instantiates the payload of an uninstantiated key from the data specified.
+.I payload
+and
+.I plen
+specify the data for the new payload.
+.I payload
+may be NULL and
+.I plen
+may be zero if the key type permits that. The key type may reject the data if
+it's in the wrong format or in some other way invalid.
+.P
+.BR keyctl_instantiate_iov ()
+is similar, but the data is passed in an array of iovec structs instead of in
+a flat buffer.
+.I payload_iov
+points to the base of the array and
+.I ioc
+indicates how many elements there are.
+.I payload_iov
+may be NULL or
+.I ioc
+may be zero to indicate that no data is being supplied.
+.P
+.BR keyctl_reject ()
+marks a key as negatively instantiated and sets the expiration timer on it.
+.I timeout
+specifies the lifetime of the key in seconds.
+.I error
+specifies the error to be returned when a search hits the key (this is
+typically
+.IR EKEYREJECTED ", " EKEYREVOKED " or " EKEYEXPIRED ")."
+Note that keyctl_reject() falls back to keyctl_negate() if the kernel does not
+support it.
+.P
+.BR keyctl_negate ()
+as
+.IR keyctl_reject ()
+with an error code of
+.IB ENOKEY .
+.P
+Only a key for which authority has been assumed may be instantiated or
+negatively instantiated, and once instantiated, the authorisation key will be
+revoked and the requesting process will be able to resume.
+.P
+The destination
+.IR keyring ,
+if given, is assumed to belong to the initial requester, and not the
+instantiating process. Therefore, the special keyring IDs refer to the
+requesting process's keyrings, not the caller's, and the requester's UID,
+etc. will be used to access them.
+.P
+The destination keyring can be
+.B zero
+if no extra link is desired.
+.P
+The requester, not the caller, must have
+.B write
+permission on the destination for a link to be made there.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_instantiate ()
+returns
+.BR 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The key or keyring specified is invalid.
+.TP
+.B EKEYEXPIRED
+The keyring specified has expired.
+.TP
+.B EKEYREVOKED
+The key or keyring specified had been revoked, or the authorisation has been
+revoked.
+.TP
+.B EINVAL
+The payload data was invalid.
+.TP
+.B ENOMEM
+Insufficient memory to store the new payload or to expand the destination
+keyring.
+.TP
+.B EDQUOT
+The key quota for the key's user would be exceeded by increasing the size of
+the key to accommodate the new payload or the key quota for the keyring's user
+would be exceeded by expanding the destination keyring.
+.TP
+.B EACCES
+The key exists, but is not
+.B writable
+by the requester.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_invalidate.3 b/keyutils-1.5.6/keyctl_invalidate.3
new file mode 100644
index 0000000..7afb70c
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_invalidate.3
@@ -0,0 +1,76 @@
+.\"
+.\" Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_INVALIDATE 3 "29 Aug 2013" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_invalidate \- Invalidate a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_invalidate(key_serial_t " key ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_invalidate ()
+invalidates a
+.IR key .
+The key is scheduled for immediate removal from all the keyrings that point to
+it, after which it will be deleted. The key will be ignored by all searches
+once this function is called even if it is not yet fully dealt with.
+.P
+The caller must have
+.B search
+permission on a key to be able to invalidate it.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_invalidate ()
+returns
+.BR 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The key specified is invalid.
+.TP
+.B EKEYEXPIRED
+The key specified has expired.
+.TP
+.B EKEYREVOKED
+The key specified had been revoked.
+.TP
+.B EACCES
+The key exists, but is not
+.B searchable
+by the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_join_session_keyring.3 b/keyutils-1.5.6/keyctl_join_session_keyring.3
new file mode 100644
index 0000000..ffbb805
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_join_session_keyring.3
@@ -0,0 +1,82 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_JOIN_SESSION_KEYRING 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_join_session_keyring \- Join a different session keyring
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "key_serial_t keyctl_join_session_keyring(const char *" name ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_join_session_keyring ()
+changes the session keyring to which a process is subscribed.
+.P
+If
+.I name
+is
+.B NULL
+then a new anonymous keyring will be created, and the process will be
+subscribed to that.
+.P
+If
+.I name
+points to a string, then if a keyring of that name is available, the process
+will attempt to subscribe to that keyring, giving an error if that is not
+permitted; otherwise a new keyring of that name is created and attached as the
+session keyring.
+.P
+To attach to an extant named keyring, the keyring must have
+.B search
+permission available to the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_join_session_keyring ()
+returns the serial number of the key it found or created. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOMEM
+Insufficient memory to create a key.
+.TP
+.B EDQUOT
+The key quota for this user would be exceeded by creating this key or linking
+it to the keyring.
+.TP
+.B EACCES
+The named keyring exists, but is not
+.B searchable
+by the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_link.3 b/keyutils-1.5.6/keyctl_link.3
new file mode 100644
index 0000000..f62549e
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_link.3
@@ -0,0 +1,108 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_LINK 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_link \- Link a key to a keyring
+keyctl_unlink \- Unlink a key from a keyring
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_link(key_serial_t " key ", key_serial_t " keyring ");"
+.sp
+.BI "long keyctl_unlink(key_serial_t " key ", key_serial_t " keyring ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_link ()
+creates a link from
+.I keyring
+to
+.IR key ,
+displacing any link to another key of the same type and description in that
+keyring if one exists.
+.P
+.BR keyctl_unlink ()
+removes the link from
+.I keyring
+to
+.I key
+if it exists.
+.P
+The caller must have
+.B write
+permission on a keyring to be able create or remove links in it.
+.P
+The caller must have
+.B link
+permission on a key to be able to create a link to it.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_link ()
+and
+.BR keyctl_unlink ()
+return
+.BR 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The key or the keyring specified are invalid.
+.TP
+.B EKEYEXPIRED
+The key or the keyring specified have expired.
+.TP
+.B EKEYREVOKED
+The key or the keyring specified have been revoked.
+.TP
+.B EACCES
+The keyring exists, but is not
+.B writable
+by the calling process.
+.P
+For
+.BR keyctl_link ()
+only:
+.TP
+.B ENOMEM
+Insufficient memory to expand the keyring
+.TP
+.B EDQUOT
+Expanding the keyring would exceed the keyring owner's quota.
+.TP
+.B EACCES
+The key exists, but is not
+.B linkable
+by the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_read.3 b/keyutils-1.5.6/keyctl_read.3
new file mode 100644
index 0000000..01905e5
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_read.3
@@ -0,0 +1,109 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_READ 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_read \- Read a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_read(key_serial_t " key ", char *" buffer ,
+.BI "size_t" buflen ");"
+.sp
+.BI "long keyctl_read_alloc(key_serial_t " key ", void **" _buffer ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_read ()
+reads the payload of a key if the key type supports it.
+.P
+The caller must have
+.B read
+permission on a key to be able to read it.
+.P
+.I buffer
+and
+.I buflen
+specify the buffer into which the payload data will be placed. If the buffer
+is too small, the full size of the payload will be returned, and no copy will
+take place.
+.P
+.BR keyctl_read_alloc ()
+is similar to
+.BR keyctl_read ()
+except that it allocates a buffer big enough to hold the payload data and
+places the data in it. If successful, A pointer to the buffer is placed in
+.IR *_buffer .
+The caller must free the buffer.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH READING KEYRINGS
+This call can be used to list the contents of a keyring. The data is
+presented to the user as an array of
+.B key_serial_t
+values, each of which corresponds to a key to which the keyring holds a link.
+.P
+The size of the keyring will be sizeof(key_serial_t) multiplied by the number
+of keys. The size of key_serial_t is invariant across different word sizes,
+though the byte-ordering is as appropriate for the kernel.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_read ()
+returns the amount of data placed into the buffer. If the buffer was too
+small, then the size of buffer required will be returned, but no data will be
+transferred. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.P
+On success
+.BR keyctl_read_alloc ()
+returns the amount of data in the buffer. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The key specified is invalid.
+.TP
+.B EKEYEXPIRED
+The key specified has expired.
+.TP
+.B EKEYREVOKED
+The key specified had been revoked.
+.TP
+.B EACCES
+The key exists, but is not
+.B readable
+by the calling process.
+.TP
+.B EOPNOTSUPP
+The key type does not support reading of the payload data.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_revoke.3 b/keyutils-1.5.6/keyctl_revoke.3
new file mode 100644
index 0000000..212c776
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_revoke.3
@@ -0,0 +1,73 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_REVOKE 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_revoke \- Revoke a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_revoke(key_serial_t " key ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_revoke ()
+marks a key as being revoked.
+.P
+After this operation has been performed on a key, attempts to access it will
+meet with error
+.BR EKEYREVOKED .
+.P
+The caller must have
+.B write
+permission on a key to be able revoke it.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_revoke ()
+returns
+.BR 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The specified key does not exist.
+.TP
+.B EKEYREVOKED
+The key has already been revoked.
+.TP
+.B EACCES
+The named key exists, but is not
+.B writable
+by the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_search.3 b/keyutils-1.5.6/keyctl_search.3
new file mode 100644
index 0000000..368584c
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_search.3
@@ -0,0 +1,138 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_SEARCH 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_search \- Search a keyring for a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_search(key_serial_t " keyring ", const char *" type ,
+.BI "const char *" description ", key_serial_t " destination ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_search ()
+recursively searches the
+.I keyring
+for a key of the specified
+.I type
+and
+.IR description .
+.P
+If found, the key will be attached to the
+.I destination
+keyring (if given), and its serial number will be returned.
+.P
+The source keyring must grant
+.B search
+permission to the caller, and for a key to be found, it must also grant
+.B search
+permission to the caller. Child keyrings will be only be recursively searched
+if they grant
+.B search
+permission to the caller as well.
+.P
+If the destination keyring is
+.BR zero ,
+no attempt will be made to forge a link to the key, and just the serial number
+will be returned.
+.P
+If the destination keyring is given, then the link may only be formed if the
+found key grants the caller
+.B link
+permission and the destination keyring grants the caller
+.B write
+permission.
+.P
+If the search is successful, and if the destination keyring already contains a
+link to a key that matches the specified
+.IR type " and " description ,
+then that link will be replaced by a link to the found key.
+.P
+The source keyring and destination keyring serial numbers may be those of
+valid keyrings to which the caller has appropriate permission, or they may be
+special keyring IDs:
+.TP
+.B KEY_SPEC_THREAD_KEYRING
+This specifies the caller's thread-specific keyring.
+.TP
+.B KEY_SPEC_PROCESS_KEYRING
+This specifies the caller's process-specific keyring.
+.TP
+.B KEY_SPEC_SESSION_KEYRING
+This specifies the caller's session-specific keyring.
+.TP
+.B KEY_SPEC_USER_KEYRING
+This specifies the caller's UID-specific keyring.
+.TP
+.B KEY_SPEC_USER_SESSION_KEYRING
+This specifies the caller's UID-session keyring.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_search ()
+returns the serial number of the key it found. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+One of the keyrings doesn't exist, no key was found by the search, or the only
+key found by the search was a negative key.
+.TP
+.B ENOTDIR
+One of the keyrings is a valid key that isn't a keyring.
+.TP
+.B EKEYEXPIRED
+One of the keyrings has expired, or the only key found was expired.
+.TP
+.B EKEYREVOKED
+One of the keyrings has been revoked, or the only key found was revoked.
+.TP
+.B ENOMEM
+Insufficient memory to expand the destination keyring.
+.TP
+.B EDQUOT
+The key quota for this user would be exceeded by creating a link to the found
+key in the destination keyring.
+.TP
+.B EACCES
+The source keyring didn't grant
+.B search
+permission, the destination keyring didn't grant
+.B write
+permission or the found key didn't grant
+.B link
+permission to the caller.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+Although this is a Linux system call, it is not present in
+.I libc
+but can be found rather in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_session_to_parent.3 b/keyutils-1.5.6/keyctl_session_to_parent.3
new file mode 100644
index 0000000..a0da527
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_session_to_parent.3
@@ -0,0 +1,75 @@
+.\"
+.\" Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_SESSION_TO_PARENT 3 "26 Jun 2010" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_session_to_parent \- Set the parent process's session keyring
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_session_to_parent();"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_session_to_parent ()
+changes the session keyring to which the calling process's parent subscribes
+to be the that of the calling process.
+.P
+The keyring must have
+.B link
+permission available to the calling process, the parent process must have the
+same UIDs/GIDs as the calling process, and the LSM must not reject the
+replacement. Furthermore, this may not be used to affect init or a kernel
+thread.
+.P
+Note that the replacement will not take immediate effect upon the parent
+process, but will rather be deferred to the next time it returns to userspace
+from kernel space.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_session_to_parent ()
+returns 0. On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOMEM
+Insufficient memory to create a key.
+.TP
+.B EPERM
+The credentials of the parent don't match those of the caller.
+.TP
+.B EACCES
+The named keyring exists, but is not
+.B linkable
+by the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_set_reqkey_keyring.3 b/keyutils-1.5.6/keyctl_set_reqkey_keyring.3
new file mode 100644
index 0000000..fc5946e
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_set_reqkey_keyring.3
@@ -0,0 +1,98 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_SET_REQKEY_KEYRING 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_set_reqkey_keyring \- Set the implicit destination keyring
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_set_reqkey_keyring(int " reqkey_defl ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_set_reqkey_keyring ()
+sets the default destination for implicit key requests for the current thread
+and returns the old setting.
+.P
+After this operation has been issued, keys acquired by implicit key requests,
+such as might be performed by open() on an AFS or NFS filesystem, will be
+linked by default to the specified keyring by this function.
+.P
+The valid values of
+.I reqkey_defl
+are:
+.TP
+.B KEY_REQKEY_DEFL_NO_CHANGE
+This makes no change to the current setting.
+.TP
+.B KEY_REQKEY_DEFL_THREAD_KEYRING
+This makes the thread-specific keyring the default destination.
+.TP
+.B KEY_REQKEY_DEFL_PROCESS_KEYRING
+This makes the process-specific keyring the default destination.
+.TP
+.B KEY_REQKEY_DEFL_SESSION_KEYRING
+This makes the session keyring the default destination.
+.TP
+.B KEY_REQKEY_DEFL_USER_KEYRING
+This makes the UID-specific keyring the default destination.
+.TP
+.B KEY_REQKEY_DEFL_USER_SESSION_KEYRING
+This makes the UID-specific session keyring the default destination.
+.TP
+.B KEY_REQKEY_DEFL_DEFAULT
+This selects the default behaviour which is to use the thread-specific keyring
+if there is one, otherwise the process-specific keyring if there is one,
+otherwise the session keyring if there is one, otherwise the UID-specific
+session keyring.
+.P
+This setting is inherited across
+.BR fork ()
+and
+.BR exec ().
+
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_set_reqkey_keyring ()
+returns
+.BR 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B EINVAL
+The value of
+.I reqkey_defl
+is invalid.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_set_timeout.3 b/keyutils-1.5.6/keyctl_set_timeout.3
new file mode 100644
index 0000000..6d6e774
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_set_timeout.3
@@ -0,0 +1,81 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_SET_TIMEOUT 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_set_timeout \- Set the expiration timer on a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_set_timeout(key_serial_t " key ", unsigned " timeout ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_set_timeout ()
+sets the expiration timer on a key to
+.I timeout
+seconds into the future. Setting
+.I timeout
+to
+.B zero
+cancels the expiration, assuming the key hasn't already expired.
+.P
+When the key expires, further attempts to access it will be met with error
+.BR EKEYEXPIRED .
+.P
+The caller must have
+.B setattr
+permission on a key to be able change its permissions mask.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_set_timeout ()
+returns
+.B 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The specified key does not exist.
+.TP
+.B EKEYEXPIRED
+The specified key has already expired.
+.TP
+.B EKEYREVOKED
+The specified key has been revoked.
+.TP
+.B EACCES
+The named key exists, but does not grant
+.B setattr
+permission to the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_setperm.3 b/keyutils-1.5.6/keyctl_setperm.3
new file mode 100644
index 0000000..9bf90f5
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_setperm.3
@@ -0,0 +1,130 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_SETPERM 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_setperm \- Change the permissions mask on a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_setperm(key_serial_t " key ", key_perm_t " perm ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_setperm ()
+changes the permissions mask on a key.
+.P
+A process that does not have the
+.B SysAdmin
+capability may not change the permissions mask on a key that doesn't have the
+same UID as the caller.
+.P
+The caller must have
+.B setattr
+permission on a key to be able change its permissions mask.
+.P
+The permissions mask is a bitwise-OR of the following flags:
+.TP
+.B KEY_xxx_VIEW
+Grant permission to view the attributes of a key.
+.TP
+.B KEY_xxx_READ
+Grant permission to read the payload of a key or to list a keyring.
+.TP
+.B KEY_xxx_WRITE
+Grant permission to modify the payload of a key or to add or remove links
+to/from a keyring.
+.TP
+.B KEY_xxx_SEARCH
+Grant permission to find a key or to search a keyring.
+.TP
+.B KEY_xxx_LINK
+Grant permission to make links to a key.
+.TP
+.B KEY_xxx_SETATTR
+Grant permission to change the ownership and permissions attributes of a key.
+.TP
+.B KEY_xxx_ALL
+Grant all the above.
+.P
+The
+.RB ' xxx '
+in the above should be replaced by one of:
+.TP
+.B POS
+Grant the permission to a process that possesses the key (has it attached
+searchably to one of the process's keyrings).
+.TP
+.B USR
+Grant the permission to a process with the same UID as the key.
+.TP
+.B GRP
+Grant the permission to a process with the same GID as the key, or with a
+match for the key's GID amongst that process's Groups list.
+.TP
+.B OTH
+Grant the permission to any other process.
+.P
+Examples include:
+.BR KEY_POS_VIEW ", " KEY_USR_READ ", " KEY_GRP_SEARCH " and " KEY_OTH_ALL .
+.P
+User, group and other grants are exclusive: if a process qualifies in
+the 'user' category, it will not qualify in the 'groups' category; and if a
+process qualifies in either 'user' or 'groups' then it will not qualify in
+the 'other' category.
+.P
+Possessor grants are cumulative with the grants from the 'user', 'groups'
+and 'other' categories.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_setperm ()
+returns
+.B 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The specified key does not exist.
+.TP
+.B EKEYEXPIRED
+The specified key has expired.
+.TP
+.B EKEYREVOKED
+The specified key has been revoked.
+.TP
+.B EACCES
+The named key exists, but does not grant
+.B setattr
+permission to the calling process.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyctl_update.3 b/keyutils-1.5.6/keyctl_update.3
new file mode 100644
index 0000000..dd95fe9
--- /dev/null
+++ b/keyutils-1.5.6/keyctl_update.3
@@ -0,0 +1,96 @@
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH KEYCTL_UPDATE 3 "4 May 2006" Linux "Linux Key Management Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+keyctl_update \- Update a key
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "long keyctl_update(key_serial_t " key ", const void *" payload ,
+.BI "size_t " plen ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR keyctl_update ()
+updates the payload of a key if the key type permits it.
+.P
+The caller must have
+.B write
+permission on a key to be able update it.
+.P
+.I payload
+and
+.I plen
+specify the data for the new payload.
+.I payload
+may be NULL and
+.I plen
+may be zero if the key type permits that. The key type may reject the data if
+it's in the wrong format or in some other way invalid.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+On success
+.BR keyctl_update ()
+returns
+.BR 0 .
+On error, the value
+.B -1
+will be returned and errno will have been set to an appropriate error.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+.TP
+.B ENOKEY
+The key specified is invalid.
+.TP
+.B EKEYEXPIRED
+The key specified has expired.
+.TP
+.B EKEYREVOKED
+The key specified had been revoked.
+.TP
+.B EINVAL
+The payload data was invalid.
+.TP
+.B ENOMEM
+Insufficient memory to store the new payload.
+.TP
+.B EDQUOT
+The key quota for this user would be exceeded by increasing the size of the
+key to accommodate the new payload.
+.TP
+.B EACCES
+The key exists, but is not
+.B writable
+by the calling process.
+.TP
+.B EOPNOTSUPP
+The key type does not support the update operation on its keys.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+This is a library function that can be found in
+.IR libkeyutils .
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (1),
+.br
+.BR add_key (2),
+.br
+.BR keyctl (2),
+.br
+.BR request_key (2),
+.br
+.BR keyctl (3),
+.br
+.BR request-key (8)
diff --git a/keyutils-1.5.6/keyutils.c b/keyutils-1.5.6/keyutils.c
new file mode 100644
index 0000000..329bfae
--- /dev/null
+++ b/keyutils-1.5.6/keyutils.c
@@ -0,0 +1,616 @@
+/* keyutils.c: key utility library
+ *
+ * Copyright (C) 2005,2011 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <asm/unistd.h>
+#include "keyutils.h"
+
+const char keyutils_version_string[] = PKGVERSION;
+const char keyutils_build_string[] = PKGBUILD;
+
+#ifdef NO_GLIBC_KEYERR
+static int error_inited;
+static void (*libc_perror)(const char *msg);
+static char *(*libc_strerror_r)(int errnum, char *buf, size_t n);
+//static int (*libc_xpg_strerror_r)(int errnum, char *buf, size_t n);
+#define RTLD_NEXT ((void *) -1L)
+#endif
+
+#define __weak __attribute__((weak))
+
+key_serial_t __weak add_key(const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ key_serial_t ringid)
+{
+ return syscall(__NR_add_key,
+ type, description, payload, plen, ringid);
+}
+
+key_serial_t __weak request_key(const char *type,
+ const char *description,
+ const char * callout_info,
+ key_serial_t destringid)
+{
+ return syscall(__NR_request_key,
+ type, description, callout_info, destringid);
+}
+
+static inline long __keyctl(int cmd,
+ unsigned long arg2,
+ unsigned long arg3,
+ unsigned long arg4,
+ unsigned long arg5)
+{
+ return syscall(__NR_keyctl,
+ cmd, arg2, arg3, arg4, arg5);
+}
+
+long __weak keyctl(int cmd, ...)
+{
+ va_list va;
+ unsigned long arg2, arg3, arg4, arg5;
+
+ va_start(va, cmd);
+ arg2 = va_arg(va, unsigned long);
+ arg3 = va_arg(va, unsigned long);
+ arg4 = va_arg(va, unsigned long);
+ arg5 = va_arg(va, unsigned long);
+ va_end(va);
+
+ return __keyctl(cmd, arg2, arg3, arg4, arg5);
+}
+
+key_serial_t keyctl_get_keyring_ID(key_serial_t id, int create)
+{
+ return keyctl(KEYCTL_GET_KEYRING_ID, id, create);
+}
+
+key_serial_t keyctl_join_session_keyring(const char *name)
+{
+ return keyctl(KEYCTL_JOIN_SESSION_KEYRING, name);
+}
+
+long keyctl_update(key_serial_t id, const void *payload, size_t plen)
+{
+ return keyctl(KEYCTL_UPDATE, id, payload, plen);
+}
+
+long keyctl_revoke(key_serial_t id)
+{
+ return keyctl(KEYCTL_REVOKE, id);
+}
+
+long keyctl_chown(key_serial_t id, uid_t uid, gid_t gid)
+{
+ return keyctl(KEYCTL_CHOWN, id, uid, gid);
+}
+
+long keyctl_setperm(key_serial_t id, key_perm_t perm)
+{
+ return keyctl(KEYCTL_SETPERM, id, perm);
+}
+
+long keyctl_describe(key_serial_t id, char *buffer, size_t buflen)
+{
+ return keyctl(KEYCTL_DESCRIBE, id, buffer, buflen);
+}
+
+long keyctl_clear(key_serial_t ringid)
+{
+ return keyctl(KEYCTL_CLEAR, ringid);
+}
+
+long keyctl_link(key_serial_t id, key_serial_t ringid)
+{
+ return keyctl(KEYCTL_LINK, id, ringid);
+}
+
+long keyctl_unlink(key_serial_t id, key_serial_t ringid)
+{
+ return keyctl(KEYCTL_UNLINK, id, ringid);
+}
+
+long keyctl_search(key_serial_t ringid,
+ const char *type,
+ const char *description,
+ key_serial_t destringid)
+{
+ return keyctl(KEYCTL_SEARCH, ringid, type, description, destringid);
+}
+
+long keyctl_read(key_serial_t id, char *buffer, size_t buflen)
+{
+ return keyctl(KEYCTL_READ, id, buffer, buflen);
+}
+
+long keyctl_instantiate(key_serial_t id,
+ const void *payload,
+ size_t plen,
+ key_serial_t ringid)
+{
+ return keyctl(KEYCTL_INSTANTIATE, id, payload, plen, ringid);
+}
+
+long keyctl_negate(key_serial_t id, unsigned timeout, key_serial_t ringid)
+{
+ return keyctl(KEYCTL_NEGATE, id, timeout, ringid);
+}
+
+long keyctl_set_reqkey_keyring(int reqkey_defl)
+{
+ return keyctl(KEYCTL_SET_REQKEY_KEYRING, reqkey_defl);
+}
+
+long keyctl_set_timeout(key_serial_t id, unsigned timeout)
+{
+ return keyctl(KEYCTL_SET_TIMEOUT, id, timeout);
+}
+
+long keyctl_assume_authority(key_serial_t id)
+{
+ return keyctl(KEYCTL_ASSUME_AUTHORITY, id);
+}
+
+long keyctl_get_security(key_serial_t id, char *buffer, size_t buflen)
+{
+ return keyctl(KEYCTL_GET_SECURITY, id, buffer, buflen);
+}
+
+long keyctl_session_to_parent(void)
+{
+ return keyctl(KEYCTL_SESSION_TO_PARENT);
+}
+
+long keyctl_reject(key_serial_t id, unsigned timeout, unsigned error,
+ key_serial_t ringid)
+{
+ long ret = keyctl(KEYCTL_REJECT, id, timeout, error, ringid);
+
+ /* fall back to keyctl_negate() if this op is not supported by this
+ * kernel version */
+ if (ret == -1 && errno == EOPNOTSUPP)
+ return keyctl_negate(id, timeout, ringid);
+ return ret;
+}
+
+long keyctl_instantiate_iov(key_serial_t id,
+ const struct iovec *payload_iov,
+ unsigned ioc,
+ key_serial_t ringid)
+{
+ long ret = keyctl(KEYCTL_INSTANTIATE_IOV, id, payload_iov, ioc, ringid);
+
+ /* fall back to keyctl_instantiate() if this op is not supported by
+ * this kernel version */
+ if (ret == -1 && errno == EOPNOTSUPP) {
+ unsigned loop;
+ size_t bsize = 0, seg;
+ void *buf, *p;
+
+ if (!payload_iov || !ioc)
+ return keyctl_instantiate(id, NULL, 0, ringid);
+ for (loop = 0; loop < ioc; loop++)
+ bsize += payload_iov[loop].iov_len;
+ if (bsize == 0)
+ return keyctl_instantiate(id, NULL, 0, ringid);
+ p = buf = malloc(bsize);
+ if (!buf)
+ return -1;
+ for (loop = 0; loop < ioc; loop++) {
+ seg = payload_iov[loop].iov_len;
+ p = memcpy(p, payload_iov[loop].iov_base, seg) + seg;
+ }
+ ret = keyctl_instantiate(id, buf, bsize, ringid);
+ free(buf);
+ }
+ return ret;
+}
+
+long keyctl_invalidate(key_serial_t id)
+{
+ return keyctl(KEYCTL_INVALIDATE, id);
+}
+
+/*****************************************************************************/
+/*
+ * fetch key description into an allocated buffer
+ * - resulting string is NUL terminated
+ * - returns count not including NUL
+ */
+int keyctl_describe_alloc(key_serial_t id, char **_buffer)
+{
+ char *buf;
+ long buflen, ret;
+
+ ret = keyctl_describe(id, NULL, 0);
+ if (ret < 0)
+ return -1;
+
+ buflen = ret;
+ buf = malloc(buflen);
+ if (!buf)
+ return -1;
+
+ for (;;) {
+ ret = keyctl_describe(id, buf, buflen);
+ if (ret < 0)
+ return -1;
+
+ if (buflen >= ret)
+ break;
+
+ buflen = ret;
+ buf = realloc(buf, buflen);
+ if (!buf)
+ return -1;
+ }
+
+ *_buffer = buf;
+ return buflen - 1;
+
+} /* end keyctl_describe_alloc() */
+
+/*****************************************************************************/
+/*
+ * fetch key contents into an allocated buffer
+ * - resulting buffer has an extra NUL added to the end
+ * - returns count (not including extraneous NUL)
+ */
+int keyctl_read_alloc(key_serial_t id, void **_buffer)
+{
+ void *buf;
+ long buflen, ret;
+
+ ret = keyctl_read(id, NULL, 0);
+ if (ret < 0)
+ return -1;
+
+ buflen = ret;
+ buf = malloc(buflen + 1);
+ if (!buf)
+ return -1;
+
+ for (;;) {
+ ret = keyctl_read(id, buf, buflen);
+ if (ret < 0)
+ return -1;
+
+ if (buflen >= ret)
+ break;
+
+ buflen = ret;
+ buf = realloc(buf, buflen + 1);
+ if (!buf)
+ return -1;
+ }
+
+ ((unsigned char *) buf)[buflen] = 0;
+ *_buffer = buf;
+ return buflen;
+
+} /* end keyctl_read_alloc() */
+
+/*****************************************************************************/
+/*
+ * fetch key security label into an allocated buffer
+ * - resulting string is NUL terminated
+ * - returns count not including NUL
+ */
+int keyctl_get_security_alloc(key_serial_t id, char **_buffer)
+{
+ char *buf;
+ long buflen, ret;
+
+ ret = keyctl_get_security(id, NULL, 0);
+ if (ret < 0)
+ return -1;
+
+ buflen = ret;
+ buf = malloc(buflen);
+ if (!buf)
+ return -1;
+
+ for (;;) {
+ ret = keyctl_get_security(id, buf, buflen);
+ if (ret < 0)
+ return -1;
+
+ if (buflen >= ret)
+ break;
+
+ buflen = ret;
+ buf = realloc(buf, buflen);
+ if (!buf)
+ return -1;
+ }
+
+ *_buffer = buf;
+ return buflen - 1;
+}
+
+/*
+ * Depth-first recursively apply a function over a keyring tree
+ */
+static int recursive_key_scan_aux(key_serial_t parent, key_serial_t key,
+ int depth, recursive_key_scanner_t func,
+ void *data)
+{
+ key_serial_t *pk;
+ key_perm_t perm;
+ size_t ringlen;
+ void *ring;
+ char *desc, type[255];
+ int desc_len, uid, gid, ret, n, kcount = 0;
+
+ if (depth > 800)
+ return 0;
+
+ /* read the key description */
+ desc = NULL;
+ desc_len = keyctl_describe_alloc(key, &desc);
+ if (desc_len < 0)
+ goto do_this_key;
+
+ /* parse */
+ type[0] = 0;
+
+ n = sscanf(desc, "%[^;];%d;%d;%x;", type, &uid, &gid, &perm);
+ if (n != 4) {
+ free(desc);
+ desc = NULL;
+ errno = -EINVAL;
+ desc_len = -1;
+ goto do_this_key;
+ }
+
+ /* if it's a keyring then we're going to want to recursively search it
+ * if we can */
+ if (strcmp(type, "keyring") == 0) {
+ /* read the keyring's contents */
+ ret = keyctl_read_alloc(key, &ring);
+ if (ret < 0)
+ goto do_this_key;
+
+ ringlen = ret;
+
+ /* walk the keyring */
+ pk = ring;
+ for (ringlen = ret;
+ ringlen >= sizeof(key_serial_t);
+ ringlen -= sizeof(key_serial_t)
+ )
+ kcount += recursive_key_scan_aux(key, *pk++, depth + 1,
+ func, data);
+
+ free(ring);
+ }
+
+do_this_key:
+ kcount += func(parent, key, desc, desc_len, data);
+ free(desc);
+ return kcount;
+}
+
+/*
+ * Depth-first apply a function over a keyring tree
+ */
+int recursive_key_scan(key_serial_t key, recursive_key_scanner_t func, void *data)
+{
+ return recursive_key_scan_aux(0, key, 0, func, data);
+}
+
+/*
+ * Depth-first apply a function over session keyring tree
+ */
+int recursive_session_key_scan(recursive_key_scanner_t func, void *data)
+{
+ key_serial_t session =
+ keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0);
+ if (session > 0)
+ return recursive_key_scan(session, func, data);
+ return 0;
+}
+
+#ifdef NO_GLIBC_KEYERR
+/*****************************************************************************/
+/*
+ * initialise error handling
+ */
+static void error_init(void)
+{
+ char *err;
+
+ error_inited = 1;
+
+ dlerror();
+
+ libc_perror = dlsym(RTLD_NEXT,"perror");
+ if (!libc_perror) {
+ fprintf(stderr, "Failed to look up next perror\n");
+ err = dlerror();
+ if (err)
+ fprintf(stderr, "%s\n", err);
+ abort();
+ }
+
+ //fprintf(stderr, "next perror at %p\n", libc_perror);
+
+ libc_strerror_r = dlsym(RTLD_NEXT,"strerror_r");
+ if (!libc_strerror_r) {
+ fprintf(stderr, "Failed to look up next strerror_r\n");
+ err = dlerror();
+ if (err)
+ fprintf(stderr, "%s\n", err);
+ abort();
+ }
+
+ //fprintf(stderr, "next strerror_r at %p\n", libc_strerror_r);
+
+#if 0
+ libc_xpg_strerror_r = dlsym(RTLD_NEXT,"xpg_strerror_r");
+ if (!libc_xpg_strerror_r) {
+ fprintf(stderr, "Failed to look up next xpg_strerror_r\n");
+ err = dlerror();
+ if (err)
+ fprintf(stderr, "%s\n", err);
+ abort();
+ }
+
+ //fprintf(stderr, "next xpg_strerror_r at %p\n", libc_xpg_strerror_r);
+#endif
+
+} /* end error_init() */
+
+/*****************************************************************************/
+/*
+ * overload glibc's strerror_r() with a version that knows about key errors
+ */
+char *strerror_r(int errnum, char *buf, size_t n)
+{
+ const char *errstr;
+ int len;
+
+ printf("hello\n");
+
+ if (!error_inited)
+ error_init();
+
+ switch (errnum) {
+ case ENOKEY:
+ errstr = "Requested key not available";
+ break;
+
+ case EKEYEXPIRED:
+ errstr = "Key has expired";
+ break;
+
+ case EKEYREVOKED:
+ errstr = "Key has been revoked";
+ break;
+
+ case EKEYREJECTED:
+ errstr = "Key was rejected by service";
+ break;
+
+ default:
+ return libc_strerror_r(errnum, buf, n);
+ }
+
+ len = strlen(errstr) + 1;
+ if (n > len) {
+ errno = ERANGE;
+ if (n > 0) {
+ memcpy(buf, errstr, n - 1);
+ buf[n - 1] = 0;
+ }
+ return NULL;
+ }
+ else {
+ memcpy(buf, errstr, len);
+ return buf;
+ }
+
+} /* end strerror_r() */
+
+#if 0
+/*****************************************************************************/
+/*
+ * overload glibc's strerror_r() with a version that knows about key errors
+ */
+int xpg_strerror_r(int errnum, char *buf, size_t n)
+{
+ const char *errstr;
+ int len;
+
+ if (!error_inited)
+ error_init();
+
+ switch (errnum) {
+ case ENOKEY:
+ errstr = "Requested key not available";
+ break;
+
+ case EKEYEXPIRED:
+ errstr = "Key has expired";
+ break;
+
+ case EKEYREVOKED:
+ errstr = "Key has been revoked";
+ break;
+
+ case EKEYREJECTED:
+ errstr = "Key was rejected by service";
+ break;
+
+ default:
+ return libc_xpg_strerror_r(errnum, buf, n);
+ }
+
+ len = strlen(errstr) + 1;
+ if (n > len) {
+ errno = ERANGE;
+ if (n > 0) {
+ memcpy(buf, errstr, n - 1);
+ buf[n - 1] = 0;
+ }
+ return -1;
+ }
+ else {
+ memcpy(buf, errstr, len);
+ return 0;
+ }
+
+} /* end xpg_strerror_r() */
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+void perror(const char *msg)
+{
+ if (!error_inited)
+ error_init();
+
+ switch (errno) {
+ case ENOKEY:
+ fprintf(stderr, "%s: Requested key not available\n", msg);
+ return;
+
+ case EKEYEXPIRED:
+ fprintf(stderr, "%s: Key has expired\n", msg);
+ return;
+
+ case EKEYREVOKED:
+ fprintf(stderr, "%s: Key has been revoked\n", msg);
+ return;
+
+ case EKEYREJECTED:
+ fprintf(stderr, "%s: Key was rejected by service\n", msg);
+ return;
+
+ default:
+ libc_perror(msg);
+ return;
+ }
+
+} /* end perror() */
+#endif
diff --git a/keyutils-1.5.6/keyutils.h b/keyutils-1.5.6/keyutils.h
new file mode 100644
index 0000000..3ddaeae
--- /dev/null
+++ b/keyutils-1.5.6/keyutils.h
@@ -0,0 +1,166 @@
+/* keyutils.h: key utility library interface
+ *
+ * Copyright (C) 2005,2011 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef KEYUTILS_H
+#define KEYUTILS_H
+
+#include <stdint.h>
+
+extern const char keyutils_version_string[];
+extern const char keyutils_build_string[];
+
+/* key serial number */
+typedef int32_t key_serial_t;
+
+/* special process keyring shortcut IDs */
+#define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */
+#define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */
+#define KEY_SPEC_SESSION_KEYRING -3 /* - key ID for session-specific keyring */
+#define KEY_SPEC_USER_KEYRING -4 /* - key ID for UID-specific keyring */
+#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */
+#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */
+#define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */
+
+/* request-key default keyrings */
+#define KEY_REQKEY_DEFL_NO_CHANGE -1
+#define KEY_REQKEY_DEFL_DEFAULT 0
+#define KEY_REQKEY_DEFL_THREAD_KEYRING 1
+#define KEY_REQKEY_DEFL_PROCESS_KEYRING 2
+#define KEY_REQKEY_DEFL_SESSION_KEYRING 3
+#define KEY_REQKEY_DEFL_USER_KEYRING 4
+#define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5
+#define KEY_REQKEY_DEFL_GROUP_KEYRING 6
+
+/* key handle permissions mask */
+typedef uint32_t key_perm_t;
+
+#define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */
+#define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */
+#define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */
+#define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */
+#define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */
+#define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */
+#define KEY_POS_ALL 0x3f000000
+
+#define KEY_USR_VIEW 0x00010000 /* user permissions... */
+#define KEY_USR_READ 0x00020000
+#define KEY_USR_WRITE 0x00040000
+#define KEY_USR_SEARCH 0x00080000
+#define KEY_USR_LINK 0x00100000
+#define KEY_USR_SETATTR 0x00200000
+#define KEY_USR_ALL 0x003f0000
+
+#define KEY_GRP_VIEW 0x00000100 /* group permissions... */
+#define KEY_GRP_READ 0x00000200
+#define KEY_GRP_WRITE 0x00000400
+#define KEY_GRP_SEARCH 0x00000800
+#define KEY_GRP_LINK 0x00001000
+#define KEY_GRP_SETATTR 0x00002000
+#define KEY_GRP_ALL 0x00003f00
+
+#define KEY_OTH_VIEW 0x00000001 /* third party permissions... */
+#define KEY_OTH_READ 0x00000002
+#define KEY_OTH_WRITE 0x00000004
+#define KEY_OTH_SEARCH 0x00000008
+#define KEY_OTH_LINK 0x00000010
+#define KEY_OTH_SETATTR 0x00000010
+#define KEY_OTH_ALL 0x0000003f
+
+/* keyctl commands */
+#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */
+#define KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */
+#define KEYCTL_UPDATE 2 /* update a key */
+#define KEYCTL_REVOKE 3 /* revoke a key */
+#define KEYCTL_CHOWN 4 /* set ownership of a key */
+#define KEYCTL_SETPERM 5 /* set perms on a key */
+#define KEYCTL_DESCRIBE 6 /* describe a key */
+#define KEYCTL_CLEAR 7 /* clear contents of a keyring */
+#define KEYCTL_LINK 8 /* link a key into a keyring */
+#define KEYCTL_UNLINK 9 /* unlink a key from a keyring */
+#define KEYCTL_SEARCH 10 /* search for a key in a keyring */
+#define KEYCTL_READ 11 /* read a key or keyring's contents */
+#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */
+#define KEYCTL_NEGATE 13 /* negate a partially constructed key */
+#define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */
+#define KEYCTL_SET_TIMEOUT 15 /* set timeout on a key */
+#define KEYCTL_ASSUME_AUTHORITY 16 /* assume authority to instantiate key */
+#define KEYCTL_GET_SECURITY 17 /* get key security label */
+#define KEYCTL_SESSION_TO_PARENT 18 /* set my session keyring on my parent process */
+#define KEYCTL_REJECT 19 /* reject a partially constructed key */
+#define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */
+#define KEYCTL_INVALIDATE 21 /* invalidate a key */
+
+/*
+ * syscall wrappers
+ */
+extern key_serial_t add_key(const char *type,
+ const char *description,
+ const void *payload,
+ size_t plen,
+ key_serial_t ringid);
+
+extern key_serial_t request_key(const char *type,
+ const char *description,
+ const char *callout_info,
+ key_serial_t destringid);
+
+extern long keyctl(int cmd, ...);
+
+/*
+ * keyctl function wrappers
+ */
+extern key_serial_t keyctl_get_keyring_ID(key_serial_t id, int create);
+extern key_serial_t keyctl_join_session_keyring(const char *name);
+extern long keyctl_update(key_serial_t id, const void *payload, size_t plen);
+extern long keyctl_revoke(key_serial_t id);
+extern long keyctl_chown(key_serial_t id, uid_t uid, gid_t gid);
+extern long keyctl_setperm(key_serial_t id, key_perm_t perm);
+extern long keyctl_describe(key_serial_t id, char *buffer, size_t buflen);
+extern long keyctl_clear(key_serial_t ringid);
+extern long keyctl_link(key_serial_t id, key_serial_t ringid);
+extern long keyctl_unlink(key_serial_t id, key_serial_t ringid);
+extern long keyctl_search(key_serial_t ringid,
+ const char *type,
+ const char *description,
+ key_serial_t destringid);
+extern long keyctl_read(key_serial_t id, char *buffer, size_t buflen);
+extern long keyctl_instantiate(key_serial_t id,
+ const void *payload,
+ size_t plen,
+ key_serial_t ringid);
+extern long keyctl_negate(key_serial_t id, unsigned timeout, key_serial_t ringid);
+extern long keyctl_set_reqkey_keyring(int reqkey_defl);
+extern long keyctl_set_timeout(key_serial_t key, unsigned timeout);
+extern long keyctl_assume_authority(key_serial_t key);
+extern long keyctl_get_security(key_serial_t key, char *buffer, size_t buflen);
+extern long keyctl_session_to_parent(void);
+extern long keyctl_reject(key_serial_t id, unsigned timeout, unsigned error,
+ key_serial_t ringid);
+struct iovec;
+extern long keyctl_instantiate_iov(key_serial_t id,
+ const struct iovec *payload_iov,
+ unsigned ioc,
+ key_serial_t ringid);
+extern long keyctl_invalidate(key_serial_t id);
+
+/*
+ * utilities
+ */
+extern int keyctl_describe_alloc(key_serial_t id, char **_buffer);
+extern int keyctl_read_alloc(key_serial_t id, void **_buffer);
+extern int keyctl_get_security_alloc(key_serial_t id, char **_buffer);
+
+typedef int (*recursive_key_scanner_t)(key_serial_t parent, key_serial_t key,
+ char *desc, int desc_len, void *data);
+extern int recursive_key_scan(key_serial_t key, recursive_key_scanner_t func, void *data);
+extern int recursive_session_key_scan(recursive_key_scanner_t func, void *data);
+
+#endif /* KEYUTILS_H */
diff --git a/keyutils-1.5.6/keyutils.spec b/keyutils-1.5.6/keyutils.spec
new file mode 100644
index 0000000..4d616fe
--- /dev/null
+++ b/keyutils-1.5.6/keyutils.spec
@@ -0,0 +1,242 @@
+%define vermajor 1
+%define verminor 5.6
+%define version %{vermajor}.%{verminor}
+%define libdir /%{_lib}
+%define usrlibdir %{_prefix}/%{_lib}
+%define libapivermajor 1
+%define libapiversion %{libapivermajor}.4
+
+# % define buildid .local
+
+Summary: Linux Key Management Utilities
+Name: keyutils
+Version: %{version}
+Release: 1%{?buildid}%{?dist}
+License: GPLv2+ and LGPLv2+
+Group: System Environment/Base
+ExclusiveOS: Linux
+Url: http://people.redhat.com/~dhowells/keyutils/
+
+Source0: http://people.redhat.com/~dhowells/keyutils/keyutils-%{version}.tar.bz2
+
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires: glibc-kernheaders >= 2.4-9.1.92
+Requires: keyutils-libs == %{version}-%{release}
+
+%description
+Utilities to control the kernel key management facility and to provide
+a mechanism by which the kernel call back to user space to get a key
+instantiated.
+
+%package libs
+Summary: Key utilities library
+Group: System Environment/Base
+
+%description libs
+This package provides a wrapper library for the key management facility system
+calls.
+
+%package libs-devel
+Summary: Development package for building Linux key management utilities
+Group: System Environment/Base
+Requires: keyutils-libs == %{version}-%{release}
+
+%description libs-devel
+This package provides headers and libraries for building key utilities.
+
+%prep
+%setup -q
+
+%build
+make \
+ NO_ARLIB=1 \
+ LIBDIR=%{libdir} \
+ USRLIBDIR=%{usrlibdir} \
+ RELEASE=.%{release} \
+ NO_GLIBC_KEYERR=1 \
+ CFLAGS="-Wall $RPM_OPT_FLAGS -Werror"
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make \
+ NO_ARLIB=1 \
+ DESTDIR=$RPM_BUILD_ROOT \
+ LIBDIR=%{libdir} \
+ USRLIBDIR=%{usrlibdir} \
+ install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post libs -p /sbin/ldconfig
+%postun libs -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%doc README LICENCE.GPL
+/sbin/*
+/bin/*
+/usr/share/keyutils
+%{_mandir}/man1/*
+%{_mandir}/man5/*
+%{_mandir}/man8/*
+%config(noreplace) /etc/*
+
+%files libs
+%defattr(-,root,root,-)
+%doc LICENCE.LGPL
+%{libdir}/libkeyutils.so.%{libapiversion}
+%{libdir}/libkeyutils.so.%{libapivermajor}
+
+%files libs-devel
+%defattr(-,root,root,-)
+%{usrlibdir}/libkeyutils.so
+%{_includedir}/*
+%{_mandir}/man3/*
+
+%changelog
+* Thu Aug 29 2013 David Howells <dhowells@redhat.com> - 1.5.6-1
+- Fix the request-key.conf.5 manpage.
+- Fix the max depth of key tree dump (keyctl show).
+- The input buffer size for keyctl padd and pinstantiate should be larger.
+- Add keyctl_invalidate.3 manpage.
+
+* Wed Nov 30 2011 David Howells <dhowells@redhat.com> - 1.5.5-1
+- Fix a Makefile error.
+
+* Wed Nov 30 2011 David Howells <dhowells@redhat.com> - 1.5.4-1
+- Fix the keyctl padd command and similar to handle binary input.
+- Make keyctl show able to take a keyring to dump.
+- Make keyctl show able to take a flag to request hex key IDs.
+- Make keyctl show print the real ID of the root keyring.
+
+* Tue Nov 15 2011 David Howells <dhowells@redhat.com>
+- Allow /sbin/request-key to have multiple config files.
+
+* Wed Aug 31 2011 David Howells <dhowells@redhat.com>
+- Adjust the manual page for 'keyctl unlink' to show keyring is optional.
+- Add --version support for the keyutils version and build date.
+
+* Thu Aug 11 2011 David Howells <dhowells@redhat.com> - 1.5.3-1
+- Make the keyutils rpm depend on the same keyutils-libs rpm version.
+
+* Tue Jul 26 2011 David Howells <dhowells@redhat.com> - 1.5.2-1
+- Use correct format spec for printing pointer subtraction results.
+
+* Tue Jul 19 2011 David Howells <dhowells@redhat.com> - 1.5.1-1
+- Fix unread variables.
+- Licence file update.
+
+* Thu Mar 10 2011 David Howells <dhowells@redhat.com> - 1.5-1
+- Disable RPATH setting in Makefile.
+- Add -I. to build to get this keyutils.h.
+- Make CFLAGS override on make command line work right.
+- Make specfile UTF-8.
+- Support KEYCTL_REJECT.
+- Support KEYCTL_INSTANTIATE_IOV.
+- Add AFSDB DNS lookup program from Wang Lei.
+- Generalise DNS lookup program.
+- Add recursive scan utility function.
+- Add bad key reap command to keyctl.
+- Add multi-unlink variant to keyctl unlink command.
+- Add multi key purger command to keyctl.
+- Handle multi-line commands in keyctl command table.
+- Move the package to version to 1.5.
+
+* Tue Mar 1 2011 David Howells <dhowells@redhat.com> - 1.4-4
+- Make build guess at default libdirs and word size.
+- Make program build depend on library in Makefile.
+- Don't include $(DESTDIR) in MAN* macros.
+- Remove NO_GLIBC_KEYSYS as it is obsolete.
+- Have Makefile extract version info from specfile and version script.
+- Provide RPM build rule in Makefile.
+- Provide distclean rule in Makefile.
+
+* Fri Dec 17 2010 Diego Elio Pettenò <flameeyes@hosting.flameeyes.eu> - 1.4-3
+- Fix local linking and RPATH.
+
+* Thu Jun 10 2010 David Howells <dhowells@redhat.com> - 1.4-2
+- Fix prototypes in manual pages (some char* should be void*).
+- Rename the keyctl_security.3 manpage to keyctl_get_security.3.
+
+* Fri Mar 19 2010 David Howells <dhowells@redhat.com> - 1.4-1
+- Fix the library naming wrt the version.
+- Move the package to version to 1.4.
+
+* Fri Mar 19 2010 David Howells <dhowells@redhat.com> - 1.3-3
+- Fix spelling mistakes in manpages.
+- Add an index manpage for all the keyctl functions.
+
+* Thu Mar 11 2010 David Howells <dhowells@redhat.com> - 1.3-2
+- Fix rpmlint warnings.
+
+* Fri Feb 26 2010 David Howells <dhowells@redhat.com> - 1.3-1
+- Fix compiler warnings in request-key.
+- Expose the kernel function to get a key's security context.
+- Expose the kernel function to set a processes keyring onto its parent.
+- Move libkeyutils library version to 1.3.
+
+* Tue Aug 22 2006 David Howells <dhowells@redhat.com> - 1.2-1
+- Remove syscall manual pages (section 2) to man-pages package [BZ 203582]
+- Don't write to serial port in debugging script
+
+* Mon Jun 5 2006 David Howells <dhowells@redhat.com> - 1.1-4
+- Call ldconfig during (un)installation.
+
+* Fri May 5 2006 David Howells <dhowells@redhat.com> - 1.1-3
+- Don't include the release number in the shared library filename
+- Don't build static library
+
+* Fri May 5 2006 David Howells <dhowells@redhat.com> - 1.1-2
+- More bug fixes from Fedora reviewer.
+
+* Thu May 4 2006 David Howells <dhowells@redhat.com> - 1.1-1
+- Fix rpmlint errors
+
+* Mon Dec 5 2005 David Howells <dhowells@redhat.com> - 1.0-2
+- Add build dependency on glibc-kernheaders with key management syscall numbers
+
+* Tue Nov 29 2005 David Howells <dhowells@redhat.com> - 1.0-1
+- Add data pipe-in facility for keyctl request2
+
+* Mon Nov 28 2005 David Howells <dhowells@redhat.com> - 1.0-1
+- Rename library and header file "keyutil" -> "keyutils" for consistency
+- Fix shared library version naming to same way as glibc.
+- Add versioning for shared library symbols
+- Create new keyutils-libs package and install library and main symlink there
+- Install base library symlink in /usr/lib and place in devel package
+- Added a keyutils archive library
+- Shorten displayed key permissions list to just those we actually have
+
+* Thu Nov 24 2005 David Howells <dhowells@redhat.com> - 0.3-4
+- Add data pipe-in facilities for keyctl add, update and instantiate
+
+* Fri Nov 18 2005 David Howells <dhowells@redhat.com> - 0.3-3
+- Added stdint.h inclusion in keyutils.h
+- Made request-key.c use request_key() rather than keyctl_search()
+- Added piping facility to request-key
+
+* Thu Nov 17 2005 David Howells <dhowells@redhat.com> - 0.3-2
+- Added timeout keyctl option
+- request_key auth keys must now be assumed
+- Fix keyctl argument ordering for debug negate line in request-key.conf
+
+* Thu Jul 28 2005 David Howells <dhowells@redhat.com> - 0.3-1
+- Must invoke initialisation from perror() override in libkeyutils
+- Minor UI changes
+
+* Wed Jul 20 2005 David Howells <dhowells@redhat.com> - 0.2-2
+- Bump version to permit building in main repositories.
+
+* Tue Jul 12 2005 David Howells <dhowells@redhat.com> - 0.2-1
+- Don't attempt to define the error codes in the header file.
+- Pass the release ID through to the makefile to affect the shared library name.
+
+* Tue Jul 12 2005 David Howells <dhowells@redhat.com> - 0.1-3
+- Build in the perror() override to get the key error strings displayed.
+
+* Tue Jul 12 2005 David Howells <dhowells@redhat.com> - 0.1-2
+- Need a defattr directive after each files directive.
+
+* Tue Jul 12 2005 David Howells <dhowells@redhat.com> - 0.1-1
+- Package creation.
diff --git a/keyutils-1.5.6/recursive_key_scan.3 b/keyutils-1.5.6/recursive_key_scan.3
new file mode 100644
index 0000000..c07be85
--- /dev/null
+++ b/keyutils-1.5.6/recursive_key_scan.3
@@ -0,0 +1,87 @@
+.\"
+.\" Copyright (C) 2011 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public Licence
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the Licence, or (at your option) any later version.
+.\"
+.TH RECURSIVE_KEY_SCAN 3 "10 Mar 2011" Linux "Linux Key Utility Calls"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH NAME
+recursive_key_scan \- Apply a function to all keys in a keyring tree
+.br
+recursive_session_key_scan \- Apply a function to all keys in the session keyring tree
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SYNOPSIS
+.nf
+.B #include <keyutils.h>
+.sp
+.BI "typedef int (*" recursive_key_scanner_t ")(key_serial_t " parent ,
+.BI " key_serial_t " key ", char *" desc ", int " desc_len ", void *" data ");"
+.sp
+.BI "long recursive_key_scan(key_serial_t " keyring ,
+.BI " recursive_key_scanner_t " func ", void *" data ");"
+.br
+.BI "long recursive_session_key_scan(recursive_key_scanner_t " func ,
+.BI " void *" data ");"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH DESCRIPTION
+.BR recursive_key_scan ()
+performs a depth-first recursive scan of the specified
+.I keyring
+tree and applies
+.I func
+to every link found in the accessible keyrings in that tree.
+.I data
+is passed to each invocation of func.
+.P
+The return values of
+.I func
+are summed and returned as the overall return value. Errors are ignored.
+Inaccessible keyrings are not scanned, but links to them are still passed to
+func.
+.P
+.BR recursive_session_key_scan ()
+works exactly like
+.IR recursive_key_scan ()
+with the caller's session keyring specified as the starting keyring.
+.P
+The callback function is called for each link found in all the keyrings in the
+nominated tree and so may be called multiple times for a particular key if that
+key has multiple links to it.
+.P
+The callback function is passed the following parameters:
+.TP
+.B parent
+The keyring containing the link or 0 for the initial key.
+.TP
+.BR key
+The key to which the link points.
+.TP
+.BR desc " and " desc_len
+A pointer to the raw description and its length as retrieved with
+.IR keyctl_describe_alloc ().
+These will be NULL and -1 respectively if the description couldn't be
+retrieved and errno will retain the error from
+.IR keyctl_describe_alloc ().
+.TP
+.B data
+The data passed to the scanner function.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH RETURN VALUE
+These functions return the sum of the results of the callback functions they
+invoke.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH ERRORS
+Ignored.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH LINKING
+When linking,
+.B -lkeyutils
+should be specified to the linker.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.SH SEE ALSO
+.BR keyctl (3),
+.BR keyctl_describe_alloc (3)
diff --git a/keyutils-1.5.6/request-key-debug.sh b/keyutils-1.5.6/request-key-debug.sh
new file mode 100755
index 0000000..83af01d
--- /dev/null
+++ b/keyutils-1.5.6/request-key-debug.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+###############################################################################
+#
+# Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+# Written by David Howells (dhowells@redhat.com)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+###############################################################################
+#
+# Request key debugging
+#
+# Call: request-key-debug.sh <keyid> <desc> <callout> <session-keyring>
+#
+
+echo RQDebug keyid: $1
+echo RQDebug desc: $2
+echo RQDebug callout: $3
+echo RQDebug session keyring: $4
+
+if [ "$3" != "neg" ]
+then
+ keyctl instantiate $1 "Debug $3" $4 || exit 1
+else
+ cat /proc/keys
+ echo keyctl negate $1 30 $4
+ keyctl negate $1 30 $4
+fi
+
+exit 0
diff --git a/keyutils-1.5.6/request-key.8 b/keyutils-1.5.6/request-key.8
new file mode 100644
index 0000000..8d4a880
--- /dev/null
+++ b/keyutils-1.5.6/request-key.8
@@ -0,0 +1,34 @@
+.\"
+.\" Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH REQUEST-KEY 8 "15 Nov 2011" Linux "Linux Key Management Utilities"
+.SH NAME
+request-key - Handle key instantiation callback requests from the kernel
+.SH SYNOPSIS
+\fB/sbin/request-key \fR<op> <key> <uid> <gid> <threadring> <processring>
+ <sessionring> [<info>]
+.SH DESCRIPTION
+This program is invoked by the kernel when the kernel is asked for a key that
+it doesn't have immediately available. The kernel creates a partially set up
+key and then calls out to this program to instantiate it. It is not intended
+to be called directly.
+.SH ERRORS
+All errors will be logged to the syslog.
+.SH FILES
+.ul
+/etc/request-key.conf
+.ul 0
+Instantiation handler configuration file.
+.P
+.ul
+/etc/request-key.d/<keytype>.conf
+.ul 0
+Keytype specific configuration file.
+.SH SEE ALSO
+\fBkeyctl\fR(1), \fBrequest-key.conf\fR(5)
diff --git a/keyutils-1.5.6/request-key.c b/keyutils-1.5.6/request-key.c
new file mode 100644
index 0000000..3762e9a
--- /dev/null
+++ b/keyutils-1.5.6/request-key.c
@@ -0,0 +1,870 @@
+/* request-key.c: hand a key request off to the appropriate process
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * /sbin/request-key <op> <key> <uid> <gid> <threadring> <processring> <sessionring> [<info>]
+ *
+ * Searches the specified session ring for a key indicating the command to run:
+ * type: "user"
+ * desc: "request-key:<op>"
+ * data: command name, eg: "/home/dhowells/request-key-create.sh"
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <signal.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include "keyutils.h"
+
+
+static int xdebug;
+static int xnolog;
+static char *xkey;
+static char *xuid;
+static char *xgid;
+static char *xthread_keyring;
+static char *xprocess_keyring;
+static char *xsession_keyring;
+static char conffile[256];
+static int confline;
+static int norecurse;
+
+static void lookup_action(char *op,
+ key_serial_t key,
+ char *ktype,
+ char *kdesc,
+ char *callout_info)
+ __attribute__((noreturn));
+
+static void execute_program(char *op,
+ key_serial_t key,
+ char *ktype,
+ char *kdesc,
+ char *callout_info,
+ char *cmdline)
+ __attribute__((noreturn));
+
+static void pipe_to_program(char *op,
+ key_serial_t key,
+ char *ktype,
+ char *kdesc,
+ char *callout_info,
+ char *prog,
+ char **argv)
+ __attribute__((noreturn));
+
+static int match(const char *pattern, int plen, const char *datum, int dlen);
+
+static void debug(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+static void debug(const char *fmt, ...)
+{
+ va_list va;
+
+ if (xdebug) {
+ va_start(va, fmt);
+ vfprintf(stderr, fmt, va);
+ va_end(va);
+
+ if (!xnolog) {
+ openlog("request-key", 0, LOG_AUTHPRIV);
+
+ va_start(va, fmt);
+ vsyslog(LOG_DEBUG, fmt, va);
+ va_end(va);
+
+ closelog();
+ }
+ }
+}
+
+static void error(const char *fmt, ...) __attribute__((noreturn, format(printf, 1, 2)));
+static void error(const char *fmt, ...)
+{
+ va_list va;
+
+ if (xdebug) {
+ va_start(va, fmt);
+ vfprintf(stderr, fmt, va);
+ va_end(va);
+ }
+
+ if (!xnolog) {
+ openlog("request-key", 0, LOG_AUTHPRIV);
+
+ va_start(va, fmt);
+ vsyslog(LOG_ERR, fmt, va);
+ va_end(va);
+
+ closelog();
+ }
+
+ exit(1);
+}
+
+#define file_error(FMT, ...) error("%s: "FMT, conffile, ## __VA_ARGS__)
+#define line_error(FMT, ...) error("%s:%d: "FMT, conffile, confline, ## __VA_ARGS__)
+
+static void oops(int x)
+{
+ error("Died on signal %d", x);
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+int main(int argc, char *argv[])
+{
+ key_serial_t key;
+ char *ktype, *kdesc, *buf, *callout_info;
+ int ret, ntype, dpos, n, fd;
+
+ if (argc == 2 && strcmp(argv[1], "--version") == 0) {
+ printf("request-key from %s (Built %s)\n",
+ keyutils_version_string, keyutils_build_string);
+ return 0;
+ }
+
+ signal(SIGSEGV, oops);
+ signal(SIGBUS, oops);
+ signal(SIGPIPE, SIG_IGN);
+
+ for (;;) {
+ if (argc > 1 && strcmp(argv[1], "-d") == 0) {
+ xdebug++;
+ argv++;
+ argc--;
+ }
+ else if (argc > 1 && strcmp(argv[1], "-n") == 0) {
+ xnolog = 1;
+ argv++;
+ argc--;
+ }
+ else
+ break;
+ }
+
+ if (argc != 8 && argc != 9)
+ error("Unexpected argument count: %d\n", argc);
+
+ fd = open("/dev/null", O_RDWR);
+ if (fd < 0)
+ error("open");
+ if (fd > 2) {
+ close(fd);
+ }
+ else if (fd < 2) {
+ ret = dup(fd);
+ if (ret < 0)
+ error("dup failed: %m\n");
+
+ if (ret < 2 && dup(fd) < 0)
+ error("dup failed: %m\n");
+ }
+
+ xkey = argv[2];
+ xuid = argv[3];
+ xgid = argv[4];
+ xthread_keyring = argv[5];
+ xprocess_keyring = argv[6];
+ xsession_keyring = argv[7];
+
+ key = atoi(xkey);
+
+ /* assume authority over the key
+ * - older kernel doesn't support this function
+ */
+ ret = keyctl_assume_authority(key);
+ if (ret < 0 && !(argc == 9 || errno == EOPNOTSUPP))
+ error("Failed to assume authority over key %d (%m)\n", key);
+
+ /* ask the kernel to describe the key to us */
+ if (xdebug < 2) {
+ ret = keyctl_describe_alloc(key, &buf);
+ if (ret < 0)
+ goto inaccessible;
+ }
+ else {
+ buf = strdup("user;0;0;1f0000;debug:1234");
+ }
+
+ /* extract the type and description from the key */
+ debug("Key descriptor: \"%s\"\n", buf);
+ ntype = -1;
+ dpos = -1;
+
+ n = sscanf(buf, "%*[^;]%n;%*d;%*d;%x;%n", &ntype, &n, &dpos);
+ if (n != 1)
+ error("Failed to parse key description\n");
+
+ ktype = buf;
+ ktype[ntype] = 0;
+ kdesc = buf + dpos;
+
+ debug("Key type: %s\n", ktype);
+ debug("Key desc: %s\n", kdesc);
+
+ /* get hold of the callout info */
+ callout_info = argv[8];
+
+ if (!callout_info) {
+ void *tmp;
+
+ if (keyctl_read_alloc(KEY_SPEC_REQKEY_AUTH_KEY, &tmp) < 0)
+ error("Failed to retrieve callout info (%m)\n");
+
+ callout_info = tmp;
+ }
+
+ debug("CALLOUT: '%s'\n", callout_info);
+
+ /* determine the action to perform */
+ lookup_action(argv[1], /* op */
+ key, /* ID of key under construction */
+ ktype, /* key type */
+ kdesc, /* key description */
+ callout_info /* call out information */
+ );
+
+inaccessible:
+ error("Key %d is inaccessible (%m)\n", key);
+
+} /* end main() */
+
+/*****************************************************************************/
+/*
+ * determine the action to perform
+ */
+static void lookup_action(char *op,
+ key_serial_t key,
+ char *ktype,
+ char *kdesc,
+ char *callout_info)
+{
+ char buf[4096 + 2], *p, *q;
+ FILE *conf;
+ int len, oplen, ktlen, kdlen, cilen;
+
+ oplen = strlen(op);
+ ktlen = strlen(ktype);
+ kdlen = strlen(kdesc);
+ cilen = strlen(callout_info);
+
+ /* search the config file for a command to run */
+ if (strlen(ktype) <= sizeof(conffile) - 30) {
+ if (xdebug < 2)
+ snprintf(conffile, sizeof(conffile) - 1,
+ "/etc/request-key.d/%s.conf", ktype);
+ else
+ snprintf(conffile, sizeof(conffile) - 1,
+ "request-key.d/%s.conf", ktype);
+ conf = fopen(conffile, "r");
+ if (conf)
+ goto opened_conf_file;
+ if (errno != ENOENT)
+ error("Cannot open %s: %m\n", conffile);
+ }
+
+ if (xdebug < 2)
+ snprintf(conffile, sizeof(conffile) - 1, "/etc/request-key.conf");
+ else
+ snprintf(conffile, sizeof(conffile) - 1, "request-key.conf");
+ conf = fopen(conffile, "r");
+ if (!conf)
+ error("Cannot open %s: %m\n", conffile);
+
+opened_conf_file:
+ debug("Opened config file '%s'\n", conffile);
+
+ for (confline = 1;; confline++) {
+ /* read the file line-by-line */
+ if (!fgets(buf, sizeof(buf), conf)) {
+ if (feof(conf))
+ error("Cannot find command to construct key %d\n", key);
+ file_error("error %m\n");
+ }
+
+ len = strlen(buf);
+ if (len >= sizeof(buf) - 2)
+ line_error("Line too long\n");
+
+ /* ignore blank lines and comments */
+ if (len == 1 || buf[0] == '#' || isspace(buf[0]))
+ continue;
+
+ buf[--len] = 0;
+ p = buf;
+
+ /* attempt to match the op */
+ q = p;
+ while (*p && !isspace(*p)) p++;
+ if (!*p)
+ goto syntax_error;
+ *p = 0;
+
+ if (!match(q, p - q, op, oplen))
+ continue;
+
+ p++;
+
+ /* attempt to match the type */
+ while (isspace(*p)) p++;
+ if (!*p)
+ goto syntax_error;
+
+ q = p;
+ while (*p && !isspace(*p)) p++;
+ if (!*p)
+ goto syntax_error;
+ *p = 0;
+
+ if (!match(q, p - q, ktype, ktlen))
+ continue;
+
+ p++;
+
+ /* attempt to match the description */
+ while (isspace(*p)) p++;
+ if (!*p)
+ goto syntax_error;
+
+ q = p;
+ while (*p && !isspace(*p)) p++;
+ if (!*p)
+ goto syntax_error;
+ *p = 0;
+
+ if (!match(q, p - q, kdesc, kdlen))
+ continue;
+
+ p++;
+
+ /* attempt to match the callout info */
+ while (isspace(*p)) p++;
+ if (!*p)
+ goto syntax_error;
+
+ q = p;
+ while (*p && !isspace(*p)) p++;
+ if (!*p)
+ goto syntax_error;
+ *p = 0;
+
+ if (!match(q, p - q, callout_info, cilen))
+ continue;
+
+ p++;
+
+ debug("%s:%d: Line matches\n", conffile, confline);
+
+ /* we've got an action */
+ while (isspace(*p)) p++;
+ if (!*p)
+ goto syntax_error;
+
+ fclose(conf);
+
+ execute_program(op, key, ktype, kdesc, callout_info, p);
+ }
+
+ file_error("No matching action\n");
+
+syntax_error:
+ line_error("Syntax error\n");
+
+} /* end lookup_action() */
+
+/*****************************************************************************/
+/*
+ * attempt to match a datum to a pattern
+ * - one asterisk is allowed anywhere in the pattern to indicate a wildcard
+ * - returns true if matched, false if not
+ */
+static int match(const char *pattern, int plen, const char *datum, int dlen)
+{
+ const char *asterisk;
+ int n;
+
+ debug("match(%*.*s,%*.*s)\n", plen, plen, pattern, dlen, dlen, datum);
+
+ asterisk = memchr(pattern, '*', plen);
+ if (!asterisk) {
+ /* exact match only if no wildcard */
+ if (plen == dlen && memcmp(pattern, datum, dlen) == 0)
+ goto yes;
+ goto no;
+ }
+
+ /* the datum mustn't be shorter than the pattern without the asterisk */
+ if (dlen < plen - 1)
+ goto no;
+
+ n = asterisk - pattern;
+ if (n == 0) {
+ /* wildcard at beginning of pattern */
+ pattern++;
+ if (!*pattern)
+ goto yes; /* "*" matches everything */
+
+ /* match the end of the datum */
+ plen--;
+ if (memcmp(pattern, datum + (dlen - plen), plen) == 0)
+ goto yes;
+ goto no;
+ }
+
+ /* need to match beginning of datum for "abc*" and "abc*def" */
+ if (memcmp(pattern, datum, n) != 0)
+ goto no;
+
+ if (!asterisk[1])
+ goto yes; /* "abc*" matches */
+
+ /* match the end of the datum */
+ asterisk++;
+ n = plen - n - 1;
+ if (memcmp(pattern, datum + (dlen - n), n) == 0)
+ goto yes;
+
+no:
+ debug(" = no\n");
+ return 0;
+
+yes:
+ debug(" = yes\n");
+ return 1;
+
+} /* end match() */
+
+/*****************************************************************************/
+/*
+ * execute a program to deal with a key
+ */
+static void execute_program(char *op,
+ key_serial_t key,
+ char *ktype,
+ char *kdesc,
+ char *callout_info,
+ char *cmdline)
+{
+ char *argv[256];
+ char *prog, *p, *q;
+ int argc, pipeit;
+
+ debug("execute_program('%s','%s')\n", callout_info, cmdline);
+
+ /* if the commandline begins with a bar, then we pipe the callout data into it and read
+ * back the payload data
+ */
+ pipeit = 0;
+
+ if (cmdline[0] == '|') {
+ pipeit = 1;
+ cmdline++;
+ }
+
+ /* extract the path to the program to run */
+ prog = p = cmdline;
+ while (*p && !isspace(*p)) p++;
+// if (!*p)
+// line_error("No command path\n");
+// *p++ = 0;
+ if (*p)
+ *p++ = 0;
+
+ argv[0] = strrchr(prog, '/') + 1;
+
+ /* extract the arguments */
+ for (argc = 1; p; argc++) {
+ while (isspace(*p)) p++;
+ if (!*p)
+ break;
+
+ if (argc >= 254)
+ line_error("Too many arguments\n");
+ argv[argc] = q = p;
+
+ while (*p && !isspace(*p)) p++;
+
+ if (*p)
+ *p++ = 0;
+ else
+ p = NULL;
+
+ debug("argv[%d]: '%s'\n", argc, argv[argc]);
+
+ if (*q != '%')
+ continue;
+
+ /* it's a macro */
+ q++;
+ if (!*q)
+ line_error("Missing macro name\n");
+
+ if (*q == '%') {
+ /* it's actually an anti-macro escape "%%..." -> "%..." */
+ argv[argc]++;
+ continue;
+ }
+
+ /* single character macros */
+ if (!q[1]) {
+ switch (*q) {
+ case 'o': argv[argc] = op; continue;
+ case 'k': argv[argc] = xkey; continue;
+ case 't': argv[argc] = ktype; continue;
+ case 'd': argv[argc] = kdesc; continue;
+ case 'c': argv[argc] = callout_info; continue;
+ case 'u': argv[argc] = xuid; continue;
+ case 'g': argv[argc] = xgid; continue;
+ case 'T': argv[argc] = xthread_keyring; continue;
+ case 'P': argv[argc] = xprocess_keyring; continue;
+ case 'S': argv[argc] = xsession_keyring; continue;
+ default:
+ line_error("Unsupported macro\n");
+ }
+ }
+
+ /* keysub macro */
+ if (*q == '{') {
+ key_serial_t keysub;
+ void *tmp;
+ char *ksdesc, *end, *subdata;
+ int ret, loop;
+
+ /* extract type and description */
+ q++;
+ ksdesc = strchr(q, ':');
+ if (!ksdesc)
+ line_error("Keysub macro lacks ':'\n");
+ *ksdesc++ = 0;
+ end = strchr(ksdesc, '}');
+ if (!end)
+ line_error("Unterminated keysub macro\n");
+
+ *end++ = 0;
+ if (*end)
+ line_error("Keysub macro has trailing rubbish\n");
+
+ debug("Keysub: %s key \"%s\"\n", q, ksdesc);
+
+ if (!q[0])
+ line_error("Keysub type empty\n");
+
+ if (!ksdesc[0])
+ line_error("Keysub description empty\n");
+
+ /* look up the key in the requestor's keyrings, but fail immediately if the
+ * key is not found rather than invoking /sbin/request-key again
+ */
+ keysub = request_key(q, ksdesc, NULL, 0);
+ if (keysub < 0)
+ line_error("Keysub key not found: %m\n");
+
+ ret = keyctl_read_alloc(keysub, &tmp);
+ if (ret < 0)
+ line_error("Can't read keysub %d data: %m\n", keysub);
+ subdata = tmp;
+
+ for (loop = 0; loop < ret; loop++)
+ if (!isprint(subdata[loop]))
+ error("keysub %d data not printable ('%02hhx')\n",
+ keysub, subdata[loop]);
+
+ argv[argc] = subdata;
+ continue;
+ }
+ }
+
+ if (argc == 0)
+ line_error("No arguments\n");
+
+ argv[argc] = NULL;
+
+ if (xdebug) {
+ char **ap;
+
+ debug("%s %s\n", pipeit ? "PipeThru" : "Run", prog);
+ for (ap = argv; *ap; ap++)
+ debug("- argv[%td] = \"%s\"\n", ap - argv, *ap);
+ }
+
+ /* become the same UID/GID as the key requesting process */
+ //setgid(atoi(xuid));
+ //setuid(atoi(xgid));
+
+ /* if the last argument is a single bar, we spawn off the program dangling on the end of
+ * three pipes and read the key material from the program, otherwise we just exec
+ */
+ if (pipeit)
+ pipe_to_program(op, key, ktype, kdesc, callout_info, prog, argv);
+
+ /* attempt to execute the command */
+ execv(prog, argv);
+
+ line_error("Failed to execute '%s': %m\n", prog);
+
+} /* end execute_program() */
+
+/*****************************************************************************/
+/*
+ * pipe the callout information to the specified program and retrieve the payload data over another
+ * pipe
+ */
+static void pipe_to_program(char *op,
+ key_serial_t key,
+ char *ktype,
+ char *kdesc,
+ char *callout_info,
+ char *prog,
+ char **argv)
+{
+ char errbuf[512], payload[32768 + 1], *pp, *pc, *pe;
+ int ipi[2], opi[2], epi[2], childpid;
+ int ifl, ofl, efl, npay, ninfo, espace, tmp;
+
+ debug("pipe_to_program(%s -> %s)", callout_info, prog);
+
+ if (pipe(ipi) < 0 || pipe(opi) < 0 || pipe(epi) < 0)
+ error("pipe failed: %m");
+
+ childpid = fork();
+ if (childpid == -1)
+ error("fork failed: %m");
+
+ if (childpid == 0) {
+ /* child process */
+ if (dup2(ipi[0], 0) < 0 ||
+ dup2(opi[1], 1) < 0 ||
+ dup2(epi[1], 2) < 0)
+ error("dup2 failed: %m");
+ close(ipi[0]);
+ close(ipi[1]);
+ close(opi[0]);
+ close(opi[1]);
+ close(epi[0]);
+ close(epi[1]);
+
+ execv(prog, argv);
+ line_error("Failed to execute '%s': %m\n", prog);
+ }
+
+ /* parent process */
+ close(ipi[0]);
+ close(opi[1]);
+ close(epi[1]);
+
+#define TOSTDIN ipi[1]
+#define FROMSTDOUT opi[0]
+#define FROMSTDERR epi[0]
+
+ ifl = fcntl(TOSTDIN, F_GETFL);
+ ofl = fcntl(FROMSTDOUT, F_GETFL);
+ efl = fcntl(FROMSTDERR, F_GETFL);
+ if (ifl < 0 || ofl < 0 || efl < 0)
+ error("fcntl/F_GETFL failed: %m");
+
+ ifl |= O_NONBLOCK;
+ ofl |= O_NONBLOCK;
+ efl |= O_NONBLOCK;
+
+ if (fcntl(TOSTDIN, F_SETFL, ifl) < 0 ||
+ fcntl(FROMSTDOUT, F_SETFL, ofl) < 0 ||
+ fcntl(FROMSTDERR, F_SETFL, efl) < 0)
+ error("fcntl/F_SETFL failed: %m");
+
+ ninfo = strlen(callout_info);
+ pc = callout_info;
+
+ npay = sizeof(payload);
+ pp = payload;
+
+ espace = sizeof(errbuf);
+ pe = errbuf;
+
+ do {
+ fd_set rfds, wfds;
+
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+
+ if (TOSTDIN != -1) {
+ if (ninfo > 0) {
+ FD_SET(TOSTDIN, &wfds);
+ }
+ else {
+ close(TOSTDIN);
+ TOSTDIN = -1;
+ continue;
+ }
+ }
+
+ if (FROMSTDOUT != -1)
+ FD_SET(FROMSTDOUT, &rfds);
+
+ if (FROMSTDERR != -1)
+ FD_SET(FROMSTDERR, &rfds);
+
+ tmp = TOSTDIN > FROMSTDOUT ? TOSTDIN : FROMSTDOUT;
+ tmp = tmp > FROMSTDERR ? tmp : FROMSTDERR;
+ tmp++;
+
+ debug("select r=%d,%d w=%d m=%d\n", FROMSTDOUT, FROMSTDERR, TOSTDIN, tmp);
+
+ tmp = select(tmp, &rfds, &wfds, NULL, NULL);
+ if (tmp < 0)
+ error("select failed: %m\n");
+
+ if (TOSTDIN != -1 && FD_ISSET(TOSTDIN, &wfds)) {
+ tmp = write(TOSTDIN, pc, ninfo);
+ if (tmp < 0) {
+ if (errno != EPIPE)
+ error("write failed: %m\n");
+
+ debug("EPIPE");
+ ninfo = 0;
+ }
+ else {
+ debug("wrote %d\n", tmp);
+
+ pc += tmp;
+ ninfo -= tmp;
+ }
+ }
+
+ if (FROMSTDOUT != -1 && FD_ISSET(FROMSTDOUT, &rfds)) {
+ tmp = read(FROMSTDOUT, pp, npay);
+ if (tmp < 0)
+ error("read failed: %m\n");
+
+ debug("read %d\n", tmp);
+
+ if (tmp == 0) {
+ close(FROMSTDOUT);
+ FROMSTDOUT = -1;
+ }
+ else {
+ pp += tmp;
+ npay -= tmp;
+
+ if (npay == 0)
+ error("Too much data read from query program\n");
+ }
+ }
+
+ if (FROMSTDERR != -1 && FD_ISSET(FROMSTDERR, &rfds)) {
+ char *nl;
+
+ tmp = read(FROMSTDERR, pe, espace);
+ if (tmp < 0)
+ error("read failed: %m\n");
+
+ debug("read err %d\n", tmp);
+
+ if (tmp == 0) {
+ close(FROMSTDERR);
+ FROMSTDERR = -1;
+ continue;
+ }
+
+ pe += tmp;
+ espace -= tmp;
+
+ while ((nl = memchr(errbuf, '\n', pe - errbuf))) {
+ int n, rest;
+
+ nl++;
+ n = nl - errbuf;
+
+ if (xdebug)
+ fprintf(stderr, "Child: %*.*s", n, n, errbuf);
+
+ if (!xnolog) {
+ openlog("request-key", 0, LOG_AUTHPRIV);
+ syslog(LOG_ERR, "Child: %*.*s", n, n, errbuf);
+ closelog();
+ }
+
+ rest = pe - nl;
+ if (rest > 0) {
+ memmove(errbuf, nl, rest);
+ pe -= n;
+ espace += n;
+ }
+ else {
+ pe = errbuf;
+ espace = sizeof(errbuf);
+ }
+ }
+
+ if (espace == 0) {
+ int n = sizeof(errbuf);
+
+ if (xdebug)
+ fprintf(stderr, "Child: %*.*s", n, n, errbuf);
+
+ if (!xnolog) {
+ openlog("request-key", 0, LOG_AUTHPRIV);
+ syslog(LOG_ERR, "Child: %*.*s", n, n, errbuf);
+ closelog();
+ }
+
+ pe = errbuf;
+ espace = sizeof(errbuf);
+ }
+ }
+
+ } while (TOSTDIN != -1 || FROMSTDOUT != -1 || FROMSTDERR != -1);
+
+ /* wait for the program to exit */
+ if (waitpid(childpid, &tmp, 0) != childpid)
+ error("wait for child failed: %m\n");
+
+ /* if the process exited non-zero or died on a signal, then we call back in to ourself to
+ * decide on negation
+ * - this is not exactly beautiful but the quickest way of having configurable negation
+ * settings
+ */
+ if (WIFEXITED(tmp) && WEXITSTATUS(tmp) != 0) {
+ if (norecurse)
+ error("child exited %d\n", WEXITSTATUS(tmp));
+
+ norecurse = 1;
+ debug("child exited %d\n", WEXITSTATUS(tmp));
+ lookup_action("negate", key, ktype, kdesc, callout_info);
+ }
+
+ if (WIFSIGNALED(tmp)) {
+ if (norecurse)
+ error("child died on signal %d\n", WTERMSIG(tmp));
+
+ norecurse = 1;
+ debug("child died on signal %d\n", WTERMSIG(tmp));
+ lookup_action("negate", key, ktype, kdesc, callout_info);
+ }
+
+ /* attempt to instantiate the key */
+ debug("instantiate with %td bytes\n", pp - payload);
+
+ if (keyctl_instantiate(key, payload, pp - payload, 0) < 0)
+ error("instantiate key failed: %m\n");
+
+ debug("instantiation successful\n");
+ exit(0);
+
+} /* end pipe_to_program() */
diff --git a/keyutils-1.5.6/request-key.conf b/keyutils-1.5.6/request-key.conf
new file mode 100644
index 0000000..ff16a95
--- /dev/null
+++ b/keyutils-1.5.6/request-key.conf
@@ -0,0 +1,41 @@
+###############################################################################
+#
+# Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+# Written by David Howells (dhowells@redhat.com)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+###############################################################################
+
+
+###############################################################################
+#
+# We can run programs or scripts
+# - Macro substitutions in arguments:
+# %%... %...
+# %o operation name
+# %k ID of key being operated upon
+# %t type of key being operated upon
+# %d description of key being operated upon
+# %c callout info
+# %u UID of requestor
+# %g GID of requestor
+# %T thread keyring of requestor (may be 0)
+# %P process keyring of requestor (may be 0)
+# %S session keyring of requestor (may be the user's default session)
+#
+################################################################################
+
+#OP TYPE DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ...
+#====== ======= =============== =============== ===============================
+create dns_resolver * * /sbin/key.dns_resolver %k
+create user debug:* negate /bin/keyctl negate %k 30 %S
+create user debug:* rejected /bin/keyctl reject %k 30 %c %S
+create user debug:* expired /bin/keyctl reject %k 30 %c %S
+create user debug:* revoked /bin/keyctl reject %k 30 %c %S
+create user debug:loop:* * |/bin/cat
+create user debug:* * /usr/share/keyutils/request-key-debug.sh %k %d %c %S
+negate * * * /bin/keyctl negate %k 30 %S
diff --git a/keyutils-1.5.6/request-key.conf.5 b/keyutils-1.5.6/request-key.conf.5
new file mode 100644
index 0000000..73e0dcb
--- /dev/null
+++ b/keyutils-1.5.6/request-key.conf.5
@@ -0,0 +1,141 @@
+.\" -*- nroff -*-
+.\" Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+.\" Written by David Howells (dhowells@redhat.com)
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version
+.\" 2 of the License, or (at your option) any later version.
+.\"
+.TH REQUEST-KEY.CONF 5 "15 November 2011" Linux "Linux Key Management Utilities"
+.SH NAME
+request-key.conf - Instantiation handler configuration file
+.SH DESCRIPTION
+.P
+This file and its associated key-type specific variants are used by the
+/sbin/request-key program to determine which program it should run to
+instantiate a key.
+.P
+request-key looks first in /etc/request-key.d/ for a file of the key type name
+plus ".conf" that it can use. If that is not found, it will fall back to
+/etc/request-key.conf.
+.P
+request-key scans through the chosen file one line at a time until it
+finds a match, which it will then use. If it doesn't find a match, it'll return
+an error and the kernel will automatically negate the key.
+.P
+Any blank line or line beginning with a hash mark '#' is considered to be a
+comment and ignored.
+.P
+All other lines are assumed to be command lines with a number of white space
+separated fields:
+.P
+<op> <type> <description> <callout-info> <prog> <arg1> <arg2> ...
+.P
+The first four fields are used to match the parameters passed to request-key by
+the kernel. \fIop\fR is the operation type; currently the only supported
+operation is "create".
+.P
+\fItype\fR, \fIdescription\fR and \fIcallout-info\fR match the three parameters
+passed to \fBkeyctl request2\fR or the \fBrequest_key()\fR system call. Each of
+these may contain one or more asterisk '*' characters as wildcards anywhere
+within the string.
+.P
+Should a match be made, the program specified by <prog> will be exec'd. This
+must have a fully qualified path name. argv[0] will be set from the part of the
+program name that follows the last slash '/' character.
+.P
+If the program name is prefixed with a pipe bar character '|', then the program
+will be forked and exec'd attached to three pipes. The callout information will
+be piped to it on it's stdin and the intended payload data will be retrieved
+from its stdout. Anything sent to stderr will be posted in syslog. If the
+program exits 0, then /sbin/request-key will attempt to instantiate the key
+with the data read from stdout. If it fails in any other way, then request-key
+will attempt to execute the appropriate 'negate' operation command.
+.P
+The program arguments can be substituted with various macros. Only complete
+argument substitution is supported - macro substitutions can't be embedded. All
+macros begin with a percent character '%'. An argument beginning with two
+percent characters will have one of them discarded.
+.P
+The following macros are supported:
+.P
+.RS
+%o Operation type
+.br
+%k Key ID
+.br
+%t Key type
+.br
+%d Key description
+.br
+%c Callout information
+.br
+%u Key UID
+.br
+%g Key GID
+.br
+%T Requestor's thread keyring
+.br
+%P Requestor's process keyring
+.br
+%S Requestor's session keyring
+.RE
+.P
+There's another macro substitution too that permits the interpolation of the
+contents of a key:
+.P
+.RS
+%{<type>:<description>}
+.RE
+.P
+This performs a lookup for a key of the given type and description on the
+requestor's keyrings, and if found, substitutes the contents for the macro. If
+not found an error will be logged and the key under construction will be
+negated.
+.SH EXAMPLE
+.P
+A basic file will be installed in the /etc. This will contain two debugging
+lines that can be used to test the installation:
+.P
+.RS
+create user debug:* negate /bin/keyctl negate %k 30 %S
+.br
+create user debug:loop:* * |/bin/cat
+.br
+create user debug:* * /usr/share/keyutils/request-key-debug.sh %k %d %c %S
+.br
+negate * * * /bin/keyctl negate %k 30 %S
+.RE
+.P
+This is set up so that something like:
+.P
+.RS
+keyctl request2 user debug:xxxx negate
+.RE
+.P
+will create a negative user-defined key, something like:
+.P
+.RS
+keyctl request2 user debug:yyyy spoon
+.RE
+.P
+will create an instantiated user-defined key with "Debug spoon" as the payload,
+and something like:
+.P
+.RS
+keyctl request2 user debug:loop:zzzz abcdefghijkl
+.RE
+.P
+will create an instantiated user-defined key with the callout information as
+the payload.
+.SH FILES
+.ul
+/etc/request-key.conf
+.ul 0
+.br
+.ul
+/etc/request-key.d/<keytype>.conf
+.ul 0
+.SH SEE ALSO
+\fBkeyctl\fR(1), \fBrequest-key.conf\fR(5)
diff --git a/keyutils-1.5.6/tests/Makefile b/keyutils-1.5.6/tests/Makefile
new file mode 100644
index 0000000..fe5b4df
--- /dev/null
+++ b/keyutils-1.5.6/tests/Makefile
@@ -0,0 +1,75 @@
+# Copyright (c) 2006 Red Hat, Inc. All rights reserved. This copyrighted material
+# is made available to anyone wishing to use, modify, copy, or
+# redistribute it subject to the terms and conditions of the GNU General
+# Public License v.2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Author: David Howells <dhowells@redhat.com>
+# Updated to new Make model by Bill Peck <bpeck@redhat.com>
+
+# The toplevel namespace within which the test lives.
+TOPLEVEL_NAMESPACE=/kernel
+
+# The name of the package under test:
+PACKAGE_NAME=keyutils
+
+# The path of the test below the package:
+RELATIVE_PATH=testsuite
+
+# Version of the Test. Used with make tag.
+export TESTVERSION=1.3
+
+# The combined namespace of the test.
+export TEST=$(TOPLEVEL_NAMESPACE)/$(PACKAGE_NAME)/$(RELATIVE_PATH)
+
+.PHONY: all install download clean
+
+TESTS = $(shell /usr/bin/find . -name runtest.sh | \
+ /bin/sed -e 's/runtest.sh//g;s/^\.\///;s/\/$$//')
+
+BUILT_FILES=
+FILES=$(METADATA) runtest.sh Makefile PURPOSE toolbox.inc.sh keyctl \
+ prepare.inc.sh
+
+run: $(FILES) build
+ sh runtest.sh $(TESTS)
+
+build: $(BUILT_FILES)
+
+clean:
+ rm -f *~ *.rpm $(BUILT_FILES)
+ find keyctl -name test.out -delete
+
+# You may need to add other targets e.g. to build executables from source code
+# Add them here:
+
+
+# Include Common Makefile
+ifneq ($(wild /usr/share/rhts/lib/rhts-make.include),)
+include /usr/share/rhts/lib/rhts-make.include
+
+# Generate the testinfo.desc here:
+$(METADATA): Makefile
+ @touch $(METADATA)
+ @echo "Owner: David Howells <dhowells@redhat.com>" > $(METADATA)
+ @echo "Name: $(TEST)" >> $(METADATA)
+ @echo "Path: $(TEST_DIR)" >> $(METADATA)
+ @echo "License: Unknown" >> $(METADATA)
+ @echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
+ @echo "Description: testsuite to verify keyutils ">> $(METADATA)
+ @echo "TestTime: 30m" >> $(METADATA)
+ @echo "RunFor: $(PACKAGE_NAME)" >> $(METADATA)
+ @echo "Requires: $(PACKAGE_NAME)" >> $(METADATA)
+ @echo "Releases: -RHEL2.1 -RHEL3" >> $(METADATA)
+ @echo "Type: Tier1" >> $(METADATA)
+ @echo "Type: KernelTier1" >> $(METADATA)
+ rhts-lint $(METADATA)
+
+endif
diff --git a/keyutils-1.5.6/tests/PURPOSE b/keyutils-1.5.6/tests/PURPOSE
new file mode 100644
index 0000000..064e775
--- /dev/null
+++ b/keyutils-1.5.6/tests/PURPOSE
@@ -0,0 +1,82 @@
+The purpose of this testsuite is to do negative and positive testing against
+the keyutils package.
+Sub Test Description
+------------------ -----------------------------------------------------
+/listing/noargs Check list/rlist subcommands fail with the wrong
+ number of arguments
+/listing/bad-args Check list/rlist subcommands fail with bad arguments
+/listing/valid Check list/rlist subcommands work
+/show/noargs Check show subcommand works with no arguments
+/reading/noargs Check read/pipe/print subcommands fail with the wrong
+ number of arguments
+/reading/bad-args Check read/pipe/print subcommands fail with bad
+ arguments
+/reading/valid Check read/pipe/print subcommands work
+/pupdate/noargs Check pupdate subcommand fails with the wrong number
+ of arguments
+/pupdate/bad-args Check pupdate subcommand fails with bad arguments
+/pupdate/userupdate Check pupdate subcommand works for user defined keys
+/newring/noargs Check newring subcommand fails with the wrong number
+ of arguments
+/newring/bad-args Check newring subcommand fails with a bad arguments
+/newring/valid Check newring subcommand works
+/session/bad-args Check session subcommand fails with bad arguments
+/session/valid Check session subcommand works
+/clear/noargs Check clear subcommand fails with the wrong number of
+ arguments
+/clear/bad-args Check clear subcommand fails with a bad arguments
+/clear/valid Check clear subcommand works
+/instantiating/noargs Check instantiate/negate subcommands fail with the
+ wrong number of arguments
+/instantiating/bad-args Check instantiate/negate subcommands fail with bad
+ arguments
+/permitting/noargs Check chown/chgrp/setperm subcommands fail with the
+ wrong number of arguments
+/permitting/bad-args Check chown/chgrp/setperm subcommands fail with bad
+ arguments
+/permitting/valid Check chown/chgrp/setperm subcommands work
+/describing/noargs Check describe/rdescribe subcommands fail with the
+ wrong number of arguments
+/describing/bad-args Check describe/rdescribe subcommands fail with bad
+ arguments
+/describing/valid Check describe/rdescribe subcommands work
+/noargs Check keyutils with no args gives format list
+/revoke/noargs Check revoke subcommand fails with the wrong number of
+ arguments
+/revoke/bad-args Check revoke subcommand fails with a bad arguments
+/revoke/valid Check revoke subcommand works
+/padd/noargs Check padd subcommand fails with the wrong number of
+ arguments
+/padd/bad-args Check padd subcommand fails with bad arguments
+/padd/useradd Check padd subcommand works
+/timeout/noargs Check timeout subcommand fails with the wrong number
+ of arguments
+/timeout/bad-args Check timeout subcommand fails with a bad arguments
+/timeout/valid Check timeout subcommand works
+/update/noargs Check update subcommand fails with the wrong number of
+ arguments
+/update/bad-args Check update subcommand fails with bad arguments
+/update/userupdate Check update subcommand works for user defined keys
+/search/noargs Check search subcommand fails with the wrong number of
+ arguments
+/search/bad-args Check search subcommand fails with a bad arguments
+/search/valid Check search subcommand works
+/link/recursion Check link subcommand handles recursive links correctly
+/link/noargs Check link subcommand fails with the wrong number of
+ arguments
+/link/bad-args Check link subcommand fails with bad arguments
+/link/valid Check link subcommand works
+/add/noargs Check add subcommand fails with the wrong number of
+ arguments
+/add/bad-args Check add subcommand fails with a bad arguments
+/add/useradd Check add subcommand works
+/requesting/piped Check request/prequest2 subcommands work
+/requesting/noargs Check request/request2 subcommands fail with the
+ wrong number of arguments
+/requesting/bad-args Check request/request2 subcommands fail with bad
+ arguments
+/requesting/valid Check request/request2 subcommands work
+/unlink/noargs Check unlink subcommand fails with the wrong number of
+ arguments
+/unlink/bad-args Check unlink subcommand fails with a bad arguments
+/unlink/valid Check unlink subcommand works
diff --git a/keyutils-1.5.6/tests/keyctl/add/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/add/bad-args/runtest.sh
new file mode 100644
index 0000000..8419fbc
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/add/bad-args/runtest.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that an empty key type fails correctly
+marker "CHECK EMPTY KEY TYPE"
+create_key --fail "" wibble stuff @p
+expect_error EINVAL
+
+# check that an unsupported key type fails correctly
+marker "CHECK UNSUPPORTED KEY TYPE"
+create_key --fail lizardsgizzards wibble stuff @p
+expect_error ENODEV
+
+# check that an invalid key type fails correctly
+marker "CHECK INVALID KEY TYPE"
+create_key --fail .user wibble stuff @p
+expect_error EPERM
+
+# check that an maximum length invalid key type fails correctly
+marker "CHECK MAXLEN KEY TYPE"
+create_key --fail $maxtype wibble stuff @p
+expect_error ENODEV
+
+# check that an overlong key type fails correctly
+marker "CHECK OVERLONG KEY TYPE"
+create_key --fail a$maxtype wibble stuff @p
+expect_error EINVAL
+
+# check that creation of a keyring with non-empty payload fails correctly
+marker "CHECK ADD KEYRING WITH PAYLOAD"
+create_key --fail keyring wibble a @p
+expect_error EINVAL
+
+# check that an max length key description works correctly (PAGE_SIZE inc NUL)
+if [ $PAGE_SIZE -lt $maxsquota ]
+then
+ marker "CHECK MAXLEN DESC"
+ create_key user $maxdesc stuff @p
+ expect_keyid keyid
+else
+ marker "CHECK MAXLEN DESC FAILS WITH EDQUOT"
+ create_key --fail user $maxdesc stuff @p
+ expect_error EDQUOT
+fi
+
+# check that an overlong key description fails correctly (>4095 inc NUL)
+marker "CHECK OVERLONG DESC"
+create_key --fail user a$maxdesc stuff @p
+
+expect_error EINVAL
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+create_key --fail user wibble stuff 0
+expect_error EINVAL
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/add/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/add/noargs/runtest.sh
new file mode 100644
index 0000000..bdd8348
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/add/noargs/runtest.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "ADD NO ARGS"
+expect_args_error keyctl add
+
+# check that one argument fails correctly
+marker "ADD ONE ARG"
+expect_args_error keyctl add user
+
+# check that two arguments fail correctly
+marker "ADD TWO ARGS"
+expect_args_error keyctl add user wibble
+
+# check that three arguments fail correctly
+marker "ADD THREE ARGS"
+expect_args_error keyctl add user wibble stuff
+
+# check that five arguments fail correctly
+marker "ADD FIVE ARGS"
+expect_args_error keyctl add user wibble stuff @s x
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/add/useradd/runtest.sh b/keyutils-1.5.6/tests/keyctl/add/useradd/runtest.sh
new file mode 100644
index 0000000..33e633c
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/add/useradd/runtest.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that we can add a user key to the session keyring
+marker "ADD USER KEY"
+create_key user wibble stuff @s
+expect_keyid keyid
+
+# read back what we put in it
+marker "PRINT PAYLOAD"
+print_key $keyid
+expect_payload payload "stuff"
+
+# check that we can update a user key
+marker "UPDATE USER KEY"
+create_key user wibble lizard @s
+
+# check we get the same key ID back
+expect_keyid keyid2
+
+if [ "x$keyid" != "x$keyid2" ]
+then
+ failed
+fi
+
+# read back what we changed it to
+marker "PRINT UPDATED PAYLOAD"
+print_key $keyid
+expect_payload payload "lizard"
+
+# attempt to add a key to that non-keyring key
+marker "ADD KEY TO NON-KEYRING"
+create_key --fail user lizard gizzards $keyid
+expect_error ENOTDIR
+
+# remove the key we added
+marker "UNLINK KEY"
+unlink_key $keyid @s
+
+keyctl show
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/clear/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/clear/bad-args/runtest.sh
new file mode 100644
index 0000000..b3e9d4c
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/clear/bad-args/runtest.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK CLEAR BAD KEY ID"
+clear_keyring --fail 0
+expect_error EINVAL
+
+# create a non-keyring
+marker "CREATE KEY"
+create_key user lizard gizzard @s
+expect_keyid keyid
+
+# check that a non-keyring ID fails correctly
+marker "CHECK CLEAR NON-KEYRING KEY"
+clear_keyring --fail $keyid
+expect_error ENOTDIR
+
+# dispose of the key we were using
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK CLEAR NON-EXISTENT KEY ID"
+clear_keyring --fail $keyid
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/clear/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/clear/noargs/runtest.sh
new file mode 100644
index 0000000..48c672f
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/clear/noargs/runtest.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "NO ARGS"
+expect_args_error keyctl clear
+
+# check that one argument fails correctly
+marker "TWO ARGS"
+expect_args_error keyctl clear 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/clear/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/clear/valid/runtest.sh
new file mode 100644
index 0000000..3a1619b
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/clear/valid/runtest.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# validate the new keyring's name and type
+marker "VALIDATE KEYRING"
+describe_key $keyringid
+expect_key_rdesc rdesc 'keyring@.*@wibble'
+
+# check that we have an empty keyring
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# clear the empty keyring
+marker "CLEAR EMPTY KEYRING"
+clear_keyring $keyringid
+
+# check that it's empty again
+marker "LIST KEYRING 2"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# stick a key in the keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# check that we can list it
+marker "LIST KEYRING WITH ONE"
+list_keyring $keyringid
+expect_keyring_rlist rlist $keyid
+
+# clear the keyring
+marker "CLEAR KEYRING WITH ONE"
+clear_keyring $keyringid
+
+# check that it's now empty again
+marker "LIST KEYRING 3"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# stick forty keys in the keyring
+marker "ADD FORTY KEYS"
+keys=""
+for ((i=0; i<40; i++))
+ do
+ create_key user lizard$i gizzard$i $keyringid
+ expect_keyid x
+ keys="$keys $x"
+ list_keyring $keyringid
+ expect_keyring_rlist rlist $x
+done
+
+marker "CHECK KEYRING CONTENTS"
+list_keyring $keyringid
+for i in $keys
+do
+ expect_keyring_rlist rlist $i
+done
+
+marker "SHOW KEYRING"
+if ! keyctl show >>$OUTPUTFILE 2>&1
+then
+ failed
+fi
+
+# clear the keyring
+marker "CLEAR KEYRING WITH ONE"
+clear_keyring $keyringid
+
+# check that it's now empty yet again
+marker "LIST KEYRING 4"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# remove the keyring we added
+marker "UNLINK KEY"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/describing/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/describing/bad-args/runtest.sh
new file mode 100644
index 0000000..5a6bc22
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/describing/bad-args/runtest.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+describe_key --fail 0
+expect_error EINVAL
+pretty_describe_key --fail 0
+expect_error EINVAL
+
+# create a key
+marker "CREATE KEY"
+create_key user lizard gizzard @s
+expect_keyid keyid
+
+# dispose of the key
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK NON-EXISTENT KEY ID"
+describe_key --fail $keyid
+expect_error ENOKEY
+pretty_describe_key --fail $keyid
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/describing/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/describing/noargs/runtest.sh
new file mode 100644
index 0000000..e96d022
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/describing/noargs/runtest.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+marker "NO ARGS"
+expect_args_error keyctl describe
+expect_args_error keyctl rdescribe
+
+marker "TWO ARGS"
+expect_args_error keyctl describe 0 0
+
+marker "THREE ARGS"
+expect_args_error keyctl rdescribe 0 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/describing/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/describing/valid/runtest.sh
new file mode 100644
index 0000000..40a6cfd
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/describing/valid/runtest.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# validate the new keyring's name and type
+marker "VALIDATE KEYRING"
+describe_key $keyringid
+expect_key_rdesc rdesc 'keyring@.*@wibble'
+
+# validate a pretty description of the keyring
+marker "VALIDATE PRETTY KEYRING"
+pretty_describe_key $keyringid
+expect_key_rdesc pdesc " *$keyringid: [-avrwsl]* *[-0-9]* *[-0-9]* keyring: wibble"
+
+# check that we have an empty keyring
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# stick a key in the keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# validate the new key's name and type
+marker "VALIDATE KEY"
+describe_key $keyid
+expect_key_rdesc rdesc 'user@.*@lizard'
+
+# validate a pretty description of the key
+marker "VALIDATE PRETTY KEY"
+pretty_describe_key $keyid
+expect_key_rdesc pdesc " *$keyid: [-avrwsl]* *[0-9]* *[-0-9]* user: lizard"
+
+# turn off view permission on the key
+marker "DISABLE VIEW PERM"
+set_key_perm $keyid 0x3e0000
+describe_key --fail $keyid
+expect_error EACCES
+
+# turn on view permission on the key
+marker "REINSTATE VIEW PERM"
+set_key_perm $keyid 0x3f0000
+describe_key $keyid
+
+# revoke the key
+marker "REVOKE KEY"
+revoke_key $keyid
+describe_key --fail $keyid
+expect_error EKEYREVOKED
+
+# remove the keyring we added
+marker "UNLINK KEY"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/instantiating/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/instantiating/bad-args/runtest.sh
new file mode 100644
index 0000000..7aa2792
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/instantiating/bad-args/runtest.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+instantiate_key --fail 0 a @p
+expect_error EPERM
+pinstantiate_key --fail a 0 @p
+expect_error EPERM
+negate_key --fail 0 10 @p
+expect_error EPERM
+
+# create a non-keyring
+marker "CREATE KEY"
+create_key user lizard gizzard @s
+expect_keyid keyid
+
+# check that instantiation of an instantiated key fails
+marker "CHECK ALREADY INSTANTIATED KEY"
+instantiate_key --fail $keyid a @p
+expect_error EPERM
+pinstantiate_key --fail a $keyid @p
+expect_error EPERM
+negate_key --fail $keyid 10 @p
+expect_error EPERM
+
+# check negative key timeout must be a number
+marker "CHECK NEGATE TIMEOUT"
+expect_args_error keyctl negate $keyid aa @p
+
+# dispose of the key we were using
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK NON-EXISTENT KEY ID"
+instantiate_key --fail 0 a @p
+expect_error EPERM
+pinstantiate_key --fail a 0 @p
+expect_error EPERM
+negate_key --fail 0 10 @p
+expect_error EPERM
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/instantiating/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/instantiating/noargs/runtest.sh
new file mode 100644
index 0000000..8603818
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/instantiating/noargs/runtest.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+marker "NO ARGS"
+expect_args_error keyctl instantiate
+expect_args_error keyctl pinstantiate
+expect_args_error keyctl negate
+
+marker "ONE ARG"
+expect_args_error keyctl instantiate 0
+expect_args_error keyctl pinstantiate 0
+expect_args_error keyctl negate 0
+
+marker "TWO ARGS"
+expect_args_error keyctl instantiate 0 0
+expect_args_error keyctl negate 0 0
+
+marker "THREE ARGS"
+expect_args_error keyctl pinstantiate 0 0 0
+
+marker "FOUR ARGS"
+expect_args_error keyctl instantiate 0 0 0 0
+expect_args_error keyctl negate 0 0 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/link/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/link/bad-args/runtest.sh
new file mode 100644
index 0000000..37fe20c
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/link/bad-args/runtest.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK LINK FROM BAD KEY ID"
+link_key --fail 0 @s
+expect_error EINVAL
+
+marker "CHECK LINK TO BAD KEY ID"
+link_key --fail @s 0
+expect_error EINVAL
+
+# create a non-keyring
+marker "CREATE KEY"
+create_key user lizard gizzard @s
+expect_keyid keyid
+
+# check that linking to a non-keyring ID fails correctly
+marker "CHECK LINK TO NON-KEYRING KEY"
+link_key --fail @s $keyid
+expect_error ENOTDIR
+
+# dispose of the key we were using
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK LINK TO NON-EXISTENT KEY ID"
+link_key --fail @s $keyid
+expect_error ENOKEY
+
+marker "CHECK LINK FROM NON-EXISTENT KEY ID"
+link_key --fail $keyid @s
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/link/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/link/noargs/runtest.sh
new file mode 100644
index 0000000..f11426c
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/link/noargs/runtest.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "NO ARGS"
+expect_args_error keyctl link
+
+# check that one argument fails correctly
+marker "ONE ARGS"
+expect_args_error keyctl link 0
+
+# check that three arguments fails correctly
+marker "THREE ARGS"
+expect_args_error keyctl link 0 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/link/recursion/runtest.sh b/keyutils-1.5.6/tests/keyctl/link/recursion/runtest.sh
new file mode 100644
index 0000000..e6f5931
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/link/recursion/runtest.sh
@@ -0,0 +1,183 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "CREATE KEYRING 1"
+create_keyring "first" @s
+expect_keyid keyringid
+set_key_perm $keyringid 0x3f3f0000
+
+# attempt to link a keyring to itself
+marker "RECURSE 1"
+link_key --fail $keyringid $keyringid
+expect_error EDEADLK
+
+# create a second keyring in the first
+marker "CREATE KEYRING 2"
+create_keyring "second" $keyringid
+expect_keyid keyring2id
+set_key_perm $keyring2id 0x3f3f0000
+
+# attempt to link a keyring to its child keyring
+marker "RECURSE 2"
+link_key --fail $keyringid $keyring2id
+expect_error EDEADLK
+
+# create a third keyring in the second
+marker "CREATE KEYRING 3"
+create_keyring "third" $keyring2id
+expect_keyid keyring3id
+set_key_perm $keyring3id 0x3f3f0000
+
+# attempt to link a keyring to its grandchild keyring
+marker "RECURSE 3"
+link_key --fail $keyringid $keyring3id
+expect_error EDEADLK
+
+# create a fourth keyring in the third
+marker "CREATE KEYRING 4"
+create_keyring "fourth" $keyring3id
+expect_keyid keyring4id
+set_key_perm $keyring4id 0x3f3f0000
+
+# attempt to link a keyring to its great grandchild keyring
+marker "RECURSE 4"
+link_key --fail $keyringid $keyring4id
+expect_error EDEADLK
+
+# create a fifth keyring in the fourth
+marker "CREATE KEYRING 5"
+create_keyring "fifth" $keyring4id
+expect_keyid keyring5id
+set_key_perm $keyring5id 0x3f3f0000
+
+# attempt to link a keyring to its great great grandchild keyring
+marker "RECURSE 5"
+link_key --fail $keyringid $keyring5id
+expect_error EDEADLK
+
+# create a sixth keyring in the fifth
+marker "CREATE KEYRING 6"
+create_keyring "sixth" $keyring5id
+expect_keyid keyring6id
+set_key_perm $keyring6id 0x3f3f0000
+
+# attempt to link a keyring to its great great great grandchild keyring
+marker "RECURSE 6"
+link_key --fail $keyringid $keyring6id
+expect_error EDEADLK
+
+# create a seventh keyring in the sixth
+marker "CREATE KEYRING 7"
+create_keyring "seventh" $keyring6id
+expect_keyid keyring7id
+set_key_perm $keyring7id 0x3f3f0000
+
+# attempt to link a keyring to its great great great great grandchild keyring
+marker "RECURSE 7"
+link_key --fail $keyringid $keyring7id
+expect_error EDEADLK
+
+# create an eigth keyring in the seventh
+marker "CREATE KEYRING 8"
+create_keyring "eighth" @s
+expect_keyid keyring8id
+set_key_perm $keyring8id 0x3f3f0000
+link_key $keyring8id $keyring7id
+unlink_key $keyring8is @s
+
+# attempt to link a keyring to its great great great great great grandchild keyring
+marker "RECURSE 8"
+link_key --fail $keyringid $keyring8id
+expect_error EDEADLK
+
+# create a ninth keyring in the eighth
+marker "CREATE KEYRING 9"
+create_keyring "ninth" $keyring8id
+expect_keyid keyring9id
+set_key_perm $keyring9id 0x3f3f0000
+
+# attempt to link a keyring to its great great great great great great grandchild keyring
+marker "RECURSE 9"
+link_key --fail $keyringid $keyring9id
+expect_error ELOOP
+
+# remove the first keyring we added
+marker "UNLINK KEYRING"
+unlink_key $keyringid @s
+
+# create two stacks of keyrings
+marker "CREATE KEYRING STACKS"
+create_keyring "A1" @s
+expect_keyid aroot
+create_keyring "B1" @s
+expect_keyid broot
+a=$aroot
+b=$broot
+
+for ((i=2; i<=4; i++))
+ do
+ create_keyring "A$i" $a
+ expect_keyid a
+ create_keyring "B$i" $b
+ expect_keyid b
+done
+
+# make sure we can't create a cycle by linking the two stacks together
+marker "LINK A TO B"
+link_key $aroot $b
+
+marker "LINK B TO A"
+link_key --fail $broot $a
+expect_error EDEADLK
+
+marker "UNLINK A FROM B"
+unlink_key $aroot $b
+
+marker "LINK B TO A"
+link_key $broot $a
+
+marker "LINK A TO B"
+link_key --fail $aroot $b
+expect_error EDEADLK
+
+marker "UNLINK B FROM A"
+unlink_key $broot $a
+
+# extend the stacks
+marker "EXTEND STACKS"
+create_keyring "A5" $a
+expect_keyid a
+create_keyring "B5" $b
+expect_keyid b
+
+# make sure we can't hide a cycle by linking the two bigger stacks together
+marker "CHECK MAXDEPTH A TO B"
+link_key $aroot $b
+link_key --fail $broot $a
+expect_error ELOOP
+unlink_key $aroot $b
+
+marker "CHECK MAXDEPTH B TO A"
+link_key $broot $a
+link_key --fail $aroot $b
+expect_error ELOOP
+unlink_key $broot $a
+
+# remove the two stacks
+marker "UNLINK STACKS"
+unlink_key $aroot @s
+unlink_key $broot @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/link/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/link/valid/runtest.sh
new file mode 100644
index 0000000..242a495
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/link/valid/runtest.sh
@@ -0,0 +1,139 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# validate the new keyring's name and type
+marker "VALIDATE KEYRING"
+describe_key $keyringid
+expect_key_rdesc rdesc 'keyring@.*@wibble'
+
+# check that we can list it
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# stick a key in the keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# check that we can list it
+marker "LIST KEYRING WITH ONE"
+list_keyring $keyringid
+expect_keyring_rlist rlist $keyid
+
+# link the key across to the session keyring
+marker "LINK KEY 1"
+link_key $keyid @s
+
+marker "CHECK KEY LINKAGE"
+list_keyring @s
+expect_keyring_rlist srlist $keyid
+
+# link the key across to the session keyring again and again
+marker "LINK KEY 2"
+link_key $keyid @s
+
+marker "LINK KEY 3"
+link_key $keyid @s
+
+# subsequent links should displace earlier links, giving us a maximum of 1 link
+marker "COUNT LINKS"
+list_keyring @s
+expect_keyring_rlist srlist
+
+nlinks=0
+for i in $srlist
+ do
+ if [ "x$i" = "x$keyid" ]
+ then
+ nlinks=$(($nlinks + 1))
+ fi
+done
+
+if [ $nlinks != 1 ]
+then
+ failed
+fi
+
+# remove the links
+marker "UNLINK KEY FROM SESSION"
+unlink_key $keyid @s
+
+# removing again should fail
+unlink_key --fail $keyid @s
+expect_error ENOENT
+
+# remove that key from the keyring (the key should be destroyed)
+marker "UNLINK KEY FROM KEYRING"
+unlink_key --wait $keyid $keyringid
+
+# and a second time should fail, but now the key doesn't exist
+unlink_key --fail $keyid $keyringid
+expect_error ENOKEY
+
+# create a second keyring in the first
+create_keyring "zebra" $keyringid
+expect_keyid keyring2id
+
+# link thrice across to the session keyring
+marker "LINK 2ND KEYRING TO SESSION"
+link_key $keyring2id @s
+link_key $keyring2id @s
+link_key $keyring2id @s
+
+# subsequent links should displace earlier links, giving us a maximum of 1 link
+marker "COUNT KEYRING LINKS"
+list_keyring @s
+expect_keyring_rlist srlist
+
+nlinks=0
+for i in $srlist
+ do
+ if [ "x$i" = "x$keyring2id" ]
+ then
+ nlinks=$(($nlinks + 1))
+ fi
+done
+
+if [ $nlinks != 1 ]
+then
+ failed
+fi
+
+# remove the keyring links
+marker "UNLINK 2ND KEYRING FROM SESSION"
+unlink_key $keyring2id @s
+
+# removing again should fail
+unlink_key --fail $keyring2id @s
+expect_error ENOENT
+
+# make another keyring link
+marker "LINK 2ND KEYRING TO SESSION"
+link_key $keyring2id @s
+
+# remove the first keyring we added
+marker "UNLINK KEYRING"
+unlink_key --wait $keyringid @s
+
+# remove the second keyring we added
+marker "UNLINK 2ND KEYRING"
+unlink_key --wait $keyring2id @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/listing/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/listing/bad-args/runtest.sh
new file mode 100644
index 0000000..339ab0f
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/listing/bad-args/runtest.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+list_keyring --fail 0
+expect_error ENOKEY
+pretty_list_keyring --fail 0
+expect_error ENOKEY
+
+# create a non-keyring
+marker "CREATE KEY"
+create_key user lizard gizzard @s
+expect_keyid keyid
+
+# dispose of the key we were using
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK NON-EXISTENT KEY ID"
+list_keyring --fail $keyid
+expect_error ENOKEY
+pretty_list_keyring --fail $keyid
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/listing/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/listing/noargs/runtest.sh
new file mode 100644
index 0000000..59c97c1
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/listing/noargs/runtest.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+marker "NO ARGS"
+expect_args_error keyctl list
+expect_args_error keyctl rlist
+
+marker "TWO ARGS"
+expect_args_error keyctl list 0 0
+expect_args_error keyctl rlist 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/listing/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/listing/valid/runtest.sh
new file mode 100644
index 0000000..0f64d0b
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/listing/valid/runtest.sh
@@ -0,0 +1,109 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# validate the new keyring's name and type
+marker "VALIDATE KEYRING"
+describe_key $keyringid
+expect_key_rdesc rdesc 'keyring@.*@wibble'
+
+# check that we have an empty keyring
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+marker "PRETTY LIST KEYRING"
+pretty_list_keyring $keyringid
+expect_payload payload "keyring is empty"
+
+# stick a key in the keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# check that we can list it
+marker "LIST KEYRING WITH ONE"
+list_keyring $keyringid
+expect_keyring_rlist rlist $keyid
+
+# check that we can pretty list it
+marker "PRETTY LIST KEYRING WITH ONE"
+pretty_list_keyring $keyringid
+expect_payload payload
+
+if ! expr "$payload" : " *$keyid:.*user: lizard" >&/dev/null
+then
+ failed
+fi
+
+# stick a second key in the keyring
+marker "ADD KEY 2"
+create_key user snake skin $keyringid
+expect_keyid keyid2
+
+# check that we can see both keys
+marker "LIST KEYRING WITH TWO"
+list_keyring $keyringid
+expect_keyring_rlist rlist
+
+if [ "x$rlist" != "x$keyid $keyid2" ]
+then
+ failed
+fi
+
+# check that we can see both keys prettily
+marker "PRETTY LIST KEYRING WITH TWO"
+pretty_list_keyring $keyringid
+prlist=""
+for i in `tail -2 $OUTPUTFILE | cut -d: -f1 | sed -e 's@ +@@g'`
+ do
+ prlist="$prlist $i"
+done
+
+if [ "x$prlist" != "x $keyid $keyid2" ]
+then
+ failed
+fi
+
+# turn off read permission on the keyring
+marker "DISABLE READ PERM"
+set_key_perm $keyringid 0x3d0000
+list_keyring $keyringid
+
+# turn off read and search permission on the keyring
+marker "DISABLE SEARCH PERM"
+set_key_perm $keyringid 0x350000
+list_keyring --fail $keyringid
+expect_error EACCES
+
+# turn on read permission on the keyring
+marker "REINSTATE READ PERM"
+set_key_perm $keyringid 0x370000
+list_keyring $keyringid
+
+# revoke the keyring
+marker "REVOKE KEYRING"
+revoke_key $keyringid
+list_keyring --fail $keyringid
+expect_error EKEYREVOKED
+
+# remove the keyring we added
+marker "UNLINK KEY"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/newring/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/newring/bad-args/runtest.sh
new file mode 100644
index 0000000..54655c3
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/newring/bad-args/runtest.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that an max length key description works correctly (4096 inc NUL)
+if [ $PAGE_SIZE -lt $maxsquota ]
+then
+ marker "CHECK MAXLEN DESC"
+ create_keyring $maxdesc @p
+ expect_keyid keyid
+else
+ marker "CHECK MAXLEN DESC FAILS WITH EDQUOT"
+ create_keyring --fail $maxdesc @p
+ expect_error EDQUOT
+fi
+
+# check that an overlong key description fails correctly (>4095 inc NUL)
+marker "CHECK OVERLONG DESC"
+create_keyring --fail a$maxdesc @p
+expect_error EINVAL
+
+# check that an empty keyring name fails
+marker "CHECK EMPTY KEYRING NAME"
+create_keyring --fail "" @p
+expect_error EINVAL
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+create_keyring --fail wibble 0
+expect_error EINVAL
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/newring/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/newring/noargs/runtest.sh
new file mode 100644
index 0000000..4ed315a
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/newring/noargs/runtest.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "ADD NO ARGS"
+expect_args_error keyctl newring
+
+# check that one argument fails correctly
+marker "ADD ONE ARG"
+expect_args_error keyctl newring user
+
+# check that three arguments fail correctly
+marker "ADD THREE ARGS"
+expect_args_error keyctl newring user wibble stuff
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/newring/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/newring/valid/runtest.sh
new file mode 100644
index 0000000..bcb9438
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/newring/valid/runtest.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# check that we now have an empty keyring
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# check that creating a second keyring of the same name displaces the first
+marker "ADD KEYRING AGAIN"
+create_keyring wibble @s
+expect_keyid keyringid2
+
+# should be different keyrings
+if [ "x$keyringid" == "x$keyringid2" ]
+then
+ failed
+fi
+
+# the first should no longer exist in the session keyring
+marker "LIST SESSION KEYRING"
+list_keyring @s
+expect_keyring_rlist sessionrlist $keyringid --absent
+
+# and should no longer be accessible
+marker "VALIDATE NEW KEYRING"
+pause_till_key_destroyed $keyringid
+describe_key --fail $keyringid
+expect_error ENOKEY
+
+# list the session keyring
+marker "LIST SESSION KEYRING2"
+list_keyring @s
+expect_keyring_rlist sessionrlist $keyringid2
+
+# validate the new keyring's name and type
+marker "VALIDATE NEW KEYRING2"
+describe_key $keyringid2
+expect_key_rdesc rdesc 'keyring@.*@wibble'
+
+# remove the keyring we added
+marker "UNLINK KEY"
+unlink_key $keyringid2 @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/noargs/runtest.sh
new file mode 100644
index 0000000..dccc4e0
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/noargs/runtest.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+. ../../prepare.inc.sh
+. ../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+marker "CHECK NO ARGS"
+expect_args_error keyctl
+
+if [ "`sed -n -e 3p $OUTPUTFILE | cut -d: -f1`" != "Format" ]
+then
+ failed
+fi
+
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/padd/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/padd/bad-args/runtest.sh
new file mode 100644
index 0000000..a13e8db
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/padd/bad-args/runtest.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that an empty key type fails correctly
+marker "CHECK EMPTY KEY TYPE"
+pcreate_key --fail stuff "" wibble @p
+expect_error EINVAL
+
+# check that an unsupported key type fails correctly
+marker "CHECK UNSUPPORTED KEY TYPE"
+pcreate_key --fail stuff lizardsgizzards wibble @p
+expect_error ENODEV
+
+# check that an invalid key type fails correctly
+marker "CHECK INVALID KEY TYPE"
+pcreate_key --fail stuff .user wibble @p
+expect_error EPERM
+
+# check that an maximum length invalid key type fails correctly
+marker "CHECK MAXLEN KEY TYPE"
+pcreate_key --fail stuff $maxtype wibble @p
+expect_error ENODEV
+
+# check that an overlong key type fails correctly
+marker "CHECK OVERLONG KEY TYPE"
+pcreate_key --fail stuff a$maxtype wibble @p
+expect_error EINVAL
+
+# check that creation of a keyring with non-empty payload fails correctly
+marker "CHECK ADD KEYRING WITH PAYLOAD"
+pcreate_key --fail stuff keyring wibble @p
+expect_error EINVAL
+
+# check that an max length key description works correctly
+if [ $PAGE_SIZE -lt $maxsquota ]
+then
+ marker "CHECK MAXLEN DESC"
+ pcreate_key stuff user $maxdesc @p
+ expect_keyid keyid
+else
+ marker "CHECK MAXLEN DESC FAILS WITH EDQUOT"
+ pcreate_key --fail stuff user $maxdesc @p
+ expect_error EDQUOT
+fi
+
+# check that an overlong key description fails correctly (>4095 inc NUL)
+marker "CHECK OVERLONG DESC"
+pcreate_key --fail stuff user a$maxdesc @p
+expect_error EINVAL
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+pcreate_key --fail stuff user wibble 0
+expect_error EINVAL
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/padd/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/padd/noargs/runtest.sh
new file mode 100644
index 0000000..97547f3
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/padd/noargs/runtest.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "ADD NO ARGS"
+expect_args_error keyctl padd
+
+# check that one argument fails correctly
+marker "ADD ONE ARG"
+expect_args_error keyctl padd user
+
+# check that two arguments fail correctly
+marker "ADD TWO ARGS"
+expect_args_error keyctl padd user wibble
+
+# check that four arguments fail correctly
+marker "ADD FOUR ARGS"
+expect_args_error keyctl padd user wibble @s x
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/padd/useradd/runtest.sh b/keyutils-1.5.6/tests/keyctl/padd/useradd/runtest.sh
new file mode 100644
index 0000000..8eb0973
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/padd/useradd/runtest.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that we can add a user key to the session keyring
+marker "ADD USER KEY"
+pcreate_key stuff user wibble @s
+expect_keyid keyid
+
+# read back what we put in it
+marker "PRINT PAYLOAD"
+print_key $keyid
+expect_payload payload "stuff"
+
+# check that we can update a user key
+marker "UPDATE USER KEY"
+pcreate_key lizard user wibble @s
+
+# check we get the same key ID back
+expect_keyid keyid2
+
+if [ "x$keyid" != "x$keyid2" ]
+then
+ failed
+fi
+
+# read back what we changed it to
+marker "PRINT UPDATED PAYLOAD"
+print_key $keyid
+expect_payload payload "lizard"
+
+# remove the key we added
+marker "UNLINK KEY"
+unlink_key $keyid @s
+
+keyctl show
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/permitting/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/permitting/bad-args/runtest.sh
new file mode 100644
index 0000000..3c2c324
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/permitting/bad-args/runtest.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+chown_key --fail 0 0
+expect_error EINVAL
+chgrp_key --fail 0 0
+expect_error EINVAL
+set_key_perm --fail 0 0
+expect_error EINVAL
+
+# create a non-keyring
+marker "CREATE KEY"
+create_key user lizard gizzard @s
+expect_keyid keyid
+
+# check that unsupported permissions aren't permitted
+marker "CHECK PERMS"
+set_key_perm --fail $keyid 0xffffffff
+expect_error EINVAL
+set_key_perm --fail $keyid 0x7f7f7f7f
+expect_error EINVAL
+
+# dispose of the key we just made
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK CLEAR NON-EXISTENT KEY ID"
+chown_key --fail $keyid 0
+expect_error ENOKEY
+chgrp_key --fail $keyid 0
+expect_error ENOKEY
+set_key_perm --fail $keyid 0
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/permitting/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/permitting/noargs/runtest.sh
new file mode 100644
index 0000000..89971e1
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/permitting/noargs/runtest.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+marker "NO ARGS"
+expect_args_error keyctl read
+expect_args_error keyctl pipe
+expect_args_error keyctl print
+
+marker "ONE ARG"
+expect_args_error keyctl chown 0
+expect_args_error keyctl chgrp 0
+expect_args_error keyctl setperm 0
+
+marker "THREE ARGS"
+expect_args_error keyctl chown 0 0 0
+expect_args_error keyctl chgrp 0 0 0
+expect_args_error keyctl setperm 0 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/permitting/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/permitting/valid/runtest.sh
new file mode 100644
index 0000000..30f8633
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/permitting/valid/runtest.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# stick a key in the keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# changing the key's ownership is not supported before 2.6.18-rc1
+if version_less_than `uname -r` 2.6.18
+then
+ marker "CHOWN"
+ chown_key --fail $keyid 1
+ expect_error EOPNOTSUPP
+elif [ `id -u` != 0 ]
+then
+ # must be running as root for this to work
+ marker "CHOWN"
+ chown_key --fail $keyid 1
+ expect_error EACCES
+else
+ marker "CHOWN"
+ chown_key $keyid 1
+
+ marker "CHOWN BACK"
+ chown_key $keyid 0
+fi
+
+# changing the key's group ownership is supported (change to "bin" group)
+if [ `id -u` != 0 ]
+then
+ marker "CHGRP"
+ chgrp_key --fail $keyid 1
+ expect_error EACCES
+else
+ marker "CHGRP"
+ chgrp_key $keyid 1
+ describe_key $keyid
+ expect_key_rdesc rdesc "user@.*@1@[0-9a-f]*@lizard"
+fi
+
+# check that each permission can be granted to the key
+marker "ITERATE PERMISSIONS"
+for i in \
+ 00210002 00210004 00210008 00210010 \
+ 00210200 00210400 00210800 00211000 \
+ 00230000 00250000 00290000 00310000 \
+ 02210000 04210000 08210000 10210000
+ do
+ set_key_perm $keyid 0x$i
+ describe_key $keyid
+ expect_key_rdesc rdesc "user@.*@.*@$i@lizard"
+done
+
+# check that we can't use group perms instead of user perms to view the key
+# (our UID matches that of the key)
+marker "VIEW GROUP PERMISSIONS"
+set_key_perm $keyid 0x00201f00
+describe_key --fail $keyid
+expect_error EACCES
+
+# check that we can't use other perms instead of user perms to view the key
+# (our UID matches that of the key)
+marker "VIEW OTHER PERMISSIONS"
+set_key_perm $keyid 0x0020001f
+describe_key --fail $keyid
+expect_error EACCES
+
+# check that taking away setattr permission renders the key immune to setperm
+marker "REMOVE SETATTR"
+set_key_perm $keyid 0x1f1f1f1f
+describe_key $keyid
+expect_key_rdesc rdesc "user@.*@.*@.*@lizard"
+
+marker "REINSTATE SETATTR"
+set_key_perm --fail $keyid 0x3f3f1f1f
+expect_error EACCES
+
+# remove the keyring we added
+marker "UNLINK KEYRING"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/pupdate/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/pupdate/bad-args/runtest.sh
new file mode 100644
index 0000000..cde245c
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/pupdate/bad-args/runtest.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# attempt to update the session keyring
+marker "CHECK UPDATE SESSION KEYRING"
+pupdate_key --fail @s a
+expect_error EOPNOTSUPP
+
+# attempt to update an invalid key
+marker "CHECK UPDATE INVALID KEY"
+pupdate_key --fail 0 a
+expect_error EINVAL
+
+# add a user key to the session keyring for us to play with
+marker "ADD USER KEY"
+create_key user wibble stuff @s
+expect_keyid keyid
+
+# remove the key we just added
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# it should fail when we attempt to update it
+marker "UPDATE UNLINKED KEY"
+pupdate_key --fail $keyid @s
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/pupdate/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/pupdate/noargs/runtest.sh
new file mode 100644
index 0000000..fb8341f
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/pupdate/noargs/runtest.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "PUPDATE NO ARGS"
+expect_args_error keyctl pupdate
+
+# check that two arguments fail correctly
+marker "PUPDATE TWO ARGS"
+expect_args_error keyctl pupdate yyy xxxx
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/pupdate/userupdate/runtest.sh b/keyutils-1.5.6/tests/keyctl/pupdate/userupdate/runtest.sh
new file mode 100644
index 0000000..fa59bc8
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/pupdate/userupdate/runtest.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that we can add a user key to the session keyring
+marker "ADD USER KEY"
+create_key user wibble stuff @s
+expect_keyid keyid
+
+# read back what we put in it
+marker "PRINT PAYLOAD"
+print_key $keyid
+expect_payload payload "stuff"
+
+# check that we can update a user key
+marker "PUPDATE USER KEY"
+pupdate_key $keyid "lizard"
+
+# read back what we changed it to
+marker "PRINT UPDATED PAYLOAD"
+print_key $keyid
+expect_payload payload "lizard"
+
+# remove the key we added
+marker "UNLINK KEY"
+unlink_key $keyid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/reading/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/reading/bad-args/runtest.sh
new file mode 100644
index 0000000..a6e360b
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/reading/bad-args/runtest.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+read_key --fail 0
+expect_error ENOKEY
+print_key --fail 0
+expect_error ENOKEY
+pipe_key --fail 0
+expect_error ENOKEY
+
+# create a non-keyring
+marker "CREATE KEY"
+create_key user lizard gizzard @s
+expect_keyid keyid
+
+# dispose of the key we just made
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK CLEAR NON-EXISTENT KEY ID"
+read_key --fail $keyid
+expect_error ENOKEY
+print_key --fail $keyid
+expect_error ENOKEY
+pipe_key --fail $keyid
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/reading/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/reading/noargs/runtest.sh
new file mode 100644
index 0000000..1d37154
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/reading/noargs/runtest.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+marker "NO ARGS"
+expect_args_error keyctl read
+expect_args_error keyctl pipe
+expect_args_error keyctl print
+
+marker "TWO ARGS"
+expect_args_error keyctl read 0 0
+expect_args_error keyctl pipe 0 0
+expect_args_error keyctl print 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/reading/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/reading/valid/runtest.sh
new file mode 100644
index 0000000..462d7ec
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/reading/valid/runtest.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# stick a key in the keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# check that the key is in the keyring
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist $keyid
+
+# read the contents of the key
+marker "PRINT KEY"
+print_key $keyid
+expect_payload payload "gizzard"
+
+# pipe the contents of the key and add a LF as the key doesn't have one
+marker "PIPE KEY"
+pipe_key $keyid
+echo >>$OUTPUTFILE
+expect_payload payload "gizzard"
+
+# read the key as hex
+marker "READ KEY"
+read_key $keyid
+expect_payload payload "67697a7a 617264"
+
+# read the contents of the keyring as hex and match it to the key ID
+marker "READ KEYRING"
+read_key $keyringid
+tmp=`printf %08x $keyid`
+if [ "$endian" = "LE" ]
+then
+ tmp=`echo $tmp | sed 's/\(..\)\(..\)\(..\)\(..\)/\4\3\2\1/'`
+fi
+expect_payload payload $tmp
+
+# remove read permission from the key and try reading it again
+# - we should still have read permission because it's searchable in our
+# keyrings
+marker "REMOVE READ PERM"
+set_key_perm $keyid 0x3d0000
+print_key $keyid
+expect_payload payload "gizzard"
+
+# remove search permission from the key as well
+# - we should still have read permission because it's searchable in our
+# keyrings
+marker "REMOVE SEARCH PERM"
+set_key_perm $keyid 0x350000
+print_key --fail $keyid
+expect_error EACCES
+
+# check that we can read it if we have to rely on possessor perms
+# - we should still have read permission because it's searchable in our
+# keyrings
+marker "CHECK POSSESSOR READ"
+set_key_perm $keyid 0x3d000000
+print_key $keyid
+expect_payload payload "gizzard"
+
+# put read permission back again
+marker "REINSTATE READ PERM"
+set_key_perm $keyid 0x370000
+print_key $keyid
+expect_payload payload "gizzard"
+
+# revoke the key
+marker "REVOKE KEY"
+revoke_key $keyid
+print_key --fail $keyid
+expect_error EKEYREVOKED
+
+# remove the keyring we added
+marker "UNLINK KEYRING"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/requesting/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/requesting/bad-args/runtest.sh
new file mode 100644
index 0000000..feb2231
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/requesting/bad-args/runtest.sh
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that an empty key type fails correctly
+marker "CHECK EMPTY KEY TYPE"
+request_key --fail "" debug:wibble
+expect_error EINVAL
+request_key --fail "" debug:wibble @p
+expect_error EINVAL
+request_key_callout --fail "" debug:wibble stuff
+expect_error EINVAL
+request_key_callout --fail "" debug:wibble stuff @p
+expect_error EINVAL
+prequest_key_callout --fail stuff "" debug:wibble
+expect_error EINVAL
+prequest_key_callout --fail stuff "" debug:wibble @p
+expect_error EINVAL
+
+# check that an unsupported key type fails correctly
+marker "CHECK UNSUPPORTED KEY TYPE"
+request_key --fail "lizardsgizzards" debug:wibble
+expect_error ENOKEY
+request_key --fail "lizardsgizzards" debug:wibble @p
+expect_error ENOKEY
+request_key_callout --fail "lizardsgizzards" debug:wibble stuff
+expect_error ENOKEY
+request_key_callout --fail "lizardsgizzards" debug:wibble stuff @p
+expect_error ENOKEY
+prequest_key_callout --fail stuff "lizardsgizzards" debug:wibble
+expect_error ENOKEY
+prequest_key_callout --fail stuff "lizardsgizzards" debug:wibble @p
+expect_error ENOKEY
+
+# check that an invalid key type fails correctly
+# - key types beginning with a dot are internal use only
+marker "CHECK INVALID KEY TYPE"
+request_key --fail ".user" debug:wibble
+expect_error EPERM
+request_key --fail ".user" debug:wibble @p
+expect_error EPERM
+request_key_callout --fail ".user" debug:wibble stuff
+expect_error EPERM
+request_key_callout --fail ".user" debug:wibble stuff @p
+expect_error EPERM
+prequest_key_callout --fail stuff ".user" debug:wibble
+expect_error EPERM
+prequest_key_callout --fail stuff ".user" debug:wibble @p
+expect_error EPERM
+
+# check that an maximum length invalid key type fails correctly
+marker "CHECK MAXLEN INVALID KEY TYPE"
+request_key --fail $maxtype debug:wibble
+expect_error ENOKEY
+request_key --fail $maxtype debug:wibble @p
+expect_error ENOKEY
+request_key_callout --fail $maxtype debug:wibble stuff
+expect_error ENOKEY
+request_key_callout --fail $maxtype debug:wibble stuff @p
+expect_error ENOKEY
+
+# check that an overlong key type fails correctly
+marker "CHECK OVERLONG KEY TYPE"
+request_key --fail a$maxtype debug:wibble
+expect_error EINVAL
+request_key --fail a$maxtype debug:wibble @p
+expect_error EINVAL
+request_key_callout --fail a$maxtype debug:wibble stuff
+expect_error EINVAL
+request_key_callout --fail a$maxtype debug:wibble stuff @p
+expect_error EINVAL
+
+# check that an max length key description works correctly
+marker "CHECK MAXLEN DESC"
+request_key --fail user $maxdesc
+expect_error ENOKEY
+
+# check that an overlong key description fails correctly
+marker "CHECK OVERLONG DESC"
+request_key --fail user a$maxdesc
+expect_error EINVAL
+
+# check that a max length callout info works correctly
+marker "CHECK MAXLEN CALLOUT"
+request_key_callout --fail user wibble $maxdesc @p
+expect_error ENOKEY
+
+# check that an overlong callout info fails correctly
+marker "CHECK OVERLONG CALLOUT"
+request_key_callout --fail user wibble a$maxcall
+expect_error EINVAL
+
+# check that a max length callout info works correctly
+marker "CHECK MAXLEN PIPED CALLOUT"
+prequest_key_callout --fail $maxcall user wibble @p
+expect_error ENOKEY
+
+# check that an overlong callout info fails correctly
+marker "CHECK OVERLONG PIPED CALLOUT"
+prequest_key_callout --fail a$maxcall user wibble
+expect_error EINVAL
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/requesting/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/requesting/noargs/runtest.sh
new file mode 100644
index 0000000..0070708
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/requesting/noargs/runtest.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+marker "NO ARGS"
+expect_args_error keyctl request
+expect_args_error keyctl request2
+expect_args_error keyctl prequest2
+
+marker "ONE ARG"
+expect_args_error keyctl request 0
+expect_args_error keyctl request2 0
+expect_args_error keyctl prequest2 0
+
+marker "TWO ARGS"
+expect_args_error keyctl request2 0 0
+
+marker "FOUR ARGS"
+expect_args_error keyctl request 0 0 0 0
+expect_args_error keyctl prequest2 0 0 0 0
+
+marker "FIVE ARGS"
+expect_args_error keyctl request2 0 0 0 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/requesting/piped/runtest.sh b/keyutils-1.5.6/tests/keyctl/requesting/piped/runtest.sh
new file mode 100644
index 0000000..529f8af
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/requesting/piped/runtest.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+set_gc_delay 10
+
+# create a pair of keyrings to play in
+marker "CREATE KEYRINGS"
+create_keyring "sandbox" @s
+expect_keyid keyringid
+
+# check that we can't yet request a non-existent key
+marker "CHECK REQUEST FAILS"
+request_key --fail user lizard $keyringid
+expect_error ENOKEY
+
+# add a user key to the first keyring
+marker "ADD USER KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# request the key
+marker "REQUEST KEY"
+request_key user lizard
+expect_keyid keyid2 $keyid
+
+# remove the key from the keyring
+marker "DETACH KEY FROM KEYRING"
+unlink_key $keyid $keyringid
+
+# request a key from /sbin/request-key to the session keyring
+marker "PIPED CALL OUT REQUEST KEY TO SESSION"
+prequest_key_callout gizzard user debug:lizard
+expect_keyid keyid
+
+# should have appeared in the session keyring
+marker "CHECK ATTACHMENT TO SESSION KEYRING"
+list_keyring @s
+expect_keyring_rlist rlist $keyid
+
+# rerequesting should pick up that key again
+marker "REDO PIPED CALL OUT REQUEST KEY TO SESSION"
+prequest_key_callout gizzard user debug:lizard
+expect_keyid keyid2 $keyid
+
+# remove the key from the session
+# - it was installed twice
+# - once by request_key's keyring arg
+# - once from the instantiation call
+# but it will only have one link
+marker "DETACH KEY FROM SESSION"
+unlink_key --wait $keyid @s
+unlink_key --fail $keyid @s
+expect_error ENOKEY
+
+# request a key from /sbin/request-key to the keyring we made
+marker "PIPED CALL OUT REQUEST KEY TO KEYRING"
+prequest_key_callout gizzard user debug:lizard $keyringid
+expect_keyid keyid
+
+# should have appeared once each in the sandbox and session keyrings
+marker "CHECK ATTACHMENT TO KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist $keyid
+
+marker "CHECK ATTACHMENT TO SESSION"
+list_keyring @s
+expect_keyring_rlist rlist $keyid
+
+# rerequesting should pick up that key again
+marker "REDO PIPED CALL OUT REQUEST KEY TO KEYRING"
+prequest_key_callout gizzard user debug:lizard $keyringid
+expect_keyid keyid2 $keyid
+
+# remove the key from the session
+marker "DETACH KEY"
+unlink_key $keyid $keyringid
+unlink_key --wait $keyid @s
+unlink_key --fail $keyid @s
+expect_error ENOKEY
+
+# remove the keyrings we added
+marker "UNLINK KEYRINGS"
+unlink_key $keyringid @s
+
+set_gc_delay $orig_gc_delay
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/requesting/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/requesting/valid/runtest.sh
new file mode 100644
index 0000000..c14d0cc
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/requesting/valid/runtest.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+set_gc_delay 10
+
+# create a pair of keyrings to play in
+marker "CREATE KEYRINGS"
+create_keyring "sandbox" @s
+expect_keyid keyringid
+
+# check that we can't yet request a non-existent key
+marker "CHECK REQUEST FAILS"
+request_key --fail user lizard $keyringid
+expect_error ENOKEY
+
+# add a user key to the first keyring
+marker "ADD USER KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# request the key
+marker "REQUEST KEY"
+request_key user lizard
+expect_keyid keyid2 $keyid
+
+# remove the key from the keyring
+marker "DETACH KEY FROM KEYRING"
+unlink_key $keyid $keyringid
+
+# request a key from /sbin/request-key to the session keyring
+marker "CALL OUT REQUEST KEY TO SESSION"
+request_key_callout user debug:lizard gizzard
+expect_keyid keyid
+
+# should have appeared in the session keyring
+marker "CHECK ATTACHMENT TO SESSION KEYRING"
+list_keyring @s
+expect_keyring_rlist rlist $keyid
+
+# rerequesting should pick up that key again
+marker "REDO CALL OUT REQUEST KEY TO SESSION"
+request_key_callout user debug:lizard gizzard
+expect_keyid keyid2 $keyid
+
+# remove the key from the session
+# - it was installed twice
+# - once by request_key's keyring arg
+# - once from the instantiation call
+# but it will only have one link
+marker "DETACH KEY FROM SESSION"
+unlink_key --wait $keyid @s
+unlink_key --fail $keyid @s
+expect_error ENOKEY
+
+# request a key from /sbin/request-key to the keyring we made
+marker "CALL OUT REQUEST KEY TO KEYRING"
+request_key_callout user debug:lizard gizzard $keyringid
+expect_keyid keyid
+
+# should have appeared once each in the sandbox and session keyrings
+marker "CHECK ATTACHMENT TO KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist $keyid
+
+marker "CHECK ATTACHMENT TO SESSION"
+list_keyring @s
+expect_keyring_rlist rlist $keyid
+
+# rerequesting should pick up that key again
+marker "REDO CALL OUT REQUEST KEY TO KEYRING"
+request_key_callout user debug:lizard gizzard $keyringid
+expect_keyid keyid2 $keyid
+
+# remove the key from the session
+marker "DETACH KEY"
+unlink_key $keyid $keyringid
+unlink_key --wait $keyid @s
+unlink_key --fail $keyid @s
+expect_error ENOKEY
+
+# remove the keyrings we added
+marker "UNLINK KEYRINGS"
+unlink_key $keyringid @s
+
+set_gc_delay $orig_gc_delay
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/revoke/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/revoke/bad-args/runtest.sh
new file mode 100644
index 0000000..a3c9b44
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/revoke/bad-args/runtest.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+revoke_key --fail 0
+expect_error EINVAL
+
+# check that a non-existent key ID fails correctly
+marker "CHECK NON-EXISTENT KEY ID"
+revoke_key --fail @t
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/revoke/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/revoke/noargs/runtest.sh
new file mode 100644
index 0000000..417e3b6
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/revoke/noargs/runtest.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "ADD NO ARGS"
+expect_args_error keyctl revoke
+
+# check that two arguments fail correctly
+marker "ADD TWO ARGS"
+expect_args_error keyctl revoke 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/revoke/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/revoke/valid/runtest.sh
new file mode 100644
index 0000000..e379476
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/revoke/valid/runtest.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# create a key and attach it to the new keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# check that we can list the keyring
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist ringlist $keyid
+
+# check we can read the key description
+marker "CHECK VALIDATE KEY"
+describe_key $keyid
+expect_key_rdesc kdesc 'user@.*@lizard'
+
+# check we can read the key's payload
+marker "CHECK READ PAYLOAD"
+print_key $keyid
+expect_payload kpayload "gizzard"
+
+# revoke the key
+marker "REVOKE KEY"
+revoke_key $keyid
+
+# check we can no longer read the key description
+marker "CHECK NO VALIDATE KEY"
+describe_key --fail $keyid
+expect_error EKEYREVOKED
+
+# check we can no longer read the key's payload
+marker "CHECK NO READ PAYLOAD"
+print_key --fail $keyid
+expect_error EKEYREVOKED
+
+# remove the key we added
+marker "UNLINK KEY"
+unlink_key $keyid $keyringid
+
+# revoke the keyring
+marker "REVOKE KEYRING"
+revoke_key $keyringid
+
+# listing the session keyring should fail
+marker "CHECK NO LIST SESSION KEYRING"
+list_keyring --fail $keyringid
+expect_error EKEYREVOKED
+
+# validating the new keyring's name and type should also fail
+marker "CHECK NO VALIDATE KEYRING"
+describe_key --fail $keyringid
+expect_error EKEYREVOKED
+
+# remove the keyring we added
+marker "UNLINK KEYRING"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/search/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/search/bad-args/runtest.sh
new file mode 100644
index 0000000..23bbc8b
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/search/bad-args/runtest.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that an empty key type fails correctly
+marker "CHECK EMPTY KEY TYPE"
+search_for_key --fail @s "" wibble
+expect_error EINVAL
+search_for_key --fail @s "" wibble @p
+expect_error EINVAL
+
+# check that an unsupported key type fails correctly
+marker "CHECK UNSUPPORTED KEY TYPE"
+search_for_key --fail @s lizardsgizzards wibble
+expect_error ENOKEY
+search_for_key --fail @s lizardsgizzards wibble @p
+expect_error ENOKEY
+
+# check that an invalid key type fails correctly
+marker "CHECK INVALID KEY TYPE"
+search_for_key --fail @s .user wibble
+expect_error EPERM
+search_for_key --fail @s .user wibble @p
+expect_error EPERM
+
+# check that an overlong key type fails correctly
+marker "CHECK OVERLONG KEY TYPE"
+search_for_key --fail @s $maxtype wibble
+expect_error ENOKEY
+search_for_key --fail @s a$maxtype wibble @p
+expect_error EINVAL
+
+# check that an max length key description works correctly (4095 inc NUL)
+marker "CHECK MAXLEN DESC"
+search_for_key --fail @s user $maxdesc
+expect_error ENOKEY
+
+search_for_key --fail @s user $maxdesc @p
+expect_error ENOKEY
+
+# check that an overlong key description fails correctly (>4095 inc NUL)
+marker "CHECK OVERLONG DESC"
+search_for_key --fail @s user a$maxdesc
+expect_error EINVAL
+
+search_for_key --fail @s user a$maxdesc @p
+expect_error EINVAL
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+search_for_key --fail @s user wibble -2000
+expect_error EINVAL
+
+# create a non-keyring key
+marker "CREATE KEY"
+create_key user a a @s
+expect_keyid keyid
+
+# search the non-keyring key
+marker "SEARCH KEY"
+search_for_key --fail $keyid user a
+expect_error ENOTDIR
+search_for_key --fail $keyid user a @p
+expect_error ENOTDIR
+
+# dispose of the key
+marker "UNLINK KEY"
+unlink_key $keyid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/search/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/search/noargs/runtest.sh
new file mode 100644
index 0000000..5059eec
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/search/noargs/runtest.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "NO ARGS"
+expect_args_error keyctl search
+
+# check that one argument fails correctly
+marker "ONE ARGS"
+expect_args_error keyctl search 0
+
+# check that two arguments fails correctly
+marker "TWO ARGS"
+expect_args_error keyctl search 0 0
+
+# check that five arguments fails correctly
+marker "FIVE ARGS"
+expect_args_error keyctl search 0 0 0 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/search/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/search/valid/runtest.sh
new file mode 100644
index 0000000..2deafc0
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/search/valid/runtest.sh
@@ -0,0 +1,173 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a pair of keyrings and attach them to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+create_keyring wibble2 @s
+expect_keyid keyring2id
+
+# stick a key in the keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# check that we can list it
+marker "LIST KEYRING WITH ONE"
+list_keyring $keyringid
+expect_keyring_rlist rlist $keyid
+
+# search the session keyring for a non-existent key
+marker "SEARCH SESSION FOR NON-EXISTENT KEY"
+search_for_key --fail @s user snake
+expect_error ENOKEY
+
+# search the session keyring for the key
+marker "SEARCH SESSION"
+search_for_key @s user lizard
+expect_keyid found $keyid
+
+# search the session keyring for the key and attach to second keyring
+marker "SEARCH SESSION AND ATTACH"
+search_for_key @s user lizard $keyring2id
+expect_keyid found $keyid
+
+# check it's attached to the second keyring
+marker "CHECK ATTACHED"
+list_keyring $keyring2id
+expect_keyring_rlist rlist $keyid
+
+# check the key contains what we expect
+marker "CHECK PAYLOAD"
+print_key $keyid
+expect_payload payload "gizzard"
+
+# detach the attachment just made
+marker "DETACH KEY"
+unlink_key $found $keyring2id
+
+# create an overlapping key in the second keyring
+create_key user lizard skin $keyring2id
+expect_keyid keyid2
+
+# check the two keys contain what we expect
+marker "CHECK PAYLOADS"
+print_key $keyid
+expect_payload payload "gizzard"
+print_key $keyid2
+expect_payload payload "skin"
+
+# a search from the session keyring should find the first key
+marker "SEARCH SESSION AGAIN"
+search_for_key @s user lizard
+expect_keyid found $keyid
+
+# a search from the first keyring should find the first key
+marker "SEARCH FIRST KEYRING"
+search_for_key $keyringid user lizard
+expect_keyid found $keyid
+
+# a search from the second keyring should find the second key
+marker "SEARCH SECOND KEYRING"
+search_for_key $keyring2id user lizard
+expect_keyid found $keyid2
+
+# link the second keyring to the first
+marker "LINK FIRST KEYRING TO SECOND"
+link_key $keyring2id $keyringid
+
+# a search from the first keyring should again find the first key
+marker "SEARCH FIRST KEYRING AGAIN"
+search_for_key $keyringid user lizard
+expect_keyid found $keyid
+
+# revoking the first key should cause the second key to be available
+revoke_key $keyid
+search_for_key $keyringid user lizard
+expect_keyid found $keyid2
+
+# get rid of the dead key
+marker "UNLINK FIRST KEY"
+unlink_key $keyid $keyringid
+
+# a search from the first keyring should now find the second key
+marker "SEARCH FIRST KEYRING AGAIN 2"
+search_for_key $keyringid user lizard
+expect_keyid found $keyid2
+
+# a search from the session keyring should now find the second key
+marker "SEARCH SESSION KEYRING AGAIN 2"
+search_for_key @s user lizard
+expect_keyid found $keyid2
+
+# unlink the second keyring from the first
+marker "UNLINK SECOND KEYRING FROM FIRST"
+unlink_key $keyring2id $keyringid
+
+# a search from the first keyring should now fail
+marker "SEARCH FIRST KEYRING FOR FAIL"
+search_for_key --fail $keyringid user lizard
+expect_error ENOKEY
+
+# a search from the session keyring should still find the second key
+marker "SEARCH SESSION KEYRING AGAIN 3"
+search_for_key @s user lizard
+expect_keyid found $keyid2
+
+# move the second keyring into the first
+marker "MOVE SECOND KEYRING INTO FIRST"
+link_key $keyring2id $keyringid
+unlink_key $keyring2id @s
+
+# a search from the first keyring should now find the second key once again
+marker "SEARCH FIRST KEYRING AGAIN 4"
+search_for_key $keyringid user lizard
+expect_keyid found $keyid2
+
+# removing search permission on the second keyring should hide the key
+marker "SEARCH WITH NO-SEARCH KEYRING"
+set_key_perm $keyring2id 0x370000
+search_for_key --fail $keyringid user lizard
+expect_error ENOKEY
+
+# putting search permission on the second keyring back again should make it
+# available again
+set_key_perm $keyring2id 0x3f0000
+search_for_key $keyringid user lizard
+expect_keyid found $keyid2
+
+# removing search permission on the second key should hide the key
+marker "SEARCH WITH NO-SEARCH KEYRING2"
+set_key_perm $keyring2id 0x370000
+search_for_key --fail $keyringid user lizard
+expect_error ENOKEY
+
+# putting search permission on the second key back again should make it
+# available again
+set_key_perm $keyring2id 0x3f0000
+search_for_key $keyringid user lizard
+expect_keyid found $keyid2
+
+# revoking the key should make the key unavailable
+revoke_key $keyid2
+search_for_key --fail $keyringid user lizard
+expect_error EKEYREVOKED
+
+# remove the keyrings we added
+marker "UNLINK KEYRING"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/session/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/session/bad-args/runtest.sh
new file mode 100644
index 0000000..e3b6f71
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/session/bad-args/runtest.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that an empty keyring name fails correctly
+marker "SESSION WITH EMPTY KEYRING NAME"
+new_session --fail ""
+expect_error EINVAL
+
+# check that an overlong keyring name fails correctly
+marker "SESSION WITH OVERLONG KEYRING NAME"
+new_session --fail a$maxdesc
+expect_error EINVAL
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/session/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/session/valid/runtest.sh
new file mode 100644
index 0000000..172343a
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/session/valid/runtest.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# describe the keyring created for an anonymous session
+if [ $OSDIST = RHEL -a $OSRELEASE -le 5 ]
+then
+ marker "ANON SESSION"
+ new_session - keyctl rdescribe @s "@"
+ expect_key_rdesc rdesc "keyring@.*@.*@.*@_ses[^@]*\$"
+
+ # check the session keyring ID is shown
+ seskeyring="`tail -2 $OUTPUTFILE | head -1`"
+ if ! expr "$seskeyring" : "Joined session keyring: [0-9]*" >&/dev/null
+ then
+ failed
+ fi
+fi
+
+# describe the keyring created for a named session
+marker "NAMED SESSION"
+new_session qwerty keyctl rdescribe @s "@"
+expect_key_rdesc rdesc "keyring@.*@.*@.*@qwerty"
+
+# check the session keyring ID is shown
+seskeyring="`tail -2 $OUTPUTFILE | head -1`"
+if ! expr "$seskeyring" : "Joined session keyring: [0-9]*" >&/dev/null
+then
+ failed
+fi
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/show/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/show/noargs/runtest.sh
new file mode 100644
index 0000000..1cde112
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/show/noargs/runtest.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that show shows us our session keyring
+marker "SHOW SESSION KEYRING"
+keyctl show >>$OUTPUTFILE 2>&1
+if [ $? != 0 ]
+then
+ failed
+fi
+
+# must be at least two lines in the output (plus the test banner lines)
+nlines=`wc -l $OUTPUTFILE | cut -d\ -f1`
+if [ "$nlines" -lt 4 ]
+then
+ failed
+fi
+
+# there must be a session keyring section on the third line
+if [ "`sed -n -e 3p $OUTPUTFILE`" != "Session Keyring" ]
+then
+ failed
+fi
+
+# the first key listed (line 2) should be a keying (the session keyring) ...
+keyring1="`grep -n keyring $OUTPUTFILE | cut -d: -f1 | head -1`"
+if [ "$keyring1" != "4" ]
+then
+ failed
+fi
+
+# ... and it should be the session keyring
+keyring1name="`sed -n -e 4p $OUTPUTFILE | awk '{print $6}'`"
+if ! expr "$keyring1name" : "^RHTS/keyctl" >&/dev/null
+then
+ failed
+fi
+
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/timeout/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/timeout/bad-args/runtest.sh
new file mode 100644
index 0000000..4ad216b
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/timeout/bad-args/runtest.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK BAD KEY ID"
+timeout_key --fail 0 10
+expect_error EINVAL
+
+# get a key
+marker "CREATE KEY"
+create_key user a a @s
+expect_keyid keyid
+
+# dispose of the key so we can use its ID
+marker "DESTROY KEY ID"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK NON-EXISTENT KEY ID"
+timeout_key --fail $keyid 10
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/timeout/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/timeout/noargs/runtest.sh
new file mode 100644
index 0000000..3ff2675
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/timeout/noargs/runtest.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "ADD NO ARGS"
+expect_args_error keyctl timeout
+
+# check that one argument fails correctly
+marker "ADD ONE ARG"
+expect_args_error keyctl timeout 0
+
+# check that three arguments fail correctly
+marker "ADD THREE ARGS"
+expect_args_error keyctl timeout 0 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/timeout/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/timeout/valid/runtest.sh
new file mode 100644
index 0000000..0674826
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/timeout/valid/runtest.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# create a key and attach it to the new keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# check that we can list the keyring
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist ringlist $keyid
+
+# check we can read the key description
+marker "CHECK VALIDATE KEY"
+describe_key $keyid
+expect_key_rdesc kdesc 'user@.*@lizard'
+
+# check we can read the key's payload
+marker "CHECK READ PAYLOAD"
+print_key $keyid
+expect_payload kpayload "gizzard"
+
+# set a silly timeout on the key
+marker "SET BIG TIMEOUT"
+timeout_key $keyid 10000000
+
+# check we can still read the key's payload
+marker "CHECK READ PAYLOAD 2"
+print_key $keyid
+expect_payload kpayload "gizzard"
+
+# set a small timeout on the key
+marker "SET SMALL TIMEOUT"
+timeout_key $keyid 2
+
+marker "WAIT FOR TIMEOUT"
+sleep_at_least 2
+
+# check the key has expired
+marker "CHECK NO READ PAYLOAD"
+print_key --fail $keyid
+expect_error EKEYEXPIRED
+
+# check revocation doesn't work
+marker "CHECK NO REVOKE KEY"
+revoke_key --fail $keyid
+expect_error EKEYEXPIRED
+
+# check timeout setting doesn't work
+marker "CHECK NO TIMEOUT KEY"
+timeout_key --fail $keyid 20
+expect_error EKEYEXPIRED
+
+# remove the key we added
+marker "UNLINK KEY"
+unlink_key $keyid $keyringid
+
+###############################################################################
+# create a key and attach it to the new keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# set a silly timeout on the key
+marker "SET BIG TIMEOUT"
+timeout_key $keyid 10000000
+
+# revoke the key
+marker "REVOKE KEY"
+revoke_key $keyid
+
+# check we can no longer set the key's timeout
+marker "CHECK NO SET KEY TIMEOUT"
+timeout_key --fail $keyid 20
+expect_error EKEYREVOKED
+
+# remove the key we added
+marker "UNLINK KEY"
+unlink_key $keyid $keyringid
+
+# revoke the keyring
+marker "TIMEOUT KEYRING"
+timeout_key $keyringid 1
+
+marker "WAIT FOR KEYRING TIMEOUT"
+sleep_at_least 1
+
+# listing the session keyring should fail
+marker "CHECK NO LIST SESSION KEYRING"
+list_keyring --fail $keyringid
+expect_error EKEYEXPIRED
+
+# validating the new keyring's name and type should also fail
+marker "CHECK NO VALIDATE KEYRING"
+describe_key --fail $keyringid
+expect_error EKEYEXPIRED
+
+# remove the keyring we added
+marker "UNLINK KEYRING"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/unlink/all/runtest.sh b/keyutils-1.5.6/tests/keyctl/unlink/all/runtest.sh
new file mode 100644
index 0000000..2014470
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/unlink/all/runtest.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+
+if keyutils_at_or_later_than 1.5
+then
+ echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+ # create a keyring and attach it to the session keyring
+ marker "ADD KEYRING"
+ create_keyring wibble @s
+ expect_keyid keyringid
+
+ # stick a key in the keyring
+ marker "ADD KEY"
+ create_key user lizard gizzard $keyringid
+ expect_keyid keyid
+
+ # check that we can list it
+ marker "LIST KEYRING WITH ONE"
+ list_keyring $keyringid
+ expect_keyring_rlist rlist $keyid
+
+ # dispose of the key and make sure it gets destroyed
+ marker "UNLINK KEY FROM KEYRING"
+ unlink_key --wait $keyid $keyringid
+
+ # trying a tree-wide unlink should succeed with no links removed
+ marker "CHECK NO UNLINK KEY FROM TREE"
+ unlink_key $keyid
+ expect_unlink_count n_unlinked 0
+
+ # check that the keyring is now empty
+ marker "LIST KEYRING"
+ list_keyring $keyringid
+ expect_keyring_rlist rlist empty
+
+ # create a key to be massively linked
+ marker "ADD MULTI KEY"
+ create_key user lizard gizzard $keyringid
+ expect_keyid keyid
+
+ # stick twenty keyrings in the keyring with twenty links
+ marker "ADD TWENTY KEYRINGS WITH LINKS"
+ subrings=
+ for ((i=0; i<20; i++))
+ do
+ create_keyring ring$i $keyringid
+ expect_keyid x
+ keys="$keys $x"
+ subrings="$subrings $x"
+ list_keyring $keyringid
+ expect_keyring_rlist rlist $x
+
+ link_key $keyid $x
+ list_keyring $x
+ expect_keyring_rlist rlist $keyid
+ done
+
+ marker "SHOW"
+ if ! keyctl show >>$OUTPUTFILE 2>&1
+ then
+ failed
+ fi
+
+ # delete all the keys from the keyring tree
+ marker "REMOVE ALL LINKS TO KEY"
+ unlink_key $keyid
+ expect_unlink_count n_unlinked 21
+
+ # there should not now be any left
+ unlink_key $keyid
+ expect_unlink_count n_unlinked 0
+
+ # check that the key is no longer in the main keyring
+ marker "CHECK GONE"
+ list_keyring $keyringid
+ expect_keyring_rlist rlist $keyid --absent
+
+ for i in $subrings
+ do
+ list_keyring $i
+ expect_keyring_rlist rlist $keyid --absent
+ done
+
+ # remove the keyring we added
+ marker "UNLINK KEY"
+ unlink_key $keyringid @s
+
+ echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+else
+ echo "++++ SKIPPING TEST" >>$OUTPUTFILE
+ marker SKIP on version
+fi
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/unlink/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/unlink/bad-args/runtest.sh
new file mode 100644
index 0000000..82f4371
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/unlink/bad-args/runtest.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that a bad key ID fails correctly
+marker "CHECK UNLINK BAD KEY ID"
+unlink_key --fail 0 @s
+expect_error EINVAL
+
+marker "CHECK UNLINK FROM BAD KEY ID"
+unlink_key --fail @s 0
+expect_error EINVAL
+
+# create a non-keyring
+marker "CREATE KEY"
+create_key user lizard gizzard @s
+expect_keyid keyid
+
+# check that unlinking from a non-keyring ID fails correctly
+marker "CHECK UNLINK FROM NON-KEYRING KEY"
+unlink_key --fail @s $keyid
+expect_error ENOTDIR
+
+# dispose of the key we were using
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# check that a non-existent key ID fails correctly
+marker "CHECK UNLINK FROM NON-EXISTENT KEY ID"
+unlink_key --fail @s $keyid
+expect_error ENOKEY
+
+marker "CHECK UNLINK NON-EXISTENT KEY ID"
+unlink_key --fail $keyid @s
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/unlink/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/unlink/noargs/runtest.sh
new file mode 100644
index 0000000..1ed9f26
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/unlink/noargs/runtest.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "NO ARGS"
+expect_args_error keyctl unlink
+
+if keyutils_older_than 1.5
+then
+ # check that one argument fails correctly
+ marker "ONE ARGS"
+ expect_args_error keyctl unlink 0
+fi
+
+# check that three arguments fails correctly
+marker "THREE ARGS"
+expect_args_error keyctl unlink 0 0 0
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/unlink/valid/runtest.sh b/keyutils-1.5.6/tests/keyctl/unlink/valid/runtest.sh
new file mode 100644
index 0000000..cedf8a4
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/unlink/valid/runtest.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# create a keyring and attach it to the session keyring
+marker "ADD KEYRING"
+create_keyring wibble @s
+expect_keyid keyringid
+
+# stick a key in the keyring
+marker "ADD KEY"
+create_key user lizard gizzard $keyringid
+expect_keyid keyid
+
+# check that we can list it
+marker "LIST KEYRING WITH ONE"
+list_keyring $keyringid
+expect_keyring_rlist rlist $keyid
+
+# dispose of the key and make sure it gets destroyed
+marker "UNLINK KEY FROM KEYRING"
+unlink_key --wait $keyid $keyringid
+
+# trying again should fail
+marker "CHECK NO UNLINK KEY FROM KEYRING"
+unlink_key --fail $keyid $keyringid
+expect_error ENOKEY
+
+# check that the keyring is now empty
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# stick twenty keys and twenty keyrings in the keyring
+marker "ADD TWENTY KEYS"
+keys=""
+for ((i=0; i<20; i++))
+ do
+ create_key user lizard$i gizzard$i $keyringid
+ expect_keyid x
+ keys="$keys $x"
+ list_keyring $keyringid
+ expect_keyring_rlist rlist $x
+done
+
+marker "ADD TWENTY KEYRINGS"
+for ((i=0; i<20; i++))
+ do
+ create_keyring ring$i $keyringid
+ expect_keyid x
+ keys="$keys $x"
+ list_keyring $keyringid
+ expect_keyring_rlist rlist $x
+done
+
+marker "CHECK KEYRING CONTENTS"
+list_keyring $keyringid
+for i in $keys
+do
+ expect_keyring_rlist rlist $i
+done
+
+marker "SHOW"
+if ! keyctl show >>$OUTPUTFILE 2>&1
+then
+ failed
+fi
+
+# delete all the keys from the keyring
+marker "DELETE CONTENTS OF KEYRING"
+for i in $keys
+ do
+ unlink_key --wait $i $keyringid
+ unlink_key --fail $i $keyringid
+ expect_error ENOKEY
+done
+
+keyctl show
+
+# check that it's now empty
+marker "LIST KEYRING"
+list_keyring $keyringid
+expect_keyring_rlist rlist empty
+
+# remove the keyring we added
+marker "UNLINK KEY"
+unlink_key $keyringid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/update/bad-args/runtest.sh b/keyutils-1.5.6/tests/keyctl/update/bad-args/runtest.sh
new file mode 100644
index 0000000..9d7971a
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/update/bad-args/runtest.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# attempt to update the session keyring
+marker "CHECK UPDATE SESSION KEYRING"
+update_key --fail @s a
+expect_error EOPNOTSUPP
+
+# attempt to update an invalid key
+marker "CHECK UPDATE INVALID KEY"
+update_key --fail 0 a
+expect_error EINVAL
+
+# add a user key to the session keyring for us to play with
+marker "ADD USER KEY"
+create_key user wibble stuff @s
+expect_keyid keyid
+
+# remove the key we just added
+marker "UNLINK KEY"
+unlink_key --wait $keyid @s
+
+# it should fail when we attempt to update it
+marker "UPDATE UNLINKED KEY"
+update_key --fail $keyid @s
+expect_error ENOKEY
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/update/noargs/runtest.sh b/keyutils-1.5.6/tests/keyctl/update/noargs/runtest.sh
new file mode 100644
index 0000000..3138e3b
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/update/noargs/runtest.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that no arguments fails correctly
+marker "ADD NO ARGS"
+expect_args_error keyctl update
+
+# check that one argument fails correctly
+marker "ADD ONE ARG"
+expect_args_error keyctl update user
+
+# check that three arguments fail correctly
+marker "ADD THREE ARGS"
+expect_args_error keyctl update user wibble stuff
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/keyctl/update/userupdate/runtest.sh b/keyutils-1.5.6/tests/keyctl/update/userupdate/runtest.sh
new file mode 100644
index 0000000..27fccfd
--- /dev/null
+++ b/keyutils-1.5.6/tests/keyctl/update/userupdate/runtest.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+. ../../../prepare.inc.sh
+. ../../../toolbox.inc.sh
+
+
+# ---- do the actual testing ----
+
+result=PASS
+echo "++++ BEGINNING TEST" >$OUTPUTFILE
+
+# check that we can add a user key to the session keyring
+marker "ADD USER KEY"
+create_key user wibble stuff @s
+expect_keyid keyid
+
+# read back what we put in it
+marker "PRINT PAYLOAD"
+print_key $keyid
+expect_payload payload "stuff"
+
+# check that we can update a user key
+marker "UPDATE USER KEY"
+update_key $keyid "lizard"
+
+# read back what we changed it to
+marker "PRINT UPDATED PAYLOAD"
+print_key $keyid
+expect_payload payload "lizard"
+
+# remove the key we added
+marker "UNLINK KEY"
+unlink_key $keyid @s
+
+echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE
+
+# --- then report the results in the database ---
+toolbox_report_result $TEST $result
diff --git a/keyutils-1.5.6/tests/prepare.inc.sh b/keyutils-1.5.6/tests/prepare.inc.sh
new file mode 100644
index 0000000..c1e2420
--- /dev/null
+++ b/keyutils-1.5.6/tests/prepare.inc.sh
@@ -0,0 +1,43 @@
+# preparation script for running keyring tests
+
+# --- need to run in own session keyring
+if [ "x`keyctl rdescribe @s | sed 's/.*;//'`" != "xRHTS/keyctl/$$" ]
+then
+ echo "Running with session keyring RHTS/keyctl/$$"
+ exec keyctl session "RHTS/keyctl/$$" sh $0 $@ || exit 8
+fi
+
+# Set up for the Red Hat Test System
+RUNNING_UNDER_RHTS=0
+if [ -x /usr/bin/rhts_environment.sh ]
+then
+ PACKAGE=$(rpm -q --qf "%{name}" --whatprovides /bin/keyctl)
+ . /usr/bin/rhts_environment.sh
+ RUNNING_UNDER_RHTS=1
+elif [ -z "$OUTPUTFILE" ]
+then
+ OUTPUTFILE=$PWD/test.out
+ echo -n >$OUTPUTFILE
+fi
+
+case `lsb_release -i | awk '{ print $3}'` in
+ Fedora*) OSDIST=Fedora;;
+ RedHatEnterprise*) OSDIST=RHEL;;
+ *) OSDIST=Unknown;;
+esac
+
+OSRELEASE=`lsb_release -r | awk '{ print $2}'`
+
+KEYUTILSVER=`keyctl --version 2>/dev/null`
+if [ -n "$KEYUTILSVER" ]
+then
+ :
+elif [ -x /bin/rpm ]
+then
+ KEYUTILSVER=`rpm -q keyutils`
+else
+ echo "Can't determine keyutils version" >&2
+ exit 9
+fi
+
+KEYUTILSVER=`expr "$KEYUTILSVER" : '.*keyutils-\([0-9.]*\).*'`
diff --git a/keyutils-1.5.6/tests/runtest.sh b/keyutils-1.5.6/tests/runtest.sh
new file mode 100644
index 0000000..d14b70b
--- /dev/null
+++ b/keyutils-1.5.6/tests/runtest.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+TESTS=$*
+
+PARENTTEST=${TEST}
+
+if [ `id -u` != 0 ]
+then
+ echo "#### Some tests require root privileges." >&2
+ echo "#### It is recommended that this be run as root." >&2
+fi
+
+for i in ${TESTS}; do
+ export TEST=$i
+ pushd $i >/dev/null
+ sh ./runtest.sh || exit 1
+ popd >/dev/null
+done
+
+if [ `id -u` != 0 ]
+then
+ echo "#### Some tests required root privileges." >&2
+ echo "#### They have been tested for the appropriate failure." >&2
+ echo "#### It is recommended that this be run as root." >&2
+fi
diff --git a/keyutils-1.5.6/tests/toolbox.inc.sh b/keyutils-1.5.6/tests/toolbox.inc.sh
new file mode 100644
index 0000000..a013f3e
--- /dev/null
+++ b/keyutils-1.5.6/tests/toolbox.inc.sh
@@ -0,0 +1,1101 @@
+###############################################################################
+#
+# Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+# Written by David Howells (dhowells@redhat.com)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+###############################################################################
+
+echo === $OUTPUTFILE ===
+
+endian=`file -L /proc/$$/exe`
+if expr "$endian" : '.* MSB executable.*' >&/dev/null
+then
+ endian=BE
+elif expr "$endian" : '.* LSB executable.*' >&/dev/null
+then
+ endian=LE
+else
+ echo -e "+++ \e[31;1mCan't Determine Endianness\e[0m"
+ echo "+++ Can't Determine Endianness" >>$OUTPUTFILE
+ exit 2
+fi
+
+maxtypelen=31
+maxtype=`for ((i=0; i<$((maxtypelen)); i++)); do echo -n a; done`
+
+PAGE_SIZE=`getconf PAGESIZE`
+maxdesclen=$((PAGE_SIZE - 1))
+maxdesc=`for ((i=0; i<$((maxdesclen)); i++)); do echo -n a; done`
+maxcall=$maxdesc
+
+maxsquota=`grep '^ *0': /proc/key-users | sed s@.*/@@`
+
+key_gc_delay_file="/proc/sys/kernel/keys/gc_delay"
+if [ -f $key_gc_delay_file ]; then
+ orig_gc_delay=`cat $key_gc_delay_file`
+else
+ orig_gc_delay=300
+fi
+
+
+function marker ()
+{
+ echo -e "+++ \e[33m$*\e[0m"
+ echo +++ $* >>$OUTPUTFILE
+}
+
+function failed()
+{
+ echo -e "\e[31;1mFAILED\e[0m"
+ echo === FAILED === >>$OUTPUTFILE
+ keyctl show >>$OUTPUTFILE
+ echo ============== >>$OUTPUTFILE
+ result=FAIL
+}
+
+function expect_args_error ()
+{
+ "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != 2 ]
+ then
+ failed
+ fi
+
+}
+
+function toolbox_report_result()
+{
+ if [ $RUNNING_UNDER_RHTS = 1 ]
+ then
+ report_result $TEST $result
+ fi
+ if [ $result = FAIL ]
+ then
+ exit 1
+ fi
+}
+
+###############################################################################
+#
+# compare version numbers to see if the first is less (older) than the second
+#
+###############################################################################
+function version_less_than ()
+{
+ a=$1
+ b=$2
+
+ if [ "$a" = "$b" ]
+ then
+ return 1
+ fi
+
+ # grab the leaders
+ x=${a%%-*}
+ y=${b%%-*}
+
+ if [ "$x" = "$a" -o "$y" = "$b" ]
+ then
+ if [ "$x" = "$y" ]
+ then
+ [ "$x" = "$a" ]
+ else
+ __version_less_than_dot "$x" "$y"
+ fi
+ elif [ "$x" = "$y" ]
+ then
+ less_than "${a#*-}" "${b#*-}"
+ else
+ __version_less_than_dot "$x" "$y"
+ fi
+}
+
+function __version_less_than_dot ()
+{
+ a=$1
+ b=$2
+
+ if [ "$a" = "$b" ]
+ then
+ return 1
+ fi
+
+ # grab the leaders
+ x=${a%%.*}
+ y=${b%%.*}
+
+ if [ "$x" = "$a" -o "$y" = "$b" ]
+ then
+ if [ "$x" = "$y" ]
+ then
+ [ "$x" = "$a" ]
+ else
+ expr "$x" \< "$y" >/dev/null
+ fi
+ elif [ "$x" = "$y" ]
+ then
+ __version_less_than_dot "${a#*.}" "${b#*.}"
+ else
+ expr "$x" \< "$y" >/dev/null
+ fi
+}
+
+###############################################################################
+#
+# Return true if the keyutils package being tested is older than the given
+# version.
+#
+###############################################################################
+function keyutils_older_than ()
+{
+ version_less_than $KEYUTILSVER $1
+}
+
+###############################################################################
+#
+# Return true if the keyutils package being tested is at or later than the
+# given version.
+#
+###############################################################################
+function keyutils_at_or_later_than ()
+{
+ ! keyutils_older_than $1
+}
+
+###############################################################################
+#
+# Return true if the keyutils package being tested is newer than the given
+# version.
+#
+###############################################################################
+function keyutils_newer_than ()
+{
+ version_less_than $1 $KEYUTILSVER
+}
+
+###############################################################################
+#
+# Return true if the keyutils package being tested is at or older than the
+# given version.
+#
+###############################################################################
+function keyutils_at_or_older_than ()
+{
+ ! keyutils_newer_than $1
+}
+
+###############################################################################
+#
+# extract an error message from the log file and check it
+#
+###############################################################################
+function expect_error ()
+{
+ my_varname=$1
+
+ my_errmsg="`tail -1 $OUTPUTFILE`"
+ eval $my_varname="\"$my_errmsg\""
+
+ if [ $# != 1 ]
+ then
+ echo "Format: expect_error <symbol>" >>$OUTPUTFILE
+ failed
+ fi
+
+ case $1 in
+ EPERM) my_err="Operation not permitted";;
+ EAGAIN) my_err="Resource temporarily unavailable";;
+ ENOENT) my_err="No such file or directory";;
+ EEXIST) my_err="File exists";;
+ ENOTDIR) my_err="Not a directory";;
+ EACCES) my_err="Permission denied";;
+ EINVAL) my_err="Invalid argument";;
+ ENODEV) my_err="No such device";;
+ ELOOP) my_err="Too many levels of symbolic links";;
+ EOPNOTSUPP) my_err="Operation not supported";;
+ EDEADLK) my_err="Resource deadlock avoided";;
+ EDQUOT) my_err="Disk quota exceeded";;
+ ENOKEY)
+ my_err="Required key not available"
+ old_err="Requested key not available"
+ alt_err="Unknown error 126"
+ ;;
+ EKEYEXPIRED)
+ my_err="Key has expired"
+ alt_err="Unknown error 127"
+ ;;
+ EKEYREVOKED)
+ my_err="Key has been revoked"
+ alt_err="Unknown error 128"
+ ;;
+ EKEYREJECTED)
+ my_err="Key has been rejected"
+ alt_err="Unknown error 129"
+ ;;
+ *)
+ echo "Unknown error message $1" >>$OUTPUTFILE
+ failed
+ ;;
+ esac
+
+ if expr "$my_errmsg" : ".*: $my_err" >&/dev/null
+ then
+ :
+ elif [ "x$alt_err" != "x" ] && expr "$my_errmsg" : ".*: $alt_err" >&/dev/null
+ then
+ :
+ elif [ "x$old_err" != "x" ] && expr "$my_errmsg" : ".*: $old_err" >&/dev/null
+ then
+ :
+ else
+ failed
+ fi
+}
+
+###############################################################################
+#
+# wait for a key to be destroyed (get removed from /proc/keys)
+#
+###############################################################################
+function pause_till_key_destroyed ()
+{
+ echo "+++ WAITING FOR KEY TO BE DESTROYED" >>$OUTPUTFILE
+ hexkeyid=`printf %08x $1`
+
+ while grep $hexkeyid /proc/keys
+ do
+ sleep 1
+ done
+}
+
+###############################################################################
+#
+# wait for a key to be unlinked
+#
+###############################################################################
+function pause_till_key_unlinked ()
+{
+ echo "+++ WAITING FOR KEY TO BE UNLINKED" >>$OUTPUTFILE
+
+ while true
+ do
+ echo keyctl unlink $1 $2 >>$OUTPUTFILE
+ keyctl unlink $1 $2 >>$OUTPUTFILE 2>&1
+ if [ $? != 1 ]
+ then
+ failed
+ fi
+
+ my_errmsg="`tail -1 $OUTPUTFILE`"
+ if ! expr "$my_errmsg" : ".*: No such file or directory" >&/dev/null
+ then
+ break
+ fi
+ sleep 1
+ done
+}
+
+###############################################################################
+#
+# request a key and attach it to the new keyring
+#
+###############################################################################
+function request_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl request "$@" >>$OUTPUTFILE
+ keyctl request "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# request a key and attach it to the new keyring, calling out if necessary
+#
+###############################################################################
+function request_key_callout ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl request2 "$@" >>$OUTPUTFILE
+ keyctl request2 "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# request a key and attach it to the new keyring, calling out if necessary and
+# passing the callout data in on stdin
+#
+###############################################################################
+function prequest_key_callout ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ data="$1"
+ shift
+
+ echo echo -n $data \| keyctl prequest2 "$@" >>$OUTPUTFILE
+ echo -n $data | keyctl prequest2 "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# create a key and attach it to the new keyring
+#
+###############################################################################
+function create_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl add "$@" >>$OUTPUTFILE
+ keyctl add "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# create a key and attach it to the new keyring, piping in the data
+#
+###############################################################################
+function pcreate_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ data="$1"
+ shift
+
+ echo echo -n $data \| keyctl padd "$@" >>$OUTPUTFILE
+ echo -n $data | keyctl padd "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# create a key and attach it to the new keyring
+#
+###############################################################################
+function create_keyring ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl newring "$@" >>$OUTPUTFILE
+ keyctl newring "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# extract a key ID from the log file
+#
+###############################################################################
+function expect_keyid ()
+{
+ my_varname=$1
+
+ my_keyid="`tail -1 $OUTPUTFILE`"
+ if expr "$my_keyid" : '[1-9][0-9]*' >&/dev/null
+ then
+ eval $my_varname=$my_keyid
+
+ if [ $# = 2 -a "x$my_keyid" != "x$2" ]
+ then
+ failed
+ fi
+ else
+ eval $my_varname=no
+ result=FAIL
+ fi
+}
+
+###############################################################################
+#
+# prettily list a keyring
+#
+###############################################################################
+function pretty_list_keyring ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl list $1 >>$OUTPUTFILE
+ keyctl list $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# list a keyring
+#
+###############################################################################
+function list_keyring ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl rlist $1 >>$OUTPUTFILE
+ keyctl rlist $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# extract a keyring listing from the log file and see if a key ID is contained
+# therein
+#
+###############################################################################
+function expect_keyring_rlist ()
+{
+ my_varname=$1
+
+ my_rlist="`tail -1 $OUTPUTFILE`"
+ eval $my_varname="\"$my_rlist\""
+
+ if [ $# = 2 -o $# = 3 ]
+ then
+ if [ "$2" = "empty" ]
+ then
+ if [ "x$my_rlist" != "x" ]
+ then
+ failed
+ fi
+ else
+ my_keyid=$2
+ my_found=0
+ my_expected=1
+ if [ $# = 3 -a "x$3" = "x--absent" ]; then my_expected=0; fi
+
+ for k in $my_rlist
+ do
+ if [ $k = $my_keyid ]
+ then
+ my_found=1
+ break;
+ fi
+ done
+
+ if [ $my_found != $my_expected ]
+ then
+ failed
+ fi
+ fi
+ fi
+}
+
+###############################################################################
+#
+# prettily describe a key
+#
+###############################################################################
+function pretty_describe_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl describe $1 >>$OUTPUTFILE
+ keyctl describe $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# describe a key
+#
+###############################################################################
+function describe_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl rdescribe $1 "@" >>$OUTPUTFILE
+ keyctl rdescribe $1 "@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# extract a raw key description from the log file and check it
+#
+###############################################################################
+function expect_key_rdesc ()
+{
+ my_varname=$1
+
+ my_rdesc="`tail -1 $OUTPUTFILE`"
+ eval $my_varname="\"$my_rdesc\""
+
+ if ! expr "$my_rdesc" : "$2" >&/dev/null
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# read a key's payload as a hex dump
+#
+###############################################################################
+function read_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl read $1 >>$OUTPUTFILE
+ keyctl read $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# read a key's payload as a printable string
+#
+###############################################################################
+function print_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl print $1 >>$OUTPUTFILE
+ keyctl print $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# pipe a key's raw payload to stdout
+#
+###############################################################################
+function pipe_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl pipe $1 >>$OUTPUTFILE
+ keyctl pipe $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# extract a printed payload from the log file
+#
+###############################################################################
+function expect_payload ()
+{
+ my_varname=$1
+
+ my_payload="`tail -1 $OUTPUTFILE`"
+ eval $my_varname="\"$my_payload\""
+
+ if [ $# == 2 -a "x$my_payload" != "x$2" ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# revoke a key
+#
+###############################################################################
+function revoke_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl revoke $1 >>$OUTPUTFILE
+ keyctl revoke $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# unlink a key from a keyring
+#
+###############################################################################
+function unlink_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ my_wait=0
+ if [ "x$1" = "x--wait" ]
+ then
+ my_wait=1
+ shift
+ fi
+
+ echo keyctl unlink $1 $2 >>$OUTPUTFILE
+ keyctl unlink $1 $2 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+
+ # keys are destroyed lazily
+ if [ $my_wait = 1 ]
+ then
+ pause_till_key_unlinked $1 $2
+ fi
+}
+
+###############################################################################
+#
+# extract a message about the number of keys unlinked
+#
+###############################################################################
+function expect_unlink_count ()
+{
+ my_varname=$1
+
+ my_nunlinks="`tail -1 $OUTPUTFILE`"
+
+ if ! expr "$my_nunlinks" : '^[0-9][0-9]* links removed$'
+ then
+ failed
+ fi
+
+ my_nunlinks=`echo $my_nunlinks | awk '{printf $1}'`
+ eval $my_varname="\"$my_nunlinks\""
+
+ if [ $# == 2 -a $my_nunlinks != $2 ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# update a key from a keyring
+#
+###############################################################################
+function update_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl update $1 $2 >>$OUTPUTFILE
+ keyctl update $1 $2 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# update a key from a keyring, piping the data in over stdin
+#
+###############################################################################
+function pupdate_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo echo -n $2 \| keyctl pupdate $1 >>$OUTPUTFILE
+ echo -n $2 | keyctl pupdate $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# clear a keyring
+#
+###############################################################################
+function clear_keyring ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl clear $1 >>$OUTPUTFILE
+ keyctl clear $1 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# link a key to a keyring
+#
+###############################################################################
+function link_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl link $1 $2 >>$OUTPUTFILE
+ keyctl link $1 $2 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# search for a key in a keyring
+#
+###############################################################################
+function search_for_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl search "$@" >>$OUTPUTFILE
+ keyctl search "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# set the permissions mask on a key
+#
+###############################################################################
+function set_key_perm ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl setperm "$@" >>$OUTPUTFILE
+ keyctl setperm "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# set the ownership of a key
+#
+###############################################################################
+function chown_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl chown "$@" >>$OUTPUTFILE
+ keyctl chown "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# set the group ownership of a key
+#
+###############################################################################
+function chgrp_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl chgrp "$@" >>$OUTPUTFILE
+ keyctl chgrp "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# run as a new session
+#
+###############################################################################
+function new_session ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl session "$@" >>$OUTPUTFILE
+ keyctl session "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# instantiate a key
+#
+###############################################################################
+function instantiate_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl instantiate "$@" >>$OUTPUTFILE
+ keyctl instantiate "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# instantiate a key, piping the data in over stdin
+#
+###############################################################################
+function pinstantiate_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ data="$1"
+ shift
+
+ echo echo -n $data \| keyctl pinstantiate "$@" >>$OUTPUTFILE
+ echo -n $data | keyctl pinstantiate "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# negate a key
+#
+###############################################################################
+function negate_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl negate "$@" >>$OUTPUTFILE
+ keyctl negate "$@" >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# set a key's expiry time
+#
+###############################################################################
+function timeout_key ()
+{
+ my_exitval=0
+ if [ "x$1" = "x--fail" ]
+ then
+ my_exitval=1
+ shift
+ fi
+
+ echo keyctl timeout $1 $2 >>$OUTPUTFILE
+ keyctl timeout $1 $2 >>$OUTPUTFILE 2>&1
+ if [ $? != $my_exitval ]
+ then
+ failed
+ fi
+}
+
+###############################################################################
+#
+# Make sure we sleep at least N seconds
+#
+###############################################################################
+function sleep_at_least ()
+{
+ my_now=`date +%s`
+ my_done_at=$(($my_now+$1+1))
+ sleep $1
+ while [ `date +%s` -lt $my_done_at ]
+ do
+ # Sleep in 1/50th of a second bursts till the time catches up
+ sleep .02
+ done
+}
+
+###############################################################################
+#
+# set gc delay time, return original value
+#
+###############################################################################
+function set_gc_delay()
+{
+ delay=$1
+ if [ -f $key_gc_delay_file ]; then
+ echo $delay > $key_gc_delay_file
+ echo "Set $key_gc_delay_file to $delay, orig: $orig_gc_delay"
+ fi
+}
+
diff --git a/keyutils-1.5.6/version.lds b/keyutils-1.5.6/version.lds
new file mode 100644
index 0000000..3e6f475
--- /dev/null
+++ b/keyutils-1.5.6/version.lds
@@ -0,0 +1,54 @@
+KEYUTILS_0.3 {
+
+ /* primary syscalls; may be overridden by glibc */
+ add_key;
+ request_key;
+ keyctl;
+
+ /* management functions */
+ keyctl_chown;
+ keyctl_clear;
+ keyctl_describe;
+ keyctl_describe_alloc;
+ keyctl_get_keyring_ID;
+ keyctl_instantiate;
+ keyctl_join_session_keyring;
+ keyctl_link;
+ keyctl_negate;
+ keyctl_read;
+ keyctl_read_alloc;
+ keyctl_revoke;
+ keyctl_search;
+ keyctl_setperm;
+ keyctl_set_reqkey_keyring;
+ keyctl_unlink;
+ keyctl_update;
+
+};
+
+KEYUTILS_1.0 {
+ /* management functions */
+ keyctl_assume_authority;
+ keyctl_set_timeout;
+
+} KEYUTILS_0.3;
+
+KEYUTILS_1.3 {
+ /* management functions */
+ keyctl_get_security;
+ keyctl_get_security_alloc;
+ keyctl_session_to_parent;
+
+} KEYUTILS_1.0;
+
+KEYUTILS_1.4 {
+ /* management functions */
+ keyctl_reject;
+ keyctl_instantiate_iov;
+ keyctl_invalidate;
+
+ /* utility functions */
+ recursive_key_scan;
+ recursive_session_key_scan;
+
+} KEYUTILS_1.3;
diff --git a/pax_global_header b/pax_global_header
new file mode 100644
index 0000000..81e6474
--- /dev/null
+++ b/pax_global_header
@@ -0,0 +1 @@
+52 comment=b59512468561ffc3f85d1e808b5d2ae6a6313276