# Stolen from upstream CVS B2_0_Release branch
# Fixes CVE-2008-0467http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-0467
# Debian BTS: http://bugs.debian.org/463596
# Upstream CORE-1603: http://tracker.firebirdsql.org/browse/CORE-1603?page=com.atlassian.jira.plugin.system.issuetabpanels:cvs-tabpanel
--- 2.0.orig/src/jrd/constants.h
+++ 2.0/src/jrd/constants.h
@@ -56,7 +56,7 @@
 
 /* Misc constant values */
 
-const int USERNAME_LENGTH	= 31;	/* Characters */
+const unsigned int USERNAME_LENGTH	= 31;	/* Characters */
 
 const size_t MAX_SQL_IDENTIFIER_SIZE = 32;
 const size_t MAX_SQL_IDENTIFIER_LEN = MAX_SQL_IDENTIFIER_SIZE - 1;
--- 2.0.orig/src/jrd/isc.cpp
+++ 2.0/src/jrd/isc.cpp
@@ -87,14 +87,13 @@
 
 #include <windows.h>
 #include <aclapi.h>
+#include <lmcons.h>
 
 static USHORT os_type;
 static SECURITY_ATTRIBUTES security_attr;
 
 //static TEXT interbase_directory[MAXPATHLEN];
 
-static bool check_user_privilege();
-
 #endif // WIN_NT
 
 static TEXT user_name[256];
@@ -393,14 +392,29 @@
 }
 #endif
 
+const TEXT* ISC_get_host(Firebird::string& host)
+{
+/**************************************
+ *
+ *      I S C _ g e t _ h o s t
+ *
+ **************************************
+ *
+ * Functional description
+ *      Get host name in non-plain buffer.
+ *
+ **************************************/
+	TEXT buffer[BUFFER_SMALL];
+	ISC_get_host(buffer, sizeof(buffer));
+	host = buffer;
+	return host.c_str();
+}
+
 #ifdef UNIX
-int ISC_get_user(TEXT*	name,
-									  int*	id,
-									  int*	group,
-									  TEXT*	project,
-									  TEXT*	organization,
-									  int*	node,
-									  const TEXT*	user_string)
+bool ISC_get_user(Firebird::string*	name, 
+				  int*	id,
+				  int*	group,
+				  const TEXT*	user_string)
 {
 /**************************************
  *
@@ -448,7 +462,7 @@
 	}
 
 	if (name)
-		strcpy(name, p);
+		*name = p;
 
 	if (id)
 		*id = euid;
@@ -456,15 +470,6 @@
 	if (group)
 		*group = egid;
 
-	if (project)
-		*project = 0;
-
-	if (organization)
-		*organization = 0;
-
-	if (node)
-		*node = 0;
-
 	return (euid == 0);
 }
 #endif
@@ -573,13 +578,10 @@
 #endif
 
 #ifdef WIN_NT
-int ISC_get_user(TEXT*	name,
-									  int*	id,
-									  int*	group,
-									  TEXT*	project,
-									  TEXT*	organization,
-									  int*	node,
-									  const TEXT*	user_string)
+bool ISC_get_user(Firebird::string*	name, 
+				  int*	id,
+				  int*	group,
+				  const TEXT*	user_string)
 {
 /**************************************
  *
@@ -597,162 +599,25 @@
 	if (group)
 		*group = -1;
 
-	if (project)
-		*project = 0;
-
-	if (organization)
-		*organization = 0;
-
-	if (node)
-		*node = 0;
-
 	if (name)
 	{
-		name[0] = 0;
-		DWORD  name_len = 128;
-		if (GetUserName(name, &name_len))
-		{
-			name[name_len] = 0;
-
-			/* NT user name is case insensitive */
-
-			for (DWORD i = 0; i < name_len; i++)
-			{
-				name[i] = UPPER7(name[i]);
-			}
-
-/* This check is not internationalized, the security model needs to be
- * reengineered, especially on SUPERSERVER where none of these local
- * user (in process) assumptions are valid.
-			if (!strcmp(name, "ADMINISTRATOR"))
-			{
-				if (id)
-					*id = 0;
-
-				if (group)
-					*group = 0;
-			}
- */
-		}
-	}
-
-	return check_user_privilege();
-}
-
-
-//____________________________________________________________
-//
-// Check to see if the user belongs to the administrator group.
-//
-// This routine was adapted from code in routine RunningAsAdminstrator
-// in \mstools\samples\regmpad\regdb.c.
-//
-static bool check_user_privilege()
-{
-	HANDLE tkhandle;
-	SID_IDENTIFIER_AUTHORITY system_sid_authority = {SECURITY_NT_AUTHORITY};
-
-	// First we must open a handle to the access token for this thread.
-
-	if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &tkhandle))
-	{
-		if (GetLastError() == ERROR_NO_TOKEN)
+		DWORD name_len = UNLEN;
+		TEXT* nm = name->getBuffer(name_len + 1);
+		if (GetUserName(nm, &name_len))
 		{
-			// If the thread does not have an access token, we'll examine the
-			// access token associated with the process.
+			nm[name_len] = 0;
 
-			if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tkhandle))
-			{
-				CloseHandle(tkhandle);
-				return false;
-			}
+			// NT user name is case insensitive
+			CharUpperBuff(nm, name_len);
+			name->recalculate_length();
 		}
 		else
 		{
-			return false;
+			*name = "";
 		}
 	}
 
