Statistics
| Branch: | Tag: | Revision:

root / image_creator / os_type / windows.py @ 55133880

History | View | Annotate | Download (6.2 kB)

1 121f3bc0 Nikos Skalkotos
# -*- coding: utf-8 -*-
2 121f3bc0 Nikos Skalkotos
#
3 ae48a082 Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
4 ae48a082 Nikos Skalkotos
#
5 ae48a082 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
6 ae48a082 Nikos Skalkotos
# without modification, are permitted provided that the following
7 ae48a082 Nikos Skalkotos
# conditions are met:
8 ae48a082 Nikos Skalkotos
#
9 ae48a082 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
10 ae48a082 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
11 ae48a082 Nikos Skalkotos
#      disclaimer.
12 ae48a082 Nikos Skalkotos
#
13 ae48a082 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
14 ae48a082 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
15 ae48a082 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
16 ae48a082 Nikos Skalkotos
#      provided with the distribution.
17 ae48a082 Nikos Skalkotos
#
18 ae48a082 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 ae48a082 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 ae48a082 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 ae48a082 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 ae48a082 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 ae48a082 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 ae48a082 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 ae48a082 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 ae48a082 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 ae48a082 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 ae48a082 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 ae48a082 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
30 ae48a082 Nikos Skalkotos
#
31 ae48a082 Nikos Skalkotos
# The views and conclusions contained in the software and
32 ae48a082 Nikos Skalkotos
# documentation are those of the authors and should not be
33 ae48a082 Nikos Skalkotos
# interpreted as representing official policies, either expressed
34 ae48a082 Nikos Skalkotos
# or implied, of GRNET S.A.
35 ae48a082 Nikos Skalkotos
36 121f3bc0 Nikos Skalkotos
"""This module hosts OS-specific code common for the various Microsoft
37 121f3bc0 Nikos Skalkotos
Windows OSs."""
38 121f3bc0 Nikos Skalkotos
39 55133880 Nikos Skalkotos
from image_creator.os_type import OSBase, sysprep
40 55133880 Nikos Skalkotos
from image_creator.util import FatalError, check_guestfs_version
41 aa2062ba Nikos Skalkotos
42 76b200cf Nikos Skalkotos
import hivex
43 76b200cf Nikos Skalkotos
import tempfile
44 76b200cf Nikos Skalkotos
import os
45 76b200cf Nikos Skalkotos
46 8c574358 Nikos Skalkotos
47 aa2062ba Nikos Skalkotos
class Windows(OSBase):
48 88f83027 Nikos Skalkotos
    """OS class for Windows"""
49 76b200cf Nikos Skalkotos
50 55133880 Nikos Skalkotos
    @sysprep(enabled=False)
51 55133880 Nikos Skalkotos
    def remove_user_accounts(self, print_header=True):
52 55133880 Nikos Skalkotos
        """Remove all user accounts with id greater than 1000"""
53 55133880 Nikos Skalkotos
        pass
54 55133880 Nikos Skalkotos
 
55 55133880 Nikos Skalkotos
    def do_sysprep(self):
56 55133880 Nikos Skalkotos
        """Prepare system for image creation."""
57 55133880 Nikos Skalkotos
58 55133880 Nikos Skalkotos
        if getattr(self, 'syspreped', False):
59 55133880 Nikos Skalkotos
            raise FatalError("Image is already syspreped!")
60 55133880 Nikos Skalkotos
61 55133880 Nikos Skalkotos
        self.mount(readonly=False)
62 55133880 Nikos Skalkotos
        try:
63 55133880 Nikos Skalkotos
            disabled_uac = self._update_uac_remote_setting(1)
64 55133880 Nikos Skalkotos
        finally:
65 55133880 Nikos Skalkotos
            self.umount()
66 55133880 Nikos Skalkotos
67 55133880 Nikos Skalkotos
        self.out.output("Shutting down helper VM ...", False)
68 55133880 Nikos Skalkotos
        self.g.sync()
69 55133880 Nikos Skalkotos
        # guestfs_shutdown which is the prefered way to shutdown the backend
70 55133880 Nikos Skalkotos
        # process was introduced in version 1.19.16
