Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Win32_SecurityDescriptor Not Found 0x80041002

66 views
Skip to first unread message

David L. Crow

unread,
Jul 8, 2002, 10:07:02 PM7/8/02
to
I am writing a C++ app to create a share and set the permissions for
it. The create the share part is working just fine. I am planningo on
creating a SecurityDescriptor object and setting the Access attribute on
the share when calling the Create method.

The problem that I am having is that when I call Get to get the
Win32_SecurityDescriptor class, I get a "Not Found" error (0x80041002).

Does anyone have any ideas how that could happen? The same code finds
the Win32_Share class just fine.

The code (sans the error checking) is below.

--
David L. Crow Texas! It's like a
cr...@OrangeBlood.org whole other country.


char * homeShareServer = argv[1];
char * homeFolderDir = argv[2];
char * sAMAccountName = argv[3];

hr = CoInitialize(0);
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, 0);

IWbemLocator *pLocator = NULL;
hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *)&pLocator);

IWbemServices *pServices = NULL;
_bstr_t path = L"\\\\" + _bstr_t(homeShareServer) + L"\\root\\cimv2";
hr = pLocator->ConnectServer(path, NULL, NULL, NULL, 0, NULL, NULL,
&pServices);
BSTR sharePath = SysAllocString(L"Win32_Share");

IWbemClassObject *pShareClass = NULL;
hr = pServices->GetObject(sharePath, 0, NULL, &pShareClass, NULL);

BSTR createMethod = SysAllocString(L"Create");

IWbemClassObject *pShareCreateMeth = NULL;
hr = pShareClass->GetMethod(createMethod, 0, &pShareCreateMeth, NULL);

IWbemClassObject *pShareCreate = NULL;
hr = pShareCreateMeth->SpawnInstance(0, &pShareCreate);

VARIANT path;
VariantInit(&path);
V_VT(&path) = VT_BSTR;
_bstr_t pathVal = _bstr_t(homeFolderDir) + L"\\" +
_bstr_t(sAMAccountName);
V_BSTR(&path) = pathVal;
hr = pShareCreate->Put(L"Path", 0, &path, 0);
VariantClear(&path);

VARIANT shareName;
VariantInit(&shareName);
V_VT(&shareName) = VT_BSTR;
_bstr_t shareNameVal = _bstr_t(sAMAccountName) + L"$";
V_BSTR(&shareName) = shareNameVal;
hr = pShareCreate->Put(L"Name", 0, &shareName, 0);
VariantClear(&shareName);

VARIANT shareType;
VariantInit(&shareType);
V_VT(&shareType) = VT_I4;
V_I4(&shareType) = 0;
hr = pShareCreate->Put(L"Type", 0, &shareType, 0);
VariantClear(&shareName);

IWbemClassObject *pSecDescClass = NULL;
BSTR secDescPath = L"Win32_SecurityDescriptor";
hr = pServices->GetObject(secDescPath, 0, NULL, &pSecDescClass, NULL);

IWbemClassObject *pSecDesc = NULL;
hr = pSecDescClass->SpawnInstance(0, &pSecDesc);

David L. Crow

unread,
Jul 9, 2002, 1:43:17 AM7/9/02
to
In microsoft.public.win32.programmer.wmi, I wrote:
> IWbemClassObject *pSecDescClass = NULL;
> BSTR secDescPath = L"Win32_SecurityDescriptor";
> hr = pServices->GetObject(secDescPath, 0, NULL, &pSecDescClass, NULL);

When I changed the second line to be

BSTR secDescPath = SysAllocString(L"Win32_SecurityDescriptor");

it fixed things. I was tipped off by turnning on full logging and looking
in the logfiles in C:\WINNT\system32\wbem\Logs .

My next problem is how to get an array of multiple ACE objects into the
DACL property of the SecurityDescriptor.

Any hints on array VARIANT values would be much appreciated.

Ivan Brugiolo [MS]

unread,
Jul 9, 2002, 5:47:45 AM7/9/02
to
given the following MOF representation of the class,

class Win32_SecurityDescriptor : Win32_MethodParameterClass
{
Win32_Trustee Owner;
Win32_Trustee Group;
Win32_ACE DACL[];
Win32_ACE SACL[];
uint32 ControlFlags;
};

the DACL is an array of instances of Win32_ACE.

In C++ terms this becomes a SAFEARRAY of type VT_ARRAY|CIM_OBJECT
where the array actually contains pointers to the IUknonw interface obtained
from an IWbemClassObject
that is an instance of a Win32_ACE class.

///////////
if it is an option for you, you might evaluate using the NetSahreAdd API,
passing the security descriptor as the shi502_security_descriptor param of
the the SAHRE_INFO_502 struct.
You can obtain the security descriptor easily by string concatenation if you
use the SDDL language.


--
This posting is provided "As Is" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"David L. Crow" <cr...@waterloo.OrangeBlood.org> wrote in message
news:agdt5l$g22$1...@waterloo.OrangeBlood.org...

