add security groups to folder issue / System.Security.Principal.IdentityNotMappedException: - c#

I am struggling with strange issue and I wonder if some one can help me please.
At some point of my program I like to add security groups with appropriate permissions to folder. Steps look like that.
Create Folder
Create Domain Local Security Group
Create Global Security group
Add Global Group to local group
Add Domain Local security group to folder "\domain\dfs\folder"
I got below piece of code to do this from Microsoft page
public static void AddDirectorySecurity(string DirectoryName, string Group, FileSystemRights Rights, InheritanceFlags iFlag, PropagationFlags pFlag, AccessControlType ControlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(DirectoryName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(Group,Rights,iFlag,pFlag,ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity); //
}
procedure of adding looks like that:
path = #"\\domain\dfs\folder"
gRDL_RW = "RDL-group-RW"
AddDirectorySecurity(path, gRDL_RW, FileSystemRights.Modify, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow);
It is working fine in my test environment but when I like to run it in production environment I am getting error:
************** Exception Text **************
System.Security.Principal.IdentityNotMappedException: Some or all identity references could not be translated.
at System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess)
at System.Security.Principal.NTAccount.Translate(Type targetType)
at System.Security.AccessControl.CommonObjectSecurity.ModifyAccess(AccessControlModification modification, AccessRule rule, Boolean& modified)
at System.Security.AccessControl.CommonObjectSecurity.AddAccessRule(AccessRule rule)
at Program_dev_1.Form1.button1_Click(Object sender, EventArgs e) in c:\Users\?????????\Documents\Visual Studio 2012\Projects\brite_dev_1\brite_dev_1\Form1.cs:line 191
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Is it a problem with "Admin rights"? I have God like permissions in production environment.
So what is going on?
I have feeling that for some reason all those user friendly names such as "FileSystemRights.Modify" can not be translated. I check locale on test and prod environment and both are this same.
Is it possible to use raw numbers that are hiding behind those user friendly names?
Maybe there is a other way to add security groups to folder? All I really like to have is a working solution.

Application was crushing when groups were tried to be add to folder because newly created groups were not know to all domain controllers immediately. I had to create procedure that check if newly create groups have been synchronized across whole estate before progressing with the rest of the code. It is not possible or I could not find a method of specifying domain controller used when adding groups to folder permission.

Related

App crashes when selecting an item in a DataGridView combobox cell if the app is open on an external monitor

I have an app that I wrote a few years ago using Winforms and C# and recently I encountered a weird bug. When selecting an item from a datagridview combobox cell the app is crashing with the error "System.OutOfMemoryException: To many items in combobox" and the stack trace below:
at System.Windows.Forms.ComboBox.NativeAdd(Object item)
at System.Windows.Forms.ComboBox.OnHandleCreated(EventArgs e)
at System.Windows.Forms.Control.WmCreate(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ComboBox.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
I don't have a desktop computer available, only laptops, and this seems to happen only if the app is open on an external monitor becuase on a built in screen it works fine.
I tried to mark my external monitor as the primary screen so the app will open on it by default because I thought it might have something to do with it but the problem remains the same.
I also tried to add a dummy combobox column to less complex form controller then the one where the problem occurs and the same thing happend.
Update:
I have made some progress. Apparently the bug occours when the scale setting of the external monitor is different than the scale setting of the built in monitor. It will be grate if anyone can explain why this happens and how can I fix it in my app's code.
Sometimes during debugging the error apears immedaitly in the app's main entry point, in those cases I used Visual Studio winforms designer to create lists of items in advance in the combobox columns. In other cases the comboxcells has a data table as a source and the datagridview has it's own data table as a source. so after selecting an item I sync them manually with the following function and the bug happens after calling DataGridView.EndEdit():
private void DGVAndDataSourceSync(DataGridViewComboBoxEditingControl senderCB, int dgvDtColumn)
{
try
{
DataRow drCBItemSource = ((DataTable)senderCB.DataSource).Rows[senderCB.SelectedIndex];
((DataRowView)senderCB.EditingControlDataGridView.CurrentRow.DataBoundItem).Row[dgvDtColumn] = drCBItemSource[DT_KEY_FIELD_COLUMN];
_ = senderCB.EditingControlDataGridView.EndEdit();
}
catch (Exception ex) { throw ex; }
}
Second Update
I continued experimenting with my app and anouther demo one I made with nothing but a datagridview containg only a combobox column. I discovered that when I go to the following lines in my app.manifest:
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />>
and comment out the line with the supportedOS tag the bug is gone. I don't understand why this is happing and it will be grate if someone knows to explain it
this is nothing to do with out of memory
here is the code that throws throws this error
int insertIndex = unchecked( (int) (long)SendMessage(NativeMethods.LB_ADDSTRING, 0, GetItemText(item)));
...
if (insertIndex == NativeMethods.LB_ERR) {
// On some platforms (e.g. Win98), the ListBox control
// appears to return LB_ERR if there are a large number (>32000)
// of items. It doesn't appear to set error codes appropriately,
// so we'll have to assume that LB_ERR corresponds to item
// overflow.
//
throw new OutOfMemoryException(SR.GetString(SR.ListBoxItemOverflow));
}
An article I posted in a comment says that this is caused by a item returning null when tostring is called during the call to GetItemText
https://www.csharp411.com/combobox-exception-too-many-items-in-the-combo-box/

Using the activeX Control "AcroPDF.dll" my application works fine, but crashes on startup if adobe acrobat is not installed

I have an application that adds text to PDF files, and I have a axAcroPDF1 preview panel that borrows acrobat to show the status of the PDF file, but it is not necessary for the function of the program, so I'd like to have the program still start even when acrobat is not installed albeit more limited functionality, and then the user just wont have a preview panel which is fine. How can I do this?
The only thing I could think to try was adding a catch/exception when this.axAcroPDF1 is initializing when the program starts, which allows me to put a message popup that Adobe reader is required, but the program still crashes after that, so I would like to have the program start regardless, and just not call on that when adobe is not installed, or any other suggestions you guys have so that this application could still function somewhat with or without adobe.
I know how to check if adobe is installed, but I don't know how to apply the result to my program.
The catch exception on initializing gives the following error (I'm a noob so probably not giving good information here):
System.Runtime.InteropServices.COMException (0x80040154): Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
at System.Windows.Forms.UnsafeNativeMethods.CoCreateInstance(Guid& clsid, Object punkOuter, Int32 context, Guid& iid)
at System.Windows.Forms.AxHost.CreateWithLicense(String license, Guid clsid)
at System.Windows.Forms.AxHost.CreateInstanceCore(Guid clsid)
at System.Windows.Forms.AxHost.CreateInstance()
at System.Windows.Forms.AxHost.GetOcxCreate()
at System.Windows.Forms.AxHost.TransitionUpTo(Int32 state)
at System.Windows.Forms.AxHost.CreateHandle()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Solution: I decided to use Inno Installer since I have some DLL files, and in the installer script, I do an adobe check, and if they dont have adobe or the right version I prompt the user to download reader. Here is the basic code to check adobe:
[Code]
procedure ExitProcess(exitCode:integer);
external 'ExitProcess#kernel32.dll stdcall';
function GetAcrobatReaderVersion(): String;
var
sVersion: String;
begin
sVersion := '';
RegQueryStringValue( HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRd32.exe',
'', sVersion );
GetVersionNumbersString( sVersion , sVersion );
Result := sVersion;
end;
function GetAcrobatVersion(): String;
var
sVersion2: String;
begin
sVersion2 := '';
RegQueryStringValue( HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe',
'', sVersion2 );
GetVersionNumbersString( sVersion2 , sVersion2 );
Result := sVersion2;
end;
function NextButtonClick(CurPage: Integer): Boolean;
begin
// by default go to next page
Result := true;
if CurPage = wpWelcome then
begin
if Length( GetAcrobatReaderVersion + GetAcrobatVersion() ) = 0 then
begin
MsgBox( 'adobe not detected', mbInformation, MB_OK );
Result := false;
ExitProcess(0);//adobe isn't installed, so exit installer
end
else
//MsgBox( 'Acrobat reader installed is version ' + GetAcrobatReaderVersion() ,
MsgBox( 'adobe detected', mbInformation, MB_OK );
end;
end;

Programmatically adding Write permissions to files in WPF

In my WPF MVVM application,I have a XML file to modify.
It is successfully working In Visual Studio.
But It showing error, while running the installed application.
How can i set the Permissions Through code..
me used this code ,
// current security settings.
FileSecurity fSecurity = File.GetAccessControl(FilePath);
// Add the FileSystemAccessRule to the security settings.
string rr = WindowsIdentity.GetCurrent().Name;
fSecurity.AddAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().Name,
FileSystemRights.FullControl, AccessControlType.Allow));
// Set the new access settings.
File.SetAccessControl(FilePath, fSecurity);
Still cant solve the Problem...,
Thanks in advance..
see the exception...
System.UnauthorizedAccessException: Attempted to perform an
unauthorized operation. at
System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type,
String name, SafeHandle handle, SecurityInfos securityInformation,
SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl,
GenericAcl dacl) at
System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, SafeHandle handle, AccessControlSections includeSections, Object
exceptionContext) at
System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, AccessControlSections includeSections) at
System.Security.AccessControl.FileSystemSecurity.Persist(String
fullPath) at System.IO.File.SetAccessControl(String path,
FileSecurity fileSecurity)
To set permissions mostly it requires power user rights(assuming your are running windows 7).
To verify above, launch the Visual studio as "Run as Administrator" and debug the your code.
What is exact exception message?
Here is working example: It sets full permissions for user group EveryOne
private static void WriteAcl ( string filename )
{
//Set security for EveryOne Group
SecurityIdentifier sid =new SecurityIdentifier(WellKnownSidType.WorldSid, null);
IdentityReference userIdentity =sid.Translate (typeof(NTAccount));
var AccessRule_AllowEveryOne = new FileSystemAccessRule ( userIdentity, FileSystemRights.FullControl, AccessControlType.Allow );
var securityDescriptor = new FileSecurity ();
securityDescriptor.SetAccessRule ( AccessRule_AllowEveryOne );
File.SetAccessControl ( filename, securityDescriptor );
}
This code works only if User Account Settings are set to Never notify. Looks its turned on at your computer?
A workaround is to launch your application as power user using Application Manifest.
http://msdn.microsoft.com/en-us/library/bb756929.aspx

