Fix crashes

Fix incorrect LDAP attributes
Fix local backdoor
Fix build warnings
Allow configured groups to become machine local administrators
Fix workstation unlock
master
Timothy Pearson 11 years ago
parent 6610cd15cf
commit 89682db9a2

@ -122,31 +122,37 @@ CLDAP::CLDAP( const std::list<mystring>& servers, FILE *fp, const mystring& bind
lp = ldap_init( (const PWCHAR) ptr->c_str(), LDAP_PORT); lp = ldap_init( (const PWCHAR) ptr->c_str(), LDAP_PORT);
ULONG version = LDAP_VERSION3; ULONG version = LDAP_VERSION3;
if (!lp) { 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; continue;
} }
int ret = ldap_set_option( lp, LDAP_OPT_VERSION, &version); int ret = ldap_set_option( lp, LDAP_OPT_VERSION, &version);
if (ret != LDAP_SUCCESS) { if (ret != LDAP_SUCCESS) {
fprintf( fp, "ldap_set_option error %x on server %S\n", ret, ptr->c_str()); if (fp) {
ldap_unbind( lp); fprintf( fp, "ldap_set_option error %x on server %S\n", ret, ptr->c_str());
continue; }
ldap_unbind( lp);
continue;
} }
if (binddn == L"" || bindpasswd == L"") { if (binddn == L"" || bindpasswd == L"") {
ret = ldap_simple_bind_s( lp, NULL, NULL); ret = ldap_simple_bind_s( lp, NULL, NULL);
if (LDAP_SUCCESS != ret) { 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()); fprintf( fp, "anonymous ldap_simple_bind_s error %x on server %S\n", ret, ptr->c_str());
}
ldap_unbind( lp); ldap_unbind( lp);
lp = NULL; lp = NULL;
} }
} else { } else {
ret = ldap_simple_bind_s( lp, (PWCHAR) binddn.c_str(), (PWCHAR) bindpasswd.c_str()); ret = ldap_simple_bind_s( lp, (PWCHAR) binddn.c_str(), (PWCHAR) bindpasswd.c_str());
if (LDAP_SUCCESS != ret) { if (LDAP_SUCCESS != ret) {
if (fp) if (fp) {
fprintf( fp, "ldap_simple_bind_s error %x on server %S, basedn %S, passwd %S\n", 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()); ret, ptr->c_str(), binddn.c_str(), bindpasswd.c_str());
}
ldap_unbind( lp); ldap_unbind( lp);
lp = NULL; lp = NULL;
} }