David L. Crow

unread,
Jul 9, 2002, 11:51:19 AM7/9/02
to
In article <uWB2Q2yJCHA.2636@tkmsftngp09>, Ivan Brugiolo [MS] wrote:
> if it is an option for you, you might evaluate using the NetSahreAdd API,

I started down the WMI road using Visual Basic where there were lots of
examples and later found out that I was restrictued to cscript 5.1 which
didn't interract very well with being invoked from another application.
Because of the WMI experience I garnered, I stuck it out using WMI from
C++. Over the last two days, I have questioned that strategy :-), but I
am almost there.

> In C++ terms this becomes a SAFEARRAY of type VT_ARRAY|CIM_OBJECT
> where the array actually contains pointers to the IUknonw interface obtained
> from an IWbemClassObject
> that is an instance of a Win32_ACE class.

Here is the code that I am using. Instead of CIM_OBJECT, I was using
VT_UNKNOWN based on some examples that I could find earlier in this
newsgroup.

Right now, I am trying to set two ACE entries on the share. Only the
second one is getting set. The second one is correct (ie the correct
user and access perms), so this leads me to believe that I am not doing
the array thing correctly. I am definitely a newbie in the COM memory
model.

Again, I have removed a bunch of error checking to make it more readable.


//
//
//
IWbemClassObject *
getSecurityDescriptor(IWbemServices *pServices,
char * homeShareServer,
char * domainName,
char * sAMAccountName) {

HRESULT hr;

BSTR secDescClassName = SysAllocString(L"Win32_SecurityDescriptor");
IWbemClassObject *pSecDescClass = NULL;
hr = pServices->GetObject(secDescClassName, 0, NULL, &pSecDescClass, NULL);
SysFreeString(secDescClassName);

IWbemClassObject *pSecDesc = NULL;
hr = pSecDescClass->SpawnInstance(0, &pSecDesc);

pSecDescClass->Release();

IWbemClassObject *userACE =
getACE(pServices, homeShareServer, "Administrators");
IWbemClassObject *adminACE = getACE(pServices, domainName, sAMAccountName);

SAFEARRAYBOUND aDim[1];
aDim[0].lLbound = 1;
aDim[0].cElements = 2;
SAFEARRAY *daclACE = SafeArrayCreate(VT_UNKNOWN, 1, aDim);

long i = 0;
SafeArrayPutElement(daclACE, &i, (IUnknown *)userACE);
i = 1;
SafeArrayPutElement(daclACE, &i, (IUnknown *)adminACE);

VARIANT dacl;
V_VT(&dacl) = VT_ARRAY | VT_UNKNOWN;
V_ARRAY(&dacl) = daclACE;

hr = pSecDesc->Put(L"DACL", 0, &dacl, 0);

return pSecDesc;
}


