I am working on a project to automate the creation of libraries on a metadata server. Using methods like METADATA_NEWOBJ and METADATA_SETATTR, I am 95% there; the one thing I haven't been able to do is set the newly created library to be read-only. Using Management Console we would do this by going to the advanced options and setting "Library access" to READONLY; can this be accomplished directly from code?
After some help from SAS Technical Support and some manual poking around, I am posting a solution in case it can help someone else.
DATA _null_;
LENGTH luri puri pturi $256;
CALL MISSING(luri, puri, pturi);
rc=0;
nobj=METADATA_GETNOBJ("omsobj:SASLibrary?@Name='MyTestLibrary'",1,luri);
IF (nobj > 0) THEN DO;
rc=METADATA_SETPROP(luri, "Library.SAS.Property.ACCESS.Name.xmlKey.txt", "READONLY", puri);
rc=METADATA_SETATTR(puri, "PropertyName", "ACCESS");
rc=METADATA_SETATTR(puri, "Delimiter", "=");
rc=METADATA_NEWOBJ("PropertyType", pturi, "ACCESS Types");
rc=METADATA_SETASSN(puri, "OwningType", "Replace", pturi);
END;
RUN;
It's not as simple as putting access=readonly on to the end of the libname statement, is it? I don't often (because I'm sadly in an environment where SAS metadata is scarcely used) use metadata libnames, but that's how I'd do it without metadata.
In our environment the users rely almost exclusively on the metadata information presented in Enterprise Guide; most of them have never seen a LIBNAME statement before. Since we need the libraries to be protected from the moment the user connects from EG, we have to secure them in the metadata definitions. Of course, I am always open to alternate ways to control access that can be handled programatically.
My preference would be to have it done in metadata - so you don't have to worry about it.
But a problem with EG is that someone can always access the path with their own libname statement, and I don't believe there's any way that can be stopped if their own access rights allow them to do it. So check their LDAP (or equivalent) permissions.
You are absolutely correct about the user's ability to override the readonly flag. We are relying upon the fact that most of our users don't know about libname statements and, even if they did, they don't know what the file system structure looks like. Consequently, they can't construct the proper libname statement.
A gotcha with this situation is that we can't enforce the permissions at the file system or authorization level because we actually need the users to be able to alter the library contents in specific cases. In those instances we obfuscate the functionality in compiled macros, internally using the reverse of your suggestion: issue a libname statement granting write access, executing the appropriating updates, and issuing a second libname statement flipping back to readonly.
Ah. Well. Hmm. If the modifications to the datasets were able to be made generic enough, you could encapsulate the libname re-setting to writable, the modification to the data and the re-re-setting in a macro with options nomprint, and teach them how to do it that way.
After some help from SAS Technical Support and some manual poking around, I am posting a solution in case it can help someone else.
DATA _null_;
LENGTH luri puri pturi $256;
CALL MISSING(luri, puri, pturi);
rc=0;
nobj=METADATA_GETNOBJ("omsobj:SASLibrary?@Name='MyTestLibrary'",1,luri);
IF (nobj > 0) THEN DO;
rc=METADATA_SETPROP(luri, "Library.SAS.Property.ACCESS.Name.xmlKey.txt", "READONLY", puri);
rc=METADATA_SETATTR(puri, "PropertyName", "ACCESS");
rc=METADATA_SETATTR(puri, "Delimiter", "=");
rc=METADATA_NEWOBJ("PropertyType", pturi, "ACCESS Types");
rc=METADATA_SETASSN(puri, "OwningType", "Replace", pturi);
END;
RUN;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.