forked from shaba/openuds
* Adding actors support for linux (based on old actor)
This commit is contained in:
parent
85a32cf667
commit
418fac20e5
@ -33,6 +33,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
from PyQt4 import QtCore, QtGui
|
||||
import six
|
||||
|
||||
from udsactor import store
|
||||
from udsactor import REST
|
||||
@ -48,7 +49,7 @@ class MyForm(QtGui.QDialog):
|
||||
self.ui = Ui_UdsActorSetupDialog()
|
||||
self.ui.setupUi(self)
|
||||
if data is not None:
|
||||
logger.debug('Setting configuration parameters in form')
|
||||
logger.debug('Setting configuration parameters in form: {}'.format(data))
|
||||
self.ui.host.setText(data.get('host', ''))
|
||||
self.ui.masterKey.setText(data.get('masterKey', ''))
|
||||
self.ui.useSSl.setCurrentIndex(1 if data.get('ssl', False) is True else 0)
|
||||
@ -56,8 +57,8 @@ class MyForm(QtGui.QDialog):
|
||||
|
||||
def _getCfg(self):
|
||||
return {
|
||||
'host': unicode(self.ui.host.text()),
|
||||
'masterKey': unicode(self.ui.masterKey.text()),
|
||||
'host': six.text_type(self.ui.host.text()),
|
||||
'masterKey': six.text_type(self.ui.masterKey.text()),
|
||||
'ssl': self.ui.useSSl.currentIndex() == 1,
|
||||
'logLevel': (self.ui.logLevelComboBox.currentIndex() + 1) * 10000
|
||||
}
|
||||
@ -104,7 +105,7 @@ if __name__ == "__main__":
|
||||
cfg = store.readConfig()
|
||||
|
||||
if cfg is not None:
|
||||
logger.setLevel(cfg.get('logLevel', 20000))
|
||||
logger.setLevel(int(cfg.get('logLevel', 20000)))
|
||||
else:
|
||||
logger.setLevel(20000)
|
||||
|
||||
|
@ -209,8 +209,8 @@ def testRemote():
|
||||
|
||||
if __name__ == '__main__':
|
||||
# ipcServer()
|
||||
ipcTest()
|
||||
# testRest()
|
||||
# ipcTest()
|
||||
testRest()
|
||||
# testIdle()
|
||||
# testServer()
|
||||
# testRemote()
|
||||
|
@ -29,14 +29,14 @@
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import SimpleHTTPServer
|
||||
import SocketServer
|
||||
|
||||
import threading
|
||||
import uuid
|
||||
import json
|
||||
from base64 import decodestring
|
||||
import six
|
||||
from six.moves import socketserver # @UnresolvedImport, pylint: disable=import-error
|
||||
from six.moves import SimpleHTTPServer # @UnresolvedImport, pylint: disable=import-error
|
||||
import time
|
||||
|
||||
from udsactor.log import logger
|
||||
@ -59,7 +59,6 @@ class HTTPServerHandler(SimpleHTTPServer.BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
self.wfile.write(json.dumps({'error': message}))
|
||||
return
|
||||
|
||||
|
||||
def do_GET(self):
|
||||
# Very simple path & params splitter
|
||||
path = self.path.split('?')[0][1:].split('/')
|
||||
@ -88,7 +87,7 @@ class HTTPServerHandler(SimpleHTTPServer.BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error('Got exception executing GET {}: {}'.format(path[1], utils.toUnicode(e.message)))
|
||||
self.sendJsonError(500, unicode(e))
|
||||
self.sendJsonError(500, str(e))
|
||||
return
|
||||
|
||||
self.send_response(200)
|
||||
@ -111,7 +110,7 @@ class HTTPServerHandler(SimpleHTTPServer.BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
HTTPServerHandler.lock.acquire()
|
||||
length = int(self.headers.getheader('content-length'))
|
||||
content = self.rfile.read(length)
|
||||
print length, ">>", content, '<<'
|
||||
print(length, ">>", content, '<<')
|
||||
params = json.loads(content)
|
||||
|
||||
operation = getattr(self, 'post_' + path[1])
|
||||
@ -121,12 +120,11 @@ class HTTPServerHandler(SimpleHTTPServer.BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error('Got exception executing POST {}: {}'.format(path[1], utils.toUnicode(e.message)))
|
||||
self.sendJsonError(500, unicode(e))
|
||||
self.sendJsonError(500, str(e))
|
||||
return
|
||||
finally:
|
||||
HTTPServerHandler.lock.release()
|
||||
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.end_headers()
|
||||
@ -158,10 +156,11 @@ class HTTPServerHandler(SimpleHTTPServer.BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
# Execute script at server space, that is, here
|
||||
# as a secondary thread
|
||||
script = params['script']
|
||||
|
||||
def executor():
|
||||
logger.debug('Executing script: {}'.format(script))
|
||||
try:
|
||||
exec script in None, None
|
||||
exec(script, None, None)
|
||||
except Exception as e:
|
||||
logger.error('Error executing script: {}'.format(e))
|
||||
th = threading.Thread(target=executor)
|
||||
@ -183,7 +182,7 @@ class HTTPServerThread(threading.Thread):
|
||||
HTTPServerHandler.ipc = ipc
|
||||
|
||||
self.certFile = createSelfSignedCert()
|
||||
self.server = SocketServer.TCPServer(address, HTTPServerHandler)
|
||||
self.server = socketserver.TCPServer(address, HTTPServerHandler)
|
||||
self.server.socket = ssl.wrap_socket(self.server.socket, certfile=self.certFile, server_side=True)
|
||||
|
||||
def getServerUrl(self):
|
||||
|
@ -1 +0,0 @@
|
||||
|
160
actors/src/udsactor/linux/operations.py
Normal file
160
actors/src/udsactor/linux/operations.py
Normal file
@ -0,0 +1,160 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import socket
|
||||
import platform
|
||||
import fcntl
|
||||
import os
|
||||
import struct
|
||||
import array
|
||||
import six
|
||||
from udsactor import utils
|
||||
|
||||
|
||||
def _getMacAddr(ifname):
|
||||
'''
|
||||
Returns the mac address of an interface
|
||||
Mac is returned as unicode utf-8 encoded
|
||||
'''
|
||||
if isinstance(ifname, list):
|
||||
return dict([(name, _getMacAddr(name)) for name in ifname])
|
||||
if isinstance(ifname, six.text_type):
|
||||
ifname = ifname.encode('utf-8') # If unicode, convert to bytes (or str in python 2.7)
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
info = bytearray(fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15])))
|
||||
return six.text_type(''.join(['%02x:' % char for char in info[18:24]])[:-1])
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _getIpAddr(ifname):
|
||||
'''
|
||||
Returns the ip address of an interface
|
||||
Ip is returned as unicode utf-8 encoded
|
||||
'''
|
||||
if isinstance(ifname, list):
|
||||
return dict([(name, _getIpAddr(name)) for name in ifname])
|
||||
if isinstance(ifname, six.text_type):
|
||||
ifname = ifname.encode('utf-8') # If unicode, convert to bytes (or str in python 2.7)
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
return six.text_type(socket.inet_ntoa(fcntl.ioctl(
|
||||
s.fileno(),
|
||||
0x8915, # SIOCGIFADDR
|
||||
struct.pack('256s', ifname[:15])
|
||||
)[20:24]))
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _getInterfaces():
|
||||
'''
|
||||
Returns a list of interfaces names coded in utf-8
|
||||
'''
|
||||
max_possible = 128 # arbitrary. raise if needed.
|
||||
space = max_possible * 16
|
||||
if platform.architecture()[0] == '32bit':
|
||||
offset, length = 32, 32
|
||||
elif platform.architecture()[0] == '64bit':
|
||||
offset, length = 16, 40
|
||||
else:
|
||||
raise OSError('Unknown arquitecture {0}'.format(platform.architecture()[0]))
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
names = array.array(str('B'), b'\0' * space)
|
||||
outbytes = struct.unpack('iL', fcntl.ioctl(
|
||||
s.fileno(),
|
||||
0x8912, # SIOCGIFCONF
|
||||
struct.pack('iL', space, names.buffer_info()[0])
|
||||
))[0]
|
||||
namestr = names.tostring()
|
||||
# return namestr, outbytes
|
||||
return [namestr[i:i + offset].split(b'\0', 1)[0].decode('utf-8') for i in range(0, outbytes, length)]
|
||||
|
||||
|
||||
def _getIpAndMac(ifname):
|
||||
ip, mac = _getIpAddr(ifname), _getMacAddr(ifname)
|
||||
return (ip, mac)
|
||||
|
||||
|
||||
def getComputerName():
|
||||
'''
|
||||
Returns computer name, with no domain
|
||||
'''
|
||||
return socket.gethostname().split('.')[0]
|
||||
|
||||
|
||||
def getNetworkInfo():
|
||||
for ifname in _getInterfaces():
|
||||
ip, mac = _getIpAndMac(ifname)
|
||||
yield utils.Bunch(name=ifname, mac=mac, ip=ip)
|
||||
|
||||
|
||||
def getDomainName():
|
||||
return ''
|
||||
|
||||
|
||||
def getLinuxVersion():
|
||||
lv = platform.linux_distribution()
|
||||
return lv[0] + ', ' + lv[1]
|
||||
|
||||
|
||||
def reboot(flags=0):
|
||||
'''
|
||||
Simple reboot using os command
|
||||
'''
|
||||
os.system('/sbin/shutdown now -r')
|
||||
|
||||
|
||||
def loggoff():
|
||||
pass
|
||||
|
||||
|
||||
def renameComputer(newName):
|
||||
pass
|
||||
|
||||
|
||||
def joinDomain(domain, ou, account, password, executeInOneStep=False):
|
||||
pass
|
||||
|
||||
|
||||
def changeUserPassword(user, oldPassword, newPassword):
|
||||
'''
|
||||
Simple password change for user using command line
|
||||
'''
|
||||
os.system('echo "{1}\n{1}" | /usr/bin/passwd {0} 2> /dev/null'.format(user, newPassword))
|
||||
|
||||
|
||||
def getIdleDuration():
|
||||
return 0
|
59
actors/src/udsactor/linux/renamer/__init__.py
Normal file
59
actors/src/udsactor/linux/renamer/__init__.py
Normal file
@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import platform
|
||||
import os
|
||||
import sys
|
||||
import pkgutil
|
||||
|
||||
from udsactor.log import logger
|
||||
|
||||
renamers = {}
|
||||
|
||||
|
||||
def rename(newName):
|
||||
distribution = platform.linux_distribution()[0].lower()
|
||||
if distribution in renamers:
|
||||
return renamers[distribution](newName)
|
||||
|
||||
logger.error('Renamer for platform "{0}" not found'.format(distribution))
|
||||
return False
|
||||
|
||||
|
||||
# Do load of packages
|
||||
def _init():
|
||||
pkgpath = os.path.dirname(sys.modules[__name__].__file__)
|
||||
for _, name, _ in pkgutil.iter_modules([pkgpath]):
|
||||
__import__(__name__ + '.' + name, globals(), locals())
|
||||
|
||||
_init()
|
73
actors/src/udsactor/linux/renamer/debian.py
Normal file
73
actors/src/udsactor/linux/renamer/debian.py
Normal file
@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2014 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from udsactor.linux.renamer import renamers
|
||||
from udsactor.log import logger
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def rename(newName):
|
||||
# If new name has "'\t'
|
||||
if '\t' in newName:
|
||||
newName, account, password = newName.split('\t')
|
||||
else:
|
||||
account = password = None
|
||||
|
||||
logger.debug('Debian renamer')
|
||||
|
||||
if account is not None:
|
||||
os.system('echo "{1}\n{1}" | /usr/bin/passwd {0} 2> /dev/null'.format(account, password))
|
||||
|
||||
f = open('/etc/hostname', 'w')
|
||||
f.write(newName)
|
||||
f.close()
|
||||
os.system('/bin/hostname %s' % newName)
|
||||
|
||||
# add name to "hosts"
|
||||
f = open('/etc/hosts', 'r')
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
f = open('/etc/hosts', 'w')
|
||||
f.write("127.0.1.1\t%s\n" % newName)
|
||||
for l in lines:
|
||||
if l[:9] == '127.0.1.1':
|
||||
continue
|
||||
f.write(l)
|
||||
f.close()
|
||||
|
||||
return True
|
||||
|
||||
# All names in lower case
|
||||
renamers['debian'] = rename
|
||||
renamers['ubuntu'] = rename
|
@ -29,7 +29,7 @@
|
||||
'''
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
import six
|
||||
import os
|
||||
@ -47,10 +47,15 @@ def readConfig():
|
||||
res = {}
|
||||
try:
|
||||
cfg = six.moves.configparser.SafeConfigParser() # @UndefinedVariable
|
||||
cfg.optionxform = six.text_type
|
||||
cfg.read(CONFIGFILE)
|
||||
# Just reads 'uds' section
|
||||
for key in cfg.options('uds'):
|
||||
res[key] = cfg.get('uds', key)
|
||||
if res[key].lower() in ('true', 'yes', 'si'):
|
||||
res[key] = True
|
||||
elif res[key].lower() in ('false', 'no'):
|
||||
res[key] = False
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ -59,10 +64,12 @@ def readConfig():
|
||||
|
||||
def writeConfig(data):
|
||||
cfg = six.moves.configparser.SafeConfigParser() # @UndefinedVariable
|
||||
cfg.optionxform = six.text_type
|
||||
cfg.add_section('uds')
|
||||
for key, val in data.iteritems():
|
||||
cfg.set('uds', key, unicode(val))
|
||||
with file(CONFIGFILE, 'w') as f:
|
||||
for key, val in data.items():
|
||||
cfg.set('uds', key, str(val))
|
||||
|
||||
with open(CONFIGFILE, 'w') as f:
|
||||
cfg.write(f)
|
||||
|
||||
os.chmod(CONFIGFILE, 0600)
|
||||
os.chmod(CONFIGFILE, 0o0600)
|
||||
|
@ -31,24 +31,27 @@
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import win32com.client
|
||||
import win32net
|
||||
import win32security
|
||||
import win32api
|
||||
import win32con
|
||||
import win32com.client # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32net # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32security # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32api # @UnresolvedImport, pylint: disable=import-error
|
||||
import win32con # @UnresolvedImport, pylint: disable=import-error
|
||||
import ctypes
|
||||
from ctypes.wintypes import DWORD, LPCWSTR
|
||||
|
||||
from udsactor import utils
|
||||
from udsactor.log import logger
|
||||
|
||||
|
||||
def getErrorMessage(res=0):
|
||||
msg = win32api.FormatMessage(res)
|
||||
return msg.decode('windows-1250', 'ignore')
|
||||
|
||||
|
||||
def getComputerName():
|
||||
return win32api.GetComputerNameEx(win32con.ComputerNamePhysicalDnsHostname)
|
||||
|
||||
|
||||
def getNetworkInfo():
|
||||
obj = win32com.client.Dispatch("WbemScripting.SWbemLocator")
|
||||
wmobj = obj.ConnectServer("localhost", "root\cimv2")
|
||||
@ -64,6 +67,7 @@ def getNetworkInfo():
|
||||
except Exception:
|
||||
return
|
||||
|
||||
|
||||
def getDomainName():
|
||||
'''
|
||||
Will return the domain name if we belong a domain, else None
|
||||
@ -80,6 +84,7 @@ def getDomainName():
|
||||
|
||||
return domain
|
||||
|
||||
|
||||
def getWindowsVersion():
|
||||
return win32api.GetVersionEx()
|
||||
|
||||
@ -90,6 +95,7 @@ EWX_FORCE = 0x00000004
|
||||
EWX_POWEROFF = 0x00000008
|
||||
EWX_FORCEIFHUNG = 0x00000010
|
||||
|
||||
|
||||
def reboot(flags=EWX_FORCEIFHUNG | EWX_REBOOT):
|
||||
hproc = win32api.GetCurrentProcess()
|
||||
htok = win32security.OpenProcessToken(hproc, win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY)
|
||||
@ -101,6 +107,7 @@ def reboot(flags=EWX_FORCEIFHUNG | EWX_REBOOT):
|
||||
def loggoff():
|
||||
win32api.ExitWindowsEx(EWX_LOGOFF)
|
||||
|
||||
|
||||
def renameComputer(newName):
|
||||
# Needs admin privileges to work
|
||||
if ctypes.windll.kernel32.SetComputerNameExW(DWORD(win32con.ComputerNamePhysicalDnsHostname), LPCWSTR(newName)) == 0:
|
||||
@ -121,6 +128,7 @@ NETSETUP_MACHINE_PWD_PASSED = 0x00000080
|
||||
NETSETUP_JOIN_WITH_NEW_NAME = 0x00000400
|
||||
NETSETUP_DEFER_SPN_SET = 0x1000000
|
||||
|
||||
|
||||
def joinDomain(domain, ou, account, password, executeInOneStep=False):
|
||||
# If account do not have domain, include it
|
||||
if '@' not in account and '\\' not in account:
|
||||
@ -156,6 +164,7 @@ def joinDomain(domain, ou, account, password, executeInOneStep=False):
|
||||
print res, error
|
||||
raise Exception('Error joining domain {}, with credentials {}/*****{}: {}, {}'.format(domain.value, account.value, ', under OU {}'.format(ou.value) if ou.value != None else '', res, error))
|
||||
|
||||
|
||||
def changeUserPassword(user, oldPassword, newPassword):
|
||||
computerName = LPCWSTR(getComputerName())
|
||||
user = LPCWSTR(user)
|
||||
@ -169,12 +178,14 @@ def changeUserPassword(user, oldPassword, newPassword):
|
||||
error = getErrorMessage()
|
||||
raise Exception('Error changing password for user {}: {}'.format(user.value, error))
|
||||
|
||||
|
||||
class LASTINPUTINFO(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('cbSize', ctypes.c_uint),
|
||||
('dwTime', ctypes.c_uint),
|
||||
]
|
||||
|
||||
|
||||
def getIdleDuration():
|
||||
lastInputInfo = LASTINPUTINFO()
|
||||
lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo)
|
||||
|
Loading…
Reference in New Issue
Block a user