def setUp(self): super(NtaclsBackupRestoreTests, self).setUp() self.server = os.environ["SERVER"] # addc samdb_url = 'ldap://' + self.server self.service = 'test1' # service/share to test # root path for service self.service_root = os.path.join(os.environ["LOCAL_PATH"], self.service) self.smb_conf_path = os.environ['SMB_CONF_PATH'] self.dom_sid = security.dom_sid(os.environ['DOMSID']) self.creds = self.insta_creds(template=self.get_credentials()) # helper will load conf into lp, that's how smbd can find services. self.ntacls_helper = ntacls.NtaclsHelper(self.service, self.smb_conf_path, self.dom_sid) self.lp = self.ntacls_helper.lp self.samdb_conn = samdb.SamDB(url=samdb_url, session_info=system_session(), credentials=self.creds, lp=self.lp) self.smb_conn = smb.SMB(self.server, self.service, lp=self.lp, creds=self.creds) self.smb_helper = ntacls.SMBHelper(self.smb_conn, self.dom_sid) self.tarfile_path = os.path.join(self.tempdir, 'ntacls-backup.tar.gz') # an example file tree self.tree = { 'file0.txt': b'test file0', 'dir1': { 'file1.txt': b'test file1', 'dir2': {} # an empty dir in dir }, } self._delete_tarfile() self.smb_helper.delete_tree() self.smb_helper.create_tree(self.tree) self._check_tree() # keep a copy of ntacls after tree just created self.original_ntacls = self.smb_helper.get_ntacls()
def _test_notify_privileged_path(self, monitor_path=None, rel_prefix=None): self.connect_unpriv() domain_sid = security.dom_sid() # we just use S-0-0 smb_helper = ntacls.SMBHelper(self.smb_conn, domain_sid) private_name = "private" private_rel = self.make_path(rel_prefix, private_name) private_path = self.make_path(test_dir, private_name) # create a private test directory self.smb_conn.mkdir(private_path) # Get the security descriptor and replace it # with a one that only grants access to SYSTEM and the # owner. private_path_sd_old = smb_helper.get_acl(private_path) private_path_sd_new = security.descriptor() private_path_sd_new.type = private_path_sd_old.type private_path_sd_new.revision = private_path_sd_old.revision private_path_sd_new = security.descriptor.from_sddl("G:BAD:(A;;0x%x;;;%s)(A;;0x%x;;;%s)" % ( security.SEC_RIGHTS_DIR_ALL, security.SID_NT_SYSTEM, security.SEC_RIGHTS_DIR_ALL, str(private_path_sd_old.owner_sid)), domain_sid) private_path_sd_new.type |= security.SEC_DESC_SELF_RELATIVE private_path_sd_new.type |= security.SEC_DESC_DACL_PROTECTED set_secinfo = security.SECINFO_GROUP | security.SECINFO_DACL | security.SECINFO_PROTECTED_DACL smb_helper.set_acl(private_path, private_path_sd_new, sinfo=set_secinfo) # setup notification request as priviliged user monitor_priv_fnum = self.smb_conn.create(Name=monitor_path, ShareAccess=1) notify_priv = self.smb_conn.notify(fnum=monitor_priv_fnum, buffer_size=0xffff, completion_filter=libsmb.FILE_NOTIFY_CHANGE_ALL, recursive=True) # setup notification request as unpriviliged user monitor_unpriv_fnum = self.smb_conn_unpriv.create(Name=monitor_path, ShareAccess=1) notify_unpriv = self.smb_conn_unpriv.notify(fnum=monitor_unpriv_fnum, buffer_size=0xffff, completion_filter=libsmb.FILE_NOTIFY_CHANGE_ALL, recursive=True) # make sure we didn't receive any changes yet. self.smb_conn.echo() changes = notify_priv.get_changes(wait=False) self.assertIsNone(changes) self.smb_conn_unpriv.echo() changes = notify_unpriv.get_changes(wait=False) self.assertIsNone(changes) # trigger notification in the private dir new_name = 'test-new' new_rel = self.make_path(private_rel, new_name) new_path = self.make_path(private_path, new_name) self.smb_conn.mkdir(new_path) # check that only the privileged user received the changes changes = notify_priv.get_changes(wait=True) self.assertIsNotNone(changes) self.assertEqual(changes[0]['name'], new_rel) self.assertEqual(changes[0]['action'], libsmb.NOTIFY_ACTION_ADDED) self.assertEqual(len(changes), 1) notify_priv = self.smb_conn.notify(fnum=monitor_priv_fnum, buffer_size=0xffff, completion_filter=libsmb.FILE_NOTIFY_CHANGE_ALL, recursive=True) # check that the unprivileged user does not receives the changes self.smb_conn_unpriv.echo() changes = notify_unpriv.get_changes(wait=False) self.assertIsNone(changes) # and there's no additional change for the privileged user self.smb_conn.echo() changes = notify_priv.get_changes(wait=False) self.assertIsNone(changes) # trigger notification in the private dir self.smb_conn.rmdir(new_path) # check that only the privileged user received the changes changes = notify_priv.get_changes(wait=True) self.assertIsNotNone(changes) self.assertEqual(changes[0]['name'], new_rel) self.assertEqual(changes[0]['action'], libsmb.NOTIFY_ACTION_REMOVED) self.assertEqual(len(changes), 1) notify_priv = self.smb_conn.notify(fnum=monitor_priv_fnum, buffer_size=0xffff, completion_filter=libsmb.FILE_NOTIFY_CHANGE_ALL, recursive=True) # check that the unprivileged user does not receives the changes self.smb_conn_unpriv.echo() changes = notify_unpriv.get_changes(wait=False) self.assertIsNone(changes) # and there's no additional change for the privileged user self.smb_conn.echo() changes = notify_priv.get_changes(wait=False) self.assertIsNone(changes) # trigger notification for both self.smb_conn.rmdir(private_path) # check that both get thte notification changes = notify_unpriv.get_changes(wait=True) self.assertIsNotNone(changes) self.assertEqual(changes[0]['name'], private_rel) self.assertEqual(changes[0]['action'], libsmb.NOTIFY_ACTION_REMOVED) self.assertEqual(len(changes), 1) notify_unpriv = self.smb_conn_unpriv.notify(fnum=monitor_unpriv_fnum, buffer_size=0xffff, completion_filter=libsmb.FILE_NOTIFY_CHANGE_ALL, recursive=True) changes = notify_priv.get_changes(wait=True) self.assertIsNotNone(changes) self.assertEqual(changes[0]['name'], private_rel) self.assertEqual(changes[0]['action'], libsmb.NOTIFY_ACTION_REMOVED) self.assertEqual(len(changes), 1) notify_priv = self.smb_conn.notify(fnum=monitor_priv_fnum, buffer_size=0xffff, completion_filter=libsmb.FILE_NOTIFY_CHANGE_ALL, recursive=True) # check that the unprivileged user does not receives the changes self.smb_conn_unpriv.echo() changes = notify_unpriv.get_changes(wait=False) self.assertIsNone(changes) # and there's no additional change for the privileged user self.smb_conn.echo() changes = notify_priv.get_changes(wait=False) self.assertIsNone(changes) # closing the handle on will trigger a NOTIFY_CLEANUP self.smb_conn_unpriv.close(monitor_unpriv_fnum) try: changes = notify_unpriv.get_changes(wait=True) self.fail() except samba.NTSTATUSError as err: self.assertEqual(err.args[0], NT_STATUS_NOTIFY_CLEANUP) # there's no additional change for the privileged user self.smb_conn.echo() changes = notify_priv.get_changes(wait=False) self.assertIsNone(changes) # closing the handle on will trigger a NOTIFY_CLEANUP self.smb_conn.close(monitor_priv_fnum) try: changes = notify_priv.get_changes(wait=True) self.fail() except samba.NTSTATUSError as err: self.assertEqual(err.args[0], NT_STATUS_NOTIFY_CLEANUP)