diff options
Diffstat (limited to 'private/net/svcdlls/rpl/server/setup.c')
-rw-r--r-- | private/net/svcdlls/rpl/server/setup.c | 716 |
1 files changed, 716 insertions, 0 deletions
diff --git a/private/net/svcdlls/rpl/server/setup.c b/private/net/svcdlls/rpl/server/setup.c new file mode 100644 index 000000000..36ee21738 --- /dev/null +++ b/private/net/svcdlls/rpl/server/setup.c @@ -0,0 +1,716 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + setup.c + +Abstract: + + Setup primitives + +Author: + + Jon Newman (jonn) 01-April-1994 + +Revision History: + + Jon Newman (jonn) 01 - April - 1994 + Added RplPolicy primitives + +--*/ + + +#include "local.h" +#include "rpldb.h" // Call(), CallM() +#include "db.h" // ConfigGetField() +#include "dblib.h" // RplFilterFirst() +#include "wksta.h" // WKSTA_WkstaName +#include "profile.h" // PROFILE_ProfileName +#include "setup.h" +#include "config.h" +#include "lmwksta.h" // NetWkstaGetInfo + +#define RPLDISK_SYS L"BBLOCK\\RPLDISK.SYS" +#define RPLDISK_OLD L"BBLOCK\\RPLDISK.OLD" +#define RPLDISK_NEW L"RPLDISK.NEW" + + + +BOOL FileExists( const WCHAR * FileToFind, DWORD * ErrorPtr) +/*++ + +Routine Description: + + This function checks whether the file exists. + +Arguments: + + +Return Value: + TRUE iff file exists + +--*/ +{ + BOOL BoolFileFound = FALSE; + DWORD TempError; + + if ( ErrorPtr == NULL ) + ErrorPtr = &TempError; + + *ErrorPtr = NO_ERROR; + + if (0xFFFFFFFF == GetFileAttributes( FileToFind )) { + *ErrorPtr = GetLastError(); + switch (*ErrorPtr) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + break; + case NO_ERROR: + default: + RplDump( ++RG_Assert, ( "*ErrorPtr=%d", *ErrorPtr)); + break; + } + } else { + BoolFileFound = TRUE; + } + + return( BoolFileFound); +} + + +DWORD RplReplaceRPLDISK( VOID) +/*++ + +Routine Description: + + This function checks whether the file RPLDISK.SYS has + been replaced with the newer version, and if not, + replaces it. + +Arguments: + +Return Value: + +--*/ +{ + DWORD Error = NO_ERROR; + WCHAR RpldiskBuffer[ MAX_PATH ]; + WCHAR SourceBuffer[ MAX_PATH ]; + WCHAR BackupBuffer[ MAX_PATH ]; + + RPL_ASSERT( RG_DirectoryLength == wcslen(RG_Directory) + && RG_DirectoryLength != 0 + && (RG_DirectoryLength + wcslen(RPLDISK_OLD)) < MAX_PATH ); + + wcscpy( RpldiskBuffer, RG_Directory ); + wcscat( RpldiskBuffer, RPLDISK_SYS ); + + wcscpy( SourceBuffer, RG_Directory ); + wcscat( SourceBuffer, RPLDISK_NEW ); + + // + // Make sure source file exists + // + + if (!FileExists(SourceBuffer, &Error)) { + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + wcscpy( BackupBuffer, RG_Directory ); + wcscat( BackupBuffer, RPLDISK_OLD ); + + // + // Copy existing RPLDISK.SYS to RPLDISK.OLD, on a best-effort basis + // + (void) CopyFile( RpldiskBuffer, BackupBuffer, FALSE ); + + // + // Copy the new RPLDISK.SYS + // + if (!CopyFile( SourceBuffer, RpldiskBuffer, FALSE )) { + Error = GetLastError(); + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + +cleanup: + + if (Error != NO_ERROR) { + RplReportEvent( NELOG_RplReplaceRPLDISK, NULL, sizeof(DWORD), &Error ); + } + + return( Error); +} + +#define LANMANINI_BINFILES L"RPLFILES\\BINFILES\\LANMAN.DOS\\LANMAN.INI" +#define LANMANINI_CONFIGSDOS L"RPLFILES\\CONFIGS\\DOS\\LANMAN.DOS\\LANMAN.INI" +#define LANMANINI_PROFILES L"RPLFILES\\PROFILES\\%ws\\LANMAN.DOS\\LANMAN.INI" +#define LANMANINI_WKSTAS L"RPLFILES\\MACHINES\\%ws\\%ws\\PRO\\LANMAN.DOS\\LANMAN.INI" +#define LANMANINI_SECTION L"WORKSTATION" +#define LANMANINI_KEY L"DOMAIN" + + +DWORD RplProcessLanmanInis( VOID ) +/*++ + +Routine Description: + + This function changes the "domain =" line in every LANMAN.INI + +Arguments: + +Return Value: + error code + +--*/ +{ + DWORD Error; + WCHAR achFile[ MAX_PATH ]; + WKSTA_INFO_100 * pw100 = NULL; + WCHAR * pwszDomainName = NULL; + PRPL_SESSION pSession = &RG_ApiSession; + BOOL InCritSec = FALSE; + BOOL InEnumeration = FALSE; + INT SpaceLeft; + BOOL TableEnd = TRUE; + WCHAR * EnumProfileName = NULL; + WCHAR * EnumWkstaName = NULL; + DWORD EnumWkstaFlags = 0; + + RPL_ASSERT( wcslen(RG_Directory) == RG_DirectoryLength + && RG_DirectoryLength+wcslen(LANMANINI_CONFIGSDOS) < MAX_PATH + && RG_DirectoryLength+wcslen(LANMANINI_BINFILES ) < MAX_PATH ); + + // + // get domain name + // + // CODEWORK OK for workgroup? Non-issue since we should be on NTAS + // + Error = NetWkstaGetInfo( NULL, 100, (LPBYTE *)&pw100); + if (Error != NO_ERROR) { + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + RPL_ASSERT( pw100 != NULL ); + pwszDomainName = pw100->wki100_langroup; + RPL_ASSERT( pwszDomainName != NULL && *pwszDomainName != L'\0' ); + + // + // update rplfiles\configs\dos\lanman.dos\lanman.ini + // + wcscpy( achFile, RG_Directory ); + wcscat( achFile, LANMANINI_CONFIGSDOS ); + + if ( !WritePrivateProfileString( LANMANINI_SECTION, + LANMANINI_KEY, + pwszDomainName, + achFile )) + { + Error = GetLastError(); + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + // + // update rplfiles\binfiles\lanman.dos\lanman.ini + // + wcscpy( achFile + RG_DirectoryLength, LANMANINI_BINFILES ); + + if ( !WritePrivateProfileString( LANMANINI_SECTION, + LANMANINI_KEY, + pwszDomainName, + achFile )) + { + Error = GetLastError(); + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + // + // update rplfiles\profiles\<profilename>\lanman.dos\lanman.ini + // + // Code lifted from NetrRplConfigEnum + // + EnterCriticalSection( &RG_ProtectDatabase); + InCritSec = TRUE; + Call( JetBeginTransaction( pSession->SesId)); + InEnumeration = TRUE; + + if ( !RplFilterFirst( pSession, PROFILE_TABLE_TAG, NULL, NULL, &TableEnd)) { + Error = NERR_RplCannotEnum; + goto cleanup; + } + + for ( ; ; ) { + + if ( TableEnd == TRUE) { + break; + } + + if (EnumProfileName != NULL) { + MIDL_user_free( EnumProfileName ); + EnumProfileName = NULL; + } + + // get profile name + SpaceLeft = MAX_PATH; // CODEWORK * sizeof(WCHAR)? + Error = ProfileGetField( pSession, + PROFILE_ProfileName, + &EnumProfileName, + &SpaceLeft); + if ( Error != NO_ERROR) { + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + // build file name and modify file + if ( ( RG_DirectoryLength + + wcslen(LANMANINI_PROFILES) + + wcslen(EnumProfileName) + - 3) >= MAX_PATH ) + { + RplDump( ++RG_Assert, ( "wkstaname too long \"%ws\"", EnumWkstaName)); + } + else + { + swprintf( achFile + RG_DirectoryLength, + LANMANINI_PROFILES, + EnumProfileName ); + if ( !WritePrivateProfileString( LANMANINI_SECTION, + LANMANINI_KEY, + pwszDomainName, + achFile )) + { + Error = GetLastError(); + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + } + + if ( !RplFilterNext( pSession, pSession->ProfileTableId, NULL, &TableEnd)) { + Error = NERR_RplCannotEnum; + goto cleanup; + } + } + + Call( JetCommitTransaction( pSession->SesId, 0)); // CODEWORK rollback on error? + InEnumeration = FALSE; + + // + // update rplfiles\machines\<wkstaname>\<profilename>\lanman.dos\lanman.ini + // + Call( JetBeginTransaction( pSession->SesId)); + InEnumeration = TRUE; + if ( !RplFilterFirst( pSession, WKSTA_TABLE_TAG, NULL, NULL, &TableEnd)) { + Error = NERR_RplCannotEnum; + goto cleanup; + } + for ( ; ; ) { + + if ( TableEnd == TRUE) { + break; + } + + // check whether this wksta has a personal profile + SpaceLeft = sizeof(DWORD); + Error = WkstaGetField( pSession, + WKSTA_Flags, + (LPVOID *)&EnumWkstaFlags, + &SpaceLeft); + if ( Error != NO_ERROR) { + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + // only write for personal profile + if ( EnumWkstaFlags & WKSTA_FLAGS_SHARING_FALSE ) { + + if (EnumWkstaName != NULL) { + MIDL_user_free( EnumWkstaName ); + EnumProfileName = NULL; + } + + // get workstation name + SpaceLeft = MAX_PATH; // CODEWORK * sizeof(WCHAR)? + Error = WkstaGetField( pSession, + WKSTA_WkstaName, + &EnumWkstaName, + &SpaceLeft); + if ( Error != NO_ERROR) { + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + if (EnumProfileName != NULL) { + MIDL_user_free( EnumProfileName ); + EnumProfileName = NULL; + } + + // get workstation-in-profile name + SpaceLeft = MAX_PATH; // CODEWORK * sizeof(WCHAR)? + Error = WkstaGetField( pSession, + WKSTA_ProfileName, + &EnumProfileName, + &SpaceLeft); + if ( Error != NO_ERROR) { + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + // build file name and modify file + if ( ( RG_DirectoryLength + + wcslen(LANMANINI_WKSTAS) + + wcslen(EnumWkstaName) + + wcslen(EnumProfileName) + - 6) >= MAX_PATH ) + { + RplDump( ++RG_Assert, + ( "Wksta+profile too long \"%ws\", \"%ws\"", + EnumWkstaName, + EnumProfileName)); + } + else + { + swprintf( achFile + RG_DirectoryLength, + LANMANINI_WKSTAS, + EnumWkstaName, + EnumProfileName ); + if ( !WritePrivateProfileString( LANMANINI_SECTION, + LANMANINI_KEY, + pwszDomainName, + achFile )) + { + Error = GetLastError(); + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + } + + + } + + + if ( !RplFilterNext( pSession, pSession->WkstaTableId, NULL, &TableEnd)) { + Error = NERR_RplCannotEnum; + goto cleanup; + } + } + +cleanup: + + if ( InEnumeration) { + Call( JetCommitTransaction( pSession->SesId, 0)); // CODEWORK rollback on error? + } + + if ( InCritSec) { + LeaveCriticalSection( &RG_ProtectDatabase); + } + if (EnumProfileName != NULL) { + MIDL_user_free( EnumProfileName ); + EnumWkstaName = NULL; + } + + if (EnumWkstaName != NULL) { + MIDL_user_free( EnumWkstaName ); + EnumWkstaName = NULL; + } + + if ( pw100 != NULL) { + NetApiBufferFree( pw100); + } + + // + // BUGBUG Need better event id/text? + // + if (Error != NO_ERROR) { + RplReportEvent( NELOG_RplCheckSecurity, NULL, sizeof(DWORD), &Error ); + } + + return( Error); +} + +#define RPL_COM L"\\COMMAND.COM" +#define WCSLEN( _x_) ((DWORD) ( sizeof(_x_)/sizeof(WCHAR) - 1)) + +BOOL RplConfigEnabled( IN PWCHAR DirName2) +{ + WCHAR SearchBuffer[ MAX_PATH ]; + DWORD SearchBufferLength; + + wcscpy( SearchBuffer, RG_DiskBinfiles); + SearchBufferLength = wcslen( SearchBuffer); + + if ( SearchBufferLength + wcslen(DirName2) + WCSLEN( RPL_COM) + > WCSLEN( SearchBuffer)) { + RplDump( ++RG_Assert, ( "DirName2=%ws", DirName2)); + return( FALSE); + } + wcscpy( SearchBuffer + SearchBufferLength, DirName2); + wcscat( SearchBuffer + SearchBufferLength, RPL_COM); + /* + * The file COMMAND.COM should be in directory given by SearchBuffer + */ + return( FileExists( SearchBuffer, NULL)); +} + + +DWORD RplCheckConfigs( VOID) +/*++ + +Routine Description: + + This function checks whether the file COMMAND.COM exists + in the proper place for each configuration, and + enables/disables the configuration accordingly. + +Arguments: + +Return Value: + +--*/ +{ + DWORD Error = NO_ERROR; + INT SpaceLeft; + BOOL TableEnd; + WCHAR * DirName2 = NULL; + DWORD Flags; + WCHAR SearchBuffer[ MAX_PATH ]; + BOOL BoolConfigEnabled = FALSE; + BOOL BoolFileFound = FALSE; + DWORD SearchBufferLength; + PRPL_SESSION pSession = &RG_ApiSession; + + wcscpy( SearchBuffer, RG_DiskBinfiles); + SearchBufferLength = wcslen( SearchBuffer); + + // + // Code lifted from NetrRplConfigEnum + // + EnterCriticalSection( &RG_ProtectDatabase); + Call( JetBeginTransaction( pSession->SesId)); + + if ( !RplFilterFirst( pSession, CONFIG_TABLE_TAG, NULL, NULL, &TableEnd)) { + Error = NERR_RplCannotEnum; + goto cleanup; + } + if ( TableEnd == TRUE) { + goto cleanup; + } + for ( ; ; ) { + + if (DirName2 != NULL) { + MIDL_user_free( DirName2 ); + DirName2 = NULL; + } + + Error = ConfigGetField( pSession, + CONFIG_DirName2, + &DirName2, + &SpaceLeft); + if ( Error != NO_ERROR) { + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + Error = ConfigGetField( pSession, + CONFIG_Flags, + (LPVOID *)&Flags, + &SpaceLeft); + if ( Error != NO_ERROR) { + RplDump( ++RG_Assert, ( "Error=%d", Error)); + goto cleanup; + } + + // + // Check whether this configuration should be enabled + // + RPL_ASSERT( (!!(Flags & CONFIG_FLAGS_ENABLED_TRUE)) + != (!!(Flags & CONFIG_FLAGS_ENABLED_FALSE)) ); + BoolConfigEnabled = !!(Flags & CONFIG_FLAGS_ENABLED_TRUE); + + if ( SearchBufferLength + wcslen(DirName2) + WCSLEN( RPL_COM) + > WCSLEN( SearchBuffer)) { + RplDump( ++RG_Assert, ( "DirName2=%ws", DirName2)); + continue; + } + wcscpy( SearchBuffer + SearchBufferLength, DirName2); + wcscat( SearchBuffer + SearchBufferLength, RPL_COM); + /* + * The file COMMAND.COM should be in directory given by SearchBuffer + */ + BoolFileFound = FileExists( SearchBuffer, NULL ); + + if (Error == NERR_Success && BoolConfigEnabled != BoolFileFound) { + Flags ^= CONFIG_FLAGS_MASK_ENABLED; // XOR + + // lifted from NetrRplConfigAdd and NetrWkstaSetinfo + CallJ( JetPrepareUpdate( pSession->SesId, + pSession->ConfigTableId, + JET_prepReplace)); + + // lifted from ConfigSetInfo + CallM( JetSetColumn( pSession->SesId, pSession->ConfigTableId, + ConfigTable[ CONFIG_Flags].ColumnId, + &Flags, sizeof( Flags), 0, NULL)); + + // lifted from NetrRplConfigAdd + CallJ( JetUpdate( pSession->SesId, + pSession->ConfigTableId, + NULL, 0, NULL)); + } + + if ( !RplFilterNext( pSession, pSession->ConfigTableId, NULL, &TableEnd)) { + Error = NERR_RplCannotEnum; + goto cleanup; + } + if ( TableEnd == TRUE) { + goto cleanup; + } + } + +cleanup: + Call( JetCommitTransaction( pSession->SesId, 0)); // CODEWORK rollback on error? + LeaveCriticalSection( &RG_ProtectDatabase); + + if (DirName2 != NULL) { + MIDL_user_free( DirName2 ); + DirName2 = NULL; + } + + if (Error != NO_ERROR) { + RplReportEvent( NELOG_RplCheckConfigs, NULL, sizeof(DWORD), &Error ); + } + + return( Error); +} + + +DWORD RplBackupDatabase( IN BOOL FullBackup) +/*++ + +Routine Description: + + This function backs up the JET database. FullBackup copies the + database file and all log files. Incremental backup copies only + the log files that are modified since the last backup. + +Arguments: + + FullBackup - set to TRUE if full backup is required. + +Return Value: + + Windows Error. + +--*/ +{ + JET_ERR JetError; + + FullBackup = TRUE; // to avoid JET bugs in JetRestore() + + JetError = JetBackup( RG_BackupPath, +#ifdef __JET500 + JET_bitBackupAtomic | + (FullBackup ? 0 + : JET_bitBackupIncremental), + NULL +#else + (FullBackup ? JET_bitOverwriteExisting + : JET_bitBackupIncremental) +#endif + ); + + if( JetError == JET_errFileNotFound && FullBackup == FALSE) { + + // + // Full backup was not performed anytime, so do it now. + // + + JetError = JetBackup( RG_BackupPath, +#ifdef __JET500 + JET_bitBackupAtomic, + NULL +#else + JET_bitOverwriteExisting +#endif + ); + } + + if ( JetError < 0) { + RplReportEvent( NELOG_RplBackupDatabase, NULL, sizeof(DWORD), &JetError); + return( NERR_RplBackupDatabase); + } + return( NO_ERROR); +} + + +DWORD SetupAction( + IN OUT PDWORD pAction, + IN BOOL FullBackup + ) +/*++ + +Routine Description: + + Performs the setup action for all RPL_SPECIAL_ACTIONS specified + in *pAction. + +Arguments: + pAction: points to RPL_SPECIAL_ACTIONS DWORD. On return, the + RPL_SPECIAL_ACTIONS flags are reset for all actions which + were successfully performed. + +Return Value: + error word + +--*/ +{ + DWORD Error; + + if ((*pAction) & RPL_REPLACE_RPLDISK) { +#ifdef NOT_YET + Error = RplReplaceRPLDISK(); + if (Error != NO_ERROR) { + return( Error); + } +#endif + *pAction &= ~RPL_REPLACE_RPLDISK; + } + + if ((*pAction) & RPL_CHECK_SECURITY) { + Error = RplProcessLanmanInis(); + if (Error != NO_ERROR) { + return( Error); + } + *pAction &= ~RPL_CHECK_SECURITY; + } + + if ((*pAction) & RPL_CHECK_CONFIGS) { + Error = RplCheckConfigs(); + if (Error != NO_ERROR) { + return( Error); + } + *pAction &= ~RPL_CHECK_CONFIGS; + } + + if ((*pAction) & RPL_CREATE_PROFILES) { + // + // CODEWORK RPL_CREATE_PROFILES not implemented + // + *pAction &= ~RPL_CREATE_PROFILES; + } + + if ((*pAction) & RPL_BACKUP_DATABASE) { + Error = RplBackupDatabase( FullBackup); + if (Error != NO_ERROR) { + return( Error); + } + *pAction &= ~RPL_BACKUP_DATABASE; + } + + return( NO_ERROR); +} + |