📄 acls.c
字号:
CHECK_ACCESS_FLAGS(fnum2, SEC_RIGHTS_FILE_ALL); smbcli_close(cli->tree, fnum2); } else { CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); } printf("trying without execute\n"); io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL & ~SEC_FILE_EXECUTE; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); printf("and with full permissions again\n"); io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum2 = io.ntcreatex.out.file.fnum; CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE); smbcli_close(cli->tree, fnum2); printf("put back original sd\n"); set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; set.set_secdesc.in.file.fnum = fnum; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = sd_orig; status = smb_raw_setfileinfo(cli->tree, &set); CHECK_STATUS(status, NT_STATUS_OK); smbcli_close(cli->tree, fnum); io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum2 = io.ntcreatex.out.file.fnum; CHECK_ACCESS_FLAGS(fnum2, SEC_FILE_WRITE_DATA | SEC_FILE_READ_ATTRIBUTE); smbcli_close(cli->tree, fnum2); smbcli_unlink(cli->tree, fname1); smbcli_rmdir(cli->tree, dname);done: set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; set.set_secdesc.in.file.fnum = fnum; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = sd_orig; status = smb_raw_setfileinfo(cli->tree, &set); smbcli_close(cli->tree, fnum); return ret;}/* test dynamic acl inheritance*/static bool test_inheritance_dynamic(struct torture_context *tctx, struct smbcli_state *cli){ NTSTATUS status; union smb_open io; const char *dname = BASEDIR "\\inheritance"; const char *fname1 = BASEDIR "\\inheritance\\testfile"; bool ret = true; int fnum=0, fnum2; union smb_fileinfo q; union smb_setfileinfo set; struct security_descriptor *sd, *sd_orig=NULL; const char *owner_sid; printf("TESTING DYNAMIC ACL INHERITANCE\n"); if (!torture_setup_dir(cli, BASEDIR)) { return false; } io.generic.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.root_fid = 0; io.ntcreatex.in.flags = 0; io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY; io.ntcreatex.in.share_access = 0; io.ntcreatex.in.alloc_size = 0; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.fname = dname; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; printf("get the original sd\n"); q.query_secdesc.level = RAW_FILEINFO_SEC_DESC; q.query_secdesc.in.file.fnum = fnum; q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER; status = smb_raw_fileinfo(cli->tree, tctx, &q); CHECK_STATUS(status, NT_STATUS_OK); sd_orig = q.query_secdesc.out.sd; owner_sid = dom_sid_string(tctx, sd_orig->owner_sid); printf("owner_sid is %s\n", owner_sid); sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE, SEC_ACE_FLAG_OBJECT_INHERIT, NULL); sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ; set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; set.set_secdesc.in.file.fnum = fnum; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = sd; status = smb_raw_setfileinfo(cli->tree, &set); CHECK_STATUS(status, NT_STATUS_OK); printf("create a file with an inherited acl\n"); io.ntcreatex.in.fname = fname1; io.ntcreatex.in.create_options = 0; io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum2 = io.ntcreatex.out.file.fnum; smbcli_close(cli->tree, fnum2); printf("try and access file with base rights - should be OK\n"); io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum2 = io.ntcreatex.out.file.fnum; smbcli_close(cli->tree, fnum2); printf("try and access file with extra rights - should be denied\n"); io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); printf("update parent sd\n"); sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA | SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE, SEC_ACE_FLAG_OBJECT_INHERIT, NULL); sd->type |= SEC_DESC_DACL_AUTO_INHERITED | SEC_DESC_DACL_AUTO_INHERIT_REQ; set.set_secdesc.in.sd = sd; status = smb_raw_setfileinfo(cli->tree, &set); CHECK_STATUS(status, NT_STATUS_OK); printf("try and access file with base rights - should be OK\n"); io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum2 = io.ntcreatex.out.file.fnum; smbcli_close(cli->tree, fnum2); printf("try and access now - should be OK if dynamic inheritance works\n"); io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA | SEC_FILE_EXECUTE; status = smb_raw_open(cli->tree, tctx, &io); if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { printf("Server does not have dynamic inheritance\n"); } if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) { printf("Server does have dynamic inheritance\n"); } CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); smbcli_unlink(cli->tree, fname1);done: printf("put back original sd\n"); set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; set.set_secdesc.in.file.fnum = fnum; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = sd_orig; status = smb_raw_setfileinfo(cli->tree, &set); smbcli_close(cli->tree, fnum); smbcli_rmdir(cli->tree, dname); return ret;}#define CHECK_STATUS_FOR_BIT_ACTION(status, bits, action) do { \ if (!(bits & desired_64)) {\ CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); \ action; \ } else { \ CHECK_STATUS(status, NT_STATUS_OK); \ } \} while (0)#define CHECK_STATUS_FOR_BIT(status, bits, access) do { \ if (NT_STATUS_IS_OK(status)) { \ if (!(granted & access)) {\ printf("(%s) %s but flags 0x%08X are not granted! granted[0x%08X] desired[0x%08X]\n", \ __location__, nt_errstr(status), access, granted, desired); \ ret = false; \ goto done; \ } \ } else { \ if (granted & access) {\ printf("(%s) %s but flags 0x%08X are granted! granted[0x%08X] desired[0x%08X]\n", \ __location__, nt_errstr(status), access, granted, desired); \ ret = false; \ goto done; \ } \ } \ CHECK_STATUS_FOR_BIT_ACTION(status, bits, do {} while (0)); \} while (0)/* test what access mask is needed for getting and setting security_descriptors */static bool test_sd_get_set(struct torture_context *tctx, struct smbcli_state *cli){ NTSTATUS status; bool ret = true; union smb_open io; union smb_fileinfo fi; union smb_setfileinfo si; struct security_descriptor *sd; struct security_descriptor *sd_owner = NULL; struct security_descriptor *sd_group = NULL; struct security_descriptor *sd_dacl = NULL; struct security_descriptor *sd_sacl = NULL; int fnum=0; const char *fname = BASEDIR "\\sd_get_set.txt"; uint64_t desired_64; uint32_t desired = 0, granted; int i = 0;#define NO_BITS_HACK (((uint64_t)1)<<32) uint64_t open_bits = SEC_MASK_GENERIC | SEC_FLAG_SYSTEM_SECURITY | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_ALL | SEC_FILE_ALL | NO_BITS_HACK; uint64_t get_owner_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL; uint64_t set_owner_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER; uint64_t get_group_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL; uint64_t set_group_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_OWNER; uint64_t get_dacl_bits = SEC_MASK_GENERIC | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_READ_CONTROL; uint64_t set_dacl_bits = SEC_GENERIC_ALL | SEC_FLAG_MAXIMUM_ALLOWED | SEC_STD_WRITE_DAC; uint64_t get_sacl_bits = SEC_FLAG_SYSTEM_SECURITY; uint64_t set_sacl_bits = SEC_FLAG_SYSTEM_SECURITY; printf("TESTING ACCESS MASKS FOR SD GET/SET\n"); /* first create a file with full access for everyone */ sd = security_descriptor_dacl_create(tctx, 0, SID_NT_ANONYMOUS, SID_BUILTIN_USERS, SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_GENERIC_ALL, 0, NULL); sd->type |= SEC_DESC_SACL_PRESENT; sd->sacl = NULL; io.ntcreatex.level = RAW_OPEN_NTTRANS_CREATE; io.ntcreatex.in.root_fid = 0; io.ntcreatex.in.flags = 0; io.ntcreatex.in.access_mask = SEC_GENERIC_ALL; io.ntcreatex.in.create_options = 0; io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; io.ntcreatex.in.alloc_size = 0; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.fname = fname; io.ntcreatex.in.sec_desc = sd; io.ntcreatex.in.ea_list = NULL; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; status = smbcli_close(cli->tree, fnum); CHECK_STATUS(status, NT_STATUS_OK); /* * now try each access_mask bit and no bit at all in a loop * and see what's allowed * NOTE: if i == 32 it means access_mask = 0 (see NO_BITS_HACK above) */ for (i=0; i <= 32; i++) { desired_64 = ((uint64_t)1) << i; desired = (uint32_t)desired_64; /* first open the file with the desired access */ io.ntcreatex.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.access_mask = desired; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS_FOR_BIT_ACTION(status, open_bits, goto next); fnum = io.ntcreatex.out.file.fnum; /* then check what access was granted */ fi.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; fi.access_information.in.file.fnum = fnum; status = smb_raw_fileinfo(cli->tree, tctx, &fi); CHECK_STATUS(status, NT_STATUS_OK); granted = fi.access_information.out.access_flags; /* test the owner */ ZERO_STRUCT(fi); fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC; fi.query_secdesc.in.file.fnum = fnum; fi.query_secdesc.in.secinfo_flags = SECINFO_OWNER; status = smb_raw_fileinfo(cli->tree, tctx, &fi); CHECK_STATUS_FOR_BIT(status, get_owner_bits, SEC_STD_READ_CONTROL); if (fi.query_secdesc.out.sd) { sd_owner = fi.query_secdesc.out.sd; } else if (!sd_owner) { sd_owner = sd; } si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; si.set_secdesc.in.file.fnum = fnum; si.set_secdesc.in.secinfo_flags = SECINFO_OWNER; si.set_secdesc.in.sd = sd_owner; status = smb_raw_setfileinfo(cli->tree, &si); CHECK_STATUS_FOR_BIT(status, set_owner_bits, SEC_STD_WRITE_OWNER); /* test the group */ ZERO_STRUCT(fi); fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC; fi.query_secdesc.in.file.fnum = fnum; fi.query_secdesc.in.secinfo_flags = SECINFO_GROUP; status = smb_raw_fileinfo(cli->tree, tctx, &fi); CHECK_STATUS_FOR_BIT(status, get_group_bits, SEC_STD_READ_CONTROL); if (fi.query_secdesc.out.sd) { sd_group = fi.query_secdesc.out.sd; } else if (!sd_group) { sd_group = sd; } si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; si.set_secdesc.in.file.fnum = fnum; si.set_secdesc.in.secinfo_flags = SECINFO_GROUP; si.set_secdesc.in.sd = sd_group; status = smb_raw_setfileinfo(cli->tree, &si); CHECK_STATUS_FOR_BIT(status, set_group_bits, SEC_STD_WRITE_OWNER); /* test the DACL */ ZERO_STRUCT(fi); fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC; fi.query_secdesc.in.file.fnum = fnum; fi.query_secdesc.in.secinfo_flags = SECINFO_DACL; status = smb_raw_fileinfo(cli->tree, tctx, &fi); CHECK_STATUS_FOR_BIT(status, get_dacl_bits, SEC_STD_READ_CONTROL); if (fi.query_secdesc.out.sd) { sd_dacl = fi.query_secdesc.out.sd; } else if (!sd_dacl) { sd_dacl = sd; } si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; si.set_secdesc.in.file.fnum = fnum; si.set_secdesc.in.secinfo_flags = SECINFO_DACL; si.set_secdesc.in.sd = sd_dacl; status = smb_raw_setfileinfo(cli->tree, &si); CHECK_STATUS_FOR_BIT(status, set_dacl_bits, SEC_STD_WRITE_DAC); /* test the SACL */ ZERO_STRUCT(fi); fi.query_secdesc.level = RAW_FILEINFO_SEC_DESC; fi.query_secdesc.in.file.fnum = fnum; fi.query_secdesc.in.secinfo_flags = SECINFO_SACL; status = smb_raw_fileinfo(cli->tree, tctx, &fi); CHECK_STATUS_FOR_BIT(status, get_sacl_bits, SEC_FLAG_SYSTEM_SECURITY); if (fi.query_secdesc.out.sd) { sd_sacl = fi.query_secdesc.out.sd; } else if (!sd_sacl) { sd_sacl = sd; } si.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; si.set_secdesc.in.file.fnum = fnum; si.set_secdesc.in.secinfo_flags = SECINFO_SACL; si.set_secdesc.in.sd = sd_sacl; status = smb_raw_setfileinfo(cli->tree, &si); CHECK_STATUS_FOR_BIT(status, set_sacl_bits, SEC_FLAG_SYSTEM_SECURITY); /* close the handle */ status = smbcli_close(cli->tree, fnum); CHECK_STATUS(status, NT_STATUS_OK);next: continue; }done: smbcli_close(cli->tree, fnum); smbcli_unlink(cli->tree, fname); return ret;}/* basic testing of security descriptor calls*/bool torture_raw_acls(struct torture_context *tctx, struct smbcli_state *cli){ bool ret = true; if (!torture_setup_dir(cli, BASEDIR)) { return false; } ret &= test_sd(tctx, cli); ret &= test_nttrans_create(tctx, cli); ret &= test_creator_sid(tctx, cli); ret &= test_generic_bits(tctx, cli); ret &= test_owner_bits(tctx, cli); ret &= test_inheritance(tctx, cli); ret &= test_inheritance_dynamic(tctx, cli); ret &= test_sd_get_set(tctx, cli); smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -