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=impersonat e,(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(refSecDescript or)
'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(refSecDescript or)
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("GetSecurityDescripto r", 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("SetSecurityDescripto r",
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_OWN ER
| 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);
================================================== ===========
Nicholas Paldino [.NET/C# MVP] wrote:
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]
- mv*@spam.guard.caspershouse.com
"Nigel Frost" <N.*******@soton.ac.uk> wrote in message
news:11********************@g47g2000cwa.googlegrou ps.com...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.