def test_16_Copying_file(request): depends(request, ["pool_04"], scope="session") cmd = 'cp "%s/testfile2" "%s/testfile"' % (MOUNTPOINT, MOUNTPOINT) results = SSH_TEST(cmd, BSD_USERNAME, BSD_PASSWORD, BSD_HOST) assert results['result'] is True, results['output']
def test_29_deleting_test_file_and_directory_from_afp_share(request): depends(request, ["pool_04"], scope="session") cmd = f'rm -f "{MOUNTPOINT}/tmp/testfile.txt" && rmdir "{MOUNTPOINT}/tmp"' results = SSH_TEST(cmd, OSX_USERNAME, OSX_PASSWORD, OSX_HOST) assert results['result'] is True, results['output']
def test_31_unmount_afp_share(request): depends(request, ["pool_04"], scope="session") cmd = f'umount -f "{MOUNTPOINT}"' results = SSH_TEST(cmd, OSX_USERNAME, OSX_PASSWORD, OSX_HOST) assert results['result'] is True, results['output']
def test_16_create_mount_point_for_afp_on_osx_system(request): depends(request, ["pool_04"], scope="session") cmd = f'mkdir -p "{MOUNTPOINT}"' results = SSH_TEST(cmd, OSX_USERNAME, OSX_PASSWORD, OSX_HOST) assert results['result'] is True, results['output']
def test_27_create_file_on_afp_share_via_osx_to_test_permissions(request): depends(request, ["pool_04"], scope="session") cmd = f'touch "{MOUNTPOINT}/testfile.txt"' results = SSH_TEST(cmd, OSX_USERNAME, OSX_PASSWORD, OSX_HOST) assert results['result'] is True, results['output']
def test_05_verify_the_pool_is_degraded(): cmd = f'zpool status {pool_name} | grep {gptid}' results = SSH_TEST(cmd, user, password, ip) assert results['result'] is True, results['output'] assert 'DEGRADED' in results['output'], results['output']
def test_08_test_backend_options(request, backend): """ Tests for backend options are performend against the backend for the domain we're joined to (DS_TYPE_ACTIVEDIRECTORY) so that auto-detection works correctly. The three default idmap backends DS_TYPE_ACTIVEDIRECTORY, DS_TYPE_LDAP, DS_TYPE_DEFAULT_DOMAIN have hard-coded ids and so we don't need to look them up. """ depends(request, ["GATHERED_BACKEND_OPTIONS"]) opts = BACKEND_OPTIONS[backend]['parameters'].copy() set_secret = False payload = { "name": "DS_TYPE_ACTIVEDIRECTORY", "range_low": "1000000000", "range_high": "2000000000", "idmap_backend": backend, "options": {} } payload3 = {"options": {}} for k, v in opts.items(): """ Populate garbage data where an opt is required. This should get us past the first step of switching to the backend before doing more comprehensive tests. """ if v['required']: payload["options"].update({k: "canary"}) results = PUT("/idmap/id/1/", payload) assert results.status_code == 200, results.text if backend == "AUTORID": IDMAP_CFG = "idmap config * " else: IDMAP_CFG = f"idmap config {WORKGROUP} " """ Validate that backend was correctly set in smb.conf. """ cmd = f'midclt call smb.getparm "{IDMAP_CFG}: backend" GLOBAL' results = SSH_TEST(cmd, user, password, ip) assert results['result'] is True, results['output'] running_backend = results['output'].strip() assert running_backend == backend.lower(), results['output'] if backend == "RID": """ sssd_compat generates a lower range based on murmur3 hash of domain SID. Since we're validating basic functionilty, checking that our range_low changed is sufficient for now. """ payload2 = {"options": {"sssd_compat": True}} results = PUT("/idmap/id/1/", payload2) assert results.status_code == 200, results.text out = results.json() assert out['range_low'] != payload['range_low'] elif backend == "AUTORID": """ autorid is unique among the idmap backends because its configuration replaces the default idmap backend "idmap config *". """ payload3["options"] = { "rangesize": 200000, "readonly": True, "ignore_builtin": True, } results = PUT("/idmap/id/1/", payload3) assert results.status_code == 200, results.text elif backend == "AD": payload3["options"] = { "schema_mode": "SFU", "unix_primary_group": True, "unix_nss_info": True, } results = PUT("/idmap/id/1/", payload3) assert results.status_code == 200, results.text elif backend == "LDAP": payload3["options"] = { "ldap_base_dn": "canary", "ldap_user_dn": "canary", "ldap_url": "canary", "ldap_user_dn_password": "******", "readonly": True, } results = PUT("/idmap/id/1/", payload3) assert results.status_code == 200, results.text secret = payload3["options"].pop("ldap_user_dn_password") set_secret = True elif backend == "RFC2307": payload3["options"] = { "ldap_server": "stand-alone", "bind_path_user": "******", "bind_path_group": "canary", "user_cn": True, "ldap_domain": "canary", "ldap_url": "canary", "ldap_user_dn": "canary", "ldap_user_dn_password": "******", "ldap_realm": True, } results = PUT("/idmap/id/1/", payload3) assert results.status_code == 200, results.text r = payload3["options"].pop("ldap_realm") payload3["options"]["realm"] = r secret = payload3["options"].pop("ldap_user_dn_password") set_secret = True for k, v in payload3['options'].items(): """ At this point we should have added every supported option for the current backend. Iterate through each option and verify that it was written to samba's running configuration. """ cmd = f'midclt call smb.getparm "{IDMAP_CFG} : {k}" GLOBAL' results = SSH_TEST(cmd, user, password, ip) assert results['result'] is True, results['output'] try: res = json.loads(results['output'].strip()) assert res == v, f"[{k}]: {res}" except json.decoder.JSONDecodeError: res = results['output'].strip() if v is True: v = "Yes" elif v is False: v = "No" assert v.casefold() == res.casefold(), f"[{k}]: {res}" if set_secret: """ API calls that set an idmap secret should result in the secret being written to secrets.tdb in Samba's private directory. To check this, force a secrets db dump, check for keys, then decode secret. """ cmd = 'midclt call directoryservices.get_db_secrets' results = SSH_TEST(cmd, user, password, ip) assert results['result'] is True, results['output'] sec = json.loads(results['output'].strip()) sec_key = f"SECRETS/GENERIC/IDMAP_LDAP_{WORKGROUP}/{secret}" assert sec_key in sec[f'{hostname.upper()}$'], results['output'] if sec_key in sec[f'{hostname.upper()}$']: stored_sec = sec[f'{hostname.upper()}$'][sec_key] decoded_sec = b64decode(stored_sec).rstrip(b'\x00').decode() assert secret == decoded_sec, stored_sec
def test_29_verify_no_nfs_principals(request): depends(request, ["KRB5_IS_HEALTHY", "ssh_password"], scope="session") cmd = 'midclt call kerberos.keytab.has_nfs_principal' results = SSH_TEST(cmd, user, password, ip) assert results['result'] is True, results['output'] assert results['output'].strip() == 'False'
def test_33_verify_has_nfs_principals(request): depends(request, ["V4_KRB_ENABLED", "ssh_password"], scope="session") cmd = 'midclt call kerberos.keytab.has_nfs_principal' results = SSH_TEST(cmd, user, password, ip) assert results['result'] is True, results['output'] assert results['output'].strip() == 'True'
def test_21_Disconnect_iSCSI_target(request): depends(request, ["pool_04"], scope="session") results = SSH_TEST('iscsictl -R -t %s' % TARGET_NAME, BSD_USERNAME, BSD_PASSWORD, BSD_HOST) assert results['result'] is True, results['output']
def test_20_verify_system_tunable_dummynet_not_loaded(): results = SSH_TEST('kldstat -m dummynet', user, password, ip) assert results['result'] is False, results['output']
def test_20_Removing_iSCSI_volume_mountpoint(request): depends(request, ["pool_04"], scope="session") results = SSH_TEST('rm -rf "%s"' % MOUNTPOINT, BSD_USERNAME, BSD_PASSWORD, BSD_HOST) assert results['result'] is True, results['output']
def test_19_Unmounting_iSCSI_volume(request): depends(request, ["pool_04"], scope="session") results = SSH_TEST('umount "%s"' % MOUNTPOINT, BSD_USERNAME, BSD_PASSWORD, BSD_HOST) assert results['result'] is True, results['output']
def test_17_Deleting_file(request): depends(request, ["pool_04"], scope="session") results = SSH_TEST('rm "%s/testfile2"' % MOUNTPOINT, BSD_USERNAME, BSD_PASSWORD, BSD_HOST) assert results['result'] is True, results['output']
def test_06_checking_staticroute_unconfigured_using_ssh(): results = SSH_TEST(f'netstat -4rn|grep -E ^{DESTINATION}', user, password, ip) assert results['result'] is False, results
def test_053_verify_pool_dataset_does_not_leak_encryption_key_into_middleware_log( ): cmd = f"""grep -R "{dataset_token_hex}" /var/log/middlewared.log""" results = SSH_TEST(cmd, user, password, ip) assert results['result'] is False, str(results['output'])
def test_12_clear_the_pool_degradation(): cmd = f'zpool clear {pool_name}' results = SSH_TEST(cmd, user, password, ip) assert results['result'] is True, results['output']
def test_080_verify_pool_dataset_unlock_does_not_leak_passphrase_into_middleware_log( ): cmd = """grep -R "my_passphrase2" /var/log/middlewared.log""" results = SSH_TEST(cmd, user, password, ip) assert results['result'] is False, str(results['output'])
def test_10_check_lazy_initialization_of_users_and_groups_by_name(request): """ When users explicitly search for a directory service or other user by name or id we should hit pwd and grp modules and synthesize a result if the user / group is not in the cache. This special behavior only occurs when single filter of "name =" or "id =". So after the initial query that should result in insertion, we add a second filter to only hit the cache. Code paths are slightly different for lookups by id or by name and so they are tested separately. """ depends(request, ["REBUILD_AD_CACHE", "ssh_password"], scope="session") global ad_user_id global ad_domain_users_id domain_prefix = f'{WORKGROUP.upper()}{WINBIND_SEPARATOR}' ad_user = f'{domain_prefix}{ADUSERNAME.lower()}' ad_group = f'{domain_prefix}domain users' cmd = 'rm -f /root/tdb/persistent/*' results = SSH_TEST(cmd, user, password, ip) assert results['result'] is True, results['output'] if not results['result']: return results = GET('/user', payload={ 'query-filters': [['username', '=', ad_user]], 'query-options': {'extra': {"search_dscache": True}}, }) assert results.status_code == 200, results.text assert len(results.json()) > 0, results.text if len(results.json()) == 0: return ad_user_id = results.json()[0]['uid'] assert results.json()[0]['username'] == ad_user, results.text results = GET('/group', payload={ 'query-filters': [['name', '=', ad_group]], 'query-options': {'extra': {"search_dscache": True}}, }) assert results.status_code == 200, results.text assert len(results.json()) > 0, results.text if len(results.json()) == 0: return ad_domain_users_id = results.json()[0]['gid'] assert results.json()[0]['name'] == ad_group, results.text """ The following two tests validate that cache insertion occured. """ results = GET('/user', payload={ 'query-filters': [['username', '=', ad_user], ['local', '=', False]], 'query-options': {'extra': {"search_dscache": True}}, }) assert results.status_code == 200, results.text assert len(results.json()) == 1, results.text results = GET('/group', payload={ 'query-filters': [['name', '=', ad_group], ['local', '=', False]], 'query-options': {'extra': {"search_dscache": True}}, }) assert results.status_code == 200, results.text assert len(results.json()) == 1, results.text
def test_03_Checking_ntpserver_configured_using_ssh(): results = SSH_TEST(f'fgrep "{ntpServer}" /etc/ntp.conf', user, password, ip) assert results['result'] is True, results
def test_05_verify_activedirectory_do_not_leak_password_in_middleware_log( request): depends(request, ["AD_ENABLED"]) cmd = f"""grep -R "{ADPASSWORD}" /var/log/middlewared.log""" results = SSH_TEST(cmd, user, password, ip) assert results['result'] is False, str(results['output'])
def test_06_Checking_ntpservers_num_configured_using_ssh(ntp_dict): results = SSH_TEST(f'fgrep -E ^server /etc/ntp.conf', user, password, ip) assert results['result'] is True, results assert len(results['output'].strip().split('\n')) == \ len(ntp_dict['servers']), results['output']
def test_26_mount_afp_share_on_osx_system(request): depends(request, ["pool_04"], scope="session") cmd = f'mount -t afp "afp://{ip}/{AFP_NAME}" "{MOUNTPOINT}"' results = SSH_TEST(cmd, OSX_USERNAME, OSX_PASSWORD, OSX_HOST) assert results['result'] is True, results['output']
def test_03_verify_vmware_get_datastore_do_not_leak_password_in_middleware_log( request): depends(request, ["ssh_password"], scope="session") cmd = f"""grep -R "{os.environ['VMWARE_PASSWORD']}" /var/log/middlewared.log""" results = SSH_TEST(cmd, user, password, ip) assert results['result'] is False, str(results['output'])
def test_28_moving_afp_test_file_into_a_new_directory(request): depends(request, ["pool_04"], scope="session") cmd = f'mkdir -p "{MOUNTPOINT}/tmp" && mv "{MOUNTPOINT}/testfile.txt" ' \ f'"{MOUNTPOINT}/tmp/testfile.txt"' results = SSH_TEST(cmd, OSX_USERNAME, OSX_PASSWORD, OSX_HOST) assert results['result'] is True, results['output']
from functions import GET, POST, PUT, DELETE, wait_on_job, SSH_TEST reason = 'Skipping test for HA' if ha else 'Skipping test for Scale' pytestmark = pytest.mark.skipif(ha or scale, reason=reason) JOB_ID = None job_results = None default_repos_url = 'https://github.com/freenas/iocage-ix-plugins.git' community_repos_url = 'https://github.com/ix-plugin-hub/iocage-plugin-index.git' custom_community_repos_url = 'https://github.com/ericbsd/iocage-plugin-index.git' if not scale and not ha: PUT("/ssh/", {"rootlogin": True}, controller_a=ha) POST("/service/start/", {"service": "ssh"}, controller_a=ha) ssh_cmd = "uname -r | cut -d '-' -f1" release_version = SSH_TEST(ssh_cmd, user, password, ip)['output'].strip() community_index_url = f'https://raw.githubusercontent.com/ix-plugin-hub/iocage-plugin-index/{release_version}-RELEASE/INDEX' community_plugin_index = GET(community_index_url).json() community_plugin_list = list(community_plugin_index.keys()) custom_community_index_url = f'https://raw.githubusercontent.com/ericbsd/iocage-plugin-index/{release_version}-RELEASE/INDEX' custom_community_plugin_index = GET(custom_community_index_url).json() custom_community_plugin_list = list(custom_community_plugin_index.keys()) PUT("/ssh/", {"rootlogin": False}, controller_a=ha) POST("/service/stop/", {"service": "ssh"}, controller_a=ha) else: community_plugin_list = [] custom_community_plugin_list = [] plugin_objects = [ "id",
def test_30_verifying_test_file_directory_were_successfully_removed(request): depends(request, ["pool_04"], scope="session") cmd = f'find -- "{MOUNTPOINT}/" -prune -type d -empty | grep -q .' results = SSH_TEST(cmd, OSX_USERNAME, OSX_PASSWORD, OSX_HOST) assert results['result'] is True, results['output']
def test_03_checking_staticroute_configured_using_ssh(): results = SSH_TEST(f'netstat -4rn|grep -E ^{DESTINATION}', user, password, ip) assert results['result'] is True, results assert results['output'].strip().split()[1] == GATEWAY, results
def test_32_removing_SMB_mountpoint(request): depends(request, ["pool_04"], scope="session") cmd = f'test -d "{MOUNTPOINT}" && rmdir "{MOUNTPOINT}" || exit 0' results = SSH_TEST(cmd, OSX_USERNAME, OSX_PASSWORD, OSX_HOST) assert results['result'] is True, results['output']
def test_14_Creating_file(request): depends(request, ["pool_04"], scope="session") cmd = 'touch "%s/testfile"' % MOUNTPOINT results = SSH_TEST(cmd, BSD_USERNAME, BSD_PASSWORD, BSD_HOST) assert results['result'] is True, results['output']