-	TOKEN_GROUPS*	ptg       = NULL;
-	DWORD			token_len = 0;
-
-	while (true)
-	{
-		/* Then we must query the size of the group information associated with
-		   the token.  This is guarenteed to fail the first time through
-		   because there is no buffer. */
-
-		if (GetTokenInformation(tkhandle,
-								TokenGroups,
-								ptg,
-								token_len,
-								&token_len))
-		{
-			break;
-		}
-
-		/* If there had been a buffer, it's either too small or something
-		   else is wrong.  Either way, we can dispose of it. */
-
-		if (ptg)
-		{
-			gds__free(ptg);
-		}
-
-		/* Here we verify that GetTokenInformation failed for lack of a large
-		   enough buffer. */
-
-		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-		{
-			CloseHandle(tkhandle);
-			return false;
-		}
-
-		// Allocate a buffer for the group information.
-		ptg = (TOKEN_GROUPS *) gds__alloc((SLONG) token_len);
-
-		if (!ptg)
-		{
-			CloseHandle(tkhandle);
-			return false;		/* NOMEM: */
-		}
-		// FREE: earlier in this loop, and at procedure return
-	}
-
-	// Create a System Identifier for the Admin group.
-
-	PSID admin_sid;
-
-	if (!AllocateAndInitializeSid(&system_sid_authority, 2,
-								  SECURITY_BUILTIN_DOMAIN_RID,
-								  DOMAIN_ALIAS_RID_ADMINS,
-								  0, 0, 0, 0, 0, 0, &admin_sid))
-	{
-		gds__free(ptg);
-		CloseHandle(tkhandle);
-		return false;
-	}
-
-	// Finally we'll iterate through the list of groups for this access
-	// token looking for a match against the SID we created above.
-
-	bool admin_priv = false;
-
-	for (DWORD i = 0; i < ptg->GroupCount; i++)
-	{
-		if (EqualSid(ptg->Groups[i].Sid, admin_sid))
-		{
-			admin_priv = true;
-			break;
-		}
-	}
-
-	// Deallocate the SID we created.
-
-	FreeSid(admin_sid);
-	gds__free(ptg);
-	CloseHandle(tkhandle);
-	return admin_priv;
+	return false;
 }
 #endif
 
--- 2.0.orig/src/jrd/isc_proto.h
+++ 2.0/src/jrd/isc_proto.h
@@ -25,6 +25,7 @@
 #define JRD_ISC_PROTO_H
 
 #include "../jrd/isc.h"
+#include "../common/classes/fb_string.h"
 
 void	ISC_ast_enter(void);
 void	ISC_ast_exit(void);
@@ -32,9 +33,9 @@
 // There's no body for those functions.
 //void	ISC_get_config(TEXT *, struct ipccfg *);
 //int		ISC_set_config(TEXT *, struct ipccfg *);
-TEXT*	ISC_get_host(TEXT *, USHORT);
-int		ISC_get_user(TEXT*, int*, int*, TEXT*,
-											 TEXT*, int*, const TEXT*);
+TEXT*  ISC_get_host(TEXT *, USHORT);
+const TEXT* ISC_get_host(Firebird::string&);
+bool  ISC_get_user(Firebird::string*, int*, int*, const TEXT*);
 SLONG	ISC_get_user_group_id(const TEXT*);
 void	ISC_set_user(const TEXT*);
 SLONG	ISC_get_prefix(const TEXT*);
--- 2.0.orig/src/jrd/jrd.cpp
+++ 2.0/src/jrd/jrd.cpp
@@ -6699,12 +6699,9 @@
  **/
 static void getUserInfo(UserId& user, const DatabaseOptions& options)
 {
-	TEXT name[129] = "";
-	TEXT project[33] = "";
-	TEXT organization[33] = "";
-
-	int node_id = 0;
 	int id = -1, group = -1;	// CVC: This var contained trash
+	int node_id = 0;
+	Firebird::string name;
 
 #ifdef BOOT_BUILD
 	bool wheel = true;
@@ -6712,12 +6709,9 @@
 	bool wheel = false;
 	if (options.dpb_user_name.isEmpty()) 
 	{
-       wheel = ISC_get_user(name,
+       wheel = ISC_get_user(&name,
                             &id,
                             &group,
-                            project,
-                            organization,
-                            &node_id,
                             options.dpb_sys_user_name.nullStr());
 	}
 
@@ -6738,18 +6732,18 @@
 		{
 			if (options.dpb_user_name.hasData())
 			{
-				options.dpb_user_name.copyTo(name, sizeof name);
+				name = options.dpb_user_name;
 			}
 			else
 			{
-				strcpy(name, "<Unknown>");
+				name = "<Unknown>";
 			}
 		}
 
 		// if the name from the user database is defined as SYSDBA,
 		// we define that user id as having system privileges
 
-		if (!strcmp(name, SYSDBA_USER_NAME))
+		if (name == SYSDBA_USER_NAME)
 		{
 			wheel = true;
 		}
@@ -6761,12 +6755,12 @@
 
 	if (wheel)
 	{
-		strcpy(name, SYSDBA_USER_NAME);
+		name = SYSDBA_USER_NAME;
 	}
 
 	user.usr_user_name = name;
-	user.usr_project_name = project;
-	user.usr_org_name = organization;
+	user.usr_project_name = "";
+	user.usr_org_name = "";
 	user.usr_sql_role_name = options.dpb_role_name;
 	user.usr_user_id = id;
 	user.usr_group_id = group;
--- 2.0.orig/src/jrd/jrd_pwd.h
+++ 2.0/src/jrd/jrd_pwd.h
@@ -66,11 +66,11 @@
 
 	static void initialize();
 	static void shutdown();
-	static void verifyUser(TEXT*, const TEXT*, const TEXT*, const TEXT*,
+	static void verifyUser(Firebird::string&, const TEXT*, const TEXT*, const TEXT*,
 		int*, int*, int*, const Firebird::string&);
 
 	static void hash(Firebird::string& h, 
-					 const TEXT* userName, 
+					 const Firebird::string& userName, 
 					 const TEXT* passwd)
 	{
 		Firebird::string salt;
@@ -79,7 +79,7 @@
 	}
 
 	static void hash(Firebird::string& h, 
-					 const TEXT* userName, 
+					 const Firebird::string& userName, 
 					 const TEXT* passwd,
 					 const Firebird::string& oldHash)
 	{
@@ -110,7 +110,7 @@
 
 	void fini();
 	void init();
-	bool lookup_user(TEXT*, int*, int*, TEXT*);
+	bool lookup_user(const TEXT*, int*, int*, TEXT*);
 	bool prepare();
 
 	static SecurityDatabase instance;
--- 2.0.orig/src/jrd/pwd.cpp
+++ 2.0/src/jrd/pwd.cpp
@@ -263,7 +263,7 @@
 	counter += (is_cached) ? 1 : 0;
 }
 
-bool SecurityDatabase::lookup_user(TEXT * user_name, int *uid, int *gid, TEXT * pwd)
+bool SecurityDatabase::lookup_user(const TEXT* user_name, int* uid, int* gid, TEXT* pwd)
 {
 	bool found = false;		// user found flag
 	TEXT uname[129];		// user name buffer
@@ -433,7 +433,7 @@
 	instance.fini();
 }
 
-void SecurityDatabase::verifyUser(TEXT* name,
+void SecurityDatabase::verifyUser(Firebird::string& name,
 								  const TEXT* user_name,
 								  const TEXT* password,
 								  const TEXT* password_enc,
@@ -444,12 +444,11 @@
 {
 	if (user_name)
 	{
-		TEXT* p = name;
-		for (const TEXT* q = user_name; *q; ++q, ++p)
+		name = user_name;
+		for (unsigned int n = 0; n < name.length(); ++n)
 		{
-			*p = UPPER7(*q);
+			name[n] = UPPER7(name[n]);
 		}
-		*p = 0;
 	}
 
 #ifndef EMBEDDED
@@ -459,7 +458,7 @@
 	// that means the current context must be saved and restored.
 
 	TEXT pw1[MAX_PASSWORD_LENGTH + 1];
-	const bool found = instance.lookup_user(name, uid, gid, pw1);
+	const bool found = instance.lookup_user(name.c_str(), uid, gid, pw1);
 	pw1[MAX_PASSWORD_LENGTH] = 0;
 	Firebird::string storedHash(pw1, MAX_PASSWORD_LENGTH);
 	storedHash.rtrim();
--- 2.0.orig/src/jrd/svc.cpp
+++ 2.0/src/jrd/svc.cpp
@@ -516,7 +516,7 @@
 		}
 		else 
 		{
-			TEXT name[129]; // unused after retrieved
+			Firebird::string name; // unused after retrieved
 			int id, group, node_id;
 			
 			Firebird::string remote = options.spb_network_protocol +
--- 2.0.orig/src/remote/inet.cpp
+++ 2.0/src/remote/inet.cpp
@@ -462,20 +462,16 @@
 
 /* Pick up some user identification information */
 	Firebird::ClumpletWriter user_id(Firebird::ClumpletReader::UnTagged, MAX_DPB_SIZE);
-	char buffer[BUFFER_SMALL];
-
+	Firebird::string buffer;
 	int eff_gid;
 	int eff_uid;
-	ISC_get_user(buffer, &eff_uid, &eff_gid, 0, 0, 0, user_string);
-	user_id.insertString(CNCT_user, buffer, strlen(buffer));
 
-	ISC_get_host(buffer, sizeof(buffer));
-	for (char* p = buffer; *p; p++) {
-		if (*p >= 'A' && *p <= 'Z') {
-			*p = *p - 'A' + 'a';
-		}
-	}
-	user_id.insertString(CNCT_host, buffer, strlen(buffer));
+	ISC_get_user(&buffer, &eff_uid, &eff_gid, user_string);
+	user_id.insertString(CNCT_user, buffer);
+
+	ISC_get_host(buffer);
+	buffer.lower();
+	user_id.insertString(CNCT_host, buffer);
 
 	if ((eff_uid == -1) || uv_flag) {
 		user_id.insertTag(CNCT_user_verification);
--- 2.0.orig/src/remote/inet_server.cpp
+++ 2.0/src/remote/inet_server.cpp
@@ -96,6 +96,7 @@
 #include "../jrd/sch_proto.h"
 #include "../jrd/thread_proto.h"
 #include "../common/utils_proto.h"
+#include "../common/classes/fb_string.h"
 
 #ifdef UNIX
 #ifdef NETBSD
@@ -328,14 +329,14 @@
             // Remove restriction on username, for DEV builds
             // restrict only for production builds.  MOD 21-July-2002
 #ifndef DEV_BUILD
-			TEXT user_name[256];	/* holds the user name */
+			Firebird::string user_name;	/* holds the user name */
 			/* check user id */
-			ISC_get_user(user_name, NULL, NULL, NULL, NULL, NULL, NULL);
+			ISC_get_user(&user_name, NULL, NULL, NULL);
 
-			if (strcmp(user_name, "root") &&
-				strcmp(user_name, FIREBIRD_USER_NAME) &&
-				strcmp(user_name, INTERBASE_USER_NAME) &&
-				strcmp(user_name, INTERBASE_USER_SHORT))
+			if (user_name != "root" &&
+				user_name != FIREBIRD_USER_NAME &&
+				user_name != INTERBASE_USER_NAME &&
+				user_name != INTERBASE_USER_SHORT)
 			{
 				/* invalid user -- bail out */
 				fprintf(stderr,
--- 2.0.orig/src/remote/os/win32/wnet.cpp
+++ 2.0/src/remote/os/win32/wnet.cpp
@@ -135,25 +135,17 @@
 	PACKET* packet = &rdb->rdb_packet;
 
 /* Pick up some user identification information */
-	TEXT buffer[128];
+	Firebird::string buffer;
 	TEXT *p;
 	Firebird::ClumpletWriter user_id(Firebird::ClumpletReader::UnTagged, MAX_DPB_SIZE);
 
-	ISC_get_user(buffer, 0, 0, 0, 0, 0, 0);
-	for (p = buffer; *p; p++) {
-		if (*p >= 'A' && *p <= 'Z') {
-			*p = *p - 'A' + 'a';
-		}
-	}
-	user_id.insertString(CNCT_user, buffer, strlen(buffer));
-
-	ISC_get_host(buffer, sizeof(buffer));
-	for (p = buffer; *p; p++) {
-		if (*p >= 'A' && *p <= 'Z') {
-			*p = *p - 'A' + 'a';
-		}
-	}
-	user_id.insertString(CNCT_host, buffer, strlen(buffer));
+	ISC_get_user(&buffer, 0, 0, 0);
+	buffer.lower();
+	user_id.insertString(CNCT_user, buffer);
+
+	ISC_get_host(buffer);
+	buffer.lower();
+	user_id.insertString(CNCT_host, buffer);
 
 	if (uv_flag) {
 		user_id.insertTag(CNCT_user_verification);
--- 2.0.orig/src/remote/xnet.cpp
+++ 2.0/src/remote/xnet.cpp
@@ -214,25 +214,16 @@
 
 	// Pick up some user identification information
 
-	TEXT buffer[BUFFER_TINY];
-	TEXT *p;
+	Firebird::string buffer;
 	Firebird::ClumpletWriter user_id(Firebird::ClumpletReader::UnTagged, MAX_DPB_SIZE);
 
-	ISC_get_user(buffer, 0, 0, 0, 0, 0, 0);
-	for (p = buffer; *p; p++) {
-		if (*p >= 'A' && *p <= 'Z') {
-			*p = *p - 'A' + 'a';
-		}
-	}
-	user_id.insertString(CNCT_user, buffer, strlen(buffer));
-
-	ISC_get_host(buffer, sizeof(buffer));
-	for (p = buffer; *p; p++) {
-		if (*p >= 'A' && *p <= 'Z') {
-			*p = *p - 'A' + 'a';
-		}
-	}
-	user_id.insertString(CNCT_host, buffer, strlen(buffer));
+	ISC_get_user(&buffer, 0, 0, 0);
+	buffer.lower();
+	user_id.insertString(CNCT_user, buffer);
+
+	ISC_get_host(buffer);
+	buffer.lower();
+	user_id.insertString(CNCT_host, buffer);
 
 	if (uv_flag) {
 		user_id.insertTag(CNCT_user_verification);
--- 2.0.orig/src/utilities/guard/guard.cpp
+++ 2.0/src/utilities/guard/guard.cpp
@@ -45,6 +45,7 @@
 #include "../jrd/gds_proto.h"
 #include "../jrd/file_params.h"
 #include "../utilities/guard/util_proto.h"
+#include "../common/classes/fb_string.h"
 
 const USHORT FOREVER	= 1;
 const USHORT ONETIME	= 2;
@@ -107,12 +108,13 @@
 	}							/* while */
 
 /* check user id */
-	TEXT user_name[256];		/* holds the user name */
-	ISC_get_user(user_name, NULL, NULL, NULL, NULL, NULL, NULL);
+	Firebird::string user_name;		/* holds the user name */
+	ISC_get_user(&user_name, NULL, NULL, NULL);
 
-	if (strcmp(user_name, INTERBASE_USER) && strcmp(user_name, "root")
-		&& strcmp(user_name, FIREBIRD_USER)
-		&& strcmp(user_name, INTERBASE_USER_SHORT))
+	if (user_name != INTERBASE_USER && 
+		user_name != "root" &&
+		user_name != FIREBIRD_USER &&
+		user_name != INTERBASE_USER_SHORT)
 	{
 		/* invalid user bail out */
 		fprintf(stderr,