C# Storing Folder Permissions

I'm having a little trouble with storing Folder Permissions. I was able to find a some documentation on writing them and reading them. What I'm trying to do is read the permissions on a folder for a specific user > Store it > change the permissions > after installer program finishes, change the permissions back.
I have all of it down (only due to code from many others) EXCEPT how to store the original folder permissions and set it back. I'll gladly read any material that you suggest, we receive several fatal errors with the software and this is one step to resolving many of them. All help is welcome and appreciated.
Below is an example of how I'm setting the permissions. Yes I know that I have everyone, but it is just for testing right now
public void setPermDir()
{
try
{
string DirectoryName = "C:\\Temp1\\";
Console.WriteLine("Adding access control entry for " + DirectoryName);
// Add the access control entry to the directory.
AddDirectorySecurity(DirectoryName, #"Everyone", FileSystemRights.FullControl, AccessControlType.Allow);
Console.WriteLine("Done.");
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
// Adds an ACL entry on the specified directory for the specified account.
public static void AddDirectorySecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(FileName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(Account,
Rights,
ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
If you return the DirectorySecurity dSecurity from AddDirectorySecurity then you could just call Directory.SetAccessControl(directoryName, dSecurity); once you were done with the modified access rules.
Update
If just SetAccessControl doesn't work the next step might be to explicitly remove the permissions you have granted using FileSystemSecurity.RemoveAccessRule.
Just keep a reference to the FileSystemAccessRule you create:
FileSystemAccessRule toRemoveWhenDone = new FileSystemAccessRule(Account, Rights, ControlType);

Set write permissions for all users for my program folder

I have build a program in Visual Studio. The program creates a logfile and writes into it while the program is running. Therefore I constructed an installer (setup-project), that should set write permissions for my program-folder regardless which user works with the program.
currently it looks like this:
// ...
}
InitializeComponent();
string folder = Directory.GetCurrentDirectory();
DirectorySecurity ds = Directory.GetAccessControl(folder);
ds.AddAccessRule(new FileSystemAccessRule("Everyone", //Everyone is important
//because rights for all users!
FileSystemRights.Read | FileSystemRights.Write, AccessControlType.Allow));
}
// ...
In the last two rows I get a System.SystemException: “Die Vertrauensstellung zwischen der primären Domäne und der vertrauenswürdigen Domäne konnte nicht hergestellt werden.“
[Translation: "The trust relationship between the primary domain and the trusted domain could not be established."]
The stacktrace reads like this:
bei System.Security.Principal.NTAccount.TranslateToSids(IdentityReferenceCollection sourceAccounts, Boolean& someFailed)
bei System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean& someFailed)
bei System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess)
bei System.Security.Principal.NTAccount.Translate(Type targetType)
bei System.Security.AccessControl.CommonObjectSecurity.ModifyAccess(AccessControlModification modification, AccessRule rule, Boolean& modified)
bei System.Security.AccessControl.CommonObjectSecurity.AddAccessRule(AccessRule rule)
bei System.Security.AccessControl.FileSystemSecurity.AddAccessRule(FileSystemAccessRule rule)
Have you an idea what I can do?
thanks
Perhaps the best answer isn't what you've asked for. There's a good reason for not writing to the program files directory. Log data in particular is transient and shouldn't be written here.
It's a much better idea to write log data to the directory specified by the TEMP environment variable. If you do this you'll save your users a few troubles and prevent them cursing your software in the future. Please check out this answer which covers the same topic:
Allow access permission to write in Program Files of Windows 7
Aren't you missing the statement where you actually set the access control back to the directory?
Directory.SetAccessControl(Directory.GetCurrentDirectory(), ds);
This previously asked question should point you in the right direction. Basically, you do NOT want any user writing to the Program Files folder. UAC, security and other measures are there to try and prevent this as much as possible.
Essentially, if you want a single file which will be written to by all users, you will want it in the ProgramData folder, accessible through the %ALLUSERSPROFILE%, rather than the individual users' temporary folder, which is definitely what you want to do with a log file. Remember that the temporary folder's content should be considered volatile, and could be deleted at any time, such as by the Disk Cleanup Wizard.

Categories