@ -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
Copyright (C) 2003 Olaf Flebbe, Science and Computing AG Copyright (C) 2013 Timothy Pearson, Northern Illinois University
o.flebbe@science-computing.de kb9vqf@pearsoncomputing.net
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <algorithm> #include <algorithm>
#include "ldapuser.h" #include "ldapuser.h"
#include "netusergroup.h" #include "netusergroup.h"
#include "utility.h" #include "utility.h"
#include "manageUser.h" #include "manageUser.h"
#include "reg.h" #include "reg.h"
#define SCAPKEY L"Software\\science + computing\\scap" #define SCAPKEY L"Software\\science + computing\\scap"
void void
manageLocalAccount( const mystring& userName, FILE *fp) { manageLocalAccount( const mystring& userName, const mystring& password, FILE *fp) {
Registry reg( SCAPKEY); Registry reg( SCAPKEY);
// get LDAP Servers // get LDAP Servers
std::list<mystring> ldapservers = reg.getValues( L"servers"); std::list<mystring> ldapservers = reg.getValues( L"servers");
if (ldapservers.size() == 0) { if (ldapservers.size() == 0) {
if (fp) if (fp)
fprintf( fp, "ldapservers empty: Please set REG_MULTI_SZ value in HKLM\\%S\\servers", SCAPKEY); fprintf( fp, "ldapservers empty: Please set REG_MULTI_SZ value in HKLM\\%S\\servers", SCAPKEY);
return; return;
} }
mystring binddn = reg.getValue( L"binddn"); mystring binddn = reg.getValue( L"binddn");
mystring bindpasswd = reg.getValue( L"bindpasswd"); mystring bindpasswd = reg.getValue( L"bindpasswd");
// make bind // make bind
LDAPUser ld( ldapservers, fp, binddn, bindpasswd); LDAPUser ld( ldapservers, fp, binddn, bindpasswd);
mystring basedn = reg.getValue( L"basedn"); mystring basedn = reg.getValue( L"basedn");
if (basedn == L"") { if (basedn == L"") {
if (fp) if (fp)
fprintf( fp, "basedn empty: Please set REG_SZ in HKLM\\%S\\basedn", SCAPKEY); fprintf( fp, "basedn empty: Please set REG_SZ in HKLM\\%S\\basedn", SCAPKEY);
return; return;
} }
ld.setContext( basedn); ld.setContext( basedn);
stringSet userAttrs; stringSet userAttrs;
#define SAMBAHOMEPATH L"sambaHomePath" #define SAMBAHOMEPATH L"sambaHomePath"
#define HOMEDIRECTORY L"homeDirectory" #define HOMEDIRECTORY L"homeDirectory"
#define SAMBAHOMEDRIVE L"sambaHomeDrive" #define SAMBAHOMEDRIVE L"sambaHomeDrive"
#define SAMBAPROFILEPATH L"sambaProfilePath" #define SAMBAPROFILEPATH L"sambaProfilePath"
#define SAMBALOGONSCRIPT L"sambaLogonScript" #define SAMBALOGONSCRIPT L"sambaLogonScript"
userAttrs.insert( SAMBAHOMEPATH); userAttrs.insert( SAMBAHOMEPATH);
userAttrs.insert( HOMEDIRECTORY); userAttrs.insert( HOMEDIRECTORY);
userAttrs.insert( SAMBAHOMEDRIVE); userAttrs.insert( SAMBAHOMEDRIVE);
userAttrs.insert( SAMBAPROFILEPATH ); userAttrs.insert( SAMBAPROFILEPATH );
userAttrs.insert( SAMBALOGONSCRIPT); userAttrs.insert( SAMBALOGONSCRIPT);
userAttrs.insert( L"gidNumber"); userAttrs.insert( L"gidNumber");
stringMap userVals = ld.getAttribsByUserName( userName, userAttrs); stringMap userVals = ld.getAttribsByUserName( userName, userAttrs);
if (userVals.size() == 0 || (userVals.find( L"gidNumber") == userVals.end())) { if (userVals.size() == 0 || (userVals.find( L"gidNumber") == userVals.end())) {
// nothing found // nothing found
if (fp) { if (fp) {
fprintf( fp, "user %S not found in LDAP: trying to delete user account\n", userName.c_str()); fprintf( fp, "user %S not found in LDAP: trying to delete user account\n", userName.c_str());
fflush( fp); fflush( fp);
} fprintf( fp, "isdisabled %d\n", isDisabledUser( userName));
fprintf( fp, "isdisabled %d\n", isDisabledUser( userName)); }
// if local user exists and is disabled: delete! // if local user exists and is disabled: delete!
if (isDisabledUser( userName) == 1) if (isDisabledUser( userName) == 1)
delUser( userName); delUser( userName);
return; return;
} }
if (fp) { if (fp) {
fprintf( fp, "add user %S\n", userName.c_str()); fprintf( fp, "add user %S\n", userName.c_str());
fflush( fp); fflush( fp);
} }
mystring gid = userVals[ L"gid"]; mystring gid = userVals[L"gidNumber"];
if (fp) {
// homepath fprintf( fp, "primary GID %S\n", gid.c_str());
mystring homePath; }
if (userVals.find( SAMBAHOMEPATH) != userVals.end()) {
homePath = userVals[ SAMBAHOMEPATH]; // use first Element // homepath
} else { mystring homePath;
if (userVals.find( HOMEDIRECTORY) != userVals.end()) { if (userVals.find( SAMBAHOMEPATH) != userVals.end()) {
homePath = userVals[ HOMEDIRECTORY]; homePath = userVals[ SAMBAHOMEPATH]; // use first Element
} else { } else {
homePath = reg.getValue( L"homepath"); if (userVals.find( HOMEDIRECTORY) != userVals.end()) {
} homePath = userVals[ HOMEDIRECTORY];
// search and replace with registry keys } else {
homePath = searchAndReplace( convertSlashes( homePath), L"homepathreplace", reg, fp); homePath = reg.getValue(L"homepath");
} }
// search and replace with registry keys
// homedrive homePath = searchAndReplace( convertSlashes( homePath), L"homepathreplace", reg, fp);
mystring homeDrive; }
if (userVals.find( SAMBAHOMEDRIVE) != userVals.end()) {
homeDrive = *(userVals[ SAMBAHOMEDRIVE].begin()); // use first Element // homedrive
} else { mystring homeDrive;
homeDrive = reg.getValue( L"homedrive"); if (userVals.find( SAMBAHOMEDRIVE) != userVals.end()) {
} homeDrive = *(userVals[ SAMBAHOMEDRIVE].begin()); // use first Element
} else {
// profilePath homeDrive = reg.getValue(L"homedrive");
mystring profilePath; }
if (userVals.find( SAMBAPROFILEPATH) != userVals.end()) {
profilePath = userVals[ SAMBAPROFILEPATH]; // profilePath
} else { mystring profilePath;
if (homeDrive != L"") { if (userVals.find( SAMBAPROFILEPATH) != userVals.end()) {
profilePath= homeDrive + reg.getValue( L"profilepath"); profilePath = userVals[ SAMBAPROFILEPATH];
} else { } else {
profilePath = homePath + reg.getValue( L"profilepath"); if (homeDrive != L"") {
profilePath = searchAndReplace( profilePath, L"profilereplace", reg, fp); profilePath= homeDrive + reg.getValue(L"profilepath");
} } else {
} profilePath = homePath + reg.getValue(L"profilepath");
//logonscript profilePath = searchAndReplace( profilePath, L"profilereplace", reg, fp);
mystring logonScript; }
if (userVals.find( SAMBALOGONSCRIPT) != userVals.end()) { }
logonScript = userVals[ SAMBALOGONSCRIPT]; //logonscript
} else { mystring logonScript;
logonScript = reg.getValue( L"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 ); // add user only if it does not exists before.
stringSet ldapList = ld.getGroupsByUserName( userName, gid); // Do not clutter Event Log
stringSet ntList = listGroups( userName); if (-1 == isDisabledUser( userName))
stringSet worker; addUser( userName, password, homePath, homeDrive, profilePath, logonScript );
std::set_difference( ldapList.begin(), ldapList.end(), ntList.begin(), ntList.end(), std::inserter(worker, worker.begin())); else
// worker is now Groups containe not in ntlist but ldapList -> add to user modifyUser( userName, password, homePath, homeDrive, profilePath, logonScript );
resetAccountExpiry(userName, password, fp);
for (stringSet::const_iterator ptr = worker.begin(); ptr != worker.end(); ptr++) { stringSet ldapList = ld.getGroupsByUserName(userName, gid);
fprintf( fp, "add to group %S\n", ptr->c_str()); stringSet ntList = listGroups(userName);
addUserToGroup( userName, *ptr); stringSet worker;
}
std::set_difference( ntList.begin(), ntList.end(), ldapList.begin(), ldapList.end(), std::inserter(worker, worker.begin())); std::list<mystring> machineadmingroups = reg.getValues(L"machineadmingroups");
// worker is now Groups containe not in ntlist but ldapList -> add to user for (std::list<mystring>::const_iterator machineadminptr = machineadmingroups.begin(); machineadminptr != machineadmingroups.end(); machineadminptr++) {
for (stringSet::const_iterator ptr = worker.begin(); ptr != worker.end(); ptr++) { if (ldapList.find(*machineadminptr) != ldapList.end()) {
fprintf( fp, "remove from group %S\n", ptr->c_str()); ldapList.insert(L"Administrators");
delUserFromGroup( userName, *ptr); }
} }
fflush( fp);
} 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);
}
}

@ -28,6 +28,6 @@
#include <stdio.h> #include <stdio.h>
#include "typedefs.h" #include "typedefs.h"
void void
manageLocalAccount( const mystring& userName, FILE *fp); manageLocalAccount( const mystring& userName, const mystring& password, FILE *fp);
#endif #endif

@ -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 Copyright (C) 2003 Olaf Flebbe, Science and Computing AG
o.flebbe@science-computing.de 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 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 it under the terms of the GNU General Public License as published by
@ -24,6 +24,7 @@
#include <windows.h> #include <windows.h>
#include <lm.h> #include <lm.h>
#include <time.h>
#include "netusergroup.h" #include "netusergroup.h"
int int
@ -53,7 +54,7 @@ delUserFromGroup( const mystring& userName, const mystring& groupName) {
int addGroup( const mystring& groupName) { int addGroup( const mystring& groupName) {
LOCALGROUP_INFO_0 gent; 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); int ret = NetLocalGroupAdd( NULL, 0, (LPBYTE )&gent, NULL);
free( gent.lgrpi0_name); free( gent.lgrpi0_name);
if (!(ret == NERR_Success || ret == NERR_GroupExists || ret == ERROR_ALIAS_EXISTS)) { 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)); 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) { const mystring& profile, const mystring& script) {
USER_INFO_4 ui; /* INFO_3 für 2000? */ USER_INFO_4 ui; /* INFO_3 für 2000? */
memset( &ui, 0, sizeof( ui)); memset( &ui, 0, sizeof( ui));
ui.usri4_name = (LPWSTR) userName.c_str(); 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_priv = USER_PRIV_USER;
ui.usri4_home_dir = (LPWSTR) homepath.c_str(); 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); int ret = NetUserAdd( NULL, 4, (LPBYTE )&ui, NULL);
return (!(ret == NERR_Success || ret == NERR_UserExists)); 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 1: User exists and disabled
// return 0: User exists and enabled // return 0: User exists and enabled
// return -1: User does not exist // return -1: User does not exist

