Commit f593e333 authored by Nikos Skalkotos's avatar Nikos Skalkotos

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
......@@ -30,6 +30,7 @@ import re
import os
import uuid
import time
from collections import namedtuple
# For more info see: http://technet.microsoft.com/en-us/library/jj612867.aspx
KMS_CLIENT_SETUP_KEYS = {
......@@ -300,8 +301,16 @@ class Windows(OSBase):
if root == self.root:
self.systemdrive = drive
admin = self.usernames[ADMIN_RID]
self.vm = VM(self.image.device, self.sysprep_params, admin)
active_admins = [u for u in self.admins if u in self.active_users]
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')
def disable_ipv6_privacy_extensions(self):
......@@ -493,9 +502,11 @@ class Windows(OSBase):
self.out.output("Preparing media for boot ...", False)
with self.mount(readonly=False, silent=True):
activated = self.registry.reset_account(ADMIN_RID)
v_val = self.registry.reset_passwd(ADMIN_RID)
disabled_uac = self.registry.update_uac_remote_setting(1)
activated = self.registry.reset_account(self.vm.admin.rid)
v_val = self.registry.reset_passwd(self.vm.admin.rid)
disabled_remote_uac = self.registry.update_uac_remote_setting(1)
disabled_uac = self.registry.update_uac(0)
self._add_boot_scripts()
# disable the firewalls
......@@ -558,15 +569,18 @@ class Windows(OSBase):
self.out.warn("The boot changes cannot be reverted. "
"The snapshot may be in a corrupted state.")
else:
if disabled_uac:
if disabled_remote_uac:
self.registry.update_uac_remote_setting(0)
if disabled_uac:
self.registry.update_uac(1)
if not activated:
self.registry.reset_account(ADMIN_RID, False)
self.registry.reset_account(self.vm.admin.rid, False)
if not self.sysprepped:
# 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.out.success("done")
......@@ -623,7 +637,6 @@ class Windows(OSBase):
next boot.
"""
admin = self.usernames[ADMIN_RID]
commands = {}
# Disable hibernation. This is not needed for a VM
......@@ -634,7 +647,7 @@ class Windows(OSBase):
# This will update the password of the admin user to self.vm.password
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
# self.registry.update_uac_remote_setting(1).
......@@ -665,7 +678,7 @@ class Windows(OSBase):
# defined on the server either by a Group Policy object (GPO) or by a
# local policy.
self.registry.enable_autologon(admin)
self.registry.enable_autologon(self.vm.admin.name)
def _do_collect_metadata(self):
"""Collect metadata about the OS"""
......@@ -821,16 +834,19 @@ class Windows(OSBase):
"""Upload the VirtIO drivers and installation scripts to the media.
"""
with self.mount(readonly=False, silent=True):
v_val = self.registry.reset_passwd(ADMIN_RID)
self._add_cleanup('virtio',
self.registry.reset_passwd, ADMIN_RID, v_val)
v_val = self.registry.reset_passwd(self.vm.admin.rid)
self._add_cleanup('virtio', self.registry.reset_passwd,
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)
self._add_cleanup('virtio',
self.registry.reset_account, ADMIN_RID, active)
if self.registry.update_uac(0):
self._add_cleanup('virtio', self.registry.update_uac, 1)
# 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)
self._add_cleanup(
......
......@@ -283,6 +283,41 @@ class Registry(object):
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):
"""Returns:
a map of RID->username for all users found on the system
......
......@@ -223,8 +223,8 @@ class VM(object):
debug = kwargs['debug'] if 'debug' in kwargs else False
uninstall = kwargs['uninstall'] if 'uninstall' in kwargs else False
winexe = WinEXE(self.admin, 'localhost', password=self.password)
winexe.runas(self.admin, self.password).no_pass()
winexe = WinEXE(self.admin.name, 'localhost', password=self.password)
winexe.no_pass()
if debug:
winexe.debug(9)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment