One of the challenges of developing software in a Windows environment is dealing with user permissions. If a user can’t access a file, that can bring your script to a grinding (and sometimes unexpected) halt. Understanding what a user can and cannot do is crucial to avoiding this scenario and ensuring only files to which the user has access are available for reading, writing, and executing. Today we’re going to take a look at a look at how Legato can help you determine what permissions a user has and ensure those file permissions don’t inappropriately interfere with your script’s proper execution.
Windows processes can be run one of two ways: normal or elevated. Since the release of Windows Vista and the introduction of User Account Control (UAC), processes will, by default with UAC enabled, be run normally, no matter whether the user running the program is an administrator or not. A process can ask to be started with elevated permissions, but that will generate a UAC prompt. In order to pass through a UAC prompt a user must have administrative rights, either through the user being a computer administrator (which is not commonplace for the average corporate account) or an administrator must enter his or her credentials.
How do users gain administrative rights? The answer lies with user groups. Users in a Windows domain environment are associated with groups. Groups are controlled on both a domain level and computer level. This allows domain administrators to give users different levels of permission based on the computer into which a user logs in. For example, a software developer may be given administrative level access on his own computer but still be a regular user on the domain. When a user logs on to a computer, Windows combines all of the rights that that user has to figure out what he or she can do on the computer. If a user is a domain administrator, he or she will be considered an administrator on every computer within that domain. In our example of a software developer being part of the Administrators group on his or her own computer, this developer will not be an administrator of other computers on the domain unless he or she is specifically added to the domain administrators’ group.
One final thing to note about Windows and elevated rights is the interaction between shared network drives, Windows Explorer, and administrative rights. When a user run programs in an elevated state, Windows runs the programs as that user but as an elevated version of that user. This leads to a strange interaction with mapped network drives where mapped drives appear to disappear in Windows 8 and earlier. This means, if you’re running GoFiler as an administrator, mapped network drives (ie. Z:\transfer\) may not work as expected. Microsoft appears to have fixed this issue in Windows 10, but if your scripts are running in a shared environment, it may be safest to use UNC paths rather than mapped drives in scripts. You can also avoid this problem by running the drive mapping commands in an elevated command prompt, which will map the drives to your administrator side.
So why would you need elevated rights to run a script? The big reason that we might need administrative rights is the ability to modify certain files. By default users are unable to modify particular Windows files, like Program Files [(x86)] and portions of the Windows folder. Running an elevated process allows us to change files in places that a normal user cannot change. Other reasons include having the ability to modify HKEY_LOCAL_MACHINE registry entries or change Windows settings. One thing to keep in mind is that administrators can add other users to the list of users able to modify files or folders, so these defaults are never guaranteed to be true (a secured system, however, will never have these files permissions modified).
Using Legato, we can check if we are running in an elevated environment by using one of two functions: the IsProcessElevated function or the IsProcessAdministrator function. On a computer with UAC enabled these two functions will always return the same value. If a process has been started elevated, they will return true (1). Otherwise, these functions will return false (0). We can use either as an initial check so that we know if our script will require elevated privileges, giving the user an error before we try to do anything else.
If you aren’t sure whether a script will require elevated privileges to run properly, you can always try to run the script. Legato includes error checking to find out where and how a script is failing. If you are attempting to write out a file, for example, you can see if the reason the script is failing is because of a lack of rights to change the file. You can do this by running the GetLastError function after a file write, using the bitwise AND function with the error mask, and determining if the resulting error is ERROR_ACCESS_DENIED. If it is, you may need to run the script with elevated privileges in order to successfully execute. For a list of defined error codes see Appendix G of the Legato SDK help. Note that these codes typically match Windows error codes for file access errors. In this case, the Windows error code for “Access Denied” is 5.
Here’s an example:
dword error;
StringToFile("Cheese", "C:\\Program Files (x86)\\GoFiler Complete\\Samples\\Test.txt");
error = GetLastError();
AddMessage("%d", error & ERROR_CODE_MASK);
If we run the above script in GoFiler without administrative rights we’ll get a ‘5’ printed in the Information View. If GoFiler is run with elevated administrative privileges, we will get a ‘0’ printed in the console, and we’ll get a text file with the word “Cheese” in it placed in our Samples folder.
Knowing for what reason our file operation has failed allows us to present a more meaningful error to the user and, in some cases, even compensate. In the above example, on error we could automatically save the file to a location that all users can access, such as the public folders or all users folders. We could also prompt the user to specify a location.
Administrative rights can be some of the most subtle problems that developers can encounter. They often can cause things to not work the way that one might expect. Recognizing what’s happening and being able to work within the confines of Windows security allows developers to better tune their software and scripts in a way that makes it easier for users to understand what is going on.
Joshua Kwiatkowski is a developer at Novaworks, primarily working on Novaworks’ cloud-based solution, GoFiler Online. He is a graduate of the Rochester Institute of Technology with a Bachelor of Science degree in Game Design and Development. He has been with the company since 2013. |
Additional Resources
Novaworks’ Legato Resources
Legato Script Developers LinkedIn Group
Primer: An Introduction to Legato