I am trying to allow for user account to take ownership of an Active
Directory object. I have assigned the Modify Owner permission to the user
on the AD object - a distribution list in this case. Using Active Directory
Users and Computers, the user can take ownership of the object. But I have
not been able to get the program I am working on to do so. Whenever I try
to write the Security Descriptor back to the object, I get the
E_ACCESSDENIED error. The program code works fine if ran as a domain
administrator. So I am thinking that I do not have a privilege activated
that I need. But I have tried using AdjustTokenPrivilege to grant the
SE_RESTORE_NAME and SE_TAKE_OWNERSHIP_NAME privileges. That does not seem
to have any effect.
Does anyone have an idea about what I am missing?
Thanks.
The test code is as follows:
void CADOwnDlg::OnBnClickedTakeownership()
{
ACL * abdacl;
DWORD abdacllen;
SID * abowner;
DWORD abownerlen;
SID * abpg;
DWORD abpglen;
ACL * absacl;
DWORD absacllen;
SECURITY_DESCRIPTOR * absd;
DWORD absdlen;
IDirectoryObject * adobject;
ADSVALUE adsvalue;
ADS_ATTR_INFO attrinfo;
LPWSTR attrstr;
DWORD buflen;
HRESULT hr;
LUID luid;
DWORD numobjattr;
ADS_ATTR_INFO * objattr;
WCHAR objectpath[256];
HANDLE prochandle;
SECURITY_DESCRIPTOR * sd;
SECURITY_DESCRIPTOR * sdsr;
unsigned char sid[256];
SID * sidnewowner;
HANDLE tokenhandle;
TOKEN_PRIVILEGES tp;
abdacl=NULL;
abdacllen=0;
abowner=NULL;
abownerlen=0;
abpg=NULL;
abpglen=0;
absacl=NULL;
absacllen=0;
absd=NULL;
absdlen=0;
adobject=NULL;
attrstr=L"nTSecurityDescriptor";
buflen=0;
DWORD numattr;
objattr=NULL;
sdsr=NULL;
memset(sid, 0, sizeof(sid));
memcpy(sid, SidVal, SidValSize);
sidnewowner=(SID *)sid;
wcscpy(objectpath, L"LDAP://CN=Test.One,OU=Client Distribution
Lists,OU=Public Distribution Lists,DC=aoins,DC=com");
hr=CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hr=ADsOpenObject(objectpath, NULL, NULL, ADS_SECURE_AUTHENTICATION,
IID_IDirectoryObject, (void **)&adobject);
hr=adobject->GetObjectAttributes(&attrstr, 1, &objattr, &numobjattr);
sd=(SECURITY_DESCRIPTOR *)objattr->pADsValues->SecurityDescriptor.lpValue;
MakeAbsoluteSD(sd, absd, &absdlen, abdacl, &abdacllen, absacl, &absacllen,
abowner, &abownerlen, abpg, &abpglen);
absd=(SECURITY_DESCRIPTOR *)malloc(absdlen);
abdacl=(ACL *)malloc(abdacllen);
absacl=(ACL *)malloc(absacllen);
abowner=(SID *)malloc(abownerlen);
abpg=(SID *)malloc(abpglen);
MakeAbsoluteSD(sd, absd, &absdlen, abdacl, &abdacllen, absacl,
&absacllen, abowner, &abownerlen, abpg, &abpglen);
SetSecurityDescriptorOwner(absd, sidnewowner, FALSE);
MakeSelfRelativeSD(absd, sdsr, &buflen);
sdsr=(SECURITY_DESCRIPTOR *)malloc(buflen);
MakeSelfRelativeSD(absd, sdsr, &buflen);
prochandle=GetCurrentProcess();
OpenProcessToken(prochandle, TOKEN_ADJUST_PRIVILEGES, &tokenhandle);
LookupPrivilegeValue("DCH1", SE_RESTORE_NAME, &luid);
tp.PrivilegeCount=1;
tp.Privileges[0].Luid=luid;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(tokenhandle, FALSE, &tp, 0, NULL, NULL);
LookupPrivilegeValue("DCH1", SE_TAKE_OWNERSHIP_NAME, &luid);
tp.PrivilegeCount=1;
tp.Privileges[0].Luid=luid;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(tokenhandle, FALSE, &tp, 0, NULL, NULL);
attrinfo.dwADsType=objattr->dwADsType;
attrinfo.dwControlCode=ADS_ATTR_UPDATE;
attrinfo.dwNumValues=1;
attrinfo.pADsValues=&adsvalue;
adsvalue.dwType=objattr->dwADsType;
adsvalue.SecurityDescriptor.lpValue=(LPBYTE)sdsr;
adsvalue.SecurityDescriptor.dwLength=buflen;
attrinfo.pszAttrName=attrstr;
hr=adobject->SetObjectAttributes(&attrinfo, 1, &numattr);
FreeADsMem(objattr);
adobject->Release();
if(abdacl!=NULL) free(abdacl);
if(abowner!=NULL) free(abowner);
if(abpg!=NULL) free(abpg);
if(absacl!=NULL) free(absacl);
if(absd!=NULL) free(absd);
if(sdsr!=NULL) free(sdsr);
CoUninitialize();
} 7 1805
"Stephen Engle" <en***********@aoins.com> wrote in message
news:eM*************@TK2MSFTNGP15.phx.gbl... The program code works fine if ran as a domain administrator. So I am thinking that I do not have a privilege activated that I need. But I have tried using AdjustTokenPrivilege to grant the SE_RESTORE_NAME and SE_TAKE_OWNERSHIP_NAME privileges. That does not seem to have any effect.
Does anyone have an idea about what I am missing?
AdjustTokenPrivileges() does not grant privileges. If it did, there would be
no security at all as any thread could grant any old privilege. Rather it
enables privleges.
To review, privilges have three states:
1) not granted
2) granted and not enabled
3) granted and enabled
AdjustTokenPrivileges() can transition from state 2 to 3 or 3 to 2 in my
list above.
Because you say the code works as a domain administrator you will have to
run the code in a more privileged security context.
You have a few options:
1) Run under a proper user context.
2) Use the credentials of a suitably privileged user and LogonUser(),
ImpersonateLoggedOnUser() and RevertToSelf() so that you have the necessary
credentials at the time you need them
3) make some inter-process request of a service installed with the proper
credentials to do your bidding. Of course, then you need a way for the
service to verify that the request comes from a party it trusts.
I'd post again in a more appropriate group. If security was my _thing_ I'd
point you, but it ain't so I can't. :-)
Regards,
Will
The thing I can't figure out here, is why Active Directory Users and
Computers can take ownership, yet my program cannot (obviously something is
missing). I tried using ADSI objects as well but got the same result. Is
ADU&C doing something behind the scenes with the servers to facilitate this,
or is it some API calls that I'm not doing?
"William DePalo [MVP VC++]" <wi***********@mvps.org> wrote in message
news:ul**************@TK2MSFTNGP14.phx.gbl... "Stephen Engle" <en***********@aoins.com> wrote in message news:eM*************@TK2MSFTNGP15.phx.gbl... The program code works fine if ran as a domain administrator. So I am thinking that I do not have a privilege
activated that I need. But I have tried using AdjustTokenPrivilege to grant the SE_RESTORE_NAME and SE_TAKE_OWNERSHIP_NAME privileges. That does not
seem to have any effect.
Does anyone have an idea about what I am missing? AdjustTokenPrivileges() does not grant privileges. If it did, there would
be no security at all as any thread could grant any old privilege. Rather it enables privleges.
To review, privilges have three states:
1) not granted 2) granted and not enabled 3) granted and enabled
AdjustTokenPrivileges() can transition from state 2 to 3 or 3 to 2 in my list above.
Because you say the code works as a domain administrator you will have to run the code in a more privileged security context.
You have a few options:
1) Run under a proper user context.
2) Use the credentials of a suitably privileged user and LogonUser(), ImpersonateLoggedOnUser() and RevertToSelf() so that you have the
necessary credentials at the time you need them
3) make some inter-process request of a service installed with the proper credentials to do your bidding. Of course, then you need a way for the service to verify that the request comes from a party it trusts.
I'd post again in a more appropriate group. If security was my _thing_ I'd point you, but it ain't so I can't. :-)
Regards, Will
"Stephen Engle" <en***********@aoins.com> wrote in message
news:um**************@TK2MSFTNGP09.phx.gbl... The thing I can't figure out here, is why Active Directory Users and Computers can take ownership, yet my program cannot (obviously something is missing).
It is a good question for which I don't have an answer. I _think_ though
that you could find an answer by looking at that group and its privileges.
Assuming that the code is proper, the issue is a privilege granted to a user
in the group and which is lacking in the user under whose context your
application runs.
Do you have the credentials of one of the users in this group? If so, and if
you run on XP you could try this experiment:
LogonUser(); // use credentials of user in AD Users group
ImpersonateLoggedOnUser();
// do what you need to do
RevertToSelf();
I tried using ADSI objects as well but got the same result. Is ADU&C doing something behind the scenes with the servers to facilitate this, or is it some API calls that I'm not doing?
Sorry, but I am not well versed in AD. You may want to search for a more
appropriate group in which to post your question.
Regards,
Will
Sorry - I should have been more plain about the user. I log on as the user
(a test id) in question to test my app (and also to test that user's rights
using Active Directory Users & Computers). Unfortunately, the only thing I
have been able to determine is that the user id has the appropriate rights
(because ADU&C can make the change) but my app still won't work, unless I'm
logged in as myself. I am a Domain Admin and therefore have so many rights
that I don't know for sure what the difference really is. But since ADU&C
can work for the test id, I would think there must be some way to do this
with my app.
Do you have any ideas as to what group might be more appropriate to post
this question to. I have looked at the huge list of Microsoft groups and
have only found this and potentially the microsoft.public.win2000.security
group that seemed to touch on this.
Thanks again.
"William DePalo [MVP VC++]" <wi***********@mvps.org> wrote in message
news:#Y*************@TK2MSFTNGP09.phx.gbl... "Stephen Engle" <en***********@aoins.com> wrote in message news:um**************@TK2MSFTNGP09.phx.gbl... The thing I can't figure out here, is why Active Directory Users and Computers can take ownership, yet my program cannot (obviously something is missing). It is a good question for which I don't have an answer. I _think_ though that you could find an answer by looking at that group and its privileges. Assuming that the code is proper, the issue is a privilege granted to a
user in the group and which is lacking in the user under whose context your application runs.
Do you have the credentials of one of the users in this group? If so, and
if you run on XP you could try this experiment:
LogonUser(); // use credentials of user in AD Users group ImpersonateLoggedOnUser();
// do what you need to do
RevertToSelf();
I tried using ADSI objects as well but got the same result. Is ADU&C doing something behind the scenes with the servers to facilitate this, or is it some API calls that I'm not doing?
Sorry, but I am not well versed in AD. You may want to search for a more appropriate group in which to post your question.
Regards, Will
"Stephen Engle" <en***********@aoins.com> wrote in message
news:uK**************@tk2msftngp13.phx.gbl... Sorry - I should have been more plain about the user. I log on as the user (a test id) in question to test my app (and also to test that user's rights using Active Directory Users & Computers). Unfortunately, the only thing I have been able to determine is that the user id has the appropriate rights (because ADU&C can make the change) but my app still won't work, unless I'm logged in as myself. I am a Domain Admin and therefore have so many rights that I don't know for sure what the difference really is. But since ADU&C can work for the test id, I would think there must be some way to do this with my app.
Do you have any ideas as to what group might be more appropriate to post this question to. I have looked at the huge list of Microsoft groups and have only found this and potentially the microsoft.public.win2000.security group that seemed to touch on this.
The two languages groups (this and m.p.vc.language) field lots of questions
on things people do with the language even though the groups' focus is
ostensibly on the language itself.
The kernel group (m.p.win32.programmer.kernel) has a similar mix of skills
among the regulars and more than a few who grok security.
Apart from the kernel group, I'd plug
activedirectory
or
adsi
into the newsgroup search edit box to find a more appropriate one. If I read
any of these groups I'd suggest one, but as I said, I don't so I can't. :-(
At the risk of stating the obvious ... are you checking the return codes
from the functions that you call? It is a really really rare event for a
function in the Win32 API to fail silently. One thing you can do is type
err
in the watch window in the debugger. This pseudo-variable is an alias for
the calling thread's last error code. When a function fails (and only if it
fails so you need to check return codes or look at the EAX register if you
forgot to capture the return) this is the place to look for the underlying
cause of the failure.
Thanks again.
You are welcome.
Regards,
Will
I have indeed been checking my return codes. The only one that fails is the
call to apply the changes back to the AD group (E_ACCESSDENIED). But thanks
for all of your help and suggestions. I will look for another place to post
and check on this.
"William DePalo [MVP VC++]" <wi***********@mvps.org> wrote in message
news:eF**************@TK2MSFTNGP15.phx.gbl... "Stephen Engle" <en***********@aoins.com> wrote in message news:uK**************@tk2msftngp13.phx.gbl... Sorry - I should have been more plain about the user. I log on as the user (a test id) in question to test my app (and also to test that user's rights using Active Directory Users & Computers). Unfortunately, the only
thing I have been able to determine is that the user id has the appropriate
rights (because ADU&C can make the change) but my app still won't work, unless I'm logged in as myself. I am a Domain Admin and therefore have so many rights that I don't know for sure what the difference really is. But since
ADU&C can work for the test id, I would think there must be some way to do
this with my app. Do you have any ideas as to what group might be more appropriate to post this question to. I have looked at the huge list of Microsoft groups
and have only found this and potentially the
microsoft.public.win2000.security group that seemed to touch on this.
The two languages groups (this and m.p.vc.language) field lots of
questions on things people do with the language even though the groups' focus is ostensibly on the language itself.
The kernel group (m.p.win32.programmer.kernel) has a similar mix of skills among the regulars and more than a few who grok security.
Apart from the kernel group, I'd plug
activedirectory
or
adsi
into the newsgroup search edit box to find a more appropriate one. If I
read any of these groups I'd suggest one, but as I said, I don't so I can't.
:-( At the risk of stating the obvious ... are you checking the return codes from the functions that you call? It is a really really rare event for a function in the Win32 API to fail silently. One thing you can do is type
err
in the watch window in the debugger. This pseudo-variable is an alias for the calling thread's last error code. When a function fails (and only if
it fails so you need to check return codes or look at the EAX register if you forgot to capture the return) this is the place to look for the underlying cause of the failure.
Thanks again.
You are welcome.
Regards, Will
"Stephen Engle" <en***********@aoins.com> wrote in message
news:e2**************@TK2MSFTNGP10.phx.gbl... I have indeed been checking my return codes. The only one that fails is the call to apply the changes back to the AD group (E_ACCESSDENIED).
Does the function that fails not detail what it requires? Is there any
possibility that it is a wild pointer problem? It it is something in wide
use, someone in the kernel group may spot the problem.
But thanks for all of your help and suggestions.
You are welcome.
Regards.
Will This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Ryan |
last post by:
We have a DTS package developed on our development PC's (SQL 7). It
runs fine. When we schedule it on the server (SQL 7), it fails. We
have been able to find that this is a known issue down to the...
|
by: tarmat |
last post by:
I've been using code such as the following, whereby I call the
constructor of a class with an object allocated on the heap. The
class is responsible for tidying up the memory.
class Base{};...
|
by: Jacob |
last post by:
I am trying to find the best way of documenting (in code and
comments) ownership of secondary contained objects. This is my
current status, and I would appreciate feedback on it:
Case 1: ...
|
by: Howard |
last post by:
Hi,
I recently had a problem where I decided to store objects in a vector.
(Previously, I had always stored pointers in vectors). Well, naturally,
when storing an object in a vector, using...
|
by: Benden Ziyade |
last post by:
Hello;
I want to write a C program that check file ownership in /bin
directory(ls, mkdir...). But I don't know how I start. I'm happy with
your helping.
|
by: Andrew |
last post by:
Apologies for the double-post.. I'm new, just getting used to this.. and
should have posted this way in the first place..
How does one go about taking ownership of a registry key using C# & .NET...
|
by: ShaiH |
last post by:
When I create a file from a simple command line application written in C# the
file ownership given to the newly created file is of administrators group
although I am running this application in my...
|
by: YellowFin Announcements |
last post by:
(Association Press) - Get ready for the next wave of business
intelligence, which will once and for all take BI mainstream, with
query, reporting, and analysis dashboards on every desktop. ...
|
by: digz |
last post by:
In the code below , a simplified version
I need to pass a smart pointer to function f which I control .I
cannot use std::auto_ptr as a parameter to f because
it releases ownership on copy...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |