Skip to content
Snippets Groups Projects
Commit f593e333 authored by Nikos Skalkotos's avatar Nikos Skalkotos
Browse files

windows: Disable UAC before booting the windows VM

This is handy because this way we don't need to unlock the
Administrator account if it is locked. Any user that is in the
Administrators group can do the job.
parent b0f3df81
No related branches found
No related tags found
No related merge requests found
...@@ -30,6 +30,7 @@ import re ...@@ -30,6 +30,7 @@ import re
import os import os
import uuid import uuid
import time import time
from collections import namedtuple
# For more info see: http://technet.microsoft.com/en-us/library/jj612867.aspx # For more info see: http://technet.microsoft.com/en-us/library/jj612867.aspx
KMS_CLIENT_SETUP_KEYS = { KMS_CLIENT_SETUP_KEYS = {
...@@ -300,8 +301,16 @@ class Windows(OSBase): ...@@ -300,8 +301,16 @@ class Windows(OSBase):
if root == self.root: if root == self.root:
self.systemdrive = drive self.systemdrive = drive
admin = self.usernames[ADMIN_RID] active_admins = [u for u in self.admins if u in self.active_users]
self.vm = VM(self.image.device, self.sysprep_params, admin) if ADMIN_RID in self.active_users or len(active_admins) == 0:
admin = ADMIN_RID
else:
active_admins.sort()
admin = active_admins[0]
self.vm = VM(
self.image.device, self.sysprep_params,
namedtuple('User', 'rid name')(admin, self.usernames[admin]))
@sysprep('Disabling IPv6 privacy extensions') @sysprep('Disabling IPv6 privacy extensions')
def disable_ipv6_privacy_extensions(self): def disable_ipv6_privacy_extensions(self):
...@@ -493,9 +502,11 @@ class Windows(OSBase): ...@@ -493,9 +502,11 @@ class Windows(OSBase):
self.out.output("Preparing media for boot ...", False) self.out.output("Preparing media for boot ...", False)
with self.mount(readonly=False, silent=True): with self.mount(readonly=False, silent=True):
activated = self.registry.reset_account(ADMIN_RID) activated = self.registry.reset_account(self.vm.admin.rid)
v_val = self.registry.reset_passwd(ADMIN_RID) v_val = self.registry.reset_passwd(self.vm.admin.rid)
disabled_uac = self.registry.update_uac_remote_setting(1) disabled_remote_uac = self.registry.update_uac_remote_setting(1)
disabled_uac = self.registry.update_uac(0)
self._add_boot_scripts() self._add_boot_scripts()
# disable the firewalls # disable the firewalls
...@@ -558,15 +569,18 @@ class Windows(OSBase): ...@@ -558,15 +569,18 @@ class Windows(OSBase):
self.out.warn("The boot changes cannot be reverted. " self.out.warn("The boot changes cannot be reverted. "
"The snapshot may be in a corrupted state.") "The snapshot may be in a corrupted state.")
else: else:
if disabled_uac: if disabled_remote_uac:
self.registry.update_uac_remote_setting(0) self.registry.update_uac_remote_setting(0)
if disabled_uac:
self.registry.update_uac(1)
if not activated: if not activated:
self.registry.reset_account(ADMIN_RID, False) self.registry.reset_account(self.vm.admin.rid, False)
if not self.sysprepped: if not self.sysprepped:
# Reset the old password # Reset the old password
self.registry.reset_passwd(ADMIN_RID, v_val) self.registry.reset_passwd(self.vm.admin.rid, v_val)
self.registry.update_firewalls(*firewall_states) self.registry.update_firewalls(*firewall_states)
self.out.success("done") self.out.success("done")
...@@ -623,7 +637,6 @@ class Windows(OSBase): ...@@ -623,7 +637,6 @@ class Windows(OSBase):
next boot. next boot.
""" """
admin = self.usernames[ADMIN_RID]
commands = {} commands = {}
# Disable hibernation. This is not needed for a VM # Disable hibernation. This is not needed for a VM
...@@ -634,7 +647,7 @@ class Windows(OSBase): ...@@ -634,7 +647,7 @@ class Windows(OSBase):
# This will update the password of the admin user to self.vm.password # This will update the password of the admin user to self.vm.password
commands["UpdatePassword"] = "net user %s %s" % \ commands["UpdatePassword"] = "net user %s %s" % \
(admin, self.vm.password) (self.vm.admin.name, self.vm.password)
# This is previously done with hivex when we executed # This is previously done with hivex when we executed
# self.registry.update_uac_remote_setting(1). # self.registry.update_uac_remote_setting(1).
...@@ -665,7 +678,7 @@ class Windows(OSBase): ...@@ -665,7 +678,7 @@ class Windows(OSBase):
# defined on the server either by a Group Policy object (GPO) or by a # defined on the server either by a Group Policy object (GPO) or by a
# local policy. # local policy.
self.registry.enable_autologon(admin) self.registry.enable_autologon(self.vm.admin.name)
def _do_collect_metadata(self): def _do_collect_metadata(self):
"""Collect metadata about the OS""" """Collect metadata about the OS"""
...@@ -821,16 +834,19 @@ class Windows(OSBase): ...@@ -821,16 +834,19 @@ class Windows(OSBase):
"""Upload the VirtIO drivers and installation scripts to the media. """Upload the VirtIO drivers and installation scripts to the media.
""" """
with self.mount(readonly=False, silent=True): with self.mount(readonly=False, silent=True):
v_val = self.registry.reset_passwd(ADMIN_RID) v_val = self.registry.reset_passwd(self.vm.admin.rid)
self._add_cleanup('virtio', self._add_cleanup('virtio', self.registry.reset_passwd,
self.registry.reset_passwd, ADMIN_RID, v_val) self.vm.admin.rid, v_val)
active = self.registry.reset_account(self.vm.admin.rid)
self._add_cleanup('virtio', self.registry.reset_account,
self.vm.admin.rid, active)
active = self.registry.reset_account(ADMIN_RID) if self.registry.update_uac(0):
self._add_cleanup('virtio', self._add_cleanup('virtio', self.registry.update_uac, 1)
self.registry.reset_account, ADMIN_RID, active)
# We disable this with powershell scripts # We disable this with powershell scripts
self.registry.enable_autologon(self.usernames[ADMIN_RID]) self.registry.enable_autologon(self.vm.admin.name)
active = self.registry.reset_first_logon_animation(False) active = self.registry.reset_first_logon_animation(False)
self._add_cleanup( self._add_cleanup(
......
...@@ -283,6 +283,41 @@ class Registry(object): ...@@ -283,6 +283,41 @@ class Registry(object):
return True return True
def update_uac(self, value):
"""Enable or disable the User Account Control by changing the value of
the EnableLUA registry key
value = 1 will enable the UAC
value = 0 will disable the UAC
Returns:
True if the key is changed
False if the key is unchanged
"""
if value not in (0, 1):
raise ValueError("Valid values for value parameter are 0 and 1")
with self.open_hive('SOFTWARE', write=True) as hive:
path = 'Microsoft/Windows/CurrentVersion/Policies/System'
system = traverse(hive, path)
enablelua = None
for val in hive.node_values(system):
if hive.value_key(val) == 'EnableLUA':
enablelua = val
if enablelua is not None:
if value == hive.value_dword(enablelua):
return False
elif value == 1:
return False
hive.node_set_value(system, REG_DWORD('EnableLUA', value))
hive.commit(None)
return True
def enum_users(self): def enum_users(self):
"""Returns: """Returns:
a map of RID->username for all users found on the system a map of RID->username for all users found on the system
......
...@@ -223,8 +223,8 @@ class VM(object): ...@@ -223,8 +223,8 @@ class VM(object):
debug = kwargs['debug'] if 'debug' in kwargs else False debug = kwargs['debug'] if 'debug' in kwargs else False
uninstall = kwargs['uninstall'] if 'uninstall' in kwargs else False uninstall = kwargs['uninstall'] if 'uninstall' in kwargs else False
winexe = WinEXE(self.admin, 'localhost', password=self.password) winexe = WinEXE(self.admin.name, 'localhost', password=self.password)
winexe.runas(self.admin, self.password).no_pass() winexe.no_pass()
if debug: if debug:
winexe.debug(9) winexe.debug(9)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment