Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

295 lines
8.0 KiB

//
// Copyright (C) 2000-2002, Microsoft Corporation
//
// File: Adsecurity.c
//
// Contents: miscellaneous dfs functions.
//
// History: April 16 2002, Author: Rohanp
//
//-----------------------------------------------------------------------------
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <dsgetdc.h>
#include <lm.h>
#include <dfsheader.h>
#include <dfsmisc.h>
#include <shellapi.h>
#include <ole2.h>
#include <activeds.h>
#include <sddl.h>
#include <WinLdap.h>
#include <NtLdap.h>
#include <ntdsapi.h>
#include <dfssecurity.h>
#include "securitylogmacros.hxx"
#include "adsecurity.tmh"
#define ACTRL_SD_PROP_NAME L"nTSecurityDescriptor"
#define DFS_DS_GENERIC_READ ( DS_GENERIC_READ & ~ACTRL_DS_LIST_OBJECT )
#define DFS_DS_GENERIC_WRITE ( DS_GENERIC_WRITE )
#define DFS_DS_GENERIC_EXECUTE ( DS_GENERIC_EXECUTE )
#define DFS_DS_GENERIC_ALL ( DS_GENERIC_ALL & ~ACTRL_DS_LIST_OBJECT )
GENERIC_MAPPING DfsAdAdminGenericMapping = {
DFS_DS_GENERIC_READ, // Generic read
DFS_DS_GENERIC_WRITE, // Generic write
DFS_DS_GENERIC_EXECUTE,
DFS_DS_GENERIC_ALL
};
DFSSTATUS
DfsReadDSObjSecDesc(
LDAP * pLDAP,
PWSTR pwszObject,
SECURITY_INFORMATION SeInfo,
PSECURITY_DESCRIPTOR *ppSD,
PULONG pcSDSize)
{
DFSSTATUS Status = ERROR_SUCCESS;
PLDAPMessage pMsg = NULL;
LDAPMessage *pEntry = NULL;
PWSTR *ppwszValues = NULL;
PLDAP_BERVAL *pSize = NULL;
PWSTR rgAttribs[2];
BYTE berValue[8];
LDAPControl SeInfoControl =
{
LDAP_SERVER_SD_FLAGS_OID_W,
{
5, (PCHAR)berValue
},
TRUE
};
PLDAPControl ServerControls[2] =
{
&SeInfoControl,
NULL
};
berValue[0] = 0x30;
berValue[1] = 0x03;
berValue[2] = 0x02;
berValue[3] = 0x01;
berValue[4] = (BYTE)((ULONG)SeInfo & 0xF);
rgAttribs[0] = ACTRL_SD_PROP_NAME;
rgAttribs[1] = NULL;
Status = ldap_search_ext_s(
pLDAP,
pwszObject,
LDAP_SCOPE_BASE,
L"(objectClass=*)",
rgAttribs,
0,
(PLDAPControl *)ServerControls,
NULL,
NULL,
10000,
&pMsg);
Status = LdapMapErrorToWin32( Status );
if(Status == ERROR_SUCCESS)
{
pEntry = ldap_first_entry(pLDAP, pMsg);
if(pEntry == NULL)
{
Status = LdapMapErrorToWin32( pLDAP->ld_errno );
}
else
{
//
// Now, we'll have to get the values
//
ppwszValues = ldap_get_values(pLDAP, pEntry, rgAttribs[0]);
if(ppwszValues != NULL)
{
pSize = ldap_get_values_len(pLDAP, pMsg, rgAttribs[0]);
if(pSize != NULL)
{
//
// Allocate the security descriptor to return
//
*ppSD = (PSECURITY_DESCRIPTOR)DfsAllocateSecurityData((*pSize)->bv_len);
if(*ppSD != NULL)
{
memcpy(*ppSD, (PBYTE)(*pSize)->bv_val, (*pSize)->bv_len);
*pcSDSize = (*pSize)->bv_len;
}
else
{
Status = ERROR_NOT_ENOUGH_MEMORY;
}
ldap_value_free_len(pSize);
}
else
{
Status = LdapMapErrorToWin32( pLDAP->ld_errno );
}
ldap_value_free(ppwszValues);
}
else
{
Status = LdapMapErrorToWin32( pLDAP->ld_errno );
}
}
}
if (pMsg != NULL)
{
ldap_msgfree(pMsg);
}
return(Status);
}
//+---------------------------------------------------------------------------
//
// Function: DfsGetObjSecurity
//
// Synopsis: Gets the ACL list of an object in sddl stringized form
//
// Arguments: [pldap] -- The open LDAP connection
// [wszObjectName] -- The fully-qualified name of the DS object
// [pwszStringSD] -- Pointer to pointer to SD in string form (sddl)
//
// Returns: ERROR_SUCCESS -- The object is reachable
//
//----------------------------------------------------------------------------
DFSSTATUS
DfsGetObjSecurity(LDAP *pldap,
LPWSTR pwszObjectName,
PSECURITY_DESCRIPTOR * pSDRet)
{
DFSSTATUS Status = 0;
PSECURITY_DESCRIPTOR pSD = NULL;
ULONG cSDSize = 0;
SECURITY_INFORMATION si;
//get everything we can think of
// si = ( DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |
// GROUP_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION |
// PROTECTED_SACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION |
// UNPROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION);
si = ( DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION);
Status = DfsReadDSObjSecDesc(
pldap,
pwszObjectName,
si,
&pSD,
&cSDSize);
if(Status == ERROR_SUCCESS)
{
*pSDRet = pSD;
}
return Status;
}
DFSSTATUS
DfsChangeDSObjSecDesc(LDAP * pLDAP,
PWSTR ObjectName,
PSECURITY_DESCRIPTOR pSecurityDescriptor,
SECURITY_INFORMATION SeInfo)
{
DFSSTATUS Status = 0;
PLDAPMod rgMods[2];
PLDAP_BERVAL pBVals[2];
LDAPMod Mod;
LDAP_BERVAL BVal;
BYTE berValue[8];
LDAPControl SeInfoControl =
{
LDAP_SERVER_SD_FLAGS_OID_W,
{
5, (PCHAR)berValue
},
TRUE
};
PLDAPControl ServerControls[2] =
{
&SeInfoControl,
NULL
};
berValue[0] = 0x30;
berValue[1] = 0x03;
berValue[2] = 0x02;
berValue[3] = 0x01;
berValue[4] = (BYTE)((ULONG)SeInfo & 0xF);
rgMods[0] = &Mod;
rgMods[1] = NULL;
pBVals[0] = &BVal;
pBVals[1] = NULL;
Mod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
Mod.mod_type = ACTRL_SD_PROP_NAME;
Mod.mod_values = (PWSTR *)pBVals;
if ( pSecurityDescriptor == NULL )
BVal.bv_len = 0;
else
{
BVal.bv_len = RtlLengthSecurityDescriptor(pSecurityDescriptor);
}
BVal.bv_val = (PCHAR)(pSecurityDescriptor);
Status = ldap_modify_ext_s(pLDAP,
ObjectName,
rgMods,
(PLDAPControl *)ServerControls,
NULL);
return Status;
}
DFSSTATUS
DfsDoesUserHaveDesiredAccessToAd(DWORD DesiredAccess,
PSECURITY_DESCRIPTOR pSD)
{
DFSSTATUS Status = 0;
DWORD dwDesiredAccess = DesiredAccess;
MapGenericMask(&dwDesiredAccess, &DfsAdAdminGenericMapping);
Status = AccessImpersonateCheckRpcClientEx(pSD,
&DfsAdAdminGenericMapping,
dwDesiredAccess);
return Status;
}