1 /***************************************************************************
   2  * CVSID: $Id$
   3  *
   4  * polkit-is-privileged.c : Determine if a user has privileges
   5  *
   6  * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
   7  *
   8  * This program is free software; you can redistribute it and/or modify
   9  * it under the terms of the GNU General Public License as published by
  10  * the Free Software Foundation; either version 2 of the License, or
  11  * (at your option) any later version.
  12  *
  13  * This program is distributed in the hope that it will be useful,
  14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16  * GNU General Public License for more details.
  17  *
  18  * You should have received a copy of the GNU General Public License
  19  * along with this program; if not, write to the Free Software
  20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  21  *
  22  **************************************************************************/
  23 
  24 
  25 #ifdef HAVE_CONFIG_H
  26 #  include <config.h>
  27 #endif
  28 
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <getopt.h>
  32 #include <dbus/dbus.h>
  33 
  34 #include <libpolkit/libpolkit.h>
  35 
  36 static void
  37 usage (int argc, char *argv[])
  38 {
  39         fprintf (stderr, "polkit-is-privileged version " PACKAGE_VERSION "\n");
  40 
  41         fprintf (stderr, 
  42                  "\n" 
  43                  "usage : %s -u <uid> -p <privilege> [-r <resource>]\n" 
  44                  "        [-s <system-bus-connection-name>]", argv[0]);
  45         fprintf (stderr,
  46                  "\n"
  47                  "Options:\n"
  48                  "    -u, --user                    Username or user id\n"
  49                  "    -s, --system-bus-unique-name  Unique system bus connection name\n"
  50                  "    -r, --resource                Resource\n"
  51                  "    -p, --privilege               Privilege to test for\n"
  52                  "    -h, --help                    Show this information and exit\n"
  53                  "    -v, --verbose                 Verbose operation\n"
  54                  "    -V, --version                 Print version number\n"
  55                  "\n"
  56                  "Queries system policy whether a given user is allowed for a given\n"
  57                  "privilege for a given resource. The resource may be omitted.\n"
  58                  "\n");
  59 }
  60 
  61 int 
  62 main (int argc, char *argv[])
  63 {
  64         int rc;
  65         char *user = NULL;
  66         char *privilege = NULL;
  67         char *resource = NULL;
  68         char *system_bus_unique_name = NULL;
  69         static const struct option long_options[] = {
  70                 {"user", required_argument, NULL, 'u'},
  71                 {"system-bus-unique-name", required_argument, NULL, 's'},
  72                 {"resource", required_argument, NULL, 'r'},
  73                 {"privilege", required_argument, NULL, 'p'},
  74                 {"help", no_argument, NULL, 'h'},
  75                 {"verbose", no_argument, NULL, 'v'},
  76                 {"version", no_argument, NULL, 'V'},
  77                 {NULL, 0, NULL, 0}
  78         };
  79         LibPolKitContext *ctx = NULL;
  80         gboolean is_allowed;
  81         gboolean is_temporary;
  82         LibPolKitResult result;
  83         gboolean is_verbose = FALSE;
  84         DBusError error;
  85         DBusConnection *connection = NULL;
  86 
  87         rc = 1;
  88         
  89         while (TRUE) {
  90                 int c;
  91                 
  92                 c = getopt_long (argc, argv, "u:r:p:s:hVv", long_options, NULL);
  93 
  94                 if (c == -1)
  95                         break;
  96                 
  97                 switch (c) {
  98                 case 's':
  99                         system_bus_unique_name = g_strdup (optarg);
 100                         break;
 101 
 102                 case 'u':
 103                         user = g_strdup (optarg);
 104                         break;
 105                         
 106                 case 'r':
 107                         resource = g_strdup (optarg);
 108                         break;
 109                         
 110                 case 'p':
 111                         privilege = g_strdup (optarg);
 112                         break;
 113                         
 114                 case 'v':
 115                         is_verbose = TRUE;
 116                         break;
 117 
 118                 case 'h':
 119                         usage (argc, argv);
 120                         rc = 0;
 121                         goto out;
 122 
 123                 case 'V':
 124                         printf ("polkit-is-privileged version " PACKAGE_VERSION "\n");
 125                         rc = 0;
 126                         goto out;
 127                         
 128                 default:
 129                         usage (argc, argv);
 130                         goto out;
 131                 }
 132         }
 133 
 134         if (user == NULL || privilege == NULL) {
 135                 usage (argc, argv);
 136                 return 1;
 137         }
 138 
 139         if (is_verbose) {
 140                 printf ("user      = '%s'\n", user);
 141                 printf ("privilege = '%s'\n", privilege);
 142                 if (resource != NULL)
 143                         printf ("resource  = '%s'\n", resource);
 144         }
 145 
 146 #ifdef POLKITD_ENABLED
 147         dbus_error_init (&error);
 148         connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
 149         if (connection == NULL) {
 150                 g_warning ("Cannot connect to system message bus");
 151                 return 1;
 152         }
 153 #endif /* POLKITD_ENABLED */
 154 
 155         ctx = libpolkit_new_context (connection);
 156         if (ctx == NULL) {
 157                 g_warning ("Cannot get libpolkit context");
 158                 goto out;
 159         }
 160 
 161         result = libpolkit_is_uid_allowed_for_privilege (ctx, 
 162                                                          system_bus_unique_name,
 163                                                          user,
 164                                                          privilege,
 165                                                          resource,
 166                                                          &is_allowed,
 167                                                          &is_temporary,
 168                                                          NULL);
 169         switch (result) {
 170         case LIBPOLKIT_RESULT_OK:
 171                 rc = is_allowed ? 0 : 1;
 172                 break;
 173 
 174         case LIBPOLKIT_RESULT_ERROR:
 175                 g_warning ("Error determing whether user is privileged.");
 176                 break;
 177 
 178         case LIBPOLKIT_RESULT_INVALID_CONTEXT:
 179                 g_print ("Invalid context.\n");
 180                 goto out;
 181 
 182         case LIBPOLKIT_RESULT_NOT_PRIVILEGED:
 183                 g_print ("Not privileged.\n");
 184                 goto out;
 185 
 186         case LIBPOLKIT_RESULT_NO_SUCH_PRIVILEGE:
 187                 g_print ("No such privilege '%s'.\n", privilege);
 188                 goto out;
 189 
 190         case LIBPOLKIT_RESULT_NO_SUCH_USER:
 191                 g_print ("No such user '%s'.\n", user);
 192                 goto out;
 193         }
 194 
 195         if (is_verbose) {
 196                 printf ("result %d\n", result);
 197                 printf ("is_allowed %d\n", is_allowed);
 198         }
 199 
 200 out:
 201         if (ctx != NULL)
 202                 libpolkit_free_context (ctx);
 203 
 204         return rc;
 205 }
 206