/*++ Copyright (c) 1992-1993 Microsoft Corporation Module Name: ExpSet.c Abstract: This file contains NetrReplExportDirSetInfo. Author: John Rogers (JohnRo) 08-Jan-1992 Environment: Runs under Windows NT. Requires ANSI C extensions: slash-slash comments, long external names. Revision History: 08-Jan-1992 JohnRo Created. 09-Jan-1992 JohnRo PC-LINT found a bug. 20-Jan-1992 JohnRo Changed prototype to match MIDL requirements. 24-Jan-1992 JohnRo Changed to use LPTSTR etc. 15-Mar-1992 JohnRo Update registry with new values. Use improved setinfo support from ExpDir.h. 22-Jul-1992 JohnRo RAID 2252: repl should prevent export on Windows/NT. Added debug output. 26-Aug-1992 JohnRo RAID 3602: NetReplExportDirSetInfo fails regardless of svc status. 29-Sep-1992 JohnRo RAID 7962: Repl APIs in wrong role kill svc. Fix remote repl admin. 30-Dec-1992 JohnRo RAID 5340: NetReplExportDirSetInfo is confused (when role=import). 05-Apr-1993 JohnRo Use NetpKdPrint() where possible. Made some changes suggested by PC-LINT 5.0 --*/ // These must be included first: #include // IN, VOID, LPTSTR, etc. #include // NET_API_STATUS, PARM equates, etc. #include // IF_DEBUG(), etc. #include // LPMASTER_LIST_REC. #include // Needed by . // These can be in any order: #include // ReplDirNamesMatch(), ReplIsDirNameValid(). #include // ExportDirIsLevelValid(), etc. #include // ERROR_ and NERR_ equates; NO_ERROR. #include // LPREPL_EDIR_INFO_1, REPL_EXTENT_ stuff, etc. #include // GetMasterRec(). #include // NetpKdPrint(), FORMAT_ equates, etc. #include // NetpSetParmError(). #include // ACQUIRE_LOCK_SHARED(), RELEASE_LOCK(). #include // PREFIX_ equates. #include // My prototype (in MIDL-generated .h file). #include // ReplConfigLock, ReplConfigRole. #include // NetpImpersonateClient(), NetpRevertToSelf(). NET_API_STATUS NetrReplExportDirSetInfo ( IN LPTSTR UncServerName OPTIONAL, IN LPTSTR DirName, IN DWORD Level, IN LPEXPORT_CONTAINER Buf, // RPC container (union) OUT LPDWORD ParmError OPTIONAL // name used by NetpSetParmError() macro. ) /*++ Routine Description: Same as NetReplExportDirSetInfo. Arguments: Same as NetReplExportDirSetInfo. Return Value: Same as NetReplExportDirSetInfo. --*/ { NET_API_STATUS ApiStatus; BOOL ConfigLocked = FALSE; BOOL Impersonated = FALSE; BOOL ListLocked = FALSE; LPMASTER_LIST_REC MasterRecord; LPVOID PossibleRec; IF_DEBUG( EXPAPI ) { NetpKdPrint(( PREFIX_REPL "NetrReplExportDirSetInfo: union at " FORMAT_LPVOID ".\n", (LPVOID) Buf )); } // // Check for caller errors. // NetpSetParmError( PARM_ERROR_UNKNOWN ); // Assume error until proven... if (Buf == NULL) { NetpKdPrint(( PREFIX_REPL "NetrReplExportDirSetInfo: null buffer pointer.\n" )); return (ERROR_INVALID_PARAMETER); } PossibleRec = (LPVOID) (Buf->Info0); // BUGBUG: nonportable? if (ReplIsDirNameValid( DirName ) == FALSE) { NetpKdPrint(( PREFIX_REPL "NetrReplExportDirSetInfo: dir name parm invalid.\n" )); return (ERROR_INVALID_PARAMETER); } else if ( !ExportDirIsLevelValid( Level, TRUE ) ) { NetpKdPrint(( PREFIX_REPL "NetrReplExportDirSetInfo: " "bad info level (before switch).\n" )); return (ERROR_INVALID_LEVEL); } else if ( !ExportDirIsApiRecordValid( Level, PossibleRec, ParmError ) ) { NetpKdPrint(( PREFIX_REPL "NetrReplExportDirSetInfo: api record invalid (parm error " FORMAT_DWORD ".\n", (ParmError!=NULL) ? (*ParmError) : PARM_ERROR_UNKNOWN )); return (ERROR_INVALID_PARAMETER); } // // Impersonate caller, so security check (write to registry) reflects // the client's process, not the repl service process. // ApiStatus = NetpImpersonateClient(); if (ApiStatus != NO_ERROR) { goto Cleanup; } Impersonated = TRUE; // // Get a shared lock on config data so we can see if role includes export. // ACQUIRE_LOCK_SHARED( ReplConfigLock ); ConfigLocked = TRUE; // // Handle entire API if this half isn't running. // if ( !ReplRoleIncludesExport( ReplConfigRole ) ) { ApiStatus = ExportDirConfigSetInfo ( UncServerName, DirName, Level, PossibleRec, ParmError ); goto Cleanup; } // // Get read-write lock on master list. // ACQUIRE_LOCK( RMGlobalListLock ); ListLocked = TRUE; // // Find the master record for this dir name. // MasterRecord = GetMasterRec( DirName ); if (MasterRecord == NULL) { // Not found. ApiStatus = NERR_UnknownDevDir; goto Cleanup; // Don't forget to release lock... } else { // Found. switch (Level) { case 1 : { LPREPL_EDIR_INFO_1 ApiRecord = PossibleRec; if ( !ReplDirNamesMatch(ApiRecord->rped1_dirname, DirName) ) { // dir name argument must match one in ApiRecord. NetpSetParmError( 1 ); // Error in first field. ApiStatus = ERROR_INVALID_PARAMETER; NetpKdPrint(( PREFIX_REPL "NetrReplExportDirSetInfo: " "dir names do not match.\n" )); } else { // // Write to registry and do security check. // ApiStatus = ExportDirWriteConfigData ( UncServerName, ApiRecord->rped1_dirname, ApiRecord->rped1_integrity, ApiRecord->rped1_extent, MasterRecord->lockcount, MasterRecord->time_of_first_lock ); if (ApiStatus == NO_ERROR) { MasterRecord->integrity = ApiRecord->rped1_integrity; MasterRecord->extent = ApiRecord->rped1_extent; NetpSetParmError( PARM_ERROR_NONE ); } } } goto Cleanup; // Don't forget to release lock... case REPL_EXPORT_INTEGRITY_INFOLEVEL : { DWORD NewIntegrity = * (LPDWORD) (LPVOID) PossibleRec; // // Write to registry and do security check. // ApiStatus = ExportDirWriteConfigData ( UncServerName, MasterRecord->dir_name, NewIntegrity, MasterRecord->extent, MasterRecord->lockcount, MasterRecord->time_of_first_lock ); if (ApiStatus == NO_ERROR) { MasterRecord->integrity = NewIntegrity; NetpSetParmError( PARM_ERROR_NONE ); } } goto Cleanup; // Don't forget to release lock... case REPL_EXPORT_EXTENT_INFOLEVEL : { DWORD NewExtent = * (LPDWORD) (LPVOID) PossibleRec; // // Write to registry and do security check. // ApiStatus = ExportDirWriteConfigData ( UncServerName, MasterRecord->dir_name, MasterRecord->integrity, NewExtent, MasterRecord->lockcount, MasterRecord->time_of_first_lock ); if (ApiStatus == NO_ERROR) { MasterRecord->extent = NewExtent; NetpSetParmError( PARM_ERROR_NONE ); } } goto Cleanup; // Don't forget to release lock... default : ApiStatus = ERROR_INVALID_LEVEL; NetpKdPrint(( PREFIX_REPL "NetrReplExportDirSetInfo: invalid level (switch).\n" )); goto Cleanup; // Don't forget to release lock... } /*NOTREACHED*/ } Cleanup: // // Release locks and tell caller how everything went. // if (ListLocked) { RELEASE_LOCK( RMGlobalListLock ); } if (ConfigLocked) { RELEASE_LOCK( ReplConfigLock ); } if (Impersonated) { (VOID) NetpRevertToSelf(); } IF_DEBUG( EXPAPI ) { NetpKdPrint(( PREFIX_REPL "NetrReplExportDirSetInfo: exiting, status: " FORMAT_API_STATUS ".\n", ApiStatus )); } return (ApiStatus); }