472,342 Members | 1,321 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,342 software developers and data experts.

LSA functions

Hi!

Has anyone been able to use LSA functions to grant or remove privileges
to/from users? I'm trying to find a way to programmatically set the "Deny
logon through Terminal Services" privilege for certain users. If someone has
a small example of how to use these functions from C# it would be very
helpful.

Thanks in advance

Morten
Nov 16 '05 #1
3 10447

"Morten" <mo**************@hotmail.com> wrote in message
news:el*************@tk2msftngp13.phx.gbl...
Hi!

Has anyone been able to use LSA functions to grant or remove privileges
to/from users? I'm trying to find a way to programmatically set the "Deny
logon through Terminal Services" privilege for certain users. If someone
has a small example of how to use these functions from C# it would be very
helpful.

Thanks in advance

Morten


Here a simple class that should do the job (use at own risk). Note that IMO,
this kind of PInvoke stuff could better be done using MC++ (C++/CLI) or
using System.Management (WMI) and RSOP.
namespace Willys.LsaSecurity
{
using System.Runtime.InteropServices;
using System.Security;
using System.Management;
using System.Runtime.CompilerServices;
using System.ComponentModel;

using LSA_HANDLE = IntPtr;

[StructLayout(LayoutKind.Sequential)]
struct LSA_OBJECT_ATTRIBUTES {
internal int Length;
internal IntPtr RootDirectory;
internal IntPtr ObjectName;
internal int Attributes;
internal IntPtr SecurityDescriptor;
internal IntPtr SecurityQualityOfService;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
struct LSA_UNICODE_STRING
{
internal ushort Length;
internal ushort MaximumLength;
[MarshalAs(UnmanagedType.LPWStr)]
internal string Buffer;
}
sealed class Win32Sec
{
[DllImport("advapi32", CharSet=CharSet.Unicode, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
internal static extern uint LsaOpenPolicy(
LSA_UNICODE_STRING[] SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
int AccessMask,
out IntPtr PolicyHandle
);

[DllImport("advapi32", CharSet=CharSet.Unicode, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
internal static extern uint LsaAddAccountRights(
LSA_HANDLE PolicyHandle,
IntPtr pSID,
LSA_UNICODE_STRING[] UserRights,
int CountOfRights
);

[DllImport("advapi32", CharSet=CharSet.Unicode, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
internal static extern int LsaLookupNames2(
LSA_HANDLE PolicyHandle,
uint Flags,
uint Count,
LSA_UNICODE_STRING[] Names,
ref IntPtr ReferencedDomains,
ref IntPtr Sids
);

[DllImport("advapi32")]
internal static extern int LsaNtStatusToWinError(int NTSTATUS);

[DllImport("advapi32")]
internal static extern int LsaClose(IntPtr PolicyHandle);

[DllImport("advapi32")]
internal static extern int LsaFreeMemory(IntPtr Buffer);

}
public sealed class LsaWrapper : IDisposable
{
[StructLayout(LayoutKind.Sequential)]
struct LSA_TRUST_INFORMATION {
internal LSA_UNICODE_STRING Name;
internal IntPtr Sid;
}
[StructLayout(LayoutKind.Sequential)]
struct LSA_TRANSLATED_SID2 {
internal SidNameUse Use;
internal IntPtr Sid;
internal int DomainIndex;
uint Flags;
}

[StructLayout(LayoutKind.Sequential)]
struct LSA_REFERENCED_DOMAIN_LIST {
internal uint Entries;
internal LSA_TRUST_INFORMATION Domains;
}

enum SidNameUse : int {
User = 1,
Group = 2,
Domain = 3,
Alias = 4,
KnownGroup = 5,
DeletedAccount = 6,
Invalid = 7,
Unknown = 8,
Computer = 9
}

enum Access : int {
POLICY_READ = 0x20006,
POLICY_ALL_ACCESS = 0x00F0FFF,
POLICY_EXECUTE = 0X20801,
POLICY_WRITE = 0X207F8
}
const uint STATUS_ACCESS_DENIED = 0xc0000022;
const uint STATUS_INSUFFICIENT_RESOURCES = 0xc000009a;
const uint STATUS_NO_MEMORY = 0xc0000017;

IntPtr lsaHandle;

public LsaWrapper(): this (null)
{}
// // local system if systemName is null
public LsaWrapper(string systemName)
{
LSA_OBJECT_ATTRIBUTES lsaAttr;
lsaAttr.RootDirectory = IntPtr.Zero;
lsaAttr.ObjectName = IntPtr.Zero;
lsaAttr.Attributes = 0;
lsaAttr.SecurityDescriptor = IntPtr.Zero;
lsaAttr.SecurityQualityOfService = IntPtr.Zero;
lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES));
lsaHandle = IntPtr.Zero;
LSA_UNICODE_STRING[] system = null;
if (systemName != null)
{
system = new LSA_UNICODE_STRING[1];
system[0] = InitLsaString(systemName);
}

uint ret = Win32Sec.LsaOpenPolicy(system, ref lsaAttr,
(int)Access.POLICY_ALL_ACCESS, out lsaHandle);
if (ret == 0)
return;
if (ret == STATUS_ACCESS_DENIED)
{
throw new UnauthorizedAccessException();
}
if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
{
throw new OutOfMemoryException();
}
throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int )ret));
}

public void AddPrivileges(string account, string privilege)
{
IntPtr pSid = GetSIDInformation(account);
LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
privileges[0] = InitLsaString(privilege);
uint ret = Win32Sec.LsaAddAccountRights(lsaHandle, pSid, privileges, 1);
if (ret == 0)
return;
if (ret == STATUS_ACCESS_DENIED)
{
throw new UnauthorizedAccessException();
}
if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
{
throw new OutOfMemoryException();
}
throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int )ret));
}
public void Dispose() {
if (lsaHandle != IntPtr.Zero)
{
Win32Sec.LsaClose(lsaHandle);
lsaHandle = IntPtr.Zero;
}
GC.SuppressFinalize(this);
}
~LsaWrapper()
{
Dispose();
}
// helper functions

IntPtr GetSIDInformation(string account)
{
LSA_UNICODE_STRING[] names = new LSA_UNICODE_STRING[1];
LSA_TRANSLATED_SID2 lts;
IntPtr tsids = IntPtr.Zero;
IntPtr tdom = IntPtr.Zero;
names[0] = InitLsaString(account);
lts.Sid = IntPtr.Zero;
Console.WriteLine("String account: {0}", names[0].Length);
int ret = Win32Sec.LsaLookupNames2(lsaHandle, 0, 1, names, ref tdom, ref
tsids);
if (ret != 0)
throw new Win32Exception(Win32Sec.LsaNtStatusToWinError(ret) );
lts = (LSA_TRANSLATED_SID2)Marshal.PtrToStructure(tsids,
typeof(LSA_TRANSLATED_SID2));
Win32Sec.LsaFreeMemory(tsids);
Win32Sec.LsaFreeMemory(tdom);
return lts.Sid;
}

static LSA_UNICODE_STRING InitLsaString(string s)
{
// Unicode strings max. 32KB
if (s.Length > 0x7ffe)
throw new ArgumentException("String too long");
LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING();
lus.Buffer = s;
lus.Length = (ushort)(s.Length * sizeof(char));
lus.MaximumLength = (ushort)(lus.Length + sizeof(char));
return lus;
}
}
}
// usage....

