1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-01-08 21:18:00 +03:00

Merge pull request #81 from Future998/linux-client-DC

Adding new Linux OS Domain Managers
This commit is contained in:
Adolfo Gómez 2023-05-17 17:43:43 +02:00 committed by GitHub
commit 98f79f83f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 653 additions and 22 deletions

View File

@ -3,6 +3,7 @@ Description=UDS Broker actor
After=network.target
[Service]
KillMode=mixed
Type=simple
User=root
Group=root

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2019 Virtual Cable S.L.
# Copyright (c) 2014-2023 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -27,6 +27,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
@author: Alexander Burmatov, thatman at altlinux dot org
'''
# pylint: disable=invalid-name
import configparser
@ -186,10 +187,67 @@ def renameComputer(newName: str) -> bool:
rename(newName)
return True # Always reboot right now. Not much slower but much more convenient
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
name: str,
domain: str,
ou: str,
account: str,
password: str,
client_software: str,
server_software: str,
membership_software: str,
ssl: bool,
automatic_id_mapping: bool
) -> None:
if server_software == 'ipa':
try:
hostname = getComputerName() + domain[domain.index('.'):]
command = f'hostnamectl set-hostname {hostname}'
subprocess.run(command, shell=True)
except Exception as e:
logger.error(f'Error set hostname for freeeipa: {e}')
try:
command = f'realm join -U {account} '
if client_software and client_software != 'automatically':
command += f'--client-software={client_software} '
if server_software:
command += f'--server-software={server_software} '
if membership_software and membership_software != 'automatically':
command += f'--membership-software={membership_software} '
if ou and server_software !='ipa':
command += f'--computer-ou="{ou}" '
if ssl == 'y':
command += '--use-ldaps '
if automatic_id_mapping == 'n':
command += '--automatic-id-mapping=no '
command += domain
subprocess.run(command, input=password.encode(), shell=True)
except Exception as e:
logger.error(f'Error join machine to domain {name}: {e}')
def joinDomain(domain: str, ou: str, account: str, password: str, executeInOneStep: bool = False):
pass
def leaveDomain(
domain: str,
account: str,
password: str,
client_software: str,
server_software: str,
) -> None:
if server_software == 'ipa':
try:
command = f'hostnamectl set-hostname {getComputerName()}'
subprocess.run(command, shell=True)
except Exception as e:
logger.error(f'Error set hostname for leave freeeipa domain: {e}')
try:
command = f'realm leave -U {account} '
if client_software and client_software != 'automatically':
command += f'--client-software={client_software} '
if server_software:
command += f'--server-software={server_software} '
command += domain
subprocess.run(command, input=password.encode(), shell=True)
except Exception as e:
logger.error(f'Error leave machine from domain {domain}: {e}')
def changeUserPassword(
user: str, oldPassword: str, newPassword: str

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2019 Virtual Cable S.L.
# Copyright (c) 2014-2023 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -28,10 +28,12 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
@author: Alexander Burmatov, thatman at altlinux dot org
'''
import signal
from . import daemon
from . import operations
from ..log import logger
from ..service import CommonService
@ -60,10 +62,42 @@ class UDSActorSvc(daemon.Daemon, CommonService):
domain: str,
ou: str,
account: str,
password: str
password: str,
client_software: str,
server_software: str,
membership_software: str,
ssl: bool,
automatic_id_mapping: bool
) -> None:
logger.info('Join domain is not supported on linux platforms right now. Just renaming.')
self.rename(name)
logger.debug(f'Starting joining domain {domain} with name {name}')
operations.joinDomain(name, \
domain, \
ou, \
account, \
password, \
client_software, \
server_software, \
membership_software, \
ssl, \
automatic_id_mapping
)
def finish(self) -> None:
try:
if self._cfg.config and self._cfg.config.os:
osData = self._cfg.config.os
if osData.action == 'rename_ad' and osData.isPersistent == 'n' :
operations.leaveDomain(
osData.ad or '',
osData.username or '',
osData.password or '',
osData.clientSoftware or '',
osData.serverSoftware or '',
)
except Exception as e:
logger.error(f'Got exception operating machine: {e}')
super().finish()
def run(self) -> None:
logger.debug('Running Daemon: {}'.format(self._isAlive))

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2019-2021 Virtual Cable S.L.U.
# Copyright (c) 2019-2023 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -27,6 +27,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
@author: Alexander Burmatov, thatman at altlinux dot org
'''
# pylint: disable=invalid-name
import warnings
@ -293,6 +294,12 @@ class UDSServerApi(UDSApi):
new_password=os.get('new_password'),
ad=os.get('ad'),
ou=os.get('ou'),
clientSoftware = os.get('clientSoftware'),
serverSoftware = os.get('serverSoftware'),
membershipSoftware = os.get('membershipSoftware'),
ssl = os.get('ssl'),
automaticIdMapping = os.get('automaticIdMapping'),
isPersistent = os.get('isPersistent'),
)
if r['os']
else None,

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2019 Virtual Cable S.L.
# Copyright (c) 2014-2023 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -27,6 +27,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
@author: Alexander Burmatov, thatman at altlinux dot org
'''
# pylint: disable=invalid-name
@ -194,10 +195,15 @@ class CommonService: # pylint: disable=too-many-instance-attributes
# Cleans sensible data
if self._cfg.config:
self._cfg = self._cfg._replace(
config=self._cfg.config._replace(os=None), data=None
)
platform.store.writeConfig(self._cfg)
try:
isPersistent = self._cfg.config.os.isPersistent == 'y'
except:
isPersistent = True
if isPersistent:
self._cfg = self._cfg._replace(
config=self._cfg.config._replace(os=None), data=None
)
platform.store.writeConfig(self._cfg)
logger.info('Service ready')
@ -235,13 +241,27 @@ class CommonService: # pylint: disable=too-many-instance-attributes
osData.new_password,
)
elif osData.action == 'rename_ad':
self.joinDomain(
osData.name,
osData.ad or '',
osData.ou or '',
osData.username or '',
osData.password or '',
)
if not osData.serverSoftware:
self.joinDomain(
osData.name,
osData.ad or '',
osData.ou or '',
osData.username or '',
osData.password or '',
)
else:
self.joinDomain(
osData.name,
osData.ad or '',
osData.ou or '',
osData.username or '',
osData.password or '',
osData.clientSoftware or '',
osData.serverSoftware or '',
osData.membershipSoftware or '',
osData.ssl or '',
osData.automaticIdMapping or ''
)
if self._rebootRequested:
try:

