Module: Puppet::Util::SUIDManager

Extended by:
Forwardable
Includes:
Warnings
Defined in:
lib/puppet/util/suidmanager.rb

Class Method Summary collapse

Methods included from Warnings

clear_warnings, notice_once, warnonce

Class Method Details

.asuser(new_uid = nil, new_gid = nil) ⇒ Object

Runs block setting uid and gid if provided then restoring original ids



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/puppet/util/suidmanager.rb', line 57

def asuser(new_uid=nil, new_gid=nil)
  return yield if Puppet.features.microsoft_windows? or !root?

  old_euid, old_egid = self.euid, self.egid
  begin
    change_group(new_gid) if new_gid
    change_user(new_uid) if new_uid

    yield
  ensure
    change_group(old_egid)
    change_user(old_euid)
  end
end

.change_group(group, permanently = false) ⇒ Object

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/puppet/util/suidmanager.rb', line 73

def change_group(group, permanently=false)
  gid = convert_xid(:gid, group)
  raise Puppet::Error, "No such group #{group}" unless gid

  if permanently
    begin
      Process::GID.change_privilege(gid)
    rescue NotImplementedError
      Process.egid = gid
      Process.gid  = gid
    end
  else
    Process.egid = gid
  end
end

.change_user(user, permanently = false) ⇒ Object

Raises:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/puppet/util/suidmanager.rb', line 90

def change_user(user, permanently=false)
  uid = convert_xid(:uid, user)
  raise Puppet::Error, "No such user #{user}" unless uid

  if permanently
    begin
      Process::UID.change_privilege(uid)
    rescue NotImplementedError
      # If changing uid, we must be root. So initgroups first here.
      initgroups(uid)
      Process.euid = uid
      Process.uid  = uid
    end
  else
    # If we're already root, initgroups before changing euid. If we're not,
    # change euid (to root) first.
    if Process.euid == 0
      initgroups(uid)
      Process.euid = uid
    else
      Process.euid = uid
      initgroups(uid)
    end
  end
end

.convert_xid(type, id) ⇒ Object

Make sure the passed argument is a number.

Raises:

  • (ArgumentError)


118
119
120
121
122
123
124
125
126
# File 'lib/puppet/util/suidmanager.rb', line 118

def convert_xid(type, id)
  map = {:gid => :group, :uid => :user}
  raise ArgumentError, "Invalid id type #{type}" unless map.include?(type)
  ret = Puppet::Util.send(type, id)
  if ret == nil
    raise Puppet::Error, "Invalid #{map[type]}: #{id}"
  end
  ret
end

.groups=(grouplist) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/puppet/util/suidmanager.rb', line 30

def groups=(grouplist)
  if osx_maj_ver == '10.6'
    return true
  else
    return Process.groups = grouplist
  end
end

.initgroups(user) ⇒ Object

Initialize supplementary groups



130
131
132
133
# File 'lib/puppet/util/suidmanager.rb', line 130

def initgroups(user)
  require 'etc'
  Process.initgroups(Etc.getpwuid(user).name, Process.gid)
end

.osx_maj_verObject



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/puppet/util/suidmanager.rb', line 16

def osx_maj_ver
  return @osx_maj_ver unless @osx_maj_ver.nil?
  require 'facter'
  # 'kernel' is available without explicitly loading all facts
  if Facter.value('kernel') != 'Darwin'
    @osx_maj_ver = false
    return @osx_maj_ver
  end
  # But 'macosx_productversion_major' requires it.
  Facter.loadfacts
  @osx_maj_ver = Facter.value('macosx_productversion_major')
end

.root?Boolean

Returns:

  • (Boolean)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/puppet/util/suidmanager.rb', line 39

def self.root?
  return Process.uid == 0 unless Puppet.features.microsoft_windows?

  require 'sys/admin'
  require 'win32/security'
  require 'facter'

  majversion = Facter.value(:kernelmajversion)
  return false unless majversion

  # if Vista or later, check for unrestricted process token
  return Win32::Security.elevated_security? unless majversion.to_f < 6.0

  group = Sys::Admin.get_group("Administrators", :sid => Win32::Security::SID::BuiltinAdministrators)
  group and group.members.index(Sys::Admin.) != nil
end

.run_and_capture(command, new_uid = nil, new_gid = nil) ⇒ Object



137
138
139
140
# File 'lib/puppet/util/suidmanager.rb', line 137

def run_and_capture(command, new_uid=nil, new_gid=nil)
  output = Puppet::Util.execute(command, :failonfail => false, :combine => true, :uid => new_uid, :gid => new_gid)
  [output, $CHILD_STATUS.dup]
end

.system(command, new_uid = nil, new_gid = nil) ⇒ Object



143
144
145
146
147
148
149
150
# File 'lib/puppet/util/suidmanager.rb', line 143

def system(command, new_uid=nil, new_gid=nil)
  status = nil
  asuser(new_uid, new_gid) do
    Kernel.system(command)
    status = $CHILD_STATUS.dup
  end
  status
end