Ok folks so me and @CodesInChaos, we’ve been playing around like a lot researching the current state of the file-system and seeing into what could be done to aid not only this bogus situation but any future situations resulting from the fact that… we’ve been having little experience with modifying directories.
When you think of it, we’ve been adding files, removing files, changing files… I thought that some logic for modification of directories themselves was missing I even began introducing some changes to code responsible for the file system… all the mechanics based on Merkla Patricia Tries right in front of me… and I was scrapping my head on how to restore images of the sub-items when the folder-lead-node gets modified.
So I wrote code that that would make a backup copy of all of the images /hashes of the sub-elements… it quickly occurred to me that it was not needed to be done manually since like two years ago we have implemented some crazy cool copy constructors and stuff…
so I was like ok… make a back-up of the Merkle-Patricia root node, meaning the once within a specific directory; replace the current directory and transplant back the root-element from the previous directory.
I wrote all the code.
I was about to test it.
And then all of the sudden @CodesInChaos pointed out that this logic prevents sub-folders and files from being deleted since the code would always restore the previous.
So I ended up deleting …err… uncommenting all of the changes.
Leaving some in-code rationalization for posterity.
it follows.
/*
[Theory - Modification of Directories] - BEGIN
-----------------------
Update 16.07.22
What follows is not needed.
Reason? Had we implemented what follows it would not allow for deletion of files and sub-folders.
All it takes for folders to be explicitly modifiable is for the exact to-be-replaced-with instance to be provided to
this very function ( addNode() ).
The drawback is performance, since the current version of the node needs be queried for beforehand.
That apriori retrievd copy though, is to contain images of all the sub sub-nodes [Assumption 2].
ToDo:That needs to be verified as there might be some optimization checks scrapping this data as it is made available
outside of the Trie.
If, only a Security Descriptor is provided, only it is injected.
In any case, changes are made to propagate to the Root of the Trie.
There never is a need to modofy and /or update any of the sub-elements of the folder, in this scenario.
-----------------------
Notice: a leaf-node might as well be a 'directory' i.e. an instance of a CTrieDB.
In order to support explicit modification of directories, as a directory is modified (i.e. its name
or its security descriptor gets changed), we need to make sure that the updated version of the directory
'holds' all of the child-nodes. For this, we need to check for all of these and make sure references in the modified (upper-level, currently modified)
directory are valid.
Child-nodes, while residing in the cold storage, they do not hold any references to parential objects.
Such references are generated on-the fly as data gets retrieved, instead.
Thus, there is no need to be modifying child-nodes, in such a scenario at all.
[Assumption 1]: *Typically, whenever files are explicitly modified, such an operation triggers an update which propagates as far as the Root-node goes.*
This holds when modifying driectories, as a diretory is 'just' a leaf-node within a parental Merkle-Patricia-Trie.
So, whenever a directory is explicitly updated:
1) either A) a new instance of CTrieDB is provided *OR* B) just a new security descriptor is provided.
2) A) -> we replace the current CTrieDB retaining references (images/hashes!) of all of the child-nodes.
B) -> set the new security descriptor within of the present instance and be on our way
3) we rely on the exisiting mechanics assuring propagation of changes, upwords and towards the Root of the Trie [Assumption 1].
[Theory - Modification of Directories] - END
*/
So… seems like everything needed was already in place.
As for tackling the current bug, our first approach relied on introducing falsified security descriptors, dynamically for files that were being retrieved from the ‘token_pools’ directory.
It worked.
Together with @CodesInChaos we’ve decided it was too dirty an approach and it kept introducing a performance hit, of course, as the check was being made each time any file on the system was accessed.
Anyway, here’s the code:
//Retrieves security descriptior associated with an object.
std::shared_ptr<CRightsToken> CTrieNode::getPermToken()
{
std::lock_guard<std::recursive_mutex> lock(mGuardian);
//System State-Domain - BEGIN
std::string path = this->getPath(true);
std::string systemDir =("token_pools/");
if (path.rfind(systemDir,0)==0)
{//hot-fix to mitigate a missing security descriptor on the 'System' state-domain.
//this should be a 'one-time'process, after which a security descriptor should be inherited just fine during consecutive access attempts.
mPermToken= CRightsToken::genSysOnlyDescriptor();
}
//System State-Domain - END
return mPermToken;
}
So we decided to introduce a #GridScript patch, to be broadcasted across the network, signed through Overwatch privileges. The ‘patch’ would remotely alter security descriptors within the Token Pools system directory and of all of the files within.
I need yet to code it and ask for a permission from his holiness @TheOldWizard
Copy. Over and out.