using (Willys.LsaSecurity.LsaWrapper lsa = new
Willys.LsaSecurity.LsaWrapper())
{
// add SeDenyRemoteInteractiveLogonRight will effectively deny TS access to
someAccount
lsa.AddPrivileges("someAccount",
"SeDenyRemoteInteractiveLogonRight");
}
Willy.
Nov 16 '05 #2
Hi Willy!

Thanks for your suggestion. I'm having a few problems using your code. I get
this error:

LSA.cs(218): sizeof can only be used in an unsafe context (consider using
System.Runtime.InteropServices.Marshal.SizeOf)

Any idea how that can be solved? Also, I've been looking for a way to use
WMI - preferably using a vb script - to do the same so if you have any idea
how this can be done I'd be greatful.

Best regards

Morten

"Willy Denoyette [MVP]" <wi*************@pandora.be> wrote in message
news:un**************@TK2MSFTNGP09.phx.gbl...

"Morten" <mo**************@hotmail.com> wrote in message
news:el*************@tk2msftngp13.phx.gbl...
Hi!

Has anyone been able to use LSA functions to grant or remove privileges
to/from users? I'm trying to find a way to programmatically set the "Deny
logon through Terminal Services" privilege for certain users. If someone
has a small example of how to use these functions from C# it would be
very helpful.

Thanks in advance

Morten