71 55133880 Nikos Skalkotos
        if check_guestfs_version(self.g, 1, 19, 16) >= 0:
72 55133880 Nikos Skalkotos
            ret = self.g.shutdown()
73 55133880 Nikos Skalkotos
        else:
74 55133880 Nikos Skalkotos
            ret = self.g.kill_subprocess()
75 55133880 Nikos Skalkotos
76 55133880 Nikos Skalkotos
        self.out.success('done')
77 55133880 Nikos Skalkotos
78 55133880 Nikos Skalkotos
        self.out.output("Starting windows VM ...", False)
79 55133880 Nikos Skalkotos
        try:
80 55133880 Nikos Skalkotos
            pass
81 55133880 Nikos Skalkotos
        finally:
82 55133880 Nikos Skalkotos
            self.out.output("Relaunching helper VM (may take a while) ...",
83 55133880 Nikos Skalkotos
                            False)
84 55133880 Nikos Skalkotos
            self.g.launch()
85 55133880 Nikos Skalkotos
            self.out.success('done')
86 55133880 Nikos Skalkotos
87 55133880 Nikos Skalkotos
        if disabled_uac:
88 55133880 Nikos Skalkotos
            self._update_uac_remote_setting(0)
89 55133880 Nikos Skalkotos
90 55133880 Nikos Skalkotos
        self.syspreped = True
91 55133880 Nikos Skalkotos
92 55133880 Nikos Skalkotos
    def _registry_file_path(self, regfile):
93 55133880 Nikos Skalkotos
        """Retrieves the case sensitive path to a registry file"""
94 55133880 Nikos Skalkotos
95 55133880 Nikos Skalkotos
        systemroot = self.g.inspect_get_windows_systemroot(self.root)
96 55133880 Nikos Skalkotos
        path = "%s/system32/config/%s" % (systemroot, regfile)
97 55133880 Nikos Skalkotos
        try:
98 55133880 Nikos Skalkotos
            path = self.g.case_sensitive_path(path)
99 55133880 Nikos Skalkotos
        except RuntimeError as e:
100 55133880 Nikos Skalkotos
            raise FatalError("Unable to retrieve registry file: %s. Reason: %s"
101 55133880 Nikos Skalkotos
                             % (regfile, str(e)))
102 55133880 Nikos Skalkotos
        return path
103 55133880 Nikos Skalkotos
104 55133880 Nikos Skalkotos
    def _update_uac_remote_setting(self, value):
105 55133880 Nikos Skalkotos
        """Updates the registry key value:
106 55133880 Nikos Skalkotos
        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
107 55133880 Nikos Skalkotos
        \System]"LocalAccountTokenFilterPolicy"
108 55133880 Nikos Skalkotos

109 55133880 Nikos Skalkotos
        value = 1 will disable the UAC remote restrictions
110 55133880 Nikos Skalkotos
        value = 0 will enable the UAC remote restrictions
111 55133880 Nikos Skalkotos

112 55133880 Nikos Skalkotos
        For more info see here: http://support.microsoft.com/kb/951016
113 55133880 Nikos Skalkotos

114 55133880 Nikos Skalkotos
        Returns:
115 55133880 Nikos Skalkotos
            True if the key is changed
116 55133880 Nikos Skalkotos
            False if the key is unchanged
117 55133880 Nikos Skalkotos
        """
118 55133880 Nikos Skalkotos
119 55133880 Nikos Skalkotos
        if value not in (0, 1):
120 55133880 Nikos Skalkotos
            raise ValueError("Valid values for value parameter are 0 and 1")
121 55133880 Nikos Skalkotos
122 55133880 Nikos Skalkotos
        path = self._registry_file_path('SOFTWARE')
123 55133880 Nikos Skalkotos
        softwarefd, software = tempfile.mkstemp()
124 55133880 Nikos Skalkotos
        try:
125 55133880 Nikos Skalkotos
            os.close(softwarefd)
126 55133880 Nikos Skalkotos
            self.g.download(path, software)
127 55133880 Nikos Skalkotos
128 55133880 Nikos Skalkotos
            h = hivex.Hivex(software, write=True)
129 55133880 Nikos Skalkotos
130 55133880 Nikos Skalkotos
            key = h.root()
