summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-03-26 10:35:25 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-03-26 10:35:25 -0500
commit6610cd15cf186fe1f8e82628f6f12aa2c490bac2 (patch)
treeb90a0c31fdb5bdb33a0711b1f28ab26d0ef735d1
downloadwindows-ldap-integration-6610cd15cf186fe1f8e82628f6f12aa2c490bac2.tar.gz
windows-ldap-integration-6610cd15cf186fe1f8e82628f6f12aa2c490bac2.zip
Initial import of abandoned sc-ap project
-rwxr-xr-xsc-ap/ldap1.cpp157
-rwxr-xr-xsc-ap/ldap1.h54
-rwxr-xr-xsc-ap/ldapuser.cpp51
-rwxr-xr-xsc-ap/ldapuser.h14
-rwxr-xr-xsc-ap/manageUser.cpp159
-rwxr-xr-xsc-ap/manageUser.h33
-rwxr-xr-xsc-ap/netusergroup.cpp260
-rwxr-xr-xsc-ap/netusergroup.h56
-rwxr-xr-xsc-ap/reg.cpp144
-rwxr-xr-xsc-ap/reg.h44
-rwxr-xr-xsc-ap/sspap3.cpp249
-rwxr-xr-xsc-ap/sspap3.def9
-rwxr-xr-xsc-ap/sspap3.sln21
-rwxr-xr-xsc-ap/sspap3.vcproj182
-rwxr-xr-xsc-ap/typedefs.h14
-rwxr-xr-xsc-ap/utility.cpp68
-rwxr-xr-xsc-ap/utility.h34
17 files changed, 1549 insertions, 0 deletions
diff --git a/sc-ap/ldap1.cpp b/sc-ap/ldap1.cpp
new file mode 100755
index 0000000..435c210
--- /dev/null
+++ b/sc-ap/ldap1.cpp
@@ -0,0 +1,157 @@
+/*
+ $Id: ldap1.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 WINDOWS_MEAN_AND_LEAN
+#define UNICODE
+
+#include "ldap1.h"
+
+void
+CLDAP::do_query( const mystring& filter, const wchar_t *attrs[]) {
+ if (fp) {
+ fprintf(fp, "do_query %S\n", filter.c_str());
+ fflush(fp);
+ }
+
+ // this is extremly ugly: Why can't the compile not cast a wchar_t * to a PWCHAR???
+ ldap_search_s( lp, (const PWCHAR) context.c_str(), LDAP_SCOPE_SUBTREE,
+ (const PWCHAR) filter.c_str(), (PWCHAR *) attrs, 0, &msg);
+ if (fp) {
+ fprintf(fp, "after ldap_search\n");
+ fflush(fp);
+ }
+ if (msg != NULL) {
+ msg = ldap_first_entry( lp, msg);
+ }
+}
+mystring
+CLDAP::queryAttr( const mystring &filter, const mystring &attr, bool *exists) {
+
+ const wchar_t *attrs[]= { attr.c_str(), NULL} ; //= { attr.c_str(), NULL };
+
+ do_query( filter, attrs);
+ if (exists != NULL)
+ *exists = true;
+ while ( msg != NULL) {
+ BerElement *berPtr;
+ wchar_t *attrPtr = ldap_first_attribute( lp, msg, &berPtr);
+ while (attrPtr != NULL) {
+ wchar_t **valList = ldap_get_values( lp, msg, attrPtr);
+ for (unsigned int i = 0; i < ldap_count_values( valList); i++)
+ return mystring( valList[i]);
+ attrPtr = ldap_next_attribute( lp, msg, berPtr);
+ }
+ }
+ if (exists != NULL)
+ *exists = false;
+ return mystring(L"");
+}
+
+stringSet
+CLDAP::queryListOfAttr( const mystring &filter, const mystring &attr) {
+ stringSet listOfVal;
+ const wchar_t *attrs[]= { attr.c_str(), NULL} ; //= { attr.c_str(), NULL };
+ do_query( filter, attrs);
+ while ( msg != NULL) {
+ BerElement *berPtr;
+ wchar_t *attrPtr = ldap_first_attribute( lp, msg, &berPtr);
+ while (attrPtr != NULL) {
+ wchar_t **valList = ldap_get_values( lp, msg, attrPtr);
+ for (unsigned int i = 0; i < ldap_count_values( valList); i++)
+ listOfVal.insert( mystring( valList[i]));
+ attrPtr = ldap_next_attribute( lp, msg, berPtr);
+ }
+ msg = ldap_next_entry( lp, msg);
+ }
+ return listOfVal;
+}
+
+stringMap
+CLDAP::querySetOfAttrs( const mystring &filter, const stringSet &attr) {
+ stringMap mapOfVal;
+
+ const wchar_t **attrs;
+ attrs = (const wchar_t **) malloc( sizeof( wchar_t *) * (attr.size()+1));
+ for (unsigned int i = 0; i < attr.size()+1; i++)
+ attrs[i] = NULL;
+
+ const wchar_t **pat = attrs;
+
+ for (stringSet::const_iterator ptr = attr.begin(); ptr != attr.end(); ptr++) {
+ *pat++ = ptr->c_str();
+ }
+
+
+ do_query( filter, attrs);
+ while ( msg != NULL) {
+ BerElement *berPtr;
+ wchar_t *attrPtr = ldap_first_attribute( lp, msg, &berPtr);
+ while (attrPtr != NULL) {
+ wchar_t **valList = ldap_get_values( lp, msg, attrPtr);
+
+ mapOfVal[ mystring( attrPtr)] = mystring( valList[0]);
+ attrPtr = ldap_next_attribute( lp, msg, berPtr);
+ }
+ msg = ldap_next_entry( lp, msg);
+ }
+ return mapOfVal;
+}
+
+CLDAP::CLDAP( const std::list<mystring>& servers, FILE *fp, const mystring& binddn, const mystring& bindpasswd) {
+ this->fp = fp;
+ msg = NULL;
+ for ( std::list<mystring>::const_iterator ptr = servers.begin(); ptr != servers.end(); ptr++) {
+ 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());
+ 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 (binddn == L"" || bindpasswd == L"") {
+ ret = ldap_simple_bind_s( lp, NULL, NULL);
+ if (LDAP_SUCCESS != ret) {
+ 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)
+ 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;
+ }
+ }
+ return;
+ }
+}
+
diff --git a/sc-ap/ldap1.h b/sc-ap/ldap1.h
new file mode 100755
index 0000000..6f86b7c
--- /dev/null
+++ b/sc-ap/ldap1.h
@@ -0,0 +1,54 @@
+/*
+ $Id: ldap1.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 LDAP1_H
+#define LDAP1_H
+
+#define UNICODE
+#define WINDOWS_LEAN_AND_MEAN
+
+#include <windows.h>
+#include <lm.h>
+#include <winldap.h>
+#include "typedefs.h"
+
+class CLDAP {
+private:
+ FILE *fp;
+ LDAP *lp;
+ mystring context;
+ LDAPMessage *msg;
+
+protected:
+ void do_query( const mystring& filter, const wchar_t *attrs[]);
+ mystring queryAttr( const mystring &filter, const mystring &attr, bool *exists = NULL);
+ stringSet queryListOfAttr( const mystring &filter, const mystring &attr);
+ stringMap querySetOfAttrs( const mystring &filter, const stringSet &attr);
+
+public:
+ CLDAP( const std::list<mystring>& host, FILE *fp, const mystring& binddn, const mystring& bindpasswd);
+ void setContext( const mystring &context) {
+ this->context = context;
+ }
+
+};
+
+#endif
diff --git a/sc-ap/ldapuser.cpp b/sc-ap/ldapuser.cpp
new file mode 100755
index 0000000..062efd3
--- /dev/null
+++ b/sc-ap/ldapuser.cpp
@@ -0,0 +1,51 @@
+#include "ldapuser.h"
+
+mystring LDAPUser::getGidByUserName( const mystring &userName) {
+
+ mystring filter = L"(&(uid=";
+ filter.append( userName);
+ filter.append( L")(objectClass=posixAccount))");
+
+ return queryAttr( filter, L"gidNumber");
+}
+
+
+mystring
+LDAPUser::getGroupByGid( const mystring& gid) {
+ mystring filter = L"(&(gidNumber=" + gid + L")(objectClass=posixGroup))";
+ mystring result = queryAttr( filter, L"cn");
+ if (result == L"") {
+ return gid;
+ }
+ return result;
+}
+
+stringSet
+LDAPUser::getGroupsByUserName( const mystring& user, const mystring& gid) {
+ mystring filter = L"(&(|(gidNumber=" + gid + L")(memberUid=" + user + L"))(objectClass=posixGroup))";
+ stringSet list1 = queryListOfAttr( filter, L"cn");
+
+ return list1;
+}
+
+stringSet
+LDAPUser::getUserNames() {
+ mystring filter = L"(objectClass=posixAccount)";
+ return queryListOfAttr( filter, L"uid");
+}
+
+stringSet
+LDAPUser::getGroupNames() {
+ mystring filter = L"(objectClass=posixGroup)";
+ return queryListOfAttr( filter, L"cn");
+}
+
+stringMap
+LDAPUser::getAttribsByUserName( const mystring &userName, const stringSet attribs) {
+
+ mystring filter = L"(&(uid=";
+ filter.append( userName);
+ filter.append( L")(objectClass=posixAccount))");
+
+ return querySetOfAttrs( filter, attribs);
+}
diff --git a/sc-ap/ldapuser.h b/sc-ap/ldapuser.h
new file mode 100755
index 0000000..0b1a096
--- /dev/null
+++ b/sc-ap/ldapuser.h
@@ -0,0 +1,14 @@
+#include "ldap1.h"
+
+class LDAPUser : public CLDAP {
+public:
+ inline LDAPUser( const std::list<mystring>& host, FILE *fp, const mystring& binddn, const mystring& bindpasswd) :
+ CLDAP( host, fp, binddn, bindpasswd) {};
+
+ mystring getGidByUserName( const mystring &str);
+ stringSet getGroupsByUserName( const mystring &str, const mystring &gid);
+ mystring getGroupByGid( const mystring &str);
+ stringMap getAttribsByUserName( const mystring &userName, const stringSet attribs);
+ stringSet getUserNames();
+ stringSet getGroupNames();
+};
diff --git a/sc-ap/manageUser.cpp b/sc-ap/manageUser.cpp
new file mode 100755
index 0000000..395bfae
--- /dev/null
+++ b/sc-ap/manageUser.cpp
@@ -0,0 +1,159 @@
+/*
+ $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 <algorithm>
+#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<mystring> 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);
+}
diff --git a/sc-ap/manageUser.h b/sc-ap/manageUser.h
new file mode 100755
index 0000000..9218439
--- /dev/null
+++ b/sc-ap/manageUser.h
@@ -0,0 +1,33 @@
+/*
+ $Id: manageUser.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 MANAGE_USER_H
+#define MANAGE_USER_H
+
+#define WINDOWS_MEAN_AND_LEAN
+#define UNICODE
+
+#include <stdio.h>
+#include "typedefs.h"
+void
+manageLocalAccount( const mystring& userName, FILE *fp);
+
+#endif
diff --git a/sc-ap/netusergroup.cpp b/sc-ap/netusergroup.cpp
new file mode 100755
index 0000000..a8e34c0
--- /dev/null
+++ b/sc-ap/netusergroup.cpp
@@ -0,0 +1,260 @@
+/*
+ $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
+
+ 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 WINDOWS_MEAN_AND_LEAN
+#define UNICODE
+
+#include <windows.h>
+#include <lm.h>
+#include "netusergroup.h"
+
+int
+addUserToGroup( const mystring& userName, const mystring& groupName) {
+ if (addGroup( groupName)) {
+ return 1;
+ }
+
+ LOCALGROUP_MEMBERS_INFO_3 gmember;
+ gmember.lgrmi3_domainandname = (LPWSTR) userName.c_str();
+ int ret = NetLocalGroupAddMembers( NULL, groupName.c_str(), 3, (LPBYTE )&gmember, 1);
+ if (!(ret == NERR_Success || ret == ERROR_MEMBER_IN_ALIAS))
+ return 1;
+ return 0;
+}
+
+int
+delUserFromGroup( const mystring& userName, const mystring& groupName) {
+ LOCALGROUP_MEMBERS_INFO_3 gmember;
+ gmember.lgrmi3_domainandname = (LPWSTR) userName.c_str();
+ int ret = NetLocalGroupDelMembers( NULL, groupName.c_str(), 3, (LPBYTE )&gmember, 1);
+ if (!(ret == NERR_Success || ret == ERROR_MEMBER_IN_ALIAS))
+ return 1;
+ return 0;
+}
+
+
+int addGroup( const mystring& groupName) {
+LOCALGROUP_INFO_0 gent;
+ 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)) {
+ return 1;
+ }
+ return 0;
+}
+
+int
+addUser( const mystring& userName) {
+ USER_INFO_1 ui;
+
+ ui.usri1_name = (LPWSTR) userName.c_str();
+ ui.usri1_password = L"xyzzy";
+ ui.usri1_flags = UF_SCRIPT | UF_PASSWD_CANT_CHANGE | UF_ACCOUNTDISABLE;
+
+ ui.usri1_script_path = NULL;
+ ui.usri1_priv = USER_PRIV_USER;
+ ui.usri1_comment = NULL;
+ ui.usri1_home_dir = NULL;
+ ui.usri1_password_age = 0;
+
+ int ret = NetUserAdd( NULL,1, (LPBYTE )&ui, NULL);
+ return (!(ret == NERR_Success || ret == NERR_UserExists));
+}
+
+int addUser( const mystring& userName, 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_priv = USER_PRIV_USER;
+ ui.usri4_home_dir = (LPWSTR) homepath.c_str();
+
+ ui.usri4_flags = UF_SCRIPT | UF_PASSWD_CANT_CHANGE | UF_ACCOUNTDISABLE;
+
+ ui.usri4_script_path = (LPWSTR) script.c_str();
+ ui.usri4_max_storage = USER_MAXSTORAGE_UNLIMITED;
+ ui.usri4_country_code = 0; /* Arghhh! not documented*/
+ ui.usri4_code_page = 1252;
+
+ ui.usri4_primary_group_id = DOMAIN_GROUP_RID_USERS;
+
+ ui.usri4_profile = (LPWSTR) profile.c_str();
+ ui.usri4_home_dir_drive = (LPWSTR) homedrive.c_str();
+ int ret = NetUserAdd( NULL, 4, (LPBYTE )&ui, NULL);
+ return (!(ret == NERR_Success || ret == NERR_UserExists));
+}
+// return 1: User exists and disabled
+// return 0: User exists and enabled
+// return -1: User does not exist
+int
+isDisabledUser( const mystring& userName) {
+
+ // This API is sick
+ LPUSER_INFO_1 ui = NULL;
+ int flag = -1;
+ if (NERR_Success == NetUserGetInfo( NULL, userName.c_str(), 1, (LPBYTE *)&ui)) {
+ flag = (ui->usri1_flags & UF_ACCOUNTDISABLE) == UF_ACCOUNTDISABLE;
+ }
+ if (ui != NULL)
+ NetApiBufferFree( ui);
+ return flag;
+}
+
+int
+delUser( const mystring& userName) {
+ return NetUserDel( NULL, userName.c_str());
+}
+
+stringSet
+listGroups( const mystring& user) {
+ LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
+ LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
+
+ DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
+ DWORD dwEntriesRead = 0;
+ DWORD dwTotalEntries = 0;
+
+ DWORD i;
+ DWORD dwTotalCount = 0;
+ NET_API_STATUS nStatus;
+ stringSet groupList;
+
+ do
+ {
+ if (pBuf != NULL) {
+ NetApiBufferFree(pBuf);
+ pBuf = NULL;
+ }
+ nStatus = NetUserGetLocalGroups( NULL,
+ user.c_str(),
+ 0,
+ 0,
+ (LPBYTE*)&pBuf,
+ dwPrefMaxLen,
+ &dwEntriesRead,
+ &dwTotalEntries);
+ dwPrefMaxLen = dwTotalEntries;
+ // TODO: Endless loop possible?
+ } while (nStatus == ERROR_MORE_DATA);
+ //
+ // If the call succeeds,
+ //
+ if (nStatus == NERR_Success) {
+ if ((pTmpBuf = pBuf) != NULL) {
+ //
+ // Loop through the entries.
+ //
+ for (i = 0; (i < dwEntriesRead); i++) {
+ groupList.insert( mystring( pTmpBuf->lgrui0_name));
+ pTmpBuf++;
+ }
+ }
+ else
+ return groupList;
+ }
+ //
+ // Free the allocated buffer.
+ //
+ if (pBuf != NULL)
+ {
+ NetApiBufferFree(pBuf);
+ pBuf = NULL;
+ }
+
+ return groupList;
+}
+
+
+stringSet
+listUsers() {
+ LPUSER_INFO_0 pBuf = NULL;
+ LPUSER_INFO_0 pTmpBuf;
+ DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
+ DWORD dwEntriesRead = 0;
+ DWORD dwTotalEntries = 0;
+ DWORD dwResumeHandle = 0;
+ DWORD i;
+ DWORD dwTotalCount = 0;
+ NET_API_STATUS nStatus;
+ stringSet userList;
+ //
+ // Call the NetUserEnum function, specifying level 0;
+ // enumerate global user account types only.
+ //
+ do // begin do
+ {
+ if (pBuf != NULL) {
+ NetApiBufferFree(pBuf);
+ pBuf = NULL;
+ }
+ nStatus = NetUserEnum( NULL,
+ 0,
+ FILTER_NORMAL_ACCOUNT, // global users
+ (LPBYTE*)&pBuf,
+ dwPrefMaxLen,
+ &dwEntriesRead,
+ &dwTotalEntries,
+ &dwResumeHandle);
+ //
+ // If the call succeeds,
+ //
+ if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))
+ {
+ if ((pTmpBuf = pBuf) != NULL)
+ {
+ //
+ // Loop through the entries.
+ //
+ for (i = 0; (i < dwEntriesRead); i++)
+ {
+ userList.insert( mystring( pTmpBuf->usri0_name));
+ pTmpBuf++;
+ dwTotalCount++;
+ }
+ }
+ }
+
+ else
+ return userList;
+ //
+ // Free the allocated buffer.
+ //
+ if (pBuf != NULL)
+ {
+ NetApiBufferFree(pBuf);
+ pBuf = NULL;
+ }
+ }
+ // Continue to call NetUserEnum while
+ // there are more entries.
+ //
+ while (nStatus == ERROR_MORE_DATA); // end do
+ //
+ // Check again for allocated memory.
+ //
+ if (pBuf != NULL)
+ NetApiBufferFree(pBuf);
+
+ return userList;
+} \ No newline at end of file
diff --git a/sc-ap/netusergroup.h b/sc-ap/netusergroup.h
new file mode 100755
index 0000000..6bf8179
--- /dev/null
+++ b/sc-ap/netusergroup.h
@@ -0,0 +1,56 @@
+/*
+ $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 <stdio.h>
+#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);
+
+stringSet
+listUsers();
+
+stringSet
+listGroups( const mystring& user);
+#endif
diff --git a/sc-ap/reg.cpp b/sc-ap/reg.cpp
new file mode 100755
index 0000000..03946ac
--- /dev/null
+++ b/sc-ap/reg.cpp
@@ -0,0 +1,144 @@
+/*
+ $Id: reg.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 "reg.h"
+
+
+Registry::Registry( const mystring key) {
+ keyHandle = 0;
+ if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS , &keyHandle))
+ return;
+}
+
+Registry::~Registry() {
+ if (keyHandle != NULL)
+ RegCloseKey( keyHandle);
+}
+
+mystring Registry::getValue( const mystring& value) const {
+ wchar_t *retBuf = NULL;
+ DWORD retBufSize = 128;
+
+ while (1) {
+ retBuf = new wchar_t[ retBufSize]; //o.k. not clean alloc twice as needed
+ DWORD type;
+ long ret = RegQueryValueEx( keyHandle, value.c_str(), 0, &type, (LPBYTE) retBuf, &retBufSize);
+ if (ret == ERROR_MORE_DATA) {
+ delete[] retBuf;
+ continue;
+ }
+ if (ret != ERROR_SUCCESS || type != REG_SZ)
+ return mystring(L"");
+ break;
+ }
+ mystring ret( retBuf);
+ delete[] retBuf;
+ return ret;
+}
+
+std::list<mystring> Registry::getValues( const mystring& value) const {
+ wchar_t *retBuf = NULL;
+ DWORD retBufSize = 128;
+ std::list<mystring> list;
+ while (1) {
+ retBuf = new wchar_t[ retBufSize]; //o.k. not clean alloc twice as needed
+ DWORD type;
+ long ret = RegQueryValueEx( keyHandle, value.c_str(), 0, &type, (LPBYTE) retBuf, &retBufSize);
+ if (ret == ERROR_MORE_DATA) {
+ delete[] retBuf;
+ continue;
+ }
+ if (ret != ERROR_SUCCESS || type != REG_MULTI_SZ) {
+ delete[] retBuf;
+ return list;
+ }
+ break;
+ }
+
+ wchar_t *ptr = retBuf;
+ while (*ptr != 0) {
+ list.push_back( mystring( ptr));
+ while (*ptr != 0)
+ ptr++;
+ // ptr points to terminating 0
+ ptr++;
+ // should point to new entry, or terminating 0
+ }
+ delete[] retBuf;
+ return list;
+}
+
+std::list<mystring> Registry::getSubKeys() const {
+ wchar_t *retBuf = NULL;
+ DWORD retBufSize = 128;
+ std::list<mystring> list;
+ int numKey =0;
+ long ret;
+ do {
+
+ while (1) {
+ retBuf = new wchar_t[ retBufSize]; //o.k. not clean alloc twice as needed
+ FILETIME mod;
+ ret = RegEnumKeyEx( keyHandle, numKey, retBuf, &retBufSize, 0, NULL, NULL, &mod);
+ if (ret == ERROR_MORE_DATA) {
+ delete[] retBuf;
+ retBufSize *= 2;
+ continue;
+ }
+ if (!(ret == ERROR_NO_MORE_ITEMS || ret== ERROR_SUCCESS)){
+ delete[] retBuf;
+ return list;
+ }
+ break;
+ }
+ if (ret == ERROR_SUCCESS) {
+ list.push_back( mystring(retBuf));
+ }
+ delete[] retBuf;
+ numKey++;
+ } while (ret != ERROR_NO_MORE_ITEMS);
+ return list;
+}
+
+bool Registry::exists( const mystring& value) {
+ if (keyHandle) {
+ int ret = RegQueryValueEx( keyHandle, value.c_str(), 0, NULL, NULL, NULL);
+ return (ret == ERROR_SUCCESS);
+ }
+ return false;
+}
+
+#if 0
+main() {
+ Registry reg( L"SOFTWARE\\science + computing\\scap");
+ printf("%S\n", reg.getValue( L"basedn").c_str());
+ std::list<mystring> servers = reg.getValues( L"servers");
+ for (std::list<mystring>::const_iterator ptr = servers.begin(); ptr != servers.end(); ptr++) {
+ printf("%S\n", ptr->c_str());
+ }
+ Registry zwo( L"System\\CurrentControlSet\\Control\\Lsa\\Kerberos\\Domains");
+ std::list<mystring> realms = zwo.getSubKeys();
+ for (std::list<mystring>::const_iterator ptr = realms.begin(); ptr != realms.end(); ptr++) {
+ printf("%S\n", ptr->c_str());
+ }
+}
+#endif
diff --git a/sc-ap/reg.h b/sc-ap/reg.h
new file mode 100755
index 0000000..25e375e
--- /dev/null
+++ b/sc-ap/reg.h
@@ -0,0 +1,44 @@
+/*
+ $Id: reg.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 REG_H
+#define REG_H
+
+#define UNICODE
+#define WINDOWS_LEAN_AND_MEAN
+
+#include <windows.h>
+#include "typedefs.h"
+
+class Registry {
+ HKEY keyHandle;
+public:
+ Registry( const mystring key);
+ mystring getValue( const mystring& value) const;
+ std::list<mystring> getValues( const mystring& value) const;
+ ~Registry();
+ std::list<mystring> getSubKeys() const;
+ inline bool exists() const {
+ return keyHandle != NULL;
+ }
+ bool exists( const mystring& value);
+};
+#endif
diff --git a/sc-ap/sspap3.cpp b/sc-ap/sspap3.cpp
new file mode 100755
index 0000000..d95c124
--- /dev/null
+++ b/sc-ap/sspap3.cpp
@@ -0,0 +1,249 @@
+/*
+ $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 <windows.h>
+#include <ntsecapi.h>
+#include <sspi.h>
+#include <ntsecpkg.h>
+#include <stdio.h>
+//#include <ntstatus.h>
+#include <string.h>
+//#include <subauth.h>
+#include <malloc.h>
+#include <algorithm>
+#include <list>
+#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<mystring> 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;
+ }
+}
diff --git a/sc-ap/sspap3.def b/sc-ap/sspap3.def
new file mode 100755
index 0000000..0ab8d89
--- /dev/null
+++ b/sc-ap/sspap3.def
@@ -0,0 +1,9 @@
+LIBRARY sspap3
+
+EXPORTS
+ SpUserModeInitialize
+ SpInitialize
+ SpInstanceInit
+ SpLsaModeInitialize
+
+ \ No newline at end of file
diff --git a/sc-ap/sspap3.sln b/sc-ap/sspap3.sln
new file mode 100755
index 0000000..7f6cf19
--- /dev/null
+++ b/sc-ap/sspap3.sln
@@ -0,0 +1,21 @@
+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
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ 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
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/sc-ap/sspap3.vcproj b/sc-ap/sspap3.vcproj
new file mode 100755
index 0000000..6ed8c9c
--- /dev/null
+++ b/sc-ap/sspap3.vcproj
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="sspap3"
+ ProjectGUID="{EA164A0F-6361-40D6-B356-B6E16EB9FA15}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SSPAP3_EXPORTS;DOITALL"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"
+ CallingConvention="2"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="netapi32.lib wldap32.lib"
+ OutputFile="$(OutDir)/sspap3.dll"
+ LinkIncremental="2"
+ ModuleDefinitionFile="sspap3.def"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/sspap3.pdb"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/sspap3.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SSPAP3_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CallingConvention="2"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="netapi32.lib wldap32.lib"
+ OutputFile="$(OutDir)/sspap3.dll"
+ LinkIncremental="1"
+ ModuleDefinitionFile="sspap3.def"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/sspap3.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Quelldateien"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\ldap1.cpp">
+ </File>
+ <File
+ RelativePath=".\ldapuser.cpp">
+ </File>
+ <File
+ RelativePath=".\manageUser.cpp">
+ </File>
+ <File
+ RelativePath=".\netusergroup.cpp">
+ </File>
+ <File
+ RelativePath=".\reg.cpp">
+ </File>
+ <File
+ RelativePath=".\sspap3.cpp">
+ </File>
+ <File
+ RelativePath=".\sspap3.def">
+ </File>
+ <File
+ RelativePath=".\utility.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Headerdateien"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\ldap1.h">
+ </File>
+ <File
+ RelativePath=".\ldapuser.h">
+ </File>
+ <File
+ RelativePath=".\manageUser.h">
+ </File>
+ <File
+ RelativePath=".\netusergroup.h">
+ </File>
+ <File
+ RelativePath=".\reg.h">
+ </File>
+ <File
+ RelativePath=".\typedefs.h">
+ </File>
+ <File
+ RelativePath=".\utility.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Ressourcendateien"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/sc-ap/typedefs.h b/sc-ap/typedefs.h
new file mode 100755
index 0000000..ac3aedc
--- /dev/null
+++ b/sc-ap/typedefs.h
@@ -0,0 +1,14 @@
+#ifndef TYPEDEFS_H
+#define TYPEDEFS_H
+
+#include <string>
+#include <set>
+#include <map>
+#include <list>
+
+typedef std::wstring mystring;
+typedef std::set<mystring> stringSet;
+typedef std::map<mystring, mystring> stringMap;
+typedef std::list<mystring> stringList;
+#endif
+
diff --git a/sc-ap/utility.cpp b/sc-ap/utility.cpp
new file mode 100755
index 0000000..dd78a4c
--- /dev/null
+++ b/sc-ap/utility.cpp
@@ -0,0 +1,68 @@
+/*
+ $Id: utility.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 <sstream>
+#include <algorithm>
+
+#include "utility.h"
+
+mystring itos( int a) {
+ std::wstringstream ostr;
+
+ ostr << a;
+ return ostr.str();
+}
+
+mystring convertSlashes( const mystring& input) {
+ mystring tmpInput = input;
+ // replace / by \ -
+ std::replace( tmpInput.begin(), tmpInput.end(), L'/', L'\\');
+ // collapse \\ to \ --
+ mystring::size_type a;
+
+ while ((a = tmpInput.find( L"\\\\")) != mystring::npos) {
+ tmpInput.replace( a, 2, L"\\");
+ }
+ return tmpInput;
+}
+
+mystring searchAndReplace( const mystring& inputString, const mystring& registryKey, Registry &reg, FILE *fp) {
+ mystring tmpInputString = inputString;
+ int i = 0;
+ 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);
+ continue;
+ }
+ mystring searchString = searchReplace.front();
+ searchReplace.pop_front();
+ mystring replaceString = searchReplace.front();
+ if (tmpInputString.size() < searchString.size())
+ continue;
+ // check whether search matches
+ if (std::equal( searchString.begin(), searchString.end(), tmpInputString.begin())) {
+ tmpInputString.replace( 0, searchString.size(), replaceString);
+ }
+ i++;
+ }
+ return tmpInputString;
+}
diff --git a/sc-ap/utility.h b/sc-ap/utility.h
new file mode 100755
index 0000000..3ea1f01
--- /dev/null
+++ b/sc-ap/utility.h
@@ -0,0 +1,34 @@
+/*
+ $Id: utility.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 UTILITY_H
+#define UTILITY_H
+
+#include <stdio.h>
+#include "typedefs.h"
+#include "reg.h"
+
+mystring itos( int a);
+mystring convertSlashes( const mystring& input);
+mystring searchAndReplace( const mystring& inputString, const mystring& registryKey, Registry &reg, FILE *fp);
+
+#endif \ No newline at end of file