2023-05-16 12:22:25 +12:00
# Unix SMB/CIFS implementation.
#
2023-09-27 00:20:49 +13:00
# Base test class for samba-tool domain auth policy and silo commands.
2023-05-16 12:22:25 +12:00
#
# Copyright (C) Catalyst.Net Ltd. 2023
#
# Written by Rob van der Linde <rob@catalyst.net.nz>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
from ldb import SCOPE_ONELEVEL
from . base import SambaToolCmdTest
2023-09-27 00:20:49 +13:00
HOST = " ldap:// {DC_SERVER} " . format ( * * os . environ )
CREDS = " -U {DC_USERNAME} % {DC_PASSWORD} " . format ( * * os . environ )
2023-05-16 12:22:25 +12:00
class BaseAuthCmdTest ( SambaToolCmdTest ) :
2023-09-27 00:20:49 +13:00
""" Base test class for samba-tool domain auth policy and silo commands. """
2023-08-17 13:29:49 +12:00
@classmethod
def setUpClass ( cls ) :
2023-09-27 00:20:49 +13:00
cls . samdb = cls . getSamDB ( " -H " , HOST , CREDS )
2023-08-17 13:29:49 +12:00
super ( ) . setUpClass ( )
@classmethod
2023-09-27 00:20:49 +13:00
def setUpTestData ( cls ) :
cls . create_authentication_policy ( name = " Single Policy " )
cls . create_authentication_policy ( name = " User Policy " )
cls . create_authentication_policy ( name = " Service Policy " )
cls . create_authentication_policy ( name = " Computer Policy " )
cls . create_authentication_silo ( name = " Developers " ,
description = " Developers, Developers " ,
policy = " Single Policy " )
cls . create_authentication_silo ( name = " Managers " ,
description = " Managers " ,
policy = " Single Policy " )
cls . create_authentication_silo ( name = " QA " ,
description = " Quality Assurance " ,
user_policy = " User Policy " ,
service_policy = " Service Policy " ,
computer_policy = " Computer Policy " )
2023-05-16 12:22:25 +12:00
def get_services_dn ( self ) :
""" Returns Services DN. """
services_dn = self . samdb . get_config_basedn ( )
services_dn . add_child ( " CN=Services " )
return services_dn
def get_authn_configuration_dn ( self ) :
""" Returns AuthN Configuration DN. """
authn_policy_configuration = self . get_services_dn ( )
authn_policy_configuration . add_child ( " CN=AuthN Policy Configuration " )
return authn_policy_configuration
def get_authn_silos_dn ( self ) :
""" Returns AuthN Silos DN. """
authn_silos_dn = self . get_authn_configuration_dn ( )
authn_silos_dn . add_child ( " CN=AuthN Silos " )
return authn_silos_dn
def get_authn_policies_dn ( self ) :
""" Returns AuthN Policies DN. """
authn_policies_dn = self . get_authn_configuration_dn ( )
authn_policies_dn . add_child ( " CN=AuthN Policies " )
return authn_policies_dn
2023-06-06 14:11:26 +12:00
def get_users_dn ( self ) :
""" Returns Users DN. """
users_dn = self . samdb . get_root_basedn ( )
users_dn . add_child ( " CN=Users " )
return users_dn
def get_user ( self , username ) :
""" Get a user by username. """
users_dn = self . get_users_dn ( )
result = self . samdb . search ( base = users_dn ,
scope = SCOPE_ONELEVEL ,
expression = f " (sAMAccountName= { username } ) " )
if len ( result ) == 1 :
return result [ 0 ]
2023-09-27 00:01:06 +13:00
@classmethod
def _run ( cls , * argv ) :
2023-05-16 12:22:25 +12:00
""" Override _run, so we don ' t always have to pass host and creds. """
args = list ( argv )
2023-09-27 00:20:49 +13:00
args . extend ( [ " -H " , HOST , CREDS ] )
2023-05-16 12:22:25 +12:00
return super ( ) . _run ( * args )
runcmd = _run
runsubcmd = _run
2023-09-27 00:20:49 +13:00
@classmethod
def create_authentication_policy ( cls , name , description = None , audit = False ,
2023-05-16 12:22:25 +12:00
protect = False ) :
""" Create an authentication policy. """
# base command for create authentication policy
cmd = [ " domain " , " auth " , " policy " , " create " , " --name " , name ]
# optional attributes
if description is not None :
cmd . append ( f " --description= { description } " )
if audit :
cmd . append ( " --audit " )
if protect :
cmd . append ( " --protect " )
2023-08-17 13:29:49 +12:00
# Run command and store name in self.silos for tearDownClass to clean
# up.
2023-09-27 00:20:49 +13:00
result , out , err = cls . runcmd ( * cmd )
assert result is None
assert out . startswith ( " Created authentication policy " )
cls . addClassCleanup ( cls . delete_authentication_policy ,
name = name , force = True )
2023-05-16 12:22:25 +12:00
return name
2023-09-27 00:20:49 +13:00
@classmethod
def delete_authentication_policy ( cls , name , force = False ) :
2023-05-16 12:22:25 +12:00
""" Delete authentication policy by name. """
cmd = [ " domain " , " auth " , " policy " , " delete " , " --name " , name ]
# Force-delete protected authentication policy.
if force :
cmd . append ( " --force " )
2023-09-27 00:20:49 +13:00
result , out , err = cls . runcmd ( * cmd )
assert result is None
assert " Deleted authentication policy " in out
2023-05-16 12:22:25 +12:00
2023-09-27 00:20:49 +13:00
@classmethod
def create_authentication_silo ( cls , name , description = None , policy = None ,
2023-05-16 12:22:25 +12:00
user_policy = None , service_policy = None ,
computer_policy = None , audit = False ,
protect = False ) :
""" Create an authentication silo using the samba-tool command. """
# Base command for create authentication policy.
cmd = [ " domain " , " auth " , " silo " , " create " , " --name " , name ]
# If --policy is present, use a singular authentication policy.
# otherwise use --user-policy, --service-policy, --computer-policy
if policy is not None :
cmd + = [ " --policy " , policy ]
else :
cmd + = [ " --user-policy " , user_policy ,
" --service-policy " , service_policy ,
" --computer-policy " , computer_policy ]
# Other optional attributes.
if description is not None :
cmd . append ( f " --description= { description } " )
if protect :
cmd . append ( " --protect " )
if audit :
cmd . append ( " --audit " )
2023-08-17 13:29:49 +12:00
# Run command and store name in self.silos for tearDownClass to clean
# up.
2023-09-27 00:20:49 +13:00
result , out , err = cls . runcmd ( * cmd )
assert result is None
assert out . startswith ( " Created authentication silo " )
cls . addClassCleanup ( cls . delete_authentication_silo ,
name = name , force = True )
2023-05-16 12:22:25 +12:00
return name
2023-09-27 00:20:49 +13:00
@classmethod
def delete_authentication_silo ( cls , name , force = False ) :
2023-05-16 12:22:25 +12:00
""" Delete authentication silo by name. """
cmd = [ " domain " , " auth " , " silo " , " delete " , " --name " , name ]
# Force-delete protected authentication silo.
if force :
cmd . append ( " --force " )
2023-09-27 00:20:49 +13:00
result , out , err = cls . runcmd ( * cmd )
assert result is None
assert " Deleted authentication silo " in out
2023-05-16 12:22:25 +12:00
def get_authentication_silo ( self , name ) :
""" Get authentication silo by name. """
authn_silos_dn = self . get_authn_silos_dn ( )
result = self . samdb . search ( base = authn_silos_dn ,
scope = SCOPE_ONELEVEL ,
expression = f " (CN= { name } ) " )
if len ( result ) == 1 :
return result [ 0 ]
def get_authentication_policy ( self , name ) :
""" Get authentication policy by name. """
authn_policies_dn = self . get_authn_policies_dn ( )
result = self . samdb . search ( base = authn_policies_dn ,
scope = SCOPE_ONELEVEL ,
expression = f " (CN= { name } ) " )
if len ( result ) == 1 :
return result [ 0 ]