131 55133880 Nikos Skalkotos
            for child in ('Microsoft', 'Windows', 'CurrentVersion', 'Policies',
132 55133880 Nikos Skalkotos
                          'System'):
133 55133880 Nikos Skalkotos
                key = h.node_get_child(key, child)
134 55133880 Nikos Skalkotos
135 55133880 Nikos Skalkotos
            policy = None
136 55133880 Nikos Skalkotos
            for val in h.node_values(key):
137 55133880 Nikos Skalkotos
                if h.value_key(val) == "LocalAccountTokenFilterPolicy":
138 55133880 Nikos Skalkotos
                    policy = val
139 55133880 Nikos Skalkotos
140 55133880 Nikos Skalkotos
            if policy is not None:
141 55133880 Nikos Skalkotos
                dword = h.value_dword(policy)
142 55133880 Nikos Skalkotos
                if dword == value:
143 55133880 Nikos Skalkotos
                    return False
144 55133880 Nikos Skalkotos
            elif value == 0:
145 55133880 Nikos Skalkotos
                return False
146 55133880 Nikos Skalkotos
147 55133880 Nikos Skalkotos
            new_value = {
148 55133880 Nikos Skalkotos
                'key': "LocalAccountTokenFilterPolicy", 't': 4L,
149 55133880 Nikos Skalkotos
                'value': '%s\x00\x00\x00' % '\x00' if value == 0 else '\x01'}
150 55133880 Nikos Skalkotos
151 55133880 Nikos Skalkotos
            h.node_set_value(key, new_value)
152 55133880 Nikos Skalkotos
            h.commit(None)
153 55133880 Nikos Skalkotos
154 55133880 Nikos Skalkotos
            self.g.upload(software, path)
155 55133880 Nikos Skalkotos
156 55133880 Nikos Skalkotos
        finally:
157 55133880 Nikos Skalkotos
            os.unlink(software)
158 55133880 Nikos Skalkotos
159 55133880 Nikos Skalkotos
        return True
160 55133880 Nikos Skalkotos
161 b8c0848c Nikos Skalkotos
    def _do_collect_metadata(self):
162 b8c0848c Nikos Skalkotos
        """Collect metadata about the OS"""
163 b8c0848c Nikos Skalkotos
        super(Windows, self)._do_collect_metadata()
164 76b200cf Nikos Skalkotos
        self.meta["USERS"] = " ".join(self._get_users())
165 76b200cf Nikos Skalkotos
166 76b200cf Nikos Skalkotos
    def _get_users(self):
167 121f3bc0 Nikos Skalkotos
        """Returns a list of users found in the images"""
168 55133880 Nikos Skalkotos
        path = self._registry_file_path('SAM')
169 76b200cf Nikos Skalkotos
        samfd, sam = tempfile.mkstemp()
170 76b200cf Nikos Skalkotos
        try:
171 55133880 Nikos Skalkotos
            os.close(samfd)
172 76b200cf Nikos Skalkotos
            self.g.download(path, sam)
173 76b200cf Nikos Skalkotos
174 76b200cf Nikos Skalkotos
            h = hivex.Hivex(sam)
175 76b200cf Nikos Skalkotos
176 76b200cf Nikos Skalkotos
            key = h.root()
177 76b200cf Nikos Skalkotos
            # Navigate to /SAM/Domains/Account/Users/Names
178 76b200cf Nikos Skalkotos
            for child in ('SAM', 'Domains', 'Account', 'Users', 'Names'):
179 76b200cf Nikos Skalkotos
                key = h.node_get_child(key, child)
180 76b200cf Nikos Skalkotos
181 76b200cf Nikos Skalkotos
            users = [h.node_name(x) for x in h.node_children(key)]
182 76b200cf Nikos Skalkotos
183 76b200cf Nikos Skalkotos
        finally:
184 76b200cf Nikos Skalkotos
            os.unlink(sam)
185 76b200cf Nikos Skalkotos
186 76b200cf Nikos Skalkotos
        # Filter out the guest account
187 76b200cf Nikos Skalkotos
        return filter(lambda x: x != "Guest", users)
188 aa2062ba Nikos Skalkotos
189 aa2062ba Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :