Sid of local group in machine - c#

I try to find sid of the administrator group for example.
According to Microsoft the sid of that group is: S-1-5-21-machine-500
when the machine is identifier represents the three sub-authority values associated with a specific machine.
You can see it in the follow link:
https://msdn.microsoft.com/en-us/library/cc980032.aspx
I don't understand what the meaning of the <machine> and how I can get it using in c#.
Anybody know what is it or how I can get it?

Everything up to the 500 identifies the issuer of the SID, in this case the machine.
S-1-5 means "NT AUTHORITY", i.e. this SID is issued by is a Windows NT system. (The reason for this distinction is that SIDs are a subset of OIDs, an OSI standard for generating unique IDs, part of the DCE project and also used in LDAP).
S-1-5-21-X-X-X means "Issued by a domain", where X-X-X is a unique random number generated when the domain was created, or when the machine was installed.
This is also known as the "machine SID" or "domain SID" if it is for the domain. Specifically, the 21 identifies that the next three groups identify a domain, which will in turn issue more SIDs.
S-1-5-21-X-X-X-500 is the administrator account of the machine identified by S-1-5-21-X-X-X
The 500 is the RID or Relative ID. That's equivalent to the GID on Linux. 500 is the first local account or group to be created because RIDs are allocated beginning with 500. The next local account or group would get RID 501, and so on. 500 is generally the account Administrator, not a group though.
If you want to find information about security groups from C#, you should use the ADSI API, accessible from the System.DirectoryServices namespace. For local groups you need to use WinNT://MACHINENAME/ as your initial path.
https://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.path(v=vs.110).aspx
Note that users are not listed as members of their primary group (usually Users). You have to look at the User's PrimaryGroup property for that.

Related

NT AUTHORITY\Local Service is not listed in the Access Control List of a directory

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.

Connect to MySQL database w/ C# as non-root user?

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.

Can Domain name and host computer name be same

Recently I was trying to find answer to question "How to determine if current logged in user is part of domain or not"
On Stackoverflow I found pretty decent answers for the above which involved usage of
using System.Security.Principal;
using System.DirectoryServices.AccountManagement;
But I also see a simple solution saying
System.Environment.UserDomainName; - gives name of the current user's domain name.
System.Environment.MachineName; - gives name of the machine.
If above two are not the same means the user is part of domain returned by UserDomainName
Fair enough, also confirmed by this link from MSDN
Now the question is what if the "Domain name" and "Machine name" are identical?
or
Is it possible that a machine with the exact same name as domain name can join the domain?
If this is true, is there any possibilities to counter check this by adding something to this simple solution
I bet you the current logged on user does not have a distingished name if he or she isn't logged on to a domain. Use GetUserNameEx with the EXTENDED_NAME_FORMAT type NameFullyQualifiedDN (1).
If you get a value back then you know the current user is logged on to a domain. Though, Calling this function might block your program unexpectedly for a period of time. You probably want to call this function in a asynchronous fashion as it might atempt to connect to some Active Directory service and just eventually fail or timeout.
An yet more resilient way to accomplish this would be to look up the account SID and check whether the EqualPrefixSid can compare it with the machine. If this is the case, then you know the current account is local to the machine (i.e. not in a domain). This does not involve crossing the network and waiting for a timeout, so it's a more direct approach. Interestingly, it also implies that if the machine name is the same as the user domain, Windows would have to assume that the domain you want to logon on to is the local machine and it should therefore be almost impossible to logon to the actual domain if the machine name really is the same as the domain.

How computer name property is identified in LDAP? (active directory)

Using .net, I'm trying to pull info from this AD field: Computer Name(pre-Windows 2000). However, I don't know what the property identifier for it is.
For instance, if you want to look for the city property, you use "l". I'm wondering what the corresponding identifier is for computer name.
dSearch.PropertiesToLoad.Add("l"); //load city property
dSearch.PropertiesToLoad.Add("?"); //what is computer name?
Does anyone know what to use here? Help would be much appreciated.
The AD ldap attribute for the pre-Windows 2000 computer name is "sAMAccountName". I verified it myself on AD by creating a bogus computer account, giving it a unique pre-win 2000 name, and then checking the AD attributes using LDAP Admin.
In our environment both of these return the computer name but I can't tell which is tied to Computer Name(pre-Windows 2000).
dSearch.PropertiesToLoad.Add("cn");
dSearch.PropertiesToLoad.Add("name");
Turns out the identifier was "employeeID".

How to get "primary" user of a remote computer

I need to know how to get the name and domain of the primary user of a computer, remotely. I define the primary user preferably as the user logged on most times, or longest time over a period. Alternatively, if this is impossible, as the user currently/last logged on.
Currently, i scan an Active Directoy for all computer objects in an OU. I then loop though them, and try to get the name of the user using WMI.
I look in Win32_ComputerSystem to see if UserName returns a value. If this is not the case, i look in Win32_LogonSession and get the username for all LogonTypes that equal 2 or 10. If this returns none, or multiple values, i discard the result and look in Win32_Process for all non-system processes and define the primary user as the user with most processes running.
There are several problems with my approach:
Win32_ComputerSystem - UserName is often null.
Win32_LogonSession often return multiple or no values. There can be only 1 primary user.
Looking in Win32_Process is kinda ridiculous, since this will only return me the user with most processes, most likely not the primary user.
If no user is currently logged on, looking in Win32_Process returns no value and none of the 3 steps might return a value.
My 3 approaches might get me the current user. Does anyone know of a way to get the primary user? Or at least a better way to get the current. Not necessarily using WMI.
Thanks
If you have administrator privileges on the remote computer and sharing access
you can use Computer Management and select to
connect to other computer and see what users and groups are on that computer.
Or you can use TS Remote Administration or Remote Desktop if the remote computer has that capability.
Use psexec.exe (www.sysinternals.com) to run commands on a remote pc:
psexec \\pc1 net user | find /i "Steve"
psexec \\pc1 c:\tool\psloggedon | find /i "Steve"
1) Find if John Black has an account on PC1.
2) Find if he is currently logged on.
Use psloggedon.exe that uis is another SysInternals tool.
Check this also: http://www.wisesoft.co.uk/scripts/vbscript_display_username_of_user_on_a_remote_computer.aspx
Also if you want to find the User Name of the currently logged user on a remote computer using the remote computer IP then Go to the command line an type nbtstat -A <IP of remote computer> This will return all of the NetBIOS names registered on the computer, one of which is the username.

Categories