├── .github └── workflows │ └── codeql-analysis.yml ├── AGENTS.md ├── AUTHORS ├── COPYING ├── COPYING.LIB ├── ChangeLog ├── INSTALL ├── Makefile.am ├── README.md ├── autogen.sh ├── bindings ├── Makefile.am ├── python3 │ ├── Makefile.am │ └── test │ │ ├── Makefile.am │ │ └── capng-test.py ├── src │ ├── Makefile.am │ └── capng_swig.i └── test │ ├── Makefile.am │ └── lib_test.py ├── configure.ac ├── docs ├── Makefile.am ├── capng_apply.3 ├── capng_apply_caps_fd.3 ├── capng_capability_to_name.3 ├── capng_change_id.3 ├── capng_clear.3 ├── capng_fill.3 ├── capng_get_caps_fd.3 ├── capng_get_caps_process.3 ├── capng_get_rootid.3 ├── capng_have_capabilities.3 ├── capng_have_capability.3 ├── capng_lock.3 ├── capng_name_to_capability.3 ├── capng_print_caps_numeric.3 ├── capng_print_caps_text.3 ├── capng_restore_state.3 ├── capng_save_state.3 ├── capng_set_rootid.3 ├── capng_setpid.3 ├── capng_update.3 ├── capng_updatev.3 └── libdrop_ambient.7 ├── libcap-ng.spec ├── m4 ├── Makefile.am └── cap-ng.m4 ├── src ├── Makefile.am ├── cap-ng.c ├── cap-ng.h ├── captab.h ├── libcap-ng.pc.in ├── libdrop_ambient.c ├── lookup_table.c └── test │ ├── Makefile.am │ ├── lib_test.c │ └── thread_test.c └── utils ├── Makefile.am ├── captest.8 ├── captest.c ├── filecap.8 ├── filecap.c ├── netcap.8 ├── netcap.c ├── proc-llist.c ├── proc-llist.h ├── pscap.8 └── pscap.c /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '35 12 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | container: registry.fedoraproject.org/fedora:latest 28 | 29 | strategy: 30 | fail-fast: false 31 | matrix: 32 | language: [ 'cpp', 'python' ] 33 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 34 | # Learn more: 35 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 36 | 37 | steps: 38 | - name: Checkout repository 39 | uses: actions/checkout@v2 40 | 41 | - name: get envinronment info 42 | run: uname -a 43 | 44 | - name: print fedora version 45 | run: cat /etc/fedora-release 46 | 47 | - name: install dependencies 48 | run: dnf -y install autoconf automake libtool gcc libattr-devel kernel-headers swig python3-devel python3 python-unversioned-command which git awk 49 | 50 | 51 | # Initializes the CodeQL tools for scanning. 52 | - name: Initialize CodeQL 53 | uses: github/codeql-action/init@v2 54 | with: 55 | languages: ${{ matrix.language }} 56 | # If you wish to specify custom queries, you can do so here or in a config file. 57 | # By default, queries listed here will override any specified in a config file. 58 | # Prefix the list here with "+" to use these queries and those in the config file. 59 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 60 | 61 | # ℹ️ Command-line programs to run using the OS shell. 62 | # 📚 https://git.io/JvXDl 63 | 64 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 65 | # and modify them (or add more) to build your code if your project 66 | # uses a compiled language 67 | 68 | - run: | 69 | ./autogen.sh 70 | ./configure --with-python3 71 | make 72 | 73 | - name: Perform CodeQL Analysis 74 | uses: github/codeql-action/analyze@v2 75 | -------------------------------------------------------------------------------- /AGENTS.md: -------------------------------------------------------------------------------- 1 | # Repository Guidelines 2 | 3 | This project contains a library aimed at manipulating posix capabilities 4 | on the Linux operating system. The repository uses autotools and has 5 | optional self-tests. Follow the instructions below when making changes. 6 | 7 | ## Building 8 | 9 | 1. Bootstrap and configure the build. The README shows an example: 10 | 11 | ``` 12 | cd libcap-ng 13 | ./autogen.sh 14 | ./configure --with-python3 15 | make 16 | ``` 17 | 18 | 2. Tests can be run with `make check` as described in INSTALL: 19 | 20 | ``` 21 | 2. Type 'make' to compile the package. 22 | 23 | 3. Optionally, type 'make check' to run any self-tests that come with 24 | the package, generally using the just-built uninstalled binaries. 25 | ``` 26 | 27 | 3. Installation (`make install`) is typically performed only after 28 | successful tests. 29 | 30 | ## Project Structure for Navigation 31 | 32 | - `/src`: This is where the code that makes up libcap-ng is located 33 | - `/utils`: This holds the code for pscap, netcap, and filecap 34 | - `/docs`: This holds all of the man pages 35 | - `/bindings`: This holds swig based python bindings for libcap-ng 36 | 37 | ## Code Style 38 | 39 | Contributions should follow the Linux Kernel coding style: 40 | 41 | ``` 42 | So, if you would like to test it and report issues or even contribute code 43 | feel free to do so. But please discuss the contribution first to ensure 44 | that its acceptable. This project uses the Linux Kernel Style Guideline. 45 | Please follow it if you wish to contribute. 46 | ``` 47 | 48 | In practice this means: 49 | 50 | - Indent with tabs (8 spaces per tab). 51 | - Keep lines within ~80 columns. 52 | - Place braces and other formatting as in the kernel style. 53 | 54 | ## Commit Messages 55 | 56 | - Use a concise one-line summary followed by a blank line and additional 57 | details if needed (similar to existing commits). 58 | 59 | ## Summary 60 | 61 | - Build with `autogen.sh`, `configure`, and `make`. 62 | - Run `make check` to execute the self-tests. 63 | - Follow Linux Kernel coding style (tabs, 80 columns). 64 | - Keep commit messages short and descriptive. 65 | 66 | These guidelines should help future contributors and automated tools 67 | work consistently within the libcap-ng repository. 68 | 69 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | This library has been written by: 2 | Steve Grubb 3 | 4 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /COPYING.LIB: -------------------------------------------------------------------------------- 1 | 2 | GNU LESSER GENERAL PUBLIC LICENSE 3 | Version 2.1, February 1999 4 | 5 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 6 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 7 | Everyone is permitted to copy and distribute verbatim copies 8 | of this license document, but changing it is not allowed. 9 | 10 | [This is the first released version of the Lesser GPL. It also counts 11 | as the successor of the GNU Library Public License, version 2, hence 12 | the version number 2.1.] 13 | 14 | Preamble 15 | 16 | The licenses for most software are designed to take away your 17 | freedom to share and change it. By contrast, the GNU General Public 18 | Licenses are intended to guarantee your freedom to share and change 19 | free software--to make sure the software is free for all its users. 20 | 21 | This license, the Lesser General Public License, applies to some 22 | specially designated software packages--typically libraries--of the 23 | Free Software Foundation and other authors who decide to use it. You 24 | can use it too, but we suggest you first think carefully about whether 25 | this license or the ordinary General Public License is the better 26 | strategy to use in any particular case, based on the explanations 27 | below. 28 | 29 | When we speak of free software, we are referring to freedom of use, 30 | not price. Our General Public Licenses are designed to make sure that 31 | you have the freedom to distribute copies of free software (and charge 32 | for this service if you wish); that you receive source code or can get 33 | it if you want it; that you can change the software and use pieces of 34 | it in new free programs; and that you are informed that you can do 35 | these things. 36 | 37 | To protect your rights, we need to make restrictions that forbid 38 | distributors to deny you these rights or to ask you to surrender these 39 | rights. These restrictions translate to certain responsibilities for 40 | you if you distribute copies of the library or if you modify it. 41 | 42 | For example, if you distribute copies of the library, whether gratis 43 | or for a fee, you must give the recipients all the rights that we gave 44 | you. You must make sure that they, too, receive or can get the source 45 | code. If you link other code with the library, you must provide 46 | complete object files to the recipients, so that they can relink them 47 | with the library after making changes to the library and recompiling 48 | it. And you must show them these terms so they know their rights. 49 | 50 | We protect your rights with a two-step method: (1) we copyright the 51 | library, and (2) we offer you this license, which gives you legal 52 | permission to copy, distribute and/or modify the library. 53 | 54 | To protect each distributor, we want to make it very clear that 55 | there is no warranty for the free library. Also, if the library is 56 | modified by someone else and passed on, the recipients should know 57 | that what they have is not the original version, so that the original 58 | author's reputation will not be affected by problems that might be 59 | introduced by others. 60 | ^L 61 | Finally, software patents pose a constant threat to the existence of 62 | any free program. We wish to make sure that a company cannot 63 | effectively restrict the users of a free program by obtaining a 64 | restrictive license from a patent holder. Therefore, we insist that 65 | any patent license obtained for a version of the library must be 66 | consistent with the full freedom of use specified in this license. 67 | 68 | Most GNU software, including some libraries, is covered by the 69 | ordinary GNU General Public License. This license, the GNU Lesser 70 | General Public License, applies to certain designated libraries, and 71 | is quite different from the ordinary General Public License. We use 72 | this license for certain libraries in order to permit linking those 73 | libraries into non-free programs. 74 | 75 | When a program is linked with a library, whether statically or using 76 | a shared library, the combination of the two is legally speaking a 77 | combined work, a derivative of the original library. The ordinary 78 | General Public License therefore permits such linking only if the 79 | entire combination fits its criteria of freedom. The Lesser General 80 | Public License permits more lax criteria for linking other code with 81 | the library. 82 | 83 | We call this license the "Lesser" General Public License because it 84 | does Less to protect the user's freedom than the ordinary General 85 | Public License. It also provides other free software developers Less 86 | of an advantage over competing non-free programs. These disadvantages 87 | are the reason we use the ordinary General Public License for many 88 | libraries. However, the Lesser license provides advantages in certain 89 | special circumstances. 90 | 91 | For example, on rare occasions, there may be a special need to 92 | encourage the widest possible use of a certain library, so that it 93 | becomes 94 | a de-facto standard. To achieve this, non-free programs must be 95 | allowed to use the library. A more frequent case is that a free 96 | library does the same job as widely used non-free libraries. In this 97 | case, there is little to gain by limiting the free library to free 98 | software only, so we use the Lesser General Public License. 99 | 100 | In other cases, permission to use a particular library in non-free 101 | programs enables a greater number of people to use a large body of 102 | free software. For example, permission to use the GNU C Library in 103 | non-free programs enables many more people to use the whole GNU 104 | operating system, as well as its variant, the GNU/Linux operating 105 | system. 106 | 107 | Although the Lesser General Public License is Less protective of the 108 | users' freedom, it does ensure that the user of a program that is 109 | linked with the Library has the freedom and the wherewithal to run 110 | that program using a modified version of the Library. 111 | 112 | The precise terms and conditions for copying, distribution and 113 | modification follow. Pay close attention to the difference between a 114 | "work based on the library" and a "work that uses the library". The 115 | former contains code derived from the library, whereas the latter must 116 | be combined with the library in order to run. 117 | ^L 118 | GNU LESSER GENERAL PUBLIC LICENSE 119 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 120 | 121 | 0. This License Agreement applies to any software library or other 122 | program which contains a notice placed by the copyright holder or 123 | other authorized party saying it may be distributed under the terms of 124 | this Lesser General Public License (also called "this License"). 125 | Each licensee is addressed as "you". 126 | 127 | A "library" means a collection of software functions and/or data 128 | prepared so as to be conveniently linked with application programs 129 | (which use some of those functions and data) to form executables. 130 | 131 | The "Library", below, refers to any such software library or work 132 | which has been distributed under these terms. A "work based on the 133 | Library" means either the Library or any derivative work under 134 | copyright law: that is to say, a work containing the Library or a 135 | portion of it, either verbatim or with modifications and/or translated 136 | straightforwardly into another language. (Hereinafter, translation is 137 | included without limitation in the term "modification".) 138 | 139 | "Source code" for a work means the preferred form of the work for 140 | making modifications to it. For a library, complete source code means 141 | all the source code for all modules it contains, plus any associated 142 | interface definition files, plus the scripts used to control 143 | compilation 144 | and installation of the library. 145 | 146 | Activities other than copying, distribution and modification are not 147 | covered by this License; they are outside its scope. The act of 148 | running a program using the Library is not restricted, and output from 149 | such a program is covered only if its contents constitute a work based 150 | on the Library (independent of the use of the Library in a tool for 151 | writing it). Whether that is true depends on what the Library does 152 | and what the program that uses the Library does. 153 | 154 | 1. You may copy and distribute verbatim copies of the Library's 155 | complete source code as you receive it, in any medium, provided that 156 | you conspicuously and appropriately publish on each copy an 157 | appropriate copyright notice and disclaimer of warranty; keep intact 158 | all the notices that refer to this License and to the absence of any 159 | warranty; and distribute a copy of this License along with the 160 | Library. 161 | 162 | You may charge a fee for the physical act of transferring a copy, 163 | and you may at your option offer warranty protection in exchange for a 164 | fee. 165 | 166 | 2. You may modify your copy or copies of the Library or any portion 167 | of it, thus forming a work based on the Library, and copy and 168 | distribute such modifications or work under the terms of Section 1 169 | above, provided that you also meet all of these conditions: 170 | 171 | a) The modified work must itself be a software library. 172 | 173 | b) You must cause the files modified to carry prominent notices 174 | stating that you changed the files and the date of any change. 175 | 176 | c) You must cause the whole of the work to be licensed at no 177 | charge to all third parties under the terms of this License. 178 | 179 | d) If a facility in the modified Library refers to a function or a 180 | table of data to be supplied by an application program that uses 181 | the facility, other than as an argument passed when the facility 182 | is invoked, then you must make a good faith effort to ensure that, 183 | in the event an application does not supply such function or 184 | table, the facility still operates, and performs whatever part of 185 | its purpose remains meaningful. 186 | 187 | (For example, a function in a library to compute square roots has 188 | a purpose that is entirely well-defined independent of the 189 | application. Therefore, Subsection 2d requires that any 190 | application-supplied function or table used by this function must 191 | be optional: if the application does not supply it, the square 192 | root function must still compute square roots.) 193 | 194 | These requirements apply to the modified work as a whole. If 195 | identifiable sections of that work are not derived from the Library, 196 | and can be reasonably considered independent and separate works in 197 | themselves, then this License, and its terms, do not apply to those 198 | sections when you distribute them as separate works. But when you 199 | distribute the same sections as part of a whole which is a work based 200 | on the Library, the distribution of the whole must be on the terms of 201 | this License, whose permissions for other licensees extend to the 202 | entire whole, and thus to each and every part regardless of who wrote 203 | it. 204 | 205 | Thus, it is not the intent of this section to claim rights or contest 206 | your rights to work written entirely by you; rather, the intent is to 207 | exercise the right to control the distribution of derivative or 208 | collective works based on the Library. 209 | 210 | In addition, mere aggregation of another work not based on the Library 211 | with the Library (or with a work based on the Library) on a volume of 212 | a storage or distribution medium does not bring the other work under 213 | the scope of this License. 214 | 215 | 3. You may opt to apply the terms of the ordinary GNU General Public 216 | License instead of this License to a given copy of the Library. To do 217 | this, you must alter all the notices that refer to this License, so 218 | that they refer to the ordinary GNU General Public License, version 2, 219 | instead of to this License. (If a newer version than version 2 of the 220 | ordinary GNU General Public License has appeared, then you can specify 221 | that version instead if you wish.) Do not make any other change in 222 | these notices. 223 | ^L 224 | Once this change is made in a given copy, it is irreversible for 225 | that copy, so the ordinary GNU General Public License applies to all 226 | subsequent copies and derivative works made from that copy. 227 | 228 | This option is useful when you wish to copy part of the code of 229 | the Library into a program that is not a library. 230 | 231 | 4. You may copy and distribute the Library (or a portion or 232 | derivative of it, under Section 2) in object code or executable form 233 | under the terms of Sections 1 and 2 above provided that you accompany 234 | it with the complete corresponding machine-readable source code, which 235 | must be distributed under the terms of Sections 1 and 2 above on a 236 | medium customarily used for software interchange. 237 | 238 | If distribution of object code is made by offering access to copy 239 | from a designated place, then offering equivalent access to copy the 240 | source code from the same place satisfies the requirement to 241 | distribute the source code, even though third parties are not 242 | compelled to copy the source along with the object code. 243 | 244 | 5. A program that contains no derivative of any portion of the 245 | Library, but is designed to work with the Library by being compiled or 246 | linked with it, is called a "work that uses the Library". Such a 247 | work, in isolation, is not a derivative work of the Library, and 248 | therefore falls outside the scope of this License. 249 | 250 | However, linking a "work that uses the Library" with the Library 251 | creates an executable that is a derivative of the Library (because it 252 | contains portions of the Library), rather than a "work that uses the 253 | library". The executable is therefore covered by this License. 254 | Section 6 states terms for distribution of such executables. 255 | 256 | When a "work that uses the Library" uses material from a header file 257 | that is part of the Library, the object code for the work may be a 258 | derivative work of the Library even though the source code is not. 259 | Whether this is true is especially significant if the work can be 260 | linked without the Library, or if the work is itself a library. The 261 | threshold for this to be true is not precisely defined by law. 262 | 263 | If such an object file uses only numerical parameters, data 264 | structure layouts and accessors, and small macros and small inline 265 | functions (ten lines or less in length), then the use of the object 266 | file is unrestricted, regardless of whether it is legally a derivative 267 | work. (Executables containing this object code plus portions of the 268 | Library will still fall under Section 6.) 269 | 270 | Otherwise, if the work is a derivative of the Library, you may 271 | distribute the object code for the work under the terms of Section 6. 272 | Any executables containing that work also fall under Section 6, 273 | whether or not they are linked directly with the Library itself. 274 | ^L 275 | 6. As an exception to the Sections above, you may also combine or 276 | link a "work that uses the Library" with the Library to produce a 277 | work containing portions of the Library, and distribute that work 278 | under terms of your choice, provided that the terms permit 279 | modification of the work for the customer's own use and reverse 280 | engineering for debugging such modifications. 281 | 282 | You must give prominent notice with each copy of the work that the 283 | Library is used in it and that the Library and its use are covered by 284 | this License. You must supply a copy of this License. If the work 285 | during execution displays copyright notices, you must include the 286 | copyright notice for the Library among them, as well as a reference 287 | directing the user to the copy of this License. Also, you must do one 288 | of these things: 289 | 290 | a) Accompany the work with the complete corresponding 291 | machine-readable source code for the Library including whatever 292 | changes were used in the work (which must be distributed under 293 | Sections 1 and 2 above); and, if the work is an executable linked 294 | with the Library, with the complete machine-readable "work that 295 | uses the Library", as object code and/or source code, so that the 296 | user can modify the Library and then relink to produce a modified 297 | executable containing the modified Library. (It is understood 298 | that the user who changes the contents of definitions files in the 299 | Library will not necessarily be able to recompile the application 300 | to use the modified definitions.) 301 | 302 | b) Use a suitable shared library mechanism for linking with the 303 | Library. A suitable mechanism is one that (1) uses at run time a 304 | copy of the library already present on the user's computer system, 305 | rather than copying library functions into the executable, and (2) 306 | will operate properly with a modified version of the library, if 307 | the user installs one, as long as the modified version is 308 | interface-compatible with the version that the work was made with. 309 | 310 | c) Accompany the work with a written offer, valid for at 311 | least three years, to give the same user the materials 312 | specified in Subsection 6a, above, for a charge no more 313 | than the cost of performing this distribution. 314 | 315 | d) If distribution of the work is made by offering access to copy 316 | from a designated place, offer equivalent access to copy the above 317 | specified materials from the same place. 318 | 319 | e) Verify that the user has already received a copy of these 320 | materials or that you have already sent this user a copy. 321 | 322 | For an executable, the required form of the "work that uses the 323 | Library" must include any data and utility programs needed for 324 | reproducing the executable from it. However, as a special exception, 325 | the materials to be distributed need not include anything that is 326 | normally distributed (in either source or binary form) with the major 327 | components (compiler, kernel, and so on) of the operating system on 328 | which the executable runs, unless that component itself accompanies 329 | the executable. 330 | 331 | It may happen that this requirement contradicts the license 332 | restrictions of other proprietary libraries that do not normally 333 | accompany the operating system. Such a contradiction means you cannot 334 | use both them and the Library together in an executable that you 335 | distribute. 336 | ^L 337 | 7. You may place library facilities that are a work based on the 338 | Library side-by-side in a single library together with other library 339 | facilities not covered by this License, and distribute such a combined 340 | library, provided that the separate distribution of the work based on 341 | the Library and of the other library facilities is otherwise 342 | permitted, and provided that you do these two things: 343 | 344 | a) Accompany the combined library with a copy of the same work 345 | based on the Library, uncombined with any other library 346 | facilities. This must be distributed under the terms of the 347 | Sections above. 348 | 349 | b) Give prominent notice with the combined library of the fact 350 | that part of it is a work based on the Library, and explaining 351 | where to find the accompanying uncombined form of the same work. 352 | 353 | 8. You may not copy, modify, sublicense, link with, or distribute 354 | the Library except as expressly provided under this License. Any 355 | attempt otherwise to copy, modify, sublicense, link with, or 356 | distribute the Library is void, and will automatically terminate your 357 | rights under this License. However, parties who have received copies, 358 | or rights, from you under this License will not have their licenses 359 | terminated so long as such parties remain in full compliance. 360 | 361 | 9. You are not required to accept this License, since you have not 362 | signed it. However, nothing else grants you permission to modify or 363 | distribute the Library or its derivative works. These actions are 364 | prohibited by law if you do not accept this License. Therefore, by 365 | modifying or distributing the Library (or any work based on the 366 | Library), you indicate your acceptance of this License to do so, and 367 | all its terms and conditions for copying, distributing or modifying 368 | the Library or works based on it. 369 | 370 | 10. Each time you redistribute the Library (or any work based on the 371 | Library), the recipient automatically receives a license from the 372 | original licensor to copy, distribute, link with or modify the Library 373 | subject to these terms and conditions. You may not impose any further 374 | restrictions on the recipients' exercise of the rights granted herein. 375 | You are not responsible for enforcing compliance by third parties with 376 | this License. 377 | ^L 378 | 11. If, as a consequence of a court judgment or allegation of patent 379 | infringement or for any other reason (not limited to patent issues), 380 | conditions are imposed on you (whether by court order, agreement or 381 | otherwise) that contradict the conditions of this License, they do not 382 | excuse you from the conditions of this License. If you cannot 383 | distribute so as to satisfy simultaneously your obligations under this 384 | License and any other pertinent obligations, then as a consequence you 385 | may not distribute the Library at all. For example, if a patent 386 | license would not permit royalty-free redistribution of the Library by 387 | all those who receive copies directly or indirectly through you, then 388 | the only way you could satisfy both it and this License would be to 389 | refrain entirely from distribution of the Library. 390 | 391 | If any portion of this section is held invalid or unenforceable under 392 | any particular circumstance, the balance of the section is intended to 393 | apply, and the section as a whole is intended to apply in other 394 | circumstances. 395 | 396 | It is not the purpose of this section to induce you to infringe any 397 | patents or other property right claims or to contest validity of any 398 | such claims; this section has the sole purpose of protecting the 399 | integrity of the free software distribution system which is 400 | implemented by public license practices. Many people have made 401 | generous contributions to the wide range of software distributed 402 | through that system in reliance on consistent application of that 403 | system; it is up to the author/donor to decide if he or she is willing 404 | to distribute software through any other system and a licensee cannot 405 | impose that choice. 406 | 407 | This section is intended to make thoroughly clear what is believed to 408 | be a consequence of the rest of this License. 409 | 410 | 12. If the distribution and/or use of the Library is restricted in 411 | certain countries either by patents or by copyrighted interfaces, the 412 | original copyright holder who places the Library under this License 413 | may add an explicit geographical distribution limitation excluding those 414 | countries, so that distribution is permitted only in or among 415 | countries not thus excluded. In such case, this License incorporates 416 | the limitation as if written in the body of this License. 417 | 418 | 13. The Free Software Foundation may publish revised and/or new 419 | versions of the Lesser General Public License from time to time. 420 | Such new versions will be similar in spirit to the present version, 421 | but may differ in detail to address new problems or concerns. 422 | 423 | Each version is given a distinguishing version number. If the Library 424 | specifies a version number of this License which applies to it and 425 | "any later version", you have the option of following the terms and 426 | conditions either of that version or of any later version published by 427 | the Free Software Foundation. If the Library does not specify a 428 | license version number, you may choose any version ever published by 429 | the Free Software Foundation. 430 | ^L 431 | 14. If you wish to incorporate parts of the Library into other free 432 | programs whose distribution conditions are incompatible with these, 433 | write to the author to ask for permission. For software which is 434 | copyrighted by the Free Software Foundation, write to the Free 435 | Software Foundation; we sometimes make exceptions for this. Our 436 | decision will be guided by the two goals of preserving the free status 437 | of all derivatives of our free software and of promoting the sharing 438 | and reuse of software generally. 439 | 440 | NO WARRANTY 441 | 442 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 443 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 444 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 445 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 446 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 447 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 448 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 449 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 450 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 451 | 452 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 453 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 454 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 455 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 456 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 457 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 458 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 459 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 460 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 461 | DAMAGES. 462 | 463 | END OF TERMS AND CONDITIONS 464 | ^L 465 | How to Apply These Terms to Your New Libraries 466 | 467 | If you develop a new library, and you want it to be of the greatest 468 | possible use to the public, we recommend making it free software that 469 | everyone can redistribute and change. You can do so by permitting 470 | redistribution under these terms (or, alternatively, under the terms 471 | of the ordinary General Public License). 472 | 473 | To apply these terms, attach the following notices to the library. 474 | It is safest to attach them to the start of each source file to most 475 | effectively convey the exclusion of warranty; and each file should 476 | have at least the "copyright" line and a pointer to where the full 477 | notice is found. 478 | 479 | 480 | 482 | Copyright (C) 483 | 484 | This library is free software; you can redistribute it and/or 485 | modify it under the terms of the GNU Lesser General Public 486 | License as published by the Free Software Foundation; either 487 | version 2 of the License, or (at your option) any later version. 488 | 489 | This library is distributed in the hope that it will be useful, 490 | but WITHOUT ANY WARRANTY; without even the implied warranty of 491 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 492 | Lesser General Public License for more details. 493 | 494 | You should have received a copy of the GNU Lesser General Public 495 | License along with this library; if not, write to the Free Software 496 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 497 | 498 | Also add information on how to contact you by electronic and paper 499 | mail. 500 | 501 | You should also get your employer (if you work as a programmer) or 502 | your 503 | school, if any, to sign a "copyright disclaimer" for the library, if 504 | necessary. Here is a sample; alter the names: 505 | 506 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 507 | library `Frob' (a library for tweaking knobs) written by James 508 | Random Hacker. 509 | 510 | , 1 April 1990 511 | Ty Coon, President of Vice 512 | 513 | That's all there is to it! 514 | 515 | 516 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 0.8.6 2 | - Fix python path when invoking py-compile (Jan Palus) 3 | - Drop python2 bindings (Rudi Heitbaum) 4 | - Optimize capability name translation lookups 5 | 6 | 0.8.5 7 | - Remove python global exception handler since it's deprecated 8 | - Make the utilities link against just built libraries 9 | - Remove unused macro in cap-ng.h 10 | 11 | 0.8.4 12 | - In capng_change_id, clear PR_SET_KEEPCAPS if returning an error 13 | - pscap: add -p option for reporting a specified process (Masatake Yamato) 14 | - Annotate function prototypes to warn if results are unused 15 | - Drop python2 support 16 | 17 | 0.8.3 18 | - Fix parameters to capng_updatev python bindings to be signed 19 | - Detect capability options at runtime to make containerization easier (ntkme) 20 | - Initialize the library when linked statically 21 | - Add gcc function attributes for deallocation 22 | 23 | 0.8.2 24 | - In capng_apply, if we blew up in bounding set, allow setting capabilities 25 | - If PR_CAP_AMBIENT is not available, do not build libdrop_ambient 26 | - Improve last_cap check 27 | 28 | 0.8.1 29 | - If procfs is not available, leave last_cap as CAP_LAST_CAP 30 | - If bounding and ambient not found in status, try prctl method 31 | - In capng_apply, move ambient caps to the end of the transaction 32 | - In capng_apply, return errors more aggressively. 33 | - In capng_apply, if the action includes the bounding set,resync with the kernel 34 | - Fix signed/unsigned warning in cap-ng.c 35 | - In capng_apply, return a unique error code to diagnose any failure 36 | - In capng_have_capability, return 0 for failure 37 | - Add the libdrop_ambient admin tool 38 | 39 | 0.8 40 | - Add vararg support to python bindings for capng_updatev 41 | - Add support for ambient capabilities 42 | - Add support for V3 filesystem capabilities 43 | 44 | 0.7.11 45 | - Really clear bounding set if asked in capng_change_id 46 | - Add CAP_PERFMON, CAP_BPF, & CAP_CHECKPOINT_RESTORE 47 | - Avoid malloc/free in capng_apply (Natanael Copa) 48 | - If procfs is not available, get bounding set via prctl 49 | - Cleanup some compiler warnings 50 | 51 | 0.7.10 52 | - Update capng_change_id man page 53 | - Add capng_have_permitted_capabilities function 54 | - Update filecap to output which set the capabilities are in 55 | - Fix filecap to not output an error when a file has no capabilities 56 | - Add udplite support to netcap 57 | - Fix usage of pthread_atfork (Joe Orton) 58 | - Mark processes in child user namespaces with * (Danila Kiver) 59 | 60 | 0.7.9 61 | - Fix byte compiling python3 bindings 62 | - Detect and output a couple errors in filecap 63 | - Use pthread_atfork to optionally reset the pid and related info on fork 64 | - Rework spec file to show new python2/3 separation 65 | 66 | 0.7.8 67 | - Improve Python3 support 68 | - Fix the thread separation test 69 | - Correct typo in cap_pacct text 70 | - Update man page for captest 71 | - Fix sscanf string lengths in netcap 72 | - Correct linking of python3 module 73 | 74 | 0.7.7 75 | - Make sure all types used in _lnode are defined in proc-llist.h 76 | - Fix python binding test for old kernels 77 | - Fix leaked FD in library init 78 | 79 | 0.7.6 80 | - Fix python3 support 81 | 82 | 0.7.5 83 | - Make python3 supported 84 | - In python bindings test, clamp CAP_LAST_CAP with /proc/.../cap_last_cap 85 | - Update table for 3.16 kernel 86 | 87 | 0.7.4 88 | - In pscap, remove unused code 89 | - Add CAPNG_INIT_SUPP_GRP to capng_change_id 90 | - Drop CAP_COMPROMISE_KERNEL 91 | - Update the autotools components 92 | - Dynamically detect last capability (#895105) 93 | - Add PR_SET_NO_NEW_PRIVS to capng_lock if kernel supports it 94 | 95 | 0.7.3 96 | - Make sure stderr is used consistently in utils 97 | - Fix logic causing file based capabilities to not be supported when it should 98 | 99 | 0.7.1 100 | - Add CAP_COMPROMISE_KERNEL 101 | - Define FTW_CONTINUE in case its not defined in libc 102 | - Use glibc for xattr.h if available 103 | 104 | 0.7 105 | - Make file opens use the cloexec flag (Cristian Rodríguez) 106 | - Add CAP_BLOCK_SUSPEND 107 | - Fix possible segfaults when CAP_LAST_CAP is larger than the lookup table 108 | - In pscap, don't drop capabilities when running with capabilities 109 | 110 | 0.6.6 111 | - In netcap, make sure readlink is handled properly 112 | - Add CAP_SYSLOG 113 | - In netcap and pscap, ensure euid is initialized 114 | - Add CAP_WAKE_ALARM 115 | 116 | 0.6.5 117 | - Fix self test build problem on clean system (Sterling X. Winter) 118 | - Only open regular files in filecap 119 | - Make building Python bindings optional 120 | - Python bindings update (arfrever.fta) 121 | - Fix filecap segfault when checking a specific file 122 | - Add define for missing XATTR_NAME_CAPS since 2.6.36 makes it private 123 | 124 | 0.6.4 125 | - Update packet socket code to print interface 126 | - Fix effective capabilities read from file descriptor 127 | - Use thread ID for capget/set calls 128 | 129 | 0.6.3 130 | - In netcap and pscap use the effective uid 131 | - In capng_change_id, only retain setpcap if clearing the bounding set 132 | 133 | 0.6.2 134 | - Make pscap drop capabilities so its not listed in report 135 | - Review prctl calls to make sure we are passing 5 args 136 | - Add package config support 137 | 138 | 0.6.1 139 | - In netcap, don't complain about missing udp or raw network files 140 | - Adjusted data read in for file based capabilities 141 | 142 | 0.6 143 | - In netcap, don't complain about missing network files 144 | - Add python bindings 145 | - Add m4 macro file to help developers configure libcap-ng in their apps 146 | - Fake applying bounding set for old OS 147 | - Ignore setpcap for old OS when changing id 148 | - Remove capabilities v1 data handling from reading file attributes 149 | - Set the SECURE_NO_SETUID_FIXUP and LOCKED securebits flags in capng_lock 150 | 151 | 0.5.1 152 | - Remove unnecessary uid check in change_uid when dropping supplemental groups 153 | - Add credential printout and other improvements to captest 154 | - In the init routine, set hdr.pid to current process 155 | - Use bit mask on effective capabilities check in have_capabilities 156 | - Numeric printing of bounding set bits were in wrong order 157 | - In update function, reverse the order of bounding set vs capabilities 158 | - Revise the tests used to determine if bounding set should be updated 159 | 160 | 0.5 161 | - If attr/xattr.h is not available disable file system capabilities 162 | - Initialize capng_have_capability with capng_get_caps_process if unknown 163 | - Make capng_change_id drop the gid if given 164 | - Fixed cap_update for bounding set 165 | - Fix have_capability for bounding set 166 | - Added more tests to the make check target 167 | - Remove CAPNG_LOCK_PERMS for change_id flags 168 | - Added captest program 169 | 170 | 0.4.2 171 | - Fix missing includes for various OS and platforms 172 | - Correct misplaced #ifdef for older OS 173 | - Reorder clearing of bounding set in capng_change_id 174 | - Make locking a noop in capng_change_id for the moment 175 | 176 | 0.4.1 177 | - spec file clean ups 178 | - Man pages for all library functions 179 | 180 | 0.4 181 | - Initial public release 182 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell commands `./configure; make; make install' should 16 | configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the `README' file for 18 | instructions specific to this package. Some packages provide this 19 | `INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The `configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a `Makefile' in each directory of the package. 27 | It may also create one or more `.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script `config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file `config.log' containing compiler output (useful mainly for 31 | debugging `configure'). 32 | 33 | It can also use an optional file (typically called `config.cache' 34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 35 | the results of its tests to speed up reconfiguring. Caching is 36 | disabled by default to prevent problems with accidental use of stale 37 | cache files. 38 | 39 | If you need to do unusual things to compile the package, please try 40 | to figure out how `configure' could check whether to do them, and mail 41 | diffs or instructions to the address given in the `README' so they can 42 | be considered for the next release. If you are using the cache, and at 43 | some point `config.cache' contains results you don't want to keep, you 44 | may remove or edit it. 45 | 46 | The file `configure.ac' (or `configure.in') is used to create 47 | `configure' by a program called `autoconf'. You need `configure.ac' if 48 | you want to change it or regenerate `configure' using a newer version 49 | of `autoconf'. 50 | 51 | The simplest way to compile this package is: 52 | 53 | 1. `cd' to the directory containing the package's source code and type 54 | `./configure' to configure the package for your system. 55 | 56 | Running `configure' might take a while. While running, it prints 57 | some messages telling which features it is checking for. 58 | 59 | 2. Type `make' to compile the package. 60 | 61 | 3. Optionally, type `make check' to run any self-tests that come with 62 | the package, generally using the just-built uninstalled binaries. 63 | 64 | 4. Type `make install' to install the programs and any data files and 65 | documentation. When installing into a prefix owned by root, it is 66 | recommended that the package be configured and built as a regular 67 | user, and only the `make install' phase executed with root 68 | privileges. 69 | 70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but 71 | this time using the binaries in their final installed location. 72 | This target does not install anything. Running this target as a 73 | regular user, particularly if the prior `make install' required 74 | root privileges, verifies that the installation completed 75 | correctly. 76 | 77 | 6. You can remove the program binaries and object files from the 78 | source code directory by typing `make clean'. To also remove the 79 | files that `configure' created (so you can compile the package for 80 | a different kind of computer), type `make distclean'. There is 81 | also a `make maintainer-clean' target, but that is intended mainly 82 | for the package's developers. If you use it, you may have to get 83 | all sorts of other programs in order to regenerate files that came 84 | with the distribution. 85 | 86 | 7. Often, you can also type `make uninstall' to remove the installed 87 | files again. In practice, not all packages have tested that 88 | uninstallation works correctly, even though it is required by the 89 | GNU Coding Standards. 90 | 91 | 8. Some packages, particularly those that use Automake, provide `make 92 | distcheck', which can by used by developers to test that all other 93 | targets like `make install' and `make uninstall' work correctly. 94 | This target is generally not run by end users. 95 | 96 | Compilers and Options 97 | ===================== 98 | 99 | Some systems require unusual options for compilation or linking that 100 | the `configure' script does not know about. Run `./configure --help' 101 | for details on some of the pertinent environment variables. 102 | 103 | You can give `configure' initial values for configuration parameters 104 | by setting variables in the command line or in the environment. Here 105 | is an example: 106 | 107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 108 | 109 | *Note Defining Variables::, for more details. 110 | 111 | Compiling For Multiple Architectures 112 | ==================================== 113 | 114 | You can compile the package for more than one kind of computer at the 115 | same time, by placing the object files for each architecture in their 116 | own directory. To do this, you can use GNU `make'. `cd' to the 117 | directory where you want the object files and executables to go and run 118 | the `configure' script. `configure' automatically checks for the 119 | source code in the directory that `configure' is in and in `..'. This 120 | is known as a "VPATH" build. 121 | 122 | With a non-GNU `make', it is safer to compile the package for one 123 | architecture at a time in the source code directory. After you have 124 | installed the package for one architecture, use `make distclean' before 125 | reconfiguring for another architecture. 126 | 127 | On MacOS X 10.5 and later systems, you can create libraries and 128 | executables that work on multiple system types--known as "fat" or 129 | "universal" binaries--by specifying multiple `-arch' options to the 130 | compiler but only a single `-arch' option to the preprocessor. Like 131 | this: 132 | 133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 135 | CPP="gcc -E" CXXCPP="g++ -E" 136 | 137 | This is not guaranteed to produce working output in all cases, you 138 | may have to build one architecture at a time and combine the results 139 | using the `lipo' tool if you have problems. 140 | 141 | Installation Names 142 | ================== 143 | 144 | By default, `make install' installs the package's commands under 145 | `/usr/local/bin', include files under `/usr/local/include', etc. You 146 | can specify an installation prefix other than `/usr/local' by giving 147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an 148 | absolute file name. 149 | 150 | You can specify separate installation prefixes for 151 | architecture-specific files and architecture-independent files. If you 152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 153 | PREFIX as the prefix for installing programs and libraries. 154 | Documentation and other data files still use the regular prefix. 155 | 156 | In addition, if you use an unusual directory layout you can give 157 | options like `--bindir=DIR' to specify different values for particular 158 | kinds of files. Run `configure --help' for a list of the directories 159 | you can set and what kinds of files go in them. In general, the 160 | default for these options is expressed in terms of `${prefix}', so that 161 | specifying just `--prefix' will affect all of the other directory 162 | specifications that were not explicitly provided. 163 | 164 | The most portable way to affect installation locations is to pass the 165 | correct locations to `configure'; however, many packages provide one or 166 | both of the following shortcuts of passing variable assignments to the 167 | `make install' command line to change installation locations without 168 | having to reconfigure or recompile. 169 | 170 | The first method involves providing an override variable for each 171 | affected directory. For example, `make install 172 | prefix=/alternate/directory' will choose an alternate location for all 173 | directory configuration variables that were expressed in terms of 174 | `${prefix}'. Any directories that were specified during `configure', 175 | but not in terms of `${prefix}', must each be overridden at install 176 | time for the entire installation to be relocated. The approach of 177 | makefile variable overrides for each directory variable is required by 178 | the GNU Coding Standards, and ideally causes no recompilation. 179 | However, some platforms have known limitations with the semantics of 180 | shared libraries that end up requiring recompilation when using this 181 | method, particularly noticeable in packages that use GNU Libtool. 182 | 183 | The second method involves providing the `DESTDIR' variable. For 184 | example, `make install DESTDIR=/alternate/directory' will prepend 185 | `/alternate/directory' before all installation names. The approach of 186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and 187 | does not work on platforms that have drive letters. On the other hand, 188 | it does better at avoiding recompilation issues, and works well even 189 | when some directory options were not specified in terms of `${prefix}' 190 | at `configure' time. 191 | 192 | Optional Features 193 | ================= 194 | 195 | If the package supports it, you can cause programs to be installed 196 | with an extra prefix or suffix on their names by giving `configure' the 197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 198 | 199 | Some packages pay attention to `--enable-FEATURE' options to 200 | `configure', where FEATURE indicates an optional part of the package. 201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 202 | is something like `gnu-as' or `x' (for the X Window System). The 203 | `README' should mention any `--enable-' and `--with-' options that the 204 | package recognizes. 205 | 206 | For packages that use the X Window System, `configure' can usually 207 | find the X include and library files automatically, but if it doesn't, 208 | you can use the `configure' options `--x-includes=DIR' and 209 | `--x-libraries=DIR' to specify their locations. 210 | 211 | Some packages offer the ability to configure how verbose the 212 | execution of `make' will be. For these packages, running `./configure 213 | --enable-silent-rules' sets the default to minimal output, which can be 214 | overridden with `make V=1'; while running `./configure 215 | --disable-silent-rules' sets the default to verbose, which can be 216 | overridden with `make V=0'. 217 | 218 | Particular systems 219 | ================== 220 | 221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU 222 | CC is not installed, it is recommended to use the following options in 223 | order to use an ANSI C compiler: 224 | 225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 226 | 227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 228 | 229 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 230 | parse its `' header file. The option `-nodtk' can be used as 231 | a workaround. If GNU CC is not installed, it is therefore recommended 232 | to try 233 | 234 | ./configure CC="cc" 235 | 236 | and if that doesn't work, try 237 | 238 | ./configure CC="cc -nodtk" 239 | 240 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This 241 | directory contains several dysfunctional programs; working variants of 242 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' 243 | in your `PATH', put it _after_ `/usr/bin'. 244 | 245 | On Haiku, software installed for all users goes in `/boot/common', 246 | not `/usr/local'. It is recommended to use the following options: 247 | 248 | ./configure --prefix=/boot/common 249 | 250 | Specifying the System Type 251 | ========================== 252 | 253 | There may be some features `configure' cannot figure out 254 | automatically, but needs to determine by the type of machine the package 255 | will run on. Usually, assuming the package is built to be run on the 256 | _same_ architectures, `configure' can figure that out, but if it prints 257 | a message saying it cannot guess the machine type, give it the 258 | `--build=TYPE' option. TYPE can either be a short name for the system 259 | type, such as `sun4', or a canonical name which has the form: 260 | 261 | CPU-COMPANY-SYSTEM 262 | 263 | where SYSTEM can have one of these forms: 264 | 265 | OS 266 | KERNEL-OS 267 | 268 | See the file `config.sub' for the possible values of each field. If 269 | `config.sub' isn't included in this package, then this package doesn't 270 | need to know the machine type. 271 | 272 | If you are _building_ compiler tools for cross-compiling, you should 273 | use the option `--target=TYPE' to select the type of system they will 274 | produce code for. 275 | 276 | If you want to _use_ a cross compiler, that generates code for a 277 | platform different from the build platform, you should specify the 278 | "host" platform (i.e., that on which the generated programs will 279 | eventually be run) with `--host=TYPE'. 280 | 281 | Sharing Defaults 282 | ================ 283 | 284 | If you want to set default values for `configure' scripts to share, 285 | you can create a site shell script called `config.site' that gives 286 | default values for variables like `CC', `cache_file', and `prefix'. 287 | `configure' looks for `PREFIX/share/config.site' if it exists, then 288 | `PREFIX/etc/config.site' if it exists. Or, you can set the 289 | `CONFIG_SITE' environment variable to the location of the site script. 290 | A warning: not all `configure' scripts look for a site script. 291 | 292 | Defining Variables 293 | ================== 294 | 295 | Variables not defined in a site shell script can be set in the 296 | environment passed to `configure'. However, some packages may run 297 | configure again during the build, and the customized values of these 298 | variables may be lost. In order to avoid this problem, you should set 299 | them in the `configure' command line, using `VAR=value'. For example: 300 | 301 | ./configure CC=/usr/local2/bin/gcc 302 | 303 | causes the specified `gcc' to be used as the C compiler (unless it is 304 | overridden in the site shell script). 305 | 306 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 307 | an Autoconf bug. Until the bug is fixed you can use this workaround: 308 | 309 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 310 | 311 | `configure' Invocation 312 | ====================== 313 | 314 | `configure' recognizes the following options to control how it 315 | operates. 316 | 317 | `--help' 318 | `-h' 319 | Print a summary of all of the options to `configure', and exit. 320 | 321 | `--help=short' 322 | `--help=recursive' 323 | Print a summary of the options unique to this package's 324 | `configure', and exit. The `short' variant lists options used 325 | only in the top level, while the `recursive' variant lists options 326 | also present in any nested packages. 327 | 328 | `--version' 329 | `-V' 330 | Print the version of Autoconf used to generate the `configure' 331 | script, and exit. 332 | 333 | `--cache-file=FILE' 334 | Enable the cache: use and save the results of the tests in FILE, 335 | traditionally `config.cache'. FILE defaults to `/dev/null' to 336 | disable caching. 337 | 338 | `--config-cache' 339 | `-C' 340 | Alias for `--cache-file=config.cache'. 341 | 342 | `--quiet' 343 | `--silent' 344 | `-q' 345 | Do not print messages saying which checks are being made. To 346 | suppress all normal output, redirect it to `/dev/null' (any error 347 | messages will still be shown). 348 | 349 | `--srcdir=DIR' 350 | Look for the package's source code in directory DIR. Usually 351 | `configure' can determine that directory automatically. 352 | 353 | `--prefix=DIR' 354 | Use DIR as the installation prefix. *note Installation Names:: 355 | for more details, including other options available for fine-tuning 356 | the installation locations. 357 | 358 | `--no-create' 359 | `-n' 360 | Run the configure checks, but stop before creating any output 361 | files. 362 | 363 | `configure' also accepts some other, not widely useful, options. Run 364 | `configure --help' for more details. 365 | 366 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2009 Red Hat Inc. 3 | # All Rights Reserved. 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; see the file COPYING. If not, write to the 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | # Boston, MA 02110-1335, USA. 19 | # 20 | # Authors: 21 | # Steve Grubb 22 | # 23 | ACLOCAL_AMFLAGS = -I m4 24 | SUBDIRS = src utils m4 docs 25 | if HAVE_SWIG 26 | SUBDIRS += bindings 27 | endif 28 | EXTRA_DIST = ChangeLog AUTHORS README.md INSTALL COPYING COPYING.LIB \ 29 | libcap-ng.spec autogen.sh 30 | 31 | CONFIG_CLEAN_FILES = debug*.list 32 | clean-generic: 33 | rm -rf autom4te*.cache 34 | rm -f *.rej *.orig *.lang 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libcap-ng 2 | ========= 3 | 4 | The libcap-ng library should make programming with POSIX capabilities 5 | easier. The library has some utilities to help you analyse a system 6 | for apps that may have too much privileges. 7 | 8 | The included utilities are designed to let admins and developers spot apps from various ways that may be running with too much privilege. For example, any investigation should start with network facing apps since they would be prime targets for intrusion. The netcap program will check all running apps that have listening socket and display the results. Sample output from netcap: 9 | 10 | ``` 11 | ppid pid acct command type port capabilities 12 | 1 2295 root nasd tcp 8000 full 13 | 2323 2383 root dnsmasq tcp 53 net_admin, net_raw + 14 | 1 2286 root sshd tcp 22 full 15 | 1 2365 root cupsd tcp 631 full 16 | 1 2286 root sshd tcp6 22 full 17 | 1 2365 root cupsd tcp6 631 full 18 | 2323 2383 root dnsmasq udp 53 net_admin, net_raw + 19 | 2323 2383 root dnsmasq udp 67 net_admin, net_raw + 20 | 1 2365 root cupsd udp 631 full 21 | ``` 22 | After checking the networking apps, you should check all running apps with 23 | pscap. If you are a developer and have to give your application 24 | CAP_DAC_OVERRIDE, you must be accessing files for which you have no permission 25 | to access. This typically can be resolved by having membership in the correct 26 | groups. Try to avoid needing CAP_DAC_OVERRIDE...you may as well be root if you 27 | need it. 28 | 29 | Some application developers have chosen to use file system base capabilities 30 | rather than be setuid root and have to drop capabilities. Libcap-ng provides 31 | filecap to recursively search directories and show you which ones have 32 | capabilities and exactly what those are. 33 | 34 | C Examples 35 | ---------- 36 | As an application developer, there are probably 6 use cases that you are 37 | interested in: drop all capabilities, keep one capability, keep several 38 | capabilities, check if you have any capabilities at all, check for certain 39 | capabilities, and retain capabilities across a uid change. 40 | 41 | 1) Drop all capabilities 42 | ```c 43 | capng_clear(CAPNG_SELECT_BOTH); 44 | capng_apply(CAPNG_SELECT_BOTH); 45 | ``` 46 | 47 | 2) Keep one capability 48 | ```c 49 | capng_clear(CAPNG_SELECT_BOTH); 50 | capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_CHOWN); 51 | capng_apply(CAPNG_SELECT_BOTH); 52 | ``` 53 | 54 | 3) Keep several capabilities 55 | ```c 56 | capng_clear(CAPNG_SELECT_BOTH); 57 | capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_SETUID, CAP_SETGID, -1); 58 | capng_apply(CAPNG_SELECT_BOTH); 59 | ``` 60 | 61 | 4) Check if you have any capabilities 62 | ```c 63 | if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE) 64 | do_something(); 65 | ``` 66 | 67 | 5) Check for a specific capability 68 | ```c 69 | if (capng_have_capability(CAPNG_EFFECTIVE, CAP_CHOWN)) 70 | do_something(); 71 | ``` 72 | 73 | 6) Retain capabilities across a uid change 74 | ```c 75 | capng_clear(CAPNG_SELECT_BOTH); 76 | capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_CHOWN); 77 | if (capng_change_id(99, 99, CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING)) 78 | error(); 79 | ``` 80 | 81 | Now, isn't that a lot simpler? Note that the last example takes about 60 lines 82 | of code using the older capabilities library. As of the 0.6 release, there is 83 | a m4 macro file to help adding libcap-ng to your autotools config system. In 84 | configure.ac, add LIBCAP_NG_PATH. Then in Makefile.am locate the apps that 85 | link to libcap-ng, add $(CAPNG_LDADD) to their LDADD entries. And lastly, 86 | surround the optional capabilities code with #ifdef HAVE_LIBCAP_NG. 87 | 88 | Python 89 | ------ 90 | Libcap-ng 0.6 and later has python bindings. (Only python3 is supported from 0.8.4 onward.) You simply add 'import capng' in your script. Here are the same examples as above in python: 91 | 92 | 1) Drop all capabilities 93 | ```python 94 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 95 | capng.capng_apply(capng.CAPNG_SELECT_BOTH) 96 | ``` 97 | 98 | 2) Keep one capability 99 | ```python 100 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 101 | capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_CHOWN) 102 | capng.capng_apply(capng.CAPNG_SELECT_BOTH) 103 | ``` 104 | 105 | 3) Keep several capabilities 106 | ```python 107 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 108 | capng.capng_updatev(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_SETUID, capng.CAP_SETGID, -1) 109 | capng.capng_apply(capng.CAPNG_SELECT_BOTH) 110 | ``` 111 | 112 | 4) Check if you have any capabilities 113 | ```python 114 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS) > capng.CAPNG_NONE: 115 | do_something() 116 | ``` 117 | 118 | 5) Check for a specific capability 119 | ```python 120 | if capng.capng_have_capability(capng.CAPNG_EFFECTIVE, capng.CAP_CHOWN): 121 | do_something() 122 | ``` 123 | 124 | 6) Retain capabilities across a uid change 125 | ```python 126 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 127 | capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED, capng.CAP_CHOWN) 128 | if capng.capng_change_id(99, 99, capng.CAPNG_DROP_SUPP_GRP | capng.CAPNG_CLEAR_BOUNDING) < 0: 129 | error() 130 | ``` 131 | 132 | The one caveat is that printing capabilities from python does not work. But 133 | you can still manipulate capabilities, though. 134 | 135 | Ambient Capabilities 136 | -------------------- 137 | Ambient capabilities arrived in the 4.3 Linux kernel. Ambient capabilities 138 | allow a privileged process to bestow capabilities to a child process. This 139 | is how systemd grants capabilities to a daemon running in a service account. 140 | The problem with ambient capabilities is they are inherited forever. Every 141 | process exec'ed from the original service also has the capabilities. This is 142 | a security issue. 143 | 144 | To find and fix this, you can run the pscap program and grep for '@'. The '@' 145 | symbol denotes processes that have ambient capabilities. For example: 146 | 147 | ``` 148 | # pscap | grep @ 149 | 1 1655 systemd-oom systemd-oomd dac_override, kill @ + 150 | 1 1656 systemd-resolve systemd-resolve net_raw @ + 151 | 152 | ``` 153 | 154 | To fix this, libcap-ng 0.8.3 and later ships libdrop_ambient.so.0. It is 155 | designed to be used with LD_PRELOAD. It has a constructor function that forces 156 | the dropping of ambient capabilities. By the time the application starts, it 157 | has both effective and ambient capabilities - meaning is safe to drop ambient 158 | capabilities very early. You can either link it to an application run as a 159 | systemd service (using ld), or create a wrapper script that then starts the 160 | daemon. 161 | 162 | Building 163 | -------- 164 | 165 | After cloning libcap-ng, run: 166 | 167 | ``` 168 | cd libcap-ng 169 | ./autogen.sh 170 | ./configure 171 | make 172 | make install 173 | ``` 174 | 175 | If you want python bindings, add that option to the configure command. There is also a spec file to use if you are on a rpm based distribution. To do that, run "make dist" instead of make in the above instructions. Then use the resulting tar file with the spec file. 176 | 177 | NOTE: to distributions 178 | ---------------------- 179 | There is a "make check" target. It only works if the available kernel headers 180 | roughly match the build root kernel. Iow, if you have a chroot build system 181 | that is using a much older kernel, the macros in the kernel header files will 182 | describe functionality that does not exist in the build root. The capng_init 183 | function will probe the kernel and decide we can only do v1 rather than v3 184 | capabilities instead of what the kernel headers said was possible. If that is 185 | your case, just don't do the "make check" as part of the build process. This 186 | problem should go away as build roots eventually switch to the 5.0 or later 187 | kernels. 188 | 189 | Reporting 190 | --------- 191 | Report any bugs in this package to: 192 | https://github.com/stevegrubb/libcap-ng/issue 193 | 194 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | set -x -e 3 | # --no-recursive is available only in recent autoconf versions 4 | touch NEWS 5 | autoreconf -fv --install 6 | -------------------------------------------------------------------------------- /bindings/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2009,2015 Red Hat Inc. 3 | # All Rights Reserved. 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program; see the file COPYING. If not, write to the 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | # Boston, MA 02110-1335, USA. 19 | # 20 | # Authors: 21 | # Steve Grubb 22 | # 23 | 24 | CONFIG_CLEAN_FILES = *.loT *.rej *.orig 25 | SUBDIRS = src 26 | 27 | if USE_PYTHON3 28 | SUBDIRS += python3 test 29 | endif 30 | 31 | -------------------------------------------------------------------------------- /bindings/python3/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2009,2014-17 Red Hat Inc. 3 | # All Rights Reserved. 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program; see the file COPYING. If not, write to the 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | # Boston, MA 02110-1335, USA. 19 | # 20 | # Authors: 21 | # Steve Grubb 22 | # 23 | SUBDIRS = test 24 | CONFIG_CLEAN_FILES = *.loT *.rej *.orig 25 | AM_CFLAGS = -fPIC -DPIC $(PYTHON3_CFLAGS) 26 | AM_CPPFLAGS = -I. -I$(top_builddir) $(PYTHON3_INCLUDES) 27 | LIBS = ${top_builddir}/src/libcap-ng.la 28 | SWIG_FLAGS = -python 29 | SWIG_INCLUDES = ${AM_CPPFLAGS} 30 | pyexec_PYTHON = capng.py 31 | pyexec_LTLIBRARIES = _capng.la 32 | _capng_la_CFLAGS = -shared 33 | _capng_la_LDFLAGS = -module -avoid-version -Wl,-z,relro 34 | _capng_la_HEADERS: $(top_builddir)/config.h 35 | _capng_la_DEPENDENCIES =${top_srcdir}/src/cap-ng.h ${top_builddir}/src/libcap-ng.la 36 | _capng_la_LIBADD = ${top_builddir}/src/libcap-ng.la 37 | nodist__capng_la_SOURCES = capng_wrap.c 38 | 39 | capng.py capng_wrap.c: ${srcdir}/../src/capng_swig.i caps.h capng.h 40 | swig -o capng_wrap.c ${SWIG_FLAGS} ${SWIG_INCLUDES} ${srcdir}/../src/capng_swig.i 41 | caps.h: 42 | cat $(CAPABILITY_HEADER) | grep '^#define CAP' | grep -v '[()]' > caps.h 43 | capng.h: 44 | cat ${top_srcdir}/src/cap-ng.h | grep -v '_state' > capng.h 45 | 46 | CLEANFILES = capng.py* capng_wrap.c caps.h capng.h *~ 47 | clean-local: 48 | $(RM) -rf __pycache__ 49 | -------------------------------------------------------------------------------- /bindings/python3/test/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2023 Red Hat Inc. 3 | # All Rights Reserved. 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program; see the file COPYING. If not, write to the 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | # Boston, MA 02110-1335, USA. 19 | # 20 | # Authors: 21 | # Steve Grubb 22 | # 23 | 24 | dist_check_SCRIPTS = capng-test.py 25 | TESTS = $(dist_check_SCRIPTS) 26 | TESTS_ENVIRONMENT = PYTHONPATH=${top_builddir}/bindings/python3/:${top_builddir}/bindings/python3/.libs 27 | 28 | -------------------------------------------------------------------------------- /bindings/python3/test/capng-test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import time 6 | load_path = '../' 7 | if False: 8 | sys.path.insert(0, load_path) 9 | 10 | import capng 11 | 12 | last = capng.CAP_LAST_CAP 13 | try: 14 | with open('/proc/sys/kernel/cap_last_cap', 'r') as f: 15 | last = int(f.readline()) 16 | except IOError as e: 17 | print("Error opening /proc/sys/kernel/cap_last_cap: {0}".format(e.strerror)) 18 | 19 | print("Doing basic bit tests...") 20 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 21 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_BOTH) != capng.CAPNG_NONE: 22 | print("Failed clearing capabilities\n") 23 | sys.exit(1) 24 | 25 | capng.capng_fill(capng.CAPNG_SELECT_BOTH) 26 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_BOTH) != capng.CAPNG_FULL: 27 | print("Failed filling capabilities") 28 | sys.exit(1) 29 | 30 | text = capng.capng_print_caps_numeric(capng.CAPNG_PRINT_BUFFER, capng.CAPNG_SELECT_CAPS) 31 | len = len(text) 32 | if len < 80 and last > 30: 33 | last = 30 34 | 35 | print("Doing advanced bit tests for %d capabilities...\n" % (last)) 36 | for i in range(last+1): 37 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 38 | rc = capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE, i) 39 | if rc: 40 | print("Failed update test 1") 41 | sys.exit(1) 42 | 43 | rc = capng.capng_have_capability(capng.CAPNG_EFFECTIVE, int(i)) 44 | if rc <= capng.CAPNG_NONE: 45 | print("Failed have capability test 1") 46 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, capng.CAPNG_SELECT_CAPS) 47 | sys.exit(1) 48 | 49 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS) != capng.CAPNG_PARTIAL: 50 | print("Failed have capabilities test 1") 51 | sys.exit(1) 52 | 53 | capng.capng_fill(capng.CAPNG_SELECT_BOTH) 54 | rc = capng.capng_update(capng.CAPNG_DROP, capng.CAPNG_EFFECTIVE, i) 55 | if rc: 56 | print("Failed update test 3") 57 | sys.exit(1) 58 | 59 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS)!=capng.CAPNG_PARTIAL: 60 | print("Failed have capabilities test 3") 61 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, capng.CAPNG_SELECT_CAPS) 62 | sys.exit(1) 63 | 64 | rc = capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE, i) 65 | if rc: 66 | print("Failed update test 4") 67 | sys.exit(1) 68 | 69 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS) != capng.CAPNG_FULL: 70 | print("Failed have capabilities test 4") 71 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, capng.CAPNG_SELECT_CAPS) 72 | sys.exit(1) 73 | 74 | sys.exit(0) 75 | -------------------------------------------------------------------------------- /bindings/src/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2015 Red Hat Inc., Durham, North Carolina. 3 | # All Rights Reserved. 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | # 19 | # Authors: 20 | # Steve Grubb 21 | # 22 | 23 | EXTRA_DIST = capng_swig.i 24 | SWIG_SOURCES = capng_swig.i 25 | CONFIG_CLEAN_FILES = *.loT *.rej *.orig 26 | -------------------------------------------------------------------------------- /bindings/src/capng_swig.i: -------------------------------------------------------------------------------- 1 | /* capngswig.i -- 2 | * Copyright 2009 Red Hat Inc. 3 | * All Rights Reserved. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; see the file COPYING. If not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | * Boston, MA 02110-1335, USA. 19 | * 20 | * Authors: 21 | * Steve Grubb 22 | */ 23 | 24 | %module capng 25 | %{ 26 | #include "./capng.h" 27 | %} 28 | 29 | #if defined(SWIGPYTHON) 30 | 31 | %varargs(16, signed capability = 0) capng_updatev; 32 | 33 | #endif 34 | 35 | %define __signed__ 36 | signed 37 | %enddef 38 | #define __attribute(X) /*nothing*/ 39 | typedef unsigned __u32; 40 | #define __extension__ /*nothing*/ 41 | %include "./caps.h" 42 | %include "./capng.h" 43 | 44 | -------------------------------------------------------------------------------- /bindings/test/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- Test suite for python bindings 2 | 3 | TESTS = lib_test.py 4 | TESTS_ENVIRONMENT = PYTHONPATH=${top_builddir}/bindings/python3/:${top_builddir}/bindings/python3/.libs 5 | 6 | dist_check_SCRIPTS = $(TESTS) 7 | -------------------------------------------------------------------------------- /bindings/test/lib_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import capng 5 | 6 | 7 | def get_last_cap(): 8 | last = capng.CAP_LAST_CAP 9 | try: 10 | with open('/proc/sys/kernel/cap_last_cap', 'r') as f: 11 | last = int(f.readline()) 12 | except OSError: 13 | pass 14 | return last 15 | 16 | 17 | def main(): 18 | last = get_last_cap() 19 | 20 | print("Doing basic bit tests...") 21 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 22 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_BOTH) != capng.CAPNG_NONE: 23 | print("Failed clearing capabilities") 24 | sys.exit(1) 25 | 26 | # capng_save_state/capng_restore_state are not available in python bindings 27 | capng.capng_fill(capng.CAPNG_SELECT_BOTH) 28 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_BOTH) != capng.CAPNG_FULL: 29 | print("Failed filling capabilities") 30 | sys.exit(1) 31 | 32 | text = capng.capng_print_caps_numeric(capng.CAPNG_PRINT_BUFFER, 33 | capng.CAPNG_SELECT_CAPS) 34 | if len(text) < 80 and last > 30: 35 | last = 30 36 | 37 | print("Doing advanced bit tests for %d capabilities..." % last) 38 | for i in range(last + 1): 39 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 40 | rc = capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE, i) 41 | if rc: 42 | print("Failed update test 1") 43 | sys.exit(1) 44 | rc = capng.capng_have_capability(capng.CAPNG_EFFECTIVE, i) 45 | if rc <= capng.CAPNG_NONE: 46 | print("Failed have capability test 1") 47 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, 48 | capng.CAPNG_SELECT_CAPS) 49 | sys.exit(1) 50 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS) != capng.CAPNG_PARTIAL: 51 | print("Failed have capabilities test 1") 52 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, 53 | capng.CAPNG_SELECT_CAPS) 54 | sys.exit(1) 55 | if capng.CAP_LAST_CAP > 31: 56 | rc = capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_BOUNDING_SET, i) 57 | if rc: 58 | print("Failed bset update test 2") 59 | sys.exit(1) 60 | rc = capng.capng_have_capability(capng.CAPNG_BOUNDING_SET, i) 61 | if rc <= capng.CAPNG_NONE: 62 | print("Failed bset have capability test 2") 63 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, 64 | capng.CAPNG_SELECT_BOTH) 65 | sys.exit(1) 66 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_BOUNDS) != capng.CAPNG_PARTIAL: 67 | print("Failed bset have capabilities test 2") 68 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, 69 | capng.CAPNG_SELECT_BOTH) 70 | sys.exit(1) 71 | text = capng.capng_print_caps_text(capng.CAPNG_PRINT_BUFFER, 72 | capng.CAPNG_EFFECTIVE) 73 | name = capng.capng_capability_to_name(i) 74 | if text != name: 75 | print("Failed print text comparison") 76 | print("%s != %s" % (text, name)) 77 | sys.exit(1) 78 | capng.capng_fill(capng.CAPNG_SELECT_BOTH) 79 | rc = capng.capng_update(capng.CAPNG_DROP, capng.CAPNG_EFFECTIVE, i) 80 | if rc: 81 | print("Failed update test 3") 82 | sys.exit(1) 83 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS) != capng.CAPNG_PARTIAL: 84 | print("Failed have capabilities test 3") 85 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, 86 | capng.CAPNG_SELECT_CAPS) 87 | sys.exit(1) 88 | rc = capng.capng_update(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE, i) 89 | if rc: 90 | print("Failed update test 4") 91 | sys.exit(1) 92 | if capng.capng_have_capabilities(capng.CAPNG_SELECT_CAPS) != capng.CAPNG_FULL: 93 | print("Failed have capabilities test 4") 94 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, 95 | capng.CAPNG_SELECT_CAPS) 96 | sys.exit(1) 97 | 98 | capng.capng_clear(capng.CAPNG_SELECT_BOTH) 99 | rc = capng.capng_updatev(capng.CAPNG_ADD, capng.CAPNG_EFFECTIVE, 100 | capng.CAP_CHOWN, capng.CAP_FOWNER, capng.CAP_KILL, -1) 101 | if rc: 102 | print("Failed updatev test") 103 | sys.exit(1) 104 | rc = (capng.capng_have_capability(capng.CAPNG_EFFECTIVE, capng.CAP_CHOWN) and 105 | capng.capng_have_capability(capng.CAPNG_EFFECTIVE, capng.CAP_FOWNER) and 106 | capng.capng_have_capability(capng.CAPNG_EFFECTIVE, capng.CAP_KILL)) 107 | if not rc: 108 | print("Failed have updatev capability test") 109 | capng.capng_print_caps_numeric(capng.CAPNG_PRINT_STDOUT, 110 | capng.CAPNG_SELECT_CAPS) 111 | sys.exit(1) 112 | 113 | sys.exit(0) 114 | 115 | 116 | if __name__ == '__main__': 117 | main() 118 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | 2 | dnl 3 | define([AC_INIT_NOTICE], 4 | [### Generated automatically using autoconf version] AC_ACVERSION [ 5 | ### Copyright 2009-2024 Steve Grubb 6 | ### 7 | ### Permission is hereby granted, free of charge, to any person obtaining a 8 | ### copy of this software and associated documentation files (the "Software"), 9 | ### to deal in the Software without restriction, including without limitation 10 | ### the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | ### and/or sell copies of the Software, and to permit persons to whom the 12 | ### Software is furnished to do so, subject to the following conditions: 13 | ### 14 | ### The above copyright notice and this permission notice shall be included 15 | ### in all copies or substantial portions of the Software. 16 | ### 17 | ### THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | ### IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | ### FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | ### THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | ### OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ### ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | ### OTHER DEALINGS IN THE SOFTWARE. 24 | ### 25 | ### For usage, run `./configure --help' 26 | ### For more detailed information on installation, read the file `INSTALL'. 27 | ### 28 | ### If configuration succeeds, status is in the file `config.status'. 29 | ### A log of configuration tests is in `config.log'. 30 | ]) 31 | 32 | AC_REVISION($Revision: 1.3 $)dnl 33 | AC_INIT([libcap-ng],[0.8.6]) 34 | AC_PREREQ([2.50])dnl 35 | AC_CONFIG_HEADERS([config.h]) 36 | AC_CONFIG_MACRO_DIR([m4]) 37 | 38 | echo Configuring libcap-ng $VERSION 39 | 40 | AC_CANONICAL_TARGET 41 | AM_INIT_AUTOMAKE 42 | LT_INIT 43 | AC_SUBST(LIBTOOL_DEPS) 44 | 45 | echo . 46 | echo Checking for programs 47 | 48 | AC_PROG_CC 49 | AC_PROG_INSTALL 50 | AC_PROG_AWK 51 | 52 | echo . 53 | echo Checking for header files 54 | AC_CHECK_HEADERS(linux/capability.h, [], [AC_MSG_ERROR(linux/capability.h is required in order to build libcap-ng.)]) 55 | AC_CHECK_HEADERS(sys/xattr.h, [], [ 56 | AC_CHECK_HEADERS(attr/xattr.h, [], [AC_MSG_WARN(attr/xattr.h not found, disabling file system capabilities.)]) 57 | ]) 58 | AC_CHECK_HEADERS(linux/securebits.h, [], []) 59 | AC_CHECK_HEADERS(pthread.h, 60 | [AC_SEARCH_LIBS(pthread_atfork, pthread)], 61 | [AC_MSG_WARN(pthread.h not found, disabling pthread_atfork.)]) 62 | AC_CHECK_HEADERS(sys/vfs.h, [ 63 | AC_CHECK_HEADERS(linux/magic.h, [], [AC_MSG_WARN(linux/magic.h is required in order to verify procfs.)]) 64 | ], [AC_MSG_WARN(sys/vfs.h is required in order to verify procfs.)]) 65 | 66 | AC_ARG_WITH([capability_header], 67 | [AS_HELP_STRING([--with-capability_header=path : path to capability.h])], 68 | [CAPABILITY_HEADER=$withval], 69 | [CAPABILITY_HEADER=/usr/include/linux/capability.h]) 70 | AC_SUBST(CAPABILITY_HEADER) 71 | 72 | ALLWARNS="" 73 | ALLDEBUG="-g" 74 | OPT="-O" 75 | if test x"$GCC" = x"yes"; then 76 | OPT="-O2 -pipe" 77 | case "$target" in 78 | *linux*) 79 | ALLWARNS="-W -Wall -Wundef -Wpointer-arith -Wcast-align \ 80 | -Wwrite-strings -Waggregate-return -Wstrict-prototypes \ 81 | -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls \ 82 | -Wnested-externs -Winline -Wfloat-equal -Wchar-subscripts" 83 | ;; 84 | esac 85 | fi 86 | 87 | ALLDEBUG="-g" 88 | AC_ARG_WITH(debug, 89 | [ --with-debug turn on debugging [[default=no]]], 90 | [ 91 | if test "x${withval}" = xyes; then 92 | DEBUG="$ALLDEBUG" 93 | OPT="-O" 94 | AM_CONDITIONAL(DEBUG, true) 95 | else 96 | DEBUG="-DNDEBUG" 97 | AM_CONDITIONAL(DEBUG, false) 98 | fi 99 | ], 100 | [ DEBUG="-DNDEBUG"; AM_CONDITIONAL(DEBUG, false) ]) 101 | 102 | AC_MSG_CHECKING(__attr_dealloc_free support) 103 | AC_COMPILE_IFELSE( 104 | [AC_LANG_SOURCE( 105 | [[ 106 | #include 107 | extern char *test(const char *name) __attr_dealloc_free; 108 | int main(void) { return 0; }]])], 109 | [DEALLOC="yes"], 110 | [DEALLOC="no"] 111 | ) 112 | AC_MSG_RESULT($DEALLOC) 113 | 114 | AC_ARG_WITH(warn, 115 | [ --with-warn turn on warnings [[default=yes]]], 116 | [ 117 | if test "x${withval}" = xyes; then 118 | WARNS="$ALLWARNS" 119 | else 120 | WARNS="" 121 | fi 122 | ],WARNS="$ALLWARNS") 123 | AC_SUBST(DEBUG) 124 | 125 | WFLAGS="" 126 | AC_MSG_CHECKING(for -Wformat-truncation) 127 | TMPCFLAGS="${CFLAGS}" 128 | CFLAGS="${CFLAGS} -Wformat-truncation" 129 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[WFLAGS="-Wno-format-truncation" 130 | AC_MSG_RESULT(yes)], 131 | [AC_MSG_RESULT(no)]) 132 | CFLAGS="${TMPCFLAGS}" 133 | AC_SUBST(WFLAGS) 134 | 135 | AC_CHECK_HEADER(sys/syscall.h, 136 | [AC_DEFINE([HAVE_SYSCALL_H], [1], 137 | [Define to 1 if you have .])], [],) 138 | 139 | dnl; This is to record in the build logs what options are being taken 140 | AC_CHECK_DECLS([PR_CAP_AMBIENT], [], [], [[#include ]]) 141 | AC_CHECK_DECLS([VFS_CAP_REVISION_2], [], [], [[#include ]]) 142 | AC_CHECK_DECLS([VFS_CAP_REVISION_3], [], [], [[#include ]]) 143 | AC_CHECK_DECLS([CAP_EPOLLWAKEUP], [], [], [[#include ]]) 144 | AC_CHECK_DECLS([CAP_WAKE_ALARM], [], [], [[#include ]]) 145 | AC_CHECK_DECLS([CAP_BLOCK_SUSPEND], [], [], [[#include ]]) 146 | AC_CHECK_DECLS([CAP_AUDIT_READ], [], [], [[#include ]]) 147 | AC_CHECK_DECLS([CAP_PERFMON], [], [], [[#include ]]) 148 | AC_CHECK_DECLS([CAP_BPF], [], [], [[#include ]]) 149 | AC_CHECK_DECLS([CAP_CHECKPOINT_RESTORE], [], [], [[#include ]]) 150 | 151 | dnl only build libdrop_ambient if support for ambient capabilities was found (which is normal) 152 | if test x"${ac_cv_have_decl_PR_CAP_AMBIENT}" = x"no" ; then 153 | AC_MSG_WARN("PR_CAP_AMBIENT not available - libdrop_ambient will not be built") 154 | fi 155 | AM_CONDITIONAL(BUILD_LIBDROP_AMBIENT, test x"${ac_cv_have_decl_PR_CAP_AMBIENT}" = x"yes") 156 | 157 | AC_CHECK_PROG(swig_found, swig, yes, no) 158 | if test x"${swig_found}" = x"no" ; then 159 | AC_MSG_WARN("Swig not found - python bindings will not be made") 160 | fi 161 | AM_CONDITIONAL(HAVE_SWIG, test x"${swig_found}" = x"yes") 162 | 163 | withval="" 164 | AC_MSG_CHECKING(whether to create python3 bindings) 165 | AC_ARG_WITH(python3, 166 | AS_HELP_STRING([--with-python3],[enable building python3 bindings]), 167 | use_python3=$withval, 168 | use_python3=auto) 169 | if test x$use_python3 = xno ; then 170 | AC_MSG_RESULT(no) 171 | else 172 | AC_MSG_RESULT(investigating) 173 | AC_PATH_PROG([use_python3], [python3-config], [no]) 174 | if test ${use_python3} = no ; then 175 | if test ${withval} = yes ; then 176 | echo "Python3 bindings were selected but python3-config was not found." 177 | echo "Please ensure that it's installed or pass --without-python3 to ./configure" 178 | exit 1 179 | fi 180 | echo "Python3 bindings will NOT be built" 181 | else 182 | echo "Python3 bindings WILL be built" 183 | use_python3=yes 184 | AM_PATH_PYTHON([3.1],, [:]) 185 | PYTHON3_CFLAGS=`python3-config --cflags 2> /dev/null` 186 | PYTHON3_LIBS=`python3-config --libs 2> /dev/null` 187 | PYTHON3_INCLUDES=`python3-config --includes 2> /dev/null` 188 | AC_SUBST(PYTHON3_CFLAGS) 189 | AC_SUBST(PYTHON3_LIBS) 190 | AC_SUBST(PYTHON3_INCLUDES) 191 | fi 192 | fi 193 | AM_CONDITIONAL(USE_PYTHON3, test ${use_python3} = "yes") 194 | 195 | AC_CONFIG_FILES([Makefile src/Makefile src/libcap-ng.pc src/test/Makefile 196 | bindings/Makefile 197 | bindings/python3/Makefile bindings/src/Makefile 198 | bindings/python3/test/Makefile bindings/test/Makefile utils/Makefile 199 | m4/Makefile docs/Makefile]) 200 | AC_OUTPUT 201 | 202 | echo . 203 | echo " 204 | 205 | libcap-ng Version: $VERSION 206 | Target: $target 207 | Installation prefix: $prefix 208 | Compiler: $CC 209 | Compiler flags: 210 | `echo $CFLAGS | fmt -w 50 | sed 's,^, ,'` 211 | __attr_dealloc_free support: $DEALLOC 212 | " 213 | -------------------------------------------------------------------------------- /docs/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2009,2020 Red Hat Inc. 3 | # All Rights Reserved. 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | # 19 | # Authors: 20 | # Steve Grubb 21 | # 22 | 23 | CONFIG_CLEAN_FILES = *.rej *.orig 24 | 25 | EXTRA_DIST = $(man_MANS) 26 | 27 | man_MANS = capng_clear.3 capng_fill.3 capng_setpid.3 \ 28 | capng_get_caps_process.3 capng_update.3 capng_updatev.3 \ 29 | capng_apply.3 capng_lock.3 capng_change_id.3 capng_get_caps_fd.3 \ 30 | capng_apply_caps_fd.3 capng_have_capabilities.3 \ 31 | capng_get_rootid.3 capng_set_rootid.3 capng_have_capability.3 \ 32 | capng_print_caps_numeric.3 capng_print_caps_text.3 \ 33 | capng_name_to_capability.3 capng_capability_to_name.3 \ 34 | capng_save_state.3 capng_restore_state.3 libdrop_ambient.7 35 | 36 | -------------------------------------------------------------------------------- /docs/capng_apply.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_APPLY" "3" "Sept 2023" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_apply \- apply the stored capabilities settings 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_apply(capng_select_t set); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_apply will transfer the specified internal POSIX capabilities settings to the kernel. The options are CAPNG_SELECT_CAPS for the traditional capabilities, CAPNG_SELECT_BOUNDS for the bounding set, CAPNG_SELECT_BOTH if transferring both is desired, CAPNG_SELECT_AMBIENT if only operating on the ambient capabilities, or CAPNG_SELECT_ALL if applying all is desired. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | This returns 0 on success and a negative value on failure. The values are: 16 | .RS 17 | .TP 18 | -1 not initialized 19 | .TP 20 | -2 CAPNG_SELECT_BOUNDS and failure to drop a bounding set capability 21 | .TP 22 | -3 CAPNG_SELECT_BOUNDS and failure to re-read bounding set 23 | .TP 24 | -4 CAPNG_SELECT_BOUNDS and process does not have CAP_SETPCAP 25 | .TP 26 | -5 CAPNG_SELECT_CAPS and failure in capset syscall 27 | .TP 28 | -6 CAPNG_SELECT_AMBIENT and process has no capabilities and failed clearing ambient capabilities 29 | .TP 30 | -7 CAPNG_SELECT_AMBIENT and process has capabilities and failed clearing ambient capabilities 31 | .TP 32 | -8 CAPNG_SELECT_AMBIENT and process has capabilities and failed setting an ambient capability 33 | .TP 34 | -9 Unable to acquire process capabilities to check if CAP_SETPCAP is set. 35 | .RE 36 | 37 | .SH NOTES 38 | 39 | If you are doing multi-threaded programming, calling this function will only set capabilities on the calling thread. All other threads are unaffected. If you want to set overall capabilities for a multi-threaded process, you will need to do that before creating any threads. See the capset syscall for more information on this topic. 40 | 41 | Also, bits in the bounding set can only be dropped. You cannot set them. After dropping bounding set capabilities, the bounding set is synchronized with the kernel to reflect the true state in the kernel. 42 | 43 | .SH "SEE ALSO" 44 | 45 | .BR capset (2), 46 | .BR capng_update (3), 47 | .BR capabilities (7) 48 | 49 | .SH AUTHOR 50 | Steve Grubb 51 | -------------------------------------------------------------------------------- /docs/capng_apply_caps_fd.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_APPLY_CAPS_FD" "3" "Sept 2020" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_apply_caps_fd \- write file-based capabilities to extended attributes 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_apply_caps_fd(int fd); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | This function will write the file based capabilities to the extended attributes of the file that the descriptor was opened against. The bounding set is not included in file based capabilities operations. Note that this function will only work if compiled on a kernel that supports file based capabilities such as 2.6.2 12 | 6 and later. 13 | 14 | .SH "RETURN VALUE" 15 | 16 | This returns 0 on success, -1 if something besides a regular file is passed, and -2 if a non-root namespace id is being used for rootid. 17 | 18 | .SH "SEE ALSO" 19 | 20 | .BR capng_get_caps_fd (3), 21 | .BR capabilities (7) 22 | 23 | .SH AUTHOR 24 | Steve Grubb 25 | -------------------------------------------------------------------------------- /docs/capng_capability_to_name.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_CAPABILITY_TO_NAME" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_capability_to_name \- convert capability integer to text 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | const char *capng_capability_to_name(unsigned int capability); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_capability_to_name will take the integer being passed and look it up to see what its text string representation would be. The integer being input must be in the valid range defined in linux/capability.h. The string that is output is the same as the define text from linux/capability.h with the CAP_ prefix removed and lower case. This is useful for taking integer representation and converting it to something more user friendly for display. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | This returns a NULL pointer on failure and the correct string otherwise. 16 | 17 | .SH "SEE ALSO" 18 | 19 | .BR capng_name_to_capability (3), 20 | .BR capabilities (7) 21 | 22 | .SH AUTHOR 23 | Steve Grubb 24 | -------------------------------------------------------------------------------- /docs/capng_change_id.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_CHANGE_ID" "3" "Feb 2018" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_change_id \- change the credentials retaining capabilities 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_change_id(int uid, int gid, capng_flags_t flag); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | This function will change uid and gid to the ones given while retaining the capabilities previously specified in capng_update. It is also possible to specify -1 for either the uid or gid in which case the function will not change the uid or gid and leave it "as is". This is useful if you just want the flag options to be applied (assuming the option doesn't require more privileges that you currently have). 12 | 13 | It is not necessary and perhaps better if capng_apply has not been called prior to this function so that all necessary privileges are still intact. The caller may be required to have CAP_SETPCAP capability still active before calling this function or capabilities cannot be changed. 14 | 15 | This function also takes a flag parameter that helps to tailor the exact actions performed by the function to secure the environment. The option may be or'ed together. The legal values are: 16 | 17 | .RS 18 | .TP 19 | .B CAPNG_NO_FLAG 20 | Simply change uid and retain specified capabilities and that's all. 21 | .TP 22 | .B CAPNG_DROP_SUPP_GRP 23 | After changing id, remove any supplement groups that may still be in effect from the old uid. 24 | .TP 25 | .B CAPNG_INIT_SUPP_GRP 26 | After changing id, initialize any supplement groups that may come with the new account. If given with 27 | .B CAPNG_DROP_SUPP_GRP 28 | it will have no effect. 29 | .TP 30 | .B CAPNG_CLEAR_BOUNDING 31 | Clear the bounding set regardless to the internal representation already setup prior to changing the uid/gid. 32 | .TP 33 | .B CAPNG_CLEAR_AMBIENT 34 | Clear ambient capabilities regardless of the internal representation already setup prior to changing the uid/gid. 35 | 36 | .RE 37 | .SH "RETURN VALUE" 38 | 39 | This returns 0 on success and a negative number on failure. 40 | .RS 41 | .TP 42 | -1 means capng has not been initted properly 43 | .TP 44 | -2 means a failure requesting to keep capabilities across the uid change 45 | .TP 46 | -3 means that applying the intermediate capabilities failed 47 | .TP 48 | -4 means changing gid failed 49 | .TP 50 | -5 means dropping supplemental groups failed 51 | .TP 52 | -6 means changing the uid failed 53 | .TP 54 | -7 means dropping the ability to retain caps across a uid change failed 55 | .TP 56 | -8 means clearing the bounding set failed 57 | .TP 58 | -9 means dropping CAP_SETPCAP or ambient capabilities failed 59 | .TP 60 | -10 means initializing supplemental groups failed 61 | .RE 62 | 63 | Note: the only safe action to do upon failure of this function is to probably exit. This is because you are likely in a situation with partial permissions and not what you intended. 64 | 65 | .SH "SEE ALSO" 66 | 67 | .BR capng_update (3), 68 | .BR capng_apply (3), 69 | .BR prctl (2), 70 | .BR capabilities (7) 71 | 72 | .SH AUTHOR 73 | Steve Grubb 74 | -------------------------------------------------------------------------------- /docs/capng_clear.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_CLEAR" "3" "Sept 2020" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_clear \- clear chosen capabilities set 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | void capng_clear(capng_select_t set); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_clear sets to 0 all bits in the selected POSIX capabilities set. The options are CAPNG_SELECT_CAPS for the traditional capabilities, CAPNG_SELECT_BOUNDS for the bounding set, CAPNG_SELECT_BOTH if clearing both is desired, CAPNG_SELECT_AMBIENT if only operating on the ambient capabilities, or CAPNG_SELECT_ALL if clearing all is desired. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | None. 16 | 17 | .SH "SEE ALSO" 18 | 19 | .BR capabilities (7) 20 | 21 | .SH AUTHOR 22 | Steve Grubb 23 | -------------------------------------------------------------------------------- /docs/capng_fill.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_FILL" "3" "Sept 2020" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_fill \- fill chosen capabilities set 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | void capng_fill(capng_select_t set); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_fill sets all bits to a 1 in the selected POSIX capabilities set. The options are CAPNG_SELECT_CAPS for the traditional capabilities, CAPNG_SELECT_BOUNDS for the bounding set, CAPNG_SELECT_BOTH if filling both is desired, CAPNG_SELECT_AMBIENT if only operating on the ambient capabilities, or CAPNG_SELECT_ALL if clearing all is desired.. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | None. 16 | 17 | .SH NOTES 18 | 19 | During capng_apply, bits in the bounding set can only be dropped. You cannot set them. 20 | 21 | .SH "SEE ALSO" 22 | 23 | .BR capng_apply (3), 24 | .BR capabilities (7) 25 | 26 | .SH AUTHOR 27 | Steve Grubb 28 | -------------------------------------------------------------------------------- /docs/capng_get_caps_fd.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_GET_CAPS_FD" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_get_caps_fd \- read file-based capabilities from extended attributes 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_get_caps_fd(int fd); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | This function will read the file based capabilities stored in extended attributes of the file that the descriptor was opened against. The bounding set is not included in file based capabilities operations. Note that this function will only work if compiled on a kernel that supports file based capabilities such as 2.6.26 and later. If the "magic" bit is set, then all effect capability bits are set. Otherwise the bits are cleared. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | This returns 0 on success and -1 on failure. 16 | 17 | .SH "SEE ALSO" 18 | 19 | .BR capng_set_caps_fd (3), 20 | .BR capabilities (7) 21 | 22 | .SH AUTHOR 23 | Steve Grubb 24 | -------------------------------------------------------------------------------- /docs/capng_get_caps_process.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_GET_CAPS_PROCESS" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_get_caps_process \- get the capabilities from a process 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_get_caps_process(void); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_get_caps_process will get the capabilities and bounding set of the pid stored inside libcap-ng's state table. The default is the pid of the running process. This can be changed by using the capng_setpid function. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | This returns 0 on success and -1 on failure. 16 | 17 | .SH NOTES 18 | 19 | If you are doing multi-threaded programming, calling this function will only get capabilities on the calling thread. If you want to get overall capabilities for a multi-threaded process, you can only do that before creating any threads. Afterwards, threads may be able to independently set capabilities. 20 | 21 | capng_get_caps_process needs a mounted /proc to read the current bounding set, otherwise it will fail. 22 | 23 | .SH "SEE ALSO" 24 | 25 | .BR capng_setpid (3), 26 | .BR capabilities (7) 27 | 28 | .SH AUTHOR 29 | Steve Grubb 30 | -------------------------------------------------------------------------------- /docs/capng_get_rootid.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_GET_ROOTID" "3" "Sept 2020" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_get_rootid \- get namespace root id 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_get_rootid(void); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_get_rootid gets the rootid for capabilities operations. This is only applicable for file system operations. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | If the file is in the init namespace or the kernel does not support V3 file system capabilities, it returns CAPNG_UNSET_ROOTID. Otherwise it return an integer for the namespace root id. 16 | 17 | .SH "SEE ALSO" 18 | 19 | .BR capng_get_caps_fd (3), 20 | .BR capabilities (7) 21 | 22 | .SH AUTHOR 23 | Steve Grubb 24 | -------------------------------------------------------------------------------- /docs/capng_have_capabilities.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_HAVE_CAPABILITIES" "3" "Sept 2020" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | .nf 4 | capng_have_capabilities, capng_have_permitted_capabilities \- check for capabilities 5 | .SH "SYNOPSIS" 6 | .B #include 7 | .sp 8 | capng_results_t capng_have_capabilities(capng_select_t set); 9 | capng_results_t capng_have_permitted_capabilities(void); 10 | 11 | .SH "DESCRIPTION" 12 | 13 | capng_have_capabilities will check the selected internal capabilities sets to see what the status is. The capabilities sets must be previously setup with calls to capng_get_caps_process, capng_get_caps_fd, or in some other way setup. The options are CAPNG_SELECT_CAPS for the traditional capabilities, CAPNG_SELECT_BOUNDS for the bounding set, CAPNG_SELECT_BOTH if checking both are desired, CAPNG_SELECT_AMBIENT if only checking the ambient capabilities, or CAPNG_SELECT_ALL if testing all sets is desired. When capabilities are checked, it will only look at the effective capabilities. 14 | 15 | If, however, the source of capabilities comes from a file, then you may need to additionally check the permitted capabilities. It's for this reason that 16 | .B capng_have_permitted_capabilities 17 | was created. It takes no arguments because it simply checks the permitted set. 18 | 19 | .SH "RETURN VALUE" 20 | 21 | This function will return one of the following four self explanatory values: CAPNG_FAIL, CAPNG_NONE, CAPNG_PARTIAL, CAPNG_FULL. 22 | 23 | .SH "SEE ALSO" 24 | 25 | .BR capng_get_caps_process (3), 26 | .BR capng_get_caps_fd (3), 27 | .BR capng_have_capability (3), 28 | .BR capabilities (7) 29 | 30 | .SH AUTHOR 31 | Steve Grubb 32 | -------------------------------------------------------------------------------- /docs/capng_have_capability.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_HAVE_CAPABILITY" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_have_capability \- check for specific capability 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_have_capability(capng_type_t which, unsigned int capability); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_have_capability will check the specified internal capabilities set to see if the specified capability is set. The capabilities sets must be previously setup with calls to capng_get_caps_process, capng_get_caps_fd, or in some other way setup. The values for which should be one of: CAPNG_EFFECTIVE, CAPNG_PERMITTED, CAPNG_INHERITABLE, CAPNG_BOUNDING_SET, or CAPNG_AMBIENT. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | This function will return 1 if yes and 0 otherwise. 16 | 17 | .SH "SEE ALSO" 18 | 19 | .BR capng_get_caps_process (3), 20 | .BR capng_get_caps_fd (3), 21 | .BR capng_have_capabilities (3), 22 | .BR capabilities (7) 23 | 24 | .SH AUTHOR 25 | Steve Grubb 26 | -------------------------------------------------------------------------------- /docs/capng_lock.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_LOCK" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_lock \- lock the current process capabilities settings 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_lock(void); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_lock will take steps to prevent children of the current process to regain full privileges if the uid is 0. This should be called while possessing the CAP_SETPCAP capability in the kernel. This function will do the following if permitted by the kernel: Set the NOROOT option on for PR_SET_SECUREBITS, set the NOROOT_LOCKED option to on for PR_SET_SECUREBITS, set the PR_NO_SETUID_FIXUP option on for PR_SET_SECUREBITS, and set the PR_NO_SETUID_FIXUP_LOCKED option on for PR_SET_SECUREBITS. 12 | 13 | 14 | .SH "RETURN VALUE" 15 | 16 | This returns 0 on success and a negative number on failure. -1 means a failure setting any of the PR_SET_SECUREBITS options. 17 | 18 | .SH "SEE ALSO" 19 | 20 | .BR capng_apply (3), 21 | .BR prctl (2), 22 | .BR capabilities (7) 23 | 24 | .SH AUTHOR 25 | Steve Grubb 26 | -------------------------------------------------------------------------------- /docs/capng_name_to_capability.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_NAME_TO_CAPABILITY" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_name_to_capability \- convert capability text to integer 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_name_to_capability(const char *name); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_name_to_capability will take the string being passed and look it up to see what its integer value would be. The string being input is the same name as the define in linux/capability.h with the CAP_ prefix removed. The string case does not matter. The integer that is output is the same as the define would be from linux/capability.h. This is useful for taking string input and converting to something that can be used with capng_update. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | This returns a negative number on failure and the correct define otherwise. 16 | 17 | .SH "SEE ALSO" 18 | 19 | .BR capng_capability_to_name (3), 20 | .BR capabilities (7) 21 | 22 | .SH AUTHOR 23 | Steve Grubb 24 | -------------------------------------------------------------------------------- /docs/capng_print_caps_numeric.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_PRINT_CAPS_NUMERIC" "3" "Sept 2020" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_print_caps_numeric \- print numeric values for capabilities set 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | char *capng_print_caps_numeric(capng_print_t where, capng_select_t set); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_print_caps_numeric will create a numeric representation of the internal capabilities. The representation can be sent to either stdout or a buffer by passing CAPNG_PRINT_STDOUT or CAPNG_PRINT_BUFFER respectively for the where parameter. If the option was for a buffer, this function will malloc a buffer that the caller must free. 12 | 13 | The set parameter controls what is included in the representation. The legal options are CAPNG_SELECT_CAPS for the traditional capabilities, CAPNG_SELECT_BOUNDS for the bounding set, CAPNG_SELECT_BOTH if printing both is desired, CAPNG_SELECT_AMBIENT if only printing the ambient capabilities, or CAPNG_SELECT_ALL if printing all is desired. 14 | 15 | .SH "RETURN VALUE" 16 | 17 | If CAPNG_PRINT_BUFFER was selected for where, this will be the text buffer and NULL on failure. If CAPNG_PRINT_STDOUT was selected then this value will be NULL no matter what. 18 | 19 | .SH "SEE ALSO" 20 | 21 | .BR capng_print_caps_text (3), 22 | .BR capabilities (7) 23 | 24 | .SH AUTHOR 25 | Steve Grubb 26 | -------------------------------------------------------------------------------- /docs/capng_print_caps_text.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_PRINT_CAPS_NUMERIC" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_print_caps_text \- print names of values for capabilities set 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | char *capng_print_caps_text(capng_print_t where, capng_type_t which); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_print_caps_text will create a text string representation of the internal capability set specified. The representation can be sent to either stdout or a buffer by passing CAPNG_PRINT_STDOUT or CAPNG_PRINT_BUFFER respectively for the where parameter. If the option was for a buffer, this function will malloc a buffer that the caller must free. 12 | 13 | The legal values for the which parameter is CAPNG_EFFECTIVE, CAPNG_PERMITTED, CAPNG_INHERITABLE, CAPNG_BOUNDING_SET, or CAPNG_AMBIENT. 14 | 15 | .SH "RETURN VALUE" 16 | 17 | If CAPNG_PRINT_BUFFER was selected for where, this will be the text buffer and NULL on failure. If CAPNG_PRINT_STDOUT was selected then this value will be NULL no matter what. 18 | 19 | .SH "SEE ALSO" 20 | 21 | .BR capng_print_caps_numeric (3), 22 | .BR capabilities (7) 23 | 24 | .SH AUTHOR 25 | Steve Grubb 26 | -------------------------------------------------------------------------------- /docs/capng_restore_state.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_SAVE_STATE" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_restore_state \- set the internal library state 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | void capng_restore_state(void **state); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_restore_state is a function that takes the state information previously saved by capng_save_state and restores the libraries internal state. This function is not available in the python bindings. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | None. 16 | 17 | .SH NOTES 18 | 19 | capng_restore_state free's the previously malloc'd state, thus the state can't be restored multiple times. 20 | 21 | The working pid is part of the restored state, if restoring the state to a different thread, capng_setpid 22 | can be used to update it. 23 | 24 | .SH "SEE ALSO" 25 | 26 | .BR capng_save_state (3), 27 | .BR capabilities (7) 28 | 29 | .SH AUTHOR 30 | Steve Grubb 31 | -------------------------------------------------------------------------------- /docs/capng_save_state.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_SAVE_STATE" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_save_state \- get the internal library state 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | void *capng_save_state(void); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_save_state is a function that returns a pointer to the internal state of the libcap-ng library. It should be considered opaque and not for alteration directly. This function should be used when you suspect a third party library may use libcap-ng also and want to make sure it doesn't alter something important. This function is not available in the python bindings. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | This returns NULL on failure and a non-NULL pointer otherwise. 16 | 17 | .SH NOTES 18 | 19 | The structure returned by capng_save_state is malloc'd; it should be free'd if not used. 20 | 21 | .SH "SEE ALSO" 22 | 23 | .BR capng_restore_state (3), 24 | .BR capabilities (7) 25 | 26 | .SH AUTHOR 27 | Steve Grubb 28 | -------------------------------------------------------------------------------- /docs/capng_set_rootid.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_SET_ROOTID" "3" "Sept 2020" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_set_rootid \- set namespace root id 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_set_rootid(int rootid); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_set_rootid sets the rootid for capabilities operations. This is only applicable for file system operations. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | On success, it returns 0. It returns -1 if there is an internal error or the kernel does not suppor V3 filesystem capabilities. 16 | 17 | .SH "SEE ALSO" 18 | 19 | .BR capng_set_caps_fd (3), 20 | .BR capabilities (7) 21 | 22 | .SH AUTHOR 23 | Steve Grubb 24 | -------------------------------------------------------------------------------- /docs/capng_setpid.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_SETPID" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_setpid \- set working pid 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | void capng_setpid(int pid); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_pid sets the working pid for capabilities operations. This is useful if you want to get the capabilities of a different process. 12 | 13 | .SH NOTES 14 | 15 | If your process calls 16 | .B fork 17 | , then the child process will still have the pid of the parent process stored in libcap-ng's internal data. It is disallowed to do any kind of setcap operations because you would be crossing process boundaries. To correct this, if your program links against pthreads, then libcap-ng will use the 18 | .B pthread_atfork 19 | function (as a weak symbol) to reset the pid information to the new process automatically. You are not required to link against pthreads. You can call 20 | .B capng_setpid 21 | and adjust the stored pid manually. 22 | 23 | .SH "RETURN VALUE" 24 | 25 | None. 26 | 27 | .SH "SEE ALSO" 28 | 29 | .BR capng_get_caps_process (3), 30 | .BR capabilities (7) 31 | 32 | .SH AUTHOR 33 | Steve Grubb 34 | -------------------------------------------------------------------------------- /docs/capng_update.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_UPDATE" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_update \- update the stored capabilities settings 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_update(capng_act_t action, capng_type_t type,unsigned int capability); 8 | 9 | .SH "DESCRIPTION" 10 | 11 | capng_update will update the internal POSIX capabilities settings based on the options passed to it. The action should be either CAPNG_DROP to set the capability bit to 0, or CAPNG_ADD to set the capability bit to 1. The operation is performed on the capability set specified in the type parameter. The values are: CAPNG_EFFECTIVE, CAPNG_PERMITTED, CAPNG_INHERITABLE, CAPNG_BOUNDING_SET, or CAPNG_AMBIENT. The values may be or'ed together to perform the same operation on multiple sets. The last parameter, capability, is the capability define as given in linux/capability.h. 12 | 13 | .SH "RETURN VALUE" 14 | 15 | This returns 0 on success and -1 on failure. 16 | 17 | .SH "SEE ALSO" 18 | 19 | .BR capng_updatev (3), 20 | .BR capabilities (7) 21 | 22 | .SH AUTHOR 23 | Steve Grubb 24 | -------------------------------------------------------------------------------- /docs/capng_updatev.3: -------------------------------------------------------------------------------- 1 | .TH "CAPNG_UPDATEV" "3" "June 2009" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | capng_updatev \- update the stored capabilities settings 4 | .SH "SYNOPSIS" 5 | .B #include 6 | .sp 7 | int capng_updatev(capng_act_t action, capng_type_t type, 8 | unsigned int capability, ...); 9 | 10 | .SH "DESCRIPTION" 11 | 12 | capng_updatev will update the internal POSIX capabilities settings based on the options passed to it. The action should be either CAPNG_DROP to set the capability bit to 0, or CAPNG_ADD to set the capability bit to 1. The operation is performed on the capability set specified in the type parameter. The values are: CAPNG_EFFECTIVE, CAPNG_PERMITTED, CAPNG_INHERITABLE, CAPNG_BOUNDING_SET, or CAPNG_AMBIENT. The values may be or'ed together to perform the same operation on multiple sets. The last parameter, capability, is the capability define as given in linux/capability.h. 13 | 14 | This function differs from capng_update in that you may pass a list of capabilities. This list must be terminated with a -1 value. 15 | 16 | .SH "RETURN VALUE" 17 | 18 | This returns 0 on success and -1 on failure. 19 | 20 | .SH "SEE ALSO" 21 | 22 | .BR capng_update (3), 23 | .BR capabilities (7) 24 | 25 | .SH AUTHOR 26 | Steve Grubb 27 | -------------------------------------------------------------------------------- /docs/libdrop_ambient.7: -------------------------------------------------------------------------------- 1 | .TH "LIBDROP_AMBIENT" "7" "Nov 2020" "Red Hat" "Libcap-ng API" 2 | .SH NAME 3 | libdrop_ambient \- force application started with ambient capabilities to drop them 4 | 5 | .SH "DESCRIPTION 6 | 7 | This library can be used via LD_PRELOAD to force an application started with ambient capabilities to drop them. It leaves other capabilities intact. This can also be linked against and automatically does the right thing. You do not need to make any calls into the library because all the work is done in the constructor which runs before main() is called. 8 | 9 | .SH "SEE ALSO" 10 | 11 | .BR capabilities (7) 12 | 13 | .SH AUTHOR 14 | Steve Grubb 15 | -------------------------------------------------------------------------------- /libcap-ng.spec: -------------------------------------------------------------------------------- 1 | Summary: An alternate POSIX capabilities library 2 | Name: libcap-ng 3 | Version: 0.8.6 4 | Release: 1%{?dist} 5 | License: LGPLv2+ 6 | Group: System Environment/Libraries 7 | URL: http://people.redhat.com/sgrubb/libcap-ng 8 | Source0: http://people.redhat.com/sgrubb/libcap-ng/%{name}-%{version}.tar.gz 9 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 10 | BuildRequires: kernel-headers >= 2.6.11 11 | BuildRequires: libattr-devel 12 | 13 | %description 14 | Libcap-ng is a library that makes using POSIX capabilities easier 15 | 16 | %package devel 17 | Summary: Header files for libcap-ng library 18 | License: LGPLv2+ 19 | Group: Development/Libraries 20 | Requires: kernel-headers >= 2.6.11 21 | Requires: %{name} = %{version}-%{release} 22 | Requires: pkgconfig 23 | 24 | %description devel 25 | The libcap-ng-devel package contains the files needed for developing 26 | applications that need to use the libcap-ng library. 27 | 28 | %package python3 29 | Summary: Python3 bindings for libcap-ng library 30 | License: LGPLv2+ 31 | Group: Development/Libraries 32 | BuildRequires: python3-devel swig 33 | Requires: %{name} = %{version}-%{release} 34 | 35 | %description python3 36 | The libcap-ng-python3 package contains the bindings so that libcap-ng 37 | and can be used by python3 applications. 38 | 39 | %package utils 40 | Summary: Utilities for analyzing and setting file capabilities 41 | License: GPLv2+ 42 | Group: Development/Libraries 43 | 44 | %description utils 45 | The libcap-ng-utils package contains applications to analyze the 46 | POSIX capabilities of all the program running on a system. It also 47 | lets you set the file system based capabilities. 48 | 49 | %prep 50 | %setup -q 51 | 52 | %build 53 | %configure --libdir=%{_libdir} --with-python3 54 | make CFLAGS="%{optflags}" %{?_smp_mflags} 55 | 56 | %install 57 | make DESTDIR="${RPM_BUILD_ROOT}" INSTALL='install -p' install 58 | 59 | # Remove a couple things so they don't get picked up 60 | rm -f $RPM_BUILD_ROOT/%{_libdir}/libcap-ng.la 61 | rm -f $RPM_BUILD_ROOT/%{_libdir}/libcap-ng.a 62 | rm -f $RPM_BUILD_ROOT/%{_libdir}/libdrop_ambient.la 63 | rm -f $RPM_BUILD_ROOT/%{_libdir}/libdrop_ambient.a 64 | rm -f $RPM_BUILD_ROOT/%{_libdir}/python?.?/site-packages/_capng.a 65 | rm -f $RPM_BUILD_ROOT/%{_libdir}/python?.?/site-packages/_capng.la 66 | 67 | %check 68 | make check 69 | 70 | %ldconfig_scriptlets 71 | 72 | %files 73 | %defattr(-,root,root,-) 74 | %doc COPYING.LIB 75 | /%{_libdir}/libcap-ng.so.* 76 | /%{_libdir}/libdrop_ambient.so.* 77 | %attr(0644,root,root) %{_mandir}/man7/* 78 | 79 | %files devel 80 | %defattr(-,root,root,-) 81 | %attr(0644,root,root) %{_mandir}/man3/* 82 | %attr(0644,root,root) %{_includedir}/cap-ng.h 83 | %{_libdir}/libcap-ng.so 84 | %{_libdir}/libdrop_ambient.so 85 | %attr(0644,root,root) %{_datadir}/aclocal/cap-ng.m4 86 | %{_libdir}/pkgconfig/libcap-ng.pc 87 | 88 | %files python3 89 | %defattr(-,root,root,-) 90 | %attr(755,root,root) %{python3_sitearch}/* 91 | 92 | %files utils 93 | %defattr(-,root,root,-) 94 | %doc COPYING 95 | %attr(0755,root,root) %{_bindir}/* 96 | %attr(0644,root,root) %{_mandir}/man8/* 97 | 98 | %changelog 99 | * Tue Apr 09 2024 Steve Grubb 0.8.6-1 100 | - New upstream release 101 | 102 | -------------------------------------------------------------------------------- /m4/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2009 Red Hat Inc., Durham, North Carolina. 3 | # All Rights Reserved. 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | # 19 | # Authors: 20 | # Steve Grubb 21 | # 22 | 23 | CONFIG_CLEAN_FILES = *.loT *.rej *.orig 24 | 25 | m4datadir = $(datadir)/aclocal 26 | dist_m4data_DATA = cap-ng.m4 27 | 28 | -------------------------------------------------------------------------------- /m4/cap-ng.m4: -------------------------------------------------------------------------------- 1 | # libcap-ng.m4 - Checks for the libcap-ng support 2 | # Copyright (c) 2009 Steve Grubb sgrubb@redhat.com 3 | # 4 | AC_DEFUN([LIBCAP_NG_PATH], 5 | [ 6 | AC_ARG_WITH(libcap-ng, 7 | [ --with-libcap-ng=[auto/yes/no] Add Libcap-ng support [default=auto]],, 8 | with_libcap_ng=auto) 9 | 10 | # Check for Libcap-ng API 11 | # 12 | # libcap-ng detection 13 | 14 | if test x$with_libcap_ng = xno ; then 15 | have_libcap_ng=no; 16 | else 17 | # Start by checking for header file 18 | AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no) 19 | 20 | # See if we have libcap-ng library 21 | AC_CHECK_LIB(cap-ng, capng_clear, 22 | CAPNG_LDADD=-lcap-ng,) 23 | 24 | # Check results are usable 25 | if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then 26 | AC_MSG_ERROR(libcap-ng support was requested and the library was not found) 27 | fi 28 | if test x$CAPNG_LDADD != x -a $capng_headers = no ; then 29 | AC_MSG_ERROR(libcap-ng libraries found but headers are missing) 30 | fi 31 | fi 32 | 33 | AC_SUBST(CAPNG_LDADD) 34 | AC_MSG_CHECKING(whether to use libcap-ng) 35 | if test x$CAPNG_LDADD != x ; then 36 | AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support]) 37 | AC_CHECK_DECLS([CAPNG_AMBIENT], [], [], [[#include ]]) 38 | AC_MSG_RESULT(yes) 39 | else 40 | AC_MSG_RESULT(no) 41 | fi 42 | ]) 43 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2009,2015,2020 Red Hat Inc. 3 | # All Rights Reserved. 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program; see the file COPYING.LIB. If not, write to the 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | # Boston, MA 02110-1335, USA. 19 | # 20 | # Authors: 21 | # Steve Grubb 22 | # 23 | 24 | SUBDIRS = test 25 | pkgconfigdir = $(libdir)/pkgconfig 26 | pkgconfig_DATA = libcap-ng.pc 27 | DISTCLEANFILES = $(pkgconfig_DATA) 28 | CLEANFILES = $(BUILT_SOURCES) 29 | CONFIG_CLEAN_FILES = *.loT *.rej *.orig 30 | AM_CFLAGS = -fPIC -DPIC -W -Wall -Wshadow ${WFLAGS} -Wundef -D_GNU_SOURCE 31 | AM_CPPFLAGS = -I. -I${top_srcdir} 32 | lib_LTLIBRARIES = libcap-ng.la 33 | if BUILD_LIBDROP_AMBIENT 34 | lib_LTLIBRARIES += libdrop_ambient.la 35 | endif 36 | include_HEADERS = cap-ng.h 37 | noinst_HEADERS = captab.h 38 | libcap_ng_la_SOURCES = cap-ng.c lookup_table.c 39 | libcap_ng_la_LIBADD = 40 | libcap_ng_la_DEPENDENCIES = $(libcap_ng_la_SOURCES) ../config.h 41 | libcap_ng_la_LDFLAGS = -Wl,-z,relro 42 | libdrop_ambient_la_SOURCES = libdrop_ambient.c 43 | 44 | -------------------------------------------------------------------------------- /src/cap-ng.h: -------------------------------------------------------------------------------- 1 | /* libcap-ng.h -- 2 | * Copyright 2009,2013,2020-23 Red Hat Inc. 3 | * All Rights Reserved. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; see the file COPYING.LIB. If not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | * Boston, MA 02110-1335, USA. 19 | * 20 | * Authors: 21 | * Steve Grubb 22 | */ 23 | 24 | #ifndef LIBCAP_NG_HEADER 25 | #define LIBCAP_NG_HEADER 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | // The next 2 macros originate in sys/cdefs.h 32 | // gcc-analyzer notation 33 | #ifndef __attr_dealloc_free 34 | # define __attr_dealloc_free 35 | #endif 36 | 37 | // Warn unused result 38 | #ifndef __wur 39 | # define __wur 40 | #endif 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | typedef enum { CAPNG_DROP, CAPNG_ADD } capng_act_t; 47 | typedef enum { CAPNG_EFFECTIVE=1, CAPNG_PERMITTED=2, 48 | CAPNG_INHERITABLE=4, CAPNG_BOUNDING_SET=8, 49 | CAPNG_AMBIENT=16 } capng_type_t; 50 | typedef enum { CAPNG_SELECT_CAPS = 16, CAPNG_SELECT_BOUNDS = 32, 51 | CAPNG_SELECT_BOTH = 48, CAPNG_SELECT_AMBIENT = 64, 52 | CAPNG_SELECT_ALL = 112 } capng_select_t; 53 | typedef enum { CAPNG_FAIL=-1, CAPNG_NONE, CAPNG_PARTIAL, 54 | CAPNG_FULL } capng_results_t; 55 | typedef enum { CAPNG_PRINT_STDOUT, CAPNG_PRINT_BUFFER } capng_print_t; 56 | typedef enum { CAPNG_NO_FLAG=0, CAPNG_DROP_SUPP_GRP=1, 57 | CAPNG_CLEAR_BOUNDING=2, CAPNG_INIT_SUPP_GRP=4, 58 | CAPNG_CLEAR_AMBIENT=8 } capng_flags_t; 59 | 60 | #define CAPNG_UNSET_ROOTID -1 61 | #define CAPNG_SUPPORTS_AMBIENT 1 62 | 63 | // These functions manipulate process capabilities 64 | void capng_clear(capng_select_t set); 65 | void capng_fill(capng_select_t set); 66 | void capng_setpid(int pid); 67 | int capng_get_caps_process(void) __wur; 68 | int capng_update(capng_act_t action, capng_type_t type,unsigned int capability); 69 | int capng_updatev(capng_act_t action, capng_type_t type, 70 | unsigned int capability, ...); 71 | 72 | // These functions apply the capabilities previously setup to a process 73 | int capng_apply(capng_select_t set) __wur; 74 | int capng_lock(void) __wur; 75 | int capng_change_id(int uid, int gid, capng_flags_t flag) __wur; 76 | 77 | // These functions are used for file based capabilities 78 | int capng_get_rootid(void); 79 | int capng_set_rootid(int rootid); 80 | int capng_get_caps_fd(int fd) __wur; 81 | int capng_apply_caps_fd(int fd) __wur; 82 | 83 | // These functions check capability bits 84 | capng_results_t capng_have_capabilities(capng_select_t set); 85 | capng_results_t capng_have_permitted_capabilities(void); 86 | int capng_have_capability(capng_type_t which, unsigned int capability); 87 | 88 | // These functions printout capabilities 89 | char *capng_print_caps_numeric(capng_print_t where, capng_select_t set) 90 | __attr_dealloc_free; 91 | char *capng_print_caps_text(capng_print_t where, capng_type_t which) 92 | __attr_dealloc_free; 93 | 94 | // These functions convert between numeric and text string 95 | int capng_name_to_capability(const char *name); 96 | const char *capng_capability_to_name(unsigned int capability); 97 | 98 | // These function should be used when you suspect a third party library 99 | // may use libcap-ng also and want to make sure it doesn't alter something 100 | // important. Otherwise you shouldn't need to call these. 101 | void capng_restore_state(void **state); 102 | void *capng_save_state(void); 103 | 104 | #ifdef __cplusplus 105 | } 106 | #endif 107 | 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /src/captab.h: -------------------------------------------------------------------------------- 1 | /* captab.h -- 2 | * Copyright 2009,2011-14,2020 Red Hat Inc. 3 | * All Rights Reserved. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; see the file COPYING.LIB. If not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | * Boston, MA 02110-1335, USA. 19 | * 20 | * Authors: 21 | * Steve Grubb 22 | */ 23 | 24 | _S(CAP_CHOWN, "chown" ) 25 | _S(CAP_DAC_OVERRIDE, "dac_override" ) 26 | _S(CAP_DAC_READ_SEARCH, "dac_read_search" ) 27 | _S(CAP_FOWNER, "fowner" ) 28 | _S(CAP_FSETID, "fsetid" ) 29 | _S(CAP_KILL, "kill" ) 30 | _S(CAP_SETGID, "setgid" ) 31 | _S(CAP_SETUID, "setuid" ) 32 | _S(CAP_SETPCAP, "setpcap" ) 33 | _S(CAP_LINUX_IMMUTABLE, "linux_immutable" ) 34 | _S(CAP_NET_BIND_SERVICE, "net_bind_service" ) 35 | _S(CAP_NET_BROADCAST, "net_broadcast" ) 36 | _S(CAP_NET_ADMIN, "net_admin" ) 37 | _S(CAP_NET_RAW, "net_raw" ) 38 | _S(CAP_IPC_LOCK, "ipc_lock" ) 39 | _S(CAP_IPC_OWNER, "ipc_owner" ) 40 | _S(CAP_SYS_MODULE, "sys_module" ) 41 | _S(CAP_SYS_RAWIO, "sys_rawio" ) 42 | _S(CAP_SYS_CHROOT, "sys_chroot" ) 43 | _S(CAP_SYS_PTRACE, "sys_ptrace" ) 44 | _S(CAP_SYS_PACCT, "sys_pacct" ) 45 | _S(CAP_SYS_ADMIN, "sys_admin" ) 46 | _S(CAP_SYS_BOOT, "sys_boot" ) 47 | _S(CAP_SYS_NICE, "sys_nice" ) 48 | _S(CAP_SYS_RESOURCE, "sys_resource" ) 49 | _S(CAP_SYS_TIME, "sys_time" ) 50 | _S(CAP_SYS_TTY_CONFIG, "sys_tty_config" ) 51 | _S(CAP_MKNOD, "mknod" ) 52 | _S(CAP_LEASE, "lease" ) 53 | _S(CAP_AUDIT_WRITE, "audit_write" ) 54 | _S(CAP_AUDIT_CONTROL, "audit_control" ) 55 | #ifdef CAP_SETFCAP 56 | _S(CAP_SETFCAP, "setfcap" ) 57 | #endif 58 | #ifdef CAP_MAC_OVERRIDE 59 | _S(CAP_MAC_OVERRIDE, "mac_override" ) 60 | #endif 61 | #ifdef CAP_MAC_ADMIN 62 | _S(CAP_MAC_ADMIN, "mac_admin" ) 63 | #endif 64 | #ifdef CAP_SYSLOG 65 | _S(CAP_SYSLOG, "syslog" ) 66 | #endif 67 | #if defined(CAP_EPOLLWAKEUP) && defined(CAP_BLOCK_SUSPEND) 68 | #error "Both CAP_EPOLLWAKEUP and CAP_BLOCK_SUSPEND are defined" 69 | #endif 70 | #ifdef CAP_EPOLLWAKEUP 71 | _S(CAP_EPOLLWAKEUP, "epollwakeup" ) 72 | #endif 73 | #ifdef CAP_WAKE_ALARM 74 | _S(CAP_WAKE_ALARM, "wake_alarm" ) 75 | #endif 76 | #ifdef CAP_BLOCK_SUSPEND 77 | _S(CAP_BLOCK_SUSPEND, "block_suspend" ) 78 | #endif 79 | #ifdef CAP_AUDIT_READ 80 | _S(CAP_AUDIT_READ, "audit_read" ) 81 | #endif 82 | #ifdef CAP_PERFMON 83 | _S(CAP_PERFMON, "perfmon" ) 84 | #endif 85 | #ifdef CAP_BPF 86 | _S(CAP_BPF, "bpf" ) 87 | #endif 88 | #ifdef CAP_CHECKPOINT_RESTORE 89 | _S(CAP_CHECKPOINT_RESTORE, "checkpoint_restore") 90 | #endif 91 | -------------------------------------------------------------------------------- /src/libcap-ng.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libcap-ng 7 | Description: An alternate POSIX capabilities library. 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -lcap-ng 10 | Cflags: -I${includedir} 11 | License: LGPL-2.1-or-later 12 | 13 | -------------------------------------------------------------------------------- /src/libdrop_ambient.c: -------------------------------------------------------------------------------- 1 | /* libdrop_ambient.c -- 2 | * Copyright 2020 Red Hat Inc. 3 | * All Rights Reserved. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; see the file COPYING.LIB. If not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | * Boston, MA 02110-1335, USA. 19 | * 20 | * Authors: 21 | * Steve Grubb 22 | */ 23 | 24 | #include "config.h" 25 | #include 26 | 27 | void __attribute__ ((constructor)) init(void) 28 | { 29 | prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/lookup_table.c: -------------------------------------------------------------------------------- 1 | /* lookup_table.c -- 2 | * Copyright 2009, 2013, 2025 Red Hat Inc. 3 | * All Rights Reserved. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; see the file COPYING.LIB. If not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | * Boston, MA 02110-1335, USA. 19 | * 20 | * Authors: 21 | * Steve Grubb 22 | */ 23 | 24 | #include "config.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | 31 | #pragma GCC optimize("O3") 32 | #define hidden __attribute__ ((visibility ("hidden"))) 33 | extern unsigned int last_cap hidden; 34 | 35 | #undef cap_valid 36 | #define cap_valid(x) ((x) <= last_cap) 37 | 38 | 39 | struct transtab { 40 | unsigned int value; 41 | unsigned int offset; 42 | }; 43 | 44 | #define MSGSTRFIELD(line) MSGSTRFIELD1(line) 45 | #define MSGSTRFIELD1(line) str##line 46 | 47 | 48 | /* To create the following tables in a DSO-friendly way we split them in 49 | two separate variables: a long string which is created by concatenating 50 | all strings referenced in the table and the table itself, which uses 51 | offsets instead of string pointers. To do this without increasing 52 | the maintenance burden we use a lot of preprocessor magic. All the 53 | maintainer has to do is to add a new entry to the included file and 54 | recompile. */ 55 | 56 | static const union captab_msgstr_t { 57 | struct { 58 | #define _S(n, s) char MSGSTRFIELD(__LINE__)[sizeof (s)]; 59 | #include "captab.h" 60 | #undef _S 61 | }; 62 | char str[0]; 63 | } captab_msgstr = { { 64 | #define _S(n, s) s, 65 | #include "captab.h" 66 | #undef _S 67 | } }; 68 | static const struct transtab captab[] = { 69 | #define _S(n, s) { n, offsetof(union captab_msgstr_t, \ 70 | MSGSTRFIELD(__LINE__)) }, 71 | #include "captab.h" 72 | #undef _S 73 | }; 74 | #define CAP_NG_CAPABILITY_NAMES (sizeof(captab)/sizeof(captab[0])) 75 | 76 | 77 | 78 | 79 | static inline int capng_lookup_name(const char *name) 80 | { 81 | // brute force search 82 | for (size_t i = 0; i < CAP_NG_CAPABILITY_NAMES; i++) { 83 | if (!strcasecmp(captab_msgstr.str + captab[i].offset, name)) 84 | return captab[i].value; 85 | } 86 | return -1; 87 | } 88 | 89 | static inline const char *capng_lookup_number(unsigned int number) 90 | { 91 | if (number >= CAP_NG_CAPABILITY_NAMES) 92 | return NULL; 93 | 94 | if (captab[number].value == number) 95 | return captab_msgstr.str + captab[number].offset; 96 | 97 | // Fallback to old search in case a capability is retired 98 | for (size_t i = 0; i < CAP_NG_CAPABILITY_NAMES; i++) { 99 | if (captab[i].value == number) 100 | return captab_msgstr.str + captab[i].offset; 101 | } 102 | return NULL; 103 | } 104 | 105 | int capng_name_to_capability(const char *name) 106 | { 107 | return capng_lookup_name(name); 108 | } 109 | 110 | static char ptr2[32]; 111 | const char *capng_capability_to_name(unsigned int capability) 112 | { 113 | const char *ptr; 114 | 115 | if (!cap_valid(capability)) 116 | return NULL; 117 | 118 | ptr = capng_lookup_number(capability); 119 | if (ptr == NULL) { 120 | snprintf(ptr2, sizeof(ptr2), "cap_%u", capability); 121 | ptr = ptr2; 122 | } 123 | return ptr; 124 | } 125 | 126 | -------------------------------------------------------------------------------- /src/test/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2009,10,15 Red Hat Inc. 3 | # All Rights Reserved. 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program; see the file COPYING.LIB. If not, write to the 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | # Boston, MA 02110-1335, USA. 19 | # 20 | # Authors: 21 | # Steve Grubb 22 | # 23 | 24 | AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/src 25 | check_PROGRAMS = lib_test thread_test 26 | TESTS = $(check_PROGRAMS) 27 | 28 | lib_test_LDADD = ${top_builddir}/src/libcap-ng.la 29 | thread_test_LDADD = ${top_builddir}/src/libcap-ng.la -lpthread 30 | -------------------------------------------------------------------------------- /src/test/lib_test.c: -------------------------------------------------------------------------------- 1 | /* lib_test.c -- simple libcap-ng test suite 2 | * Copyright 2009,2012-13 Red Hat Inc. 3 | * All Rights Reserved. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program; see the file COPYING.LIB. If not, write to the 17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | * Boston, MA 02110-1335, USA. 19 | * 20 | * Authors: 21 | * Steve Grubb 22 | */ 23 | 24 | #include "config.h" 25 | #include "../cap-ng.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | static unsigned int get_last_cap(void) 34 | { 35 | int fd; 36 | 37 | fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY); 38 | if (fd == -1) { 39 | return CAP_LAST_CAP; 40 | } else { 41 | char buf[8]; 42 | int num = read(fd, buf, sizeof(buf)); 43 | if (num > 0) { 44 | errno = 0; 45 | unsigned int val = strtoul(buf, NULL, 10); 46 | if (errno == 0) 47 | return val; 48 | } 49 | close(fd); 50 | } 51 | return CAP_LAST_CAP; 52 | } 53 | 54 | int main(void) 55 | { 56 | int rc; 57 | unsigned int i, len, last = get_last_cap(); 58 | char *text; 59 | void *saved; 60 | 61 | puts("Doing basic bit tests..."); 62 | capng_clear(CAPNG_SELECT_BOTH); 63 | if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) { 64 | puts("Failed clearing capabilities"); 65 | abort(); 66 | } 67 | saved = capng_save_state(); 68 | capng_fill(CAPNG_SELECT_BOTH); 69 | if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_FULL) { 70 | puts("Failed filling capabilities"); 71 | abort(); 72 | } 73 | // Need to detect if version 1 or 2 capabilities 74 | text = capng_print_caps_numeric(CAPNG_PRINT_BUFFER, CAPNG_SELECT_CAPS); 75 | len = strlen(text); 76 | free(text); 77 | if (len < 80 && last > 30) // The kernel & headers are mismatched 78 | last = 30; 79 | // Now test that restore still works 80 | capng_restore_state(&saved); 81 | if (capng_have_capabilities(CAPNG_SELECT_BOTH) != CAPNG_NONE) { 82 | puts("Failed restoring capabilities"); 83 | abort(); 84 | } 85 | printf("Doing advanced bit tests for %d capabilities...\n", last); 86 | for (i=0; i<=last; i++) { 87 | const char *name; 88 | capng_clear(CAPNG_SELECT_BOTH); 89 | rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i); 90 | if (rc) { 91 | puts("Failed update test 1"); 92 | abort(); 93 | } 94 | rc = capng_have_capability(CAPNG_EFFECTIVE, i); 95 | if (rc == 0) { 96 | puts("Failed have capability test 1"); 97 | capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 98 | CAPNG_SELECT_CAPS); 99 | abort(); 100 | } 101 | if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){ 102 | puts("Failed have capabilities test 1"); 103 | capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 104 | CAPNG_SELECT_CAPS); 105 | abort(); 106 | } 107 | #if CAP_LAST_CAP > 31 108 | rc = capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i); 109 | if (rc) { 110 | puts("Failed bset update test 2"); 111 | abort(); 112 | } 113 | rc = capng_have_capability(CAPNG_BOUNDING_SET, i); 114 | if (rc == 0) { 115 | puts("Failed bset have capability test 2"); 116 | capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 117 | CAPNG_SELECT_BOTH); 118 | abort(); 119 | } 120 | if(capng_have_capabilities(CAPNG_SELECT_BOUNDS)!=CAPNG_PARTIAL){ 121 | puts("Failed bset have capabilities test 2"); 122 | capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 123 | CAPNG_SELECT_BOTH); 124 | abort(); 125 | } 126 | #endif 127 | text=capng_print_caps_text(CAPNG_PRINT_BUFFER, CAPNG_EFFECTIVE); 128 | if (text == NULL) { 129 | puts("Failed getting print text to buffer"); 130 | abort(); 131 | } 132 | name = capng_capability_to_name(i); 133 | if (name == NULL) { 134 | printf("Failed converting capability %d to name\n", i); 135 | abort(); 136 | } 137 | if (strcmp(text, name)) { 138 | puts("Failed print text comparison"); 139 | printf("%s != %s\n", text, name); 140 | abort(); 141 | } 142 | free(text); 143 | // Now make sure the mask part is working 144 | capng_fill(CAPNG_SELECT_BOTH); 145 | rc = capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, i); 146 | if (rc) { 147 | puts("Failed update test 3"); 148 | abort(); 149 | } 150 | // Should be partial 151 | if(capng_have_capabilities(CAPNG_SELECT_CAPS)!=CAPNG_PARTIAL){ 152 | puts("Failed have capabilities test 3"); 153 | capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 154 | CAPNG_SELECT_CAPS); 155 | abort(); 156 | } 157 | // Add back the bit and should be full capabilities 158 | rc = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i); 159 | if (rc) { 160 | puts("Failed update test 4"); 161 | abort(); 162 | } 163 | if (capng_have_capabilities(CAPNG_SELECT_CAPS) != CAPNG_FULL){ 164 | puts("Failed have capabilities test 4"); 165 | capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 166 | CAPNG_SELECT_CAPS); 167 | abort(); 168 | } 169 | } 170 | // Now test the updatev function 171 | capng_clear(CAPNG_SELECT_BOTH); 172 | rc = capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE, 173 | CAP_CHOWN, CAP_FOWNER, CAP_KILL, -1); 174 | if (rc) { 175 | puts("Failed updatev test"); 176 | abort(); 177 | } 178 | rc = capng_have_capability(CAPNG_EFFECTIVE, CAP_CHOWN) && 179 | capng_have_capability(CAPNG_EFFECTIVE, CAP_FOWNER) && 180 | capng_have_capability(CAPNG_EFFECTIVE, CAP_KILL); 181 | if (rc == 0) { 182 | puts("Failed have updatev capability test"); 183 | capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 184 | CAPNG_SELECT_CAPS); 185 | abort(); 186 | } 187 | 188 | return EXIT_SUCCESS; 189 | } 190 | 191 | -------------------------------------------------------------------------------- /src/test/thread_test.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | //#define DEBUG 1 8 | 9 | pthread_t thread1, thread2; 10 | 11 | void *thread1_main(void *arg) 12 | { 13 | capng_fill(CAPNG_SELECT_BOTH); 14 | #ifdef DEBUG 15 | printf("thread1 filled capabilities\n"); 16 | #endif 17 | sleep(2); 18 | if (capng_have_capabilities(CAPNG_SELECT_CAPS) < CAPNG_FULL) { 19 | printf("Capabilities missing when there should be some\n"); 20 | exit(1); 21 | } 22 | #ifdef DEBUG 23 | printf("SUCCESS: Full capabilities reported\n"); 24 | #endif 25 | return NULL; 26 | } 27 | 28 | void *thread2_main(void *arg) 29 | { 30 | sleep(1); 31 | #ifdef DEBUG 32 | printf("thread2 getting capabilities\n"); 33 | #endif 34 | if (capng_get_caps_process()) { 35 | printf("Unable to get process capabilities"); 36 | exit(1); 37 | } 38 | if (capng_have_capabilities(CAPNG_SELECT_CAPS) != CAPNG_NONE) { 39 | printf("Detected capabilities when there should not be any\n"); 40 | exit(1); 41 | } 42 | capng_clear(CAPNG_SELECT_BOTH); 43 | #ifdef DEBUG 44 | printf("SUCCESS: No capabilities reported\n"); 45 | #endif 46 | return NULL; 47 | } 48 | 49 | int main(void) 50 | { 51 | // This test must be run as root which naturally has all capabilities 52 | // set. So, we need to clear the capabilities so that we can see if 53 | // the test works. 54 | capng_clear(CAPNG_SELECT_CAPS); 55 | if (capng_apply(CAPNG_SELECT_CAPS)) { 56 | printf("Clearing capabilities failed"); 57 | return 1; 58 | } 59 | 60 | printf("Testing thread separation of capabilities\n"); 61 | pthread_create(&thread1, NULL, thread1_main, NULL); 62 | pthread_create(&thread2, NULL, thread2_main, NULL); 63 | sleep(3); 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /utils/Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am -- 2 | # Copyright 2009,2015 Red Hat Inc. 3 | # All Rights Reserved. 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program; see the file COPYING. If not, write to the 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 18 | # Boston, MA 02110-1335, USA. 19 | # 20 | # Authors: 21 | # Steve Grubb 22 | # 23 | 24 | CONFIG_CLEAN_FILES = *.loT *.rej *.orig 25 | AUTOMAKE_OPTIONS = no-dependencies 26 | EXTRA_DIST = $(man_MANS) 27 | AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/src 28 | LDADD = ${top_builddir}/src/libcap-ng.la 29 | AM_CFLAGS = -W -Wall -Wshadow ${WFLAGS} -Wundef -D_GNU_SOURCE 30 | bin_PROGRAMS = pscap netcap filecap captest 31 | man_MANS = pscap.8 netcap.8 filecap.8 captest.8 32 | 33 | pscap_SOURCES = pscap.c 34 | netcap_SOURCES = netcap.c proc-llist.c proc-llist.h 35 | filecap_SOURCES = filecap.c 36 | captest_SOURCES = captest.c 37 | -------------------------------------------------------------------------------- /utils/captest.8: -------------------------------------------------------------------------------- 1 | .TH CAPTEST: "8" "Sept 2020" "Red Hat" "System Administration Utilities" 2 | .SH NAME 3 | captest \- a program to demonstrate capabilities 4 | .SH SYNOPSIS 5 | .B captest [ \-\-ambient \-\-drop-all | \-\-drop-caps | \-\-id ] [ \-\-init-grp ] [ \-\-lock ] [ \-\-text ] 6 | .SH DESCRIPTION 7 | \fBcaptest\fP is a program that demonstrates and prints out the current process capabilities. Each option prints the same report. It will output current capabilities. then it will try to access /etc/shadow directly to show if that can be done. Then it creates a child process that attempts to read /etc/shadow and outputs the results of that. Then it outputs the capabilities that a child process would have. 8 | 9 | You can also apply file system capabilities to this program to study how they work. For example, filecap /usr/bin/captest chown. Then run captest as a normal user. Another interesting test is to make captest suid root so that you can see what the interaction is between root's credentials and capabilities. For example, chmod 4755 /usr/bin/captest. When run as a normal user, the program will see if privilege escalation is possible. But do not leave this app setuid root after you are don testing so that an attacker cannot take advantage of it. 10 | 11 | .SH OPTIONS 12 | .TP 13 | .B \-\-ambient 14 | This attempts to add CAP_CHOWN ambient capability. 15 | .TP 16 | .B \-\-drop-all 17 | This drops all capabilities including ambient and clears the bounding set. 18 | .TP 19 | .B \-\-drop-caps 20 | This drops just traditional capabilities. 21 | .TP 22 | .B \-\-id 23 | This changes to uid and gid 99, drops supplemental groups, and clears the bounding set. 24 | .TP 25 | .B \-\-init-grp 26 | This changes to uid and gid 99 and then adds any supplemental groups that comes with that account. You would have add them prior to testing because by default there are no supplemental groups on account 99. 27 | .TP 28 | .B \-\-text 29 | This option outputs the effective capabilities in text rather than numerically. 30 | .TP 31 | .B \-\-lock 32 | This prevents the ability for child processes to regain privileges if the uid is 0. 33 | 34 | .SH "SEE ALSO" 35 | .BR filecap (8), 36 | .BR capabilities (7) 37 | 38 | .SH AUTHOR 39 | Steve Grubb 40 | -------------------------------------------------------------------------------- /utils/captest.c: -------------------------------------------------------------------------------- 1 | /* 2 | * captest.c - A program that demonstrates and outputs capabilities 3 | * Copyright (c) 2009, 2013, 2020 Red Hat Inc. 4 | * All Rights Reserved. 5 | * 6 | * This software may be freely redistributed and/or modified under the 7 | * terms of the GNU General Public License as published by the Free 8 | * Software Foundation; either version 2, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; see the file COPYING. If not, write to the 18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 19 | * Boston, MA 02110-1335, USA. 20 | * 21 | * Authors: 22 | * Steve Grubb 23 | * 24 | */ 25 | #include "config.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #ifdef HAVE_LINUX_SECUREBITS_H 35 | #include 36 | #endif 37 | 38 | /* children can't get caps back */ 39 | #ifndef SECURE_NOROOT 40 | #define SECURE_NOROOT 0 41 | #endif 42 | #ifndef SECURE_NOROOT_LOCKED 43 | #define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */ 44 | #endif 45 | /* Setuid apps run by uid 0 don't get caps back */ 46 | #ifndef SECURE_NO_SETUID_FIXUP 47 | #define SECURE_NO_SETUID_FIXUP 2 48 | #endif 49 | #ifndef SECURE_NO_SETUID_FIXUP_LOCKED 50 | #define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */ 51 | #endif 52 | 53 | static int text = 0, no_child = 0, lock = 0, ambient = 0; 54 | 55 | static void report(void) 56 | { 57 | int rc, escalated = 0, need_comma = 0; 58 | uid_t uid, euid, suid; 59 | gid_t gid, egid, sgid; 60 | 61 | // Refresh what we have for capabilities 62 | if (capng_get_caps_process()) { 63 | printf("Error getting capabilities\n"); 64 | exit(1); 65 | } 66 | 67 | // Check user credentials 68 | getresuid(&uid, &euid, &suid); 69 | getresgid(&gid, &egid, &sgid); 70 | if (no_child) { 71 | if ((uid != euid && uid != 0) || 72 | capng_have_capability(CAPNG_EFFECTIVE, 73 | CAP_SETUID)) { 74 | printf("Attempting to regain root..."); 75 | setuid(0); 76 | getresuid(&uid, &euid, &suid); 77 | if (uid == 0) { 78 | printf("SUCCESS - PRIVILEGE ESCALATION POSSIBLE\n"); 79 | setgid(0); 80 | getresgid(&gid, &egid, &sgid); 81 | escalated = 1; 82 | } else 83 | printf("FAILED\n"); 84 | } 85 | printf("Child "); 86 | } 87 | printf("User credentials uid:%u euid:%u suid:%u\n", uid, euid, suid); 88 | if (no_child) 89 | printf("Child "); 90 | printf("Group credentials gid:%u egid:%u sgid:%u\n", gid, egid, sgid); 91 | if (uid != euid || gid != egid) 92 | printf("Note: app has mismatching credentials!!\n"); 93 | 94 | // Check capabilities 95 | if (text) { 96 | if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE) { 97 | if (no_child) 98 | printf("Child capabilities: none\n"); 99 | else 100 | printf("Current capabilities: none\n"); 101 | } else { 102 | if (no_child) 103 | printf("Child "); 104 | printf("Effective: "); 105 | capng_print_caps_text(CAPNG_PRINT_STDOUT, 106 | CAPNG_EFFECTIVE); 107 | printf("\n"); 108 | if (no_child) 109 | printf("Child "); 110 | printf("Permitted: "); 111 | capng_print_caps_text(CAPNG_PRINT_STDOUT, 112 | CAPNG_PERMITTED); 113 | printf("\n"); 114 | if (no_child) 115 | printf("Child "); 116 | printf("Inheritable: "); 117 | capng_print_caps_text(CAPNG_PRINT_STDOUT, 118 | CAPNG_INHERITABLE); 119 | printf("\n"); 120 | if (no_child) 121 | printf("Child "); 122 | printf("Bounding Set: "); 123 | capng_print_caps_text(CAPNG_PRINT_STDOUT, 124 | CAPNG_BOUNDING_SET); 125 | printf("\n"); 126 | if (no_child) 127 | printf("Child "); 128 | printf("Ambient: "); 129 | capng_print_caps_text(CAPNG_PRINT_STDOUT, 130 | CAPNG_AMBIENT); 131 | printf("\n"); 132 | } 133 | } else { 134 | if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE) { 135 | if (no_child) 136 | printf("Child capabilities: none\n"); 137 | else 138 | printf("Current capabilities: none\n"); 139 | } else { 140 | if (no_child) 141 | printf("Child capabilities:\n"); 142 | capng_print_caps_numeric(CAPNG_PRINT_STDOUT, 143 | CAPNG_SELECT_ALL); 144 | } 145 | } 146 | 147 | // Now check securebits flags 148 | #ifdef PR_SET_SECUREBITS 149 | if (no_child) 150 | printf("Child "); 151 | printf("securebits flags: "); 152 | rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NOROOT); 153 | if (rc & (1 << SECURE_NOROOT)) { 154 | printf("NOROOT"); 155 | need_comma = 1; 156 | } 157 | rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NOROOT_LOCKED); 158 | if (rc & (1 << SECURE_NOROOT_LOCKED)) { 159 | if (need_comma) 160 | printf(", "); 161 | printf("NOROOT_LOCKED"); 162 | need_comma = 1; 163 | } 164 | rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP); 165 | if (rc & (1 << SECURE_NO_SETUID_FIXUP)) { 166 | if (need_comma) 167 | printf(", "); 168 | printf("NO_SETUID_FIXUP"); 169 | need_comma = 1; 170 | } 171 | rc = prctl(PR_GET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP_LOCKED); 172 | if (rc & (1 << SECURE_NO_SETUID_FIXUP_LOCKED)) { 173 | if (need_comma) 174 | printf(", "); 175 | printf("NO_SETUID_FIXUP_LOCKED"); 176 | need_comma = 1; 177 | } 178 | if (need_comma == 0) 179 | printf("none"); 180 | printf("\n"); 181 | #endif 182 | // Now do child process checks 183 | if (no_child == 0 || escalated) { 184 | printf("Attempting direct access to shadow..."); 185 | if (access("/etc/shadow", R_OK) == 0) 186 | printf("SUCCESS\n"); 187 | else 188 | printf("FAILED (%s)\n", strerror(errno)); 189 | } 190 | if (no_child == 0) { 191 | printf("Attempting to access shadow by child process..."); 192 | rc = system("cat /etc/shadow > /dev/null 2>&1"); 193 | if (rc == 0) 194 | printf("SUCCESS\n"); 195 | else 196 | printf("FAILED\n"); 197 | if (text) 198 | system("/usr/bin/captest --no-child --text"); 199 | else 200 | system("/usr/bin/captest --no-child"); 201 | } 202 | } 203 | 204 | static void usage(void) 205 | { 206 | printf("usage: captest [ --ambient | --drop-all | --drop-caps | --id | --init-grp ] [ --lock ] [ --text ]\n"); 207 | } 208 | 209 | int main(int argc, char *argv[]) 210 | { 211 | int which = 0, i; 212 | 213 | for (i = 1; i < argc; i++) { 214 | if (strcmp(argv[i], "--text") == 0) 215 | text = 1; 216 | else if (strcmp(argv[i], "--no-child") == 0) 217 | no_child = 1; 218 | else if (strcmp(argv[i], "--lock") == 0) 219 | lock = 1; 220 | else if (strcmp(argv[i], "--drop-all") == 0) 221 | which = 1; 222 | else if (strcmp(argv[i], "--drop-caps") == 0) 223 | which = 2; 224 | else if (strcmp(argv[i], "--id") == 0) 225 | which = 3; 226 | else if (strcmp(argv[i], "--init-grp") == 0) 227 | which = 4; 228 | else if (strcmp(argv[i], "--ambient") == 0) 229 | ambient = 1; 230 | else { 231 | usage(); 232 | return 0; 233 | } 234 | } 235 | switch (which) 236 | { 237 | case 1: 238 | capng_clear(CAPNG_SELECT_ALL); 239 | if (lock) { 240 | if (capng_lock()) { 241 | fprintf(stderr, "capng_lock failed\n"); 242 | return 1; 243 | } 244 | } 245 | if (capng_apply(CAPNG_SELECT_ALL)) { 246 | fprintf(stderr, "capng_apply failed\n"); 247 | return 1; 248 | } 249 | report(); 250 | break; 251 | case 2: 252 | capng_clear(CAPNG_SELECT_CAPS); 253 | if (ambient) 254 | capng_update(CAPNG_ADD, CAPNG_AMBIENT, 255 | CAP_CHOWN); 256 | if (lock) { 257 | if (capng_lock()) { 258 | fprintf(stderr, "capng_lock failed\n"); 259 | return 1; 260 | } 261 | } 262 | if (ambient) { 263 | if (capng_apply( 264 | CAPNG_SELECT_CAPS|CAPNG_SELECT_AMBIENT)) { 265 | fprintf(stderr, "capng_apply failed\n"); 266 | return 1; 267 | } 268 | } else { 269 | if (capng_apply(CAPNG_SELECT_CAPS)) { 270 | fprintf(stderr, "capng_apply failed\n"); 271 | return 1; 272 | } 273 | } 274 | report(); 275 | break; 276 | case 3: 277 | case 4: { 278 | int rc; 279 | 280 | capng_clear(CAPNG_SELECT_BOTH); 281 | capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, 282 | CAP_CHOWN); 283 | if (ambient) 284 | capng_update(CAPNG_ADD, 285 | CAPNG_INHERITABLE|CAPNG_AMBIENT, 286 | CAP_CHOWN); 287 | if (which == 4) 288 | rc = capng_change_id(99, 99, 289 | CAPNG_INIT_SUPP_GRP | CAPNG_CLEAR_BOUNDING); 290 | else 291 | rc = capng_change_id(99, 99, 292 | CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING); 293 | if (rc < 0) { 294 | printf("Error changing uid: %d\n", rc); 295 | capng_print_caps_text(CAPNG_PRINT_STDOUT, 296 | CAPNG_EFFECTIVE); 297 | printf("\n"); 298 | return 1; 299 | } 300 | printf("Keeping CAP_CHOWN to show capabilities across uid change.\n"); 301 | report(); 302 | } break; 303 | case 0: 304 | if (lock) { 305 | if (capng_lock()) { 306 | fprintf(stderr, "capng_lock failed\n"); 307 | return 1; 308 | } 309 | } 310 | report(); 311 | break; 312 | } 313 | return 0; 314 | } 315 | 316 | -------------------------------------------------------------------------------- /utils/filecap.8: -------------------------------------------------------------------------------- 1 | .TH FILECAP: "8" "Aug 2018" "Red Hat" "System Administration Utilities" 2 | .SH NAME 3 | filecap \- a program to see capabilities 4 | .SH SYNOPSIS 5 | .B filecap [ \-a | \-d | /dir | /dir/file [cap1 cap2 ...] ] 6 | .SH DESCRIPTION 7 | \fBfilecap\fP is a program that prints out a report of programs with file based capabilities. If a file is not in the report or there is no report at all, no capabilities were found. For expedience, the default is to check only the directories in the PATH environmental variable. If the \-a command line option is given, then all directories will be checked. If a directory is passed, it will recursively check that directory. If a path to a file is given, it will only check that file. If a file is given followed by capabilities, then the capabilities are written to the file. 8 | 9 | .SH OPTIONS 10 | .TP 11 | .B \-a 12 | This tells the program to show all capabilities starting from the / directory. Normally the PATH environmental variable is used to show you capabilities on files you are likely to execute. 13 | .TP 14 | .B \-d 15 | This dumps all capabilities for reference. 16 | 17 | .SH "EXAMPLES" 18 | .nf 19 | To check file capabilities in $PATH: 20 | .B filecap 21 | 22 | To check file capabilities of whole system: 23 | .B filecap -a 24 | 25 | To check file capabilities recursively in a directory: 26 | .B filecap /usr 27 | 28 | To check file capabilities of a specific program: 29 | .B filecap /bin/passwd 30 | 31 | To list all possible capabilities: 32 | .B filecap -d 33 | 34 | To set a file capability on a specific program: 35 | .B filecap /bin/ping net_raw net_admin 36 | 37 | To remove file capabilities on a specific program: 38 | .B filecap /bin/ping none 39 | .fi 40 | .SH "SEE ALSO" 41 | .BR pscap (8), 42 | .BR netcap (8), 43 | .BR capabilities (7). 44 | 45 | .SH AUTHOR 46 | Steve Grubb 47 | -------------------------------------------------------------------------------- /utils/filecap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * filecap.c - A program that lists running processes with capabilities 3 | * Copyright (c) 2009-10,2012,2017,2020 Red Hat Inc. 4 | * All Rights Reserved. 5 | * 6 | * This software may be freely redistributed and/or modified under the 7 | * terms of the GNU General Public License as published by the Free 8 | * Software Foundation; either version 2, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; see the file COPYING. If not, write to the 18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 19 | * Boston, MA 02110-1335, USA. 20 | * 21 | * Authors: 22 | * Steve Grubb 23 | */ 24 | 25 | #include "config.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "cap-ng.h" 31 | #include 32 | #include 33 | 34 | #ifndef FTW_CONTINUE 35 | #define FTW_CONTINUE 0 36 | #endif 37 | 38 | 39 | static int show_all = 0, header = 0, capabilities = 0, cremove = 0; 40 | static int single_file = 0; 41 | 42 | static void usage(void) 43 | { 44 | fprintf(stderr, 45 | "usage: filecap [-a | -d | /dir | /dir/file [cap1 cap2 ...] ]\n"); 46 | exit(1); 47 | } 48 | 49 | // Returns 1 on error and 0 otherwise 50 | static int check_file(const char *fpath, 51 | const struct stat *sb, 52 | int typeflag_unused __attribute__ ((unused)), 53 | struct FTW *s_unused __attribute__ ((unused))) 54 | { 55 | int ret = FTW_CONTINUE; 56 | 57 | if (S_ISREG(sb->st_mode) == 0) 58 | return ret; 59 | 60 | int fd = open(fpath, O_RDONLY|O_CLOEXEC); 61 | if (fd >= 0) { 62 | capng_results_t rc; 63 | int permitted = 0; 64 | 65 | capng_clear(CAPNG_SELECT_BOTH); 66 | if (capng_get_caps_fd(fd) < 0 && errno != ENODATA) { 67 | fprintf(stderr, 68 | "Unable to get capabilities of %s: %s\n", 69 | fpath, strerror(errno)); 70 | if (single_file) 71 | ret = 1; 72 | } 73 | rc = capng_have_capabilities(CAPNG_SELECT_CAPS); 74 | if (rc == CAPNG_NONE) { 75 | permitted = 1; 76 | rc = capng_have_permitted_capabilities(); 77 | } 78 | if (rc > CAPNG_NONE) { 79 | if (header == 0) { 80 | header = 1; 81 | printf("%-9s %-20s capabilities rootid\n", 82 | "set", "file"); 83 | } 84 | 85 | int rootid = capng_get_rootid(); 86 | printf("%s %s ", 87 | permitted ? "permitted" : "effective", fpath); 88 | 89 | if (rc == CAPNG_FULL) 90 | printf("full"); 91 | else 92 | capng_print_caps_text(CAPNG_PRINT_STDOUT, 93 | CAPNG_PERMITTED); 94 | 95 | if (rootid != CAPNG_UNSET_ROOTID) 96 | printf(" %d", rootid); 97 | printf("\n"); 98 | } 99 | close(fd); 100 | } 101 | return ret; 102 | } 103 | 104 | 105 | // Use cases: 106 | // filecap 107 | // filecap -a 108 | // filecap /path/dir 109 | // filecap /path/file 110 | // filecap /path/file capability1 capability2 capability 3 ... 111 | // 112 | int main(int argc, char *argv[]) 113 | { 114 | #if CAP_LAST_CAP < 31 || !defined (VFS_CAP_U32) || \ 115 | (!defined (HAVE_ATTR_XATTR_H) && !defined(HAVE_SYS_XATTR_H)) 116 | fprintf(stderr, "File based capabilities are not supported\n"); 117 | #else 118 | char *path_env, *path = NULL, *dir = NULL; 119 | struct stat sbuf; 120 | int nftw_flags = FTW_PHYS; 121 | int i, rc = 0; 122 | 123 | if (argc >1) { 124 | for (i=1; i= 0) { 165 | if (path == NULL) 166 | usage(); 167 | capng_update(CAPNG_ADD, 168 | CAPNG_PERMITTED|CAPNG_EFFECTIVE, 169 | cap); 170 | capabilities = 1; 171 | } else if (strcmp("none", argv[i]) == 0) { 172 | capng_clear(CAPNG_SELECT_BOTH); 173 | capabilities = 1; 174 | cremove = 1; 175 | } else { 176 | fprintf(stderr, 177 | "Unrecognized capability.\n"); 178 | usage(); 179 | } 180 | } 181 | } 182 | } 183 | if (path == NULL && dir == NULL && show_all == 0) { 184 | path_env = getenv("PATH"); 185 | if (path_env != NULL) { 186 | path = strdup(path_env); 187 | if (!path) 188 | return 1; 189 | for (dir=strtok(path,":"); dir!=NULL; 190 | dir=strtok(NULL,":")) { 191 | nftw(dir, check_file, 1024, nftw_flags); 192 | } 193 | free(path); 194 | } 195 | } else if (path == NULL && dir == NULL && show_all == 1) { 196 | // Find files 197 | nftw("/", check_file, 1024, nftw_flags); 198 | } else if (dir) { 199 | // Print out the dir 200 | nftw(dir, check_file, 1024, nftw_flags); 201 | }else if (path && capabilities == 0) { 202 | // Print out specific file 203 | single_file = 1; 204 | rc = check_file(path, &sbuf, 0, NULL); 205 | } else if (path && capabilities == 1) { 206 | // Write capabilities to file 207 | int fd = open(path, O_WRONLY|O_NOFOLLOW|O_CLOEXEC); 208 | if (fd < 0) { 209 | fprintf(stderr, 210 | "Could not open %s for writing (%s)\n", path, 211 | strerror(errno)); 212 | return 1; 213 | } 214 | if (capng_apply_caps_fd(fd) < 0) { 215 | fprintf(stderr, 216 | "Could not set capabilities on %s: %s\n", 217 | path, strerror(errno)); 218 | rc = 1; 219 | } 220 | close(fd); 221 | } 222 | #endif 223 | return rc; 224 | } 225 | 226 | -------------------------------------------------------------------------------- /utils/netcap.8: -------------------------------------------------------------------------------- 1 | .TH NETCAP: "8" "Sept 2020" "Red Hat" "System Administration Utilities" 2 | .SH NAME 3 | netcap \- a program to see capabilities 4 | .SH SYNOPSIS 5 | .B netcap 6 | .SH DESCRIPTION 7 | \fBnetcap\fP is a program that prints out a report of process capabilities. If the application is using tcp, udp, raw, or packet family of sockets AND has any capabilities, it will be in the report. If the process has partial capabilities, it is further examined to see if it has an open-ended bounding set. If this is found to be true, a '+' symbol is added. If the process has ambient capabilities, a '@' symbols is added. 8 | 9 | Some directories in the /proc file system are readonly by root. The program will try to access and report what it can. But if nothing comes out, try changing to the root user and re-run this program. 10 | 11 | .SH "SEE ALSO" 12 | .BR pscap (8), 13 | .BR filecap (8), 14 | .BR capabilities (7), 15 | .BR netstat (8). 16 | 17 | .SH AUTHOR 18 | Steve Grubb 19 | -------------------------------------------------------------------------------- /utils/netcap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * netcap.c - A program that lists network apps with capabilities 3 | * Copyright (c) 2009-10,2012,2020 Red Hat Inc. 4 | * All Rights Reserved. 5 | * 6 | * This software may be freely redistributed and/or modified under the 7 | * terms of the GNU General Public License as published by the Free 8 | * Software Foundation; either version 2, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; see the file COPYING. If not, write to the 18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 19 | * Boston, MA 02110-1335, USA. 20 | * 21 | * Authors: 22 | * Steve Grubb 23 | * 24 | * The /proc/net/tcp|udp|raw parsing code was borrowed from netstat.c 25 | */ 26 | 27 | #include "config.h" 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include "cap-ng.h" 37 | #include "proc-llist.h" 38 | 39 | static llist l; 40 | static int perm_warn = 0, header = 0, last_uid = -1; 41 | static char *tacct = NULL; 42 | 43 | static void usage(void) 44 | { 45 | fprintf(stderr, "usage: netcap\n"); 46 | exit(1); 47 | } 48 | 49 | static int collect_process_info(void) 50 | { 51 | DIR *d, *f; 52 | struct dirent *ent; 53 | d = opendir("/proc"); 54 | if (d == NULL) { 55 | fprintf(stderr, "Can't open /proc: %s\n", strerror(errno)); 56 | return 1; 57 | } 58 | while (( ent = readdir(d) )) { 59 | FILE *sf; 60 | int pid, ppid; 61 | capng_results_t caps; 62 | char buf[100]; 63 | char *tmp, cmd[16], state; 64 | char *text = NULL, *bounds = NULL, *ambient = NULL; 65 | int fd, len, euid = -1; 66 | 67 | // Skip non-process dir entries 68 | if(*ent->d_name<'0' || *ent->d_name>'9') 69 | continue; 70 | errno = 0; 71 | pid = strtol(ent->d_name, NULL, 10); 72 | if (errno) 73 | continue; 74 | 75 | // Parse up the stat file for the proc 76 | snprintf(buf, 32, "/proc/%d/stat", pid); 77 | fd = open(buf, O_RDONLY|O_CLOEXEC, 0); 78 | if (fd < 0) 79 | continue; 80 | len = read(fd, buf, sizeof buf - 1); 81 | close(fd); 82 | if (len < 40) 83 | continue; 84 | buf[len] = 0; 85 | tmp = strrchr(buf, ')'); 86 | if (tmp) 87 | *tmp = 0; 88 | else 89 | continue; 90 | memset(cmd, 0, sizeof(cmd)); 91 | sscanf(buf, "%d (%15c", &ppid, cmd); 92 | sscanf(tmp+2, "%c %d", &state, &ppid); 93 | 94 | // Skip kthreads 95 | if (pid == 2 || ppid == 2) 96 | continue; 97 | 98 | // now get the capabilities 99 | capng_clear(CAPNG_SELECT_ALL); 100 | capng_setpid(pid); 101 | if (capng_get_caps_process()) 102 | continue; 103 | caps = capng_have_capabilities(CAPNG_SELECT_CAPS); 104 | if (caps <= CAPNG_NONE) 105 | continue; 106 | if (caps == CAPNG_FULL) { 107 | text = strdup("full"); 108 | if (!text) { 109 | fprintf(stderr, "Out of memory\n"); 110 | continue; 111 | } 112 | } else { 113 | text = capng_print_caps_text(CAPNG_PRINT_BUFFER, 114 | CAPNG_PERMITTED); 115 | if (text == NULL) { 116 | fprintf(stderr, "Out of memory doing pid %d\n", 117 | pid); 118 | continue; 119 | } 120 | } 121 | 122 | // Get the effective uid 123 | snprintf(buf, 32, "/proc/%d/status", pid); 124 | sf = fopen(buf, "rte"); 125 | if (sf == NULL) 126 | euid = 0; 127 | else { 128 | int line = 0; 129 | __fsetlocking(sf, FSETLOCKING_BYCALLER); 130 | while (fgets(buf, sizeof(buf), sf)) { 131 | if (line == 0) { 132 | line++; 133 | continue; 134 | } 135 | if (memcmp(buf, "Uid:", 4) == 0) { 136 | int id; 137 | sscanf(buf, "Uid: %d %d", 138 | &id, &euid); 139 | break; 140 | } 141 | } 142 | fclose(sf); 143 | } 144 | 145 | caps = capng_have_capabilities(CAPNG_SELECT_AMBIENT); 146 | if (caps > CAPNG_NONE) 147 | ambient = strdup("@"); 148 | else 149 | ambient = strdup(""); 150 | if (!ambient) { 151 | fprintf(stderr, "Out of memory\n"); 152 | free(text); 153 | continue; 154 | } 155 | 156 | // Now record the bounding set information 157 | caps = capng_have_capabilities(CAPNG_SELECT_BOUNDS); 158 | if (caps > CAPNG_NONE) 159 | bounds = strdup("+"); 160 | else 161 | bounds = strdup(""); 162 | if (!bounds) { 163 | fprintf(stderr, "Out of memory\n"); 164 | free(text); 165 | free(ambient); 166 | continue; 167 | } 168 | 169 | // Now lets get the inodes each process has open 170 | snprintf(buf, 32, "/proc/%d/fd", pid); 171 | f = opendir(buf); 172 | if (f == NULL) { 173 | if (errno == EACCES) { 174 | if (perm_warn == 0) { 175 | fprintf(stderr, 176 | "You may need to be root to " 177 | "get a full report\n"); 178 | perm_warn = 1; 179 | } 180 | } else 181 | fprintf(stderr, "Can't open %s: %s\n", buf, 182 | strerror(errno)); 183 | free(text); 184 | free(bounds); 185 | free(ambient); 186 | continue; 187 | } 188 | // For each file in the fd dir... 189 | while (( ent = readdir(f) )) { 190 | char line[256], ln[256], *s, *e; 191 | unsigned long inode; 192 | lnode node; 193 | int llen; 194 | 195 | if (ent->d_name[0] == '.') 196 | continue; 197 | snprintf(ln, 256, "%s/%s", buf, ent->d_name); 198 | if ((llen = readlink(ln, line, sizeof(line)-1)) < 0) 199 | continue; 200 | line[llen] = 0; 201 | 202 | // Only look at the socket entries 203 | if (memcmp(line, "socket:", 7) == 0) { 204 | // Type 1 sockets 205 | s = strchr(line+7, '['); 206 | if (s == NULL) 207 | continue; 208 | s++; 209 | e = strchr(s, ']'); 210 | if (e == NULL) 211 | continue; 212 | *e = 0; 213 | } else if (memcmp(line, "[0000]:", 7) == 0) { 214 | // Type 2 sockets 215 | s = line + 8; 216 | } else 217 | continue; 218 | errno = 0; 219 | inode = strtoul(s, NULL, 10); 220 | if (errno) 221 | continue; 222 | node.ppid = ppid; 223 | node.pid = pid; 224 | node.uid = euid; 225 | node.cmd = strdup(cmd); 226 | node.inode = inode; 227 | node.capabilities = strdup(text); 228 | node.bounds = strdup(bounds); 229 | node.ambient = strdup(ambient); 230 | if (node.cmd && node.capabilities && node.bounds && 231 | node.ambient) 232 | // We make one entry for each socket inode 233 | list_append(&l, &node); 234 | else { 235 | free(node.cmd); 236 | free(node.capabilities); 237 | free(node.bounds); 238 | free(node.ambient); 239 | } 240 | } 241 | closedir(f); 242 | free(text); 243 | free(bounds); 244 | free(ambient); 245 | } 246 | closedir(d); 247 | return 0; 248 | } 249 | 250 | static void report_finding(unsigned int port, const char *type, const char *ifc) 251 | { 252 | struct passwd *p; 253 | lnode *n = list_get_cur(&l); 254 | 255 | // And print out anything with capabilities 256 | if (header == 0) { 257 | printf("%-5s %-5s %-10s %-16s %-8s %-6s %s\n", 258 | "ppid", "pid", "acct", "command", "type", "port", 259 | "capabilities"); 260 | header = 1; 261 | } 262 | if (n->uid == 0) { 263 | // Take short cut for this one 264 | tacct = "root"; 265 | last_uid = 0; 266 | } else if (last_uid != (int)n->uid) { 267 | // Only look up if name changed 268 | p = getpwuid(n->uid); 269 | last_uid = n->uid; 270 | if (p) 271 | tacct = p->pw_name; 272 | // If not taking this branch, use last val 273 | } 274 | if (tacct) { 275 | printf("%-5d %-5d %-10s", n->ppid, n->pid, tacct); 276 | } else 277 | printf("%-5d %-5d %-10d", n->ppid, n->pid, last_uid); 278 | printf(" %-16s %-8s", n->cmd, type); 279 | if (ifc) 280 | printf(" %-6s", ifc); 281 | else 282 | printf(" %-6u", port); 283 | printf(" %s %s%s\n", n->capabilities, n->ambient, n->bounds); 284 | } 285 | 286 | static void read_tcp(const char *proc, const char *type) 287 | { 288 | int line = 0; 289 | FILE *f; 290 | char buf[256]; 291 | unsigned long rxq, txq, time_len, retr, inode; 292 | unsigned int local_port, rem_port, state, timer_run; 293 | int d, uid, timeout; 294 | char rem_addr[128], local_addr[128], more[512]; 295 | 296 | f = fopen(proc, "rte"); 297 | if (f == NULL) { 298 | if (errno != ENOENT) 299 | fprintf(stderr, "Can't open %s: %s\n", 300 | proc, strerror(errno)); 301 | return; 302 | } 303 | __fsetlocking(f, FSETLOCKING_BYCALLER); 304 | while (fgets(buf, sizeof(buf), f)) { 305 | if (line == 0) { 306 | line++; 307 | continue; 308 | } 309 | more[0] = 0; 310 | sscanf(buf, "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X " 311 | "%lX:%lX %X:%lX %lX %d %d %lu %511s\n", 312 | &d, local_addr, &local_port, rem_addr, &rem_port, 313 | &state, &txq, &rxq, &timer_run, &time_len, &retr, 314 | &uid, &timeout, &inode, more); 315 | if (list_find_inode(&l, inode)) 316 | report_finding(local_port, type, NULL); 317 | } 318 | fclose(f); 319 | } 320 | 321 | static void read_udp(const char *proc, const char *type) 322 | { 323 | int line = 0; 324 | FILE *f; 325 | char buf[256]; 326 | unsigned long rxq, txq, time_len, retr, inode; 327 | unsigned int local_port, rem_port, state, timer_run; 328 | int d, uid, timeout; 329 | char rem_addr[128], local_addr[128], more[512]; 330 | 331 | f = fopen(proc, "rte"); 332 | if (f == NULL) { 333 | if (errno != ENOENT) 334 | fprintf(stderr, "Can't open %s: %s\n", 335 | proc, strerror(errno)); 336 | return; 337 | } 338 | __fsetlocking(f, FSETLOCKING_BYCALLER); 339 | while (fgets(buf, sizeof(buf), f)) { 340 | if (line == 0) { 341 | line++; 342 | continue; 343 | } 344 | more[0] = 0; 345 | sscanf(buf, "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X " 346 | "%lX:%lX %X:%lX %lX %d %d %lu %511s\n", 347 | &d, local_addr, &local_port, rem_addr, &rem_port, 348 | &state, &txq, &rxq, &timer_run, &time_len, &retr, 349 | &uid, &timeout, &inode, more); 350 | if (list_find_inode(&l, inode)) 351 | report_finding(local_port, type, NULL); 352 | } 353 | fclose(f); 354 | } 355 | 356 | static void read_raw(const char *proc, const char *type) 357 | { 358 | int line = 0; 359 | FILE *f; 360 | char buf[256]; 361 | unsigned long rxq, txq, time_len, retr, inode; 362 | unsigned int local_port, rem_port, state, timer_run; 363 | int d, uid, timeout; 364 | char rem_addr[128], local_addr[128], more[512]; 365 | 366 | f = fopen(proc, "rte"); 367 | if (f == NULL) { 368 | if (errno != ENOENT) 369 | fprintf(stderr, "Can't open %s: %s\n", 370 | proc, strerror(errno)); 371 | return; 372 | } 373 | __fsetlocking(f, FSETLOCKING_BYCALLER); 374 | while (fgets(buf, sizeof(buf), f)) { 375 | if (line == 0) { 376 | line++; 377 | continue; 378 | } 379 | more[0] = 0; 380 | sscanf(buf, "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X " 381 | "%lX:%lX %X:%lX %lX %d %d %lu %511s\n", 382 | &d, local_addr, &local_port, rem_addr, &rem_port, 383 | &state, &txq, &rxq, &timer_run, &time_len, &retr, 384 | &uid, &timeout, &inode, more); 385 | if (list_find_inode(&l, inode)) 386 | report_finding(0, type, NULL); 387 | } 388 | fclose(f); 389 | } 390 | 391 | // Caller must have buffer > 16 bytes 392 | static void get_interface(unsigned int iface, char *ifc) 393 | { 394 | unsigned int line = 0; 395 | FILE *f; 396 | char buf[256], more[256]; 397 | 398 | // Terminate the interface in case of error 399 | *ifc = 0; 400 | 401 | // Increment the interface number since header is 2 lines long 402 | iface++; 403 | 404 | f = fopen("/proc/net/dev", "rte"); 405 | if (f == NULL) { 406 | if (errno != ENOENT) 407 | fprintf(stderr, "Can't open /proc/net/dev: %s\n", 408 | strerror(errno)); 409 | return; 410 | } 411 | __fsetlocking(f, FSETLOCKING_BYCALLER); 412 | while (fgets(buf, sizeof(buf), f)) { 413 | if (line == iface) { 414 | char *c; 415 | sscanf(buf, "%16s: %255s\n", ifc, more); 416 | c = strchr(ifc, ':'); 417 | if (c) 418 | *c = 0; 419 | fclose(f); 420 | return; 421 | } 422 | line++; 423 | } 424 | fclose(f); 425 | } 426 | 427 | static void read_packet(void) 428 | { 429 | int line = 0; 430 | FILE *f; 431 | char buf[256]; 432 | unsigned long sk, inode; 433 | unsigned int ref_cnt, type, proto, iface, r, rmem, uid; 434 | char more[256], ifc[32]; 435 | 436 | f = fopen("/proc/net/packet", "rte"); 437 | if (f == NULL) { 438 | if (errno != ENOENT) 439 | fprintf(stderr, "Can't open /proc/net/packet: %s\n", 440 | strerror(errno)); 441 | return; 442 | } 443 | __fsetlocking(f, FSETLOCKING_BYCALLER); 444 | while (fgets(buf, sizeof(buf), f)) { 445 | if (line == 0) { 446 | line++; 447 | continue; 448 | } 449 | more[0] = 0; 450 | sscanf(buf, "%lX %u %u %X %u %u %u %u %lu %255s\n", 451 | &sk, &ref_cnt, &type, &proto, &iface, 452 | &r, &rmem, &uid, &inode, more); 453 | get_interface(iface, ifc); 454 | if (list_find_inode(&l, inode)) 455 | report_finding(0, "pkt", ifc); 456 | } 457 | fclose(f); 458 | } 459 | 460 | int main(int argc, char __attribute__((unused)) *argv[]) 461 | { 462 | if (argc > 1) { 463 | fputs("Too many arguments\n", stderr); 464 | usage(); 465 | } 466 | 467 | list_create(&l); 468 | collect_process_info(); 469 | 470 | // Now we check the tcp socket list... 471 | read_tcp("/proc/net/tcp", "tcp"); 472 | read_tcp("/proc/net/tcp6", "tcp6"); 473 | 474 | // Next udp sockets... 475 | read_udp("/proc/net/udp", "udp"); 476 | read_udp("/proc/net/udp6", "udp6"); 477 | read_udp("/proc/net/udplite", "udplite"); 478 | read_udp("/proc/net/udplite6", "udplite6"); 479 | 480 | // Next, raw sockets... 481 | read_raw("/proc/net/raw", "raw"); 482 | read_raw("/proc/net/raw6", "raw6"); 483 | 484 | // And last, read packet sockets 485 | read_packet(); 486 | 487 | // Could also do icmp,netlink,unix 488 | 489 | list_clear(&l); 490 | return 0; 491 | } 492 | 493 | -------------------------------------------------------------------------------- /utils/proc-llist.c: -------------------------------------------------------------------------------- 1 | /* 2 | * proc-llist.c - Minimal linked list library 3 | * Copyright (c) 2009, 2020 Red Hat Inc. 4 | * All Rights Reserved. 5 | * 6 | * This software may be freely redistributed and/or modified under the 7 | * terms of the GNU General Public License as published by the Free 8 | * Software Foundation; either version 2, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; see the file COPYING. If not, write to the 18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 19 | * Boston, MA 02110-1335, USA. 20 | * 21 | * Authors: 22 | * Steve Grubb 23 | */ 24 | 25 | #include "config.h" 26 | #include 27 | #include 28 | #include "proc-llist.h" 29 | 30 | void list_create(llist *l) 31 | { 32 | l->head = NULL; 33 | l->cur = NULL; 34 | l->cnt = 0; 35 | } 36 | 37 | void list_append(llist *l, lnode *node) 38 | { 39 | lnode* newnode; 40 | 41 | if (node == NULL || l == NULL) 42 | return; 43 | 44 | newnode = malloc(sizeof(lnode)); 45 | if (newnode == NULL) 46 | return; 47 | 48 | newnode->ppid = node->ppid; 49 | newnode->pid = node->pid; 50 | newnode->uid = node->uid; 51 | newnode->inode = node->inode; 52 | // Take custody of the memory 53 | newnode->cmd = node->cmd; 54 | newnode->capabilities = node->capabilities; 55 | newnode->bounds = node->bounds; 56 | newnode->ambient = node->ambient; 57 | newnode->next = NULL; 58 | 59 | // if we are at top, fix this up 60 | if (l->head == NULL) 61 | l->head = newnode; 62 | else // Otherwise add pointer to newnode 63 | l->cur->next = newnode; 64 | 65 | // make newnode current 66 | l->cur = newnode; 67 | l->cnt++; 68 | } 69 | 70 | void list_clear(llist* l) 71 | { 72 | lnode* nextnode; 73 | register lnode* cur; 74 | 75 | cur = l->head; 76 | while (cur) { 77 | nextnode=cur->next; 78 | free(cur->cmd); 79 | free(cur->capabilities); 80 | free(cur->bounds); 81 | free(cur->ambient); 82 | free(cur); 83 | cur=nextnode; 84 | } 85 | l->head = NULL; 86 | l->cur = NULL; 87 | l->cnt = 0; 88 | } 89 | 90 | lnode *list_find_inode(llist *l, unsigned long i) 91 | { 92 | register lnode* cur; 93 | 94 | cur = l->head; /* start at the beginning */ 95 | while (cur) { 96 | if (cur->inode == i) { 97 | l->cur = cur; 98 | return cur; 99 | } else 100 | cur = cur->next; 101 | } 102 | return NULL; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /utils/proc-llist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * proc-llist.h 3 | * Copyright (c) 2009, 2020 Red Hat Inc. 4 | * All Rights Reserved. 5 | * 6 | * This software may be freely redistributed and/or modified under the 7 | * terms of the GNU General Public License as published by the Free 8 | * Software Foundation; either version 2, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; see the file COPYING. If not, write to the 18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 19 | * Boston, MA 02110-1335, USA. 20 | * 21 | * Authors: 22 | * Steve Grubb 23 | */ 24 | 25 | #ifndef PROC_HEADER 26 | #define PROC_HEADER 27 | 28 | #include "config.h" 29 | #include /* Ensure types in _lnode are defined on all systems */ 30 | 31 | 32 | /* This is the node of the linked list. Any data elements that are per 33 | * record goes here. */ 34 | typedef struct _lnode{ 35 | pid_t ppid; // parent process ID 36 | pid_t pid; // process ID 37 | uid_t uid; // user ID 38 | char *cmd; // command run by user 39 | unsigned long inode; // inode of socket 40 | char *capabilities; // Text of partial capabilities 41 | char *bounds; // Text for bounding set 42 | char *ambient; // Text for ambient set 43 | struct _lnode* next; // Next node pointer 44 | } lnode; 45 | 46 | /* This is the linked list head. Only data elements that are 1 per 47 | * event goes here. */ 48 | typedef struct { 49 | lnode *head; // List head 50 | lnode *cur; // Pointer to current node 51 | unsigned int cnt; // How many items in this list 52 | } llist; 53 | 54 | void list_create(llist *l); 55 | static inline lnode *list_get_cur(llist *l) { return l->cur; } 56 | void list_append(llist *l, lnode *node); 57 | void list_clear(llist* l); 58 | 59 | /* Given a message type, find the matching node */ 60 | lnode *list_find_inode(llist *l, unsigned long i); 61 | 62 | #endif 63 | 64 | -------------------------------------------------------------------------------- /utils/pscap.8: -------------------------------------------------------------------------------- 1 | .TH PSCAP: "8" "Sept 2020" "Red Hat" "System Administration Utilities" 2 | .SH NAME 3 | pscap \- a program to see capabilities 4 | .SH SYNOPSIS 5 | .B pscap [ \-a | \-p pid ] 6 | .SH DESCRIPTION 7 | \fBpscap\fP is a program that prints out a report of process capabilities. If the application has any capabilities, it will be in the report with the exception of init. By giving the \-a command line option, init will be included, too. By giving a pid with the \-p command line option, only the process specified with the pid is reported. If a process is not in the report, it has dropped all capabilities. If the process has partial capabilities, it is further examined to see if it has an open-ended bounding set. If this is found to be true, a '+' symbol is added. If the process has ambient capabilities, a '@' symbols is added. 8 | 9 | The command name in the output may be followed by an asterisk mark (*). This mark denotes processes which run in child user namespaces (relative to the user namespace of pscap itself). 10 | 11 | .SH "SEE ALSO" 12 | .BR netcap (8), 13 | .BR filecap (8), 14 | .BR capabilities (7), 15 | .BR ps (8). 16 | 17 | .SH AUTHOR 18 | Steve Grubb 19 | -------------------------------------------------------------------------------- /utils/pscap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pscap.c - A program that lists running processes with capabilities 3 | * Copyright (c) 2009,2012,2020 Red Hat Inc. 4 | * All Rights Reserved. 5 | * 6 | * This software may be freely redistributed and/or modified under the 7 | * terms of the GNU General Public License as published by the Free 8 | * Software Foundation; either version 2, or (at your option) any 9 | * later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; see the file COPYING. If not, write to the 18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor 19 | * Boston, MA 02110-1335, USA. 20 | * 21 | * Authors: 22 | * Steve Grubb 23 | */ 24 | 25 | #include "config.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "cap-ng.h" 38 | 39 | #define CMD_LEN 16 40 | #define USERNS_MARK_LEN 2 41 | 42 | static void usage(void) 43 | { 44 | fprintf(stderr, "usage: pscap [-a|-p pid]\n"); 45 | exit(1); 46 | } 47 | 48 | /* 49 | * Precise recursive checks for parent-child relation between namespaces 50 | * using ioctl() were avoided, because there didn't seem to be any case when 51 | * we may dereference the namespace symlink in /proc/PID/ns for processes in 52 | * user namespaces other than the current or child ones. Thus, the check just 53 | * tries to dereference the link and checks that it does not point to the 54 | * current NS. 55 | */ 56 | static bool in_child_userns(int pid) 57 | { 58 | char ns_file_path[32]; 59 | struct stat statbuf; 60 | ino_t own_ns_inode; 61 | dev_t own_ns_dev; 62 | 63 | if (stat("/proc/self/ns/user", &statbuf) < 0) 64 | return false; 65 | 66 | own_ns_inode = statbuf.st_ino; 67 | own_ns_dev = statbuf.st_dev; 68 | 69 | snprintf(ns_file_path, 32, "/proc/%d/ns/user", pid); 70 | if (stat(ns_file_path, &statbuf) < 0) 71 | return false; 72 | 73 | return statbuf.st_ino != own_ns_inode || statbuf.st_dev != own_ns_dev; 74 | } 75 | 76 | int main(int argc, char *argv[]) 77 | { 78 | char *endptr = NULL; 79 | DIR *d; 80 | struct dirent *ent; 81 | int header = 0, show_all = 0, caps; 82 | pid_t our_pid = getpid(); 83 | pid_t target_pid = 0; 84 | 85 | if (argc > 3) { 86 | fputs("Too many arguments\n", stderr); 87 | usage(); 88 | } 89 | if (argc == 2) { 90 | if (strcmp(argv[1], "-a") == 0) 91 | show_all = 1; 92 | else 93 | usage(); 94 | } 95 | else if (argc == 3) { 96 | if (strcmp(argv[1], "-p") == 0) { 97 | errno = 0; 98 | target_pid = strtol(argv[2], &endptr, 10); 99 | if (errno) { 100 | fprintf(stderr, "Can't read pid: %s\n", argv[2]); 101 | return 1; 102 | } 103 | if ((endptr == argv[2]) || (*endptr != '\0') || !target_pid) { 104 | fprintf(stderr, "Invalid pid argument: %s\n", argv[2]); 105 | return 1; 106 | } 107 | if (target_pid == 1) 108 | show_all = 1; 109 | } else 110 | usage(); 111 | } 112 | 113 | d = opendir("/proc"); 114 | if (d == NULL) { 115 | fprintf(stderr, "Can't open /proc: %s\n", strerror(errno)); 116 | return 1; 117 | } 118 | while (( ent = readdir(d) )) { 119 | int pid, ppid, uid = -1, euid = -1; 120 | char buf[100]; 121 | char *tmp, cmd[CMD_LEN + USERNS_MARK_LEN], state, *name = NULL; 122 | int fd, len; 123 | struct passwd *p; 124 | 125 | // Skip non-process dir entries 126 | if(*ent->d_name<'0' || *ent->d_name>'9') 127 | continue; 128 | errno = 0; 129 | pid = strtol(ent->d_name, NULL, 10); 130 | if (errno) 131 | continue; 132 | 133 | if (target_pid && (pid != target_pid)) 134 | continue; 135 | 136 | /* Skip our pid so we aren't listed */ 137 | if (pid == our_pid) 138 | continue; 139 | 140 | // Parse up the stat file for the proc 141 | snprintf(buf, 32, "/proc/%d/stat", pid); 142 | fd = open(buf, O_RDONLY|O_CLOEXEC, 0); 143 | if (fd < 0) 144 | continue; 145 | len = read(fd, buf, sizeof buf - 1); 146 | close(fd); 147 | if (len < 40) 148 | continue; 149 | buf[len] = 0; 150 | tmp = strrchr(buf, ')'); 151 | if (tmp) 152 | *tmp = 0; 153 | else 154 | continue; 155 | memset(cmd, 0, sizeof(cmd)); 156 | sscanf(buf, "%d (%15c", &ppid, cmd); 157 | sscanf(tmp+2, "%c %d", &state, &ppid); 158 | 159 | // Skip kthreads 160 | if (pid == 2 || ppid == 2) 161 | continue; 162 | 163 | if (!show_all && pid == 1) 164 | continue; 165 | 166 | // now get the capabilities 167 | capng_clear(CAPNG_SELECT_ALL); 168 | capng_setpid(pid); 169 | if (capng_get_caps_process()) 170 | continue; 171 | 172 | // And print out anything with capabilities 173 | caps = capng_have_capabilities(CAPNG_SELECT_CAPS); 174 | if (caps > CAPNG_NONE) { 175 | // Get the effective uid 176 | FILE *f; 177 | int line; 178 | snprintf(buf, 32, "/proc/%d/status", pid); 179 | f = fopen(buf, "rte"); 180 | if (f == NULL) 181 | euid = 0; 182 | else { 183 | line = 0; 184 | __fsetlocking(f, FSETLOCKING_BYCALLER); 185 | while (fgets(buf, sizeof(buf), f)) { 186 | if (line == 0) { 187 | line++; 188 | continue; 189 | } 190 | if (memcmp(buf, "Uid:", 4) == 0) { 191 | int id; 192 | sscanf(buf, "Uid: %d %d", 193 | &id, &euid); 194 | break; 195 | } 196 | } 197 | fclose(f); 198 | } 199 | 200 | if (header == 0) { 201 | printf("%-5s %-5s %-10s %-18s %s\n", 202 | "ppid", "pid", "uid", "command", 203 | "capabilities"); 204 | header = 1; 205 | } 206 | if (euid == 0) { 207 | // Take short cut for this one 208 | name = "root"; 209 | uid = 0; 210 | } else if (euid != uid) { 211 | // Only look up if name changed 212 | p = getpwuid(euid); 213 | uid = euid; 214 | if (p) 215 | name = p->pw_name; 216 | // If not taking this branch, use last val 217 | } 218 | 219 | if (in_child_userns(pid)) 220 | strcat(cmd, " *"); 221 | 222 | if (name) { 223 | printf("%-5d %-5d %-10s %-18s ", ppid, pid, 224 | name, cmd); 225 | } else 226 | printf("%-5d %-5d %-10d %-18s ", ppid, pid, 227 | uid, cmd); 228 | if (caps == CAPNG_PARTIAL) { 229 | capng_print_caps_text(CAPNG_PRINT_STDOUT, 230 | CAPNG_PERMITTED); 231 | if (capng_have_capabilities( 232 | CAPNG_SELECT_AMBIENT) > CAPNG_NONE) 233 | printf(" @"); 234 | if (capng_have_capabilities(CAPNG_SELECT_BOUNDS) 235 | > CAPNG_NONE) 236 | printf(" +"); 237 | printf("\n"); 238 | } else { 239 | printf("full"); 240 | if (capng_have_capabilities( 241 | CAPNG_SELECT_AMBIENT) > CAPNG_NONE) 242 | printf(" @"); 243 | if (capng_have_capabilities(CAPNG_SELECT_BOUNDS) 244 | > CAPNG_NONE) 245 | printf(" +"); 246 | printf("\n"); 247 | } 248 | } 249 | } 250 | closedir(d); 251 | return 0; 252 | } 253 | 254 | 255 | --------------------------------------------------------------------------------