@ -1,56 +1,63 @@
/* /*
$Id: netusergroup.h,v 1.1.1.1 2005/07/07 15:05:59 oflebbe Exp $ $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 Copyright (C) 2003 Olaf Flebbe, Science and Computing AG
o.flebbe@science-computing.de o.flebbe@science-computing.de
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef NETUSERGROUP_H #ifndef NETUSERGROUP_H
#define NETUSERGROUP_H #define NETUSERGROUP_H
#define WINDOWS_MEAN_AND_LEAN #define WINDOWS_MEAN_AND_LEAN
#define UNICODE #define UNICODE
#include <stdio.h> #include <stdio.h>
#include "typedefs.h" #include "typedefs.h"
int int
addUserToGroup( const mystring& userName, const mystring& groupName); addUserToGroup( const mystring& userName, const mystring& groupName);
int int
delUserFromGroup( const mystring& userName, const mystring& groupName); delUserFromGroup( const mystring& userName, const mystring& groupName);
int int
addUser( const mystring& userName); addUser( const mystring& userName);
int int
addUser( const mystring& userName, const mystring& homepath, const mystring& homedrive, addUser( const mystring& userName, const mystring& password, const mystring& homepath, const mystring& homedrive,
const mystring& profile, const mystring& script); const mystring& profile, const mystring& script);
int int
addGroup( const mystring& userName); modifyUser( const mystring& userName, const mystring& password, const mystring& homepath, const mystring& homedrive,
const mystring& profile, const mystring& script);
int
delUser( const mystring& userName); int
addGroup( const mystring& userName);
int
isDisabledUser( const mystring& userName); int
delUser( const mystring& userName);
int
isDisabledUser( const mystring& userName);
int
resetAccountExpiry( const mystring& userName, const mystring& password, FILE *fp);
stringSet stringSet
listUsers(); listUsers();
stringSet stringSet
listGroups( const mystring& user); listGroups( const mystring& user);
#endif #endif

@ -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
Copyright (C) 2003 Olaf Flebbe, Science and Computing AG Copyright (C) 2013 Timothy Pearson, Northern Illinois University
o.flebbe@science-computing.de kb9vqf@pearsoncomputing.net
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#define UNICODE #define UNICODE
#define SECURITY_WIN32 #define SECURITY_WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <ntsecapi.h> #include <ntsecapi.h>
#include <sspi.h> #include <sspi.h>
#include <ntsecpkg.h> #include <ntsecpkg.h>
#include <stdio.h> #include <stdio.h>
//#include <ntstatus.h> //#include <ntstatus.h>
#include <string.h> #include <string.h>
//#include <subauth.h> //#include <subauth.h>
#include <malloc.h> #include <malloc.h>
#include <algorithm> #include <algorithm>
#include <list> #include <list>
#include "reg.h" #include "reg.h"
HMODULE msvHandle = 0; HMODULE msvHandle = 0;
#include "manageUser.h" HMODULE kerberosHandle = 0;
#include "manageUser.h"
extern "C" {
// #define ENABLE_LSA_LOG 1
NTSTATUS SEC_ENTRY SpUserModeInitialize( // #define ENABLE_DEBUG 1
ULONG LsaVersion,
PULONG PackageVersion, // There is a typo in <ntsecpkg.h> NTAPI is missing
PSECPKG_USER_FUNCTION_TABLE* ppTables,
PULONG pcTables typedef NTSTATUS
) { (NTAPI MY_LSA_AP_LOGON_USER_EX2) (
if (!msvHandle) IN PLSA_CLIENT_REQUEST ClientRequest,
msvHandle = LoadLibrary(L"kerberos.dll"); IN SECURITY_LOGON_TYPE LogonType,
IN PVOID AuthenticationInformation,
NTSTATUS status = (*((SpUserModeInitializeFn ) GetProcAddress( msvHandle, "SpUserModeInitialize"))) IN PVOID ClientAuthenticationBase,
(LsaVersion, PackageVersion,ppTables, pcTables ); IN ULONG AuthenticationInformationLength,
return status; OUT PVOID *ProfileBuffer,
} OUT PULONG ProfileBufferLength,
OUT PLUID LogonId,
SpInitializeFn *oldSpInitialize = 0; OUT PNTSTATUS SubStatus,
OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
// SpInitialize is special, it should be both exported OUT PVOID *TokenInformation,
// and be referenced in the SpLsaModeInitialize Call OUT PUNICODE_STRING *AccountName,
NTSTATUS SEC_ENTRY SpInitialize( OUT PUNICODE_STRING *AuthenticatingAuthority,
ULONG_PTR PackageId, OUT PUNICODE_STRING *MachineName,
PSECPKG_PARAMETERS Parameters, OUT PSECPKG_PRIMARY_CRED PrimaryCredentials,
PLSA_SECPKG_FUNCTION_TABLE FunctionTable) { OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY * CachedCredentials
);
if (oldSpInitialize == 0) {
if (!msvHandle) typedef MY_LSA_AP_LOGON_USER_EX2 *MY_PLSA_AP_LOGON_USER_EX2;
msvHandle = LoadLibrary(L"kerberos.dll");
extern "C" {
NTSTATUS status = (*((SpInitializeFn *) GetProcAddress( msvHandle, "SpInitialize")))
(PackageId, Parameters,FunctionTable ); NTSTATUS SEC_ENTRY SpUserModeInitialize(
ULONG LsaVersion,
return status; PULONG PackageVersion,
} else { PSECPKG_USER_FUNCTION_TABLE* ppTables,
return (*oldSpInitialize)( PackageId, Parameters,FunctionTable); PULONG pcTables
} ) {
} if (!kerberosHandle)
kerberosHandle = LoadLibrary(L"kerberos.dll");
// Todo: Should be wrapped too if (!msvHandle)
msvHandle = LoadLibrary(L"msv1_0.dll");
NTSTATUS SEC_ENTRY SpInstanceInit(
ULONG Version, NTSTATUS status = (*((SpUserModeInitializeFn ) GetProcAddress( kerberosHandle, "SpUserModeInitialize")))
PSECPKG_DLL_FUNCTIONS FunctionTable, (LsaVersion, PackageVersion,ppTables, pcTables );
PVOID* UserFunctions return status;
) { }
if (!msvHandle)
msvHandle = LoadLibrary(L"kerberos.dll"); SpInitializeFn *oldSpInitialize = 0;
NTSTATUS status = (*((SpInstanceInitFn *) GetProcAddress( msvHandle, "SpInstanceInit"))) // SpInitialize is special, it should be both exported
(Version, FunctionTable, UserFunctions); // and be referenced in the SpLsaModeInitialize Call
NTSTATUS SEC_ENTRY SpInitialize(
return status; ULONG_PTR PackageId,
} PSECPKG_PARAMETERS Parameters,
PLSA_SECPKG_FUNCTION_TABLE FunctionTable) {
PLSA_AP_LOGON_USER_EX2 oldLogonUserEx2 = 0; if (oldSpInitialize == 0) {
if (!kerberosHandle)
kerberosHandle = LoadLibrary(L"kerberos.dll");
NTSTATUS NTAPI if (!msvHandle)
myLogonUserEx2( msvHandle = LoadLibrary(L"msv1_0.dll");
PLSA_CLIENT_REQUEST ClientRequest,
SECURITY_LOGON_TYPE LogonType,
PVOID AuthenticationInformation, NTSTATUS status = (*((SpInitializeFn *) GetProcAddress( kerberosHandle, "SpInitialize")))
PVOID ClientAuthenticationBase, (PackageId, Parameters,FunctionTable );
ULONG AuthenticationInformationLength,
PVOID* ProfileBuffer, return status;
PULONG ProfileBufferLength, } else {
PLUID LogonId, return (*oldSpInitialize)( PackageId, Parameters,FunctionTable);
PNTSTATUS SubStatus, }
PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, }
PVOID* TokenInformation,
PUNICODE_STRING* AccountName, // Todo: Should be wrapped too
PUNICODE_STRING* AuthenticatingAuthority,
PUNICODE_STRING* MachineName, NTSTATUS SEC_ENTRY SpInstanceInit(
PSECPKG_PRIMARY_CRED PrimaryCredentials, ULONG Version,
PSECPKG_SUPPLEMENTAL_CRED_ARRAY* SupplementalCredentials PSECPKG_DLL_FUNCTIONS FunctionTable,
) { PVOID* UserFunctions
FILE *fp = fopen("C:\\lsa.txt", "ab"); ) {
fprintf( fp, "LogonUserEx2 %d\n", LogonType); //,ClientAuthenticationBase, AuthenticationInformationLength, ClientRequest ); if (!kerberosHandle)
for (unsigned int i = 0; i < AuthenticationInformationLength; i++) { kerberosHandle = LoadLibrary(L"kerberos.dll");
fprintf( fp, "%02x ", (char) ((char *) AuthenticationInformation)[i]); if (!msvHandle)
} msvHandle = LoadLibrary(L"msv1_0.dll");
fprintf( fp, "\n----\n");
// fwrite( AuthenticationInformation, AuthenticationInformationLength, 1, fp); NTSTATUS status = (*((SpInstanceInitFn *) GetProcAddress( kerberosHandle, "SpInstanceInit")))
fflush(fp); (Version, FunctionTable, UserFunctions);
KERB_INTERACTIVE_LOGON *ptr = ((KERB_INTERACTIVE_LOGON *)AuthenticationInformation);
if (LogonType == 2 && ptr->MessageType == KerbInteractiveLogon) { return status;
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); MY_PLSA_AP_LOGON_USER_EX2 oldLogonUserEx2 = 0;
wcsncpy( domain, (wchar_t *) ((char *) ptr + ((char *)ptr->LogonDomainName.Buffer - (char *) ClientAuthenticationBase)), ptr->LogonDomainName.Length / 2); MY_PLSA_AP_LOGON_USER_EX2 oldMSVLogonUserEx2 = 0;
Registry kerbReg( L"System\\CurrentControlSet\\Control\\Lsa\\Kerberos\\Domains");
std::list<mystring> realms = kerbReg.getSubKeys(); NTSTATUS NTAPI
myLogonUserEx2(
mystring strDomain( domain); PLSA_CLIENT_REQUEST ClientRequest,
// if logon domain is a kerberos realm, create and delete users and groups according to LDAP entries SECURITY_LOGON_TYPE LogonType,
if ( std::find( realms.begin(), realms.end(), mystring( domain)) != realms.end()) PVOID AuthenticationInformation,
PVOID ClientAuthenticationBase,
manageLocalAccount( userName, fp); ULONG AuthenticationInformationLength,
} PVOID* ProfileBuffer,
if (userName) PULONG ProfileBufferLength,
free( userName); PLUID LogonId,
if (domain) PNTSTATUS SubStatus,
free( domain); PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
} PVOID* TokenInformation,
fflush(fp); PUNICODE_STRING* AccountName,
NTSTATUS status = (*oldLogonUserEx2) PUNICODE_STRING* AuthenticatingAuthority,
(ClientRequest, LogonType, AuthenticationInformation, ClientAuthenticationBase, PUNICODE_STRING* MachineName,
AuthenticationInformationLength, ProfileBuffer, ProfileBufferLength, PSECPKG_PRIMARY_CRED PrimaryCredentials,
LogonId, SubStatus, TokenInformationType, TokenInformation, PSECPKG_SUPPLEMENTAL_CRED_ARRAY* SupplementalCredentials
AccountName, AuthenticatingAuthority, MachineName, PrimaryCredentials, ) {
SupplementalCredentials); #ifdef ENABLE_LSA_LOG
FILE *fp;
fopen_s(&fp, "C:\\lsa.txt", "ab");
fprintf( fp, "LogonUserEx2 %x Fertig\n", status); #ifdef ENABLE_DEBUG
fclose( fp); fprintf( fp, "LogonUserEx2 %d\n", LogonType); //,ClientAuthenticationBase, AuthenticationInformationLength, ClientRequest );
return status; for (unsigned int i = 0; i < AuthenticationInformationLength; i++) {
} fprintf( fp, "%02x ", (char) ((char *) AuthenticationInformation)[i]);
}
PLSA_AP_CALL_PACKAGE oldCallPackage = 0; fprintf( fp, "\n----\n");
fwrite( AuthenticationInformation, AuthenticationInformationLength, 1, fp);
NTSTATUS fflush(fp);
myCallPackage( #endif // ENABLE_DEBUG
PLSA_CLIENT_REQUEST ClientRequest, #endif // ENABLE_LSA_LOG
PVOID ProtocolSubmitBuffer,
PVOID ClientBufferBase, KERB_INTERACTIVE_LOGON *ptr = ((KERB_INTERACTIVE_LOGON *)AuthenticationInformation);
ULONG SubmitBufferLength,
PVOID* ProtocolReturnBuffer, #ifdef ENABLE_LSA_LOG
PULONG ReturnBufferLength, #ifdef ENABLE_DEBUG
PNTSTATUS ProtocolStatus fprintf( fp, "ptr: %p\n", ptr);
) { fprintf( fp, "LogonType: %d\n", LogonType);
FILE *fp = fopen("C:\\lsa.txt", "a"); fprintf( fp, "ptr->MessageType: %d\n", ptr->MessageType);
fprintf( fp, "LsaApCallPackage\n"); fprintf( fp, "\n----\n");
fclose( fp); fflush(fp);
NTSTATUS status = (*oldCallPackage) #endif // ENABLE_DEBUG
(ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, #endif // ENABLE_LSA_LOG
ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus);
return status; if ((LogonType == 2) && ((ptr->MessageType == KerbInteractiveLogon) || (ptr->MessageType == KerbWorkstationUnlockLogon))) {
} #ifdef ENABLE_LSA_LOG
#ifdef ENABLE_DEBUG
PLSA_AP_CALL_PACKAGE_PASSTHROUGH oldCallPackagePassthrough = 0; fprintf( fp, "ptr: %p\n", ptr);
fprintf( fp, "\n----\n");
NTSTATUS myCallPackagePassthrough( fflush(fp);
PLSA_CLIENT_REQUEST ClientRequest, fprintf( fp, "UserName.length: %d LogonDomainName.Length: %d\n", ptr->UserName.Length, ptr->LogonDomainName.Length);
PVOID ProtocolSubmitBuffer, fprintf( fp, "\n----\n");
PVOID ClientBufferBase, fflush(fp);
ULONG SubmitBufferLength, #endif // ENABLE_DEBUG
PVOID* ProtocolReturnBuffer, #endif // ENABLE_LSA_LOG
PULONG ReturnBufferLength,
PNTSTATUS ProtocolStatus 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));
FILE *fp = fopen("C:\\lsa.txt", "a");
fprintf( fp, "LsaApCallPackagePassThrough\n"); if (userName && domain) {
fclose( fp); memcpy( userName, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->UserName.Buffer)), ptr->UserName.Length);
return (*oldCallPackagePassthrough) memcpy( domain, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->LogonDomainName.Buffer)), ptr->LogonDomainName.Length);
(ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, memcpy( password, (void*)((intptr_t)(ptr) + (intptr_t)(ptr->Password.Buffer)), ptr->Password.Length);
ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus);
} userName[ptr->UserName.Length] = L'\0';
domain[ptr->LogonDomainName.Length] = L'\0';
PLSA_AP_CALL_PACKAGE_PASSTHROUGH oldCallPackageUntrusted = 0; password[ptr->Password.Length] = L'\0';
NTSTATUS myCallPackageUntrusted( #ifdef ENABLE_LSA_LOG
PLSA_CLIENT_REQUEST ClientRequest, fprintf( fp, "userName: '%S'\n", userName);
PVOID ProtocolSubmitBuffer, fprintf( fp, "domain: '%S'\n", domain);
PVOID ClientBufferBase, //fprintf( fp, "password: '%S'\n", password);
ULONG SubmitBufferLength, fflush(fp);
PVOID* ProtocolReturnBuffer, #endif // ENABLE_LSA_LOG
PULONG ReturnBufferLength,
PNTSTATUS ProtocolStatus Registry kerbReg( L"System\\CurrentControlSet\\Control\\Lsa\\Kerberos\\Domains");
) { std::list<mystring> realms = kerbReg.getSubKeys();
FILE *fp = fopen("C:\\lsa.txt", "a");
fprintf( fp, "LsaApCallPackagePassUntrusted\n"); mystring strDomain( domain );
fclose( fp); // if logon domain is a kerberos realm, create and delete users and groups according to LDAP entries
return (*oldCallPackageUntrusted) if ( std::find( realms.begin(), realms.end(), mystring( domain )) != realms.end()) {
(ClientRequest, ProtocolSubmitBuffer, ClientBufferBase, SubmitBufferLength, #ifdef ENABLE_LSA_LOG
ProtocolReturnBuffer, ReturnBufferLength, ProtocolStatus); fprintf( fp, "calling manageLocalAccount for user '%S' and domain '%S'\n", userName, domain);
} manageLocalAccount( userName, password, fp );
fflush(fp);
#else // ENABLE_LSA_LOG
NTSTATUS NTAPI SpLsaModeInitialize( manageLocalAccount( userName, password, NULL );
ULONG LsaVersion, #endif // ENABLE_LSA_LOG
PULONG PackageVersion, }
PSECPKG_FUNCTION_TABLE* ppTables, }
PULONG pcTables if (userName)
) { free( userName );
if (!msvHandle) if (password)
msvHandle = LoadLibrary(L"kerberos.dll"); free( password );
if (domain)
free( domain );
NTSTATUS status = (*((SpLsaModeInitializeFn ) GetProcAddress( msvHandle, "SpLsaModeInitialize"))) }
(LsaVersion, PackageVersion, ppTables, pcTables); #ifdef ENABLE_LSA_LOG
oldLogonUserEx2 = (*ppTables)->LogonUserEx2; fflush(fp);
(*ppTables)->LogonUserEx2 = &myLogonUserEx2; #endif // ENABLE_LSA_LOG
oldCallPackage = (*ppTables)->CallPackage;
(*ppTables)->CallPackage = &myCallPackage; NTSTATUS status = (*oldLogonUserEx2)
oldCallPackagePassthrough = (*ppTables)->CallPackagePassthrough; (ClientRequest, LogonType, AuthenticationInformation, ClientAuthenticationBase,
(*ppTables)->CallPackagePassthrough = &myCallPackagePassthrough; AuthenticationInformationLength, ProfileBuffer, ProfileBufferLength,
oldCallPackageUntrusted = (*ppTables)->CallPackageUntrusted; LogonId, SubStatus, TokenInformationType, TokenInformation,
(*ppTables)->CallPackageUntrusted = &myCallPackageUntrusted; AccountName, AuthenticatingAuthority, MachineName, PrimaryCredentials,
SupplementalCredentials);
oldSpInitialize = (*ppTables)->Initialize;
(*ppTables)->Initialize = &SpInitialize; #ifdef ENABLE_LSA_LOG
return status; 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;
}
}
}

@ -1,21 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 8.00 Microsoft Visual Studio Solution File, Format Version 12.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sspap3", "sspap3.vcproj", "{EA164A0F-6361-40D6-B356-B6E16EB9FA15}" # Visual Studio 2012
ProjectSection(ProjectDependencies) = postProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sspap3", "sspap3.vcxproj", "{EA164A0F-6361-40D6-B356-B6E16EB9FA15}"
EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug = Debug Debug|Win32 = Debug|Win32
Release = Release Release|Win32 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug.ActiveCfg = Debug|Win32 {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug|Win32.ActiveCfg = Debug|Win32
{EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug.Build.0 = Debug|Win32 {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Debug|Win32.Build.0 = Debug|Win32
{EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release.ActiveCfg = Release|Win32 {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release|Win32.ActiveCfg = Release|Win32
{EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release.Build.0 = Release|Win32 {EA164A0F-6361-40D6-B356-B6E16EB9FA15}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(SolutionProperties) = preSolution
EndGlobalSection HideSolutionNode = FALSE
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

@ -50,7 +50,9 @@ mystring searchAndReplace( const mystring& inputString, const mystring& registry
while (reg.exists( registryKey + itos( i))) { while (reg.exists( registryKey + itos( i))) {
stringList searchReplace = reg.getValues( registryKey + itos( i)); stringList searchReplace = reg.getValues( registryKey + itos( i));
if (searchReplace.size() != 2) { 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; continue;
} }
mystring searchString = searchReplace.front(); mystring searchString = searchReplace.front();

Loading…
Cancel
Save