For a Windows folder, Advanced security settings can be entered. In Windows 2016 there is frame "Add a condition to limit access. The principal will be granted the specified permissions only if conditions are met."
Items (= security groups) can be added and is basically selecting one or more AD security groups (when Dynamic Access Control (DAC) is not further installed.
The question is, how can we program in C# (or powershell) adding (and removing) such a condition with two AD security groups.
A pretty old question, but just in case somebody still googles for an answer. The access rule in the screenshot seems to be kind of extension to regular ACL.
The only way to modify it I found is through the SDDL.
Get ACL Object: $acl = Get-Acl -Path $FolderPath
Get current SDDL string: $acl.Sddl
Expand an existing entry with the conditional rule like this (Note X, 0x1301bf and ;(Member_of_any {SID(S-1-5-21-XXX-XXX-XXX-1619)}) parts).
(A;OICI;FA;;;S-1-5-21-XXX-XXX-XXX-1113)
(XA;OICI;0x1301bf;;;S-1-5-21-XXX-XXX-XXX-1113;(Member_of_any {SID(S-1-5-21-XXX-XXX-XXX-1619)}))
More examples can be learned by examining different SDDLs from GUI-made objects.
Modify $acl object: $acl.SetSecurityDescriptorSddlForm($NewSddl)
Re-apply it to the folder: Set-Acl -Path $FolderPath -AclObject $acl
Related
I'm having this issue where I'm trying to check if NT\Authority Local Service has read\execute permissions on a directory (folder). The product that I work on REQUIRES that the folder the user is installing to has read\execute permissions set for Local Service.
The problem is that when I get the Access Control List (ACL) recursively (groups-within-groups), Local Service is not listed so I can't check if he has permissions to that folder or not.
By default, Local Service does not have read/execute permissions to user profiles (My Documents, Desktop, etc...) but I won't know if Local Service has access to other directories the user chooses to install to.
NOTE: Local Service DOES have access to Program Files, even though it is NOT listed in the ACL. Is it hidden somewhere else?
This is a short snippet on how I'm pulling the ACL:
GroupPrincipal groupPrincipal =
GroupPrincipal.FindByIdentity(principalContext, identityReferenceValue);
// GetMembers(true) is recursive (groups-within-groups)
foreach (var member in groupPrincipal.GetMembers(true)) {
if (member.SamAccountName.Equals("LOCAL SERVICE")) {
foundLocalService = true;
break;
}
}
Is there any other way I should be doing this? (Other than adding an access rule for Local Service on that directory)
Is Local Service just not listed in Directories ACL's?
Any help would be greatly appreciated.
It's notoriously difficult to calculate "effective permissions" for an account. But the simple answer to your question is that you will likely want to look for either on of:
The local Users group, sometimes shown as BUILTIN\Users or COMPUTERNAME\Users, or
Authenticated Users, sometimes shown as NT AUTHORITY\Authenticated Users.
Authenticated Users is one of the well-know SIDs. It is "a group that includes all users whose identities were authenticated when they logged on.". As long as you can prove who you are, you are included in Authenticated Users. The SID for this is always S-1-5-11 on every Windows computer.
However, it's not really considered a real group. To find it when adding permissions to a folder, you have to have "Built-in security principals" selected under "Select this object type":
The local Users group contains Authenticated Users by default. On my computer, I actually see both Users and Authenticated Users in the default permissions on the file system.
That's what you will most likely see, and that's likely all that matters.
But that's not the only way. You could see Everyone (S-1-1-0), which includes every user, authenticated or not.
Or, it could be a file or folder that has the LOCAL SERVICE account as the owner.
Or, there could be a local group that was created manually and LOCAL SERVICE was added to.
One way to get a more authoritative list of what you can look for is to run this under the LOCAL SERVICE account:
whoami /groups
That will tell you every group in the authentication token, which is every group that you are considered a member of for authentication purposes.
But you can't just open a command prompt as LOCAL SERVICE. So one way to do this is to open the Task Scheduler and create a task that runs under LOCAL SERVICE, with the action of:
Program: cmd
Arguments: /c "whoami /groups > C:\temp\localservice.txt"
Then run the task and, when it's done, look at C:\temp\localservice.txt. It will have a table of group names and their SIDs that you can look for.
Let me start by saying I'm completely new to databases, but have been reading through the MySQL tutorial they have.
Right now, I'm trying to make an app that allows unprivileged users (non-root) to connect and do some commands on a database through a C# GUI app. The users will login to the database using windows authentication.
Now, I was able to to make a quick GUI where the person running the program can connect to the database on a local host using "root" and get whatever content is in it.
My question is, how exactly do I allow users to connect w/ non-root privileges? The only things I've been able to find all deal w/ using the connection string w/ "root" as the user.
Edit: The database is already made. I won't personally be able to connect to it as a root user and give other users permissions.
You could use the grant syntax, as root to grant permissions to other users. E.g.:
GRANT ALL PRIVILEGES ON mydatabase.* TO pfinferno
Some important concepts too are the rows in the table shown here:
select user,host,password from mysql.user where user='pfinferno';
Important takeaways, users can have multiple hostnames or wildcard. Each have their own rights and passwords. Though the password from the above is hashed, at least you can quickly eyeball it so see if all the passwords match (such as root with 3 accounts).
The host column is populated by the following values, mostly:
Specimen A:
localhost
127.0.0.1
%
common names such md21.newyork.comcastbusiness.net and the like
The % value is the wildcard. It is for flexibility, but it can be highly dangerous when used with users like 'root'#'%'. Keeping root as the 1st two only in Specimen A is highly advised. Also, the first two are quite different in different tools. What I recommend is having a root user row for the first two, and keeping the passwords the same. There are pros and cons to this approach. But remember that when you can't connect that something else out there was relying on the connection, be it an agent, phpmyadmin, a tool, the my.conf settings, etc. You will be revisiting this a lot.
In the example given by Mureinik it grants privileges to the user with the wildcard host = %. This means it is banking on a user created as such. Note that it is typical to have user accounts setup that way. Though there is nothing restricting you to locking it down tighter.
When a user attempts to connect to the server, the user he is ultimately connected as can be resolved to a different user/host combo, as can be seen in the case where there is no localhost (host) user or common-name, but rather one with a host value of wildcard %. This can be seen with this query:
Specimen B:
select current_user(),user();
The latter is the user presented by the connection attempt, the former is the one that was resolved and actual. The implications can cause one to waste days in debugging, as can be seen in these forums. Some people can't connect for days, I am serious.
Specimen C:
create user 'pfinferno'#'localhost' identified by 'thePassword';
create user 'pfinferno'#'127.0.0.1' identified by 'thePassword';
create user 'pfinferno' identified by 'thePassword';
create user 'pfinferno'#'md21.newyork.comcastbusiness.net' identified by 'thePassword';
-- note #3 above is same as 'pfinferno'#'%'
Now granted, the host name may be wildcard for normal users, and host name may be localhost and 127.0.0.1 for root only. But in the attempt to lock down security, admins often create user accounts based on hostname coming in (such as Specimen C, line 4), and vary security with grants based on that. Managing it can be a bit overwhelming. So they often just say screw it, I will create the wildcard user. That may be fine for a new user, say Susie, but for Secimen C line 4, if that is who you are coming in, you can have grants on line 3 user that you won't pick up. So the resolving of what user your are actuallity (See Specimen B), goes from most specific hostname to fallback to more general, until it finds one such as wildcard.
Unfortunately, users don't connect with hostname specified per se, they just are what they are. They try to connect. So you don't say hey I want to be this thing #hostname, you just are what you are. You are 'pfinferno'#'md21.newyork.comcastbusiness.net', but may fallback to wildcard.
If users are dropped in Specimen C except for wildcard %, well you better have the grants that went with them that you expect, because you are now a new user.
Try to limit the use of wildcards on the grant statement to not do *.* as in the lazy approach, which would just grant rights to all databases and tables. In Mureinik's example, it was for all tables in one database. Not too shabby. Try to fine tune rights, such as granting SELECT privileges on tables or not at all, to users that don't need them. Be careful with WITH GRANT OPTION as seen on the net with cut and paste from it. If you use it, you just granted the user rights to grant other users rights.
SSH Tunnels
One reason you might not want to use Secimen A host = % wildcard (other than the obvious We are Risk Averse) is that
create user 'pfinferno'#'localhost' identified by 'thePassword';
is perfect for SSH Tunnels. You would be connecting through a cryptographically secure channel with PKI, and present yourself as if you are # localhost. This drastically reduces security exposure.
Why Can't I Connect?
Hopefully the below visual with little commentary can show why I named this section as I did.
drop user 'pfinferno'#'localhost';
drop user 'pfinferno'#'127.0.0.1';
drop user 'pfinferno'#'%';
drop user 'pfinferno'#'md21.newyork.comcastbusiness.net';
flush privileges; -- some say this is not necessary, I have found otherwise
create user 'pfinferno'#'localhost' identified by 'thePassword';
create user 'pfinferno'#'127.0.0.1' identified by 'thePassword';
create user 'pfinferno' identified by 'thePassword';
create user 'pfinferno'#'md21.newyork.comcastbusiness.net' identified by 'thePassword';
...
select user,host,password from mysql.user where user='pfinferno';
grant all on so_gibberish.* to 'pfinferno'#'%'; -- grant all rights on so_gibberish db
flush privileges; -- some say this is not necessary, I have found otherwise
Look at some grants.
show grants for 'pfinferno'#'localhost'; -- sandboxed. Can just log in and sit there
+-----------------------------------------------------------------------------------------+
| Grants for pfinferno#localhost |
+-----------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'pfinferno'#'localhost' IDENTIFIED BY PASSWORD '*74692AE70C53...' |
+-----------------------------------------------------------------------------------------+
show grants for 'pfinferno'#'127.0.0.1'; -- sandboxed. Can just log in and sit there
same as above
show grants for 'pfinferno'; -- wildcard % user, has all rights on so_gibberish;
+-----------------------------------------------------------------------------------------+
| Grants for pfinferno#% |
+-----------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'pfinferno'#'%' IDENTIFIED BY PASSWORD '*74692AE70C53...' |
| GRANT ALL PRIVILEGES ON `so_gibberish`.* TO 'pfinferno'#'%' |
+-----------------------------------------------------------------------------------------+
Note above that GRANT USAGE means at least you have the rights to log in and sit (sandboxed). But the wildcard %user also has all rights on so_gibberish db in its entirety.
Now I go to mysql prompt via mysql -u pfinferno -pthePassword
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
mysql> select current_user(),user();
+---------------------+---------------------+
| current_user() | user() |
+---------------------+---------------------+
| pfinferno#localhost | pfinferno#localhost |
+---------------------+---------------------+
The attempted user (user()) was resolved to the same (current_user()). I was sandboxed, able to do basically nothing, except select now() til bored to death.
mysql> use so_gibberish;
ERROR 1044 (42000): Access denied for user 'pfinferno'#'localhost' to database 'so_gibberish'
quit mysql CLI as that user.
Now
drop user 'pfinferno'#'localhost';
drop user 'pfinferno'#'127.0.0.1';
drop user 'pfinferno'#'md21.newyork.comcastbusiness.net';
I just dropped three out of four of my pfinferno users
Go to mysql prompt via mysql -u pfinferno -pthePassword
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| so_gibberish |
+--------------------+
mysql> select current_user(),user();
+----------------+---------------------+
| current_user() | user() |
+----------------+---------------------+
| pfinferno#% | pfinferno#localhost |
+----------------+---------------------+
mysql> use so_gibberish;
Database changed
This shows that # the CLI (or any program) from any host, that the attempt to connect is first as presented by user and then as resolved to actual ( see the output from user() and current_user(), respectively).
So, perhaps oddly, as I dropped users, the EFFECTIVE RIGHTS increased as the user was resolved to a different one. This can be the subject of hours/days/weeks of debugging. Users can have no clue who they are really logged in as (resolved to), or why they can't, as each, by the way, can have a different password ! This is especially true with user root with several rows in mysql.user ... and considering that probably 50% of all mysql users connect with it, initially, as developers. Just a guestimate.
Well, first of all, you have to realize that this "root" (from MySQL) is different from the "root" user (from your computer).
When you log on MySQL database (as root firstly), you can create another user with least privileges. (Creating user: https://dev.mysql.com/doc/refman/5.1/en/create-user.html)
After that, you can give (grant) some privileges to this specific user. (Granting privileges: https://dev.mysql.com/doc/refman/5.1/en/grant.html)
You can, for instance, allow that some user will only select data from the tables. Another user can insert/update. And so on.
So, in your application, you can specify another user instead of root, as you can normally see.
I am wanting to make a silent installer as an option for administrators to deploy my product.
The product requires authentication to a master account and a user account. I want to make it possible to "stamp" the MSI for a certain user, storing their master account, user account and password. Note that none of these values are to do with Windows but are specific to the service that this installer is installing the client for.
What is the best way to do this?
Generally speaking you should use properties to set these values silently either using the command line interface for msiexec.exe or in a transform applied via the command line:
Command line:
msiexec /i "MySetup.msi" USER="OneUser" /PASS="PassWord" /qn
Transform:
msiexec /i "MySetup.msi" TRANSFORMS="MyTransform.mst" /qn
You can generate a transform via Orca, and it can override almost any value in the associated MSI file. Transforms are heavily used for application repackaging in large companies for silent deployment via systems such as Altiris, SCCM, and similar desktop management systems.
You simply define the properties in the property table, set some default value and allow them to be overridden by command line or transform and then use these values inside a custom action to set up the connection you require, or set the properties to the appropriate fields in the service installation tables.
ServiceInstall Element in Wix. And the MSI table ServiceInstall. It looks like this post may help you, I haven't studied it in detail though: WiX ServiceInstall - setting the service to run as the current windows user
Any idea how do I do the following using C#?
Going to Tools -> Internet Options -> Security
Select the Security tab
Click the Custom Level button
In the Miscellaneous section change Display mixed content to Enable
The "cheat" way to do this is to change the value
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\0\1609
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\1\1609
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\2\1609
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\3\1609
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\4\1609
Where 0-4 are Zone identifiers and the value is 0 to Allow, 1 to Prompt, and 3 to Block. Keep in mind that if your code does this on anyone's machine but your own, you're likely to find your code blocked as malware.
The "proper" way to do this is to use the APIs to create an IInternetZoneManager and call SetZoneActionPolicy to adjust the settings for URLACTION_HTML_MIXED_CONTENT in the zones you want to adjust.
You aren't supposed to do this "programmatically". That's why there isn't an API for it. Only the user can change their security settings, and they do it using the built-in interface that you've already discovered.
The poor IE team has been working overtime trying to tighten up the security of their browser. They're not going to throw in something like this that would nullify all of their efforts in a matter of seconds.
Recall that even once this option is selected, there's a confirmation dialog presented. How do you propose to "click" that programmatically? (Hmm, on second thought, don't tell me. That's probably the next question you'll be asking.)
Give up on trying to do this programmatically, and ask the user to do it themselves. Provide a complete help file or other documentation that explains why you're requesting that they make this change, what features will be unavailable if they do not choose to make this change, and what the possible security risks of making such a change are. And, of course, specific instructions on how the change is made.
Or, better yet, redesign your app so that it doesn't require a system-wide modification of IE's security settings. It's hard to imagine a legitimate case for this. A better solution might be asking the user to add your site to their "trusted sites". Remember that local pages have different security settings than remote pages by default.
Also do not forget Group Policies. Most (if not all) IE settings may also be specified in Group Policies.
According to Local group policy setting for IE security page vs Internet options security page
the Group Policy settings override user-defined settings.
So, on my home PC (works without domain controller) I have a choice to define IE settings either via Local Group Policy Editor or via Internet Options. For example, if I run gpedit.msc to open Local Group Policy Editor, select
Computer Configuration\Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone
change "Display mixed content" setting to "Enabled", then select "Enable" in drop down box, click Apply,
then open Security Settings for Internet Zone in IE - I will see that "Display mixed content" changed to Enable and
the selection is disabled because it is overriden by Policy.
For the entire list of supported policies download WindowsServer2012andWindows8GroupPolicySettings.xlsx
from
http://www.microsoft.com/en-us/download/details.aspx?id=25250
Now back to the question how to change settings programmatically.
EricLaw correctly suggested using SetZoneActionPolicy from IInternetZoneManager.
But it is hard to find samples for calling it from C#.
I ended up copying
http://www.pinvoke.net/default.aspx/Interfaces.IInternetZoneManager
into my code and then doing:
//This will disable "Download signed ActiveX" (IE setting # 0x1001) for Internet Zone (zone #3)
IInternetZoneManager izm = Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("7b8a2d95-0ac9-11d1-896c-00c04Fb6bfc4"))) as IInternetZoneManager;
IntPtr pPolicy = Marshal.AllocHGlobal(4);
Marshal.Copy(new int[] { 3 }, 0, pPolicy, 1);//3 means "Disable"
int result = izm.SetZoneActionPolicy((uint)UrlZone.Internet, (uint)0x1001, pPolicy, 4, (uint)UrlZoneReg.CurrentUserKey);
Marshal.ReleaseComObject(izm);
Marshal.FreeHGlobal(pPolicy);
I also tried changing group policy programmatically.
I used library from
https://bitbucket.org/MartinEden/local-policy
and then:
//This will disable "Download signed ActiveX controls" computer policy for Internet Zone (zone #3)
const string keyPath = #"SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3";
var gpo = new LocalPolicy.ComputerGroupPolicyObject();
using (var machine = gpo.GetRootRegistryKey(LocalPolicy.GroupPolicySection.Machine))
{
using (var terminalServicesKey = machine.CreateSubKey(keyPath))
{
terminalServicesKey.SetValue("1001", 3, Microsoft.Win32.RegistryValueKind.DWord);
}
}
gpo.Save();
After successfully testing the code above on Win7 SP1 with IE 11 I decided to go back to the original suggestion from EricLaw: modify
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\*\1001
directly because this is what Microsoft is recommending. See, for example How to strengthen the security settings for the Local Machine zone in Internet Explorer or Enhanced Browsing Security
I am not sure but I think you can find all these settings in "registry". You need to find out the appropriate key. And to change those values you need to have proper rights. Registry can be accessed from .net code
I am trying to use eventlogs in my application using C#, so I added the following code
if (!EventLog.SourceExists("SomeName"))
EventLog.CreateEventSource("SomeName", "Application");
The EventLog.SourceExists causes SecurityException that says
"The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security."
I am running as administrator in Windows 7.
Any help would be appriciated.
This is a permissions problem - you should give the running user permission to read the following registry key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog
Alternaitvely you can bypas the CreateEventSource removing the need to access this registry key.
Both solutions are explained in more detail in the following thread - How do I create an Event Log source under Vista?.
Yes, it's a permissions issue, but it's actually worse than indicated by the currently accepted answer. There are actually 2 parts.
Part 1
In order to use SourceExists(), the account that your code is running under must have "Read" permission for the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog key and it must also have "Read" permissions on each of the descendant-keys. The problem is that some of the children of that key don't inherit permissions, and only allow a subset of accounts to read them. E.g. some that I know about:
Security
State
Virtual Server
So you have to also manually change those when they exist.
FYI, for those keys (e.g. "State") where even the Administrator account doesn't have "Full Access" permission, you'll have to use PsExec/PsExec64 to "fix" things. As indicated in this StackOverflow answer, download PsTools. Run this from an elevated command prompt: PsExec64 -i -s regedit.exe and you'll them be able to add the permissions you need to that key.
Part 2
In order to successfully use CreateEventSource(), the account that your code is running under must have "Full Control" permissions on HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog as well as have "Full Control" permissions on the log you're adding the new source to.
But wait, there's more...
It is also important to know that both CreateEventSource() and WriteEntry() call SourceExists() "under the hood". So ultimately, if you want to use the EventLog class in .Net, you have to change permissions in the registry. The account needs "Full Control" on the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog key and "Read" for all children.
Commentary: And I believe all of this mess is because when Microsoft originally designed the EventLog, they decided it was critical that people would be able to log something by "Source" without needing to know what log that "Source" went with.
Short tip:
One event source is registered during Service instalation (if application is Windows Service), and can be used without Security Exception with low-profile process owner (not Administrator)
I perform service installation / run with C# code in typical way from SO/ MSDN
Important is property ServiceName in class System.ServiceProcess.ServiceBase .
Good afternoon,
The simplest is that you run vs2019 as an administrator, so when debugging or excute the service, it will run correctly without generating the exception.