SetSecurityDescriptor error 1307

  • Thread starter Thread starter Nigel Frost
  • Start date Start date
N

Nigel Frost

I have a .Net console application. It creates a user's folder, sets
permissions using WMI, then fails to give the ownership of that folder
to the user (for quotas).

This all executes on a single 2003 server, within a larger domain. My
admin account, from which I run the app, and the user's account, are
both AD domain accounts.

Seems simple enough, and it works fine with a VB script from the
console. However, when I run my C# .Net app, it fails with 1307.

I've read the other posts regarding this, in ASP, and I've tried both
WMI and ADSI methods to set owner - both give the same error 1307.

The only case when this app does work properly, is when I change
ownership of the folder to my own admin account.

I'm obviously missing the point here. Am I right in thinking this has
to do with impersonation? Do I need to use COM+? Can anyone please put
me on the right track - thanks very much.
 
Nigel,

Can you show the script, as well as the code from the console app?
There might be a discrepancy between the two that is missed (or rather,
something is out of order, since what you would call in VB Script is
different than what you would call in C#).

Hope this helps.
 
Nicholas,
Thanks for taking an interest in my problem.
As a further test, I used WMI in my app to create a Win32_Process to
run my VB script in a command window. It also failed with error 1307.
So I have two command windows - the original one with permission to
change the ownership, and the spawned one that does not!

Here are some (edited) code extracts:

The VB script
-------------
set refWMI =
GetObject("winMgmts:{impersonationLevel=impersonate,(Security,Restore)}!\\"
& strMachine & "\root\cimv2")

'find the user's Win32_Account and Win32_SID
set col = refWMI.ExecQuery("SELECT * FROM Win32_ACCOUNT " & "WHERE
Name='" & strUser & "' AND Domain='testdomain'" )
For Each ref in col
set refAccount = ref
set refSID = refWMI.Get("Win32_SID='" & refAccount.SID & "'")
exit for
Next

'get the Win32_LogicalFileSecuritySetting for the user's home folder
set refSecSetting = refWMI.Get("Win32_LogicalFileSecuritySetting='" &
strUserDirPath & "'")

'get Win32_SecurityDescriptor
ret = refSecSetting.GetSecurityDescriptor(refSecDescriptor)

'create Win32_Trustee
Set refNewTrustee = refWMI.Get("Win32_Trustee").spawnInstance_()
With refNewTrustee
.Domain = refAccount.Domain
.Name = refAccount.Name
.SID = refSID.BinaryRepresentation
.SidLength = refSID.SidLength
.SIDString = refSID.SID
End With

'set the new owner
refSecDescriptor.Owner = refNewTrustee

'Commit changes
ret = refSecSetting.SetSecurityDescriptor(refSecDescriptor)

C# WMI code
-----------
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = ImpersonationLevel.Impersonate;
options.Authentication = AuthenticationLevel.Unchanged;
scope = new ManagementScope(strScope,options);
scope.Connect();

// Win32_LogicalFileSecuritySetting
string wql = string.Format(
@"SELECT * FROM Win32_LogicalFileSecuritySetting WHERE

Path='e:\\share\\{0}'",user);
ManagementObjectCollection queryCol = execQuery(scope, wql); // my fn
foreach (ManagementObject moSetting in queryCol)
{
securitySetting = moSetting;
break;
}

// Win32_SecurityDescriptor
Object[] oArgs = new Object[1];
result = securitySetting.InvokeMethod("GetSecurityDescriptor", oArgs);
securityDescriptor = (ManagementBaseObject)oArgs[0];

securityDescriptor["ControlFlags"] = 32771;

// Win32_Account for user
userAccount = getUserAccount(scope, domain, user); // my fn

// Win32_SID for user
userSid = getUserSID(scope, user, userAccount); my fn

// The current owner
ManagementBaseObject currentOwner =
(ManagementBaseObject)securityDescriptor["Owner"];

// new owner - Win32_Trustee for user
ManagementBaseObject newOwner =
(ManagementBaseObject)currentOwner.Clone();

newOwner["Domain"] = (string)userAccount["Domain"];
newOwner["Name"] = (string)userAccount["Name"];
newOwner["SID"] = (Byte[])userSid["BinaryRepresentation"];
newOwner["SidLength"] = (UInt32)userSid["SidLength"];
newOwner["SIDString"] = (string)userSid["SID"];
securityDescriptor["Owner"] = newOwner;

// Commit the changes
Object[] oSetArgs = new Object[1] { securityDescriptor };

// Here is where I get the error 1307
result = securitySetting.InvokeMethod("SetSecurityDescriptor",
oSetArgs);

=============================================================

C# ADSI code
------------
string path = string.Format(@"e:\\share\\{0}",user);

ADsSecurityUtilityClass asu = new ADsSecurityUtilityClass();

// Get DACL and OWNER info
asu.SecurityMask = (int)(ADS_SECURITY_INFO_ENUM.ADS_SECURITY_INFO_OWNER

| ADS_SECURITY_INFO_ENUM.ADS_SECURITY_INFO_DACL);

SecurityDescriptor sd = asu.GetSecurityDescriptor(
path,
(int)ADS_PATHTYPE_ENUM.ADS_PATH_FILE,
(int)ADS_SD_FORMAT_ENUM.ADS_SD_FORMAT_IID) as SecurityDescriptor;
}

sd.Owner = string.Format(@"testdomain\{0}",user);

// Here is where I get the error 1307
asu.SetSecurityDescriptor(
path,
(int)ADS_PATHTYPE_ENUM.ADS_PATH_FILE,
sd,
(int)ADS_SD_FORMAT_ENUM.ADS_SD_FORMAT_IID);

=============================================================

C# running VB Script
--------------------
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = ImpersonationLevel.Impersonate;
options.Authentication = AuthenticationLevel.Unchanged;
scope = new ManagementScope(strScope,options);
scope.Connect();

// Create a process in which to run the script
ManagementClass process = createManagementClass(scope,"WIN32_Process");

UInt32 pid = 0;
object[] methodArgs =
{
@"cmd.exe /k cscript owner.vbs njf1", // keep the cmd window open
@"C:\projects\xyz\vb",
null,
pid
};

// Run the cmd window - the script fails with error 1307
Object result = process.InvokeMethod ("Create", methodArgs);

=============================================================

Nigel,

Can you show the script, as well as the code from the console app?
There might be a discrepancy between the two that is missed (or rather,
something is out of order, since what you would call in VB Script is
different than what you would call in C#).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Nigel Frost said:
I have a .Net console application. It creates a user's folder, sets
permissions using WMI, then fails to give the ownership of that folder
to the user (for quotas).

This all executes on a single 2003 server, within a larger domain. My
admin account, from which I run the app, and the user's account, are
both AD domain accounts.

Seems simple enough, and it works fine with a VB script from the
console. However, when I run my C# .Net app, it fails with 1307.

I've read the other posts regarding this, in ASP, and I've tried both
WMI and ADSI methods to set owner - both give the same error 1307.

The only case when this app does work properly, is when I change
ownership of the folder to my own admin account.

I'm obviously missing the point here. Am I right in thinking this has
to do with impersonation? Do I need to use COM+? Can anyone please put
me on the right track - thanks very much.
 
Back
Top