root / image_creator / os_type / windows.py @ 12c97404
History | View | Annotate | Download (10.1 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 | c50c5ae7 | Nikos Skalkotos | from image_creator.util import FatalError, check_guestfs_version, get_command |
41 | aa2062ba | Nikos Skalkotos | |
42 | 76b200cf | Nikos Skalkotos | import hivex |
43 | 76b200cf | Nikos Skalkotos | import tempfile |
44 | 76b200cf | Nikos Skalkotos | import os |
45 | c50c5ae7 | Nikos Skalkotos | import time |
46 | c50c5ae7 | Nikos Skalkotos | import random |
47 | 12c97404 | Nikos Skalkotos | import subprocess |
48 | c50c5ae7 | Nikos Skalkotos | |
49 | c50c5ae7 | Nikos Skalkotos | kvm = get_command('kvm')
|
50 | 76b200cf | Nikos Skalkotos | |
51 | 8c574358 | Nikos Skalkotos | |
52 | aa2062ba | Nikos Skalkotos | class Windows(OSBase): |
53 | 88f83027 | Nikos Skalkotos | """OS class for Windows"""
|
54 | 76b200cf | Nikos Skalkotos | |
55 | 12c97404 | Nikos Skalkotos | def needed_sysprep_params(self): |
56 | 12c97404 | Nikos Skalkotos | """Returns a list of needed sysprep parameters. Each element in the
|
57 | 12c97404 | Nikos Skalkotos | list is a SysprepParam object.
|
58 | 12c97404 | Nikos Skalkotos | """
|
59 | 12c97404 | Nikos Skalkotos | |
60 | 12c97404 | Nikos Skalkotos | password = self.SysprepParam(
|
61 | 12c97404 | Nikos Skalkotos | 'password', 'Image Administrator Password', 20, lambda x: True) |
62 | 12c97404 | Nikos Skalkotos | |
63 | 12c97404 | Nikos Skalkotos | return [password]
|
64 | 12c97404 | Nikos Skalkotos | |
65 | 12c97404 | Nikos Skalkotos | @sysprep(enabled=True) |
66 | 12c97404 | Nikos Skalkotos | def disable_ipv6_privacy_extensions(self, print_header=True): |
67 | 12c97404 | Nikos Skalkotos | """Disable IPv6 privacy extensions"""
|
68 | 12c97404 | Nikos Skalkotos | |
69 | 12c97404 | Nikos Skalkotos | if print_header:
|
70 | 12c97404 | Nikos Skalkotos | self.out.output("Disabling IPv6 privacy extensions") |
71 | 12c97404 | Nikos Skalkotos | |
72 | 12c97404 | Nikos Skalkotos | out, err, rc = self._guest_exec(
|
73 | 12c97404 | Nikos Skalkotos | 'netsh interface ipv6 set global randomizeidentifiers=disabled '
|
74 | 12c97404 | Nikos Skalkotos | 'store=persistent')
|
75 | 12c97404 | Nikos Skalkotos | |
76 | 12c97404 | Nikos Skalkotos | if rc != 0: |
77 | 12c97404 | Nikos Skalkotos | raise FatalError("Unable to disable IPv6 privacy extensions: %s" % |
78 | 12c97404 | Nikos Skalkotos | err) |
79 | 12c97404 | Nikos Skalkotos | |
80 | 12c97404 | Nikos Skalkotos | @sysprep(enabled=True) |
81 | 12c97404 | Nikos Skalkotos | def microsoft_sysprep(self, print_header=True): |
82 | 12c97404 | Nikos Skalkotos | """Run the Micorsoft System Preparation Tool on the Image. After this
|
83 | 12c97404 | Nikos Skalkotos | runs, no other task may run.
|
84 | 12c97404 | Nikos Skalkotos | """
|
85 | 12c97404 | Nikos Skalkotos | |
86 | 12c97404 | Nikos Skalkotos | if print_header:
|
87 | 12c97404 | Nikos Skalkotos | self.out.output("Executing sysprep on the image (may take more " |
88 | 12c97404 | Nikos Skalkotos | "than 10 minutes)")
|
89 | 12c97404 | Nikos Skalkotos | |
90 | 12c97404 | Nikos Skalkotos | out, err, rc = self._guest_exec(r'C:\windows\system32\sysprep\sysprep ' |
91 | 12c97404 | Nikos Skalkotos | r'/quiet /generalize /oobe /shutdown')
|
92 | 12c97404 | Nikos Skalkotos | self.syspreped = True |
93 | 12c97404 | Nikos Skalkotos | if rc != 0: |
94 | 12c97404 | Nikos Skalkotos | raise FatalError("Unable to perform sysprep: %s" % err) |
95 | c50c5ae7 | Nikos Skalkotos | |
96 | 55133880 | Nikos Skalkotos | def do_sysprep(self): |
97 | 55133880 | Nikos Skalkotos | """Prepare system for image creation."""
|
98 | 55133880 | Nikos Skalkotos | |
99 | 55133880 | Nikos Skalkotos | if getattr(self, 'syspreped', False): |
100 | 55133880 | Nikos Skalkotos | raise FatalError("Image is already syspreped!") |
101 | 55133880 | Nikos Skalkotos | |
102 | 12c97404 | Nikos Skalkotos | txt = "System preparation parameter: `%s' is needed but missing!"
|
103 | 12c97404 | Nikos Skalkotos | for param in self.needed_sysprep_params(): |
104 | 12c97404 | Nikos Skalkotos | if param[0] not in self.sysprep_params: |
105 | 12c97404 | Nikos Skalkotos | raise FatalError(txt % param[0]) |
106 | 12c97404 | Nikos Skalkotos | |
107 | 55133880 | Nikos Skalkotos | self.mount(readonly=False) |
108 | 55133880 | Nikos Skalkotos | try:
|
109 | 55133880 | Nikos Skalkotos | disabled_uac = self._update_uac_remote_setting(1) |
110 | 55133880 | Nikos Skalkotos | finally:
|
111 | 55133880 | Nikos Skalkotos | self.umount()
|
112 | 55133880 | Nikos Skalkotos | |
113 | 55133880 | Nikos Skalkotos | self.out.output("Shutting down helper VM ...", False) |
114 | 55133880 | Nikos Skalkotos | self.g.sync()
|
115 | 55133880 | Nikos Skalkotos | # guestfs_shutdown which is the prefered way to shutdown the backend
|
116 | 55133880 | Nikos Skalkotos | # process was introduced in version 1.19.16
|
117 | 55133880 | Nikos Skalkotos | if check_guestfs_version(self.g, 1, 19, 16) >= 0: |
118 | 55133880 | Nikos Skalkotos | ret = self.g.shutdown()
|
119 | 55133880 | Nikos Skalkotos | else:
|
120 | 55133880 | Nikos Skalkotos | ret = self.g.kill_subprocess()
|
121 | 55133880 | Nikos Skalkotos | |
122 | 55133880 | Nikos Skalkotos | self.out.success('done') |
123 | 55133880 | Nikos Skalkotos | try:
|
124 | c50c5ae7 | Nikos Skalkotos | self.out.output("Starting windows VM ...", False) |
125 | c50c5ae7 | Nikos Skalkotos | |
126 | c50c5ae7 | Nikos Skalkotos | def random_mac(): |
127 | c50c5ae7 | Nikos Skalkotos | mac = [0x00, 0x16, 0x3e, |
128 | c50c5ae7 | Nikos Skalkotos | random.randint(0x00, 0x7f), |
129 | c50c5ae7 | Nikos Skalkotos | random.randint(0x00, 0xff), |
130 | c50c5ae7 | Nikos Skalkotos | random.randint(0x00, 0xff)] |
131 | c50c5ae7 | Nikos Skalkotos | return ':'.join(map(lambda x: "%02x" % x, mac)) |
132 | c50c5ae7 | Nikos Skalkotos | |
133 | c50c5ae7 | Nikos Skalkotos | vm = kvm('-smp', '1', '-m', '1024', '-drive', |
134 | c50c5ae7 | Nikos Skalkotos | 'file=%s,format=raw,cache=none,if=virtio' %
|
135 | c50c5ae7 | Nikos Skalkotos | self.image.device,
|
136 | c50c5ae7 | Nikos Skalkotos | '-netdev', 'type=user,hostfwd=tcp::445-:445,id=netdev0', |
137 | c50c5ae7 | Nikos Skalkotos | '-device', 'virtio-net-pci,mac=%s,netdev=netdev0' % |
138 | c50c5ae7 | Nikos Skalkotos | random_mac(), '-vnc', ':0', _bg=True) |
139 | 12c97404 | Nikos Skalkotos | time.sleep(60)
|
140 | c50c5ae7 | Nikos Skalkotos | self.out.success('done') |
141 | 12c97404 | Nikos Skalkotos | |
142 | 12c97404 | Nikos Skalkotos | tasks = self.list_syspreps()
|
143 | 12c97404 | Nikos Skalkotos | enabled = filter(lambda x: x.enabled, tasks) |
144 | 12c97404 | Nikos Skalkotos | |
145 | 12c97404 | Nikos Skalkotos | size = len(enabled)
|
146 | 12c97404 | Nikos Skalkotos | |
147 | 12c97404 | Nikos Skalkotos | # Make sure the ms sysprep is the last task to run if it is enabled
|
148 | 12c97404 | Nikos Skalkotos | enabled = filter(
|
149 | 12c97404 | Nikos Skalkotos | lambda x: x.im_func.func_name != 'microsoft_sysprep', enabled) |
150 | 12c97404 | Nikos Skalkotos | |
151 | 12c97404 | Nikos Skalkotos | ms_sysprep_enabled = False
|
152 | 12c97404 | Nikos Skalkotos | if len(enabled) != size: |
153 | 12c97404 | Nikos Skalkotos | enabled.append(self.ms_sysprep)
|
154 | 12c97404 | Nikos Skalkotos | ms_sysprep_enabled = True
|
155 | 12c97404 | Nikos Skalkotos | |
156 | 12c97404 | Nikos Skalkotos | cnt = 0
|
157 | 12c97404 | Nikos Skalkotos | for task in enabled: |
158 | 12c97404 | Nikos Skalkotos | cnt += 1
|
159 | 12c97404 | Nikos Skalkotos | self.out.output(('(%d/%d)' % (cnt, size)).ljust(7), False) |
160 | 12c97404 | Nikos Skalkotos | task() |
161 | 12c97404 | Nikos Skalkotos | setattr(task.im_func, 'executed', True) |
162 | 12c97404 | Nikos Skalkotos | |
163 | 12c97404 | Nikos Skalkotos | if not ms_sysprep_enabled: |
164 | 12c97404 | Nikos Skalkotos | self._shutdown()
|
165 | 12c97404 | Nikos Skalkotos | |
166 | c50c5ae7 | Nikos Skalkotos | vm.wait() |
167 | 55133880 | Nikos Skalkotos | finally:
|
168 | 12c97404 | Nikos Skalkotos | if vm.process.alive:
|
169 | 12c97404 | Nikos Skalkotos | vm.terminate() |
170 | 12c97404 | Nikos Skalkotos | |
171 | 55133880 | Nikos Skalkotos | self.out.output("Relaunching helper VM (may take a while) ...", |
172 | 55133880 | Nikos Skalkotos | False)
|
173 | 55133880 | Nikos Skalkotos | self.g.launch()
|
174 | 55133880 | Nikos Skalkotos | self.out.success('done') |
175 | 55133880 | Nikos Skalkotos | |
176 | 55133880 | Nikos Skalkotos | if disabled_uac:
|
177 | 55133880 | Nikos Skalkotos | self._update_uac_remote_setting(0) |
178 | 55133880 | Nikos Skalkotos | |
179 | 12c97404 | Nikos Skalkotos | def _shutdown(self): |
180 | 12c97404 | Nikos Skalkotos | """Shuts down the windows VM"""
|
181 | 12c97404 | Nikos Skalkotos | |
182 | 12c97404 | Nikos Skalkotos | self.out.output("Shutting down windows VM ...", False) |
183 | 12c97404 | Nikos Skalkotos | out, err, rc = self._guest_exec(r'shutdown /s /t 5') |
184 | 12c97404 | Nikos Skalkotos | |
185 | 12c97404 | Nikos Skalkotos | if rc != 0: |
186 | 12c97404 | Nikos Skalkotos | raise FatalError("Unable to perform shutdown: %s" % err) |
187 | 12c97404 | Nikos Skalkotos | |
188 | 12c97404 | Nikos Skalkotos | self.out.success('done') |
189 | 55133880 | Nikos Skalkotos | |
190 | 55133880 | Nikos Skalkotos | def _registry_file_path(self, regfile): |
191 | 55133880 | Nikos Skalkotos | """Retrieves the case sensitive path to a registry file"""
|
192 | 55133880 | Nikos Skalkotos | |
193 | 55133880 | Nikos Skalkotos | systemroot = self.g.inspect_get_windows_systemroot(self.root) |
194 | 55133880 | Nikos Skalkotos | path = "%s/system32/config/%s" % (systemroot, regfile)
|
195 | 55133880 | Nikos Skalkotos | try:
|
196 | 55133880 | Nikos Skalkotos | path = self.g.case_sensitive_path(path)
|
197 | 55133880 | Nikos Skalkotos | except RuntimeError as e: |
198 | 55133880 | Nikos Skalkotos | raise FatalError("Unable to retrieve registry file: %s. Reason: %s" |
199 | 55133880 | Nikos Skalkotos | % (regfile, str(e)))
|
200 | 55133880 | Nikos Skalkotos | return path
|
201 | 55133880 | Nikos Skalkotos | |
202 | 55133880 | Nikos Skalkotos | def _update_uac_remote_setting(self, value): |
203 | 55133880 | Nikos Skalkotos | """Updates the registry key value:
|
204 | 55133880 | Nikos Skalkotos | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
|
205 | 55133880 | Nikos Skalkotos | \System]"LocalAccountTokenFilterPolicy"
|
206 | 55133880 | Nikos Skalkotos |
|
207 | 55133880 | Nikos Skalkotos | value = 1 will disable the UAC remote restrictions
|
208 | 55133880 | Nikos Skalkotos | value = 0 will enable the UAC remote restrictions
|
209 | 55133880 | Nikos Skalkotos |
|
210 | 55133880 | Nikos Skalkotos | For more info see here: http://support.microsoft.com/kb/951016
|
211 | 55133880 | Nikos Skalkotos |
|
212 | 55133880 | Nikos Skalkotos | Returns:
|
213 | 55133880 | Nikos Skalkotos | True if the key is changed
|
214 | 55133880 | Nikos Skalkotos | False if the key is unchanged
|
215 | 55133880 | Nikos Skalkotos | """
|
216 | 55133880 | Nikos Skalkotos | |
217 | 55133880 | Nikos Skalkotos | if value not in (0, 1): |
218 | 55133880 | Nikos Skalkotos | raise ValueError("Valid values for value parameter are 0 and 1") |
219 | 55133880 | Nikos Skalkotos | |
220 | 55133880 | Nikos Skalkotos | path = self._registry_file_path('SOFTWARE') |
221 | 55133880 | Nikos Skalkotos | softwarefd, software = tempfile.mkstemp() |
222 | 55133880 | Nikos Skalkotos | try:
|
223 | 55133880 | Nikos Skalkotos | os.close(softwarefd) |
224 | 55133880 | Nikos Skalkotos | self.g.download(path, software)
|
225 | 55133880 | Nikos Skalkotos | |
226 | 55133880 | Nikos Skalkotos | h = hivex.Hivex(software, write=True)
|
227 | 55133880 | Nikos Skalkotos | |
228 | 55133880 | Nikos Skalkotos | key = h.root() |
229 | 55133880 | Nikos Skalkotos | for child in ('Microsoft', 'Windows', 'CurrentVersion', 'Policies', |
230 | 55133880 | Nikos Skalkotos | 'System'):
|
231 | 55133880 | Nikos Skalkotos | key = h.node_get_child(key, child) |
232 | 55133880 | Nikos Skalkotos | |
233 | 55133880 | Nikos Skalkotos | policy = None
|
234 | 55133880 | Nikos Skalkotos | for val in h.node_values(key): |
235 | 55133880 | Nikos Skalkotos | if h.value_key(val) == "LocalAccountTokenFilterPolicy": |
236 | 55133880 | Nikos Skalkotos | policy = val |
237 | 55133880 | Nikos Skalkotos | |
238 | 55133880 | Nikos Skalkotos | if policy is not None: |
239 | 55133880 | Nikos Skalkotos | dword = h.value_dword(policy) |
240 | 55133880 | Nikos Skalkotos | if dword == value:
|
241 | 55133880 | Nikos Skalkotos | return False |
242 | 55133880 | Nikos Skalkotos | elif value == 0: |
243 | 55133880 | Nikos Skalkotos | return False |
244 | 55133880 | Nikos Skalkotos | |
245 | 55133880 | Nikos Skalkotos | new_value = { |
246 | 55133880 | Nikos Skalkotos | 'key': "LocalAccountTokenFilterPolicy", 't': 4L, |
247 | 55133880 | Nikos Skalkotos | 'value': '%s\x00\x00\x00' % '\x00' if value == 0 else '\x01'} |
248 | 55133880 | Nikos Skalkotos | |
249 | 55133880 | Nikos Skalkotos | h.node_set_value(key, new_value) |
250 | 55133880 | Nikos Skalkotos | h.commit(None)
|
251 | 55133880 | Nikos Skalkotos | |
252 | 55133880 | Nikos Skalkotos | self.g.upload(software, path)
|
253 | 55133880 | Nikos Skalkotos | |
254 | 55133880 | Nikos Skalkotos | finally:
|
255 | 55133880 | Nikos Skalkotos | os.unlink(software) |
256 | 55133880 | Nikos Skalkotos | |
257 | 55133880 | Nikos Skalkotos | return True |
258 | 55133880 | Nikos Skalkotos | |
259 | b8c0848c | Nikos Skalkotos | def _do_collect_metadata(self): |
260 | b8c0848c | Nikos Skalkotos | """Collect metadata about the OS"""
|
261 | b8c0848c | Nikos Skalkotos | super(Windows, self)._do_collect_metadata() |
262 | 76b200cf | Nikos Skalkotos | self.meta["USERS"] = " ".join(self._get_users()) |
263 | 76b200cf | Nikos Skalkotos | |
264 | 76b200cf | Nikos Skalkotos | def _get_users(self): |
265 | 121f3bc0 | Nikos Skalkotos | """Returns a list of users found in the images"""
|
266 | 55133880 | Nikos Skalkotos | path = self._registry_file_path('SAM') |
267 | 76b200cf | Nikos Skalkotos | samfd, sam = tempfile.mkstemp() |
268 | 76b200cf | Nikos Skalkotos | try:
|
269 | 55133880 | Nikos Skalkotos | os.close(samfd) |
270 | 76b200cf | Nikos Skalkotos | self.g.download(path, sam)
|
271 | 76b200cf | Nikos Skalkotos | |
272 | 76b200cf | Nikos Skalkotos | h = hivex.Hivex(sam) |
273 | 76b200cf | Nikos Skalkotos | |
274 | 76b200cf | Nikos Skalkotos | key = h.root() |
275 | 76b200cf | Nikos Skalkotos | # Navigate to /SAM/Domains/Account/Users/Names
|
276 | 76b200cf | Nikos Skalkotos | for child in ('SAM', 'Domains', 'Account', 'Users', 'Names'): |
277 | 76b200cf | Nikos Skalkotos | key = h.node_get_child(key, child) |
278 | 76b200cf | Nikos Skalkotos | |
279 | 76b200cf | Nikos Skalkotos | users = [h.node_name(x) for x in h.node_children(key)] |
280 | 76b200cf | Nikos Skalkotos | |
281 | 76b200cf | Nikos Skalkotos | finally:
|
282 | 76b200cf | Nikos Skalkotos | os.unlink(sam) |
283 | 76b200cf | Nikos Skalkotos | |
284 | 76b200cf | Nikos Skalkotos | # Filter out the guest account
|
285 | 76b200cf | Nikos Skalkotos | return filter(lambda x: x != "Guest", users) |
286 | aa2062ba | Nikos Skalkotos | |
287 | 12c97404 | Nikos Skalkotos | def _guest_exec(self, command): |
288 | 12c97404 | Nikos Skalkotos | user = "Administrator%" + self.sysprep_params['password'] |
289 | 12c97404 | Nikos Skalkotos | addr = 'localhost'
|
290 | 12c97404 | Nikos Skalkotos | runas = '--runas=%s' % user
|
291 | 12c97404 | Nikos Skalkotos | winexe = subprocess.Popen( |
292 | 12c97404 | Nikos Skalkotos | ['winexe', '-U', user, "//%s" % addr, runas, command], |
293 | 12c97404 | Nikos Skalkotos | stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
294 | 12c97404 | Nikos Skalkotos | |
295 | 12c97404 | Nikos Skalkotos | result = winexe.communicate() |
296 | 12c97404 | Nikos Skalkotos | rc = winexe.poll() |
297 | 12c97404 | Nikos Skalkotos | |
298 | 12c97404 | Nikos Skalkotos | return (result[0], result[1], rc) |
299 | 12c97404 | Nikos Skalkotos | |
300 | aa2062ba | Nikos Skalkotos | # vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |