/***************************************************************************
 *   Copyright (C) 2012-2015 by Timothy Pearson                            *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _LIBTDELDAP_H_
#define _LIBTDELDAP_H_

#include <stdint.h>
#include <unistd.h>
#include <sys/stat.h>
#include <ldap.h>
#include <kadm5/admin.h>

#include <tqobject.h>
#include <tqstring.h>
#include <tqdatetime.h>
#include <tqvaluelist.h>
#include <tqfile.h>

#include <ksimpleconfig.h>

// FIXME
// Connect this to CMake/Automake
#define TDE_BINDIR "/opt/trinity/bin"

#define TDE_LDAP_PID_DIR "/etc/trinity/ldap/pid/"
#define TDE_LDAP_CERT_UPDATER_PID_FILE TDE_LDAP_PID_DIR "/tdeldapcertupdater.pid"

#define TDE_CERTIFICATE_DIR "/etc/trinity/ldap/tde-ca/"

#define KERBEROS_PKI_ANCHORDIR "/etc/trinity/ldap/tde-ca/anchors/"
#define KERBEROS_PKI_PRIVATEDIR "/etc/trinity/ldap/tde-ca/private/"
#define KERBEROS_PKI_PUBLICDIR "/etc/trinity/ldap/tde-ca/public/"

#define KERBEROS_PKI_PEM_FILE KERBEROS_PKI_ANCHORDIR "tdeca.pem"
#define KERBEROS_PKI_PEMKEY_FILE KERBEROS_PKI_ANCHORDIR "tdeca.key.pem"
#define KERBEROS_PKI_CRL_FILE KERBEROS_PKI_ANCHORDIR "tdecrl.pem"
#define KERBEROS_PKI_CRLDB_FILE KERBEROS_PKI_ANCHORDIR "tdecrl.db"
#define KERBEROS_PKI_KDC_FILE KERBEROS_PKI_PUBLICDIR "@@@KDCSERVER@@@.pki.crt"
#define KERBEROS_PKI_KDCKEY_FILE KERBEROS_PKI_PRIVATEDIR "@@@KDCSERVER@@@.pki.key"
#define KERBEROS_PKI_KDCREQ_FILE KERBEROS_PKI_PRIVATEDIR "@@@KDCSERVER@@@.pki.req"

#define LDAP_CERT_FILE KERBEROS_PKI_PUBLICDIR "@@@ADMINSERVER@@@.ldap.crt"
#define LDAP_CERTKEY_FILE KERBEROS_PKI_PRIVATEDIR "@@@ADMINSERVER@@@.ldap.key"
#define LDAP_CERTREQ_FILE KERBEROS_PKI_PRIVATEDIR "@@@ADMINSERVER@@@.ldap.req"
#define LDAP_CERTREVOC_FILE KERBEROS_PKI_PUBLICDIR "@@@ADMINSERVER@@@.ldap.crl"

#define OPENSSL_EXTENSIONS_FILE TDE_CERTIFICATE_DIR "openssl.cfg"

#define DEFAULT_IGNORED_USERS_LIST "avahi,avahi-autoipd,backup,bin,colord,daemon,games,gnats,haldaemon,hplip,irc,klog,landscape,libuuid,list,lp,mail,man,messagebus,news,ntp,polkituser,postfix,proxy,pulse,root,rtkit,saned,sshd,statd,sync,sys,syslog,timidity,usbmux,uucp,www-data"

#define CRON_UPDATE_PRIMARY_REALM_CERTIFICATES_FILE "/etc/cron.daily/tde-upd-pri-rlm-certs"
#define CRON_UPDATE_PRIMARY_REALM_CERTIFICATES_COMMAND TDE_BINDIR "/primaryrccertupdater"

// 1 year
#define KERBEROS_PKI_PEMKEY_EXPIRY_DAYS 365

// 1 month
#define KERBEROS_PKI_CRL_EXPIRY_DAYS 30
#define KERBEROS_PKI_KRB_EXPIRY_DAYS 30
#define KERBEROS_PKI_LDAP_EXPIRY_DAYS 30

// Values from hdb.asn1
enum LDAPKRB5Flags {
	KRB5_INITIAL			= 0x00000001,
	KRB5_FORWARDABLE		= 0x00000002,
	KRB5_PROXIABLE			= 0x00000004,
	KRB5_RENEWABLE			= 0x00000008,
	KRB5_POSTDATE			= 0x00000010,
	KRB5_SERVER			= 0x00000020,
	KRB5_CLIENT			= 0x00000040,
	KRB5_INVALID			= 0x00000080,
	KRB5_REQUIRE_PREAUTH		= 0x00000100,
	KRB5_CHANGE_PW			= 0x00000200,
	KRB5_REQUIRE_HWAUTH		= 0x00000400,
	KRB5_OK_AS_DELEGATE		= 0x00000800,
	KRB5_USER_TO_USER		= 0x00001000,
	KRB5_IMMUTABLE			= 0x00002000,
	KRB5_TRUSTED_FOR_DELEGATION	= 0x00004000,
	KRB5_ALLOW_KERBEROS_4		= 0x00008000,
	KRB5_ALLOW_DIGEST		= 0x00010000,
	KRB5_LOCKED_OUT			= 0x00020000,

	KRB5_ACTIVE_DEFAULT		= KRB5_FORWARDABLE | KRB5_RENEWABLE | KRB5_CLIENT | KRB5_CHANGE_PW,
	KRB5_DISABLED_ACCOUNT		= KRB5_FORWARDABLE | KRB5_SERVER | KRB5_INVALID | KRB5_REQUIRE_PREAUTH | KRB5_REQUIRE_HWAUTH | KRB5_OK_AS_DELEGATE | KRB5_USER_TO_USER,
	KRB5_MACHINE_ACCOUNT_DEFAULT	= KRB5_FORWARDABLE | KRB5_PROXIABLE | KRB5_RENEWABLE | KRB5_POSTDATE | KRB5_SERVER | KRB5_CLIENT,
	KRB5_SERVICE_PRINCIPAL_DEFAULT	= KRB5_FORWARDABLE | KRB5_PROXIABLE | KRB5_RENEWABLE | KRB5_POSTDATE | KRB5_SERVER | KRB5_CLIENT,
	KRB5_FLAG_MAX			= 0x80000000
};

enum LDAPMachineRole {
	ROLE_WORKSTATION		= 0,
	ROLE_SECONDARY_REALM_CONTROLLER	= 1,
	ROLE_PRIMARY_REALM_CONTROLLER	= 2
};

inline LDAPKRB5Flags operator|(LDAPKRB5Flags a, LDAPKRB5Flags b)
{
	return static_cast<LDAPKRB5Flags>(static_cast<int>(a) | static_cast<int>(b));
}

inline LDAPKRB5Flags operator&(LDAPKRB5Flags a, LDAPKRB5Flags b)
{
	return static_cast<LDAPKRB5Flags>(static_cast<int>(a) & static_cast<int>(b));
}

// Values from krb5.asn1
enum KRB5TicketFlags {
	KRB5_TICKET_RESERVED		= 0x00000001,
	KRB5_TICKET_FORWARDABLE		= 0x00000002,
	KRB5_TICKET_FORWARDED		= 0x00000004,
	KRB5_TICKET_PROXIABLE		= 0x00000008,
	KRB5_TICKET_PROXY		= 0x00000010,
	KRB5_TICKET_MAY_POSTDATE	= 0x00000020,
	KRB5_TICKET_POSTDATED		= 0x00000040,
	KRB5_TICKET_INVALID		= 0x00000080,
	KRB5_TICKET_RENEWABLE		= 0x00000100,
	KRB5_TICKET_INITIAL		= 0x00000200,
	KRB5_TICKET_PREAUTHENT		= 0x00000400,
	KRB5_TICKET_HW_AUTHENT		= 0x00000800,
	KRB5_TICKET_TRANSIT_CHECKED	= 0x00001000,
	KRB5_TICKET_OK_AS_DELEGATE	= 0x00002000,
	KRB5_TICKET_ANONYMOUS		= 0x00004000,
	KRB5_TICKET_ENC_PA_REP		= 0x00008000,

	KRB5_TICKET_FLAG_MAX		= 0x80000000
};

inline KRB5TicketFlags operator|(KRB5TicketFlags a, KRB5TicketFlags b)
{
	return static_cast<KRB5TicketFlags>(static_cast<int>(a) | static_cast<int>(b));
}

inline KRB5TicketFlags operator&(KRB5TicketFlags a, KRB5TicketFlags b)
{
	return static_cast<KRB5TicketFlags>(static_cast<int>(a) & static_cast<int>(b));
}

typedef TQValueList<uid_t> UserList;
typedef TQValueList<gid_t> GroupList;

namespace PKICertificateStatus {
	enum PKICertificateStatusEnum {
		Invalid		= 0,
		Valid		= 1,
		Revoked		= 2
	};
}

typedef TQValueList<TQByteArray> TQByteArrayList;

typedef TQPair<uint32_t, TQByteArray> PKICertificateEntry;
typedef TQValueList<PKICertificateEntry> PKICertificateEntryList;

class TDE_EXPORT LDAPCredentials
{
	public:
		LDAPCredentials();
		~LDAPCredentials();

	public:
		TQString username;
		TQString password;
		TQString realm;
		bool use_tls;
		bool use_gssapi;
		bool use_smartcard;
		TQString service;
};

// PRIVATE
class TDE_EXPORT LDAPRealmConfig
{
	public:
		TQString name;
		bool bonded;
		long uid_offset;
		long gid_offset;
		TQStringList domain_mappings;
		TQString kdc;
		int kdc_port;
		TQString admin_server;
		int admin_server_port;
		bool pkinit_require_eku;
		bool pkinit_require_krbtgt_otherName;
		bool win2k_pkinit;
		bool win2k_pkinit_require_binding;
		TQString certificate_revocation_list_url;
};

// PRIVATE
class TDE_EXPORT LDAPCertConfig
{
	public:
		LDAPCertConfig();
		~LDAPCertConfig();

	public:
		bool generate_certs;
		TQString provided_kerberos_pem;
		TQString provided_kerberos_pemkey;
		TQString provided_kerberos_crt;
		TQString provided_kerberos_key;
		TQString provided_ldap_crt;
		TQString provided_ldap_key;

		int caExpiryDays;
		int caCrlExpiryDays;
		int kerberosExpiryDays;
		int ldapExpiryDays;

		TQString countryName;
		TQString stateOrProvinceName;
		TQString localityName;
		TQString organizationName;
		TQString orgUnitName;
		TQString commonName;
		TQString emailAddress;
};

// PRIVATE
class TDE_EXPORT LDAPPamConfig
{
	public:
		LDAPPamConfig();
		~LDAPPamConfig();

	public:
		bool enable_pkcs11_login;
		int pkcs11_login_card_slot;
		bool enable_cached_credentials;
		bool autocreate_user_directories_enable;
		mode_t autocreate_user_directories_umask;
		TQString autocreate_user_directories_skel;
};

// PRIVATE
class TDE_EXPORT LDAPClientRealmConfig
{
	public:
		bool enable_bonding;
		TQString hostFQDN;
		TQString defaultRealm;
		int ticketLifetime;
		TQString ldapRole;

		int ldapVersion;
		int ldapTimeout;
		TQString bindPolicy;
		int ldapBindTimeout;
		TQString passwordHash;
		TQString ignoredUsers;

		bool configurationVerifiedForLocalMachine;

		LDAPPamConfig pamConfig;
};

typedef TQMap<TQString, LDAPRealmConfig> LDAPRealmConfigList;

class TDE_EXPORT LDAPUserInfo
{
	public:
		LDAPUserInfo();
		~LDAPUserInfo();

	public:
		bool informationValid;
		TQString distinguishedName;
		TQString creatorsName;

		TQString name;
		uid_t uid;
		TQString shell;
		TQString homedir;
		gid_t primary_gid;
		bool tde_builtin_account;
		LDAPKRB5Flags status;			// Default active user is 586 [KRB5_ACTIVE_DEFAULT] and locked out user is 7586 [KRB5_DISABLED_ACCOUNT]
		TQString new_password;
		TQDateTime account_created;
		TQDateTime account_modified;
		TQDateTime password_last_changed;
		bool password_expires;
		TQDateTime password_expiration;
		bool password_ages;
		int new_password_interval;
		int new_password_warn_interval;
		int new_password_lockout_delay;
		bool password_has_minimum_age;
		int password_minimum_age;
		int maximum_ticket_lifetime;

		// Page 1
		TQString commonName;
		TQString givenName;
		TQString surName;
		TQString initials;
		TQString title;
		TQString email;
		TQString description;
		TQString locality;
		TQString telephoneNumber;
		TQString faxNumber;
		TQString homePhone;
		TQString mobilePhone;
		TQString pagerNumber;
		TQString website;
		TQByteArray profileAvatar;

		// Page 2
		TQString poBox;
		TQString street;
		TQString address;
		TQString state;
		TQString postcode;
		TQString registeredAddress;
		TQString homeAddress;

		// Page 3
		TQString seeAlso;
		TQString deliveryOffice;
		TQString department;
		TQString roomNumber;
		TQString employeeType;
		TQString employeeNumber;
		TQString manager;
		TQString secretary;
		TQString isdnNumber;
		TQString teletexID;
		TQString telexNumber;
		TQString preferredDelivery;
		TQString destinationIndicator;
		TQString x121Address;
		TQString displayName;
		TQString preferredLanguage;
		TQString uniqueIdentifier;
		TQString businessCategory;
		TQString carLicense;
		TQString notes;

		// PKI
		PKICertificateEntryList pkiCertificates;
};

class TDE_EXPORT LDAPGroupInfo
{
	public:
		LDAPGroupInfo();
		~LDAPGroupInfo();

	public:
		bool informationValid;
		TQString distinguishedName;
		TQString creatorsName;

		TQString name;
		TQString displayName;
		gid_t gid;
		bool tde_builtin_account;
		TQStringList userlist;
};

class TDE_EXPORT LDAPMachineInfo
{
	public:
		LDAPMachineInfo();
		~LDAPMachineInfo();

	public:
		bool informationValid;
		TQString distinguishedName;
		TQString creatorsName;

		TQString name;
		TQString newPassword;
		bool tde_builtin_account;
		LDAPKRB5Flags status;		// Default is 126 [KRB5_MACHINE_ACCOUNT_DEFAULT]
};

class TDE_EXPORT LDAPServiceInfo
{
	public:
		LDAPServiceInfo();
		~LDAPServiceInfo();

	public:
		bool informationValid;
		TQString distinguishedName;
		TQString creatorsName;

		TQString name;
		TQString machine;
		TQString machine_dn;
		bool tde_builtin_account;
		LDAPKRB5Flags status;		// Default is 126 [KRB5_SERVICE_PRINCIPAL_DEFAULT]
};

class TDE_EXPORT LDAPTDEBuiltinsInfo
{
	public:
		LDAPTDEBuiltinsInfo();
		~LDAPTDEBuiltinsInfo();

	public:
		bool informationValid;
		TQString builtinRealmAdminAccount;
		TQString builtinRealmAdminGroup;
		TQString builtinMachineAdminGroup;
		TQString builtinStandardUserGroup;
};

class TDE_EXPORT LDAPMasterReplicationMapping
{
	public:
		LDAPMasterReplicationMapping();
		~LDAPMasterReplicationMapping();

	public:
		int id;
		TQString fqdn;
};

typedef TQValueList<LDAPMasterReplicationMapping> LDAPMasterReplicationMap;

class TDE_EXPORT LDAPMasterReplicationInfo
{
	public:
		LDAPMasterReplicationInfo();
		~LDAPMasterReplicationInfo();

	public:
		bool informationValid;
		bool enabled;
		LDAPMasterReplicationMap serverIDs;
		TQString retryMethod;
		int timeout;
		int syncMethod;
		TQString syncDN;
		TQString syncPassword;
		TQString certificateFile;
		TQString caCertificateFile;
		bool ignore_ssl_failure;
		bool replicate_olcGlobal;
};

class TDE_EXPORT KerberosTicketInfo
{
	public:
		KerberosTicketInfo();
		~KerberosTicketInfo();

	public:
		bool informationValid;
		TQString cacheURL;
		TQString cachePrincipal;
		int cacheVersion;
		TQString serverPrincipal;
		TQString clientPrincipal;
		TQString encryptionType;
		int keyVersionNumber;
		int ticketSize;
		TQDateTime authenticationTime;
		TQDateTime validStartTime;
		TQDateTime validEndTime;
		KRB5TicketFlags flags;
		TQStringList addresses;
};

typedef TQValueList<LDAPUserInfo> LDAPUserInfoList;
typedef TQValueList<LDAPGroupInfo> LDAPGroupInfoList;
typedef TQValueList<LDAPMachineInfo> LDAPMachineInfoList;
typedef TQValueList<LDAPServiceInfo> LDAPServiceInfoList;
typedef TQValueList<KerberosTicketInfo> KerberosTicketInfoList;

class PtyProcess;

class TDE_EXPORT LDAPManager : public TQObject {
	TQ_OBJECT

	public:
		LDAPManager(TQString realm, TQString host, TQObject *parent=0, const char *name=0);
		LDAPManager(TQString realm, TQString host, LDAPCredentials* creds, TQObject *parent=0, const char *name=0);
		~LDAPManager();

		TQString realm();
		TQString basedn();
		int bind(TQString* errstr=0);
		int unbind(bool force, TQString* errstr=0);
		LDAPUserInfoList users(int* retcode=0, TQString *errstr=0);
		LDAPGroupInfoList groups(int* retcode=0, TQString *errstr=0);
		LDAPMachineInfoList machines(int* retcode=0, TQString *errstr=0);
		LDAPServiceInfoList machineServices(TQString machine_dn, int* retcode=0);
		LDAPServiceInfoList services(int* retcode=0, TQString *errstr=0);
		LDAPUserInfo getUserByDistinguishedName(TQString dn);
		LDAPGroupInfo getGroupByDistinguishedName(TQString dn, TQString *errstr=0);

		int updateUserInfo(LDAPUserInfo user, TQString *errstr=0);
		int updateGroupInfo(LDAPGroupInfo group, TQString *errstr=0);
		int updateMachineInfo(LDAPMachineInfo group, TQString *errstr=0);
		int updateServiceInfo(LDAPServiceInfo group, TQString *errstr=0);
		int addUserInfo(LDAPUserInfo user, TQString *errstr=0);
		int addGroupInfo(LDAPGroupInfo group, TQString *errstr=0);
		int addMachineInfo(LDAPMachineInfo machine, TQString *errstr=0);
		int addServiceInfo(LDAPServiceInfo service, TQString *errstr=0);
		int deleteUserInfo(LDAPUserInfo user, TQString *errstr=0);
		int deleteGroupInfo(LDAPGroupInfo group, TQString *errstr=0);
		int deleteMachineInfo(LDAPMachineInfo machine, TQString *errstr=0);
		int deleteServiceInfo(LDAPServiceInfo service, TQString *errstr=0);

		int exportKeytabForPrincipal(TQString principal, TQString fileName, TQString *errstr=0);
		int deleteKeytabEntriesForPrincipal(TQString principal, TQString fileName, TQString *errstr=0);

		LDAPCredentials currentLDAPCredentials(bool inferGSSAPIData=false);

		int moveKerberosEntries(TQString newSuffix, TQString* errstr=0);
		int writeCertificateFileIntoDirectory(TQByteArray cert, TQString attr, TQString* errstr=0);
		int writePKICertificateFilesIntoDirectory(LDAPUserInfo user, TQString attr, TQString* errstr=0);

		TQString getRealmCAMaster(TQString* errstr=0);
		int setRealmCAMaster(TQString masterFQDN, TQString* errstr=0);
		int getLdapCertificateStoreAttribute(TQString attribute, TQString* value, TQString* errstr=0);
		int setLdapCertificateStoreAttribute(TQString attribute, TQString value, TQString* errstr=0);

		LDAPTDEBuiltinsInfo getTDEBuiltinMappings(TQString *errstr=0);
		LDAPMasterReplicationInfo getLDAPMasterReplicationSettings(TQString *errstr=0);
		int setLDAPMasterReplicationSettings(LDAPMasterReplicationInfo replicationinfo, TQString *errstr=0);
		int writeSudoersConfFile(TQString *errstr=0);
		int getTDECertificate(TQString certificateName, TQFile *fileHandle, TQString *errstr=0);
		int getTDECertificate(TQString certificateName, TQString fileName, TQString *errstr=0);
		int getTDECertificate(TQString certificateName, TQByteArray *certificate, TQString *errstr=0);
		int setPasswordForUser(LDAPUserInfo user, TQString *errstr);

		static int writePrimaryRealmCertificateUpdateCronFile(TQString *errstr=0);
		static int installCACertificateInHostCAStore(TQString *errstr=0);
		static int retrieveAndInstallCaCrl(LDAPManager* manager=0, TQString *errstr=0);
		static TQString getMachineFQDN();
		static int writeTDERealmList(LDAPRealmConfigList realms, KSimpleConfig* config, TQString *errstr=0);
		static LDAPRealmConfigList fetchAndReadTDERealmList(TQString *defaultRealm=0);
		static LDAPRealmConfigList readTDERealmList(KSimpleConfig* config, bool disableAllBonds=false);
		static TQDateTime getCertificateExpiration(TQString certfile);
		static TQDateTime getCertificateExpiration(TQByteArray certfileContents);

		static int generatePublicKerberosCACertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg);
		static int generatePublicKerberosCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg);
		static int generatePublicLDAPCertificate(LDAPCertConfig certinfo, LDAPRealmConfig realmcfg, uid_t ldap_uid, gid_t ldap_gid);

		static int generateClientCertificatePair(int expirydays, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, int clientKeyBitLength=2048, TQString autoLoginPIN=TQString::null, TQString *errstr=0);
		static int generateClientCertificatePrivateKey(TQString privateKeyFile, int clientKeyBitLength=2048, TQString *errstr=0);
		static int generateClientCertificatePublicCertificate(int expirydays, LDAPUserInfo user, LDAPRealmConfig realmcfg, TQString signingPrivateKeyFile, TQString privateKeyFile, TQString publicCertFile, TQString autoLoginPIN=TQString::null, TQString *errstr=0);

		int generatePKICRL(int expirydays, LDAPRealmConfig realmcfg, TQString crlFile, TQString signingPrivateKeyFile, TQString revocationDatabaseFile, TQString *errstr=0);

		static TQString ldapdnForRealm(TQString realm);
		static TQString openssldcForRealm(TQString realm);
		static TQString cnFromDn(TQString dn);

		static KerberosTicketInfoList getKerberosTicketList(TQString cache=TQString::null, TQString *cacheFileName=0);
		static int getKerberosPassword(LDAPCredentials &creds, TQString prompt, bool requestServicePrincipal=false, bool allowSmartCard=false, TQWidget* parent=0);
		static int getNewKerberosPassword(LDAPCredentials &oldCreds, LDAPCredentials &newCreds, TQString prompt, bool allowSmartCard=false, TQWidget* parent=0);
		static int obtainKerberosTicket(LDAPCredentials creds, TQString principal, TQString *errstr=0);
		static int obtainKerberosServiceTicket(TQString principal, TQString *errstr=0);
		static int destroyKerberosTicket(TQString principal, TQString *errstr=0);

		static int changeKerberosPassword(LDAPCredentials oldCreds, LDAPCredentials newCreds, TQString principal, TQString *errstr=0);

		static TQString detailedKAdminErrorMessage(TQString initialMessage);
		static TQString readFullLineFromPtyProcess(PtyProcess* proc);

		static LDAPClientRealmConfig loadClientRealmConfig(KSimpleConfig* config, bool useDefaults=false);
		static int saveClientRealmConfig(LDAPClientRealmConfig clientRealmConfig, KSimpleConfig* config, TQString *errstr=0);
		static int writeClientKrb5ConfFile(LDAPClientRealmConfig clientRealmConfig, LDAPRealmConfigList realmList, TQString *errstr=0);
		static int writeLDAPConfFile(LDAPRealmConfig realmcfg, LDAPMachineRole machineRole, TQString *errstr=0);
		static int writeNSSwitchFile(TQString *errstr=0);
		static int writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, TQString *errstr=0);
		static int writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUserInfo user, TQString opensslConfigFile, TQString caRootKeyFile=TQString::null, TQString caRootCertFile=TQString::null, TQString caRootDatabaseFile=TQString::null, TQString autoLoginPIN=TQString::null, TQString *errstr=0);
		static int writeClientCronFiles(TQString *errstr=0);
		static int rehashClientPKCSCertificates(TQString *errstr=0);
		static int writePAMFiles(LDAPPamConfig pamConfig, TQString *errstr=0);
		static bool pkcsLoginEnabled();

		static int bondRealm(const TQString &adminUserName, const TQString &adminPassword,
					const TQString &adminRealm, TQString *errstr=0);
		static int unbondRealm(LDAPRealmConfig realmcfg, const TQString &adminUserName,
					const TQString &adminPassword, const TQString &adminRealm, TQString *errstr=0);

	private:
		int bindKAdmin(LDAPCredentials *administrativeCredentials=NULL, TQString *errstr=0);
		int unbindKAdmin(TQString *errstr=0);
		int kAdminAddNewPrincipal(TQString principalName, TQString newPassword, TQString *errstr=0);
		int kAdminDeletePrincipal(TQString principalName, TQString *errstr=0);
		LDAPUserInfo parseLDAPUserRecord(LDAPMessage* entry);
		LDAPGroupInfo parseLDAPGroupRecord(LDAPMessage* entry);
		LDAPMachineInfo parseLDAPMachineRecord(LDAPMessage* entry);
		LDAPServiceInfo parseLDAPMachineServiceRecord(LDAPMessage* entry);
		LDAPTDEBuiltinsInfo parseLDAPTDEBuiltinsRecord(LDAPMessage* entry);
		LDAPMasterReplicationInfo parseLDAPMasterReplicationRecord(LDAPMasterReplicationInfo replicationinfo, LDAPMessage* entry);
		TQString parseLDAPSyncProvOverlayConfigRecord(LDAPMessage* entry);
		bool parseLDAPTDEStringAttribute(LDAPMessage* entry, TQString attribute, TQString& retval);
		static TQString getOpenSSLVersion();

	private:
		TQString m_realm;
		TQString m_host;
		int m_port;
		TQString m_basedc;
		LDAPCredentials* m_creds;
		LDAP *m_ldap;

		// kadmin interface
		krb5_context m_krb5admContext;
		void* m_krb5admHandle;
		char* m_krb5admKeytabFilename;
		char* m_krb5admRealmName;
};

#endif // _LIBTDELDAP_H_