Here a simple class that should do the job (use at own risk). Note that
IMO, this kind of PInvoke stuff could better be done using MC++ (C++/CLI)
or using System.Management (WMI) and RSOP.
namespace Willys.LsaSecurity
{
using System.Runtime.InteropServices;
using System.Security;
using System.Management;
using System.Runtime.CompilerServices;
using System.ComponentModel;

using LSA_HANDLE = IntPtr;

[StructLayout(LayoutKind.Sequential)]
struct LSA_OBJECT_ATTRIBUTES {
internal int Length;
internal IntPtr RootDirectory;
internal IntPtr ObjectName;
internal int Attributes;
internal IntPtr SecurityDescriptor;
internal IntPtr SecurityQualityOfService;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
struct LSA_UNICODE_STRING
{
internal ushort Length;
internal ushort MaximumLength;
[MarshalAs(UnmanagedType.LPWStr)]
internal string Buffer;
}
sealed class Win32Sec
{
[DllImport("advapi32", CharSet=CharSet.Unicode, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
internal static extern uint LsaOpenPolicy(
LSA_UNICODE_STRING[] SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
int AccessMask,
out IntPtr PolicyHandle
);

[DllImport("advapi32", CharSet=CharSet.Unicode, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
internal static extern uint LsaAddAccountRights(
LSA_HANDLE PolicyHandle,
IntPtr pSID,
LSA_UNICODE_STRING[] UserRights,
int CountOfRights
);

[DllImport("advapi32", CharSet=CharSet.Unicode, SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
internal static extern int LsaLookupNames2(
LSA_HANDLE PolicyHandle,
uint Flags,
uint Count,
LSA_UNICODE_STRING[] Names,
ref IntPtr ReferencedDomains,
ref IntPtr Sids
);

[DllImport("advapi32")]
internal static extern int LsaNtStatusToWinError(int NTSTATUS);

[DllImport("advapi32")]
internal static extern int LsaClose(IntPtr PolicyHandle);

[DllImport("advapi32")]
internal static extern int LsaFreeMemory(IntPtr Buffer);

}
public sealed class LsaWrapper : IDisposable
{
[StructLayout(LayoutKind.Sequential)]
struct LSA_TRUST_INFORMATION {
internal LSA_UNICODE_STRING Name;
internal IntPtr Sid;
}
[StructLayout(LayoutKind.Sequential)]
struct LSA_TRANSLATED_SID2 {
internal SidNameUse Use;
internal IntPtr Sid;
internal int DomainIndex;
uint Flags;
}

[StructLayout(LayoutKind.Sequential)]
struct LSA_REFERENCED_DOMAIN_LIST {
internal uint Entries;
internal LSA_TRUST_INFORMATION Domains;
}

enum SidNameUse : int {
User = 1,
Group = 2,
Domain = 3,
Alias = 4,
KnownGroup = 5,
DeletedAccount = 6,
Invalid = 7,
Unknown = 8,
Computer = 9
}

enum Access : int {
POLICY_READ = 0x20006,
POLICY_ALL_ACCESS = 0x00F0FFF,
POLICY_EXECUTE = 0X20801,
POLICY_WRITE = 0X207F8
}
const uint STATUS_ACCESS_DENIED = 0xc0000022;
const uint STATUS_INSUFFICIENT_RESOURCES = 0xc000009a;
const uint STATUS_NO_MEMORY = 0xc0000017;

IntPtr lsaHandle;

public LsaWrapper(): this (null)
{}
// // local system if systemName is null
public LsaWrapper(string systemName)
{
LSA_OBJECT_ATTRIBUTES lsaAttr;
lsaAttr.RootDirectory = IntPtr.Zero;
lsaAttr.ObjectName = IntPtr.Zero;
lsaAttr.Attributes = 0;
lsaAttr.SecurityDescriptor = IntPtr.Zero;
lsaAttr.SecurityQualityOfService = IntPtr.Zero;
lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES));
lsaHandle = IntPtr.Zero;
LSA_UNICODE_STRING[] system = null;
if (systemName != null)
{
system = new LSA_UNICODE_STRING[1];
system[0] = InitLsaString(systemName);
}

uint ret = Win32Sec.LsaOpenPolicy(system, ref lsaAttr,
(int)Access.POLICY_ALL_ACCESS, out lsaHandle);
if (ret == 0)
return;
if (ret == STATUS_ACCESS_DENIED)
{
throw new UnauthorizedAccessException();
}
if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
{
throw new OutOfMemoryException();
}
throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int )ret));
}

public void AddPrivileges(string account, string privilege)
{
IntPtr pSid = GetSIDInformation(account);
LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
privileges[0] = InitLsaString(privilege);
uint ret = Win32Sec.LsaAddAccountRights(lsaHandle, pSid, privileges, 1);
if (ret == 0)
return;
if (ret == STATUS_ACCESS_DENIED)
{
throw new UnauthorizedAccessException();
}
if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
{
throw new OutOfMemoryException();
}
throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int )ret));
}
public void Dispose() {
if (lsaHandle != IntPtr.Zero)
{
Win32Sec.LsaClose(lsaHandle);
lsaHandle = IntPtr.Zero;
}
GC.SuppressFinalize(this);
}
~LsaWrapper()
{
Dispose();
}
// helper functions

IntPtr GetSIDInformation(string account)
{
LSA_UNICODE_STRING[] names = new LSA_UNICODE_STRING[1];
LSA_TRANSLATED_SID2 lts;
IntPtr tsids = IntPtr.Zero;
IntPtr tdom = IntPtr.Zero;
names[0] = InitLsaString(account);
lts.Sid = IntPtr.Zero;
Console.WriteLine("String account: {0}", names[0].Length);
int ret = Win32Sec.LsaLookupNames2(lsaHandle, 0, 1, names, ref tdom, ref
tsids);
if (ret != 0)
throw new Win32Exception(Win32Sec.LsaNtStatusToWinError(ret) );
lts = (LSA_TRANSLATED_SID2)Marshal.PtrToStructure(tsids,
typeof(LSA_TRANSLATED_SID2));
Win32Sec.LsaFreeMemory(tsids);
Win32Sec.LsaFreeMemory(tdom);
return lts.Sid;
}

static LSA_UNICODE_STRING InitLsaString(string s)
{
// Unicode strings max. 32KB
if (s.Length > 0x7ffe)
throw new ArgumentException("String too long");
LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING();
lus.Buffer = s;
lus.Length = (ushort)(s.Length * sizeof(char));
lus.MaximumLength = (ushort)(lus.Length + sizeof(char));
return lus;
}
}
}
// usage....

