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.
711 lines
20 KiB
711 lines
20 KiB
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corp., 1991 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
|
|
ShareAcl.cxx
|
|
|
|
This file contains the implementation for the Shares Acl
|
|
Editor. It is just a front end for the Generic ACL Editor that is
|
|
specific to Shares,.
|
|
|
|
FILE HISTORY:
|
|
ChuckC 06-Aug-1992 Culled from NTFSACL.CXX
|
|
Yi-HsinS 09-Oct-1992 Added ulHelpContext to EditShareAcl
|
|
Yi-HsinS 20-Nov-1992 Make ntlanman.dll link dynamically to
|
|
acledit.dll ( not statically ).
|
|
DavidHov 17-Oct-1993 Made pSedDiscretionaryEditor extern "C"
|
|
because mangling on Alpha didn't
|
|
equate to that in LIBMAIN.CXX
|
|
*/
|
|
|
|
#include <ntincl.hxx>
|
|
|
|
extern "C"
|
|
{
|
|
#include <ntioapi.h>
|
|
#include <ntseapi.h>
|
|
#include <helpnums.h>
|
|
}
|
|
|
|
|
|
#define INCL_NETCONS
|
|
#define INCL_WINDOWS
|
|
#define INCL_NETERRORS
|
|
#define INCL_DOSERRORS
|
|
#define INCL_NETSHARE
|
|
#define _WINNETWK_
|
|
#include <lmui.hxx>
|
|
#undef _WINNETWK_
|
|
|
|
#define INCL_BLT_MSGPOPUP
|
|
#include <blt.hxx>
|
|
#include <dbgstr.hxx>
|
|
|
|
#include <string.hxx>
|
|
#include <strnumer.hxx>
|
|
#include <security.hxx>
|
|
#include <ntacutil.hxx>
|
|
#include <uibuffer.hxx>
|
|
#include <strlst.hxx>
|
|
#include <errmap.hxx>
|
|
|
|
|
|
extern "C"
|
|
{
|
|
#include <sedapi.h>
|
|
#include <sharedlg.h>
|
|
#include <lmapibuf.h>
|
|
}
|
|
|
|
|
|
#include <uiassert.hxx>
|
|
#include <shareacl.hxx>
|
|
|
|
typedef DWORD (*PSEDDISCRETIONARYACLEDITOR)( HWND, HANDLE, LPWSTR,
|
|
PSED_OBJECT_TYPE_DESCRIPTOR, PSED_APPLICATION_ACCESSES,
|
|
LPWSTR, PSED_FUNC_APPLY_SEC_CALLBACK, ULONG_PTR, PSECURITY_DESCRIPTOR,
|
|
BOOLEAN, BOOLEAN, LPDWORD, DWORD );
|
|
|
|
extern HMODULE hmodAclEditor;
|
|
|
|
extern "C"
|
|
{
|
|
// BUGBUG: This needs to be in a header file so mangling will
|
|
// work properly
|
|
extern PSEDDISCRETIONARYACLEDITOR pSedDiscretionaryAclEditor;
|
|
}
|
|
|
|
#define ACLEDIT_DLL_STRING SZ("acledit.dll")
|
|
#define SEDDISCRETIONARYACLEDITOR_STRING ("SedDiscretionaryAclEditor")
|
|
/*
|
|
* declare the callback routine based on typedef in sedapi.h.
|
|
* CODEWORK - that file should declare for us!
|
|
*/
|
|
DWORD SedCallback( HWND hwndParent,
|
|
HANDLE hInstance,
|
|
ULONG_PTR ulCallbackContext,
|
|
PSECURITY_DESCRIPTOR psecdesc,
|
|
PSECURITY_DESCRIPTOR psecdescNewObjects,
|
|
BOOLEAN fApplyToSubContainers,
|
|
BOOLEAN fApplyToSubObjects,
|
|
LPDWORD StatusReturn
|
|
) ;
|
|
|
|
/*
|
|
* structure for callback function's usage.
|
|
* all we do today during callback is set the
|
|
* Dacl to be passed back to the Shared dialog,
|
|
* and set a flag to tell us if the user actually
|
|
* did anything. The flag is FALSE as long as the
|
|
* user hits cancel.
|
|
*/
|
|
typedef struct _SHARE_CALLBACK_INFO
|
|
{
|
|
OS_SECURITY_DESCRIPTOR * pOsSecDesc ;
|
|
BOOL fSecDescModified ;
|
|
} SHARE_CALLBACK_INFO ;
|
|
|
|
/*
|
|
* routine that sets up the right generic mappings
|
|
*/
|
|
void InitializeShareGenericMapping( PGENERIC_MAPPING pSHAREGenericMapping ) ;
|
|
|
|
/* The following two arrays define the permission names for NT Files. Note
|
|
* that each index in one array corresponds to the index in the other array.
|
|
* The second array will be modifed to contain a string pointer pointing to
|
|
* the corresponding IDS_* in the first array.
|
|
*/
|
|
MSGID msgidSharePermNames[] =
|
|
{
|
|
IDS_SHARE_PERM_GEN_NO_ACCESS,
|
|
IDS_SHARE_PERM_GEN_READ,
|
|
IDS_SHARE_PERM_GEN_MODIFY,
|
|
IDS_SHARE_PERM_GEN_ALL
|
|
} ;
|
|
|
|
SED_APPLICATION_ACCESS sedappaccessSharePerms[] =
|
|
{
|
|
{ SED_DESC_TYPE_RESOURCE, FILE_PERM_GEN_NO_ACCESS, 0, NULL },
|
|
{ SED_DESC_TYPE_RESOURCE, FILE_PERM_GEN_READ, 0, NULL },
|
|
{ SED_DESC_TYPE_RESOURCE, FILE_PERM_GEN_MODIFY, 0, NULL },
|
|
{ SED_DESC_TYPE_RESOURCE, FILE_PERM_GEN_ALL, 0, NULL }
|
|
} ;
|
|
|
|
#define COUNT_FILEPERMS_ARRAY (sizeof(sedappaccessSharePerms)/sizeof(SED_APPLICATION_ACCESS))
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: EditShareAcl
|
|
|
|
SYNOPSIS: This Procedure prepares the structures necessary for the
|
|
generic ACL editor, specifically for NT Shares.
|
|
|
|
ENTRY: hwndParent - Parent window handle
|
|
|
|
pszServer - Name of server the resource resides on
|
|
(in the form "\\server")
|
|
pszResource - Fully qualified name of resource we will
|
|
edit, basically a share name.
|
|
pfSecDescModified - used to return to share dialog if
|
|
the User cancelled or hit OK.
|
|
ppOsSEcDesc - pointer to pointer to OS_SECURITY_DESCRIPTOR.
|
|
*ppOsSecDesc is NULL if this is a new share or a share
|
|
without any security descriptor, in which case we create
|
|
one.
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES: We assume we are dealing with a SHARE by the time
|
|
this function is called.
|
|
|
|
HISTORY:
|
|
ChuckC 10-Aug-1992 Created. Culled from NTFS ACL code.
|
|
Yi-HsinS 09-Oct-1992 Added ulHelpContextBase
|
|
|
|
********************************************************************/
|
|
|
|
APIERR EditShareAcl( HWND hwndParent,
|
|
const TCHAR * pszServer,
|
|
const TCHAR * pszResource,
|
|
BOOL * pfSecDescModified,
|
|
OS_SECURITY_DESCRIPTOR ** ppOsSecDesc,
|
|
ULONG ulHelpContextBase )
|
|
|
|
{
|
|
UIASSERT(pszServer) ;
|
|
UIASSERT(pszResource) ;
|
|
UIASSERT(ppOsSecDesc) ;
|
|
UIASSERT(pfSecDescModified) ;
|
|
|
|
APIERR err = NERR_Success; // JonN 01/27/00: PREFIX bug 444914
|
|
|
|
do { // error breakout
|
|
|
|
/*
|
|
* if we *ppsecdesc is NULL, this is new share or a share with no
|
|
* security descriptor.
|
|
* we go and create a new (default) security descriptor.
|
|
*/
|
|
if (!*ppOsSecDesc)
|
|
{
|
|
APIERR err = ::CreateDefaultAcl(ppOsSecDesc) ;
|
|
if (err != NERR_Success)
|
|
break ;
|
|
}
|
|
|
|
/* Retrieve the resource strings appropriate for the type of object we
|
|
* are looking at
|
|
*/
|
|
RESOURCE_STR nlsTypeName( IDS_SHARE ) ;
|
|
RESOURCE_STR nlsDefaultPermName( IDS_SHARE_PERM_GEN_READ ) ;
|
|
|
|
if ( ( err = nlsTypeName.QueryError() ) ||
|
|
( err = nlsDefaultPermName.QueryError()) )
|
|
{
|
|
break ;
|
|
}
|
|
|
|
/*
|
|
* other misc stuff we need pass to security editor
|
|
*/
|
|
SED_OBJECT_TYPE_DESCRIPTOR sedobjdesc ;
|
|
SED_HELP_INFO sedhelpinfo ;
|
|
GENERIC_MAPPING SHAREGenericMapping ;
|
|
|
|
// setup mappings
|
|
InitializeShareGenericMapping( &SHAREGenericMapping ) ;
|
|
|
|
// setup help
|
|
RESOURCE_STR nlsHelpFileName( ulHelpContextBase == HC_UI_SHELL_BASE
|
|
? IDS_SHELLHELPFILENAME
|
|
: IDS_SMHELPFILENAME ) ;
|
|
if ( err = nlsHelpFileName.QueryError() )
|
|
{
|
|
DBGEOL("::EditShareAcl - Failed to retrieve help file name") ;
|
|
break ;
|
|
}
|
|
|
|
sedhelpinfo.pszHelpFileName = (LPWSTR) nlsHelpFileName.QueryPch() ;
|
|
sedhelpinfo.aulHelpContext[HC_MAIN_DLG] = ulHelpContextBase +
|
|
HC_NTSHAREPERMS ;
|
|
sedhelpinfo.aulHelpContext[HC_ADD_USER_DLG] = ulHelpContextBase +
|
|
HC_SHAREADDUSER ;
|
|
sedhelpinfo.aulHelpContext[HC_ADD_USER_MEMBERS_LG_DLG] =
|
|
ulHelpContextBase +
|
|
HC_SHAREADDUSER_LOCALGROUP ;
|
|
sedhelpinfo.aulHelpContext[HC_ADD_USER_MEMBERS_GG_DLG] =
|
|
ulHelpContextBase +
|
|
HC_SHAREADDUSER_GLOBALGROUP ;
|
|
sedhelpinfo.aulHelpContext[HC_ADD_USER_SEARCH_DLG] =
|
|
ulHelpContextBase +
|
|
HC_SHAREADDUSER_FINDUSER ;
|
|
|
|
// These are not used, set to zero
|
|
sedhelpinfo.aulHelpContext[HC_SPECIAL_ACCESS_DLG] = 0 ;
|
|
sedhelpinfo.aulHelpContext[HC_NEW_ITEM_SPECIAL_ACCESS_DLG] = 0 ;
|
|
|
|
// setup the object description
|
|
sedobjdesc.Revision = SED_REVISION1 ;
|
|
sedobjdesc.IsContainer = FALSE ;
|
|
sedobjdesc.AllowNewObjectPerms = FALSE ;
|
|
sedobjdesc.MapSpecificPermsToGeneric = TRUE ;
|
|
sedobjdesc.GenericMapping = &SHAREGenericMapping ;
|
|
sedobjdesc.GenericMappingNewObjects = &SHAREGenericMapping ;
|
|
sedobjdesc.HelpInfo = &sedhelpinfo ;
|
|
sedobjdesc.ObjectTypeName = (LPTSTR)nlsTypeName.QueryPch();
|
|
sedobjdesc.SpecialObjectAccessTitle = NULL ;
|
|
|
|
/* Now we need to load the global arrays with the permission names
|
|
* from the resource file.
|
|
*/
|
|
UINT cArrayItems = COUNT_FILEPERMS_ARRAY ;
|
|
MSGID * msgidPermNames = msgidSharePermNames ;
|
|
PSED_APPLICATION_ACCESS pappaccess = sedappaccessSharePerms ;
|
|
|
|
/* Loop through each permission title retrieving the text from the
|
|
* resource file and setting the pointer in the array. The memory
|
|
* will be deleted when strlistPermNames is destructed.
|
|
*/
|
|
STRLIST strlistPermNames ;
|
|
for ( UINT i = 0 ; i < cArrayItems ; i++ )
|
|
{
|
|
RESOURCE_STR * pnlsPermName = new RESOURCE_STR( msgidPermNames[i]) ;
|
|
err = (pnlsPermName==NULL) ? ERROR_NOT_ENOUGH_MEMORY :
|
|
pnlsPermName->QueryError() ;
|
|
if ( err ||
|
|
(err = strlistPermNames.Add( pnlsPermName )) )
|
|
{
|
|
delete pnlsPermName ;
|
|
break ;
|
|
}
|
|
pappaccess[i].PermissionTitle = (LPTSTR) pnlsPermName->QueryPch() ;
|
|
}
|
|
if ( err )
|
|
break ;
|
|
|
|
SED_APPLICATION_ACCESSES SedAppAccesses ;
|
|
SedAppAccesses.Count = cArrayItems ;
|
|
SedAppAccesses.AccessGroup = pappaccess ;
|
|
SedAppAccesses.DefaultPermName = (LPTSTR)nlsDefaultPermName.QueryPch() ;
|
|
|
|
DWORD dwSedReturnStatus ;
|
|
|
|
/*
|
|
* pass this along so when the call back function is called,
|
|
* we can set it.
|
|
*/
|
|
SHARE_CALLBACK_INFO callbackinfo ;
|
|
callbackinfo.pOsSecDesc = *ppOsSecDesc ;
|
|
callbackinfo.fSecDescModified = FALSE ;
|
|
|
|
if ( ::hmodAclEditor == NULL )
|
|
{
|
|
::hmodAclEditor = ::LoadLibraryEx( ACLEDIT_DLL_STRING,
|
|
NULL,
|
|
LOAD_WITH_ALTERED_SEARCH_PATH );
|
|
if ( ::hmodAclEditor == NULL )
|
|
{
|
|
err = ::GetLastError();
|
|
break;
|
|
}
|
|
|
|
::pSedDiscretionaryAclEditor = (PSEDDISCRETIONARYACLEDITOR)
|
|
::GetProcAddress( ::hmodAclEditor,
|
|
SEDDISCRETIONARYACLEDITOR_STRING );
|
|
if ( ::pSedDiscretionaryAclEditor == NULL )
|
|
{
|
|
err = ::GetLastError();
|
|
break;
|
|
}
|
|
}
|
|
|
|
UIASSERT( ::pSedDiscretionaryAclEditor != NULL );
|
|
|
|
err = (*pSedDiscretionaryAclEditor)( hwndParent,
|
|
NULL, // dont need instance
|
|
(LPWSTR) pszServer,
|
|
&sedobjdesc,
|
|
&SedAppAccesses,
|
|
(LPWSTR) pszResource,
|
|
(PSED_FUNC_APPLY_SEC_CALLBACK) SedCallback,
|
|
(ULONG_PTR) &callbackinfo,
|
|
(*ppOsSecDesc)->QueryDescriptor(),
|
|
FALSE, // always can read
|
|
FALSE, // If we can read, we can write
|
|
&dwSedReturnStatus,
|
|
0 ) ;
|
|
|
|
if (err)
|
|
break ;
|
|
|
|
*pfSecDescModified = callbackinfo.fSecDescModified ;
|
|
|
|
} while (FALSE) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SedCallback
|
|
|
|
SYNOPSIS: Security Editor callback for the SHARE ACL Editor
|
|
|
|
ENTRY: See sedapi.hxx
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES: Normally, the callback is expected to perform the 'apply'.
|
|
In this case, since the object may not exist yet, we defer
|
|
the 'apply' till the user hits OK in the Shares dialog.
|
|
All the CallBack does is simply save away that precious
|
|
modified ACL in the OS_SECURITY_DESCRIPTOR object we were
|
|
given in the first place.
|
|
|
|
HISTORY:
|
|
ChuckC 10-Aug-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
|
|
DWORD SedCallback( HWND hwndParent,
|
|
HANDLE hInstance,
|
|
ULONG_PTR ulCallbackContext,
|
|
PSECURITY_DESCRIPTOR psecdesc,
|
|
PSECURITY_DESCRIPTOR psecdescNewObjects,
|
|
BOOLEAN fApplyToSubContainers,
|
|
BOOLEAN fApplyToSubObjects,
|
|
LPDWORD StatusReturn
|
|
)
|
|
{
|
|
UNREFERENCED( hInstance ) ;
|
|
UNREFERENCED( psecdescNewObjects ) ;
|
|
UNREFERENCED( fApplyToSubObjects ) ;
|
|
UNREFERENCED( fApplyToSubContainers ) ;
|
|
UNREFERENCED( StatusReturn ) ;
|
|
|
|
APIERR err = NO_ERROR ;
|
|
OS_SECURITY_DESCRIPTOR * pOsSecDesc =
|
|
((SHARE_CALLBACK_INFO *)ulCallbackContext)->pOsSecDesc ;
|
|
|
|
do { // error breakout loop
|
|
|
|
OS_SECURITY_DESCRIPTOR osNewSecDesc (psecdesc) ;
|
|
if (err = osNewSecDesc.QueryError())
|
|
break ;
|
|
|
|
BOOL fDaclPresent ;
|
|
OS_ACL * pOsDacl ;
|
|
if (err = osNewSecDesc.QueryDACL(&fDaclPresent, &pOsDacl))
|
|
break ;
|
|
|
|
// set the new DACL
|
|
err = pOsSecDesc->SetDACL(TRUE, pOsDacl) ;
|
|
|
|
} while (FALSE) ;
|
|
|
|
if ( err )
|
|
::MsgPopup( hwndParent, (MSGID) err ) ;
|
|
else
|
|
((SHARE_CALLBACK_INFO *)ulCallbackContext)->fSecDescModified = TRUE ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: InitializeShareGenericMapping
|
|
|
|
SYNOPSIS: Initializes the passed generic mapping structure
|
|
for shares
|
|
|
|
ENTRY: pSHAREGenericMapping - Pointer to GENERIC_MAPPING to be init.
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES: There currently is no public definition, replace if one
|
|
ever becomes available.
|
|
|
|
HISTORY:
|
|
ChuckC 10-Aug-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
void InitializeShareGenericMapping( PGENERIC_MAPPING pSHAREGenericMapping )
|
|
{
|
|
pSHAREGenericMapping->GenericRead = FILE_GENERIC_READ ;
|
|
pSHAREGenericMapping->GenericWrite = FILE_GENERIC_WRITE ;
|
|
pSHAREGenericMapping->GenericExecute = FILE_GENERIC_EXECUTE ;
|
|
pSHAREGenericMapping->GenericAll = FILE_ALL_ACCESS ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CreateDefaultAcl
|
|
|
|
SYNOPSIS: Create a default ACL for either a new share or for
|
|
a share that dont exist.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS: NERR_Success if OK, api error otherwise.
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
ChuckC 10-Aug-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
APIERR CreateDefaultAcl( OS_SECURITY_DESCRIPTOR ** ppOsSecDesc )
|
|
{
|
|
UIASSERT(ppOsSecDesc) ;
|
|
|
|
APIERR err ;
|
|
OS_ACL aclDacl ;
|
|
OS_ACE osace ;
|
|
OS_SECURITY_DESCRIPTOR * pOsSecDesc ;
|
|
|
|
*ppOsSecDesc = NULL ; // empty it.
|
|
|
|
do
|
|
{ // error breakout
|
|
|
|
/*
|
|
* make sure we constructed OK
|
|
*/
|
|
if ( (err = aclDacl.QueryError()) ||
|
|
(err = osace.QueryError()) )
|
|
{
|
|
break ;
|
|
}
|
|
|
|
/*
|
|
* create it! use NULL to mean we build it ourselves.
|
|
*/
|
|
pOsSecDesc = new OS_SECURITY_DESCRIPTOR(NULL) ;
|
|
if (pOsSecDesc == NULL)
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
if (err = pOsSecDesc->QueryError())
|
|
{
|
|
break ;
|
|
}
|
|
|
|
/*
|
|
* This sets up an ACE with Generic all access
|
|
*/
|
|
osace.SetAccessMask( GENERIC_ALL ) ;
|
|
osace.SetInheritFlags( 0 ) ;
|
|
osace.SetType( ACCESS_ALLOWED_ACE_TYPE ) ;
|
|
|
|
#if 0
|
|
//
|
|
// The server should set the owner/group before we get the security
|
|
// descriptor so we don't need to do this anymore
|
|
//
|
|
|
|
/*
|
|
* now set the group and owner to be the Administrators.
|
|
* need create Adminstrators SID.
|
|
*/
|
|
OS_SID ossidBuiltin ;
|
|
if (err = NT_ACCOUNTS_UTILITY::QuerySystemSid( UI_SID_BuiltIn,
|
|
&ossidBuiltin ))
|
|
{
|
|
break ;
|
|
}
|
|
OS_SID ossidAdmin (ossidBuiltin.QueryPSID(),
|
|
(ULONG)DOMAIN_ALIAS_RID_ADMINS) ;
|
|
if (err = ossidAdmin.QueryError())
|
|
break ;
|
|
|
|
if ( (err = pOsSecDesc->SetGroup( ossidAdmin, TRUE )) ||
|
|
(err = pOsSecDesc->SetOwner( ossidAdmin, TRUE )) )
|
|
{
|
|
break ;
|
|
}
|
|
#endif
|
|
/*
|
|
* create a world SID, and add this to the full access ACE.
|
|
* then put the ACE in the ACL, and the ACL in the Security
|
|
* descriptor.
|
|
*/
|
|
OS_SID ossidWorld ;
|
|
if ( (err = ossidWorld.QueryError()) ||
|
|
(err = NT_ACCOUNTS_UTILITY::QuerySystemSid(
|
|
UI_SID_World,
|
|
&ossidWorld )) ||
|
|
(err = osace.SetSID( ossidWorld )) ||
|
|
(err = aclDacl.AddACE( 0, osace )) ||
|
|
(err = pOsSecDesc->SetDACL( TRUE, &aclDacl )) )
|
|
{
|
|
break ;
|
|
}
|
|
|
|
/*
|
|
* all set, set the security descriptor
|
|
*/
|
|
*ppOsSecDesc = pOsSecDesc ;
|
|
|
|
} while (FALSE) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: GetSharePerm
|
|
|
|
SYNOPSIS: CAll the NETAPI to retrieve existing Security Descriptor
|
|
from the Share.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS: NERR_Success if OK, api error otherwise.
|
|
|
|
NOTES: CODEWORK. This should be a LMOBJ thing when we have time.
|
|
Currently just direct call to NETAPI.
|
|
|
|
HISTORY:
|
|
ChuckC 10-Aug-1992 Created
|
|
|
|
********************************************************************/
|
|
APIERR GetSharePerm (const TCHAR * pszServer,
|
|
const TCHAR * pszShare,
|
|
OS_SECURITY_DESCRIPTOR ** ppOsSecDesc )
|
|
{
|
|
#ifndef WIN32
|
|
#error This is currently NOT 16 bit compatible.
|
|
#endif
|
|
APIERR err ;
|
|
LPBYTE pBuffer ;
|
|
PSECURITY_DESCRIPTOR psecdesc ;
|
|
OS_SECURITY_DESCRIPTOR * pOsSecDesc ;
|
|
|
|
/*
|
|
* call API to get the security descriptor
|
|
*/
|
|
err = NetShareGetInfo((LPTSTR) pszServer,
|
|
(LPTSTR) pszShare,
|
|
502,
|
|
&pBuffer) ;
|
|
if (err != NERR_Success)
|
|
return err ;
|
|
|
|
if (*ppOsSecDesc)
|
|
delete *ppOsSecDesc ;
|
|
*ppOsSecDesc = NULL ;
|
|
|
|
/*
|
|
* if no such thang, just say none. we'll create later as need.
|
|
*/
|
|
psecdesc = ((SHARE_INFO_502 *)pBuffer)->shi502_security_descriptor ;
|
|
if (!psecdesc)
|
|
{
|
|
NetApiBufferFree(pBuffer) ;
|
|
return NERR_Success ;
|
|
}
|
|
|
|
do { // error break out loop
|
|
|
|
// create a new security descriptor
|
|
pOsSecDesc = new OS_SECURITY_DESCRIPTOR(NULL) ;
|
|
if (pOsSecDesc == NULL)
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
if (err = pOsSecDesc->QueryError())
|
|
{
|
|
break ;
|
|
}
|
|
|
|
/*
|
|
* create alias to the security descriptor we go from the API
|
|
*/
|
|
OS_SECURITY_DESCRIPTOR osShareSecDesc (psecdesc) ;
|
|
if (err = osShareSecDesc.QueryError())
|
|
break ;
|
|
|
|
/*
|
|
* make copy of it for use by security editor
|
|
*/
|
|
if ( (err = pOsSecDesc->Copy( osShareSecDesc )) )
|
|
{
|
|
break ;
|
|
}
|
|
|
|
} while (FALSE) ;
|
|
|
|
if (err == NERR_Success)
|
|
*ppOsSecDesc = pOsSecDesc ;
|
|
|
|
NetApiBufferFree(pBuffer) ;
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SetSharePerm
|
|
|
|
SYNOPSIS: CAll the NETAPI to set the Security Descriptor
|
|
for the Share.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS: NERR_Success if OK, api error otherwise.
|
|
|
|
NOTES: CODEWORK. This should be a LMOBJ thing when we have time.
|
|
Currently just direct call to NETAPI.
|
|
|
|
HISTORY:
|
|
ChuckC 10-Aug-1992 Created
|
|
|
|
********************************************************************/
|
|
APIERR SetSharePerm (const TCHAR * pszServer,
|
|
const TCHAR * pszShare,
|
|
const OS_SECURITY_DESCRIPTOR * pOsSecDesc )
|
|
{
|
|
#ifndef WIN32
|
|
#error This is currently NOT 16 bit compatible.
|
|
#endif
|
|
APIERR err ;
|
|
SHARE_INFO_1501 shareinfo1501 ;
|
|
::ZeroMemory(&shareinfo1501,
|
|
sizeof(shareinfo1501)); // JonN 01/27/00: PREFIX bug 444913
|
|
|
|
shareinfo1501.shi1501_security_descriptor =
|
|
pOsSecDesc->QueryDescriptor() ;
|
|
|
|
/*
|
|
* call API to get the security descriptor
|
|
*/
|
|
err = NetShareSetInfo((LPTSTR) pszServer,
|
|
(LPTSTR) pszShare,
|
|
1501,
|
|
(LPBYTE)&shareinfo1501,
|
|
NULL) ;
|
|
|
|
return err ;
|
|
}
|