View File

@ -24,6 +24,12 @@ class ActorOsConfigurationType(typing.NamedTuple):
new_password: typing.Optional[str] = None
ad: typing.Optional[str] = None
ou: typing.Optional[str] = None
clientSoftware: typing.Optional[str] = None
serverSoftware: typing.Optional[str] = None
membershipSoftware: typing.Optional[str] = None
ssl: typing.Optional[str] = None
automaticIdMapping: typing.Optional[str] = None
isPersistent: typing.Optional[str] = None
class ActorDataConfigurationType(typing.NamedTuple):
unique_id: typing.Optional[str] = None

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2022 Virtual Cable S.L.U.
# Copyright (c) 2012-2023 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -29,6 +29,7 @@
"""
@author: Adolfo Gómez, dkmaster at dkmon dot com
@author: Alexander Burmatov, thatman at altlinux dot org
"""
import typing
@ -117,6 +118,12 @@ class OSManager(Module):
'ou': 'ou' # or '' if default ou
'username': 'userwithaddmachineperms@domain.xxxx'
'password': 'passwordForTheUserWithPerms',
'clientSoftware': 'sssd' or 'winbind' or 'automatically' if linux os manager,
'serverSoftware': 'active-directory' or 'ipa' if linux os manager,
'membershipSoftware': 'samba' or 'adcli' or 'automatically' if linux os manager,
'ssl': 'n' or 'y' if linux os manager,
'automaticIdMapping': 'n' or 'y' if linux os manager,
'isPersistent': 'n' or 'y' if linux os manager,
}
* rename vm, do NOT ADD to AD, and change password for an user
{

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2022 Virtual Cable S.L.U.
# Copyright (c) 2012-2023 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -29,6 +29,7 @@
"""
@author: Adolfo Gómez, dkmaster at dkmon dot com
@author: Alexander Burmatov, thatman at altlinux dot org
"""
import os.path
import typing
@ -41,6 +42,8 @@ from uds.core import VERSION
from .linux_osmanager import LinuxOsManager
from .linux_randompass_osmanager import LinuxRandomPassManager
from .linux_ad_osmanager import LinuxOsADManager
from .linux_freeipa_osmanager import LinuxOsFreeIPAManager
downloadsManager().registerDownloadable(
f'udsactor_{VERSION}_all.deb',

View File

@ -0,0 +1,255 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2023 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: Alexander Burmatov, thatman at altlinux dot org
"""
import codecs
import logging
import typing
from django.utils.translation import gettext_noop as _, gettext_lazy
from uds.core.ui import gui
from uds.core import exceptions
from uds.core.managers import cryptoManager
from .linux_osmanager import LinuxOsManager
if typing.TYPE_CHECKING:
from uds.models.user_service import UserService
logger = logging.getLogger(__name__)
class LinuxOsADManager(LinuxOsManager):
typeName = _('Linux OS Active Directory Manager')
typeType = 'LinuxADManager'
typeDescription = _('Os Manager to control Linux virtual machines with active directory')
iconFile = 'losmanager.png'
domain = gui.TextField(
length=64,
label=_('Domain'),
order=1,
tooltip=_(
'Domain to join machines to (use FQDN form, Netbios name not supported for most operations)'
),
required=True,
)
account = gui.TextField(
length=64,
label=_('Account'),
order=2,
tooltip=_('Account with rights to add machines to domain'),
required=True,
)
password = gui.PasswordField(
length=64,
label=_('Password'),
order=3,
tooltip=_('Password of the account'),
required=True,
)
ou = gui.TextField(
length=256,
label=_('OU'),
order=4,
tooltip=_(
'Organizational unit where to add machines in domain (check it before using it). i.e.: ou=My Machines,dc=mydomain,dc=local'
),
)
clientSoftware = gui.ChoiceField(
label=_('Client software'),
order=5,
tooltip=_('Use specific client software'),
values=[
{'id': 'automatically', 'text': gettext_lazy('Automatically')},
{'id': 'sssd', 'text': gettext_lazy('SSSD')},
{'id': 'winbind', 'text': gettext_lazy('Winbind')},
],
tab=_('Advanced'),
defvalue='automatically',
)
membershipSoftware = gui.ChoiceField(
label=_('Membership software'),
order=6,
tooltip=_('Use specific membership software'),
values=[
{'id': 'automatically', 'text': gettext_lazy('Automatically')},
{'id': 'samba', 'text': gettext_lazy('Samba')},
{'id': 'adcli', 'text': gettext_lazy('adcli')},
],
tab=_('Advanced'),
defvalue='automatically',
)
removeOnExit = gui.CheckBoxField(
label=_('Machine clean'),
order=7,
tooltip=_(
'If checked, UDS will try to remove the machine from the domain USING the provided credentials'
),
tab=_('Advanced'),
defvalue=gui.TRUE,
)
ssl = gui.CheckBoxField(
label=_('Use SSL'),
order=8,
tooltip=_('If checked, a ssl connection to Active Directory will be used'),
tab=_('Advanced'),
defvalue=gui.TRUE,
)
automaticIdMapping = gui.CheckBoxField(
label=_('Automatic ID mapping'),
order=9,
tooltip=_('If checked, automatic ID mapping'),
tab=_('Advanced'),
defvalue=gui.TRUE,
)
# Inherits base "onLogout"
onLogout = LinuxOsManager.onLogout
idle = LinuxOsManager.idle
deadLine = LinuxOsManager.deadLine
_domain: str
_ou: str
_account: str
_password: str
_removeOnExit: str
_ssl: str
_automaticIdMapping: str
_clientSoftware: str
_serverSoftware: str
_membershipSoftware: str
def __init__(self, environment, values):
super(LinuxOsADManager, self).__init__(environment, values)
if values:
if values['domain'] == '':
raise exceptions.ValidationError(_('Must provide a domain!'))
if values['account'] == '':
raise exceptions.ValidationError(
_('Must provide an account to add machines to domain!')
)
if values['password'] == '':
raise exceptions.ValidationError(
_('Must provide a password for the account!')
)
self._domain = values['domain']
self._account = values['account']
self._password = values['password']
self._ou = values['ou'].strip()
self._clientSoftware = values['clientSoftware']
self._serverSoftware = 'active-directory'
self._membershipSoftware = values['membershipSoftware']
self._removeOnExit = 'y' if values['removeOnExit'] else 'n'
self._ssl = 'y' if values['ssl'] else 'n'
self._automaticIdMapping = 'y' if values['automaticIdMapping'] else 'n'
else:
self._domain = ''
self._account = ''
self._password = '' # nosec: no encoded password
self._ou = ''
self._clientSoftware = ''
self._serverSoftware = 'active-directory'
self._membershipSoftware = ''
self._removeOnExit = 'n'
self._ssl = 'n'
self._automaticIdMapping = 'n'
def actorData(
self, userService: 'UserService'
) -> typing.MutableMapping[str, typing.Any]:
return {
'action': 'rename_ad',
'name': userService.getName(),
'ad': self._domain,
'username': self._account,
'password': self._password,
'ou': self._ou,
'clientSoftware': self._clientSoftware,
'serverSoftware': self._serverSoftware,
'membershipSoftware': self._membershipSoftware,
'ssl': self._ssl,
'automaticIdMapping': self._automaticIdMapping,
'isPersistent': 'y' if self.isPersistent() else 'n',
}
def marshal(self) -> bytes:
"""
Serializes the os manager data so we can store it in database
"""
base = super().marshal()
return '\t'.join(
[
'v1',
self._domain,
self._account,
cryptoManager().encrypt(self._password),
self._ou,
self._clientSoftware,
self._serverSoftware,
self._membershipSoftware,
self._removeOnExit,
self._ssl,
self._automaticIdMapping,
codecs.encode(base, 'hex').decode(),
]
).encode('utf8')
def unmarshal(self, data: bytes) -> None:
values = data.decode('utf8').split('\t')
if values[0] in ('v1'):
self._domain = values[1]
self._account = values[2]
self._password = cryptoManager().decrypt(values[3])
self._ou = values[4]
self._clientSoftware = values[5]
self._serverSoftware = values[6]
self._membershipSoftware = values[7]
self._removeOnExit = values[8]
self._ssl = values[9]
self._automaticIdMapping = values[10]
super().unmarshal(codecs.decode(values[11].encode(), 'hex'))
def valuesDict(self) -> gui.ValuesDictType:
dct = super().valuesDict()
dct['domain'] = self._domain
dct['account'] = self._account
dct['password'] = self._password
dct['ou'] = self._ou
dct['clientSoftware'] = self._clientSoftware
dct['serverSoftware'] = self._serverSoftware
dct['membershipSoftware'] = self._membershipSoftware
dct['removeOnExit'] = self._removeOnExit == 'y'
dct['ssl'] = self._ssl == 'y'
dct['automaticIdMapping'] = self._automaticIdMapping == 'y'
return dct

View File

@ -0,0 +1,240 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012-2023 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: Alexander Burmatov, thatman at altlinux dot org
"""
import codecs
import logging
import typing
from django.utils.translation import gettext_noop as _, gettext_lazy
from uds.core.ui import gui
from uds.core import exceptions
from uds.core.managers import cryptoManager
from .linux_osmanager import LinuxOsManager
if typing.TYPE_CHECKING:
from uds.models.user_service import UserService
logger = logging.getLogger(__name__)
class LinuxOsFreeIPAManager(LinuxOsManager):
typeName = _('Linux OS FreeIPA Manager')
typeType = 'LinuxFreeIPAManager'
typeDescription = _('Os Manager to control Linux virtual machines with FreeIPA')
iconFile = 'losmanager.png'
domain = gui.TextField(
length=64,
label=_('Domain'),
order=1,
tooltip=_(
'Domain to join machines to (use FQDN form, Netbios name not supported for most operations)'
),
required=True,
)
account = gui.TextField(
length=64,
label=_('Account'),
order=2,
tooltip=_('Account with rights to add machines to domain'),
required=True,
)
password = gui.PasswordField(
length=64,
label=_('Password'),
order=3,
tooltip=_('Password of the account'),
required=True,
)
clientSoftware = gui.ChoiceField(
label=_('Client software'),
order=4,
tooltip=_('Use specific client software'),
values=[
{'id': 'automatically', 'text': gettext_lazy('Automatically')},
{'id': 'sssd', 'text': gettext_lazy('SSSD')},
{'id': 'winbind', 'text': gettext_lazy('Winbind')},
],
tab=_('Advanced'),
defvalue='automatically',
)
membershipSoftware = gui.ChoiceField(
label=_('Membership software'),
order=5,
tooltip=_('Use specific membership software'),
values=[
{'id': 'automatically', 'text': gettext_lazy('Automatically')},
{'id': 'samba', 'text': gettext_lazy('Samba')},
{'id': 'adcli', 'text': gettext_lazy('adcli')},
],
tab=_('Advanced'),
defvalue='automatically',
)
removeOnExit = gui.CheckBoxField(
label=_('Machine clean'),
order=6,
tooltip=_(
'If checked, UDS will try to remove the machine from the domain USING the provided credentials'
),
tab=_('Advanced'),
defvalue=gui.TRUE,
)
ssl = gui.CheckBoxField(
label=_('Use SSL'),
order=7,
tooltip=_('If checked, a ssl connection to Active Directory will be used'),
tab=_('Advanced'),
defvalue=gui.TRUE,
)
automaticIdMapping = gui.CheckBoxField(
label=_('Automatic ID mapping'),
order=8,
tooltip=_('If checked, automatic ID mapping'),
tab=_('Advanced'),
defvalue=gui.TRUE,
)
# Inherits base "onLogout"
onLogout = LinuxOsManager.onLogout
idle = LinuxOsManager.idle
deadLine = LinuxOsManager.deadLine
_domain: str
_account: str
_password: str
_removeOnExit: str
_ssl: str
_automaticIdMapping: str
_clientSoftware: str
_serverSoftware: str
_membershipSoftware: str
def __init__(self, environment, values):
super(LinuxOsFreeIPAManager, self).__init__(environment, values)
if values:
if values['domain'] == '':
raise exceptions.ValidationError(_('Must provide a domain!'))
if values['account'] == '':
raise exceptions.ValidationError(
_('Must provide an account to add machines to domain!')
)
if values['password'] == '':
raise exceptions.ValidationError(
_('Must provide a password for the account!')
)
self._domain = values['domain']
self._account = values['account']
self._password = values['password']
self._clientSoftware = values['clientSoftware']
self._serverSoftware = 'ipa'
self._membershipSoftware = values['membershipSoftware']
self._removeOnExit = 'y' if values['removeOnExit'] else 'n'
self._ssl = 'y' if values['ssl'] else 'n'
self._automaticIdMapping = 'y' if values['automaticIdMapping'] else 'n'
else:
self._domain = ''
self._account = ''
self._password = '' # nosec: no encoded password
self._clientSoftware = ''
self._serverSoftware = 'ipa'
self._membershipSoftware = ''
self._removeOnExit = 'n'
self._ssl = 'n'
self._automaticIdMapping = 'n'
def actorData(
self, userService: 'UserService'
) -> typing.MutableMapping[str, typing.Any]:
return {
'action': 'rename_ad',
'name': userService.getName(),
'ad': self._domain,
'username': self._account,
'password': self._password,
'clientSoftware': self._clientSoftware,
'serverSoftware': self._serverSoftware,
'membershipSoftware': self._membershipSoftware,
'ssl': self._ssl,
'automaticIdMapping': self._automaticIdMapping,
'isPersistent': 'y' if self.isPersistent() else 'n',
}
def marshal(self) -> bytes:
"""
Serializes the os manager data so we can store it in database
"""
base = super().marshal()
return '\t'.join(
[
'v1',
self._domain,
self._account,
cryptoManager().encrypt(self._password),
self._clientSoftware,
self._serverSoftware,
self._membershipSoftware,
self._removeOnExit,
self._ssl,
self._automaticIdMapping,
codecs.encode(base, 'hex').decode(),
]
).encode('utf8')
def unmarshal(self, data: bytes) -> None:
values = data.decode('utf8').split('\t')
if values[0] in ('v1'):
self._domain = values[1]
self._account = values[2]
self._password = cryptoManager().decrypt(values[3])
self._clientSoftware = values[4]
self._serverSoftware = values[5]
self._membershipSoftware = values[6]
self._removeOnExit = values[7]
self._ssl = values[8]
self._automaticIdMapping = values[9]
super().unmarshal(codecs.decode(values[10].encode(), 'hex'))
def valuesDict(self) -> gui.ValuesDictType:
dct = super().valuesDict()
dct['domain'] = self._domain
dct['account'] = self._account
dct['password'] = self._password
dct['clientSoftware'] = self._clientSoftware
dct['serverSoftware'] = self._serverSoftware
dct['membershipSoftware'] = self._membershipSoftware
dct['removeOnExit'] = self._removeOnExit == 'y'
dct['ssl'] = self._ssl == 'y'
dct['automaticIdMapping'] = self._automaticIdMapping == 'y'
return dct