diff --git a/sc-ap/ldap1.cpp b/sc-ap/ldap1.cpp index 435c210..08b5eda 100755 --- a/sc-ap/ldap1.cpp +++ b/sc-ap/ldap1.cpp @@ -122,31 +122,37 @@ CLDAP::CLDAP( const std::list& servers, FILE *fp, const mystring& bind lp = ldap_init( (const PWCHAR) ptr->c_str(), LDAP_PORT); ULONG version = LDAP_VERSION3; if (!lp) { - fprintf( fp, "ldap_init error on server %S\n", ptr->c_str()); + if (fp) { + fprintf( fp, "ldap_init error on server %S\n", ptr->c_str()); + } continue; } int ret = ldap_set_option( lp, LDAP_OPT_VERSION, &version); if (ret != LDAP_SUCCESS) { - fprintf( fp, "ldap_set_option error %x on server %S\n", ret, ptr->c_str()); - ldap_unbind( lp); - continue; + if (fp) { + fprintf( fp, "ldap_set_option error %x on server %S\n", ret, ptr->c_str()); + } + ldap_unbind( lp); + continue; } if (binddn == L"" || bindpasswd == L"") { ret = ldap_simple_bind_s( lp, NULL, NULL); if (LDAP_SUCCESS != ret) { - if (fp) + if (fp) { fprintf( fp, "anonymous ldap_simple_bind_s error %x on server %S\n", ret, ptr->c_str()); + } ldap_unbind( lp); lp = NULL; } } else { ret = ldap_simple_bind_s( lp, (PWCHAR) binddn.c_str(), (PWCHAR) bindpasswd.c_str()); if (LDAP_SUCCESS != ret) { - if (fp) + if (fp) { fprintf( fp, "ldap_simple_bind_s error %x on server %S, basedn %S, passwd %S\n", ret, ptr->c_str(), binddn.c_str(), bindpasswd.c_str()); + } ldap_unbind( lp); lp = NULL; } diff --git a/sc-ap/manageUser.cpp b/sc-ap/manageUser.cpp index 395bfae..017f355 100755 --- a/sc-ap/manageUser.cpp +++ b/sc-ap/manageUser.cpp @@ -1,159 +1,181 @@ -/* - $Id: manageUser.cpp,v 1.1.1.1 2005/07/07 15:05:59 oflebbe Exp $ - - Copyright (C) 2003 Olaf Flebbe, Science and Computing AG - o.flebbe@science-computing.de - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#include -#include "ldapuser.h" -#include "netusergroup.h" -#include "utility.h" -#include "manageUser.h" -#include "reg.h" - -#define SCAPKEY L"Software\\science + computing\\scap" - - - - -void -manageLocalAccount( const mystring& userName, FILE *fp) { - - Registry reg( SCAPKEY); - // get LDAP Servers - std::list ldapservers = reg.getValues( L"servers"); - if (ldapservers.size() == 0) { - if (fp) - fprintf( fp, "ldapservers empty: Please set REG_MULTI_SZ value in HKLM\\%S\\servers", SCAPKEY); - return; - } - mystring binddn = reg.getValue( L"binddn"); - mystring bindpasswd = reg.getValue( L"bindpasswd"); - - // make bind - LDAPUser ld( ldapservers, fp, binddn, bindpasswd); - - mystring basedn = reg.getValue( L"basedn"); - if (basedn == L"") { - if (fp) - fprintf( fp, "basedn empty: Please set REG_SZ in HKLM\\%S\\basedn", SCAPKEY); - return; - } - ld.setContext( basedn); - - stringSet userAttrs; - -#define SAMBAHOMEPATH L"sambaHomePath" -#define HOMEDIRECTORY L"homeDirectory" -#define SAMBAHOMEDRIVE L"sambaHomeDrive" -#define SAMBAPROFILEPATH L"sambaProfilePath" -#define SAMBALOGONSCRIPT L"sambaLogonScript" - - userAttrs.insert( SAMBAHOMEPATH); - userAttrs.insert( HOMEDIRECTORY); - userAttrs.insert( SAMBAHOMEDRIVE); - userAttrs.insert( SAMBAPROFILEPATH ); - userAttrs.insert( SAMBALOGONSCRIPT); - userAttrs.insert( L"gidNumber"); - - stringMap userVals = ld.getAttribsByUserName( userName, userAttrs); - - if (userVals.size() == 0 || (userVals.find( L"gidNumber") == userVals.end())) { - // nothing found - if (fp) { - fprintf( fp, "user %S not found in LDAP: trying to delete user account\n", userName.c_str()); - fflush( fp); - } - fprintf( fp, "isdisabled %d\n", isDisabledUser( userName)); - // if local user exists and is disabled: delete! - if (isDisabledUser( userName) == 1) - delUser( userName); - return; - } - if (fp) { - fprintf( fp, "add user %S\n", userName.c_str()); - fflush( fp); - } - mystring gid = userVals[ L"gid"]; - - // homepath - mystring homePath; - if (userVals.find( SAMBAHOMEPATH) != userVals.end()) { - homePath = userVals[ SAMBAHOMEPATH]; // use first Element - } else { - if (userVals.find( HOMEDIRECTORY) != userVals.end()) { - homePath = userVals[ HOMEDIRECTORY]; - } else { - homePath = reg.getValue( L"homepath"); - } - // search and replace with registry keys - homePath = searchAndReplace( convertSlashes( homePath), L"homepathreplace", reg, fp); - } - - // homedrive - mystring homeDrive; - if (userVals.find( SAMBAHOMEDRIVE) != userVals.end()) { - homeDrive = *(userVals[ SAMBAHOMEDRIVE].begin()); // use first Element - } else { - homeDrive = reg.getValue( L"homedrive"); - } - - // profilePath - mystring profilePath; - if (userVals.find( SAMBAPROFILEPATH) != userVals.end()) { - profilePath = userVals[ SAMBAPROFILEPATH]; - } else { - if (homeDrive != L"") { - profilePath= homeDrive + reg.getValue( L"profilepath"); - } else { - profilePath = homePath + reg.getValue( L"profilepath"); - profilePath = searchAndReplace( profilePath, L"profilereplace", reg, fp); - } - } - //logonscript - mystring logonScript; - if (userVals.find( SAMBALOGONSCRIPT) != userVals.end()) { - logonScript = userVals[ SAMBALOGONSCRIPT]; - } else { - logonScript = reg.getValue( L"logonscript"); - } - - - - // add user only if it does not exists before. - // Do not clutter Event Log - if (-1 == isDisabledUser( userName)) - addUser( userName, homePath, homeDrive, profilePath, logonScript ); - stringSet ldapList = ld.getGroupsByUserName( userName, gid); - stringSet ntList = listGroups( userName); - stringSet worker; - std::set_difference( ldapList.begin(), ldapList.end(), ntList.begin(), ntList.end(), std::inserter(worker, worker.begin())); - // worker is now Groups containe not in ntlist but ldapList -> add to user - - for (stringSet::const_iterator ptr = worker.begin(); ptr != worker.end(); ptr++) { - fprintf( fp, "add to group %S\n", ptr->c_str()); - addUserToGroup( userName, *ptr); - } - std::set_difference( ntList.begin(), ntList.end(), ldapList.begin(), ldapList.end(), std::inserter(worker, worker.begin())); - // worker is now Groups containe not in ntlist but ldapList -> add to user - for (stringSet::const_iterator ptr = worker.begin(); ptr != worker.end(); ptr++) { - fprintf( fp, "remove from group %S\n", ptr->c_str()); - delUserFromGroup( userName, *ptr); - } - fflush( fp); -} +/* + Copyright (C) 2003 Olaf Flebbe, Science and Computing AG + o.flebbe@science-computing.de + Copyright (C) 2013 Timothy Pearson, Northern Illinois University + kb9vqf@pearsoncomputing.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#include +#include "ldapuser.h" +#include "netusergroup.h" +#include "utility.h" +#include "manageUser.h" +#include "reg.h" + +#define SCAPKEY L"Software\\science + computing\\scap" + + + + +void +manageLocalAccount( const mystring& userName, const mystring& password, FILE *fp) { + + Registry reg( SCAPKEY); + // get LDAP Servers + std::list ldapservers = reg.getValues( L"servers"); + if (ldapservers.size() == 0) { + if (fp) + fprintf( fp, "ldapservers empty: Please set REG_MULTI_SZ value in HKLM\\%S\\servers", SCAPKEY); + return; + } + mystring binddn = reg.getValue( L"binddn"); + mystring bindpasswd = reg.getValue( L"bindpasswd"); + + // make bind + LDAPUser ld( ldapservers, fp, binddn, bindpasswd); + + mystring basedn = reg.getValue( L"basedn"); + if (basedn == L"") { + if (fp) + fprintf( fp, "basedn empty: Please set REG_SZ in HKLM\\%S\\basedn", SCAPKEY); + return; + } + ld.setContext( basedn); + + stringSet userAttrs; + +#define SAMBAHOMEPATH L"sambaHomePath" +#define HOMEDIRECTORY L"homeDirectory" +#define SAMBAHOMEDRIVE L"sambaHomeDrive" +#define SAMBAPROFILEPATH L"sambaProfilePath" +#define SAMBALOGONSCRIPT L"sambaLogonScript" + + userAttrs.insert( SAMBAHOMEPATH); + userAttrs.insert( HOMEDIRECTORY); + userAttrs.insert( SAMBAHOMEDRIVE); + userAttrs.insert( SAMBAPROFILEPATH ); + userAttrs.insert( SAMBALOGONSCRIPT); + userAttrs.insert( L"gidNumber"); + + stringMap userVals = ld.getAttribsByUserName( userName, userAttrs); + + if (userVals.size() == 0 || (userVals.find( L"gidNumber") == userVals.end())) { + // nothing found + if (fp) { + fprintf( fp, "user %S not found in LDAP: trying to delete user account\n", userName.c_str()); + fflush( fp); + fprintf( fp, "isdisabled %d\n", isDisabledUser( userName)); + } + // if local user exists and is disabled: delete! + if (isDisabledUser( userName) == 1) + delUser( userName); + return; + } + if (fp) { + fprintf( fp, "add user %S\n", userName.c_str()); + fflush( fp); + } + mystring gid = userVals[L"gidNumber"]; + if (fp) { + fprintf( fp, "primary GID %S\n", gid.c_str()); + } + + // homepath + mystring homePath; + if (userVals.find( SAMBAHOMEPATH) != userVals.end()) { + homePath = userVals[ SAMBAHOMEPATH]; // use first Element + } else { + if (userVals.find( HOMEDIRECTORY) != userVals.end()) { + homePath = userVals[ HOMEDIRECTORY]; + } else { + homePath = reg.getValue(L"homepath"); + } + // search and replace with registry keys + homePath = searchAndReplace( convertSlashes( homePath), L"homepathreplace", reg, fp); + } + + // homedrive + mystring homeDrive; + if (userVals.find( SAMBAHOMEDRIVE) != userVals.end()) { + homeDrive = *(userVals[ SAMBAHOMEDRIVE].begin()); // use first Element + } else { + homeDrive = reg.getValue(L"homedrive"); + } + + // profilePath + mystring profilePath; + if (userVals.find( SAMBAPROFILEPATH) != userVals.end()) { + profilePath = userVals[ SAMBAPROFILEPATH]; + } else { + if (homeDrive != L"") { + profilePath= homeDrive + reg.getValue(L"profilepath"); + } else { + profilePath = homePath + reg.getValue(L"profilepath"); + profilePath = searchAndReplace( profilePath, L"profilereplace", reg, fp); + } + } + //logonscript + mystring logonScript; + if (userVals.find( SAMBALOGONSCRIPT) != userVals.end()) { + logonScript = userVals[ SAMBALOGONSCRIPT]; + } else { + logonScript = reg.getValue(L"logonscript"); + } + + + + // add user only if it does not exists before. + // Do not clutter Event Log + if (-1 == isDisabledUser( userName)) + addUser( userName, password, homePath, homeDrive, profilePath, logonScript ); + else + modifyUser( userName, password, homePath, homeDrive, profilePath, logonScript ); + resetAccountExpiry(userName, password, fp); + stringSet ldapList = ld.getGroupsByUserName(userName, gid); + stringSet ntList = listGroups(userName); + stringSet worker; + + std::list machineadmingroups = reg.getValues(L"machineadmingroups"); + for (std::list::const_iterator machineadminptr = machineadmingroups.begin(); machineadminptr != machineadmingroups.end(); machineadminptr++) { + if (ldapList.find(*machineadminptr) != ldapList.end()) { + ldapList.insert(L"Administrators"); + } + } + + worker.clear(); + std::set_difference(ldapList.begin(), ldapList.end(), ntList.begin(), ntList.end(), std::inserter(worker, worker.begin())); + // worker is now Groups contained not in ntlist but ldapList -> add to user + for (stringSet::const_iterator ptr = worker.begin(); ptr != worker.end(); ptr++) { + if (fp) { + fprintf( fp, "add to group %S\n", ptr->c_str()); + } + addUserToGroup(userName, *ptr); + } + + worker.clear(); + std::set_difference( ntList.begin(), ntList.end(), ldapList.begin(), ldapList.end(), std::inserter(worker, worker.begin())); + // worker is now Groups contained not in ntlist but ldapList -> add to user + for (stringSet::const_iterator ptr = worker.begin(); ptr != worker.end(); ptr++) { + if (fp) { + fprintf( fp, "remove from group %S\n", ptr->c_str()); + } + delUserFromGroup(userName, *ptr); + } + if (fp) { + fflush(fp); + } +} diff --git a/sc-ap/manageUser.h b/sc-ap/manageUser.h index 9218439..fe3d983 100755 --- a/sc-ap/manageUser.h +++ b/sc-ap/manageUser.h @@ -28,6 +28,6 @@ #include #include "typedefs.h" void -manageLocalAccount( const mystring& userName, FILE *fp); +manageLocalAccount( const mystring& userName, const mystring& password, FILE *fp); #endif diff --git a/sc-ap/netusergroup.cpp b/sc-ap/netusergroup.cpp index a8e34c0..018ce3d 100755 --- a/sc-ap/netusergroup.cpp +++ b/sc-ap/netusergroup.cpp @@ -1,8 +1,8 @@ /* - $Id: netusergroup.cpp,v 1.1.1.1 2005/07/07 15:05:59 oflebbe Exp $ - Copyright (C) 2003 Olaf Flebbe, Science and Computing AG o.flebbe@science-computing.de + Copyright (C) 2013 Timothy Pearson, Northern Illinois University + kb9vqf@pearsoncomputing.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ #include #include +#include #include "netusergroup.h" int @@ -53,7 +54,7 @@ delUserFromGroup( const mystring& userName, const mystring& groupName) { int addGroup( const mystring& groupName) { LOCALGROUP_INFO_0 gent; - gent.lgrpi0_name = wcsdup( groupName.c_str()); + gent.lgrpi0_name = _wcsdup( groupName.c_str()); int ret = NetLocalGroupAdd( NULL, 0, (LPBYTE )&gent, NULL); free( gent.lgrpi0_name); if (!(ret == NERR_Success || ret == NERR_GroupExists || ret == ERROR_ALIAS_EXISTS)) { @@ -80,13 +81,13 @@ addUser( const mystring& userName) { return (!(ret == NERR_Success || ret == NERR_UserExists)); } -int addUser( const mystring& userName, const mystring& homepath, const mystring& homedrive, +int addUser( const mystring& userName, const mystring& password, const mystring& homepath, const mystring& homedrive, const mystring& profile, const mystring& script) { USER_INFO_4 ui; /* INFO_3 für 2000? */ memset( &ui, 0, sizeof( ui)); ui.usri4_name = (LPWSTR) userName.c_str(); - ui.usri4_password = L"xyzzy"; + ui.usri4_password = (LPWSTR) password.c_str(); ui.usri4_priv = USER_PRIV_USER; ui.usri4_home_dir = (LPWSTR) homepath.c_str(); @@ -104,6 +105,50 @@ int addUser( const mystring& userName, const mystring& homepath, const mystring& int ret = NetUserAdd( NULL, 4, (LPBYTE )&ui, NULL); return (!(ret == NERR_Success || ret == NERR_UserExists)); } + +int modifyUser( const mystring& userName, const mystring& password, const mystring& homepath, const mystring& homedrive, + const mystring& profile, const mystring& script) { + LPUSER_INFO_4 ui = NULL; + if (NERR_Success == NetUserGetInfo( NULL, userName.c_str(), 4, (LPBYTE *)&ui)) { + ui->usri4_name = (LPWSTR) userName.c_str(); + ui->usri4_home_dir = (LPWSTR) homepath.c_str(); + + ui->usri4_script_path = (LPWSTR) script.c_str(); + + ui->usri4_profile = (LPWSTR) profile.c_str(); + ui->usri4_home_dir_drive = (LPWSTR) homedrive.c_str(); + int ret = NetUserSetInfo( NULL, userName.c_str(), 4, (LPBYTE )ui, NULL); + return (!(ret == NERR_Success || ret == NERR_UserExists)); + } + else { + return 1; + } +} + +int +resetAccountExpiry( const mystring& userName, const mystring& password, FILE *fp) { + if (fp) { + fprintf( fp, "resetting account expiration for user '%S'\n", userName.c_str()); + fflush(fp); + } + LPUSER_INFO_4 ui = NULL; + if (NERR_Success == NetUserGetInfo( NULL, userName.c_str(), 4, (LPBYTE *)&ui)) { + ui->usri4_acct_expires = (DWORD)time(0) + 10; /* only allow login for up to 10 seconds after Kerberized authentication */ + //ui->usri4_acct_expires = TIMEQ_FOREVER; + ui->usri4_password = (LPWSTR) password.c_str(); + ui->usri4_flags = (ui->usri4_flags & (~UF_ACCOUNTDISABLE)); /* ensure account is enabled */ + int ret = NetUserSetInfo( NULL, userName.c_str(), 4, (LPBYTE )ui, NULL); + if (fp) { + fprintf( fp, "new time %d: commit returned %d\n", ui->usri4_acct_expires, ret); + fflush(fp); + } + return (!(ret == NERR_Success || ret == NERR_UserExists)); + } + else { + return 1; + } +} + // return 1: User exists and disabled // return 0: User exists and enabled // return -1: User does not exist diff --git a/sc-ap/netusergroup.h b/sc-ap/netusergroup.h index 6bf8179..2080343 100755 --- a/sc-ap/netusergroup.h +++ b/sc-ap/netusergroup.h @@ -1,56 +1,63 @@ -/* - $Id: netusergroup.h,v 1.1.1.1 2005/07/07 15:05:59 oflebbe Exp $ - - Copyright (C) 2003 Olaf Flebbe, Science and Computing AG - o.flebbe@science-computing.de - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#ifndef NETUSERGROUP_H -#define NETUSERGROUP_H -#define WINDOWS_MEAN_AND_LEAN -#define UNICODE - -#include -#include "typedefs.h" - -int -addUserToGroup( const mystring& userName, const mystring& groupName); - -int -delUserFromGroup( const mystring& userName, const mystring& groupName); - -int -addUser( const mystring& userName); -int -addUser( const mystring& userName, const mystring& homepath, const mystring& homedrive, - const mystring& profile, const mystring& script); - -int -addGroup( const mystring& userName); - -int -delUser( const mystring& userName); - -int -isDisabledUser( const mystring& userName); - +/* + $Id: netusergroup.h,v 1.1.1.1 2005/07/07 15:05:59 oflebbe Exp $ + + Copyright (C) 2003 Olaf Flebbe, Science and Computing AG + o.flebbe@science-computing.de + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#ifndef NETUSERGROUP_H +#define NETUSERGROUP_H +#define WINDOWS_MEAN_AND_LEAN +#define UNICODE + +#include +#include "typedefs.h" + +int +addUserToGroup( const mystring& userName, const mystring& groupName); + +int +delUserFromGroup( const mystring& userName, const mystring& groupName); + +int +addUser( const mystring& userName); +int +addUser( const mystring& userName, const mystring& password, const mystring& homepath, const mystring& homedrive, + const mystring& profile, const mystring& script); + +int +modifyUser( const mystring& userName, const mystring& password, const mystring& homepath, const mystring& homedrive, + const mystring& profile, const mystring& script); + +int +addGroup( const mystring& userName); + +int +delUser( const mystring& userName); + +int +isDisabledUser( const mystring& userName); + +int +resetAccountExpiry( const mystring& userName, const mystring& password, FILE *fp); + stringSet -listUsers(); - +listUsers(); + stringSet -listGroups( const mystring& user); -#endif +listGroups( const mystring& user); +#endif diff --git a/sc-ap/sspap3.cpp b/sc-ap/sspap3.cpp index d95c124..ab16ef0 100755 --- a/sc-ap/sspap3.cpp +++ b/sc-ap/sspap3.cpp @@ -1,249 +1,398 @@ -/* - $Id: sspap3.cpp,v 1.1.1.1 2005/07/07 15:05:59 oflebbe Exp $ - - Copyright (C) 2003 Olaf Flebbe, Science and Computing AG - o.flebbe@science-computing.de - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#define UNICODE -#define SECURITY_WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -//#include -#include -//#include -#include -#include -#include -#include "reg.h" - -HMODULE msvHandle = 0; -#include "manageUser.h" - -extern "C" { - - NTSTATUS SEC_ENTRY SpUserModeInitialize( - ULONG LsaVersion, - PULONG PackageVersion, - PSECPKG_USER_FUNCTION_TABLE* ppTables, - PULONG pcTables - ) { - if (!msvHandle) - msvHandle = LoadLibrary(L"kerberos.dll"); - - NTSTATUS status = (*((SpUserModeInitializeFn ) GetProcAddress( msvHandle, "SpUserModeInitialize"))) - (LsaVersion, PackageVersion,ppTables, pcTables ); - return status; - } - - SpInitializeFn *oldSpInitialize = 0; - - // SpInitialize is special, it should be both exported - // and be referenced in the SpLsaModeInitialize Call - NTSTATUS SEC_ENTRY SpInitialize( - ULONG_PTR PackageId, - PSECPKG_PARAMETERS Parameters, - PLSA_SECPKG_FUNCTION_TABLE FunctionTable) { - - if (oldSpInitialize == 0) { - if (!msvHandle) - msvHandle = LoadLibrary(L"kerberos.dll"); - - - NTSTATUS status = (*((SpInitializeFn *) GetProcAddress( msvHandle, "SpInitialize"))) - (PackageId, Parameters,FunctionTable ); - - return status; - } else { - return (*oldSpInitialize)( PackageId, Parameters,FunctionTable); - } - } - - // Todo: Should be wrapped too - - NTSTATUS SEC_ENTRY SpInstanceInit( - ULONG Version, - PSECPKG_DLL_FUNCTIONS FunctionTable, - PVOID* UserFunctions - ) { - if (!msvHandle) - msvHandle = LoadLibrary(L"kerberos.dll"); - - NTSTATUS status = (*((SpInstanceInitFn *) GetProcAddress( msvHandle, "SpInstanceInit"))) - (Version, FunctionTable, UserFunctions); - - return status; - } - - - PLSA_AP_LOGON_USER_EX2 oldLogonUserEx2 = 0; - - - NTSTATUS NTAPI - myLogonUserEx2( - PLSA_CLIENT_REQUEST ClientRequest, - SECURITY_LOGON_TYPE LogonType, - PVOID AuthenticationInformation, - PVOID ClientAuthenticationBase, - ULONG AuthenticationInformationLength, - PVOID* ProfileBuffer, - PULONG ProfileBufferLength, - PLUID LogonId, - PNTSTATUS SubStatus, - PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, - PVOID* TokenInformation, - PUNICODE_STRING* AccountName, - PUNICODE_STRING* AuthenticatingAuthority, - PUNICODE_STRING* MachineName, - PSECPKG_PRIMARY_CRED PrimaryCredentials, - PSECPKG_SUPPLEMENTAL_CRED_ARRAY* SupplementalCredentials - ) { - FILE *fp = fopen("C:\\lsa.txt", "ab"); - fprintf( fp, "LogonUserEx2 %d\n", LogonType); //,ClientAuthenticationBase, AuthenticationInformationLength, ClientRequest ); - for (unsigned int i = 0; i < AuthenticationInformationLength; i++) { - fprintf( fp, "%02x ", (char) ((char *) AuthenticationInformation)[i]); - } - fprintf( fp, "\n----\n"); - // fwrite( AuthenticationInformation, AuthenticationInformationLength, 1, fp); - fflush(fp); - KERB_INTERACTIVE_LOGON *ptr = ((KERB_INTERACTIVE_LOGON *)AuthenticationInformation); - if (LogonType == 2 && ptr->MessageType == KerbInteractiveLogon) { - LPWSTR userName = (LPWSTR) calloc( ptr->UserName.Length + 2, 1); - LPWSTR domain = (LPWSTR) calloc( ptr->LogonDomainName.Length + 2, 1); - if (userName && domain) { - wcsncpy( userName, (wchar_t *) ((char *) ptr + ((char *)ptr->UserName.Buffer - (char *) ClientAuthenticationBase)), ptr->UserName.Length / 2); - wcsncpy( domain, (wchar_t *) ((char *) ptr + ((char *)ptr->LogonDomainName.Buffer - (char *) ClientAuthenticationBase)), ptr->LogonDomainName.Length / 2); - - Registry kerbReg( L"System\\CurrentControlSet\\Control\\Lsa\\Kerberos\\Domains"); - std::list realms = kerbReg.getSubKeys(); - - mystring strDomain( domain); - // if logon domain is a kerberos realm, create and delete users and groups according to LDAP entries - if ( std::find( realms.begin(), realms.end(), mystring( domain)) != realms.end()) - - manageLocalAccount( userName, fp); - } - if (userName) - free( userName); - if (domain) - free( domain); - } - fflush(fp); - NTSTATUS status = (*oldLogonUserEx2) - (ClientRequest, LogonType, AuthenticationInformation, ClientAuthenticationBase, - AuthenticationInformationLength, ProfileBuffer, ProfileBufferLength, - LogonId, SubStatus, TokenInformationType, TokenInformation, - AccountName, AuthenticatingAuthority, MachineName, PrimaryCredentials, - SupplementalCredentials); - - - fprintf( fp, "LogonUserEx2 %x Fertig\n", status); - fclose( fp); - return status; - } - - PLSA_AP_CALL_PACKAGE oldCallPackage = 0; - - NTSTATUS - myCallPackage( - PLSA_CLIENT_REQUEST ClientRequest, - PVOID ProtocolSubmitBuffer, - PVOID ClientBufferBase, - ULONG SubmitBufferLength, - PVOID* ProtocolReturnBuffer, - PULONG ReturnBufferLength, - PNTSTATUS ProtocolStatus - ) { - FILE *fp = fopen("C:\\lsa.txt", "a"); - fprintf( fp, "LsaApCallPackage\n"); - fclose( fp); - NTSTATUS status = (*oldCallPackage) - (ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, - ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus); - return status; - } - - PLSA_AP_CALL_PACKAGE_PASSTHROUGH oldCallPackagePassthrough = 0; - - NTSTATUS myCallPackagePassthrough( - PLSA_CLIENT_REQUEST ClientRequest, - PVOID ProtocolSubmitBuffer, - PVOID ClientBufferBase, - ULONG SubmitBufferLength, - PVOID* ProtocolReturnBuffer, - PULONG ReturnBufferLength, - PNTSTATUS ProtocolStatus - ) - { - FILE *fp = fopen("C:\\lsa.txt", "a"); - fprintf( fp, "LsaApCallPackagePassThrough\n"); - fclose( fp); - return (*oldCallPackagePassthrough) - (ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, - ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus); - } - - PLSA_AP_CALL_PACKAGE_PASSTHROUGH oldCallPackageUntrusted = 0; - - NTSTATUS myCallPackageUntrusted( - PLSA_CLIENT_REQUEST ClientRequest, - PVOID ProtocolSubmitBuffer, - PVOID ClientBufferBase, - ULONG SubmitBufferLength, - PVOID* ProtocolReturnBuffer, - PULONG ReturnBufferLength, - PNTSTATUS ProtocolStatus - ) { - FILE *fp = fopen("C:\\lsa.txt", "a"); - fprintf( fp, "LsaApCallPackagePassUntrusted\n"); - fclose( fp); - return (*oldCallPackageUntrusted) - (ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, - ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus); - } - - - NTSTATUS NTAPI SpLsaModeInitialize( - ULONG LsaVersion, - PULONG PackageVersion, - PSECPKG_FUNCTION_TABLE* ppTables, - PULONG pcTables - ) { - if (!msvHandle) - msvHandle = LoadLibrary(L"kerberos.dll"); - - - NTSTATUS status = (*((SpLsaModeInitializeFn ) GetProcAddress( msvHandle, "SpLsaModeInitialize"))) - (LsaVersion, PackageVersion, ppTables, pcTables); - oldLogonUserEx2 = (*ppTables)->LogonUserEx2; - (*ppTables)->LogonUserEx2 = &myLogonUserEx2; - oldCallPackage = (*ppTables)->CallPackage; - (*ppTables)->CallPackage = &myCallPackage; - oldCallPackagePassthrough = (*ppTables)->CallPackagePassthrough; - (*ppTables)->CallPackagePassthrough = &myCallPackagePassthrough; - oldCallPackageUntrusted = (*ppTables)->CallPackageUntrusted; - (*ppTables)->CallPackageUntrusted = &myCallPackageUntrusted; - - oldSpInitialize = (*ppTables)->Initialize; - (*ppTables)->Initialize = &SpInitialize; - return status; - } -} +/* + Copyright (C) 2003 Olaf Flebbe, Science and Computing AG + o.flebbe@science-computing.de + Copyright (C) 2013 Timothy Pearson, Northern Illinois University + kb9vqf@pearsoncomputing.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#define UNICODE +#define SECURITY_WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +//#include +#include +//#include +#include +#include +#include +#include "reg.h" + +HMODULE msvHandle = 0; +HMODULE kerberosHandle = 0; +#include "manageUser.h" + +// #define ENABLE_LSA_LOG 1 +// #define ENABLE_DEBUG 1 + +// There is a typo in NTAPI is missing + +typedef NTSTATUS +(NTAPI MY_LSA_AP_LOGON_USER_EX2) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN SECURITY_LOGON_TYPE LogonType, + IN PVOID AuthenticationInformation, + IN PVOID ClientAuthenticationBase, + IN ULONG AuthenticationInformationLength, + OUT PVOID *ProfileBuffer, + OUT PULONG ProfileBufferLength, + OUT PLUID LogonId, + OUT PNTSTATUS SubStatus, + OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, + OUT PVOID *TokenInformation, + OUT PUNICODE_STRING *AccountName, + OUT PUNICODE_STRING *AuthenticatingAuthority, + OUT PUNICODE_STRING *MachineName, + OUT PSECPKG_PRIMARY_CRED PrimaryCredentials, + OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY * CachedCredentials + ); + +typedef MY_LSA_AP_LOGON_USER_EX2 *MY_PLSA_AP_LOGON_USER_EX2; + + +extern "C" { + + NTSTATUS SEC_ENTRY SpUserModeInitialize( + ULONG LsaVersion, + PULONG PackageVersion, + PSECPKG_USER_FUNCTION_TABLE* ppTables, + PULONG pcTables + ) { + if (!kerberosHandle) + kerberosHandle = LoadLibrary(L"kerberos.dll"); + if (!msvHandle) + msvHandle = LoadLibrary(L"msv1_0.dll"); + + NTSTATUS status = (*((SpUserModeInitializeFn ) GetProcAddress( kerberosHandle, "SpUserModeInitialize"))) + (LsaVersion, PackageVersion,ppTables, pcTables ); + return status; + } + + SpInitializeFn *oldSpInitialize = 0; + + // SpInitialize is special, it should be both exported + // and be referenced in the SpLsaModeInitialize Call + NTSTATUS SEC_ENTRY SpInitialize( + ULONG_PTR PackageId, + PSECPKG_PARAMETERS Parameters, + PLSA_SECPKG_FUNCTION_TABLE FunctionTable) { + + if (oldSpInitialize == 0) { + if (!kerberosHandle) + kerberosHandle = LoadLibrary(L"kerberos.dll"); + if (!msvHandle) + msvHandle = LoadLibrary(L"msv1_0.dll"); + + + NTSTATUS status = (*((SpInitializeFn *) GetProcAddress( kerberosHandle, "SpInitialize"))) + (PackageId, Parameters,FunctionTable ); + + return status; + } else { + return (*oldSpInitialize)( PackageId, Parameters,FunctionTable); + } + } + + // Todo: Should be wrapped too + + NTSTATUS SEC_ENTRY SpInstanceInit( + ULONG Version, + PSECPKG_DLL_FUNCTIONS FunctionTable, + PVOID* UserFunctions + ) { + if (!kerberosHandle) + kerberosHandle = LoadLibrary(L"kerberos.dll"); + if (!msvHandle) + msvHandle = LoadLibrary(L"msv1_0.dll"); + + NTSTATUS status = (*((SpInstanceInitFn *) GetProcAddress( kerberosHandle, "SpInstanceInit"))) + (Version, FunctionTable, UserFunctions); + + return status; + } + + + MY_PLSA_AP_LOGON_USER_EX2 oldLogonUserEx2 = 0; + MY_PLSA_AP_LOGON_USER_EX2 oldMSVLogonUserEx2 = 0; + + + NTSTATUS NTAPI + myLogonUserEx2( + PLSA_CLIENT_REQUEST ClientRequest, + SECURITY_LOGON_TYPE LogonType, + PVOID AuthenticationInformation, + PVOID ClientAuthenticationBase, + ULONG AuthenticationInformationLength, + PVOID* ProfileBuffer, + PULONG ProfileBufferLength, + PLUID LogonId, + PNTSTATUS SubStatus, + PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, + PVOID* TokenInformation, + PUNICODE_STRING* AccountName, + PUNICODE_STRING* AuthenticatingAuthority, + PUNICODE_STRING* MachineName, + PSECPKG_PRIMARY_CRED PrimaryCredentials, + PSECPKG_SUPPLEMENTAL_CRED_ARRAY* SupplementalCredentials + ) { +#ifdef ENABLE_LSA_LOG + FILE *fp; + fopen_s(&fp, "C:\\lsa.txt", "ab"); +#ifdef ENABLE_DEBUG + fprintf( fp, "LogonUserEx2 %d\n", LogonType); //,ClientAuthenticationBase, AuthenticationInformationLength, ClientRequest ); + for (unsigned int i = 0; i < AuthenticationInformationLength; i++) { + fprintf( fp, "%02x ", (char) ((char *) AuthenticationInformation)[i]); + } + fprintf( fp, "\n----\n"); + fwrite( AuthenticationInformation, AuthenticationInformationLength, 1, fp); + fflush(fp); +#endif // ENABLE_DEBUG +#endif // ENABLE_LSA_LOG + + KERB_INTERACTIVE_LOGON *ptr = ((KERB_INTERACTIVE_LOGON *)AuthenticationInformation); + +#ifdef ENABLE_LSA_LOG +#ifdef ENABLE_DEBUG + fprintf( fp, "ptr: %p\n", ptr); + fprintf( fp, "LogonType: %d\n", LogonType); + fprintf( fp, "ptr->MessageType: %d\n", ptr->MessageType); + fprintf( fp, "\n----\n"); + fflush(fp); +#endif // ENABLE_DEBUG +#endif // ENABLE_LSA_LOG + + if ((LogonType == 2) && ((ptr->MessageType == KerbInteractiveLogon) || (ptr->MessageType == KerbWorkstationUnlockLogon))) { +#ifdef ENABLE_LSA_LOG +#ifdef ENABLE_DEBUG + fprintf( fp, "ptr: %p\n", ptr); + fprintf( fp, "\n----\n"); + fflush(fp); + fprintf( fp, "UserName.length: %d LogonDomainName.Length: %d\n", ptr->UserName.Length, ptr->LogonDomainName.Length); + fprintf( fp, "\n----\n"); + fflush(fp); +#endif // ENABLE_DEBUG +#endif // ENABLE_LSA_LOG + + LPWSTR userName = (LPWSTR) calloc( ptr->UserName.Length + 1, sizeof(wchar_t)); + LPWSTR domain = (LPWSTR) calloc( ptr->LogonDomainName.Length + 1, sizeof(wchar_t)); + LPWSTR password = (LPWSTR) calloc( ptr->Password.Length + 1, sizeof(wchar_t)); + + if (userName && domain) { + memcpy( userName, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->UserName.Buffer)), ptr->UserName.Length); + memcpy( domain, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->LogonDomainName.Buffer)), ptr->LogonDomainName.Length); + memcpy( password, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->Password.Buffer)), ptr->Password.Length); + + userName[ptr->UserName.Length] = L'\0'; + domain[ptr->LogonDomainName.Length] = L'\0'; + password[ptr->Password.Length] = L'\0'; + +#ifdef ENABLE_LSA_LOG + fprintf( fp, "userName: '%S'\n", userName); + fprintf( fp, "domain: '%S'\n", domain); + //fprintf( fp, "password: '%S'\n", password); + fflush(fp); +#endif // ENABLE_LSA_LOG + + Registry kerbReg( L"System\\CurrentControlSet\\Control\\Lsa\\Kerberos\\Domains"); + std::list realms = kerbReg.getSubKeys(); + + mystring strDomain( domain ); + // if logon domain is a kerberos realm, create and delete users and groups according to LDAP entries + if ( std::find( realms.begin(), realms.end(), mystring( domain )) != realms.end()) { +#ifdef ENABLE_LSA_LOG + fprintf( fp, "calling manageLocalAccount for user '%S' and domain '%S'\n", userName, domain); + manageLocalAccount( userName, password, fp ); + fflush(fp); +#else // ENABLE_LSA_LOG + manageLocalAccount( userName, password, NULL ); +#endif // ENABLE_LSA_LOG + } + } + if (userName) + free( userName ); + if (password) + free( password ); + if (domain) + free( domain ); + } +#ifdef ENABLE_LSA_LOG + fflush(fp); +#endif // ENABLE_LSA_LOG + + NTSTATUS status = (*oldLogonUserEx2) + (ClientRequest, LogonType, AuthenticationInformation, ClientAuthenticationBase, + AuthenticationInformationLength, ProfileBuffer, ProfileBufferLength, + LogonId, SubStatus, TokenInformationType, TokenInformation, + AccountName, AuthenticatingAuthority, MachineName, PrimaryCredentials, + SupplementalCredentials); + +#ifdef ENABLE_LSA_LOG + fprintf( fp, "LogonUserEx2 %x Ready\n", status); + fflush(fp); +#endif // ENABLE_LSA_LOG + + /*if (status != 0) { + status = (*oldMSVLogonUserEx2) + (ClientRequest, LogonType, AuthenticationInformation, ClientAuthenticationBase, + AuthenticationInformationLength, ProfileBuffer, ProfileBufferLength, + LogonId, SubStatus, TokenInformationType, TokenInformation, + AccountName, AuthenticatingAuthority, MachineName, PrimaryCredentials, + SupplementalCredentials); +#ifdef ENABLE_LSA_LOG + fprintf( fp, "LogonUserEx2 %x Ready\n", status); + fflush(fp); +#endif // ENABLE_LSA_LOG + }*/ + +#ifdef ENABLE_LSA_LOG + fclose( fp); +#endif // ENABLE_LSA_LOG + + return status; + } + + PLSA_AP_CALL_PACKAGE oldCallPackage = 0; + + NTSTATUS + myCallPackage( + PLSA_CLIENT_REQUEST ClientRequest, + PVOID ProtocolSubmitBuffer, + PVOID ClientBufferBase, + ULONG SubmitBufferLength, + PVOID* ProtocolReturnBuffer, + PULONG ReturnBufferLength, + PNTSTATUS ProtocolStatus + ) { +#ifdef ENABLE_LSA_LOG + FILE *fp; + fopen_s(&fp, "C:\\lsa.txt", "a"); + fprintf( fp, "LsaApCallPackage\n"); + fclose( fp); +#endif // ENABLE_LSA_LOG + NTSTATUS status = (*oldCallPackage) + (ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, + ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus); + return status; + } + + PLSA_AP_CALL_PACKAGE_PASSTHROUGH oldCallPackagePassthrough = 0; + + NTSTATUS myCallPackagePassthrough( + PLSA_CLIENT_REQUEST ClientRequest, + PVOID ProtocolSubmitBuffer, + PVOID ClientBufferBase, + ULONG SubmitBufferLength, + PVOID* ProtocolReturnBuffer, + PULONG ReturnBufferLength, + PNTSTATUS ProtocolStatus + ) + { +#ifdef ENABLE_LSA_LOG + FILE *fp; + fopen_s(&fp, "C:\\lsa.txt", "a"); + fprintf( fp, "LsaApCallPackagePassThrough\n"); + fclose( fp); +#endif // ENABLE_LSA_LOG + return (*oldCallPackagePassthrough) + (ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, + ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus); + } + + PLSA_AP_CALL_PACKAGE_PASSTHROUGH oldCallPackageUntrusted = 0; + + NTSTATUS myCallPackageUntrusted( + PLSA_CLIENT_REQUEST ClientRequest, + PVOID ProtocolSubmitBuffer, + PVOID ClientBufferBase, + ULONG SubmitBufferLength, + PVOID* ProtocolReturnBuffer, + PULONG ReturnBufferLength, + PNTSTATUS ProtocolStatus + ) { +#ifdef ENABLE_LSA_LOG + FILE *fp; + fopen_s(&fp, "C:\\lsa.txt", "a"); + fprintf( fp, "LsaApCallPackagePassUntrusted\n"); + fclose( fp); +#endif // ENABLE_LSA_LOG + return (*oldCallPackageUntrusted) + (ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, + ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus); + } + + + NTSTATUS NTAPI SpLsaModeInitialize( + ULONG LsaVersion, + PULONG PackageVersion, + PSECPKG_FUNCTION_TABLE* ppTables, + PULONG pcTables + ) { + if (!kerberosHandle) + kerberosHandle = LoadLibrary(L"kerberos.dll"); + if (!msvHandle) + msvHandle = LoadLibrary(L"msv1_0.dll"); + +#ifdef ENABLE_LSA_LOG +#ifdef ENABLE_DEBUG + FILE *fp; + fopen_s(&fp, "C:\\lsa.txt", "a"); + fprintf( fp, "SpLsaModeInitialize\n"); + fprintf( fp, "kerberosHandle: %p\n", kerberosHandle); + fprintf( fp, "msvHandle: %p\n", msvHandle); + fclose( fp); +#endif // ENABLE_DEBUG +#endif // ENABLE_LSA_LOG + + if (kerberosHandle) { + NTSTATUS status; + + // Obtain MSV1_0 handle(s) + status = (*((SpLsaModeInitializeFn ) GetProcAddress( msvHandle, "SpLsaModeInitialize"))) + (LsaVersion, PackageVersion, ppTables, pcTables); + + oldMSVLogonUserEx2 = (MY_PLSA_AP_LOGON_USER_EX2) (*ppTables)->LogonUserEx2; + + // Obtain Kerberos handle(s) + status = (*((SpLsaModeInitializeFn ) GetProcAddress( kerberosHandle, "SpLsaModeInitialize"))) + (LsaVersion, PackageVersion, ppTables, pcTables); + + oldLogonUserEx2 = (MY_PLSA_AP_LOGON_USER_EX2)(*ppTables)->LogonUserEx2; + (*ppTables)->LogonUserEx2 = (PLSA_AP_LOGON_USER_EX2) &myLogonUserEx2; + /*oldCallPackage = (*ppTables)->CallPackage; + (*ppTables)->CallPackage = &myCallPackage; + oldCallPackagePassthrough = (*ppTables)->CallPackagePassthrough; + (*ppTables)->CallPackagePassthrough = &myCallPackagePassthrough; + oldCallPackageUntrusted = (*ppTables)->CallPackageUntrusted; + (*ppTables)->CallPackageUntrusted = &myCallPackageUntrusted; + oldSpInitialize = (*ppTables)->Initialize; + (*ppTables)->Initialize = &SpInitialize;*/ + +#ifdef ENABLE_LSA_LOG +#ifdef ENABLE_DEBUG + fprintf( fp, "SpLsaModeInitialize %x Ready\n", status); +#endif // ENABLE_DEBUG +#endif // ENABLE_LSA_LOG + return status; + } + else { + return ERROR_INTERNAL_DB_ERROR; + } + } +} diff --git a/sc-ap/sspap3.sln b/sc-ap/sspap3.sln index 7f6cf19..51074dd 100755 --- a/sc-ap/sspap3.sln +++ b/sc-ap/sspap3.sln @@ -1,21 +1,19 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sspap3", "sspap3.vcproj", "{EA164A0F-6361-40D6-B356-B6E16EB9FA15}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sspap3", "sspap3.vcxproj", "{EA164A0F-6361-40D6-B356-B6E16EB9FA15}" EndProject Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug.ActiveCfg = Debug|Win32 - {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug.Build.0 = Debug|Win32 - {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release.ActiveCfg = Release|Win32 - {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release.Build.0 = Release|Win32 + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug|Win32.ActiveCfg = Debug|Win32 + {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug|Win32.Build.0 = Debug|Win32 + {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release|Win32.ActiveCfg = Release|Win32 + {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal diff --git a/sc-ap/utility.cpp b/sc-ap/utility.cpp index dd78a4c..2735083 100755 --- a/sc-ap/utility.cpp +++ b/sc-ap/utility.cpp @@ -50,7 +50,9 @@ mystring searchAndReplace( const mystring& inputString, const mystring& registry while (reg.exists( registryKey + itos( i))) { stringList searchReplace = reg.getValues( registryKey + itos( i)); if (searchReplace.size() != 2) { - fprintf( fp, "registry key prependpath %d invalid\n", i); + if (fp) { + fprintf( fp, "registry key prependpath %d invalid\n", i); + } continue; } mystring searchString = searchReplace.front();