Module: ExecSandbox::Users
- Defined in:
- lib/exec_sandbox/users.rb
Overview
Manages sandbox users.
Class Method Summary collapse
-
.create(user_name, primary_group_name = nil) ⇒ Fixnum
Creates a user for unprivileged operations.
-
.destroy(user_name) ⇒ Object
Removes a user that was previously created by create.
-
.destroy_temps(prefix = 'xsbx.rb') ⇒ Array<String>
Destroys users created by temp.
-
.named(pattern) ⇒ Array<String>
Finds users whose names match a String or Regexp pattern.
-
.temp(prefix = 'xsbx.rb') ⇒ String
Creates an unprivileged user.
Class Method Details
.create(user_name, primary_group_name = nil) ⇒ Fixnum
Creates a user for unprivileged operations.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/exec_sandbox/users.rb', line 37 def self.create(user_name, primary_group_name = nil) group_id = primary_group_name && Etc.getgrnam(primary_group_name).gid if RUBY_PLATFORM =~ /darwin/ # OSX home_dir = "/Users/#{user_name}" unless group_id # Create a group with the same name as the user. group_id = `dscl . -list /Groups`.split. map { |g| `dscl . -read /Groups/#{g} PrimaryGroupID`.split.last. to_i }.sort.last + 1 # Simulate adduser's group creation. command_prefix = ['dscl', '.', '-create', "/Groups/#{user_name}"] [ [], ['PrimaryGroupID', group_id.to_s], ].each do |command_suffix| command = command_prefix + command_suffix unless Kernel.system(*command) raise RuntimeError, "User creation failed at #{command.inspect}!" end end end # Find an available UID. user_id = `dscl . -list /Users`.split. map { |u| `dscl . -read /Users/#{u} UniqueID`.split.last.to_i }. sort.last + 1 # Simulate adduser. command_prefix = ['dscl', '.', '-create', "/Users/#{user_name}"] [ [], ['UserShell', '/bin/bash'], ['UniqueID', user_id.to_s], ['PrimaryGroupID', group_id.to_s], ['NFSHomeDirectory', home_dir], ].each do |command_suffix| command = command_prefix + command_suffix unless Kernel.system(*command) raise RuntimeError, "User creation failed at #{command.inspect}!" end end elsif RUBY_PLATFORM =~ /win/ # Windows raise 'Windows is not supported; patches welcome!' else # Linux if group_id command = ['useradd', '--gid', group_id.to_s, '--no-user-group', '--no-create-home', '--system', '--comment', 'exec_sandbox.rb temporary user', user_name] else command = ['useradd', '--user-group', '--no-create-home', '--system', '--comment', 'exec_sandbox.rb temporary user', user_name] end unless Kernel.system(*command) raise RuntimeError, "User creation failed at #{command.inspect}!" end home_dir = File.join '/home', user_name user_id = Etc.getpwnam(user_name).uid group_id = Etc.getpwnam(user_name).gid end # RUBY_PLATFORM FileUtils.mkdir_p home_dir FileUtils.chown_R user_id, group_id, home_dir FileUtils.chmod_R 0750, home_dir user_id end |
.destroy(user_name) ⇒ Object
Removes a user that was previously created by create.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/exec_sandbox/users.rb', line 112 def self.destroy(user_name) user_pw = Etc.getpwnam(user_name) home_dir = user_pw.dir FileUtils.rm_rf home_dir user_gid = user_pw.gid group_name = Etc.getgrgid(user_gid).name # If the group name matches the user name, the group is a temp. destroy_group = user_name == group_name if RUBY_PLATFORM =~ /darwin/ # OSX command = ['dscl', '.', '-delete', "/Users/#{user_name}"] unless Kernel.system(*command) raise RuntimeError, "User removal failed at #{command.inspect}!" end if destroy_group command = ['dscl', '.', '-delete', "/Groups/#{group_name}"] unless Kernel.system(*command) raise RuntimeError, "User removal failed at #{command.inspect}!" end end elsif RUBY_PLATFORM =~ /win/ # Windows raise 'Windows is not supported; patches welcome!' ['userdel', git_user] else # Linux command = ['userdel', user_name] unless Kernel.system(*command) raise RuntimeError, "User removal failed at #{command.inspect}!" end if destroy_group # Make sure that the group exists. userdel might remove it. begin Etc.getgrnam(group_name) rescue ArgumentError destroy_group = false end end if destroy_group command = ['groupdel', group_name] unless Kernel.system(*command) raise RuntimeError, "User removal failed at #{command.inspect}!" end end end # RUBY_PLATFORM end |
.destroy_temps(prefix = 'xsbx.rb') ⇒ Array<String>
Destroys users created by temp.
175 176 177 178 179 180 |
# File 'lib/exec_sandbox/users.rb', line 175 def self.destroy_temps(prefix = 'xsbx.rb') # Matches the names created by temp. pattern = /^#{prefix}\-[0-9a-f]+\.[0-9a-f]+\.[0-9a-f]+$/ # Each returns the collection that it iterates over. self.named(pattern).each { |name| destroy name } end |
.named(pattern) ⇒ Array<String>
Finds users whose names match a String or Regexp pattern.
163 164 165 166 167 168 169 |
# File 'lib/exec_sandbox/users.rb', line 163 def self.named(pattern) users = [] Etc.passwd do |user| users << user.name if pattern === user.name end users end |
.temp(prefix = 'xsbx.rb') ⇒ String
Creates an unprivileged user.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/exec_sandbox/users.rb', line 14 def self.temp(prefix = 'xsbx.rb') loop do user_name = prefix + '-%x.%x.%x' % [$PID, Time.now.to_i, rand(65536)] etc = nil begin etc = Etc.getpwnam(name) rescue ArgumentError # User not found: good! end next if etc create user_name return user_name end end |