summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan McLellan <btm@loftninjas.org>2017-07-19 15:26:26 -0400
committerBryan McLellan <btm@loftninjas.org>2017-07-19 15:57:48 -0400
commitd4c860f87fc8ef9fa14d2b9c8ad1183fb6f75535 (patch)
tree45e91338a692951ecf1708290cdace93719a7fa2
parentcb07cc92ec9f5bc5f390bbb2553105525cf18869 (diff)
downloadmixlib-shellout-btm/elevated.tar.gz
Update error messages to indicate user who lacks privilege on Windowsbtm/elevated
In some cases the user running mixlib-shellout needs additional privileges, in other cases the user we're trying to run the process as needs them. Signed-off-by: Bryan McLellan <btm@loftninjas.org>
-rw-r--r--lib/mixlib/shellout/windows/core_ext.rb145
1 files changed, 54 insertions, 91 deletions
diff --git a/lib/mixlib/shellout/windows/core_ext.rb b/lib/mixlib/shellout/windows/core_ext.rb
index 5f78353..f3de488 100644
--- a/lib/mixlib/shellout/windows/core_ext.rb
+++ b/lib/mixlib/shellout/windows/core_ext.rb
@@ -35,7 +35,7 @@ module Process::Constants
WAIT_FAILED = 0xFFFFFFFF
ERROR_PRIVILEGE_NOT_HELD = 1314
- ERROR_LOGON_TYPE_NOT_GRANTED = 0X569
+ ERROR_LOGON_TYPE_NOT_GRANTED = 0x569
end
# Define the functions needed to check with Service windows station
@@ -276,100 +276,14 @@ module Process
# interactive windows station to attach to, which is created with the
# LogonUser cann with the LOGON32_LOGON_INTERACTIVE flag.
if winsta_name =~ /^Service-0x0-.*$/i
- token = FFI::MemoryPointer.new(:ulong)
-
- bool = LogonUserW(
- logon, # User
- domain, # Domain
- passwd, # Password
- LOGON32_LOGON_INTERACTIVE, # Logon Type
- LOGON32_PROVIDER_DEFAULT, # Logon Provider
- token # User token handle
- )
-
- unless bool
- if FFI.errno == ERROR_LOGON_TYPE_NOT_GRANTED
- raise SystemCallError.new("LogonUserW (You must hold `Log on as a service` and `Log on as a batch job` permissions.)", FFI.errno)
- else
- raise SystemCallError.new("LogonUserW", FFI.errno)
- end
- end
+ token = logon_user(logon, domain, passwd, LOGON32_LOGON_INTERACTIVE)
- token = token.read_ulong
-
- begin
- bool = CreateProcessAsUserW(
- token, # User token handle
- app, # App name
- cmd, # Command line
- process_security, # Process attributes
- thread_security, # Thread attributes
- inherit, # Inherit handles
- hash["creation_flags"], # Creation Flags
- env, # Environment
- cwd, # Working directory
- startinfo, # Startup Info
- procinfo # Process Info
- )
-
- unless bool
- if FFI.errno == ERROR_PRIVILEGE_NOT_HELD
- raise SystemCallError.new("CreateProcessAsUserW (You must hold the 'Replace a process level token' permission. Refresh the logon context after adding this right to make it effective.)", FFI.errno)
- else
- raise SystemCallError.new("CreateProcessAsUserW failed.", FFI.errno)
- end
- end
- ensure
- CloseHandle(token)
- end
+ create_process_as_user(token, app, cmd, process_security, thread_security, hash["creation_flags"], env, cwd, startinfo, procinfo)
else
if hash["elevated"]
- token = FFI::MemoryPointer.new(:ulong)
-
- bool = LogonUserW(
- logon, # User
- domain, # Domain
- passwd, # Password
- LOGON32_LOGON_BATCH, # Logon Type
- LOGON32_PROVIDER_DEFAULT, # Logon Provider
- token # User token handle
- )
-
- unless bool
- if FFI.errno == ERROR_LOGON_TYPE_NOT_GRANTED
- raise SystemCallError.new("LogonUserW (You must hold `Log on as a service` and `Log on as a batch job` permissions.)", FFI.errno)
- else
- raise SystemCallError.new("LogonUserW", FFI.errno)
- end
- end
+ token = logon_user(logon, domain, passwd, LOGON32_LOGON_BATCH)
- token = token.read_ulong
-
- begin
- bool = CreateProcessAsUserW(
- token, # User token handle
- app, # App name
- cmd, # Command line
- process_security, # Process attributes
- thread_security, # Thread attributes
- inherit, # Inherit handles
- hash["creation_flags"], # Creation Flags
- env, # Environment
- cwd, # Working directory
- startinfo, # Startup Info
- procinfo # Process Info
- )
-
- unless bool
- if FFI.errno == ERROR_PRIVILEGE_NOT_HELD
- raise SystemCallError.new("CreateProcessAsUserW (You must hold the 'Replace a process level token' permission. Refresh the logon context after adding this right to make it effective.)", FFI.errno)
- else
- raise SystemCallError.new("CreateProcessAsUserW failed.", FFI.errno)
- end
- end
- ensure
- CloseHandle(token)
- end
+ create_process_as_user(token, app, cmd, process_security, thread_security, hash["creation_flags"], env, cwd, startinfo, procinfo)
else
bool = CreateProcessWithLogonW(
logon, # User
@@ -428,5 +342,54 @@ module Process
procinfo[:dwThreadId]
)
end
+
+ def logon_user(user, domain, passwd, type, provider = LOGON32_PROVIDER_DEFAULT)
+ token = FFI::MemoryPointer.new(:ulong)
+
+ bool = LogonUserW(
+ user, # User
+ domain, # Domain
+ passwd, # Password
+ type, # Logon Type
+ provider, # Logon Provider
+ token # User token handle
+ )
+
+ unless bool
+ if (FFI.errno == ERROR_LOGON_TYPE_NOT_GRANTED) && (type == LOGON32_LOGON_BATCH)
+ raise SystemCallError.new("LogonUserW (User '#{user}' must hold 'Log on as a batch job' permissions.)", FFI.errno)
+ else
+ raise SystemCallError.new("LogonUserW", FFI.errno)
+ end
+ end
+
+ token.read_ulong
+ end
+
+ def create_process_as_user(token, app, cmd, process_security, thread_security, inherit, creation_flags, env, cwd, startinfo, procinfo)
+ bool = CreateProcessAsUserW(
+ token, # User token handle
+ app, # App name
+ cmd, # Command line
+ process_security, # Process attributes
+ thread_security, # Thread attributes
+ inherit, # Inherit handles
+ creation_flags, # Creation Flags
+ env, # Environment
+ cwd, # Working directory
+ startinfo, # Startup Info
+ procinfo # Process Info
+ )
+
+ unless bool
+ if FFI.errno == ERROR_PRIVILEGE_NOT_HELD
+ raise SystemCallError.new("CreateProcessAsUserW (User '#{::ENV['USERNAME']}' must hold the 'Replace a process level token' and 'Adjust Memory Quotas for a process' permissions. Logoff the user after adding this right to make it effective.)", FFI.errno)
+ else
+ raise SystemCallError.new("CreateProcessAsUserW failed.", FFI.errno)
+ end
+ end
+ ensure
+ CloseHandle(token)
+ end
end
end