none
System.Security.AccessControl - Printers RRS feed

  • Question

  • Does anyone know how to to use System.Security.AccessControl libraries to get/create a security descriptor for a printer in C#?  I can see there is a resource type for printer but I can't seem to find any examples.  I'm trying to use the AddPrinter API and specify a securitydescriptor so that when I create a printer Everyone doesn't have print rights.
    • Moved by Bob Shen Wednesday, November 7, 2012 5:46 AM (From:Visual C# General)
    Monday, November 5, 2012 4:50 PM

Answers

  • Hi Jim,

    It's probably best not to worry about manipulating ACLs, ACEs, etc.  Use SDDL to define who has access and get the security descriptor via ConvertStringSecurityDescriptorToSecurityDescriptor.

    You can define it in your C# code.

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, uint StringSDRevision, out IntPtr SecurityDescriptor, out uint SecurityDescriptorSize);
    const uint SDDL_REVISION_1 = 1;
    // Give Authenticated Users access GENERIC ALL access to object
    String sSecurityDescriptor = "D:(A;;GA;;;AU)";
    IntPtr lpSecurityDescriptor;
    uint   SecurityDescriptorSize;
    if (!ConvertStringSecurityDescriptorToSecurityDescriptor(sSecurityDescriptor, SDDL_REVISION_1, out lpSecurityDescriptor, out SecurityDescriptorSize))
    {
         // Error
    }

     lpSecurityDescriptor can then be passed as the security descriptor in PRINTER_INFO_2 when you call AddPrinter.  The list of well known SIDs can be found here - http://msdn.microsoft.com/en-us/library/windows/desktop/aa379602(v=vs.85).aspx.  If you need to pass in a specific user account you'll need to use their SID string (S-xxxx).


    Carlos Lopez - Microsoft Escalation Engineer

    • Marked as answer by JimBoutit1 Friday, November 9, 2012 4:14 PM
    Wednesday, November 7, 2012 7:39 PM

All replies

  • I think you post a question here too:

    http://dotnetforum.net/topic/61700-systemsecurityaccesscontrol-printers/

    1. I bet you need a print server to control the security. Seriouly a printer connect to USB port can't do much.

    2. You should set this in group policy then writing a program to do that.

    chanmm


    chanmm

    Tuesday, November 6, 2012 3:16 AM
  • Are you seriously an MVP?

    I was able to use this class to get a little farther. 

    http://archive.msdn.microsoft.com/NativeObjectSecurity/Wiki/Print.aspx?title=Home&version=5&action=Print

    Now I can read/set the dacl; but I can't figure out if I can use the .Net objects to pass something to the unmanaged windows api.

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd183343(v=vs.85).aspx
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa379561(v=vs.85).aspx

    GeneralSecuritygs = newGeneralSecurity(false, ResourceType.Printer, "Pxx-100", AccessControlSections.Access);

    AuthorizationRuleCollectionrules = gs.GetAccessRules(true, true, Type.GetType("System.Security.Principal.NTAccount"));

    foreach(AuthorizationRuleace inrules)

                {

    Console.WriteLine("User{0}:", ace.IdentityReference.ToString());

               }

    NTAccountuser = newNTAccount("testdomain", "testuser");

    SecurityIdentifieruserSI = (SecurityIdentifier)user.Translate(typeof(SecurityIdentifier));

    GeneralAccessRulenace = newGeneralAccessRule(userSI, 131080, AccessControlType.Allow);

                gs.AddAccessRule(nace);

                gs.Persist(

    "Pxx-100");

    Tuesday, November 6, 2012 1:40 PM
  • Hi Jim,

    It's probably best not to worry about manipulating ACLs, ACEs, etc.  Use SDDL to define who has access and get the security descriptor via ConvertStringSecurityDescriptorToSecurityDescriptor.

    You can define it in your C# code.

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, uint StringSDRevision, out IntPtr SecurityDescriptor, out uint SecurityDescriptorSize);
    const uint SDDL_REVISION_1 = 1;
    // Give Authenticated Users access GENERIC ALL access to object
    String sSecurityDescriptor = "D:(A;;GA;;;AU)";
    IntPtr lpSecurityDescriptor;
    uint   SecurityDescriptorSize;
    if (!ConvertStringSecurityDescriptorToSecurityDescriptor(sSecurityDescriptor, SDDL_REVISION_1, out lpSecurityDescriptor, out SecurityDescriptorSize))
    {
         // Error
    }

     lpSecurityDescriptor can then be passed as the security descriptor in PRINTER_INFO_2 when you call AddPrinter.  The list of well known SIDs can be found here - http://msdn.microsoft.com/en-us/library/windows/desktop/aa379602(v=vs.85).aspx.  If you need to pass in a specific user account you'll need to use their SID string (S-xxxx).


    Carlos Lopez - Microsoft Escalation Engineer

    • Marked as answer by JimBoutit1 Friday, November 9, 2012 4:14 PM
    Wednesday, November 7, 2012 7:39 PM
  • Thanks Carlos - That helped out a lot.
    Friday, November 9, 2012 4:15 PM