//
//
//
IWbemClassObject *
getACE(IWbemServices *pServices, char *domainName, char *accountName) {
HRESULT hr;

BSTR trusteeClassName = SysAllocString(L"Win32_Trustee");
IWbemClassObject *pTrusteeClass = NULL;
hr = pServices->GetObject(trusteeClassName, 0, NULL, &pTrusteeClass, NULL);
SysFreeString(trusteeClassName);

IWbemClassObject *pTrustee = NULL;
hr = pTrusteeClass->SpawnInstance(0, &pTrustee);
pTrusteeClass->Release();

char * adminName = (char *)malloc(strlen(domainName) +
strlen(accountName) + 2);
sprintf(adminName, "%s\\%s", domainName, accountName);

IWbemClassObject *pAccount = NULL;
_bstr_t adminPath = L"Win32_Account.Name='" + _bstr_t(accountName) +
L"',Domain='" + _bstr_t(domainName) + L"'";
hr = pServices->GetObject(adminPath, 0, NULL, &pAccount, NULL);

VARIANT pSIDString;
hr = pAccount->Get(L"SID", 0, &pSIDString, NULL, NULL);
pAccount->Release();

IWbemClassObject *pSID = NULL;
_bstr_t sidPath = L"Win32_SID.SID='" + _bstr_t(V_BSTR(&pSIDString)) + L"'";
printf("sidString = %S\n", V_BSTR(&pSIDString));
hr = pServices->GetObject(sidPath, 0, NULL, &pSID, NULL);
VariantClear(&pSIDString);

VARIANT pSIDArray;
hr = pSID->Get(L"BinaryRepresentation", 0, &pSIDArray, NULL, NULL);

hr = pTrustee->Put(L"SID", 0, &pSIDArray, 0);
VariantClear(&pSIDArray);

VARIANT domain;
VariantInit(&domain);
V_VT(&domain) = VT_BSTR;
_bstr_t domainVal = _bstr_t(domainName);
V_BSTR(&domain) = domainVal;
hr = pTrustee->Put(L"Domain", 0, &domain, 0);
VariantClear(&domain);

VARIANT name;
VariantInit(&name);
V_VT(&name) = VT_BSTR;
_bstr_t nameVal = _bstr_t(accountName);
V_BSTR(&name) = nameVal;
hr = pTrustee->Put(L"Name", 0, &name, 0);
VariantClear(&name);

IWbemClassObject *pACEClass = NULL;
hr = pServices->GetObject(L"Win32_ACE", 0, NULL, &pACEClass, NULL);

IWbemClassObject *pACE = NULL;
hr = pACEClass->SpawnInstance(0, &pACE);

VARIANT accessMask;
V_VT(&accessMask) = VT_I4;
V_I4(&accessMask) = FILE_ALL_ACCESS; // Full Control
hr = pACE->Put(L"AccessMask", 0, &accessMask, 0);
VariantClear(&accessMask);

VARIANT aceFlags;
V_VT(&aceFlags) = VT_I4;
V_I4(&aceFlags) = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
hr = pACE->Put(L"AceFlags", 0, &aceFlags, 0);
VariantClear(&aceFlags);

VARIANT aceType;
V_VT(&aceType) = VT_I4;
V_I4(&aceType) = 0;
hr = pACE->Put(L"AceType", 0, &aceType, 0);
VariantClear(&aceType);

VARIANT trustee;
V_VT(&trustee) = VT_UNKNOWN;
V_UNKNOWN(&trustee) = (IUnknown *)pTrustee;
hr = pACE->Put(L"Trustee", 0, &trustee, 0);
VariantClear(&trustee);

return pACE;

David L. Crow

unread,
Jul 9, 2002, 12:54:39 PM7/9/02
to
In microsoft.public.win32.programmer.wmi, you wrote:
> I am definitely a newbie in the COM memory model.

I was able to figure out my problem. I realized that
SafeArrayPutElement returned an HRESULT and it told me immediately that
I was using a bad index which led me to a mis-specified lLbound. The
code I copied from MSDN for creating the array was assuming a 1-based
array index.

I now have solved all of my problems and am creating shares with the
permissions that I want!

Ivan Brugiolo [MS]

unread,
Jul 9, 2002, 1:48:35 PM7/9/02
to
you array has a lower bound of 1, and you are inserting in position 0 and 1,
hence only the second succeds.

if you have a lower bound of 0, it should just work

SAFEARRAYBOUND aDim[1];
aDim[0].lLbound = 1; ////////////////////////////////////// change to
0


aDim[0].cElements = 2;
SAFEARRAY *daclACE = SafeArrayCreate(VT_UNKNOWN, 1, aDim);

--

David L. Crow

unread,
Jul 9, 2002, 3:02:40 PM7/9/02
to
Thanks for your continued help.

I know have a great executable that will use WMI to create a share and
set the permissions that I want. It works perfectly when run from a
DOS shell. However, when run from a CreateProcess() call in an executable
running as a service, the pLocator->ConnectServer() calls fails with

0x800706a7 The RPC protocol sequence is not supported.

In wbemxprox.log, the error message is

ConnectViaDCOM, CoCreateInstanceEx resulted in hr = 0x0
(Tue Jul 09 13:56:25 2002) :
NTLMLogin resulted in hr = 0x800706a7(Tue Jul 09 13:56:25 2002) :
Error loading module {F7CE2E13-8C90-11D1-9E7B-00C04FC324A8},
return code is 0x800706a7(Tue Jul 09 13:56:25 2002) :

I thought this was a DLL loading issue, but I made sure that my PATH
includes C:\WINNT\system32\wbem .

Any ideas would be appreciated.

David L. Crow

unread,
Jul 9, 2002, 5:28:14 PM7/9/02
to
In article <slrnaimcq...@waterloo.OrangeBlood.org>, David L. Crow wrote:
> I know have a great executable that will use WMI to create a share and
> set the permissions that I want. It works perfectly when run from a
> DOS shell. However, when run from a CreateProcess() call in an executable
> running as a service, the pLocator->ConnectServer() calls fails with
>
> 0x800706a7 The RPC protocol sequence is not supported.
>
> In wbemxprox.log, the error message is
>
> ConnectViaDCOM, CoCreateInstanceEx resulted in hr = 0x0
> (Tue Jul 09 13:56:25 2002) :
> NTLMLogin resulted in hr = 0x800706a7(Tue Jul 09 13:56:25 2002) :
> Error loading module {F7CE2E13-8C90-11D1-9E7B-00C04FC324A8},
> return code is 0x800706a7(Tue Jul 09 13:56:25 2002) :

The environment in the process created from the service was empty. I
set the PATH to include
c:\winnt;c:\winnt\system32;c:\winnt\system32\wbem, but I didn't set
anything else.

Turns out that SystemRoot is required. By setting SystemRoot, everything
is working perfectly in the destination environment.

0 new messages