How can I run a Perl script as root yet still affect user gconf settings

我的梦境 提交于 2019-12-19 03:37:08

问题


THE NEW QUERY: I am trying to make a unified script that initializes a new Ubuntu install to my liking, it must be run under sudo to install packages, but using gconftool-2 to affect gconf setting relies on the dbus session which is not handled properly by the method of simply changing UID in the script alone. Does someone know how to manage to do this?

OLD QUERY: I am writing a Perl script to be executed on first boot of a new Ubuntu install. This is to ease adding repositories, installing packages, and setting gconf settings. My problem is permissions. To install packages I need the script to be executed as sudo, but then the gconftool-2 call act on the root user and not on my personal user.


回答1:


You can change uids in the middle of the script by altering the uid with POSIX::setuid() (see perldoc POSIX):

use POSIX 'setuid';

# call cpan to install modules...

POSIX::setuid($newuid);

# ... continue with script



回答2:


You can use sudo again to drop your root privileges like:

sudo -u 'your_username' gfconftool-2



回答3:


After much reading and trial and error it seems that what is missing when you run a script as root is that the DBUS_SESSION_BUS_ADDRESS environment variable is not set. This must be set AND the uid changed to that of the user before the gconf settings can be set. This is my test script that I used to try it out. Run one or the other of the system calls at the end to switch the window button order. Try the script as the user or as root (sudo) to see that it works.

#!/usr/bin/perl

use strict;
use warnings;

use POSIX;

# get the user's name (as opposed to root)
my $user_name = getlogin();
# get the uid of the user by name
my $user_uid = getpwnam($user_name);
print $user_name . ": " . $user_uid . "\n";

my %dbus;
# get the DBUS machine ID
$dbus{'machine_id'} = qx{cat /var/lib/dbus/machine-id};
chomp( $dbus{'machine_id'} );
# read the user's DBUS session file to get variable DBUS_SESSION_BUS_ADDRESS
$dbus{'file'} = "/home/" . $user_name . "/.dbus/session-bus/" . $dbus{'machine_id'} . "-0";
print "checking DBUS file: " . $dbus{'file'} . "\n";
if (-e $dbus{'file'}) { 
  open(my $fh, '<', $dbus{'file'}) or die "Cannot open $dbus{file}";
  while(<$fh>) {
    if ( /^DBUS_SESSION_BUS_ADDRESS=(.*)$/ ) {
      $dbus{'address'} = $1;
      print "Found DBUS address: " . $dbus{'address'} . "\n";
    }
  }
} else {
  print "cannot find DBUS file";
}

# set the uid to the user's uid not root's
POSIX::setuid($user_uid);
# set the DBUS_SESSION_BUS_ADDRESS environment variable
$ENV{'DBUS_SESSION_BUS_ADDRESS'} = $dbus{'address'};

my $command1 = 'gconftool-2 --set "/apps/metacity/general/button_layout" --type string "menu:maximize,minimize,close"';
my $command2 = 'gconftool-2 --set "/apps/metacity/general/button_layout" --type string "menu:minimize,maximize,close"';
system($command1);
## or
#system($command2);

Note: Got some good info here.



来源:https://stackoverflow.com/questions/3875715/how-can-i-run-a-perl-script-as-root-yet-still-affect-user-gconf-settings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!