diff options
author | David Zeuthen <davidz@redhat.com> | 2008-11-06 10:43:38 -0500 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2008-11-06 10:43:38 -0500 |
commit | aa1660ad22141b4db12f054233f0fae976a948e9 (patch) | |
tree | 8ae5b1bc8eb9d19189266a943c73955c2bcfc1bd | |
download | polkit-aa1660ad22141b4db12f054233f0fae976a948e9.tar.gz |
initial commit
51 files changed, 5520 insertions, 0 deletions
@@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307 USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! @@ -0,0 +1 @@ +Write me diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..66b86d7 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = data src docs po + +NULL = + +EXTRA_DIST = \ + HACKING \ + mkinstalldirs \ + $(NULL) + +# xsltproc barfs on 'make distcheck'; disable for now +DISTCHECK_CONFIGURE_FLAGS=--disable-man-pages --disable-gtk-doc + +clean-local : + rm -f *~ diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..362cc32 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,95 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +DIE=0 + +(test -f $srcdir/configure.ac) || { + echo -n "**Error**: Directory $srcdir does not look like the" + echo " top-level package directory" + exit 1 +} + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have autoconf installed." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && { + (libtool --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have libtool installed." + echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" + DIE=1 + } +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have automake installed." + echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" + DIE=1 + NO_AUTOMAKE=yes +} + + +# if no automake, don't bother testing for aclocal +test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: Missing aclocal. The version of automake" + echo "installed doesn't appear recent enough." + echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +if test -z "$*"; then + echo "**Warning**: I am going to run configure with no arguments." + echo "If you wish to pass any to it, please specify them on the" + echo $0 " command line." + echo +fi + +case $CC in +xlc ) + am_opt=--include-deps;; +esac + + aclocalinclude="$ACLOCAL_FLAGS" + + if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then + if test -z "$NO_LIBTOOLIZE" ; then + echo "Running libtoolize..." + libtoolize --force --copy + fi + fi + echo "Running aclocal $aclocalinclude ..." + aclocal $aclocalinclude + if grep "^AM_CONFIG_HEADER" configure.ac >/dev/null; then + echo "Running autoheader..." + autoheader + fi + echo "Running automake --gnu -Wno-portability $am_opt ..." + automake --add-missing --gnu -Wno-portability $am_opt + echo "Running autoconf ..." + autoconf + +intltoolize --copy --force --automake || exit 1 + +conf_flags="--enable-maintainer-mode --enable-gtk-doc" + +if test x$NOCONFIGURE = x; then + echo "Running $srcdir/configure $conf_flags $@ ..." + $srcdir/configure $conf_flags "$@" \ + && echo "Now type make to compile." || exit 1 +else + echo "Skipping configure process." +fi diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..4882377 --- /dev/null +++ b/configure.ac @@ -0,0 +1,204 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59c) +AC_INIT(polkit, 0.90, http://lists.freedesktop.org/mailman/listinfo/polkit-devel) +AM_INIT_AUTOMAKE(polkit, 0.90) +AM_CONFIG_HEADER(config.h) +AM_MAINTAINER_MODE + +# libtool versioning - this applies to all libraries in this package +# +# See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details +# +LT_CURRENT=0 +LT_REVISION=0 +LT_AGE=0 +AC_SUBST(LT_CURRENT) +AC_SUBST(LT_REVISION) +AC_SUBST(LT_AGE) + +AC_ISC_POSIX +AC_PROG_CC +AM_PROG_CC_STDC +AC_HEADER_STDC +AM_PROG_LIBTOOL +AC_PROG_MAKE_SET +AC_PROG_LN_S +AC_SYS_LARGEFILE +AM_PROG_CC_C_O + +# Taken from dbus +AC_ARG_ENABLE(ansi, [ --enable-ansi enable -ansi -pedantic gcc flags],enable_ansi=$enableval,enable_ansi=no) +AC_ARG_ENABLE(verbose-mode, [ --enable-verbose-mode support verbose debug mode],enable_verbose_mode=$enableval,enable_verbose_mode=$USE_MAINTAINER_MODE) +AC_ARG_ENABLE(man-pages, [ --enable-man-pages build manual pages],enable_man_pages=$enableval,enable_man_pages=yes) + +if test "${enable_man_page}" != no; then +dnl +dnl Check for xsltproc +dnl +AC_PATH_PROG([XSLTPROC], [xsltproc]) + if test -z "$XSLTPROC"; then + enable_man_pages=no + fi +fi +AM_CONDITIONAL(MAN_PAGES_ENABLED, test x$enable_man_pages = xyes) + +GTK_DOC_CHECK([1.3]) + +#### gcc warning flags + +if test "x$GCC" = "xyes"; then + changequote(,)dnl + case " $CFLAGS " in + *[\ \ ]-Wall[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wall" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-Wchar-subscripts[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wchar-subscripts" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-Wmissing-declarations[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wmissing-declarations" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-Wnested-externs[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wnested-externs" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-Wpointer-arith[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wpointer-arith" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-Wcast-align[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wcast-align" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-Wsign-compare[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wsign-compare" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-Wformat[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wformat" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-Wformat-security[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wformat-security" ;; + esac + + if test "x$enable_ansi" = "xyes"; then + case " $CFLAGS " in + *[\ \ ]-ansi[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -ansi" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-D_POSIX_C_SOURCE*) ;; + *) CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=199309L" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-D_BSD_SOURCE[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -D_BSD_SOURCE" ;; + esac + + case " $CFLAGS " in + *[\ \ ]-pedantic[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -pedantic" ;; + esac + fi + changequote([,])dnl +fi + +PKG_CHECK_MODULES(GLIB, [gio-2.0 >= 2.14.0]) +AC_SUBST(GIO_CFLAGS) +AC_SUBST(GIO_LIBS) + +PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.14.0 gio-2.0 >= 2.14.0]) +AC_SUBST(GLIB_CFLAGS) +AC_SUBST(GLIB_LIBS) + +PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.0]) +AC_SUBST(DBUS_CFLAGS) +AC_SUBST(DBUS_LIBS) + +PKG_CHECK_MODULES(DBUS_GLIB, [dbus-glib-1 >= 0.73]) +AC_SUBST(DBUS_GLIB_CFLAGS) +AC_SUBST(DBUS_GLIB_LIBS) + +EXPAT_LIB="" +AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here], + [ + expat=$withval + CPPFLAGS="$CPPFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + ] + ) +AC_CHECK_HEADERS(expat.h, [AC_DEFINE(HAVE_EXPAT_H)], + [AC_MSG_ERROR([Can't find expat.h. Please install expat.])]) +AC_CHECK_LIB(expat,XML_ParserCreate,[EXPAT_LIBS="-lexpat"], + [AC_MSG_ERROR([Can't find expat library. Please install expat.])]) +AC_SUBST(EXPAT_LIBS) + +if test "x$GCC" = "xyes"; then + LDFLAGS="-Wl,--as-needed $LDFLAGS" +fi + +# ******************** +# Internationalisation +# ******************** + +IT_PROG_INTLTOOL([0.40.0]) +GETTEXT_PACKAGE=polkit +AC_SUBST([GETTEXT_PACKAGE]) +AM_GLIB_GNU_GETTEXT +AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[gettext domain]) + +AC_OUTPUT([ +Makefile +data/Makefile +src/Makefile +src/polkit/Makefile +src/polkitd/Makefile +src/programs/Makefile +docs/version.xml +docs/Makefile +docs/man/Makefile +po/Makefile.in +]) + +dnl ========================================================================== +echo " + polkit $VERSION + ================= + + prefix: ${prefix} + libdir: ${libdir} + libexecdir: ${libexecdir} + bindir: ${bindir} + sbindir: ${sbindir} + datadir: ${datadir} + sysconfdir: ${sysconfdir} + localstatedir: ${localstatedir} + docdir: ${docdir} + + compiler: ${CC} + cflags: ${CFLAGS} + cppflags: ${CPPFLAGS} + xsltproc: ${XSLTPROC} + + Maintainer mode: ${USE_MAINTAINER_MODE} + Building unit tests: ${enable_tests} + GCC coverage profiling: ${enable_gcov} + Building verbose mode: ${enable_verbose_mode} + Building api docs: ${enable_gtk_doc} + Building man pages: ${enable_man_pages} +" diff --git a/data/Makefile.am b/data/Makefile.am new file mode 100644 index 0000000..319217b --- /dev/null +++ b/data/Makefile.am @@ -0,0 +1,22 @@ +## Process this file with automake to produce Makefile.in + +servicedir = $(datadir)/dbus-1/system-services +service_in_files = org.freedesktop.PolicyKit1.service.in +service_DATA = $(service_in_files:.service.in=.service) + +$(service_DATA): $(service_in_files) Makefile + @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ + +dbusconfdir = $(sysconfdir)/dbus-1/system.d +dbusconf_in_files = org.freedesktop.PolicyKit1.conf.in +dbusconf_DATA = $(dbusconf_in_files:.conf.in=.conf) + +$(dbusconf_DATA): $(dbusconf_in_files) Makefile + @sed -e "s|\@polkituser\@|$(POLKIT_USER)|" $< > $@ + +CLEANFILES = $(BUILT_SOURCES) + +EXTRA_DIST = org.freedesktop.PolicyKit1.Authority.xml $(service_in_files) $(dbusconf_in_files) + +clean-local : + rm -f *~ $(service_DATA) $(dbusconf_DATA) diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml new file mode 100644 index 0000000..dbd5b4c --- /dev/null +++ b/data/org.freedesktop.PolicyKit1.Authority.xml @@ -0,0 +1,19 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/"> + + <interface name="org.freedesktop.PolicyKit1.Authority"> + + <method name="SayHello"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="message" direction="in" type="s"/> + <arg name="result" direction="out" type="s"/> + </method> + + <method name="CheckClaims"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="claims" direction="in" type="a(ssa{ss})"/> + <arg name="result" direction="out" type="s"/> + </method> + + </interface> +</node> diff --git a/data/org.freedesktop.PolicyKit1.conf.in b/data/org.freedesktop.PolicyKit1.conf.in new file mode 100644 index 0000000..ad602a7 --- /dev/null +++ b/data/org.freedesktop.PolicyKit1.conf.in @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- --> + +<!DOCTYPE busconfig PUBLIC + "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <policy user="root"> + <allow own="org.freedesktop.PolicyKit1"/> + </policy> +</busconfig> diff --git a/data/org.freedesktop.PolicyKit1.service.in b/data/org.freedesktop.PolicyKit1.service.in new file mode 100644 index 0000000..09abeed --- /dev/null +++ b/data/org.freedesktop.PolicyKit1.service.in @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.freedesktop.PolicyKit1 +Exec=@libexecdir@/polkitd-1 +User=root diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 0000000..b647ac9 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,76 @@ + +SUBDIRS = man + +NULL = + +AUTOMAKE_OPTIONS = 1.7 + +# The name of the module. +DOC_MODULE=polkit + +# The top-level SGML file. +DOC_MAIN_SGML_FILE=polkit-docs.xml + +# Extra options to supply to gtkdoc-scan +SCAN_OPTIONS=--ignore-headers=config.h + +# The directory containing the source code. Relative to $(srcdir) +DOC_SOURCE_DIR=../src/polkit + +# Used for dependencies +HFILE_GLOB=$(top_srcdir)/src/polkit/*.h +CFILE_GLOB=$(top_srcdir)/src/polkit/*.c + +# Headers to ignore +IGNORE_HFILES= \ + $(NULL) + +# CFLAGS and LDFLAGS for compiling scan program. Only needed +# if $(DOC_MODULE).types is non-empty. +INCLUDES = \ + $(DBUS_GLIB_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GIO_CFLAGS) \ + -I$(top_srcdir)/src/polkit \ + -I$(top_builddir)/src/polkit \ + $(NULL) + +GTKDOC_LIBS = \ + $(DBUS_GLIB_LIBS) \ + $(GLIB_LIBS) \ + $(GIO_LIBS) \ + $(top_builddir)/src/polkit/libpolkit-gobject-1.la \ + $(NULL) + +# Extra options to supply to gtkdoc-mkdb +MKDB_OPTIONS=--sgml-mode --output-format=xml + +# Extra options to supply to gtkdoc-mktmpl +MKTMPL_OPTIONS= + +# Non-autogenerated SGML files to be included in $(DOC_MAIN_SGML_FILE) +content_files = \ + version.xml \ + $(NULL) + +# Images to copy into HTML directory +HTML_IMAGES = \ + $(NULL) + +# Extra options to supply to gtkdoc-fixref +FIXXREF_OPTIONS= + +MAINTAINERCLEANFILES = \ + *~ \ + Makefile.in \ + polkit.types \ + polkit-*.txt \ + $(NULL) + +if ENABLE_GTK_DOC +include $(top_srcdir)/gtk-doc.make +else +EXTRA_DIST = +endif + +EXTRA_DIST += version.xml.in diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am new file mode 100644 index 0000000..a61a882 --- /dev/null +++ b/docs/man/Makefile.am @@ -0,0 +1,18 @@ + +NULL = + +if MAN_PAGES_ENABLED + +man_MANS = PolicyKit-1.8 \ + $(NULL) + +%-1.8 : %.xml + $(XSLTPROC) -nonet http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + +endif # MAN_PAGES_ENABLED + +EXTRA_DIST= PolicyKit.xml \ + $(NULL) + +clean-local: + rm -f *~ *.8 diff --git a/docs/man/PolicyKit.xml b/docs/man/PolicyKit.xml new file mode 100644 index 0000000..6cb9145 --- /dev/null +++ b/docs/man/PolicyKit.xml @@ -0,0 +1,60 @@ +<refentry id="PolicyKit-1.8"> + <refentryinfo> + <title>PolicyKit-1</title> + <date>August 2007</date> + <productname>PolicyKit-1</productname> + </refentryinfo> + + <refmeta> + <refentrytitle>PolicyKit-1</refentrytitle> + <manvolnum>8</manvolnum> + <refmiscinfo class="version"></refmiscinfo> + </refmeta> + + <refnamediv> + <refname>PolicyKit-1</refname> + <refpurpose>Authorization API</refpurpose> + </refnamediv> + + <refsect1><title>DESCRIPTION</title> + <para> + For more information about the big picture refer to the + PolicyKit specification which can be normally be found + under <filename>/usr/share/doc</filename>. + </para> + + <para> + <emphasis>TODO:</emphasis> This manual page should contain a + simple introduction to PolicyKit for a system administrator + audience. Remains to be written. + </para> + </refsect1> + + + <refsect1><title>AUTHOR</title> + <para> + Written by David Zeuthen <email>david@fubar.dk</email> with + a lot of help from many others. + </para> + </refsect1> + + <refsect1> + <title>BUGS</title> + <para> + Please send bug reports to either the distribution or the + polkit-devel mailing list, + see <ulink url="http://lists.freedesktop.org/mailman/listinfo/polkit-devel"/>. + to subscribe. + </para> + </refsect1> + + <refsect1> + <title>SEE ALSO</title> + <para> + <citerefentry> + <refentrytitle>polkit-adm-1</refentrytitle><manvolnum>1</manvolnum> + </citerefentry> + </para> + </refsect1> +</refentry> + diff --git a/docs/polkit-docs.xml b/docs/polkit-docs.xml new file mode 100644 index 0000000..565bfe0 --- /dev/null +++ b/docs/polkit-docs.xml @@ -0,0 +1,99 @@ +<?xml version="1.0"?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ +<!ENTITY version SYSTEM "version.xml"> +]> +<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude"> + <bookinfo> + <title>PolicyKit Reference Manual</title> + <releaseinfo>Version &version;</releaseinfo> + <authorgroup> + <author> + <firstname>David</firstname> + <surname>Zeuthen</surname> + <affiliation> + <address> + <email>davidz@redhat.com</email> + </address> + </affiliation> + </author> + </authorgroup> + + <copyright> + <year>2008</year> + <holder>The PolicyKit Authors</holder> + </copyright> + + <legalnotice> + <para> + Permission is granted to copy, distribute and/or modify this + document under the terms of the <citetitle>GNU Free + Documentation License</citetitle>, Version 1.1 or any later + version published by the Free Software Foundation with no + Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. You may obtain a copy of the <citetitle>GNU Free + Documentation License</citetitle> from the Free Software + Foundation by visiting <ulink type="http" + url="http://www.fsf.org">their Web site</ulink> or by writing + to: + + <address> + The Free Software Foundation, Inc., + <street>59 Temple Place</street> - Suite 330, + <city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>, + <country>USA</country> + </address> + </para> + + <para> + Many of the names used by companies to distinguish their + products and services are claimed as trademarks. Where those + names appear in any GNOME documentation, and those trademarks + are made aware to the members of the GNOME Documentation + Project, the names have been printed in caps or initial caps. + </para> + </legalnotice> + </bookinfo> + + <reference id="ref-api"> + <title>API Reference</title> + <partintro> + <para> + This part presents the class and function reference for the + <literal>libpolkit-gobject-1</literal> library. + </para> + </partintro> + <xi:include href="xml/polkitauthority.xml"/> + <xi:include href="xml/polkitauthorizationclaim.xml"/> + <xi:include href="xml/polkitauthorizationresult.xml"/> + <xi:include href="xml/polkitactiondescription.xml"/> + <xi:include href="xml/polkiterror.xml"/> + <xi:include href="xml/polkitsubject.xml"/> + <xi:include href="xml/polkituser.xml"/> + <xi:include href="xml/polkitprocess.xml"/> + <chapter id="extending"> + <title>Extending PolicyKit</title> + <xi:include href="xml/polkitbackend.xml"/> + <xi:include href="xml/polkitlocalbackend.xml"/> + <xi:include href="xml/polkitbackendstub.xml"/> + </chapter> + </reference> + + <chapter id="polkit-hierarchy"> + <title>Object Hierarchy</title> + <xi:include href="xml/tree_index.sgml"/> + </chapter> + + <index> + <title>Index</title> + </index> + + <!-- License --> + + <appendix id="license"> + <title>License</title> + <para> +<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../../COPYING" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting> + </para> + </appendix> +</book> diff --git a/docs/version.xml.in b/docs/version.xml.in new file mode 100644 index 0000000..d78bda9 --- /dev/null +++ b/docs/version.xml.in @@ -0,0 +1 @@ +@VERSION@ diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/po/ChangeLog diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 0000000..b72d517 --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,4 @@ +# please keep this list sorted alphabetically +# + + diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..53c4283 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,3 @@ +# List of source files containing translatable strings. +# Please keep this file sorted alphabetically. +[encoding: UTF-8] diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..562a3e2 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,5 @@ + +SUBDIRS = polkit polkitd programs + +clean-local : + rm -f *~ diff --git a/src/polkit/Makefile.am b/src/polkit/Makefile.am new file mode 100644 index 0000000..1ab8817 --- /dev/null +++ b/src/polkit/Makefile.am @@ -0,0 +1,78 @@ +NULL = + +INCLUDES = \ + -I$(top_builddir)/src \ + -I$(top_srcdir)/src \ + -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \ + -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \ + -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ + -DPACKAGE_BIN_DIR=\""$(bindir)"\" \ + -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \ + -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \ + -DPACKAGE_LIB_DIR=\""$(libdir)"\" \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + $(NULL) + +BUILT_SOURCES = \ + polkitbackendstubglue.h \ + polkitauthorityglue.h \ + $(NULL) + +polkitbackendstubglue.h: $(top_srcdir)/data/org.freedesktop.PolicyKit1.Authority.xml Makefile.am + dbus-binding-tool --prefix=_polkit_backend_stub --mode=glib-server --output=polkitbackendstubglue.h $(top_srcdir)/data/org.freedesktop.PolicyKit1.Authority.xml + +polkitauthorityglue.h: $(top_srcdir)/data/org.freedesktop.PolicyKit1.Authority.xml Makefile.am + dbus-binding-tool --mode=glib-client --output=polkitauthorityglue.h $(top_srcdir)/data/org.freedesktop.PolicyKit1.Authority.xml + +lib_LTLIBRARIES=libpolkit-gobject-1.la + +libpolkit_gobject_1includedir=$(includedir)/polkit-1/polkit + +libpolkit_gobject_1include_HEADERS = \ + polkit.h \ + polkitactiondescription.h \ + polkitauthority.h \ + polkitauthorizationclaim.h \ + polkitauthorizationresult.h \ + polkitbackend.h \ + polkiterror.h \ + polkitsubject.h \ + polkituser.h \ + polkitprocess.h \ + $(NULL) + +libpolkit_gobject_1_la_SOURCES = \ + polkit.h \ + polkitauthority.h polkitauthority.c \ + polkitactiondescription.h polkitactiondescription.c \ + polkitauthorizationclaim.h polkitauthorizationclaim.c \ + polkitauthorizationresult.h polkitauthorizationresult.c \ + polkitbackend.h polkitbackend.c \ + polkitbackendstub.h polkitbackendstub.c \ + polkiterror.h polkiterror.c \ + polkitsubject.h polkitsubject.c \ + polkitlocalbackend.h polkitlocalbackend.c \ + polkituser.h polkituser.c \ + polkitprocess.h polkitprocess.c \ + polkitserialization.h polkitserialization.c \ + $(BUILT_SOURCES) \ + $(NULL) + +libpolkit_gobject_1_la_CFLAGS = \ + -D_POLKIT_COMPILATION \ + $(GLIB_CFLAGS) \ + $(GIO_CFLAGS) \ + $(DBUS_GLIB_CFLAGS) \ + $(NULL) + +libpolkit_gobject_1_la_LIBADD = \ + $(GLIB_LIBS) \ + $(GIO_LIBS) \ + $(DBUS_GLIB_LIBS) \ + $(NULL) + +CLEANFILES = $(BUILT_SOURCES) + +clean-local : + rm -f *~ diff --git a/src/polkit/polkit.h b/src/polkit/polkit.h new file mode 100644 index 0000000..afdad46 --- /dev/null +++ b/src/polkit/polkit.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#ifndef __POLKIT_H +#define __POLKIT_H + +#define _POLKIT_INSIDE_POLKIT_H 1 +#include <polkit/polkiterror.h> +#include <polkit/polkitsubject.h> +#include <polkit/polkitauthority.h> +#include <polkit/polkitbackendstub.h> +#include <polkit/polkitbackend.h> +#include <polkit/polkitlocalbackend.h> +#include <polkit/polkitauthorizationclaim.h> +#include <polkit/polkitauthorizationresult.h> +#include <polkit/polkituser.h> +#include <polkit/polkitprocess.h> +#include <polkit/polkitactiondescription.h> +#undef _POLKIT_INSIDE_POLKIT_H + +#endif /* __POLKIT_H */ + + diff --git a/src/polkit/polkitactiondescription.c b/src/polkit/polkitactiondescription.c new file mode 100644 index 0000000..2a8d5b7 --- /dev/null +++ b/src/polkit/polkitactiondescription.c @@ -0,0 +1,1112 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <string.h> +#include "polkitactiondescription.h" + +/** + * SECTION:polkitactiondescription + * @short_description: Description of an action + * @include: polkit/polkit.h + * + * Describes an action. + */ + +/*--------------------------------------------------------------------------------------------------------------*/ + +struct _PolkitActionDescriptionPrivate +{ + char *action_id; + GIcon *icon; + char *description; + char *message; + char *vendor_name; + char *vendor_url; + GHashTable *annotations; +}; + +enum { + PROP_0, + PROP_ACTION_ID, + PROP_ICON, + PROP_DESCRIPTION, + PROP_MESSAGE, + PROP_VENDOR_NAME, + PROP_VENDOR_URL, + PROP_ANNOTATIONS, +}; + + +G_DEFINE_TYPE (PolkitActionDescription, polkit_action_description, G_TYPE_OBJECT) + +#define POLKIT_ACTION_DESCRIPTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_ACTION_DESCRIPTION, PolkitActionDescriptionPrivate)) + +static void +polkit_action_description_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + PolkitActionDescription *action_description = POLKIT_ACTION_DESCRIPTION (object); + + switch (prop_id) { + case PROP_ACTION_ID: + g_value_set_string (value, action_description->priv->action_id); + break; + + case PROP_ICON: + g_value_set_object (value, action_description->priv->icon); + break; + + case PROP_DESCRIPTION: + g_value_set_string (value, action_description->priv->description); + break; + + case PROP_MESSAGE: + g_value_set_string (value, action_description->priv->message); + break; + + case PROP_VENDOR_NAME: + g_value_set_string (value, action_description->priv->vendor_name); + break; + + case PROP_VENDOR_URL: + g_value_set_string (value, action_description->priv->vendor_url); + break; + + case PROP_ANNOTATIONS: + g_value_set_boxed (value, action_description->priv->annotations); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +polkit_action_description_init (PolkitActionDescription *action_description) +{ + action_description->priv = POLKIT_ACTION_DESCRIPTION_GET_PRIVATE (action_description); + action_description->priv->annotations = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_free); +} + +static void +polkit_action_description_finalize (GObject *object) +{ + PolkitActionDescription *action_description; + + g_return_if_fail (object != NULL); + g_return_if_fail (POLKIT_IS_ACTION_DESCRIPTION (object)); + + action_description = POLKIT_ACTION_DESCRIPTION (object); + + if (action_description->priv->icon != NULL) + g_object_unref (action_description->priv->icon); + g_free (action_description->priv->action_id); + g_free (action_description->priv->description); + g_free (action_description->priv->message); + g_free (action_description->priv->vendor_name); + g_free (action_description->priv->vendor_url); + g_hash_table_unref (action_description->priv->annotations); + + G_OBJECT_CLASS (polkit_action_description_parent_class)->finalize (object); +} + +static void +polkit_action_description_class_init (PolkitActionDescriptionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = polkit_action_description_get_property; + object_class->finalize = polkit_action_description_finalize; + + /** + * PolkitActionDescription:action-id: + * + * The action id for the action being described. + */ + g_object_class_install_property (object_class, + PROP_ACTION_ID, + g_param_spec_string ("action-id", + "action-id", + "The action identifier for the action", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * PolkitActionDescription:icon: + * + * The icon for the action being described. + */ + g_object_class_install_property (object_class, + PROP_ICON, + g_param_spec_object ("icon", + "icon", + "The icon for the action", + G_TYPE_ICON, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * PolkitActionDescription:description: + * + * A localized human readable description of the action. + */ + g_object_class_install_property (object_class, + PROP_DESCRIPTION, + g_param_spec_string ("description", + "description", + "Description of action", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * PolkitActionDescription:message: + * + * A localized human readable message to display to the user + * when he lacks an authorization for the action. + */ + g_object_class_install_property (object_class, + PROP_MESSAGE, + g_param_spec_string ("message", + "message", + "Message for the action", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * PolkitActionDescription:vendor-name: + * + * The name of the organization supplying the action. + */ + g_object_class_install_property (object_class, + PROP_VENDOR_NAME, + g_param_spec_string ("vendor-name", + "vendor-name", + "Vendor for the action", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * PolkitActionDescription:vendor-url: + * + * An URL (Uniform Resource Locator) describing the action. + */ + g_object_class_install_property (object_class, + PROP_VENDOR_URL, + g_param_spec_string ("vendor-url", + "vendor-url", + "Vendor URL for the action", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * PolkitActionDescription:annotations: + * + * A set of key/value pairs giving more information about the action. + */ + g_object_class_install_property (object_class, + PROP_ANNOTATIONS, + g_param_spec_boxed ("annotations", + "annotations", + "Annotations for the action", + G_TYPE_HASH_TABLE, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private (klass, sizeof (PolkitActionDescriptionPrivate)); +} + +const gchar * +polkit_action_description_get_action_id (PolkitActionDescription *action_description) +{ + g_return_val_if_fail (POLKIT_IS_ACTION_DESCRIPTION (action_description), NULL); + return action_description->priv->action_id; +} + +GIcon * +polkit_action_description_get_icon (PolkitActionDescription *action_description) +{ + g_return_val_if_fail (POLKIT_IS_ACTION_DESCRIPTION (action_description), NULL); + if (action_description->priv->icon != NULL) + return g_object_ref (action_description->priv->icon); + return NULL; +} + +const gchar * +polkit_action_description_get_description (PolkitActionDescription *action_description) +{ + g_return_val_if_fail (POLKIT_IS_ACTION_DESCRIPTION (action_description), NULL); + return action_description->priv->description; +} + +const gchar * +polkit_action_description_get_message (PolkitActionDescription *action_description) +{ + g_return_val_if_fail (POLKIT_IS_ACTION_DESCRIPTION (action_description), NULL); + return action_description->priv->message; +} + +const gchar * +polkit_action_description_get_vendor_name (PolkitActionDescription *action_description) +{ + g_return_val_if_fail (POLKIT_IS_ACTION_DESCRIPTION (action_description), NULL); + return action_description->priv->vendor_name; +} + +const gchar * +polkit_action_description_get_vendor_url (PolkitActionDescription *action_description) +{ + g_return_val_if_fail (POLKIT_IS_ACTION_DESCRIPTION (action_description), NULL); + return action_description->priv->vendor_url; +} + +GHashTable * +polkit_action_description_get_annotations (PolkitActionDescription *action_description) +{ + g_return_val_if_fail (POLKIT_IS_ACTION_DESCRIPTION (action_description), NULL); + return action_description->priv->annotations; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#include <expat.h> /* TODO: move to separate file */ + +enum { + STATE_NONE, + STATE_UNKNOWN_TAG, + STATE_IN_POLICY_CONFIG, + STATE_IN_POLICY_VENDOR, + STATE_IN_POLICY_VENDOR_URL, + STATE_IN_POLICY_ICON_NAME, + STATE_IN_ACTION, + STATE_IN_ACTION_DESCRIPTION, + STATE_IN_ACTION_MESSAGE, + STATE_IN_ACTION_VENDOR, + STATE_IN_ACTION_VENDOR_URL, + STATE_IN_ACTION_ICON_NAME, + STATE_IN_DEFAULTS, + STATE_IN_DEFAULTS_ALLOW_ANY, + STATE_IN_DEFAULTS_ALLOW_INACTIVE, + STATE_IN_DEFAULTS_ALLOW_ACTIVE, + STATE_IN_ANNOTATE +}; + +#define PARSER_MAX_DEPTH 32 + +typedef struct { + XML_Parser parser; + int state; + int state_stack[PARSER_MAX_DEPTH]; + int stack_depth; + + const char *path; + + char *global_vendor; + char *global_vendor_url; + char *global_icon_name; + + char *action_id; + char *vendor; + char *vendor_url; + char *icon_name; + + //PolKitResult defaults_allow_any; + //PolKitResult defaults_allow_inactive; + //PolKitResult defaults_allow_active; + + GHashTable *policy_descriptions; + GHashTable *policy_messages; + + char *policy_description_nolang; + char *policy_message_nolang; + + /* the language according to $LANG (e.g. en_US, da_DK, fr, en_CA minus the encoding) */ + char *lang; + + /* the value of xml:lang for the thing we're reading in _cdata() */ + char *elem_lang; + + char *annotate_key; + GHashTable *annotations; + + PolKitActionDescriptionForeachFunc cb; + void *user_data; +} ParserData; + +static void +pd_unref_action_data (ParserData *pd) +{ + g_free (pd->action_id); + pd->action_id = NULL; + + g_free (pd->vendor); + pd->vendor = NULL; + g_free (pd->vendor_url); + pd->vendor_url = NULL; + g_free (pd->icon_name); + pd->icon_name = NULL; + + g_free (pd->policy_description_nolang); + pd->policy_description_nolang = NULL; + g_free (pd->policy_message_nolang); + pd->policy_message_nolang = NULL; + if (pd->policy_descriptions != NULL) { + g_hash_table_unref (pd->policy_descriptions); + pd->policy_descriptions = NULL; + } + if (pd->policy_messages != NULL) { + g_hash_table_unref (pd->policy_messages); + pd->policy_messages = NULL; + } + g_free (pd->annotate_key); + pd->annotate_key = NULL; + if (pd->annotations != NULL) { + g_hash_table_unref (pd->annotations); + pd->annotations = NULL; + } + g_free (pd->elem_lang); + pd->elem_lang = NULL; +} + +static void +pd_unref_data (ParserData *pd) +{ + pd_unref_action_data (pd); + g_free (pd->lang); + pd->lang = NULL; + + g_free (pd->global_vendor); + pd->global_vendor = NULL; + g_free (pd->global_vendor_url); + pd->global_vendor_url = NULL; + g_free (pd->global_icon_name); + pd->global_icon_name = NULL; +} + +static void +_start (void *data, const char *el, const char **attr) +{ + int state; + int num_attr; + ParserData *pd = data; + + for (num_attr = 0; attr[num_attr] != NULL; num_attr++) + ; + + state = STATE_NONE; + + switch (pd->state) { + case STATE_NONE: + if (strcmp (el, "policyconfig") == 0) { + state = STATE_IN_POLICY_CONFIG; + } + break; + case STATE_IN_POLICY_CONFIG: + if (strcmp (el, "action") == 0) { + if (num_attr != 2 || strcmp (attr[0], "id") != 0) + goto error; + state = STATE_IN_ACTION; + + //if (!polkit_action_validate_id (attr[1])) + // goto error; + + pd_unref_action_data (pd); + pd->action_id = g_strdup (attr[1]); + pd->policy_descriptions = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_free); + pd->policy_messages = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_free); + /* initialize defaults */ + //pd->defaults_allow_any = POLKIT_RESULT_NO; + //pd->defaults_allow_inactive = POLKIT_RESULT_NO; + //pd->defaults_allow_active = POLKIT_RESULT_NO; + } else if (strcmp (el, "vendor") == 0 && num_attr == 0) { + state = STATE_IN_POLICY_VENDOR; + } else if (strcmp (el, "vendor_url") == 0 && num_attr == 0) { + state = STATE_IN_POLICY_VENDOR_URL; + } else if (strcmp (el, "icon_name") == 0 && num_attr == 0) { + state = STATE_IN_POLICY_ICON_NAME; + } + break; + case STATE_IN_ACTION: + if (strcmp (el, "defaults") == 0) { + state = STATE_IN_DEFAULTS; + } else if (strcmp (el, "description") == 0) { + if (num_attr == 2 && strcmp (attr[0], "xml:lang") == 0) { + pd->elem_lang = g_strdup (attr[1]); + } + state = STATE_IN_ACTION_DESCRIPTION; + } else if (strcmp (el, "message") == 0) { + if (num_attr == 2 && strcmp (attr[0], "xml:lang") == 0) { + pd->elem_lang = g_strdup (attr[1]); + } + state = STATE_IN_ACTION_MESSAGE; + } else if (strcmp (el, "vendor") == 0 && num_attr == 0) { + state = STATE_IN_ACTION_VENDOR; + } else if (strcmp (el, "vendor_url") == 0 && num_attr == 0) { + state = STATE_IN_ACTION_VENDOR_URL; + } else if (strcmp (el, "icon_name") == 0 && num_attr == 0) { + state = STATE_IN_ACTION_ICON_NAME; + } else if (strcmp (el, "annotate") == 0) { + if (num_attr != 2 || strcmp (attr[0], "key") != 0) + goto error; + state = STATE_IN_ANNOTATE; + + g_free (pd->annotate_key); + pd->annotate_key = g_strdup (attr[1]); + } + break; + case STATE_IN_DEFAULTS: + if (strcmp (el, "allow_any") == 0) + state = STATE_IN_DEFAULTS_ALLOW_ANY; + else if (strcmp (el, "allow_inactive") == 0) + state = STATE_IN_DEFAULTS_ALLOW_INACTIVE; + else if (strcmp (el, "allow_active") == 0) + state = STATE_IN_DEFAULTS_ALLOW_ACTIVE; + break; + default: + break; + } + + if (state == STATE_NONE) { + g_warning ("skipping unknown tag <%s> at line %d of %s", + el, (int) XML_GetCurrentLineNumber (pd->parser), pd->path); + state = STATE_UNKNOWN_TAG; + } + + pd->state = state; + pd->state_stack[pd->stack_depth] = pd->state; + pd->stack_depth++; + return; +error: + XML_StopParser (pd->parser, FALSE); +} + +static polkit_bool_t +_validate_icon_name (const char *icon_name) +{ + unsigned int n; + polkit_bool_t ret; + size_t len; + + ret = FALSE; + + len = strlen (icon_name); + + /* check for common suffixes */ + if (g_str_has_suffix (icon_name, ".png")) + goto out; + if (g_str_has_suffix (icon_name, ".jpg")) + goto out; + + /* icon name cannot be a path */ + for (n = 0; n < len; n++) { + if (icon_name [n] == '/') { + goto out; + } + } + + ret = TRUE; + +out: + return ret; +} + +static void +_cdata (void *data, const char *s, int len) +{ + char *str; + ParserData *pd = data; + + str = g_strndup (s, len); + + switch (pd->state) { + + case STATE_IN_ACTION_DESCRIPTION: + if (pd->elem_lang == NULL) { + g_free (pd->policy_description_nolang); + pd->policy_description_nolang = str; + str = NULL; + } else { + g_hash_table_insert (pd->policy_descriptions, + g_strdup (pd->elem_lang), + str); + str = NULL; + } + break; + + case STATE_IN_ACTION_MESSAGE: + if (pd->elem_lang == NULL) { + g_free (pd->policy_message_nolang); + pd->policy_message_nolang = str; + str = NULL; + } else { + g_hash_table_insert (pd->policy_messages, + g_strdup (pd->elem_lang), + str); + str = NULL; + } + break; + + case STATE_IN_POLICY_VENDOR: + g_free (pd->global_vendor); + pd->global_vendor = str; + str = NULL; + break; + + case STATE_IN_POLICY_VENDOR_URL: + g_free (pd->global_vendor_url); + pd->global_vendor_url = str; + str = NULL; + break; + + case STATE_IN_POLICY_ICON_NAME: + if (! _validate_icon_name (str)) { + g_warning ("Icon name '%s' is invalid", str); + goto error; + } + + g_free (pd->global_icon_name); + pd->global_icon_name = str; + str = NULL; + break; + + case STATE_IN_ACTION_VENDOR: + g_free (pd->vendor); + pd->vendor = str; + str = NULL; + break; + + case STATE_IN_ACTION_VENDOR_URL: + g_free (pd->vendor_url); + pd->vendor_url = str; + str = NULL; + break; + + case STATE_IN_ACTION_ICON_NAME: + if (! _validate_icon_name (str)) { + kit_warning ("Icon name '%s' is invalid", str); + goto error; + } + + g_free (pd->icon_name); + pd->icon_name = str; + str = NULL; + break; + + case STATE_IN_DEFAULTS_ALLOW_ANY: + //if (!polkit_result_from_string_representation (str, &pd->defaults_allow_any)) + // goto error; + break; + case STATE_IN_DEFAULTS_ALLOW_INACTIVE: + //if (!polkit_result_from_string_representation (str, &pd->defaults_allow_inactive)) + // goto error; + break; + case STATE_IN_DEFAULTS_ALLOW_ACTIVE: + //if (!polkit_result_from_string_representation (str, &pd->defaults_allow_active)) + // goto error; + break; + + case STATE_IN_ANNOTATE: + if (pd->annotations == NULL) { + pd->annotations = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_free); + } + g_hash_table_insert (pd->annotations, + g_strdup (pd->annotate_key), + str); + str = NULL; + break; + + default: + break; + } + g_free (str); + return; +error: + g_free (str); + XML_StopParser (pd->parser, FALSE); +} + +/** + * _localize: + * @translations: a mapping from xml:lang to the value, e.g. 'da' -> 'Smadre', 'en_CA' -> 'Punch, Aye!' + * @untranslated: the untranslated value, e.g. 'Punch' + * @lang: the locale we're interested in, e.g. 'da_DK', 'da', 'en_CA', 'en_US'; basically just $LANG + * with the encoding cut off. Maybe be NULL. + * + * Pick the correct translation to use. + * + * Returns: the localized string to use + */ +static const char * +_localize (GHashTable *translations, + const char *untranslated, + const char *lang) +{ + const char *result; + char lang2[256]; + int n; + + if (lang == NULL) { + result = untranslated; + goto out; + } + + /* first see if we have the translation */ + result = (const char *) g_hash_table_lookup (translations, (void *) lang); + if (result != NULL) + goto out; + + /* we could have a translation for 'da' but lang=='da_DK'; cut off the last part and try again */ + strncpy (lang2, lang, sizeof (lang2)); + for (n = 0; lang2[n] != '\0'; n++) { + if (lang2[n] == '_') { + lang2[n] = '\0'; + break; + } + } + result = (const char *) kit_hash_lookup (translations, (void *) lang2); + if (result != NULL) + goto out; + + /* fall back to untranslated */ + result = untranslated; +out: + return result; +} + +static void +_end (void *data, const char *el) +{ + ParserData *pd = data; + + g_free (pd->elem_lang); + pd->elem_lang = NULL; + + switch (pd->state) { + case STATE_IN_ACTION: + { + const char *policy_description; + const char *policy_message; + //PolKitActionDescription *pfe; + char *vendor; + char *vendor_url; + char *icon_name; + + vendor = pd->vendor; + if (vendor == NULL) + vendor = pd->global_vendor; + + vendor_url = pd->vendor_url; + if (vendor_url == NULL) + vendor_url = pd->global_vendor_url; + + icon_name = pd->icon_name; + if (icon_name == NULL) + icon_name = pd->global_icon_name; + +#if 0 + /* NOTE: caller takes ownership of the annotations object */ + pfe = _polkit_action_description_new (pd->action_id, + vendor, + vendor_url, + icon_name, + pd->defaults_allow_any, + pd->defaults_allow_inactive, + pd->defaults_allow_active, + pd->annotations); + if (pfe == NULL) + goto oom; +#else + g_hash_table_unref (pd->annotations); +#endif + + pd->annotations = NULL; + + policy_description = _localize (pd->policy_descriptions, pd->policy_description_nolang, pd->lang); + policy_message = _localize (pd->policy_messages, pd->policy_message_nolang, pd->lang); + +#if 0 + if (!_polkit_action_description_set_descriptions (pfe, + policy_description, + policy_message)) { + polkit_action_description_unref (pfe); + goto oom; + } +#endif + +#if 0 + if (pd->cb (pfe, pd->user_data)) { + /* TODO: short-circuit */ + } +#endif + + /* and now throw it all away! (eh, don't worry, the user have probably reffed it!) */ + //polkit_action_description_unref (pfe); + break; + } + default: + break; + } + + --pd->stack_depth; + if (pd->stack_depth < 0 || pd->stack_depth >= PARSER_MAX_DEPTH) { + polkit_debug ("reached max depth?"); + goto error; + } + if (pd->stack_depth > 0) + pd->state = pd->state_stack[pd->stack_depth - 1]; + else + pd->state = STATE_NONE; + + return; +oom: + pd->is_oom = 1; +error: + XML_StopParser (pd->parser, FALSE); +} + + +/** + * polkit_action_description_get_from_file: + * @path: path to file, e.g. <literal>/usr/share/polkit-1/actions/org.freedesktop.policykit.policy</literal> + * @cb: callback function + * @user_data: user data + * @error: return location for error + * + * Load a .policy file and iterate over all entries. + * + * Returns: #TRUE if @cb short-circuited the iteration. If there was + * an error parsing @file, then @error will be set. + **/ +polkit_bool_t +polkit_action_description_get_from_file (const char *path, + PolKitActionDescriptionForeachFunc cb, + void *user_data, + PolKitError **error) +{ + ParserData pd; + int xml_res; + char *lang; + char *buf; + size_t buflen; + + buf = NULL; + + /* clear parser data */ + memset (&pd, 0, sizeof (ParserData)); + + if (!kit_str_has_suffix (path, ".policy")) { + polkit_error_set_error (error, + POLKIT_ERROR_POLICY_FILE_INVALID, + "Policy files must have extension .policy; file '%s' doesn't", path); + goto error; + } + + if (!kit_file_get_contents (path, &buf, &buflen)) { + if (errno == ENOMEM) { + polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, + "Cannot load PolicyKit policy file at '%s': %s", + path, + "No memory for parser"); + } else { + polkit_error_set_error (error, POLKIT_ERROR_POLICY_FILE_INVALID, + "Cannot load PolicyKit policy file at '%s': %m", + path); + } + goto error; + } + + pd.path = path; + pd.cb = cb; + pd.user_data = user_data; + +/* #ifdef POLKIT_BUILD_TESTS + TODO: expat appears to leak on certain OOM paths +*/ +#if 0 + XML_Memory_Handling_Suite memsuite = {p_malloc, p_realloc, kit_free}; + pd.parser = XML_ParserCreate_MM (NULL, &memsuite, NULL); +#else + pd.parser = XML_ParserCreate (NULL); +#endif + pd.stack_depth = 0; + if (pd.parser == NULL) { + polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, + "Cannot load PolicyKit policy file at '%s': %s", + path, + "No memory for parser"); + goto error; + } + XML_SetUserData (pd.parser, &pd); + XML_SetElementHandler (pd.parser, _start, _end); + XML_SetCharacterDataHandler (pd.parser, _cdata); + + /* init parser data */ + pd.state = STATE_NONE; + lang = getenv ("LANG"); + if (lang != NULL) { + int n; + pd.lang = kit_strdup (lang); + if (pd.lang == NULL) { + polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, + "Cannot load PolicyKit policy file at '%s': No memory for lang", + path); + goto error; + } + for (n = 0; pd.lang[n] != '\0'; n++) { + if (pd.lang[n] == '.') { + pd.lang[n] = '\0'; + break; + } + } + } + + xml_res = XML_Parse (pd.parser, buf, buflen, 1); + + if (xml_res == 0) { + if (XML_GetErrorCode (pd.parser) == XML_ERROR_NO_MEMORY) { + polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, + "Out of memory parsing %s", + path); + } else if (pd.is_oom) { + polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, + "Out of memory parsing %s", + path); + } else { + polkit_error_set_error (error, POLKIT_ERROR_POLICY_FILE_INVALID, + "%s:%d: parse error: %s", + path, + (int) XML_GetCurrentLineNumber (pd.parser), + XML_ErrorString (XML_GetErrorCode (pd.parser))); + } + XML_ParserFree (pd.parser); + goto error; + } + + XML_ParserFree (pd.parser); + kit_free (buf); + pd_unref_data (&pd); + + return FALSE; /* TODO */ +error: + pd_unref_data (&pd); + kit_free (buf); + return FALSE; /* TODO */ +} + + +GList * +polkit_action_description_new_from_file (GFile *file, + GCancellable *cancellable, + GError **error) +{ + ParserData pd; + char *contents; + gsize contents_len; + GList *ret; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + ret = NULL; + contents = NULL; + parse_context = NULL; + + parser.error = parse_error; + + parser_data = parser_data_new (&ret); + + if (!g_file_load_contents (file, + cancellable, + &contents, + &contents_len, + NULL, + error)) { + goto out; + } + + g_warning ("need to parse '%s' %d", contents, contents_len); + + + /* clear parser data */ + memset (&pd, 0, sizeof (ParserData)); + + pd.parser = XML_ParserCreate (NULL); + + XML_SetUserData (pd.parser, &pd); + XML_SetElementHandler (pd.parser, _start, _end); + XML_SetCharacterDataHandler (pd.parser, _cdata); + + /* init parser data */ + pd.state = STATE_NONE; + lang = getenv ("LANG"); + if (lang != NULL) { + int n; + pd.lang = kit_strdup (lang); + if (pd.lang == NULL) { + polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, + "Cannot load PolicyKit policy file at '%s': No memory for lang", + path); + goto error; + } + for (n = 0; pd.lang[n] != '\0'; n++) { + if (pd.lang[n] == '.') { + pd.lang[n] = '\0'; + break; + } + } + } + + xml_res = XML_Parse (pd.parser, buf, buflen, 1); + + if (xml_res == 0) { + if (XML_GetErrorCode (pd.parser) == XML_ERROR_NO_MEMORY) { + polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, + "Out of memory parsing %s", + path); + } else if (pd.is_oom) { + polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, + "Out of memory parsing %s", + path); + } else { + polkit_error_set_error (error, POLKIT_ERROR_POLICY_FILE_INVALID, + "%s:%d: parse error: %s", + path, + (int) XML_GetCurrentLineNumber (pd.parser), + XML_ErrorString (XML_GetErrorCode (pd.parser))); + } + XML_ParserFree (pd.parser); + goto error; + } + + XML_ParserFree (pd.parser); + kit_free (buf); + pd_unref_data (&pd); + + out: + g_free (contents); + return ret; +} + +GList * +polkit_action_description_new_from_directory (GFile *directory, + GCancellable *cancellable, + GError **error) +{ + GFileEnumerator *e; + GError *local_error; + GFileInfo *file_info; + GList *ret; + + g_return_val_if_fail (G_IS_FILE (directory), NULL); + + ret = NULL; + + local_error = NULL; + e = g_file_enumerate_children (directory, + "standard::*", + G_FILE_QUERY_INFO_NONE, + NULL, + &local_error); + if (local_error != NULL) { + g_propagate_error (error, local_error); + goto out; + } + + while ((file_info = g_file_enumerator_next_file (e, NULL, &local_error)) != NULL) { + const char *name; + GFile *file; + + name = g_file_info_get_name (file_info); + /* only consider files with the right suffix */ + if (g_str_has_suffix (name, ".policy")) { + GList *descs_from_file; + + file = g_file_get_child (directory, name); + + descs_from_file = polkit_action_description_new_from_file (file, + cancellable, + &local_error); + if (local_error != NULL) { + g_list_foreach (ret, (GFunc) g_object_unref, NULL); + g_list_free (ret); + ret = NULL; + + g_propagate_error (error, local_error); + goto out; + } + + ret = g_list_concat (ret, descs_from_file); + + g_object_unref (file); + } + g_object_unref (file_info); + } + + if (local_error != NULL) { + g_list_foreach (ret, (GFunc) g_object_unref, NULL); + g_list_free (ret); + ret = NULL; + + g_propagate_error (error, local_error); + goto out; + } + + out: + if (e != NULL) + g_object_unref (e); + return ret; +} + diff --git a/src/polkit/polkitactiondescription.h b/src/polkit/polkitactiondescription.h new file mode 100644 index 0000000..f60fb99 --- /dev/null +++ b/src/polkit/polkitactiondescription.h @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_ACTION_DESCRIPTION_H__ +#define __POLKIT_ACTION_DESCRIPTION_H__ + +#include <glib-object.h> +#include <gio/gio.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_ACTION_DESCRIPTION (polkit_action_description_get_type ()) +#define POLKIT_ACTION_DESCRIPTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_ACTION_DESCRIPTION, PolkitActionDescription)) +#define POLKIT_ACTION_DESCRIPTION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_ACTION_DESCRIPTION, PolkitActionDescriptionClass)) +#define POLKIT_IS_ACTION_DESCRIPTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_ACTION_DESCRIPTION)) +#define POLKIT_IS_ACTION_DESCRIPTION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_ACTION_DESCRIPTION)) +#define POLKIT_ACTION_DESCRIPTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_ACTION_DESCRIPTION, PolkitActionDescriptionClass)) + +typedef struct _PolkitActionDescription PolkitActionDescription; +typedef struct _PolkitActionDescriptionClass PolkitActionDescriptionClass; +typedef struct _PolkitActionDescriptionPrivate PolkitActionDescriptionPrivate; + +struct _PolkitActionDescription +{ + GObject parent_instance; + PolkitActionDescriptionPrivate *priv; +}; + +struct _PolkitActionDescriptionClass +{ + GObjectClass parent_class; +}; + +GType polkit_action_description_get_type (void) G_GNUC_CONST; +GList * polkit_action_description_new_from_file (GFile *file, + GCancellable *cancellable, + GError **error); +GList * polkit_action_description_new_from_directory (GFile *directory, + GCancellable *cancellable, + GError **error); +const gchar * polkit_action_description_get_action_id (PolkitActionDescription *action_description); +GIcon * polkit_action_description_get_icon (PolkitActionDescription *action_description); +const gchar * polkit_action_description_get_description (PolkitActionDescription *action_description); +const gchar * polkit_action_description_get_message (PolkitActionDescription *action_description); +const gchar * polkit_action_description_get_vendor_name (PolkitActionDescription *action_description); +const gchar * polkit_action_description_get_vendor_url (PolkitActionDescription *action_description); +GHashTable * polkit_action_description_get_annotations (PolkitActionDescription *action_description); + +G_END_DECLS + +#endif /* __POLKIT_ACTION_DESCRIPTION_H__ */ diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c new file mode 100644 index 0000000..f7c5045 --- /dev/null +++ b/src/polkit/polkitauthority.c @@ -0,0 +1,262 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> +#include "polkitauthority.h" +#include "polkitauthorityglue.h" +#include "polkitserialization.h" + +/** + * SECTION:polkitauthority + * @short_description: Authorization checking and management + * @include: polkit/polkit.h + * + * The #PolkitAuthority class represents an authority that can check + * claims made by third parties. Some implementations allow managing + * authorizations. + */ + +struct _PolkitAuthorityPrivate +{ + DBusGProxy *dbus_proxy; +}; + +G_DEFINE_TYPE (PolkitAuthority, polkit_authority, G_TYPE_OBJECT); + +#define POLKIT_AUTHORITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_AUTHORITY, PolkitAuthorityPrivate)) + +enum { + CHANGED_SIGNAL, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void +polkit_authority_finalize (GObject *object) +{ + PolkitAuthority *authority; + + authority = POLKIT_AUTHORITY (object); + + if (authority->priv->dbus_proxy != NULL) + g_object_unref (authority->priv->dbus_proxy); + + G_OBJECT_CLASS (polkit_authority_parent_class)->finalize (object); +} + +static void +polkit_authority_class_init (PolkitAuthorityClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = polkit_authority_finalize; + + /** + * PolkitAuthority::changed: + * @authority: a #PolkitAuthority. + * + * Emitted when something on @authority changes. + */ + signals[CHANGED_SIGNAL] = g_signal_new ("changed", + POLKIT_TYPE_AUTHORITY, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (PolkitAuthorityClass, changed), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + g_type_class_add_private (klass, sizeof (PolkitAuthorityPrivate)); +} + + +static void +polkit_authority_init (PolkitAuthority *authority) +{ + authority->priv = POLKIT_AUTHORITY_GET_PRIVATE (authority); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +say_hello_cb (DBusGProxy *dbus_proxy, + char *result, + GError *error, + gpointer user_data) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); + if (error != NULL) + g_simple_async_result_set_from_error (simple, error); + else + g_simple_async_result_set_op_res_gpointer (simple, result, NULL); + g_simple_async_result_complete (simple); +} + +void +polkit_authority_say_hello (PolkitAuthority *authority, + const gchar *name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_say_hello); + + org_freedesktop_PolicyKit1_Authority_say_hello_async (authority->priv->dbus_proxy, + name, + say_hello_cb, + simple); +} + +gchar * +polkit_authority_say_hello_finish (PolkitAuthority *authority, + GAsyncResult *res, + GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res); + g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_authority_say_hello); + g_simple_async_result_propagate_error (simple, error); + return g_simple_async_result_get_op_res_gpointer (simple); +} + +/** + * polkit_authority_say_hello_sync: + * @authority: A #PolkitAuthority. + * @name: A name to say hello to. + * @cancellable: A #GCancellable or %NULL. + * @error: Return location for error. + * + * Says hello to @name. + * + * Returns: %NULL if @error is set, otherwise a newly allocated string + * containing the greeting, free with g_free(). + **/ +gchar * +polkit_authority_say_hello_sync (PolkitAuthority *authority, + const gchar *name, + GCancellable *cancellable, + GError **error) +{ + gchar *result; + + if (org_freedesktop_PolicyKit1_Authority_say_hello (authority->priv->dbus_proxy, + name, + &result, + error)) { + return result; + } else { + return NULL; + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +PolkitAuthorizationResult +polkit_authority_check_claims_sync (PolkitAuthority *authority, + GList *claims, + GCancellable *cancellable, + GError **error) +{ + PolkitAuthorizationResult result; + char *result_str; + GPtrArray *p; + + result = POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED; + + p = _serialize_ptr_array_from_obj_list + (claims, + (PolkitSerializeFromObjectFunc) _authorization_claim_to_value); + + if (org_freedesktop_PolicyKit1_Authority_check_claims (authority->priv->dbus_proxy, + p, + &result_str, + error)) { + result = _authorization_result_from_string (result_str); + } + + _free_serialized_obj_ptr_array (p); + + return result; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static PolkitAuthority * +_polkit_authority_new (DBusGConnection *connection, + const gchar *service_name, + const gchar *object_path) +{ + PolkitAuthority *authority; + + authority = POLKIT_AUTHORITY (g_object_new (POLKIT_TYPE_AUTHORITY, NULL)); + authority->priv->dbus_proxy = dbus_g_proxy_new_for_name (connection, + service_name, + object_path, + "org.freedesktop.PolicyKit1.Authority"); + + return authority; +} + +/** + * polkit_authority_get: + * + * Gets the default authority for checking claims. + * + * Returns: A reference to a #PolkitAuthority instance. Call + * g_object_unref() to free it. + **/ +PolkitAuthority * +polkit_authority_get (void) +{ + PolkitAuthority *authority; + DBusGConnection *bus; + GError *error; + + bus = NULL; + authority = NULL; + + error = NULL; + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (bus == NULL) { + g_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + goto out; + } + + authority = _polkit_authority_new (bus, + "org.freedesktop.PolicyKit1", + "/authority"); + + out: + if (bus != NULL) + dbus_g_connection_unref (bus); + return authority; +} diff --git a/src/polkit/polkitauthority.h b/src/polkit/polkitauthority.h new file mode 100644 index 0000000..cd2914b --- /dev/null +++ b/src/polkit/polkitauthority.h @@ -0,0 +1,106 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_AUTHORITY_H +#define __POLKIT_AUTHORITY_H + +#include <glib-object.h> +#include <gio/gio.h> +#include <polkit/polkitauthorizationclaim.h> +#include <polkit/polkitauthorizationresult.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_AUTHORITY (polkit_authority_get_type ()) +#define POLKIT_AUTHORITY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_AUTHORITY, PolkitAuthority)) +#define POLKIT_AUTHORITY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), POLKIT_TYPE_AUTHORITY, PolkitAuthorityClass)) +#define POLKIT_AUTHORITY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_AUTHORITY,PolkitAuthorityClass)) +#define POLKIT_IS_AUTHORITY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_AUTHORITY)) +#define POLKIT_IS_AUTHORITY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_AUTHORITY)) + +typedef struct _PolkitAuthority PolkitAuthority; +typedef struct _PolkitAuthorityPrivate PolkitAuthorityPrivate; +typedef struct _PolkitAuthorityClass PolkitAuthorityClass; + +struct _PolkitAuthority +{ + GObject parent_instance; + + /*< private >*/ + PolkitAuthorityPrivate *priv; +}; + +struct _PolkitAuthorityClass +{ + GObjectClass parent_class; + + /*< public >*/ + + /* signals */ + void (* changed) (PolkitAuthority *authority); + + /*< private >*/ + + /* Padding for future expansion */ + void (*_polkit_reserved1) (void); + void (*_polkit_reserved2) (void); + void (*_polkit_reserved3) (void); + void (*_polkit_reserved4) (void); + void (*_polkit_reserved5) (void); + void (*_polkit_reserved6) (void); + void (*_polkit_reserved7) (void); + void (*_polkit_reserved8) (void); +}; + +GType polkit_authority_get_type (void) G_GNUC_CONST; + +void polkit_authority_say_hello (PolkitAuthority *authority, + const gchar *name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gchar *polkit_authority_say_hello_finish (PolkitAuthority *authority, + GAsyncResult *res, + GError **error); + +gchar *polkit_authority_say_hello_sync (PolkitAuthority *authority, + const gchar *name, + GCancellable *cancellable, + GError **error); + +PolkitAuthorizationResult polkit_authority_check_claims_sync (PolkitAuthority *authority, + GList *claims, + GCancellable *cancellable, + GError **error); + +PolkitAuthority *polkit_authority_get (void); + +G_END_DECLS + +#endif /* __POLKIT_AUTHORITY_H */ + diff --git a/src/polkit/polkitauthorizationclaim.c b/src/polkit/polkitauthorizationclaim.c new file mode 100644 index 0000000..1d3d501 --- /dev/null +++ b/src/polkit/polkitauthorizationclaim.c @@ -0,0 +1,299 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <string.h> +#include "polkitauthorizationclaim.h" + +/** + * SECTION:polkitauthorizationclaim + * @short_description: Authorization Claim + * @include: polkit/polkit.h + * + * Represents an authorization claim. + */ + +/*--------------------------------------------------------------------------------------------------------------*/ + +struct _PolkitAuthorizationClaimPrivate +{ + PolkitSubject *subject; + char *action_id; + GHashTable *attributes; +}; + +enum { + PROP_0, + PROP_SUBJECT, + PROP_ACTION_ID, + PROP_ATTRIBUTES, +}; + + +G_DEFINE_TYPE (PolkitAuthorizationClaim, polkit_authorization_claim, G_TYPE_OBJECT) + +#define POLKIT_AUTHORIZATION_CLAIM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_AUTHORIZATION_CLAIM, PolkitAuthorizationClaimPrivate)) + +static void +polkit_authorization_claim_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + PolkitAuthorizationClaim *authorization_claim = POLKIT_AUTHORIZATION_CLAIM (object); + + switch (prop_id) { + case PROP_SUBJECT: + g_value_set_object (value, authorization_claim->priv->subject); + break; + + case PROP_ACTION_ID: + g_value_set_string (value, authorization_claim->priv->action_id); + break; + + case PROP_ATTRIBUTES: + g_value_set_boxed (value, authorization_claim->priv->attributes); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +polkit_authorization_claim_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + PolkitAuthorizationClaim *authorization_claim = POLKIT_AUTHORIZATION_CLAIM (object); + + switch (prop_id) { + case PROP_SUBJECT: + polkit_authorization_claim_set_subject (authorization_claim, POLKIT_SUBJECT (g_value_get_object (value))); + break; + + case PROP_ACTION_ID: + polkit_authorization_claim_set_action_id (authorization_claim, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +polkit_authorization_claim_init (PolkitAuthorizationClaim *authorization_claim) +{ + authorization_claim->priv = POLKIT_AUTHORIZATION_CLAIM_GET_PRIVATE (authorization_claim); + + authorization_claim->priv->attributes = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_free); +} + +static void +polkit_authorization_claim_finalize (GObject *object) +{ + PolkitAuthorizationClaim *authorization_claim; + + g_return_if_fail (object != NULL); + g_return_if_fail (POLKIT_IS_AUTHORIZATION_CLAIM (object)); + + authorization_claim = POLKIT_AUTHORIZATION_CLAIM (object); + + if (authorization_claim->priv->subject != NULL) + g_object_unref (authorization_claim->priv->subject); + g_free (authorization_claim->priv->action_id); + g_hash_table_unref (authorization_claim->priv->attributes); + + G_OBJECT_CLASS (polkit_authorization_claim_parent_class)->finalize (object); +} + +static void +polkit_authorization_claim_class_init (PolkitAuthorizationClaimClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = polkit_authorization_claim_get_property; + object_class->set_property = polkit_authorization_claim_set_property; + object_class->finalize = polkit_authorization_claim_finalize; + + /** + * PolkitAuthorizationClaim:subject: + * + * The subject making the authorization claim. + */ + g_object_class_install_property (object_class, + PROP_SUBJECT, + g_param_spec_object ("subject", + "subject", + "The subject making the authorization claim", + POLKIT_TYPE_SUBJECT, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * PolkitAuthorizationClaim:action-id: + * + * The action id for the authorization claim. + */ + g_object_class_install_property (object_class, + PROP_ACTION_ID, + g_param_spec_string ("action-id", + "action-id", + "The action for the authorization claim", + NULL, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** + * PolkitAuthorizationClaim:attributes: + * + * A #GHashTable from strings into the strings containing + * attributes for the claim. + */ + g_object_class_install_property (object_class, + PROP_ATTRIBUTES, + g_param_spec_boxed ("attributes", + "attributes", + "The attributes for the authorization claim", + G_TYPE_HASH_TABLE, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private (klass, sizeof (PolkitAuthorizationClaimPrivate)); +} + +PolkitSubject * +polkit_authorization_claim_get_subject (PolkitAuthorizationClaim *authorization_claim) +{ + g_return_val_if_fail (POLKIT_IS_AUTHORIZATION_CLAIM (authorization_claim), NULL); + return g_object_ref (authorization_claim->priv->subject); +} + +void +polkit_authorization_claim_set_subject (PolkitAuthorizationClaim *authorization_claim, + PolkitSubject *subject) +{ + g_return_if_fail (POLKIT_IS_AUTHORIZATION_CLAIM (authorization_claim)); + g_return_if_fail (POLKIT_IS_SUBJECT (subject)); + + if (!polkit_subject_equal (authorization_claim->priv->subject, subject)) { + if (authorization_claim->priv->subject != NULL) + g_object_unref (authorization_claim->priv->subject); + authorization_claim->priv->subject = g_object_ref (subject); + } +} + +gchar * +polkit_authorization_claim_get_action_id (PolkitAuthorizationClaim *authorization_claim) +{ + g_return_val_if_fail (POLKIT_IS_AUTHORIZATION_CLAIM (authorization_claim), NULL); + return g_strdup (authorization_claim->priv->action_id); +} + +void +polkit_authorization_claim_set_action_id (PolkitAuthorizationClaim *authorization_claim, + const gchar *action_id) +{ + g_return_if_fail (POLKIT_IS_AUTHORIZATION_CLAIM (authorization_claim)); + g_return_if_fail (action_id != NULL); + + if (authorization_claim->priv->action_id == NULL || + strcmp (authorization_claim->priv->action_id, action_id) != 0) { + g_free (authorization_claim->priv->action_id); + authorization_claim->priv->action_id = g_strdup (action_id); + g_object_notify (G_OBJECT (authorization_claim), "action-id"); + } +} + +/** + * polkit_authorization_claim_get_attributes: + * @authorization_claim: A #PolkitAuthorizationClaim. + * + * Gets the attributes (a #GHashTable mapping strings to strings) for + * @authorization_claim. + * + * Returns: A #GHashTable. Caller should not free it, it is owned by + * @authorization_claim. + **/ +GHashTable * +polkit_authorization_claim_get_attributes (PolkitAuthorizationClaim *authorization_claim) +{ + g_return_val_if_fail (POLKIT_IS_AUTHORIZATION_CLAIM (authorization_claim), NULL); + return authorization_claim->priv->attributes; +} + +char * +polkit_authorization_claim_get_attribute (PolkitAuthorizationClaim *authorization_claim, + const gchar *key) +{ + g_return_val_if_fail (POLKIT_IS_AUTHORIZATION_CLAIM (authorization_claim), NULL); + g_return_val_if_fail (key != NULL, NULL); + + return g_strdup (g_hash_table_lookup (authorization_claim->priv->attributes, key)); +} + +void +polkit_authorization_claim_set_attribute (PolkitAuthorizationClaim *authorization_claim, + const gchar *key, + const gchar *value) +{ + g_return_if_fail (POLKIT_IS_AUTHORIZATION_CLAIM (authorization_claim)); + g_return_if_fail (key != NULL); + + if (value == NULL) { + g_hash_table_remove (authorization_claim->priv->attributes, key); + } else { + g_hash_table_replace (authorization_claim->priv->attributes, + g_strdup (key), + g_strdup (value)); + } +} + + +PolkitAuthorizationClaim * +polkit_authorization_claim_new (PolkitSubject *subject, + const gchar *action_id) +{ + PolkitAuthorizationClaim *authorization_claim; + + authorization_claim = POLKIT_AUTHORIZATION_CLAIM (g_object_new (POLKIT_TYPE_AUTHORIZATION_CLAIM, + "subject", subject, + "action-id", action_id, + NULL)); + + return authorization_claim; +} diff --git a/src/polkit/polkitauthorizationclaim.h b/src/polkit/polkitauthorizationclaim.h new file mode 100644 index 0000000..b04304b --- /dev/null +++ b/src/polkit/polkitauthorizationclaim.h @@ -0,0 +1,76 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_AUTHORIZATION_CLAIM_H__ +#define __POLKIT_AUTHORIZATION_CLAIM_H__ + +#include <glib-object.h> +#include <polkit/polkitsubject.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_AUTHORIZATION_CLAIM (polkit_authorization_claim_get_type ()) +#define POLKIT_AUTHORIZATION_CLAIM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_AUTHORIZATION_CLAIM, PolkitAuthorizationClaim)) +#define POLKIT_AUTHORIZATION_CLAIM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_AUTHORIZATION_CLAIM, PolkitAuthorizationClaimClass)) +#define POLKIT_IS_AUTHORIZATION_CLAIM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_AUTHORIZATION_CLAIM)) +#define POLKIT_IS_AUTHORIZATION_CLAIM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_AUTHORIZATION_CLAIM)) +#define POLKIT_AUTHORIZATION_CLAIM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_AUTHORIZATION_CLAIM, PolkitAuthorizationClaimClass)) + +typedef struct _PolkitAuthorizationClaim PolkitAuthorizationClaim; +typedef struct _PolkitAuthorizationClaimClass PolkitAuthorizationClaimClass; +typedef struct _PolkitAuthorizationClaimPrivate PolkitAuthorizationClaimPrivate; + +struct _PolkitAuthorizationClaim +{ + GObject parent_instance; + PolkitAuthorizationClaimPrivate *priv; +}; + +struct _PolkitAuthorizationClaimClass +{ + GObjectClass parent_class; +}; + +GType polkit_authorization_claim_get_type (void) G_GNUC_CONST; +PolkitAuthorizationClaim * polkit_authorization_claim_new (PolkitSubject *subject, + const gchar *action_id); +PolkitSubject * polkit_authorization_claim_get_subject (PolkitAuthorizationClaim *authorization_claim); +void polkit_authorization_claim_set_subject (PolkitAuthorizationClaim *authorization_claim, + PolkitSubject *subject); +gchar * polkit_authorization_claim_get_action_id (PolkitAuthorizationClaim *authorization_claim); +void polkit_authorization_claim_set_action_id (PolkitAuthorizationClaim *authorization_claim, + const gchar *action_id); +GHashTable * polkit_authorization_claim_get_attributes (PolkitAuthorizationClaim *authorization_claim); +char * polkit_authorization_claim_get_attribute (PolkitAuthorizationClaim *authorization_claim, + const gchar *key); +void polkit_authorization_claim_set_attribute (PolkitAuthorizationClaim *authorization_claim, + const gchar *key, + const gchar *value); + +G_END_DECLS + +#endif /* __POLKIT_AUTHORIZATION_CLAIM_H__ */ diff --git a/src/polkit/polkitauthorizationresult.c b/src/polkit/polkitauthorizationresult.c new file mode 100644 index 0000000..f2d019a --- /dev/null +++ b/src/polkit/polkitauthorizationresult.c @@ -0,0 +1,55 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <polkit/polkitauthorizationresult.h> + +/** + * SECTION:polkitauthorizationresult + * @title: PolkitAuthorizationResult + * @short_description: Result of checking a claim + * @include: polkit/polkit.h + * + * The #PolkitAuthorizationResult enumeration is for possible results + * when checking whether a claim is authorized. + **/ + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +polkit_authorization_result_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) + { + static const GEnumValue values[] = { + ENUM_ENTRY (POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED, "NotAuthorized"), + ENUM_ENTRY (POLKIT_AUTHORIZATION_RESULT_AUTHORIZED, "Authorized"), + ENUM_ENTRY (POLKIT_AUTHORIZATION_RESULT_CHALLENGE, "Challenge"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("PolkitAuthorizationResult", values); + } + return etype; +} diff --git a/src/polkit/polkitauthorizationresult.h b/src/polkit/polkitauthorizationresult.h new file mode 100644 index 0000000..4c3fda3 --- /dev/null +++ b/src/polkit/polkitauthorizationresult.h @@ -0,0 +1,57 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_AUTHORIZATION_RESULT_H +#define __POLKIT_AUTHORIZATION_RESULT_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_AUTHORIZATION_RESULT (polkit_authorization_result_get_type ()) + +/** + * PolkitAuthorizationResult: + * @POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED: Not authorized. + * @POLKIT_AUTHORIZATION_RESULT_AUTHORIZED: Authorized. + * @POLKIT_AUTHORIZATION_RESULT_CHALLENGE: Can be authorized if further information is given. + * + * The possible results when checking whether a claim is authorized. + */ +typedef enum { + POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED, + POLKIT_AUTHORIZATION_RESULT_AUTHORIZED, + POLKIT_AUTHORIZATION_RESULT_CHALLENGE +} PolkitAuthorizationResult; + +GType polkit_authorization_result_get_type (void) G_GNUC_CONST; + + +G_END_DECLS + +#endif /* __POLKIT_AUTHORIZATION_RESULT_H */ + diff --git a/src/polkit/polkitbackend.c b/src/polkit/polkitbackend.c new file mode 100644 index 0000000..ce34456 --- /dev/null +++ b/src/polkit/polkitbackend.c @@ -0,0 +1,117 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include "polkitbackend.h" + +/** + * SECTION:polkitbackend + * @short_description: Abstract base class for backends + * @include: polkit/polkit.h + * + * The #PolkitBackend class represents a backend responding to + * requests from instances of the #PolkitAuthority class. + */ + +G_DEFINE_ABSTRACT_TYPE (PolkitBackend, polkit_backend, G_TYPE_OBJECT); + +enum { + CHANGED_SIGNAL, + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void +polkit_backend_finalize (GObject *object) +{ + PolkitBackend *backend; + + backend = POLKIT_BACKEND (object); + + G_OBJECT_CLASS (polkit_backend_parent_class)->finalize (object); +} + +static void +polkit_backend_class_init (PolkitBackendClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = polkit_backend_finalize; + + /** + * PolkitBackend::changed: + * @backend: a #PolkitBackend. + * + * Emitted when something on @backend changes. + */ + signals[CHANGED_SIGNAL] = g_signal_new ("changed", + POLKIT_TYPE_BACKEND, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (PolkitBackendClass, changed), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +polkit_backend_init (PolkitBackend *backend) +{ +} + +gchar * +polkit_backend_say_hello (PolkitBackend *backend, + PolkitSubject *inquirer, + const gchar *name, + GError **error) +{ + PolkitBackendClass *klass; + + g_return_val_if_fail (POLKIT_IS_BACKEND (backend), NULL); + klass = POLKIT_BACKEND_GET_CLASS (backend); + + return (* klass->say_hello) (backend, + inquirer, + name, + error); +} + +PolkitAuthorizationResult +polkit_backend_check_claims (PolkitBackend *backend, + PolkitSubject *inquirer, + GList *claims, + GError **error) +{ + PolkitBackendClass *klass; + + g_return_val_if_fail (POLKIT_IS_BACKEND (backend), POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED); + klass = POLKIT_BACKEND_GET_CLASS (backend); + + return (* klass->check_claims) (backend, + inquirer, + claims, + error); +} + diff --git a/src/polkit/polkitbackend.h b/src/polkit/polkitbackend.h new file mode 100644 index 0000000..4cfd3e3 --- /dev/null +++ b/src/polkit/polkitbackend.h @@ -0,0 +1,103 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_BACKEND_H +#define __POLKIT_BACKEND_H + +#include <glib-object.h> +#include <gio/gio.h> +#include <polkit/polkitauthorizationclaim.h> +#include <polkit/polkitauthorizationresult.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_BACKEND (polkit_backend_get_type ()) +#define POLKIT_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_BACKEND, PolkitBackend)) +#define POLKIT_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), POLKIT_TYPE_BACKEND, PolkitBackendClass)) +#define POLKIT_BACKEND_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_BACKEND,PolkitBackendClass)) +#define POLKIT_IS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_BACKEND)) +#define POLKIT_IS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_BACKEND)) + +typedef struct _PolkitBackend PolkitBackend; +typedef struct _PolkitBackendClass PolkitBackendClass; + +struct _PolkitBackend +{ + GObject parent_instance; +}; + +/* TODO: maybe we also want async versions that are tried before the sync ones */ + +struct _PolkitBackendClass +{ + GObjectClass parent_class; + + /*< public >*/ + + /* signals */ + void (* changed) (PolkitBackend *backend); + + /* vtable */ + gchar * (* say_hello) (PolkitBackend *backend, + PolkitSubject *inquirer, + const gchar *name, + GError **error); + + PolkitAuthorizationResult (* check_claims) (PolkitBackend *backend, + PolkitSubject *inquirer, + GList *claims, + GError **error); + + /*< private >*/ + + /* Padding for future expansion */ + void (*_polkit_reserved1) (void); + void (*_polkit_reserved2) (void); + void (*_polkit_reserved3) (void); + void (*_polkit_reserved4) (void); + void (*_polkit_reserved5) (void); + void (*_polkit_reserved6) (void); + void (*_polkit_reserved7) (void); + void (*_polkit_reserved8) (void); +}; + +GType polkit_backend_get_type (void) G_GNUC_CONST; + +gchar *polkit_backend_say_hello (PolkitBackend *backend, + PolkitSubject *inquirer, + const gchar *name, + GError **error); + +PolkitAuthorizationResult polkit_backend_check_claims (PolkitBackend *backend, + PolkitSubject *inquirer, + GList *claims, + GError **error); + +G_END_DECLS + +#endif /* __POLKIT_BACKEND_H */ + diff --git a/src/polkit/polkitbackendstub.c b/src/polkit/polkitbackendstub.c new file mode 100644 index 0000000..04e80ef --- /dev/null +++ b/src/polkit/polkitbackendstub.c @@ -0,0 +1,224 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <glib.h> +#include <glib/gi18n-lib.h> +#include <glib-object.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include "polkiterror.h" +#include "polkitbackendstub.h" +#include "polkituser.h" +#include "polkitserialization.h" + +/** + * SECTION:polkitbackendstub + * @short_description: Stub for proxying backends + * @include: polkit/polkit.h + * + * Used on the server side for proxying a #PolkitBackend over + * D-Bus. On the client side, #PolkitAuthority is used. + */ + +/*--------------------------------------------------------------------------------------------------------------*/ + +/* exported methods */ + +gboolean _polkit_backend_stub_say_hello (PolkitBackendStub *backend_stub, + const char *name, + DBusGMethodInvocation *context); + +gboolean _polkit_backend_stub_check_claims (PolkitBackendStub *backend_stub, + GPtrArray *_claims, + DBusGMethodInvocation *context); + +#include "polkitbackendstubglue.h" + +/*--------------------------------------------------------------------------------------------------------------*/ + +struct _PolkitBackendStubPrivate +{ + PolkitBackend *backend; +}; + +G_DEFINE_TYPE (PolkitBackendStub, polkit_backend_stub, G_TYPE_OBJECT) + +#define POLKIT_BACKEND_STUB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_BACKEND_STUB, PolkitBackendStubPrivate)) + +static void +polkit_backend_stub_init (PolkitBackendStub *backend_stub) +{ + backend_stub->priv = POLKIT_BACKEND_STUB_GET_PRIVATE (backend_stub); + +} + +static void +polkit_backend_stub_finalize (GObject *object) +{ + PolkitBackendStub *backend_stub; + + g_return_if_fail (object != NULL); + g_return_if_fail (POLKIT_IS_BACKEND_STUB (object)); + + backend_stub = POLKIT_BACKEND_STUB (object); + + if (backend_stub->priv->backend != NULL) + g_object_unref (backend_stub->priv->backend); + + G_OBJECT_CLASS (polkit_backend_stub_parent_class)->finalize (object); +} + +static void +polkit_backend_stub_class_init (PolkitBackendStubClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = polkit_backend_stub_finalize; + + g_type_class_add_private (klass, sizeof (PolkitBackendStubPrivate)); + + dbus_g_error_domain_register (POLKIT_ERROR, + "org.freedesktop.PolicyKit.Error", + POLKIT_TYPE_ERROR); + + dbus_g_object_type_install_info (POLKIT_TYPE_BACKEND_STUB, &dbus_glib__polkit_backend_stub_object_info); +} + +PolkitBackendStub * +polkit_backend_stub_new (DBusGConnection *connection, + const char *object_path, + PolkitBackend *backend) +{ + PolkitBackendStub *backend_stub; + + backend_stub = POLKIT_BACKEND_STUB (g_object_new (POLKIT_TYPE_BACKEND_STUB, NULL)); + + dbus_g_connection_register_g_object (connection, + object_path, + G_OBJECT (backend_stub)); + + backend_stub->priv->backend = g_object_ref (backend); + + return backend_stub; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +static PolkitSubject * +get_inquirer (DBusGMethodInvocation *context) +{ + PolkitSubject *subject; + + /* TODO; get from context */ + subject = polkit_user_new ("root"); + + return subject; +} + +/*--------------------------------------------------------------------------------------------------------------*/ +/* exported methods */ + +gboolean +_polkit_backend_stub_say_hello (PolkitBackendStub *backend_stub, + const char *name, + DBusGMethodInvocation *context) +{ + PolkitSubject *inquirer; + GError *error; + char *result; + + error = NULL; + inquirer = get_inquirer (context); + + result = polkit_backend_say_hello (backend_stub->priv->backend, + inquirer, + name, + &error); + + if (error != NULL) { + dbus_g_method_return_error (context, error); + g_error_free (error); + } else { + dbus_g_method_return (context, result); + g_free (result); + } + + g_object_unref (inquirer); + + return TRUE; +} + +/*--------------------------------------------------------------------------------------------------------------*/ + +gboolean +_polkit_backend_stub_check_claims (PolkitBackendStub *backend_stub, + GPtrArray *_claims, + DBusGMethodInvocation *context) +{ + PolkitSubject *inquirer; + GError *error; + GList *claims; + PolkitAuthorizationResult result; + + error = NULL; + inquirer = get_inquirer (context); + + claims = _serialize_ptr_array_to_obj_list + (_claims, + (PolkitSerializeToObjectFunc) _authorization_claim_from_data); + + if (claims == NULL) { + dbus_g_method_return_error (context, + g_error_new (POLKIT_ERROR, + POLKIT_ERROR_FAILED, + "Data is malformed")); + goto out; + } + + result = polkit_backend_check_claims (backend_stub->priv->backend, + inquirer, + claims, + &error); + + if (error != NULL) { + dbus_g_method_return_error (context, error); + g_error_free (error); + } else { + char *result_str; + result_str = _authorization_result_to_string (result); + dbus_g_method_return (context, result_str); + g_free (result_str); + } + + g_object_unref (inquirer); + + g_list_foreach (claims, (GFunc) g_object_unref, NULL); + g_list_free (claims); + + out: + return TRUE; +} + +/*--------------------------------------------------------------------------------------------------------------*/ diff --git a/src/polkit/polkitbackendstub.h b/src/polkit/polkitbackendstub.h new file mode 100644 index 0000000..a594909 --- /dev/null +++ b/src/polkit/polkitbackendstub.h @@ -0,0 +1,67 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_BACKEND_STUB_H__ +#define __POLKIT_BACKEND_STUB_H__ + +#include <glib-object.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> +#include <polkit/polkitbackend.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_BACKEND_STUB (polkit_backend_stub_get_type ()) +#define POLKIT_BACKEND_STUB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_BACKEND_STUB, PolkitBackendStub)) +#define POLKIT_BACKEND_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_BACKEND_STUB, PolkitBackendStubClass)) +#define POLKIT_IS_BACKEND_STUB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_BACKEND_STUB)) +#define POLKIT_IS_BACKEND_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_BACKEND_STUB)) +#define POLKIT_BACKEND_STUB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_BACKEND_STUB, PolkitBackendStubClass)) + +typedef struct _PolkitBackendStub PolkitBackendStub; +typedef struct _PolkitBackendStubClass PolkitBackendStubClass; +typedef struct _PolkitBackendStubPrivate PolkitBackendStubPrivate; + +struct _PolkitBackendStub +{ + GObject parent_instance; + PolkitBackendStubPrivate *priv; +}; + +struct _PolkitBackendStubClass +{ + GObjectClass parent_class; +}; + +GType polkit_backend_stub_get_type (void) G_GNUC_CONST; +PolkitBackendStub *polkit_backend_stub_new (DBusGConnection *connection, + const char *object_path, + PolkitBackend *backend); + +G_END_DECLS + +#endif /* __POLKIT_BACKEND_STUB_H__ */ diff --git a/src/polkit/polkiterror.c b/src/polkit/polkiterror.c new file mode 100644 index 0000000..3ec9cf0 --- /dev/null +++ b/src/polkit/polkiterror.c @@ -0,0 +1,67 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <polkit/polkiterror.h> + +/** + * SECTION:polkiterror + * @title: PolkitError + * @short_description: Error helper functions + * @include: polkit/polkit.h + * + * Contains helper functions for reporting errors to the user. + **/ + +/** + * polkit_error_quark: + * + * Gets the #PolkitError Quark. + * + * Return value: a #GQuark. + **/ +GQuark +polkit_error_quark (void) +{ + return g_quark_from_static_string ("g-polkit-error-quark"); +} + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +polkit_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) + { + static const GEnumValue values[] = { + ENUM_ENTRY (POLKIT_ERROR_FAILED, "Failed"), + ENUM_ENTRY (POLKIT_ERROR_NOT_SUPPORTED, "NotSupported"), + { 0, 0, 0 } + }; + g_assert (POLKIT_ERROR_NUM_ERRORS == G_N_ELEMENTS (values) - 1); + etype = g_enum_register_static ("PolkitErrorEnum", values); + } + return etype; +} diff --git a/src/polkit/polkiterror.h b/src/polkit/polkiterror.h new file mode 100644 index 0000000..73da465 --- /dev/null +++ b/src/polkit/polkiterror.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_ERROR_H +#define __POLKIT_ERROR_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_ERROR (polkit_error_get_type ()) + +/** + * POLKIT_ERROR: + * + * Error domain for PolicyKit. Errors in this domain will be from the + * #PolkitErrorEnum enumeration. See #GError for more information on + * error domains. + **/ +#define POLKIT_ERROR polkit_error_quark() + +GQuark polkit_error_quark (void); +GType polkit_error_get_type (void) G_GNUC_CONST; + +/** + * PolkitErrorEnum: + * @POLKIT_ERROR_FAILED: The operation failed. + * @POLKIT_ERROR_NOT_SUPPORTED: Operation not supported by backend. + * + * Error codes returned by PolicyKit functions. + */ +typedef enum { + POLKIT_ERROR_FAILED, + POLKIT_ERROR_NOT_SUPPORTED, + POLKIT_ERROR_NUM_ERRORS +} PolkitErrorEnum; + +G_END_DECLS + +#endif /* __POLKIT_ERROR_H */ + diff --git a/src/polkit/polkitlocalbackend.c b/src/polkit/polkitlocalbackend.c new file mode 100644 index 0000000..9947a8c --- /dev/null +++ b/src/polkit/polkitlocalbackend.c @@ -0,0 +1,167 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <string.h> +#include "polkiterror.h" +#include "polkitlocalbackend.h" +#include "polkitserialization.h" /* TODO: remove */ + +/** + * SECTION:polkitlocalbackend + * @short_description: Backend using local files + * @include: polkit/polkit.h + * + * The #PolkitLocalBackend class is an implementation of + * #PolkitBackend that stores authorizations on the local file + * system. + */ + +struct _PolkitLocalBackendPrivate +{ + int stuff; +}; + +static gchar *say_hello (PolkitBackend *_backend, + PolkitSubject *inquirer, + const gchar *name, + GError **error); + +static PolkitAuthorizationResult check_claims (PolkitBackend *_backend, + PolkitSubject *inquirer, + GList *claims, + GError **error); + +G_DEFINE_TYPE (PolkitLocalBackend, polkit_local_backend, POLKIT_TYPE_BACKEND); + +#define POLKIT_LOCAL_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_LOCAL_BACKEND, PolkitLocalBackendPrivate)) + +static void +polkit_local_backend_finalize (GObject *object) +{ + PolkitLocalBackend *local_backend; + + local_backend = POLKIT_LOCAL_BACKEND (object); + + G_OBJECT_CLASS (polkit_local_backend_parent_class)->finalize (object); +} + +static void +polkit_local_backend_class_init (PolkitLocalBackendClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + PolkitBackendClass *backend_class = POLKIT_BACKEND_CLASS (klass); + + backend_class->say_hello = say_hello; + backend_class->check_claims = check_claims; + + gobject_class->finalize = polkit_local_backend_finalize; + + g_type_class_add_private (klass, sizeof (PolkitLocalBackendPrivate)); +} + +static void +polkit_local_backend_init (PolkitLocalBackend *local_backend) +{ + local_backend->priv = POLKIT_LOCAL_BACKEND_GET_PRIVATE (local_backend); +} + +PolkitBackend * +polkit_local_backend_new (void) +{ + PolkitBackend *backend; + + backend = POLKIT_BACKEND (g_object_new (POLKIT_TYPE_LOCAL_BACKEND, NULL)); + + return backend; +} + +static gchar * +say_hello (PolkitBackend *_backend, + PolkitSubject *inquirer, + const gchar *name, + GError **error) +{ + char *ret; + + ret = NULL; + + if (strcmp (name, "davidz") == 0) { + g_set_error_literal (error, + POLKIT_ERROR, + POLKIT_ERROR_NOT_SUPPORTED, + "We don't want to async greet davidz!"); + } else { + ret = g_strdup_printf ("Local async greets 'Hi %s!'", name); + } + + return ret; +} + +PolkitAuthorizationResult +check_claims (PolkitBackend *_backend, + PolkitSubject *inquirer, + GList *claims, + GError **error) +{ + PolkitLocalBackend *backend; + PolkitAuthorizationResult result; + GList *l; + + backend = POLKIT_LOCAL_BACKEND (_backend); + + for (l = claims; l != NULL; l = l->next) { + PolkitAuthorizationClaim *claim = POLKIT_AUTHORIZATION_CLAIM (l->data); + char *action_id; + PolkitSubject *subject; + GHashTable *attributes; + GHashTableIter iter; + const char *key; + const char *value; + + g_object_get (claim, + "subject", &subject, + "action-id", &action_id, + "attributes", &attributes, + NULL); + + g_print ("action-id: %s\n", action_id); + g_print ("subject: %s\n", _subject_to_string (subject)); + + g_hash_table_iter_init (&iter, attributes); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { + g_print (" '%s' -> '%s'\n", key, value); + } + + g_print ("\n"); + + g_object_unref (subject); + g_free (action_id); + g_hash_table_unref (attributes); + } + + /* TODO */ + result = POLKIT_AUTHORIZATION_RESULT_AUTHORIZED; + + return result; +} diff --git a/src/polkit/polkitlocalbackend.h b/src/polkit/polkitlocalbackend.h new file mode 100644 index 0000000..ccfd815 --- /dev/null +++ b/src/polkit/polkitlocalbackend.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_LOCAL_BACKEND_H +#define __POLKIT_LOCAL_BACKEND_H + +#include <polkit/polkitbackend.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_LOCAL_BACKEND (polkit_local_backend_get_type ()) +#define POLKIT_LOCAL_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_LOCAL_BACKEND, PolkitLocalBackend)) +#define POLKIT_LOCAL_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), POLKIT_TYPE_LOCAL_BACKEND, PolkitLocalBackendClass)) +#define POLKIT_LOCAL_BACKEND_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_LOCAL_BACKEND,PolkitLocalBackendClass)) +#define POLKIT_IS_LOCAL_BACKEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_LOCAL_BACKEND)) +#define POLKIT_IS_LOCAL_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_LOCAL_BACKEND)) + +typedef struct _PolkitLocalBackend PolkitLocalBackend; +typedef struct _PolkitLocalBackendClass PolkitLocalBackendClass; +typedef struct _PolkitLocalBackendPrivate PolkitLocalBackendPrivate; + +struct _PolkitLocalBackend +{ + PolkitBackend parent_instance; + + /*< private >*/ + PolkitLocalBackendPrivate *priv; +}; + +struct _PolkitLocalBackendClass +{ + PolkitBackendClass parent_class; +}; + +GType polkit_local_backend_get_type (void) G_GNUC_CONST; +PolkitBackend *polkit_local_backend_new (void); + +G_END_DECLS + +#endif /* __POLKIT_LOCAL_BACKEND_H */ + diff --git a/src/polkit/polkitprocess.c b/src/polkit/polkitprocess.c new file mode 100644 index 0000000..a522682 --- /dev/null +++ b/src/polkit/polkitprocess.c @@ -0,0 +1,185 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <string.h> + +#include "polkitprocess.h" + +/** + * SECTION:polkitprocess + * @short_description: Process + * @include: polkit/polkit.h + * + * Represents a process. + */ + +/*--------------------------------------------------------------------------------------------------------------*/ + +struct _PolkitProcessPrivate +{ + GPid pid; +}; + +enum { + PROP_0, + PROP_PID, +}; + +static void polkit_process_subject_iface_init (PolkitSubjectIface *iface); + +G_DEFINE_TYPE_WITH_CODE (PolkitProcess, polkit_process, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT, + polkit_process_subject_iface_init)) + +#define POLKIT_PROCESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_PROCESS, PolkitProcessPrivate)) + +static void +polkit_process_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + PolkitProcess *process = POLKIT_PROCESS (object); + + switch (prop_id) { + case PROP_PID: + g_value_set_int (value, process->priv->pid); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +polkit_process_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + PolkitProcess *process = POLKIT_PROCESS (object); + + switch (prop_id) { + case PROP_PID: + polkit_process_set_pid (process, g_value_get_int (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +polkit_process_init (PolkitProcess *process) +{ + process->priv = POLKIT_PROCESS_GET_PRIVATE (process); +} + +static void +polkit_process_finalize (GObject *object) +{ + PolkitProcess *process; + + g_return_if_fail (object != NULL); + g_return_if_fail (POLKIT_IS_PROCESS (object)); + + process = POLKIT_PROCESS (object); + + G_OBJECT_CLASS (polkit_process_parent_class)->finalize (object); +} + +static void +polkit_process_class_init (PolkitProcessClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = polkit_process_get_property; + object_class->set_property = polkit_process_set_property; + object_class->finalize = polkit_process_finalize; + + /** + * PolkitProcess:pid: + * + * The process id. + */ + g_object_class_install_property (object_class, + PROP_PID, + g_param_spec_int ("pid", + "pid", + "The process id", + -1, + G_MAXINT, /* TODO: maybe there's a MAX_PID? */ + -1, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private (klass, sizeof (PolkitProcessPrivate)); +} + +pid_t +polkit_process_get_pid (PolkitProcess *process) +{ + g_return_val_if_fail (POLKIT_IS_PROCESS (process), -1); + return process->priv->pid; +} + +void +polkit_process_set_pid (PolkitProcess *process, + pid_t pid) +{ + g_return_if_fail (POLKIT_IS_PROCESS (process)); + if (pid != process->priv->pid) { + process->priv->pid = pid; + g_object_notify (G_OBJECT (process), "pid"); + } +} + +PolkitSubject * +polkit_process_new (pid_t pid) +{ + return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_PROCESS, + "pid", pid, + NULL)); +} + +static gboolean +polkit_process_equal (PolkitSubject *subject1, + PolkitSubject *subject2) +{ + PolkitProcess *process1 = POLKIT_PROCESS (subject1); + PolkitProcess *process2 = POLKIT_PROCESS (subject2); + + return process1->priv->pid == process2->priv->pid; +} + +static void +polkit_process_subject_iface_init (PolkitSubjectIface *iface) +{ + iface->equal = polkit_process_equal; +} diff --git a/src/polkit/polkitprocess.h b/src/polkit/polkitprocess.h new file mode 100644 index 0000000..c992801 --- /dev/null +++ b/src/polkit/polkitprocess.h @@ -0,0 +1,67 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_PROCESS_H__ +#define __POLKIT_PROCESS_H__ + +#include <sys/types.h> +#include <glib-object.h> +#include <polkit/polkitsubject.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_PROCESS (polkit_process_get_type ()) +#define POLKIT_PROCESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_PROCESS, PolkitProcess)) +#define POLKIT_PROCESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_PROCESS, PolkitProcessClass)) +#define POLKIT_IS_PROCESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_PROCESS)) +#define POLKIT_IS_PROCESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_PROCESS)) +#define POLKIT_PROCESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_PROCESS, PolkitProcessClass)) + +typedef struct _PolkitProcess PolkitProcess; +typedef struct _PolkitProcessClass PolkitProcessClass; +typedef struct _PolkitProcessPrivate PolkitProcessPrivate; + +struct _PolkitProcess +{ + GObject parent_instance; + PolkitProcessPrivate *priv; +}; + +struct _PolkitProcessClass +{ + GObjectClass parent_class; +}; + +GType polkit_process_get_type (void) G_GNUC_CONST; +PolkitSubject *polkit_process_new (pid_t pid); +pid_t polkit_process_get_pid (PolkitProcess *process); +void polkit_process_set_pid (PolkitProcess *process, + pid_t pid); + +G_END_DECLS + +#endif /* __POLKIT_PROCESS_H__ */ diff --git a/src/polkit/polkitserialization.c b/src/polkit/polkitserialization.c new file mode 100644 index 0000000..1ab3043 --- /dev/null +++ b/src/polkit/polkitserialization.c @@ -0,0 +1,251 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <stdlib.h> +#include <string.h> +#include <dbus/dbus-glib.h> + +#include <polkit/polkitserialization.h> +#include <polkit/polkituser.h> +#include <polkit/polkitprocess.h> + +PolkitAuthorizationResult +_authorization_result_from_string (const char *str) +{ + PolkitAuthorizationResult ret; + + g_return_val_if_fail (str != NULL, POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED); + + ret = POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED; + + if (strcmp (str, "authorized") == 0) { + ret = POLKIT_AUTHORIZATION_RESULT_AUTHORIZED; + } else if (strcmp (str, "challenge") == 0) { + ret = POLKIT_AUTHORIZATION_RESULT_CHALLENGE; + } else if (strcmp (str, "notauthorized") == 0) { + ret = POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED; + } else { + g_warning ("unknown authorization result string '%s'", str); + } + + return ret; +} + +char * +_authorization_result_to_string (PolkitAuthorizationResult result) +{ + char *ret; + + switch (result) { + case POLKIT_AUTHORIZATION_RESULT_AUTHORIZED: + ret = g_strdup ("authorized"); + break; + case POLKIT_AUTHORIZATION_RESULT_CHALLENGE: + ret = g_strdup ("challenge"); + break; + default: + g_warning ("unknown authorization result with code %d", result); + /* explicit fallthrough */ + case POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED: + ret = g_strdup ("notauthorized"); + break; + } + + return ret; +} + +PolkitSubject * +_subject_from_string (const char *str) +{ + PolkitSubject *subject; + + g_return_val_if_fail (str != NULL, NULL); + + subject = NULL; + + if (g_str_has_prefix (str, "user:")) { + subject = polkit_user_new (str + sizeof ("user:") - 1); + } else if (g_str_has_prefix (str, "process:")) { + pid_t pid; + pid = (pid_t) (atoi (str + sizeof ("process:") - 1)); + subject = polkit_process_new ((pid)); + } else { + g_warning ("Please add support for deserializing strings of form '%s'", str); + } + + return subject; +} + +char * +_subject_to_string (PolkitSubject *subject) +{ + char *ret; + + g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), NULL); + + ret = NULL; + + if (POLKIT_IS_USER (subject)) { + char *s; + s = polkit_user_get_user_name (POLKIT_USER (subject)); + ret = g_strdup_printf ("user:%s", s); + g_free (s); + } else if (POLKIT_IS_PROCESS (subject)) { + pid_t pid; + pid = polkit_process_get_pid (POLKIT_PROCESS (subject)); + ret = g_strdup_printf ("process:%d", pid); + } else { + g_warning ("Please add support for serializing type %s", + g_type_name (G_TYPE_FROM_INSTANCE (subject))); + } + + return ret; +} + + +#define CLAIM_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \ + G_TYPE_STRING, \ + G_TYPE_STRING, \ + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING), \ + G_TYPE_INVALID)) + +void +_authorization_claim_to_value (PolkitAuthorizationClaim *claim, GValue *value) +{ + char *action_id; + char *subject_str; + PolkitSubject *subject; + GHashTable *attributes; + + subject = polkit_authorization_claim_get_subject (claim); + action_id = polkit_authorization_claim_get_action_id (claim); + subject_str = _subject_to_string (subject); + + attributes = polkit_authorization_claim_get_attributes (claim); + + g_value_init (value, CLAIM_STRUCT_TYPE); + g_value_take_boxed (value, dbus_g_type_specialized_construct (CLAIM_STRUCT_TYPE)); + dbus_g_type_struct_set (value, + 0, subject_str, + 1, action_id, + 2, attributes, + G_MAXUINT); + + g_free (action_id); + g_free (subject_str); + g_object_unref (subject); +} + +PolkitAuthorizationClaim * +_authorization_claim_from_data (gpointer data) +{ + GValue elem0 = {0}; + PolkitAuthorizationClaim *claim; + PolkitSubject *subject; + char *subject_str; + char *action_id; + GHashTable *attributes; + GHashTableIter iter; + const char *key; + const char *value; + + claim = NULL; + + g_value_init (&elem0, CLAIM_STRUCT_TYPE); + g_value_set_static_boxed (&elem0, data); + dbus_g_type_struct_get (&elem0, + 0, &subject_str, + 1, &action_id, + 2, &attributes, + G_MAXUINT); + + subject = _subject_from_string (subject_str); + if (subject == NULL) + goto out; + + claim = polkit_authorization_claim_new (subject, action_id); + g_hash_table_iter_init (&iter, attributes); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { + polkit_authorization_claim_set_attribute (claim, key, value); + } + + out: + g_free (subject_str); + g_free (action_id); + if (subject != NULL) + g_object_unref (subject); + if (attributes != NULL) + g_hash_table_unref (attributes); + return claim; +} + +GList * +_serialize_ptr_array_to_obj_list (GPtrArray *ptr_array, + PolkitSerializeToObjectFunc func) +{ + GList *ret; + int n; + + ret = NULL; + for (n = 0; n < (int) ptr_array->len; n++) { + GObject *object; + object = func (ptr_array->pdata[n]); + if (object == NULL) + goto fail; + ret = g_list_prepend (ret, object); + } + ret = g_list_reverse (ret); + return ret; + fail: + g_list_foreach (ret, (GFunc) g_object_unref, NULL); + g_list_free (ret); + return NULL; +} + +GPtrArray * +_serialize_ptr_array_from_obj_list (GList *list, + PolkitSerializeFromObjectFunc func) +{ + GPtrArray *ptr_array; + GList *l; + + ptr_array = g_ptr_array_new (); + for (l = list; l != NULL; l = l->next) { + GObject *object = G_OBJECT (l->data); + GValue elem = {0}; + + func (object, &elem); + + g_ptr_array_add (ptr_array, g_value_get_boxed (&elem)); + } + + return ptr_array; +} + +void +_free_serialized_obj_ptr_array (GPtrArray *ptr_array) +{ + g_ptr_array_foreach (ptr_array, (GFunc) g_value_array_free, NULL); + g_ptr_array_free (ptr_array, TRUE); +} diff --git a/src/polkit/polkitserialization.h b/src/polkit/polkitserialization.h new file mode 100644 index 0000000..1ab94ed --- /dev/null +++ b/src/polkit/polkitserialization.h @@ -0,0 +1,49 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#ifndef __POLKIT_SERIALIZATION_H +#define __POLKIT_SERIALIZATION_H + +#include <polkit/polkitauthorizationclaim.h> +#include <polkit/polkitauthorizationresult.h> + +typedef GObject * (*PolkitSerializeToObjectFunc) (gpointer data); +typedef void (*PolkitSerializeFromObjectFunc) (GObject *object, + GValue *value); + + +PolkitAuthorizationResult _authorization_result_from_string (const char *str); +char * _authorization_result_to_string (PolkitAuthorizationResult result); +PolkitSubject * _subject_from_string (const char *str); +char * _subject_to_string (PolkitSubject *subject); +void _authorization_claim_to_value (PolkitAuthorizationClaim *claim, + GValue *value); +PolkitAuthorizationClaim *_authorization_claim_from_data (gpointer data); +GList * _serialize_ptr_array_to_obj_list (GPtrArray *ptr_array, + PolkitSerializeToObjectFunc func); +GPtrArray * _serialize_ptr_array_from_obj_list (GList *list, + PolkitSerializeFromObjectFunc func); +void _free_serialized_obj_ptr_array (GPtrArray *ptr_array); + + +#endif /* __POLKIT_SERIALIZATION_H */ diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c new file mode 100644 index 0000000..062a7de --- /dev/null +++ b/src/polkit/polkitsubject.c @@ -0,0 +1,115 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" + +#include "polkitsubject.h" + +/** + * SECTION:polkitsubject + * @title: PolkitSubject + * @short_description: Interface for subjects + * @include: polkit/polkit.h + * + * #PolkitSubject is a very minimal interface for subjects. It provides functions + * for checking the equality of two subjects + * + * To check if two #PolkitSubjects are equal, see polkit_subject_equal(). + **/ + +static void polkit_subject_base_init (gpointer g_class); +static void polkit_subject_class_init (gpointer g_class, + gpointer class_data); + +GType +polkit_subject_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) { + const GTypeInfo subject_info = { + sizeof (PolkitSubjectIface), /* class_size */ + polkit_subject_base_init, /* base_init */ + NULL, /* base_finalize */ + polkit_subject_class_init, /* class_init */ + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + GType g_define_type_id = + g_type_register_static (G_TYPE_INTERFACE, + "PolkitSubject", + &subject_info, + 0); + + g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT); + + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + +static void +polkit_subject_class_init (gpointer g_class, + gpointer class_data) +{ +} + +static void +polkit_subject_base_init (gpointer g_class) +{ +} + + +/** + * polkit_subject_equal: + * @subject1: pointer to the first #PolkitSubject. + * @subject2: pointer to the second #PolkitSubject. + * + * Checks if two subjects are equal. + * + * Returns: %TRUE if @subject1 is equal to @subject2. %FALSE otherwise. + **/ +gboolean +polkit_subject_equal (PolkitSubject *subject1, + PolkitSubject *subject2) +{ + PolkitSubjectIface *iface; + + if (subject1 == NULL && subject2 == NULL) + return TRUE; + + if (subject1 == NULL || subject2 == NULL) + return FALSE; + + if (G_TYPE_FROM_INSTANCE (subject1) != G_TYPE_FROM_INSTANCE (subject2)) + return FALSE; + + iface = POLKIT_SUBJECT_GET_IFACE (subject1); + + return (* iface->equal) (subject1, subject2); +} diff --git a/src/polkit/polkitsubject.h b/src/polkit/polkitsubject.h new file mode 100644 index 0000000..df29922 --- /dev/null +++ b/src/polkit/polkitsubject.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_SUBJECT_H__ +#define __POLKIT_SUBJECT_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_SUBJECT (polkit_subject_get_type ()) +#define POLKIT_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POLKIT_TYPE_SUBJECT, PolkitSubject)) +#define POLKIT_IS_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POLKIT_TYPE_SUBJECT)) +#define POLKIT_SUBJECT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), POLKIT_TYPE_SUBJECT, PolkitSubjectIface)) + +/** + * PolkitSubject: + * + * An abstract type that specifies a subject. + **/ +typedef struct _PolkitSubject PolkitSubject; +typedef struct _PolkitSubjectIface PolkitSubjectIface; + +/** + * PolkitSubjectIface: + * @g_iface: The parent interface. + * @equal: Checks if two #PolkitSubject<!-- -->s are equal. + * + * #PolkitSubjectIface is used to implement #PolkitSubject types for various + * different subjects + */ +struct _PolkitSubjectIface +{ + GTypeInterface g_iface; + + /* Virtual Table */ + + gboolean (* equal) (PolkitSubject *subject1, + PolkitSubject *subject2); +}; + +GType polkit_subject_get_type (void) G_GNUC_CONST; +gboolean polkit_subject_equal (PolkitSubject *subject1, + PolkitSubject *subject2); + +G_END_DECLS + +#endif /* __POLKIT_SUBJECT_H__ */ diff --git a/src/polkit/polkituser.c b/src/polkit/polkituser.c new file mode 100644 index 0000000..32d691f --- /dev/null +++ b/src/polkit/polkituser.c @@ -0,0 +1,188 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" +#include <string.h> + +#include "polkituser.h" + +/** + * SECTION:polkituser + * @short_description: User + * @include: polkit/polkit.h + * + * Represents a user. + */ + +/*--------------------------------------------------------------------------------------------------------------*/ + +struct _PolkitUserPrivate +{ + char *user_name; +}; + +enum { + PROP_0, + PROP_USER_NAME, +}; + +static void polkit_user_subject_iface_init (PolkitSubjectIface *iface); + +G_DEFINE_TYPE_WITH_CODE (PolkitUser, polkit_user, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT, + polkit_user_subject_iface_init)) + +#define POLKIT_USER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_TYPE_USER, PolkitUserPrivate)) + +static void +polkit_user_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + PolkitUser *user = POLKIT_USER (object); + + switch (prop_id) { + case PROP_USER_NAME: + g_value_set_string (value, user->priv->user_name); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +polkit_user_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + PolkitUser *user = POLKIT_USER (object); + + switch (prop_id) { + case PROP_USER_NAME: + polkit_user_set_user_name (user, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +polkit_user_init (PolkitUser *user) +{ + user->priv = POLKIT_USER_GET_PRIVATE (user); +} + +static void +polkit_user_finalize (GObject *object) +{ + PolkitUser *user; + + g_return_if_fail (object != NULL); + g_return_if_fail (POLKIT_IS_USER (object)); + + user = POLKIT_USER (object); + + g_free (user->priv->user_name); + + G_OBJECT_CLASS (polkit_user_parent_class)->finalize (object); +} + +static void +polkit_user_class_init (PolkitUserClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = polkit_user_get_property; + object_class->set_property = polkit_user_set_property; + object_class->finalize = polkit_user_finalize; + + /** + * PolkitUser:user-name: + * + * The user name. + */ + g_object_class_install_property (object_class, + PROP_USER_NAME, + g_param_spec_string ("user-name", + "user-name", + "The user name", + NULL, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private (klass, sizeof (PolkitUserPrivate)); +} + +gchar * +polkit_user_get_user_name (PolkitUser *user) +{ + g_return_val_if_fail (POLKIT_IS_USER (user), NULL); + return g_strdup (user->priv->user_name); +} + +void +polkit_user_set_user_name (PolkitUser *user, + const char *user_name) +{ + g_return_if_fail (POLKIT_IS_USER (user)); + g_return_if_fail (user_name != NULL); + + if (user->priv->user_name == NULL || strcmp (user_name, user->priv->user_name) != 0) { + g_free (user->priv->user_name); + user->priv->user_name = g_strdup (user_name); + g_object_notify (G_OBJECT (user), "user-name"); + } +} + +PolkitSubject * +polkit_user_new (const gchar *user_name) +{ + return POLKIT_SUBJECT (g_object_new (POLKIT_TYPE_USER, + "user-name", user_name, + NULL)); +} + +static gboolean +polkit_user_equal (PolkitSubject *subject1, + PolkitSubject *subject2) +{ + PolkitUser *user1 = POLKIT_USER (subject1); + PolkitUser *user2 = POLKIT_USER (subject2); + + return strcmp (user1->priv->user_name, user2->priv->user_name) == 0; +} + +static void +polkit_user_subject_iface_init (PolkitSubjectIface *iface) +{ + iface->equal = polkit_user_equal; +} diff --git a/src/polkit/polkituser.h b/src/polkit/polkituser.h new file mode 100644 index 0000000..44e4a56 --- /dev/null +++ b/src/polkit/polkituser.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#if !defined (_POLKIT_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H) +#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef __POLKIT_USER_H__ +#define __POLKIT_USER_H__ + +#include <glib-object.h> +#include <polkit/polkitsubject.h> + +G_BEGIN_DECLS + +#define POLKIT_TYPE_USER (polkit_user_get_type ()) +#define POLKIT_USER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_USER, PolkitUser)) +#define POLKIT_USER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_USER, PolkitUserClass)) +#define POLKIT_IS_USER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_USER)) +#define POLKIT_IS_USER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_USER)) +#define POLKIT_USER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_USER, PolkitUserClass)) + +typedef struct _PolkitUser PolkitUser; +typedef struct _PolkitUserClass PolkitUserClass; +typedef struct _PolkitUserPrivate PolkitUserPrivate; + +struct _PolkitUser +{ + GObject parent_instance; + PolkitUserPrivate *priv; +}; + +struct _PolkitUserClass +{ + GObjectClass parent_class; +}; + +GType polkit_user_get_type (void) G_GNUC_CONST; +PolkitSubject *polkit_user_new (const char *user_name); +gchar *polkit_user_get_user_name (PolkitUser *user); +void polkit_user_set_user_name (PolkitUser *user, + const gchar *user_name); + +G_END_DECLS + +#endif /* __POLKIT_USER_H__ */ diff --git a/src/polkitd/Makefile.am b/src/polkitd/Makefile.am new file mode 100644 index 0000000..7fe92ca --- /dev/null +++ b/src/polkitd/Makefile.am @@ -0,0 +1,39 @@ +NULL = + +INCLUDES = \ + -I$(top_builddir)/src \ + -I$(top_srcdir)/src \ + -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \ + -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \ + -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ + -DPACKAGE_BIN_DIR=\""$(bindir)"\" \ + -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \ + -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \ + -DPACKAGE_LIB_DIR=\""$(libdir)"\" \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + $(NULL) + +libexec_PROGRAMS = polkitd-1 + +polkitd_1_SOURCES = \ + main.c \ + $(NULL) + +polkitd_1_CFLAGS = \ + -I$(top_srcdir)/src \ + -DG_LOG_DOMAIN=\"polkitd-1\" \ + $(DBUS_GLIB_CFLAGS) \ + $(NULL) + +polkitd_1_LDADD = \ + $(DBUS_GLIB_LIBS) \ + $(GLIB_LIBS) \ + $(GIO_LIBS) \ + $(top_builddir)/src/polkit/libpolkit-gobject-1.la \ + $(NULL) + +CLEANFILES = $(BUILT_SOURCES) + +clean-local : + rm -f *~ diff --git a/src/polkitd/main.c b/src/polkitd/main.c new file mode 100644 index 0000000..ab3e24f --- /dev/null +++ b/src/polkitd/main.c @@ -0,0 +1,194 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 David Zeuthen <david@fubar.dk> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <pwd.h> +#include <grp.h> + +#include <glib.h> +#include <glib/gi18n-lib.h> +#include <glib-object.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include <polkit/polkit.h> + +#define NAME_TO_CLAIM "org.freedesktop.PolicyKit1" + +static PolkitBackend * +get_backend (void) +{ + return polkit_local_backend_new (); +} + +static gboolean +acquire_name_on_proxy (DBusGProxy *bus_proxy) +{ + GError *error; + guint result; + gboolean res; + gboolean ret; + + ret = FALSE; + + if (bus_proxy == NULL) { + goto out; + } + + error = NULL; + res = dbus_g_proxy_call (bus_proxy, + "RequestName", + &error, + G_TYPE_STRING, NAME_TO_CLAIM, + G_TYPE_UINT, 0, + G_TYPE_INVALID, + G_TYPE_UINT, &result, + G_TYPE_INVALID); + if (! res) { + if (error != NULL) { + g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message); + g_error_free (error); + } else { + g_warning ("Failed to acquire %s", NAME_TO_CLAIM); + } + goto out; + } + + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + if (error != NULL) { + g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message); + g_error_free (error); + } else { + g_warning ("Failed to acquire %s", NAME_TO_CLAIM); + } + goto out; + } + + ret = TRUE; + + out: + return ret; +} + +int +main (int argc, char **argv) +{ + GError *error; + GMainLoop *loop; + GOptionContext *context; + DBusGProxy *bus_proxy; + DBusGConnection *bus; + int ret; + PolkitBackend *backend; + PolkitBackendStub *stub; + static GOptionEntry entries[] = { + { NULL } + }; + + ret = 1; + backend = NULL; + stub = NULL; + loop = NULL; + bus = NULL; + + g_type_init (); + + context = g_option_context_new ("PolicyKit daemon"); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_parse (context, &argc, &argv, NULL); + g_option_context_free (context); + + error = NULL; + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (bus == NULL) { + g_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + goto out; + } + + bus_proxy = dbus_g_proxy_new_for_name (bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + if (bus_proxy == NULL) { + g_warning ("Could not construct bus_proxy object; bailing out"); + goto out; + } + + if (!acquire_name_on_proxy (bus_proxy) ) { + g_warning ("Could not acquire name; bailing out"); + goto out; + } + + g_debug ("Starting polkitd-1 version %s", VERSION); + + backend = get_backend (); + if (backend == NULL) { + g_warning ("Couldn't find suitable backend to use"); + goto out; + } + + stub = polkit_backend_stub_new (bus, + "/authority", + backend); + + if (stub == NULL) { + goto out; + } + + loop = g_main_loop_new (NULL, FALSE); + + g_main_loop_run (loop); + + ret = 0; + +out: + if (backend != NULL) + g_object_unref (backend); + + if (stub != NULL) + g_object_unref (stub); + + if (loop != NULL) + g_main_loop_unref (loop); + + if (bus != NULL) + dbus_g_connection_unref (bus); + + return ret; +} diff --git a/src/programs/Makefile.am b/src/programs/Makefile.am new file mode 100644 index 0000000..8ba3fe5 --- /dev/null +++ b/src/programs/Makefile.am @@ -0,0 +1,36 @@ + +NULL = + +INCLUDES = \ + -I$(top_builddir)/src \ + -I$(top_srcdir)/src \ + -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \ + -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \ + -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ + -DPACKAGE_BIN_DIR=\""$(bindir)"\" \ + -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \ + -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \ + -DPACKAGE_LIB_DIR=\""$(libdir)"\" \ + -D_POSIX_PTHREAD_SEMANTICS \ + -D_REENTRANT \ + $(NULL) + +bin_PROGRAMS = polkit-verify-claim-1 + +polkit_verify_claim_1_SOURCES = polkit-verify-claim.c + +polkit_verify_claim_1_CFLAGS = \ + $(GLIB_CFLAGS) \ + $(GIO_CFLAGS) \ + $(DBUS_GLIB_CFLAGS) \ + $(NULL) + +polkit_verify_claim_1_LDADD = \ + $(GLIB_LDADD) \ + $(GIO_LDADD) \ + $(DBUS_GLIB_LDADD) \ + $(top_builddir)/src/polkit/libpolkit-gobject-1.la \ + $(NULL) + +clean-local : + rm -f *~ diff --git a/src/programs/polkit-verify-claim.c b/src/programs/polkit-verify-claim.c new file mode 100644 index 0000000..36ad439 --- /dev/null +++ b/src/programs/polkit-verify-claim.c @@ -0,0 +1,101 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include <polkit/polkit.h> + +int +main (int argc, char *argv[]) +{ + GList *ret; + GError *error; + GFile *dir; + + g_type_init (); + + dir = g_file_new_for_commandline_arg (argv[1]); + + error = NULL; + ret = polkit_action_description_new_from_directory (dir, + NULL, + &error); + if (error != NULL) { + g_print ("Got error: %s\n", error->message); + g_error_free (error); + goto out; + } + + g_debug ("rock'n'roll!"); + + g_list_foreach (ret, (GFunc) g_object_unref, NULL); + g_list_free (ret); + + out: + return 0; + +#if 0 + PolkitAuthorizationResult result; + GError *error; + PolkitAuthority *authority; + + g_type_init (); + + authority = polkit_authority_get (); + + PolkitSubject *subject1; + PolkitSubject *subject2; + PolkitSubject *subject3; + + subject1 = polkit_user_new ("moe"); + subject2 = polkit_user_new ("bernie"); + subject3 = polkit_process_new (42); + + GList *claims; + claims = NULL; + claims = g_list_prepend (claims, polkit_authorization_claim_new (subject1, "org.foo.1")); + claims = g_list_prepend (claims, polkit_authorization_claim_new (subject2, "org.foo.2")); + claims = g_list_prepend (claims, polkit_authorization_claim_new (subject3, "org.foo.3")); + + PolkitAuthorizationClaim *claim; + claim = polkit_authorization_claim_new (subject3, "org.foo.4"); + polkit_authorization_claim_set_attribute (claim, "foo", "bar"); + polkit_authorization_claim_set_attribute (claim, "unix-device", "/dev/sda"); + claims = g_list_prepend (claims, claim); + + + error = NULL; + result = polkit_authority_check_claims_sync (authority, + claims, + NULL, + &error); + if (error != NULL) { + g_print ("Got error: %s\n", error->message); + g_error_free (error); + } else { + g_print ("Got result: %d\n", result); + } + + g_object_unref (authority); + + return 0; +#endif +} |