Help! - 0x80070005 - Access Denied Calling SetInfo ( )

J

Jeff Petter

We are in the process of migrating all of our users from old NT domains to AD, and as a part of the process all of the users have a new standardized ID along with a new password. A utility I have to write pre-position, so to speak, the new profile, so that when the user logs onto the new domain for the first time, their desktop will have the same look, feel and appearance as the desktop in the old domain, oh and functionality as well. What has been a real stumbling block for me is that it is our corporate security policy (and one we get audited on monthly) requires that users are prompted to change their passwords upon first logon. So, as I see it, I have to first clear the flag that requires the password change, do my work, and then set the flag back. Easier said than done - for me anyhow, I have eight separate programs so far, and partly out of comfort and partly because of the complexity of quite a bit of what I am trying to do, I am using C++.

I've been playing with the ADSI interface, and can change user passwords, log them on, create their profiles, migrate their previous profile settings (i.e. My Documents, Favorites, drive mappings, printers, etc), and then set the property so that they have to change their password upon their first logon. However, that isn't good enough for management because their initial password would then be different from the corporate standard default. And since they cannot repeat passwords, I didn't want to go down the route of changing that property, resetting the password, and changing the property back.

So, essentially what I have tried to do is:
1) clear the flag requiring them to change their password upon first logon.
2) log them on to get the handle to their logon token
3) set the flag requiring them to change their password upon first logon.

As I understand it, the properties are changed with the IADsUser::put ( ) function, which writes to a buffer, and to make the change in AD, a call to SetInfo( ) needs to be made. The SetInfo( ) call is where I am now receiving the errors. The call returns a 0x800570005, which is access denied. However I am running it under an account that does have access, and furthermore I can go in and manually make the change.

Does anyone have any idea where I might have made an error, or if there is a different sequence I must follow with ADSI?

As always, I appreciate any and all help.

The code is below, and again, SetInfo throws the error.

Thanks,
Jeff
*******************************************************************************************
/*************************************************************

Function: RemoveFlag
This function will interface with Active Directory and perform the
following operation:
1) remove flag requiring the user to change their passowrd on next logon

*//////////////////////////////////////////////////////////////
HRESULT RemoveFlag(LPSTR user)
{
HRESULT hr = S_OK;
IADsUser *pUser = NULL;
VARIANT var;
// ansi strings
char szConnectRoot[] = "WinNT://US1/";
char szConnectStrEnd[] = ",user";
char szConnectStr[128];
TCHAR errorMsg[128];

// Unicode strings
LPWSTR wsConnectStr = NULL;

// initialize COM
hr = CoInitialize (NULL);
if (SUCCEEDED(hr))
{
// build connect string in ansi
lstrcpy (szConnectStr, szConnectRoot);
lstrcat (szConnectStr, user);
lstrcat (szConnectStr, szConnectStrEnd);

// convert ansi strings to unicode
wsConnectStr = ConvertToUnicodeString (szConnectStr);

// bind to the AD user object
hr = ADsGetObject(wsConnectStr,
IID_IADsUser,
(void**) &pUser);


if (FAILED (hr))
{
_stprintf (errorMsg, "Unable to connect to AD User Object: %x", hr);
MessageBox (NULL,errorMsg , "Critical Error - Aborting...", MB_OK | MB_ICONSTOP);
CoUninitialize( );
return hr;
}

if (!pUser)
{
return E_FAIL;
}

// clear the password expiration flag
VariantInit (&var);
V_I4 (&var) = 0;
V_VT (&var) = VT_I4;


hr = pUser->Put (_bstr_t("PasswordExpired"), var);
if (FAILED (hr))
{
_stprintf (errorMsg, "Unable update password expiration: %x", hr);
MessageBox (NULL, errorMsg, "Critical Error - Aborting...", MB_OK | MB_ICONSTOP);
CoUninitialize( );
return hr;
}

hr = pUser->SetInfo();
if (FAILED (hr))
{
_stprintf (errorMsg, "Unable to update AD User Information: %x", hr);
MessageBox (NULL, errorMsg, "Critical Error - Aborting...", MB_OK | MB_ICONSTOP);
CoUninitialize( );
return hr;
}

// release resources
pUser->Release();
CoUninitialize();
}
return hr;
}
//////// End Function RemoveFlag /////////////////////////////
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top