# 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 #include +#include 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, ""); + name = ""; } } // 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,