using (Willys.LsaSecurity.LsaWrapper lsa = new
Willys.LsaSecurity.LsaWrapper())
{
// add SeDenyRemoteInteractiveLogonRight will effectively deny TS access
to someAccount
lsa.AddPrivileges("someAccount",
"SeDenyRemoteInteractiveLogonRight");
}
Willy.

Nov 16 '05 #3

"Morten" <mo**************@hotmail.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
Hi Willy!

Thanks for your suggestion. I'm having a few problems using your code. I
get this error:

LSA.cs(218): sizeof can only be used in an unsafe context (consider using
System.Runtime.InteropServices.Marshal.SizeOf)

Any idea how that can be solved? Also, I've been looking for a way to use
WMI - preferably using a vb script - to do the same so if you have any
idea how this can be done I'd be greatful.

Best regards

Morten

Never understood why sizeof(char) needs an unsafe context, but you can get
arround it by this...

lus.Length = (ushort)(s.Length * 2); // Unicode char is 2 bytes
lus.MaximumLength = (ushort)(lus.Length + 2)

Assuming you are running in a AD, you should definitely take a look at Group
policy management (GPO) to apply these kind of privileges, that way you
don't have to write any code.

Willy.


Nov 16 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: hokiegal99 | last post by:
A few questions about the following code. How would I "wrap" this in a function, and do I need to? Also, how can I make the code smart enough to...
99
by: David MacQuigg | last post by:
I'm not getting any feedback on the most important benefit in my proposed "Ideas for Python 3" thread - the unification of methods and functions. ...
21
by: Rubén Campos | last post by:
I haven't found any previous message related to what I'm going to ask here, but accept my anticipated excuses if I'm wrong. I want to ask about...
17
by: cwdjrxyz | last post by:
Javascript has a very small math function list. However there is no reason that this list can not be extended greatly. Speed is not an issue,...
2
by: Bryan Olson | last post by:
The current Python standard library provides two cryptographic hash functions: MD5 and SHA-1 . The authors of MD5 originally stated: It is...
7
by: Tim ffitch | last post by:
Hi I have created a VB dll file that contains common functions I use across various projects in VB, Access and Excel. Rather than have to code...
23
by: Timothy Madden | last post by:
Hello all. I program C++ since a lot of time now and I still don't know this simple thing: what's the problem with local functions so they are...
14
by: v4vijayakumar | last post by:
Why we need "virtual private member functions"? Why it is not an (compile time) error?
7
by: Immortal Nephi | last post by:
My project grows large when I put too many member functions into one class. The header file and source code file will have approximately 50,000...
6
KevinADC
by: KevinADC | last post by:
This snippet of code provides several examples of programming techniques that can be applied to most programs. using hashes to create unique...
0
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
0
jalbright99669
by: jalbright99669 | last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
2
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...
0
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.