I need to find a way to programmatically grant permissions on a ServerContainer of a default site in Active Directory.
Manually it's simple to do via the "Active Directory Sites and Services":
And then from the properties one needs to go to here to grant required permissions:
I have tried to do it via PowerShell, I managed to find the ServersContainer but I cannot find a way to set its permissions. I have browsed lots of stuff on Google but I cannot find a solution.
Anybody has got an idea how to approach it?
Sites are ADObjects living in CN=Configuration, so if you use Get-ADObject you can then use Get-ACL on that object in the AD PS drive. Which you can then use the methods on that object or the Set-ACL cmdlet to alter.
$params = #{
Filter = 'ObjectClass -eq "site" -and name -eq "Default-First-Site-Name"'
SearchBase = 'CN=Configuration,DC=contoso,DC=com'
}
$SiteDN = (Get-ADObject #params).DistinguishedName
$SiteACL = Get-ACL "AD:\$($SiteDN)"
Related
I am connecting to Exchange on 365 using EWS and using the GetUserAvailability method on the ExchangeService object to retrieve a collection of calendar items for a number of users (no more that 30).
My user that I am using to connect to EWS has impersonation rights and everything is working with the exception of one thing.
When I loop through the AttendeesAvailability collection, and then through each CalendarEvent within its CalendarEvents collection, I am able to see the Details object and access things like the Subject, Location, IsPrivate, etc...
The problem I have, is that the Details.StoreId is always null.
I have two 365 Exchange environments, our and a client's. When I try and access the StoreId on ours, it works absolutely fine and has the unique ID as expected. When I run the same come on the client's instance, it is null; but all the other properties are populated for the Details object.
This lead me to believe that it was a permissions issue for the service user within Exchange. So, I have slowly raised the permissions levels, hoping to hit the sweet spot, but nothing. The user is now an Exchange Admin (which I believe should have blanket access to anything and everything within the Exchange environment - including calendar items for each person's mailbox). Still not joy.
So, is it a configuration issue with the Exchange setup?
It is worth noting that all the other functionality that my application has, works perfect. It is just this ID that I am missing.
I am at a loss on this one. If it wasn't for the fact that I have shaved my head due to the lock down, I would be pulling my hair out right about now.
Any help or suggestions would be greatly appreciated.
Cheers
UPDATE 1
So, I have found that if I perform the same process on the service account that I am authenticating with, I get the StoreId back. This account was created after the migration from on-prem to O365 (which may mean nothing). I am in the process of getting access to another account that has been created since the migration to see if it works for that one as well. This will help me identify if the issue is likely to be with the migrated mailboxes only or with any mailbox apart from the account used to authenticate. I will update soon...
UPDATE 2
I have tested against a new account. I set the default permissions on the new account's calendar to Reviewer (even tried Owner and Anonymous just for a sanity check). When I authenticate using the service account, I don't get the StoreId. When I authenticate using the new test account, I do get the StoreId.
This leads me to believe that it is a permissions issue. It's now a case of finding out what that magic permissions is. It still eludes me as to why it is only the ID that I don't get back.
Still open to any suggestions.
UPDATE 3
It looks like it may be something different between build versions on EWS.
The version that works is reporting a server version of 15.20.3021.030.
The version that does not work is version 15.20.3045.019.
So, it's been a while, but Microsoft have now fixed the issue and the existing code is now working fine.
I can also confirm that this work when using OAuth as well.
The problem is probably related to not having sufficient rights from the account you use for the Exchange Service authentication to the target account.
Use the command below to give rights and try again.
Add-MailboxFolderPermission -Identity User#domain.com:\Calendar -User serviceceaccount#domain.com -AccessRights Reviewer
This is a very annoying issue, I have opened an incident with MS in the past, but got the disappointing answer that this won't change soon.
Below is the PS code to set rights to all users, rooms, resources, regardless of culture (language) and name of the calendar folder.
Param(
[parameter(position=0,Mandatory=$true)][string] $serviceaccount,
[parameter(position=1,Mandatory=$true)][string] $mailboxtype
)
$acl = "Reviewer"
if ($mailboxtype -eq "All") {
$mailboxes = Get-Mailbox | Where {$_.RecipientTypeDetails -eq "UserMailbox" -or $_.RecipientTypeDetails -eq "RoomMailbox" -or $_.RecipientTypeDetails -eq "EquipmentMailbox"} | Select -expand PrimarySmtpAddress | Select -expand Address | Where {$_ -NotLike "Administrator#*"}
}
elseif ($mailboxtype -eq "Users") {
$mailboxes = Get-Mailbox | Where {$_.RecipientTypeDetails -eq "UserMailbox"} | Select -expand PrimarySmtpAddress | Select -expand Address | Where {$_ -NotLike "Administrator#*"}
}
elseif ($mailboxtype -eq "Resources") {
$mailboxes = Get-Mailbox | Where {$_.RecipientTypeDetails -eq "RoomMailbox" -or $_.RecipientTypeDetails -eq "EquipmentMailbox"} | Select -expand PrimarySmtpAddress | Select -expand Address
}
else {
"Error specifying target mailbox type. Choose one of: 'All', 'Users' or 'Resources'.`n
'All' - UserMailbox, RoomMailbox, EquipmentMailbox.`n
'Users' - UserMailbox.`n
'Resources' - RoomMailbox, EquipmentMailbox."
}
foreach ($mbx in $mailboxes)
{
$calName = Get-MailboxFolderStatistics -Identity $mbx -FolderScope Calendar | Where-Object { $_.FolderType -eq 'Calendar'} | Select-Object Name, FolderId #-ErrorAction Stop
#echo "${mbx}:\$($calName.Name)"
Add-MailboxFolderPermission -Identity ${mbx}:\$($calName.Name) -User $serviceaccount -AccessRights $acl | Select-Object Identity, FolderName, User, AccessRights
}
Save as PS script, call with two params: serviceaccount & mailboxtype
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
I have a folder that I want to protect its contents,
I'm denying full control to it by this code:
void changeFolderPermission(string folder, FileSystemRights rights, AccessControlType type)
{
DirectoryInfo myDirInfo = new DirectoryInfo(folder);
DirectorySecurity myDirSecurity = myDirInfo.GetAccessControl();
string user = System.Environment.UserName;
myDirSecurity.ResetAccessRule(new FileSystemAccessRule(user, rights, type));
myDirInfo.SetAccessControl(myDirSecurity);
}
I'm using it like this:
changeFolderPermission(FolderName, FileSystemRights.FullControl, AccessControlType.Deny);
It's working fine, I mean, when i try to open the folder, it won't let me.
Problem is, I could easily remove that permission by right clicking on the folder,
going to security, look for that special permission and just deleting it ..
is there a way to prevent someone from doing this ?
I want the folder to be fully secured.
Now I know that there's something like this:
hangeFolderPermission(FolderName, FileSystemRights.ChangePermissions, AccessControlType.Deny);
but I'm still being able to change the permissions.
any help would be appreciated .. thanx alot in advance .. :)
You can not prevent a user with admin rights from accessing a folder or file.
If the user does not have admin rights, then set the permissions (via an admin account) to deny the user access. Properly configured permissions will prevent the non-admin user from accessing the folder/file.
You never said anything in your original post about sending the folder to other people. Presumably this sending mechanism involves email, ftp, etc to ANOTHER COMPUTER. Assumption #2 is that your C# program is what will be reading the contents of said folder.
In this case its simple, create a password-protected zip file of your directory and send that. Then embed the password within your C# code and open the zip file and read its contents.
There are several really good zip manipulation libraries out there such as dotnetzip and #ziplib
Our ASP.NET C# web application uploads various files like jpgs, pngs, docx, txt, etc to a folder called ClientBin.
Everything works fine on our Visual Studio 2010 .NET test server that comes along with the Visual Studio 2010 .NET IDE.
However, if we deploy the application to an IIS7 server, we have to give the web user of our application permission to upload file.
We basically log on to our Server with IIS7, and then manually modify Security properties of the folder called ClientBin that should ultimately contain the content like jpgs, pngs, docx, txt, etc.
---Manual approach to allow web user to upload successfully work---------------------------
Right-click the projectfolder\ClientBin folder in Explorer, choose "Properties" and select the Security tab. Click "Add" to add the appropriate user or group. Highlight the ASP.NET account, and check the boxes for the desired access.
---Manual approach to make uploading successfully work---------------------------
--Programmatic approach which still gives web user an Exception error when trying to upload------------------
String DirectoryPath = System.IO.Path.Combine(Server.MapPath("~/ClientBin/"));
DirectorySecurity specificDirectorySecurity = Directory.GetAccessControl(DirectoryPath);
specificDirectorySecurity.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.Modify, AccessControlType.Allow));
specificDirectorySecurity.AddAccessRule(new FileSystemAccessRule("Administrators", FileSystemRights.Modify, AccessControlType.Allow));
specificDirectorySecurity.AddAccessRule(new FileSystemAccessRule("SYSTEM", FileSystemRights.Modify, AccessControlType.Allow));
Directory.SetAccessControl(DirectoryPath, specificDirectorySecurity);
--Programmatic approach which still gives web user an Exception error when trying to upload------------------
Another online post suggested I solve the issue by entering the following in web.config:
----XML configuration that might solve problem with programmatic approach--------
identity impersonate="true" userName="ComputerName\Administrator"
password="don"
----XML configuration that might solve problem with programmatic approach--------
However, I'm worried about security issue if I make identity impersonate to true.
What is the most secure and most automated ( which might mean a programmatic solution) way of doing this?
Thanks,
newemployee
Typically the application is given rights to the directory and the application manages the users access to the upload folder.
All:
Even though I failed to figure out how C# can modify permissions for upload folder.
It seems that Microsoft Windows PowerShell can programmatically modifies permissions for upload folder.
Here is a snippet of the code that programmatically modifies permissions for upload folder:
$computerHostName = [System.Net.Dns]::GetHostName()
#These constants are used to set permissions
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [system.security.accesscontrol.PropagationFlags]::None
$colRights = [System.Security.AccessControl.FileSystemRights]"Modify"
$objType =[System.Security.AccessControl.AccessControlType]::Allow
#(MSDN Docs) The IIS_IUSRS Group has access to all the necessary file and system resources
# so that an account, when added to this group, can seamlessly act as an application pool identity.
# IIS_IUSRS group by default includes the web users that log on to the Perls Applications.
#If a web user needs to upload resources to the folder within the Perls Web Application that
# contains uploaded resource files then we need to ensure that the members of the
# IIS_IUSRS Group have permissions to add resource files to that particular Perls Web Application upload folder.
#This determines which user is the guest user for IIS. Windows Vista and 08 use the IIS_USRS group, Previous version use
#IUSR_[MachineName]
if ([environment]::osversion.Version.Major -eq 6) {
$webUser="IIS_IUSRS"
} else {
$webUser="IUSR_" + $computerHostName
}
$clientBinDirectoryPath = "D:\DeployedApplications\" + $umbrellaComponentName + "\" + $siteWebComponentName + "\" + "ClientBin"
$perlsPivotErrorDirectoryPath = "D:\DeployedApplications\" + $umbrellaComponentName + "\" + $siteWebComponentName + "\" + "PerlsPivotErrorDirectory"
$aclForClientBinDirectoryPath = Get-Acl $clientBinDirectoryPath
$accessRuleForClientBinDirectoryPath = New-Object System.Security.AccessControl.FileSystemAccessRule($webUser, $colRights, $inherit, $propagation, $objType)
$aclForClientBinDirectoryPath.AddAccessRule($accessRuleForClientBinDirectoryPath)
Set-Acl -aclobject $aclForClientBinDirectoryPath $clientBinDirectoryPath
$aclForPerlsPivotErrorDirectoryPath = Get-Acl $perlsPivotErrorDirectoryPath
$accessRuleForPerlsPivotErrorDirectoryPath = New-Object System.Security.AccessControl.FileSystemAccessRule($webUser, $colRights, $inherit, $propagation, $objType)
$aclForPerlsPivotErrorDirectoryPath.AddAccessRule($accessRuleForPerlsPivotErrorDirectoryPath)
Set-Acl -aclobject $aclForPerlsPivotErrorDirectoryPath $perlsPivotErrorDirectoryPath
Provided I have admin access, I need a way to manage (Create, modify, remove) local accounts in a remote machine from an ASP.NET client.
I'm clueless in how to approach this. Is WMI a possibility (System.Management namespace)?
Any pointers?
Give this a try:
DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://ComputerName" & ",computer", "AdminUN", "AdminPW");
DirectoryEntry user = directoryEntry.Children.Add("username", "user");
user.Invoke("SetPassword", new object[] { "password"});
ser.CommitChanges();
If you do need to go the Active Directory route, you can change the directoryEntry path string to something like this: LDAP://CN=ComputerName,DC=MySample,DC=com
I used System.DirectoryServices to get data from users in a n ActiveDirectory (LDAP).
I don't know if that's the kind of thing you're looking for.
Hope it helps.
You should be able to do this via DirectoryEntry.