File grantwebyastrights of Package webyast-base

#!/usr/bin/env ruby
#
#--
# Webyast framework
#
# Copyright (C) 2009, 2010 Novell, Inc. 
#   This library is free software; you can redistribute it and/or modify
# it only under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation. 
#
#   This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
# details. 
#
#   You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#++
#
# grantwebyastrights
#
# show, grant and revoke policies for WebYaST
#
# run: grantwebyastrights
#

require 'fileutils'
require 'getoptlong'
require 'rubygems'
require 'yaml'

#checking which policykit is used
WEBYAST_CONFIG_FILE = "/etc/webyast/config.yml"
@polkit1 = true
if File.exist?(WEBYAST_CONFIG_FILE)
  values = YAML::load(File.open(WEBYAST_CONFIG_FILE, 'r').read)
  @polkit1 = false if values["polkit1"] == false
end

STDOUT.puts "Using old PolicyKit" unless @polkit1

if @polkit1
  require 'polkit1'
end

$debug = 0

def usage why
  STDERR.puts why
  STDERR.puts ""
  STDERR.puts "Usage: grantwebyastrights --user <user> --action (show|grant|revoke) [--policy <policy>]"
  STDERR.puts "NOTE: This program should be run by user root"
  STDERR.puts ""
  STDERR.puts ""
  unless @polkit1
    STDERR.puts "This call grant/revoke ALL permissions for the YaST Webservice."
    STDERR.puts "In order to grant/revoke single rights use:"
    STDERR.puts "polkit-auth --user <user> (--grant|-revoke) <policyname>"
    STDERR.puts ""
    STDERR.puts "In order to show all possible permissions use:"
    STDERR.puts "polkit-action"
  else
    STDERR.puts "In order to show all possible permissions use:"
    STDERR.puts "pkaction"
  end
  exit 1
end

options = GetoptLong.new(
  [ "--user",   GetoptLong::REQUIRED_ARGUMENT ],
  [ "--debug",  GetoptLong::OPTIONAL_ARGUMENT ],
  [ "--policy", GetoptLong::OPTIONAL_ARGUMENT ],
  [ "--action", GetoptLong::REQUIRED_ARGUMENT ]
)

user = nil
action = nil
single_policy = nil

begin
  options.each do |opt, arg|
    case opt
    when "--user"; user = arg
    when "--action"; action = arg
    when "--policy"; single_policy = arg
    when "--debug"; $debug += 1
    end
  end
rescue GetoptLong::InvalidOption => o
  usage "Invalid option #{o}"
end

$debug = nil if $debug == 0

usage "excessive arguments"  unless ARGV.empty?
usage "user parameter missing" unless user
usage "action parameter (show|grant|revoke) missing" unless action

SuseString = "org.opensuse.yast"

def webyast_perm?(perm)
  return (perm.include? SuseString) && (not perm.include? ".scr")
end

def granted_perms(user)
   if @polkit1
    perms = webyast_perms
    perms.reject! { |perm| 
      PolKit1::polkit1_check(perm, user) == :no 
    }
  else
    perms = `polkit-auth --user '#{user}' --explicit`
    #do NOT raise if an error happens here cause while the package installation this call returns always an error
    #  raise "polkit-auth failed with ret code #{$?.exitstatus}. Output: #{perms}" unless $?.exitstatus.zero?
    perms = perms.split "\n"
    perms.reject! { |perm| not webyast_perm?(perm) }
  end
  return perms
end

def webyast_perms
  if @polkit1
    perms = `pkaction`
  else
    perms = `polkit-action`
    raise "polkit-action failed with ret code #{$?.exitstatus}. Output: #{perms}" unless $?.exitstatus.zero?
  end
  perms = perms.split "\n"
  perms.reject! { |perm| not webyast_perm?(perm) }
  return perms
end

begin
  case action
  when "grant" then
    unless single_policy == nil
      STDOUT.puts "granting: #{single_policy}"
      if @polkit1
        PolKit1::polkit1_write(single_policy, true, user)
      else
        out = `polkit-auth --user '#{user}' --grant '#{single_policy}'`
        #do NOT raise if an error happens here cause while the package installation this call can return an error for already existing 
        #permissions ( It is not possible to check this before)
        #raise "Granting permissions failed with ret code #{$?.exitstatus}. Output: #{out}" unless $?.exitstatus.zero?
      end
    else
      granted = granted_perms user
      non_granted = webyast_perms.reject{ |perm| granted.include? perm }
      non_granted.each do |policy|
        STDOUT.puts "granting: #{policy}"
        if @polkit1
          PolKit1::polkit1_write(policy, true, user)
        else
          out = `polkit-auth --user '#{user}' --grant '#{policy}'`
          #do NOT raise if an error happens here cause while the package installation this call can return an error for already existing 
          #permissions ( It is not possible to check this before)
          #raise "Granting permissions failed with ret code #{$?.exitstatus}. Output: #{out}" unless $?.exitstatus.zero?
        end
      end
    end
  when "show"
    unless single_policy == nil
      STDOUT.puts single_policy if granted_perms(user).include?(single_policy)
    else
      STDOUT.puts granted_perms(user).join("\n")
    end
  when "revoke"
    unless single_policy == nil
      STDOUT.puts "revoking: #{single_policy}"
      if @polkit1
        PolKit1::polkit1_write(single_policy, false, user)
      else
        out = `polkit-auth --user '#{user}' --revoke '#{single_policy}'`
        raise "Revoking permissions failed with ret code #{$?.exitstatus}. Output: #{out}" unless $?.exitstatus.zero?
      end
    else
      granted = granted_perms user
      granted.each do |policy|
        STDOUT.puts "revoking: #{policy}"
        if @polkit1
          PolKit1::polkit1_write(policy, false, user)
        else
          out = `polkit-auth --user '#{user}' --revoke '#{policy}'`
          raise "Revoking permissions failed with ret code #{$?.exitstatus}. Output: #{out}" unless $?.exitstatus.zero?
        end
      end
    end
  end
rescue Exception => e
  STDERR.puts e.message
  Process.exit! 1
end
openSUSE Build Service is sponsored by