def setup_container_acl_and_permission(self, user_type, user_name, perm_type, perm_action): """Setup container acl and permissions. Args: user_type (str): Container user_type. user_name (str): Container user_name. perm_type (str): Container permission type: (attribute, property, acl, or ownership) perm_action (str): Container permission read/write action. """ permission = "none" if perm_type == "attribute": permission = perm_action elif perm_type == "property": permission = perm_action.replace("r", "t") permission = permission.replace("w", "T") elif perm_type == "acl": permission = perm_action.replace("r", "a") permission = permission.replace("w", "A") elif perm_type == "ownership": permission = perm_action.replace("w", "to") permission = permission.replace("r", "rwdTAa") else: self.fail("##In setup_container_acl_and_permission, unsupported " "perm_type {}".format(perm_type)) self.log.info( "At setup_container_acl_and_permission, setup %s, %s, %s, with %s", user_type, user_name, perm_type, permission) result = self.update_container_acl( secTestBase.acl_entry(user_type, user_name, permission)) if result.stderr_text: self.fail("##setup_container_acl_and_permission, fail on " "update_container_acl, expected Pass, but Failed.")
def test_daos_pool_acl_groups(self): ''' Epic: DAOS-1961: Testing related to DAOS security features. Testcase description: DAOS-2951: Pool ACE/ACL identities verification. DAOS-2955: Primary group user ACL verification. DAOS-2957: Secondary group user ACL verification. DAOS-3546: Test ACL access when user/group management isn't synced between client and server nodes. DAOS-2961: DAOS dmg pool overwrite-acl verification DAOS-2962: DAOS dmg pool delete-acl verification DAOS-2963: DAOS dmg pool get-acl verification Description: Create pool with pass-in user on primary and secondary group acl permission, verify pool user and group read, write, read-write and none permissions enforcement with all forms of input under different test sceanrios. :avocado: tags=all,full_regression,security,pool_acl,sec_acl_groups ''' user_gid = os.getegid() current_group = grp.getgrgid(user_gid)[0] primary_grp_perm = self.params.get(\ "pg_permission", "/run/pool_acl/primary_secondary_group_test/*")[0] read, write = self.params.get(\ "pg_read_write", "/run/pool_acl/primary_secondary_group_test/*") acl_entries = ["", "", "",\ secTestBase.acl_entry("group", current_group, primary_grp_perm, PERMISSIONS), ""] if primary_grp_perm.lower() == "none": primary_grp_perm = "" if primary_grp_perm not in PERMISSIONS: self.fail( "##primary_grp_perm %s is invalid, valid permissions are:" "'none', 'r', w', 'rw'", primary_grp_perm) self.log.info("==Starting self.pool_acl_verification") self.log.info(" =acl_entries = %s", acl_entries) self.log.info(" =expect read = %s", read) self.log.info(" =expect write= %s", write) self.pool_acl_verification(acl_entries, read, write, True) self.log.info( "--->Testcase Passed. " " user_type: group, permission: %s, expect_read: %s," " expect_write: %s.\n", primary_grp_perm, read, write)
def pool_acl_verification(self, current_user_acl, read, write, secondary_grp_test=False): """Verify the daos pool security with an acl file. Steps: (1)Setup dmg tool for creating a pool (2)Generate acl file with permissions (3)Create a pool with acl (4)Verify the pool create status (5)Get the pool's acl list (6)Verify pool's ace entry update and delete (7)Verify pool read operation (8)Verify pool write operation (9)Cleanup user and destroy pool Args: current_user_acl (str): acl with read write access credential. read (str): expecting read permission. write (str): expecting write permission. Return: None: pass to continue; fail to report the testlog and stop. """ # (1)Create dmg command scm_size = self.params.get("scm_size", "/run/pool_acl/*") get_acl_file = self.params.get("acl_file", "/run/pool_acl/*", "acl_test.txt") acl_file = os.path.join(self.tmp, get_acl_file) num_user = self.params.get("num_user", "/run/pool_acl/*") num_group = self.params.get("num_group", "/run/pool_acl/*") self.hostlist_clients = agu.include_local_host(self.hostlist_clients) # (2)Generate acl file with permissions self.log.info(" (1)Generate acl file with user/group permissions") permission_list = self.create_pool_acl(num_user, num_group, current_user_acl, acl_file) # (3)Create a pool with acl self.dmg.exit_status_exception = False data = self.dmg.pool_create(scm_size, acl_file=acl_file) self.dmg.exit_status_exception = True self.log.info(" (2)dmg= %s", self.dmg) self.log.info(" (3)Create a pool with acl") # (4)Verify the pool create status self.log.info(" (4)dmg.run() result=\n%s", self.dmg.result) if "ERR" in self.dmg.result.stderr: self.fail("##(4)Unable to parse pool uuid and svc.") # (5)Get the pool's acl list # dmg pool get-acl --pool <UUID> self.log.info(" (5)Get a pool's acl list by: " "dmg pool get-acl --pool --hostlist") pool_acl_list = self.get_pool_acl_list(data["uuid"]) self.log.info(" pool original permission_list: %s", permission_list) self.log.info(" pool get_acl permission_list: %s", pool_acl_list) # (6)Verify pool acl ace update and delete self.log.info(" (6)Verify update and delete of pool's acl entry.") tmp_ace = "daos_ci_test_new" new_entries = [ secTestBase.acl_entry("user", tmp_ace, "", PERMISSIONS), secTestBase.acl_entry("group", tmp_ace, "", PERMISSIONS) ] acl_principals = [ secTestBase.acl_principal("user", tmp_ace), secTestBase.acl_principal("group", tmp_ace) ] for new_entry in new_entries: self.update_pool_acl_entry(data["uuid"], "update", new_entry) for principal in acl_principals: self.update_pool_acl_entry(data["uuid"], "delete", principal) # (7)Verify pool read operation # daos pool query --pool <uuid> self.log.info(" (7)Verify pool read by: daos pool query --pool") self.verify_pool_readwrite(data["svc"], data["uuid"], "read", expect=read) # (8)Verify pool write operation # daos container create --pool <uuid> self.log.info( " (8)Verify pool write by: daos container create --pool") self.verify_pool_readwrite(data["svc"], data["uuid"], "write", expect=write) if secondary_grp_test: self.log.info(" (8-0)Verifying verify_pool_acl_prim_sec_groups") self.verify_pool_acl_prim_sec_groups(pool_acl_list, acl_file, data["uuid"], data["svc"]) # (9)Cleanup user and destroy pool self.log.info(" (9)Cleanup users and groups") self.cleanup_user_group(num_user, num_group)
def verify_pool_acl_prim_sec_groups(self, pool_acl_list, acl_file, uuid, svc): """Verify daos pool acl access. Verify access with primary and secondary groups access permission. Args: pool_acl_list (list): pool acl entry list. acl_file (str): acl file to be used. uuid (str): daos pool uuid. svc (int): daos pool svc. Return: None. """ sec_group = self.params.get("secondary_group_name", "/run/pool_acl/*") sec_group_perm = self.params.get("sg_permission", "/run/pool_acl/*") sec_group_rw = self.params.get("sg_read_write", "/run/pool_acl/*") user_gid = os.getegid() current_group = grp.getgrgid(user_gid)[0] primary_grp_perm = self.params.get( "pg_permission", "/run/pool_acl/primary_secondary_group_test/*")[0] sec_group = self.params.get( "secondary_group_name", "/run/pool_acl/primary_secondary_group_test/*") sec_group_perm = self.params.get( "sg_permission", "/run/pool_acl/primary_secondary_group_test/*") sec_group_rw = self.params.get( "sg_read_write", "/run/pool_acl/primary_secondary_group_test/*") l_group = grp.getgrgid(os.getegid())[0] for group in sec_group: secTestBase.add_del_user(self.hostlist_clients, "groupadd", group) cmd = "usermod -G " + ",".join(sec_group) self.log.info(" (8-1)verify_pool_acl_prim_sec_groups, cmd= %s", cmd) secTestBase.add_del_user(self.hostlist_clients, cmd, l_group) self.log.info( " (8-2)Before update sec_group permission, pool_acl_list= %s", pool_acl_list) for group, permission in zip(sec_group, sec_group_perm): if permission == "none": permission = "" n_acl = secTestBase.acl_entry("group", group, permission, PERMISSIONS) pool_acl_list.append(n_acl) self.log.info( " (8-3)After update sec_group permission, pool_acl_list= %s", pool_acl_list) self.log.info(" pool acl_file= %s", acl_file) secTestBase.create_acl_file(acl_file, pool_acl_list) # modify primary-group permission for secondary-group test grp_entry = secTestBase.acl_entry("group", current_group, primary_grp_perm, PERMISSIONS) new_grp_entry = secTestBase.acl_entry("group", current_group, "", PERMISSIONS) self.modify_acl_file_entry(acl_file, grp_entry, new_grp_entry) # dmg pool overwrite-acl --pool <uuid> --acl-file <file> result = self.dmg.pool_overwrite_acl(uuid, acl_file) self.log.info(" (8-4)dmg= %s", self.dmg) self.log.info(" (8-5)dmg.run() result=\n %s", result) # Verify pool read operation # daos pool query --pool <uuid> self.log.info(" (8-6)Verify pool read by: daos pool query --pool") exp_read = sec_group_rw[0] self.verify_pool_readwrite(svc, uuid, "read", expect=exp_read) # Verify pool write operation # daos container create --pool <uuid> self.log.info( " (8-7)Verify pool write by: daos container create pool") exp_write = sec_group_rw[1] self.verify_pool_readwrite(svc, uuid, "write", expect=exp_write) for group in sec_group: secTestBase.add_del_user(self.hostlist_clients, "groupdel", group)
def get_base_acl_entries(self, test_user): """Get container acl entries per cont enforcement order for test_user. Args: test_user (str): test user. Returns (list str): List of base container acl entries for the test_user. """ if test_user == "OWNER": base_acl_entries = [ secTestBase.acl_entry("user", "OWNER", ""), secTestBase.acl_entry("user", self.current_user, ""), secTestBase.acl_entry("group", "GROUP", "rwcdtTaAo"), secTestBase.acl_entry("group", self.current_group, "rwcdtTaAo"), secTestBase.acl_entry("user", "EVERYONE", "rwcdtTaAo") ] elif test_user == "user": base_acl_entries = [ "", secTestBase.acl_entry("user", self.current_user, ""), secTestBase.acl_entry("group", "GROUP", "rwcdtTaAo"), secTestBase.acl_entry("group", self.current_group, ""), secTestBase.acl_entry("user", "EVERYONE", "rwcdtTaAo") ] elif test_user == "group": base_acl_entries = [ "", "", secTestBase.acl_entry("group", "GROUP", ""), secTestBase.acl_entry("group", self.current_group, ""), secTestBase.acl_entry("user", "EVERYONE", "rwcdtTaAo") ] elif test_user == "GROUP": base_acl_entries = [ "", "", "", secTestBase.acl_entry("group", self.current_group, ""), secTestBase.acl_entry("user", "EVERYONE", "rwcdtTaAo") ] elif test_user == "EVERYONE": base_acl_entries = [ "", "", "", "", secTestBase.acl_entry("user", "EVERYONE", "") ] else: base_acl_entries = ["", "", "", "", ""] return base_acl_entries
def test_container_user_acl(self): """ Description: DAOS-4838: Verify container user security with ACL. DAOS-4390: Test daos_cont_set_owner DAOS-4839: Verify container group user with ACL. DAOS-4840: Verify container user and group access with ACL grant/remove modification. DAOS-4841: Verify container ACL works when servers not sync with client compute hosts. Test container 5 users enforcement order: (defined on test.yaml) OWNER: container owner assigned with the permissions. user: container user assigned with the permissions. user-group: container user-group assigned with the permissions. GROUP: container group assigned with the permissions. EVERYONE: everyone assigned with the permissions. Test container user acl permissions: w - set_container_attribute or data r - get_container_attribute or data T - set_container_property t - get_container_property a - get_container_acl_list A - update_container_acl o - set_container_owner d - destroy_container Steps: (1)Setup (2)Create pool and container with acl (3)Verify container permissions rw, rw-attribute (4)Verify container permissions tT, rw-property (5)Verify container permissions aA, rw-acl (6)Verify container permission o, set-owner (7)Verify container permission d, delete (8)Cleanup :avocado: tags=all,full_regression,security,container_acl, :avocado: tags=cont_user_sec,cont_group_sec,cont_sec """ #(1)Setup self.log.info("(1)==>Setup container user acl test.") cont_permission, expect_read, expect_write = self.params.get( "perm_expect", "/run/container_acl/permissions/*") new_test_user = self.params.get("new_user", "/run/container_acl/*") new_test_group = self.params.get("new_group", "/run/container_acl/*") attribute_name, attribute_value = self.params.get( "attribute", "/run/container_acl/*") property_name, property_value = self.params.get( "property", "/run/container_acl/*") secTestBase.add_del_user( self.hostlist_clients, "useradd", new_test_user) secTestBase.add_del_user( self.hostlist_clients, "groupadd", new_test_group) acl_file_name = os.path.join( self.tmp, self.params.get( "acl_file_name", "/run/container_acl/*", "cont_test_acl.txt")) test_user = self.params.get( "testuser", "/run/container_acl/daos_user/*") test_user_type = secTestBase.get_user_type(test_user) base_acl_entries = self.get_base_acl_entries(test_user) if test_user == "user": test_user = self.current_user if test_user == "group": test_user = self.current_group self.log.info( "==>(1.1)Start testing container acl on user: %s", test_user) #(2)Create pool and container with acl self.log.info("(2)==>Create a pool and a container with acl\n" " base_acl_entries= %s\n", base_acl_entries) self.pool_uuid = self.create_pool_with_dmg() secTestBase.create_acl_file(acl_file_name, base_acl_entries) self.container_uuid = self.create_container_with_daos( self.pool, None, acl_file_name) #(3)Verify container permissions rw, rw-attribute permission_type = "attribute" self.log.info("(3)==>Verify container permission %s", permission_type) self.update_container_acl( secTestBase.acl_entry(test_user_type, test_user, "rw")) self.verify_cont_rw_attribute( "write", "pass", attribute_name, attribute_value) self.setup_container_acl_and_permission( test_user_type, test_user, permission_type, cont_permission) self.log.info( "(3.1)Verify container_attribute: write, expect: %s", expect_write) self.verify_cont_rw_attribute( "write", expect_write, attribute_name, attribute_value) self.log.info( "(3.2)Verify container_attribute: read, expect: %s", expect_read) self.verify_cont_rw_attribute("read", expect_read, attribute_name) #(4)Verify container permissions tT rw-property permission_type = "property" self.log.info("(4)==>Verify container permission tT, rw-property") self.log.info( "(4.1)Update container-acl %s, %s, permission_type: %s with %s", test_user_type, test_user, permission_type, cont_permission) self.setup_container_acl_and_permission( test_user_type, test_user, permission_type, cont_permission) self.log.info( "(4.2)Verify container_attribute: read, expect: %s", expect_read) self.verify_cont_rw_property("read", expect_read) self.log.info( "(4.3)Verify container_attribute: write, expect: %s", expect_write) self.verify_cont_rw_property( "write", expect_write, property_name, property_value) self.log.info( "(4.4)Verify container_attribute: read, expect: %s", expect_read) self.verify_cont_rw_property("read", expect_read) #(5)Verify container permissions aA, rw-acl permission_type = "acl" self.log.info("(5)==>Verify container permission aA, rw-acl ") self.log.info( "(5.1)Update container-acl %s, %s, permission_type: %s with %s", test_user_type, test_user, permission_type, cont_permission) expect = "pass" #User who created the container has full acl access. self.setup_container_acl_and_permission( test_user_type, test_user, permission_type, cont_permission) self.log.info("(5.2)Verify container_acl: write, expect: %s", expect) self.verify_cont_rw_acl( "write", expect, secTestBase.acl_entry( test_user_type, test_user, cont_permission)) self.log.info("(5.3)Verify container_acl: read, expect: %s", expect) self.verify_cont_rw_acl("read", expect) #(6)Verify container permission o, set-owner self.log.info("(6)==>Verify container permission o, set-owner") permission_type = "ownership" expect = "deny" if "w" in cont_permission: expect = "pass" self.log.info( "(6.1)Update container-set ownership %s, %s, permission_type:" " %s with %s", test_user_type, test_user, permission_type, cont_permission) self.setup_container_acl_and_permission( test_user_type, test_user, permission_type, cont_permission) self.log.info("(6.2)Verify container_ownership: write, expect: %s", expect) self.verify_cont_set_owner( expect, new_test_user+"@", new_test_group+"@") #Verify container permission A acl-write after set container # to a different owner. if cont_permission == "w": permission_type = "acl" expect = "deny" self.log.info("(6.3)Verify container_acl write after changed " "ownership: expect: %s", expect) self.verify_cont_rw_acl("write", expect, secTestBase.acl_entry( test_user_type, test_user, cont_permission)) #(7)Verify container permission d, delete self.log.info("(7)==>Verify cont-delete on container and pool" " with/without d permission.") permission_type = "delete" c_permission = "rwaAtTod" p_permission = "rctd" expect = "pass" if "r" not in cont_permission: #remove d from cont_permission c_permission = "rwaAtTo" if "w" not in cont_permission: #remove d from pool_permission p_permission = "rct" if cont_permission == "": expect = "deny" self.update_container_acl(secTestBase.acl_entry(test_user_type, test_user, c_permission)) self.update_pool_acl_entry(self.pool_uuid, "update", secTestBase.acl_entry("user", "OWNER", p_permission)) self.verify_cont_delete(expect) #(8)Cleanup secTestBase.add_del_user( self.hostlist_clients, "userdel", new_test_user) secTestBase.add_del_user( self.hostlist_clients, "groupdel", new_test_group)
def test_daos_pool_acl_enforcement(self): ''' Epic: DAOS-1961: Testing related to DAOS security features. Testcase description: DAOS-2950: New pool create with pass-in ACL and connect credential verification. DAOS-2952: Pool ACE/ACL permissions verification. DAOS-2953: Pool ACL enforcement order verification. DAOS-3611: Pool ACL verification after user removed from a granted group. DAOS-3612: ACL update to remove/grant user/group access pool DAOS-3546: Test ACL access when user/group management isn't synced between client and server nodes Description: Create pool with pass-in user and group acl permission, verify pool user and group read, write, read-write and none permissions enforcement with all forms of input under different test sceanrios. :avocado: tags=all,full_regression,security,pool_acl,sec_acl ''' user_uid = os.geteuid() user_gid = os.getegid() current_user = pwd.getpwuid(user_uid)[0] current_group = grp.getgrgid(user_gid)[0] user_type = self.params.get("user", "/run/pool_acl/*")[0].lower() permission, read, write = self.params.get("name", "/run/pool_acl/*") user_types = ["owner", "user", "ownergroup", "group", "everyone"] default_acl_entries = ["A::OWNER@:", secTestBase.acl_entry("user", current_user, "", PERMISSIONS), "A:G:GROUP@:", secTestBase.acl_entry("group", current_group, "", PERMISSIONS), "A::EVERYONE@:"] test_acl_entries = ["", "", "", "", ""] if permission.lower() == "none": permission = "" if permission not in PERMISSIONS: self.fail("##permission %s is invalid, valid permissions are:" "'none', 'r', w', 'rw'", permission) if user_type not in user_types: self.fail("##user_type %s is invalid, valid user_types are: " "%s", user_type, user_types) user_type_ind = user_types.index(user_type) self.log.info("===>Start DAOS pool acl enforcement order Testcase: " " user_type: %s, permission: %s, expect_read: %s," " expect_write: " "%s.", user_type, permission, read, write) #take care of the user_type which have higher privilege for ind in range(5): if ind < user_type_ind: test_acl_entries[ind] = "" elif ind == user_type_ind: continue else: test_acl_entries[ind] = default_acl_entries[ind] test_permission = permission #take care of rest of the user-type permission group_acl = "" for ind in range(user_type_ind, 5): if ind != user_type_ind: #setup opposite test_permission with permission test_permission = "rw" if permission == "rw": test_permission = "" if user_types[ind] == "group": group_acl = test_permission test_acl_entries[ind] = default_acl_entries[ind] + test_permission #union of ownergroup and group permission if user_type == "ownergroup": if permission != group_acl: union_acl = "".join(list(set().union(permission, group_acl))) if union_acl == "": read = "deny" write = "deny" elif union_acl == "r": read = "pass" write = "deny" elif union_acl == "w": read = "deny" write = "deny" else: read = "pass" write = "pass" self.pool_acl_verification(test_acl_entries, read, write) self.log.info( "--->Testcase Passed. " " user_type: %s, permission: %s, expect_read: %s," " expect_write: %s.\n", user_type, permission, read, write)