|
From: <ale...@us...> - 2010-07-09 12:51:12
|
Revision: 51322
http://firebird.svn.sourceforge.net/firebird/?rev=51322&view=rev
Author: alexpeshkoff
Date: 2010-07-09 12:51:05 +0000 (Fri, 09 Jul 2010)
Log Message:
-----------
ODS change: made RDB$USERS system table, added virtual table SEC$USERS
Modified Paths:
--------------
firebird/trunk/builds/posix/Makefile.in.firebird
firebird/trunk/builds/posix/make.shared.variables
firebird/trunk/src/dbs/security.sql
firebird/trunk/src/include/gen/ids.h
firebird/trunk/src/jrd/DatabaseSnapshot.cpp
firebird/trunk/src/jrd/DatabaseSnapshot.h
firebird/trunk/src/jrd/Relation.h
firebird/trunk/src/jrd/UserManagement.cpp
firebird/trunk/src/jrd/UserManagement.h
firebird/trunk/src/jrd/constants.h
firebird/trunk/src/jrd/fields.h
firebird/trunk/src/jrd/idx.h
firebird/trunk/src/jrd/ini.epp
firebird/trunk/src/jrd/met.epp
firebird/trunk/src/jrd/names.h
firebird/trunk/src/jrd/opt.cpp
firebird/trunk/src/jrd/recsrc/RecordSource.h
firebird/trunk/src/jrd/relations.h
firebird/trunk/src/jrd/svc.cpp
firebird/trunk/src/jrd/types.h
firebird/trunk/src/msgs/facilities2.sql
firebird/trunk/src/msgs/messages2.sql
firebird/trunk/src/utilities/gsec/gsec.cpp
firebird/trunk/src/utilities/gsec/gsec.h
firebird/trunk/src/utilities/gsec/gsecswi.h
firebird/trunk/src/utilities/gsec/secur_proto.h
firebird/trunk/src/utilities/gsec/security.epp
Added Paths:
-----------
firebird/trunk/src/jrd/recsrc/UsersTableScan.cpp
Modified: firebird/trunk/builds/posix/Makefile.in.firebird
===================================================================
--- firebird/trunk/builds/posix/Makefile.in.firebird 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/builds/posix/Makefile.in.firebird 2010-07-09 12:51:05 UTC (rev 51322)
@@ -76,9 +76,7 @@
# use the static files as a last resort.
#
# The bootstrap version of gpre (gpre_boot) is used to build all the
-# engine files, except security.bin. security.epp requires the security
-# database which is not available at this time. The code in jrd/alt.cpp
-# that references the functions in security.bin has been #ifdef'ed out.
+# engine file.
# During this phase of the build process the limited version of alt.bin
# is used. The full version of alt.bin is compiled later in the build
# process after the security database is available. After the
Modified: firebird/trunk/builds/posix/make.shared.variables
===================================================================
--- firebird/trunk/builds/posix/make.shared.variables 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/builds/posix/make.shared.variables 2010-07-09 12:51:05 UTC (rev 51322)
@@ -53,7 +53,7 @@
recsrc/MergeJoin.cpp recsrc/NestedLoopJoin.cpp \
recsrc/ProcedureScan.cpp recsrc/RecordSource.cpp recsrc/RecursiveStream.cpp \
recsrc/SingularStream.cpp recsrc/SkipRowsStream.cpp recsrc/SortedStream.cpp recsrc/Union.cpp \
- recsrc/VirtualTableScan.cpp recsrc/WindowedStream.cpp
+ recsrc/VirtualTableScan.cpp recsrc/UsersTableScan.cpp recsrc/WindowedStream.cpp
JRD_ServerSources = $(addprefix jrd/, $(JRD_ServerFiles))
JRD_ServerSources += gpre/pretty.cpp
@@ -357,7 +357,7 @@
# MOD 29-July-2002
# Stub for services entrypoints missing in static library
-STUB_Sources = jrd/svc_stub.cpp
+STUB_Sources = jrd/svc_stub.cpp utilities/gsec/security.epp
STUB_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(STUB_Sources))))
Modified: firebird/trunk/src/dbs/security.sql
===================================================================
--- firebird/trunk/src/dbs/security.sql 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/dbs/security.sql 2010-07-09 12:51:05 UTC (rev 51322)
@@ -22,57 +22,6 @@
* (see http://www.volny.cz/iprenosil/interbase/ for details).
*/
-/* Domain definitions */
-CREATE DOMAIN RDB$COMMENT AS BLOB SUB_TYPE TEXT SEGMENT SIZE 80 CHARACTER SET UNICODE_FSS;
-CREATE DOMAIN RDB$NAME_PART AS VARCHAR(32) CHARACTER SET UNICODE_FSS DEFAULT _UNICODE_FSS '';
-CREATE DOMAIN RDB$GID AS INTEGER;
-CREATE DOMAIN RDB$PASSWD AS VARCHAR(64) CHARACTER SET BINARY;
-CREATE DOMAIN RDB$UID AS INTEGER;
-CREATE DOMAIN RDB$USER_NAME AS VARCHAR(128) CHARACTER SET UNICODE_FSS;
-CREATE DOMAIN RDB$USER_PRIVILEGE AS INTEGER;
-
-
-/* Table: RDB$USERS */
-CREATE TABLE RDB$USERS (
- RDB$USER_NAME RDB$USER_NAME NOT NULL PRIMARY KEY,
- /* local system user name for setuid for file permissions */
- RDB$SYS_USER_NAME RDB$USER_NAME,
- RDB$GROUP_NAME RDB$USER_NAME,
- RDB$UID RDB$UID,
- RDB$GID RDB$GID,
- RDB$PASSWD RDB$PASSWD NOT NULL,
-
- /* Privilege level of user - mark a user as having DBA privilege */
- RDB$PRIVILEGE RDB$USER_PRIVILEGE,
-
- RDB$COMMENT RDB$COMMENT,
- RDB$FIRST_NAME RDB$NAME_PART,
- RDB$MIDDLE_NAME RDB$NAME_PART,
- RDB$LAST_NAME RDB$NAME_PART);
-
-COMMIT;
-
-/* View: USERS. Let's user modify his own password. */
-CREATE VIEW USERS (USER_NAME, SYS_USER_NAME, GROUP_NAME, UID, GID, PASSWD,
- PRIVILEGE, COMMENT, FIRST_NAME, MIDDLE_NAME, LAST_NAME, FULL_NAME) AS
- SELECT RDB$USER_NAME, RDB$SYS_USER_NAME, RDB$GROUP_NAME, RDB$UID, RDB$GID, RDB$PASSWD,
- RDB$PRIVILEGE, RDB$COMMENT, RDB$FIRST_NAME, RDB$MIDDLE_NAME, RDB$LAST_NAME,
- COALESCE (RDB$first_name || _UNICODE_FSS ' ', '') ||
- COALESCE (RDB$middle_name || _UNICODE_FSS ' ', '') ||
- COALESCE (RDB$last_name, '')
- FROM RDB$USERS
- WHERE CURRENT_USER = 'SYSDBA'
- OR CURRENT_ROLE = 'RDB$ADMIN'
- OR CURRENT_USER = RDB$USERS.RDB$USER_NAME;
-
-/* Access rights */
-GRANT ALL ON RDB$USERS to VIEW USERS;
-GRANT SELECT ON USERS to PUBLIC;
-GRANT UPDATE(PASSWD, GROUP_NAME, UID, GID, FIRST_NAME, MIDDLE_NAME, LAST_NAME)
- ON USERS TO PUBLIC;
-
-COMMIT;
-
/* Needed record - with PASSWD = random + SHA1 (random + 'SYSDBA' + crypt('masterke')) */
INSERT INTO RDB$USERS(RDB$USER_NAME, RDB$PASSWD, RDB$FIRST_NAME, RDB$MIDDLE_NAME, RDB$LAST_NAME)
VALUES ('SYSDBA', 'NLtwcs9LrxLMOYhG0uGM9i6KS7mf3QAKvFVpmRg=', 'Sql', 'Server', 'Administrator');
Modified: firebird/trunk/src/include/gen/ids.h
===================================================================
--- firebird/trunk/src/include/gen/ids.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/include/gen/ids.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -592,3 +592,28 @@
const USHORT f_pkg_desc = 6;
+// Relation 43 (RDB$USERS)
+
+ const USHORT f_user_name = 0;
+ const USHORT f_group_name = 1;
+ const USHORT f_uid = 2;
+ const USHORT f_gid = 3;
+ const USHORT f_passwd_type = 4;
+ const USHORT f_passwd = 5;
+ const USHORT f_first_name = 6;
+ const USHORT f_middle_name = 7;
+ const USHORT f_last_name = 8;
+ const USHORT f_user_desc = 9;
+
+
+// Relation 44 (SEC$USERS)
+
+ const USHORT f_sec_user_name = 0;
+ const USHORT f_sec_group_name = 1;
+ const USHORT f_sec_uid = 2;
+ const USHORT f_sec_gid = 3;
+ const USHORT f_sec_first_name = 4;
+ const USHORT f_sec_middle_name = 5;
+ const USHORT f_sec_last_name = 6;
+
+
Modified: firebird/trunk/src/jrd/DatabaseSnapshot.cpp
===================================================================
--- firebird/trunk/src/jrd/DatabaseSnapshot.cpp 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/DatabaseSnapshot.cpp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -370,7 +370,7 @@
DatabaseSnapshot::DatabaseSnapshot(thread_db* tdbb, MemoryPool& pool)
- : snapshot(pool), idMap(pool), idCounter(0)
+ : DataDump(pool), snapshot(pool)
{
SET_TDBB(tdbb);
@@ -589,7 +589,7 @@
jrd_rel* relation = MET_lookup_relation_id(tdbb, rel_id, false);
fb_assert(relation);
MET_scan_relation(tdbb, relation);
- fb_assert(relation->isVirtual());
+ fb_assert(relation->isVirtual() && !relation->isUsers());
Format* format = MET_current(tdbb, relation);
fb_assert(format);
@@ -601,7 +601,7 @@
}
-void DatabaseSnapshot::clearRecord(Record* record)
+void DataDump::clearRecord(Record* record)
{
fb_assert(record);
@@ -612,7 +612,7 @@
}
-void DatabaseSnapshot::putField(thread_db* tdbb, Record* record, const DumpField& field,
+void DataDump::putField(thread_db* tdbb, Record* record, const DumpField& field,
int& charset, bool set_charset)
{
fb_assert(record);
Modified: firebird/trunk/src/jrd/DatabaseSnapshot.h
===================================================================
--- firebird/trunk/src/jrd/DatabaseSnapshot.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/DatabaseSnapshot.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -18,6 +18,7 @@
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
+ * Alex Peshkoff, 2010 - divided into class DataDump and the remaining part of DatabaseSnapshot
*/
#ifndef JRD_DATABASE_SNAPSHOT_H
@@ -26,24 +27,36 @@
#include "../common/classes/array.h"
#include "../common/classes/init.h"
#include "../jrd/isc_s_proto.h"
+#include "../common/classes/timestamp.h"
+#include "../jrd/val.h"
namespace Jrd {
// forward declarations
class jrd_rel;
+class Record;
class RecordBuffer;
class RuntimeStatistics;
-class DatabaseSnapshot
+class DataDump
{
+public:
enum ValueType {VALUE_GLOBAL_ID, VALUE_INTEGER, VALUE_TIMESTAMP, VALUE_STRING};
+ DataDump(MemoryPool& pool)
+ : idMap(pool), idCounter(0) { }
+
struct DumpField
{
+ DumpField(USHORT p_id, ValueType p_type, USHORT p_length, const void* p_data)
+ : id(p_id), type(p_type), length(p_length), data(p_data) { }
+ DumpField()
+ : id(0), type(VALUE_GLOBAL_ID), length(0), data(NULL) { }
+
USHORT id;
ValueType type;
USHORT length;
- void* data;
+ const void* data;
};
class DumpRecord
@@ -178,6 +191,16 @@
ULONG sizeLimit;
};
+ void clearRecord(Record*);
+ void putField(thread_db*, Record*, const DumpField&, int&, bool = false);
+
+private:
+ Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<SINT64, SLONG> > > idMap;
+ int idCounter;
+};
+
+class DatabaseSnapshot : public DataDump
+{
struct RelationData
{
int rel_id;
@@ -321,8 +344,6 @@
private:
RecordBuffer* allocBuffer(thread_db*, MemoryPool&, int);
- void clearRecord(Record*);
- void putField(thread_db*, Record*, const DumpField&, int&, bool = false);
static void dumpData(thread_db*);
@@ -338,8 +359,6 @@
static void putMemoryUsage(const Firebird::MemoryStats&, Writer&, int, int);
Firebird::Array<RelationData> snapshot;
- Firebird::GenericMap<Firebird::Pair<Firebird::NonPooled<SINT64, SLONG> > > idMap;
- int idCounter;
};
} // namespace
Modified: firebird/trunk/src/jrd/Relation.h
===================================================================
--- firebird/trunk/src/jrd/Relation.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/Relation.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -176,8 +176,8 @@
{
public:
USHORT rel_id;
- USHORT rel_flags;
USHORT rel_current_fmt; // Current format number
+ ULONG rel_flags;
Format* rel_current_format; // Current record format
Firebird::MetaName rel_name; // ascii relation name
vec<Format*>* rel_formats; // Known record formats
@@ -219,6 +219,7 @@
bool isSystem() const;
bool isTemporary() const;
bool isVirtual() const;
+ bool isUsers() const;
// global temporary relations attributes
RelationPages* getPages(thread_db* tdbb, SLONG tran = -1, bool allocPages = true);
@@ -282,22 +283,23 @@
// rel_flags
-const USHORT REL_scanned = 0x0001; // Field expressions scanned (or being scanned)
-const USHORT REL_system = 0x0002;
-const USHORT REL_deleted = 0x0004; // Relation known gonzo
-const USHORT REL_get_dependencies = 0x0008; // New relation needs dependencies during scan
-const USHORT REL_force_scan = 0x0010; // system relation has been updated since ODS change, force a scan
-const USHORT REL_check_existence = 0x0020; // Existence lock released pending drop of relation
-const USHORT REL_blocking = 0x0040; // Blocking someone from dropping relation
-const USHORT REL_sys_triggers = 0x0080; // The relation has system triggers to compile
-const USHORT REL_sql_relation = 0x0100; // Relation defined as sql table
-const USHORT REL_check_partners = 0x0200; // Rescan primary dependencies and foreign references
-const USHORT REL_being_scanned = 0x0400; // relation scan in progress
-const USHORT REL_sys_trigs_being_loaded = 0x0800; // System triggers being loaded
-const USHORT REL_deleting = 0x1000; // relation delete in progress
-const USHORT REL_temp_tran = 0x2000; // relation is a GTT delete rows
-const USHORT REL_temp_conn = 0x4000; // relation is a GTT preserve rows
-const USHORT REL_virtual = 0x8000; // relation is virtual
+const ULONG REL_scanned = 0x0001; // Field expressions scanned (or being scanned)
+const ULONG REL_system = 0x0002;
+const ULONG REL_deleted = 0x0004; // Relation known gonzo
+const ULONG REL_get_dependencies = 0x0008; // New relation needs dependencies during scan
+const ULONG REL_force_scan = 0x0010; // system relation has been updated since ODS change, force a scan
+const ULONG REL_check_existence = 0x0020; // Existence lock released pending drop of relation
+const ULONG REL_blocking = 0x0040; // Blocking someone from dropping relation
+const ULONG REL_sys_triggers = 0x0080; // The relation has system triggers to compile
+const ULONG REL_sql_relation = 0x0100; // Relation defined as sql table
+const ULONG REL_check_partners = 0x0200; // Rescan primary dependencies and foreign references
+const ULONG REL_being_scanned = 0x0400; // relation scan in progress
+const ULONG REL_sys_trigs_being_loaded = 0x0800; // System triggers being loaded
+const ULONG REL_deleting = 0x1000; // relation delete in progress
+const ULONG REL_temp_tran = 0x2000; // relation is a GTT delete rows
+const ULONG REL_temp_conn = 0x4000; // relation is a GTT preserve rows
+const ULONG REL_virtual = 0x8000; // relation is virtual
+const ULONG REL_users = 0x00010000; // relation is users list
inline bool jrd_rel::isSystem() const
@@ -312,9 +314,14 @@
inline bool jrd_rel::isVirtual() const
{
- return (rel_flags & REL_virtual);
+ return (rel_flags & (REL_virtual | REL_users));
}
+inline bool jrd_rel::isUsers() const
+{
+ return (rel_flags & REL_users);
+}
+
inline RelationPages* jrd_rel::getPages(thread_db* tdbb, SLONG tran, bool allocPages)
{
if (!isTemporary())
Modified: firebird/trunk/src/jrd/UserManagement.cpp
===================================================================
--- firebird/trunk/src/jrd/UserManagement.cpp 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/UserManagement.cpp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -30,31 +30,36 @@
#include "../jrd/msg_encode.h"
#include "../utilities/gsec/gsec.h"
#include "../utilities/gsec/secur_proto.h"
+#include "../jrd/met_proto.h"
+#include "../jrd/ini.h"
+#include "gen/ids.h"
using namespace Jrd;
using namespace Firebird;
UserManagement::UserManagement(jrd_tra* tra)
- : database(0), transaction(0), commands(*tra->tra_pool)
+ : DataDump(*tra->tra_pool), database(0), transaction(0), buffer(0),
+ threadDbb(NULL), realUser(NULL), commands(*tra->tra_pool)
{
- char securityDatabaseName[MAXPATHLEN];
- Auth::SecurityDatabase::getPath(securityDatabaseName);
- ISC_STATUS_ARRAY status;
Attachment* att = tra->tra_attachment;
-
- ClumpletWriter dpb(ClumpletReader::dpbList, MAX_DPB_SIZE);
- dpb.insertByte(isc_dpb_gsec_attach, TRUE);
- dpb.insertString(isc_dpb_trusted_auth, att->att_user->usr_user_name);
- if (att->att_user->usr_flags & USR_trole)
+ if (!att || !att->att_user)
{
- dpb.insertString(isc_dpb_trusted_role, ADMIN_ROLE, strlen(ADMIN_ROLE));
+ (Arg::Gds(isc_random) << "Unknown user name for given transaction").raise();
}
- else if (!att->att_user->usr_sql_role_name.empty())
+ if (!att->att_user->locksmith())
{
- dpb.insertString(isc_dpb_trusted_role, att->att_user->usr_sql_role_name);
+ realUser = att->att_user->usr_user_name.c_str();
}
+ char securityDatabaseName[MAXPATHLEN];
+ Auth::SecurityDatabase::getPath(securityDatabaseName);
+
+ ClumpletWriter dpb(ClumpletReader::dpbList, MAX_DPB_SIZE);
+ dpb.insertByte(isc_dpb_gsec_attach, TRUE);
+ dpb.insertString(isc_dpb_trusted_auth, SYSDBA_USER_NAME);
+
+ ISC_STATUS_ARRAY status;
if (isc_attach_database(status, 0, securityDatabaseName, &database,
dpb.getBufferLength(), reinterpret_cast<const char*>(dpb.getBuffer())))
{
@@ -92,6 +97,8 @@
status_exception::raise(status);
}
}
+
+ delete buffer;
}
void UserManagement::commit()
@@ -119,6 +126,25 @@
return ret;
}
+void UserManagement::checkSecurityResult(int errcode, ISC_STATUS* status, const char* userName)
+{
+ Arg::StatusVector tmp;
+
+ if (!errcode)
+ {
+ return;
+ }
+
+ tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC));
+ if (errcode == GsecMsg22)
+ {
+ tmp << userName;
+ }
+ tmp.append(Arg::StatusVector(&status[0]));
+
+ tmp.raise();
+}
+
void UserManagement::execute(USHORT id)
{
if (!transaction || !commands[id])
@@ -138,30 +164,108 @@
#else
ISC_STATUS_ARRAY status;
int errcode = (!commands[id]->user_name_entered) ? GsecMsg18 :
- SECURITY_exec_line(status, database, transaction, commands[id], NULL, NULL);
+ SECURITY_exec_line(status, realUser, database, transaction, commands[id], NULL, NULL);
- switch (errcode)
+ checkSecurityResult(errcode, status, commands[id]->user_name);
+
+ delete commands[id];
+ commands[id] = NULL;
+#endif
+}
+
+void UserManagement::display(void* arg, const internal_user_data* u, bool/*firstTime*/)
+{
+ UserManagement* instance = reinterpret_cast<UserManagement*>(arg);
+ fb_assert(instance && instance->buffer);
+
+ instance->display(u);
+}
+
+void UserManagement::display(const internal_user_data* u)
+{
+ Record* record = buffer->getTempRecord();
+ clearRecord(record);
+
+ int attachment_charset = ttype_none;
+
+ if (u->user_name_entered)
+ putField(threadDbb, record,
+ DumpField(f_sec_user_name, VALUE_STRING, strlen(u->user_name), u->user_name),
+ attachment_charset);
+ if (u->group_name_entered)
+ putField(threadDbb, record,
+ DumpField(f_sec_group_name, VALUE_STRING, strlen(u->group_name), u->group_name),
+ attachment_charset);
+ if (u->uid_entered)
+ putField(threadDbb, record,
+ DumpField(f_sec_uid, VALUE_INTEGER, sizeof(int), &u->uid),
+ attachment_charset);
+ if (u->gid_entered)
+ putField(threadDbb, record,
+ DumpField(f_sec_gid, VALUE_INTEGER, sizeof(int), &u->gid),
+ attachment_charset);
+ if (u->first_name_entered)
+ putField(threadDbb, record,
+ DumpField(f_sec_first_name, VALUE_STRING, strlen(u->first_name), u->first_name),
+ attachment_charset);
+ if (u->middle_name_entered)
+ putField(threadDbb, record,
+ DumpField(f_sec_middle_name, VALUE_STRING, strlen(u->middle_name), u->middle_name),
+ attachment_charset);
+ if (u->last_name_entered)
+ putField(threadDbb, record,
+ DumpField(f_sec_last_name, VALUE_STRING, strlen(u->last_name), u->last_name),
+ attachment_charset);
+
+ buffer->store(record);
+}
+
+RecordBuffer* UserManagement::getList(thread_db* tdbb)
+{
+#ifdef EMBEDDED
+ // this restriction for embedded is temporarty and will gone when new build system will be introduced
+ status_exception::raise(Arg::Gds(isc_random) << "User management not supported in embedded library");
+#else
+ if (buffer)
{
- case 0: // nothing
- break;
- case GsecMsg22:
- {
- Arg::StatusVector tmp;
- tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC)) << Arg::Str(commands[id]->user_name);
- tmp.append(Arg::StatusVector(&status[0]));
- tmp.raise();
- }
+ return buffer;
+ }
- default:
+ try
+ {
+ threadDbb = tdbb;
+
+ jrd_rel* relation = MET_lookup_relation_id(threadDbb, rel_sec_users, false);
+ fb_assert(relation);
+
+ MET_scan_relation(threadDbb, relation);
+ fb_assert(relation->isUsers());
+
+ Format* format = MET_current(threadDbb, relation);
+ fb_assert(format);
+
+ MemoryPool* pool = threadDbb->getTransaction()->tra_pool;
+ fb_assert(pool);
+
+ buffer = FB_NEW(*pool) RecordBuffer(*pool, format);
+ fb_assert(buffer);
+
+ ISC_STATUS_ARRAY status;
+ internal_user_data u;
+ u.operation = DIS_OPER;
+ int errcode = SECURITY_exec_line(status, realUser, database, transaction, &u, display, this);
+ checkSecurityResult(errcode, status, u.user_name);
+ }
+ catch (const Exception&)
+ {
+ if (buffer)
{
- Arg::StatusVector tmp;
- tmp << Arg::Gds(ENCODE_ISC_MSG(errcode, GSEC_MSG_FAC));
- tmp.append(Arg::StatusVector(&status[0]));
- tmp.raise();
+ delete buffer;
+ buffer = NULL;
}
+ throw;
}
- delete commands[id];
- commands[id] = NULL;
+ return buffer;
#endif
}
Modified: firebird/trunk/src/jrd/UserManagement.h
===================================================================
--- firebird/trunk/src/jrd/UserManagement.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/UserManagement.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -25,7 +25,9 @@
#include "firebird.h"
#include "../common/classes/array.h"
+#include "../common/classes/fb_string.h"
#include "../jrd/ibase.h"
+#include "../jrd/DatabaseSnapshot.h"
struct internal_user_data;
@@ -33,9 +35,10 @@
class thread_db;
class jrd_tra;
+class RecordBuffer;
// User management argument for deferred work
-class UserManagement
+class UserManagement : public DataDump
{
public:
explicit UserManagement(jrd_tra* tra);
@@ -47,10 +50,19 @@
void execute(USHORT id);
// commit transaction in security database
void commit();
+ // return users list for SEC$USERS
+ RecordBuffer* getList(thread_db* tdbb);
private:
FB_API_HANDLE database, transaction;
+ RecordBuffer* buffer;
+ thread_db* threadDbb;
+ const char* realUser;
Firebird::HalfStaticArray<internal_user_data*, 8> commands;
+
+ static void display(void* arg, const internal_user_data* u, bool firstTime);
+ void display(const internal_user_data* u);
+ static void checkSecurityResult(int errcode, ISC_STATUS* status, const char* userName);
};
} // namespace
Modified: firebird/trunk/src/jrd/constants.h
===================================================================
--- firebird/trunk/src/jrd/constants.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/constants.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -202,7 +202,8 @@
rel_external = 2,
rel_virtual = 3,
rel_global_temp_preserve = 4,
- rel_global_temp_delete = 5
+ rel_global_temp_delete = 5,
+ rel_vrt_users = 6
};
// procedure types
Modified: firebird/trunk/src/jrd/fields.h
===================================================================
--- firebird/trunk/src/jrd/fields.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/fields.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -166,3 +166,9 @@
FIELD(fld_arg_mechanism , nam_arg_mechanism , dtype_short , sizeof(SSHORT) , 0 , NULL , true)
FIELD(fld_identity_type , nam_identity_type , dtype_short , sizeof(SSHORT) , 0 , NULL , true)
+
+ FIELD(fld_uid , nam_uid , dtype_long , sizeof(SLONG) , 0 , NULL , true)
+ FIELD(fld_gid , nam_gid , dtype_long , sizeof(SLONG) , 0 , NULL , true)
+ FIELD(fld_passwd_type , nam_passwd_type , dtype_text , 32 , dsc_text_type_ascii , NULL , true)
+ FIELD(fld_passwd , nam_passwd , dtype_blob , BLOB_SIZE , isc_blob_untyped , NULL , true)
+ FIELD(fld_name_part , nam_name_part , dtype_text , 32 , dsc_text_type_metadata , NULL , true)
Modified: firebird/trunk/src/jrd/idx.h
===================================================================
--- firebird/trunk/src/jrd/idx.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/idx.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -345,6 +345,10 @@
SEGMENT(f_prm_procedure, idx_metadata), // procedure name
SEGMENT(f_prm_name, idx_metadata), // parameter name
SEGMENT(f_prm_pkg_name, idx_metadata) // package name
+ }},
+ // define index RDB$INDEX_52 for RDB$USERS unique RDB$USER_NAME;
+ INDEX(52, ODS_12_0, rel_users, idx_unique, 1)
+ SEGMENT(f_user_name, idx_metadata) // procedure name
}}
// Last index in ODS 12.0 is RDB$INDEX_51
Modified: firebird/trunk/src/jrd/ini.epp
===================================================================
--- firebird/trunk/src/jrd/ini.epp 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/ini.epp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -71,7 +71,7 @@
static void add_index_set(thread_db*);
static void add_security_to_sys_rel(thread_db*, const Firebird::MetaName&,
- const TEXT*, const UCHAR*, const SSHORT);
+ const TEXT*, const UCHAR*, const SSHORT, const bool);
static void store_generator(thread_db*, const gen*, AutoRequest&);
static void store_global_field(thread_db*, const gfld*, AutoRequest&);
static void store_intlnames(thread_db*);
@@ -468,10 +468,39 @@
*acl++ = ACL_end;
length = acl - buffer;
- add_security_to_sys_rel(tdbb, ownerName, "RDB$ROLES", buffer, length);
- add_security_to_sys_rel(tdbb, ownerName, "RDB$PAGES", buffer, length);
+ add_security_to_sys_rel(tdbb, ownerName, "RDB$ROLES", buffer, length, true);
+ add_security_to_sys_rel(tdbb, ownerName, "RDB$PAGES", buffer, length, true);
// DFW writes here
- add_security_to_sys_rel(tdbb, ownerName, "RDB$FORMATS", buffer, length);
+ add_security_to_sys_rel(tdbb, ownerName, "RDB$FORMATS", buffer, length, true);
+
+ // nobody except DBA should access it
+ acl = buffer;
+ *acl++ = ACL_version;
+ *acl++ = ACL_id_list;
+ *acl++ = id_person;
+
+ length = ownerName.length();
+ if (length > MAX_UCHAR)
+ length = MAX_UCHAR;
+
+ *acl++ = (UCHAR)length;
+ if (length)
+ {
+ const TEXT* p_1 = ownerName.c_str();
+ memcpy(acl, p_1, length);
+ acl += length;
+ }
+ *acl++ = ACL_end;
+ *acl++ = ACL_priv_list;
+ *acl++ = priv_protect;
+ *acl++ = priv_control;
+ *acl++ = priv_delete;
+ *acl++ = priv_write;
+ *acl++ = priv_read;
+ *acl++ = ACL_end;
+ *acl++ = ACL_end;
+ length = acl - buffer;
+ add_security_to_sys_rel(tdbb, ownerName, "RDB$USERS", buffer, length, false);
}
@@ -863,7 +892,8 @@
const Firebird::MetaName& user_name,
const TEXT* rel_name,
const UCHAR* acl,
- const SSHORT acl_length)
+ const SSHORT acl_length,
+ const bool pub_select)
{
/**************************************
*
@@ -935,7 +965,7 @@
handle1.reset();
- for (int cnt = 0; cnt < 6; cnt++)
+ for (int cnt = 0; cnt < (pub_select ? 6 : 5); cnt++)
{
STORE(REQUEST_HANDLE handle1) PRIV IN RDB$USER_PRIVILEGES
switch (cnt)
Modified: firebird/trunk/src/jrd/met.epp
===================================================================
--- firebird/trunk/src/jrd/met.epp 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/met.epp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -3607,6 +3607,9 @@
case rel_view:
fb_assert(relation->rel_view_rse);
break;
+ case rel_vrt_users:
+ relation->rel_flags |= REL_users;
+ break;
case rel_virtual:
relation->rel_flags |= REL_virtual;
break;
Modified: firebird/trunk/src/jrd/names.h
===================================================================
--- firebird/trunk/src/jrd/names.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/names.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -257,6 +257,18 @@
NAME("RDB$ARGUMENT_NAME", nam_arg_name)
NAME("RDB$IDENTITY_TYPE", nam_identity_type)
+NAME("RDB$USERS", nam_users)
+NAME("RDB$USER_NAME", nam_user_name)
+NAME("RDB$GROUP_NAME", nam_group_name)
+NAME("RDB$UID", nam_uid)
+NAME("RDB$GID", nam_gid)
+NAME("RDB$PASSWD_TYPE", nam_passwd_type)
+NAME("RDB$PASSWD", nam_passwd)
+NAME("RDB$FIRST_NAME", nam_first_name)
+NAME("RDB$MIDDLE_NAME", nam_middle_name)
+NAME("RDB$LAST_NAME", nam_last_name)
+NAME("RDB$NAME_PART", nam_name_part)
+
NAME("MON$ATTACHMENTS", nam_mon_attachments)
NAME("MON$ATTACHMENT_ID", nam_mon_att_id)
NAME("MON$ATTACHMENT_NAME", nam_mon_att_name)
@@ -331,6 +343,7 @@
NAME("MON$TRANSACTIONS", nam_mon_transactions)
NAME("MON$TRANSACTION_ID", nam_mon_tra_id)
NAME("MON$USER", nam_mon_user)
+NAME("SEC$USERS", nam_sec_users)
NAME("MON$VARIABLE_NAME", nam_mon_var_name)
NAME("MON$VARIABLE_VALUE", nam_mon_var_value)
NAME("MON$PACKAGE_NAME", nam_mon_pkg_name)
Modified: firebird/trunk/src/jrd/opt.cpp
===================================================================
--- firebird/trunk/src/jrd/opt.cpp 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/opt.cpp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -3074,6 +3074,11 @@
// External table
rsb = FB_NEW(*tdbb->getDefaultPool()) ExternalTableScan(csb, alias, stream);
}
+ else if (relation->isUsers())
+ {
+ // Users table
+ rsb = FB_NEW(*tdbb->getDefaultPool()) UsersTableScan(csb, alias, stream);
+ }
else if (relation->isVirtual())
{
// Virtual table
Modified: firebird/trunk/src/jrd/recsrc/RecordSource.h
===================================================================
--- firebird/trunk/src/jrd/recsrc/RecordSource.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/recsrc/RecordSource.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -302,6 +302,29 @@
const Firebird::string m_name;
};
+ class UsersTableScan : public RecordStream
+ {
+ struct Impure : public RecordSource::Impure
+ {
+ RecordBuffer* irsb_record_buffer;
+ };
+
+ public:
+ UsersTableScan(CompilerScratch* csb, const Firebird::string& name, UCHAR stream);
+
+ void open(thread_db* tdbb) const;
+ void close(thread_db* tdbb) const;
+
+ bool getRecord(thread_db* tdbb) const;
+ bool refetchRecord(thread_db* tdbb) const;
+ bool lockRecord(thread_db* tdbb) const;
+
+ void dump(thread_db* tdbb, Firebird::UCharBuffer& buffer) const;
+
+ private:
+ const Firebird::string m_name;
+ };
+
class ProcedureScan : public RecordStream
{
struct Impure : public RecordSource::Impure
Added: firebird/trunk/src/jrd/recsrc/UsersTableScan.cpp
===================================================================
--- firebird/trunk/src/jrd/recsrc/UsersTableScan.cpp (rev 0)
+++ firebird/trunk/src/jrd/recsrc/UsersTableScan.cpp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -0,0 +1,142 @@
+/*
+ * The contents of this file are subject to the Initial
+ * Developer's Public License Version 1.0 (the "License");
+ * you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
+ *
+ * Software distributed under the License is distributed AS IS,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights
+ * and limitations under the License.
+ *
+ * The Original Code was created by Dmitry Yemanov
+ * for the Firebird Open Source RDBMS project.
+ *
+ * Copyright (c) 2009 Dmitry Yemanov <di...@fi...>
+ * and all contributors signed below.
+ *
+ * All Rights Reserved.
+ * Contributor(s): ______________________________________.
+ * Alex Peshkoff, 2010 - implemented users scan based on virtual tables
+ */
+
+#include "firebird.h"
+#include "../jrd/jrd.h"
+#include "../jrd/req.h"
+#include "../jrd/rse.h"
+#include "../jrd/cmp_proto.h"
+#include "../jrd/met_proto.h"
+#include "../jrd/vio_proto.h"
+#include "../jrd/UserManagement.h"
+#include "../jrd/tra.h"
+
+#include "RecordSource.h"
+
+using namespace Firebird;
+using namespace Jrd;
+
+
+// -------------------------------
+// Data access: users table scan
+// -------------------------------
+
+UsersTableScan::UsersTableScan(CompilerScratch* csb, const string& name, UCHAR stream)
+ : RecordStream(csb, stream), m_name(csb->csb_pool, name)
+{
+ m_impure = CMP_impure(csb, sizeof(Impure));
+}
+
+void UsersTableScan::open(thread_db* tdbb) const
+{
+ jrd_req* const request = tdbb->getRequest();
+ Impure* const impure = request->getImpure<Impure>(m_impure);
+
+ impure->irsb_flags = irsb_open;
+
+ record_param* const rpb = &request->req_rpb[m_stream];
+ rpb->getWindow(tdbb).win_flags = 0;
+
+ jrd_rel* const relation = rpb->rpb_relation;
+
+ const Record* const record = rpb->rpb_record;
+ const Format* format = NULL;
+ if (!record || !record->rec_format)
+ {
+ format = MET_current(tdbb, relation);
+ VIO_record(tdbb, rpb, format, request->req_pool);
+ }
+ else
+ {
+ format = record->rec_format;
+ }
+
+ rpb->rpb_number.setValue(BOF_NUMBER);
+
+ impure->irsb_record_buffer = tdbb->getTransaction()->getUserManagement()->getList(tdbb);
+}
+
+void UsersTableScan::close(thread_db* tdbb) const
+{
+ jrd_req* const request = tdbb->getRequest();
+
+ invalidateRecords(request);
+
+ Impure* const impure = request->getImpure<Impure>(m_impure);
+
+ if (impure->irsb_flags & irsb_open)
+ {
+ impure->irsb_flags &= ~irsb_open;
+ impure->irsb_record_buffer = NULL;
+ }
+}
+
+bool UsersTableScan::getRecord(thread_db* tdbb) const
+{
+ jrd_req* const request = tdbb->getRequest();
+ record_param* const rpb = &request->req_rpb[m_stream];
+ Impure* const impure = request->getImpure<Impure>(m_impure);
+
+ if (!(impure->irsb_flags & irsb_open))
+ {
+ rpb->rpb_number.setValid(false);
+ return false;
+ }
+
+ rpb->rpb_number.increment();
+
+ fb_assert(impure->irsb_record_buffer);
+
+ if (impure->irsb_record_buffer->fetch(rpb->rpb_number.getValue(), rpb->rpb_record))
+ {
+ rpb->rpb_number.setValid(true);
+ return true;
+ }
+
+ rpb->rpb_number.setValid(false);
+ return false;
+}
+
+bool UsersTableScan::refetchRecord(thread_db* tdbb) const
+{
+ return true;
+}
+
+bool UsersTableScan::lockRecord(thread_db* tdbb) const
+{
+ status_exception::raise(Arg::Gds(isc_record_lock_not_supp));
+ return false; // compiler silencer
+}
+
+void UsersTableScan::dump(thread_db* tdbb, UCharBuffer& buffer) const
+{
+ buffer.add(isc_info_rsb_begin);
+
+ buffer.add(isc_info_rsb_relation);
+ dumpName(tdbb, m_name, buffer);
+
+ buffer.add(isc_info_rsb_type);
+ buffer.add(isc_info_rsb_virt_sequential);
+
+ buffer.add(isc_info_rsb_end);
+}
Property changes on: firebird/trunk/src/jrd/recsrc/UsersTableScan.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Modified: firebird/trunk/src/jrd/relations.h
===================================================================
--- firebird/trunk/src/jrd/relations.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/relations.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -590,3 +590,28 @@
FIELD(f_pkg_sys_flag, nam_sys_flag, fld_flag, 1, ODS_12_0)
FIELD(f_pkg_desc, nam_description, fld_description, 1, ODS_12_0)
END_RELATION
+
+// Relation 43 (RDB$USERS)
+RELATION(nam_users, rel_users, ODS_12_0, rel_persistent)
+ FIELD(f_user_name, nam_user_name, fld_user, 1, ODS_12_0)
+ FIELD(f_group_name, nam_group_name, fld_user, 1, ODS_12_0)
+ FIELD(f_uid, nam_uid, fld_uid, 1, ODS_12_0)
+ FIELD(f_gid, nam_gid, fld_gid, 1, ODS_12_0)
+ FIELD(f_passwd_type, nam_passwd_type, fld_passwd_type, 1, ODS_12_0)
+ FIELD(f_passwd, nam_passwd, fld_passwd, 1, ODS_12_0)
+ FIELD(f_first_name, nam_first_name, fld_name_part, 1, ODS_12_0)
+ FIELD(f_middle_name, nam_middle_name, fld_name_part, 1, ODS_12_0)
+ FIELD(f_last_name, nam_last_name, fld_name_part, 1, ODS_12_0)
+ FIELD(f_user_desc, nam_description, fld_description, 1, ODS_12_0)
+END_RELATION
+
+// Relation 44 (SEC$USERS)
+RELATION(nam_sec_users, rel_sec_users, ODS_12_0, rel_vrt_users)
+ FIELD(f_sec_user_name, nam_user_name, fld_user, 1, ODS_12_0)
+ FIELD(f_sec_group_name, nam_group_name, fld_user, 1, ODS_12_0)
+ FIELD(f_sec_uid, nam_uid, fld_uid, 1, ODS_12_0)
+ FIELD(f_sec_gid, nam_gid, fld_gid, 1, ODS_12_0)
+ FIELD(f_sec_first_name, nam_first_name, fld_name_part, 1, ODS_12_0)
+ FIELD(f_sec_middle_name, nam_middle_name, fld_name_part, 1, ODS_12_0)
+ FIELD(f_sec_last_name, nam_last_name, fld_name_part, 1, ODS_12_0)
+END_RELATION
Modified: firebird/trunk/src/jrd/svc.cpp
===================================================================
--- firebird/trunk/src/jrd/svc.cpp 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/svc.cpp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -1924,27 +1924,31 @@
// Only need to add username and password information to those calls which need
// to make a database connection
- if (svc_id == isc_action_svc_backup ||
+
+ bool flNeedUser = (svc_id == isc_action_svc_backup ||
svc_id == isc_action_svc_restore ||
svc_id == isc_action_svc_nbak ||
svc_id == isc_action_svc_nrest ||
svc_id == isc_action_svc_repair ||
- svc_id == isc_action_svc_add_user ||
- svc_id == isc_action_svc_delete_user ||
- svc_id == isc_action_svc_modify_user ||
- svc_id == isc_action_svc_display_user ||
- svc_id == isc_action_svc_display_user_adm ||
svc_id == isc_action_svc_db_stats ||
svc_id == isc_action_svc_properties ||
svc_id == isc_action_svc_trace_start ||
svc_id == isc_action_svc_trace_stop ||
svc_id == isc_action_svc_trace_suspend ||
svc_id == isc_action_svc_trace_resume ||
- svc_id == isc_action_svc_trace_list ||
+ svc_id == isc_action_svc_trace_list);
+
+ bool flGsecUser = (svc_id == isc_action_svc_add_user ||
+ svc_id == isc_action_svc_delete_user ||
+ svc_id == isc_action_svc_modify_user ||
+ svc_id == isc_action_svc_display_user ||
+ svc_id == isc_action_svc_display_user_adm ||
svc_id == isc_action_svc_set_mapping ||
- svc_id == isc_action_svc_drop_mapping)
+ svc_id == isc_action_svc_drop_mapping);
+
+ if (flNeedUser || flGsecUser)
{
- // add the username and password to the end of svc_switches if needed
+ // add the username to the end of svc_switches if needed
if (svc_switches.hasData())
{
if (svc_username.hasData())
@@ -1952,9 +1956,15 @@
string auth = "-";
auth += TRUSTED_USER_SWITCH;
auth += ' ';
+ if (flGsecUser)
+ {
+ // gsec service - gsec will take care itself about security
+ auth += SYSDBA_USER_NAME;
+ auth += " -REAL_USER ";
+ }
auth += svc_username;
auth += ' ';
- if (svc_trusted_role)
+ if (svc_trusted_role && (!flGsecUser))
{
auth += "-";
auth += TRUSTED_ROLE_SWITCH;
@@ -1965,6 +1975,7 @@
}
}
+
// All services except for get_ib_log require switches
spb.rewind();
if ((!svc_switches.hasData()) && svc_id != isc_action_svc_get_fb_log)
Modified: firebird/trunk/src/jrd/types.h
===================================================================
--- firebird/trunk/src/jrd/types.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/jrd/types.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -112,6 +112,7 @@
TYPE ("VIRTUAL", rel_virtual, nam_r_type)
TYPE ("GLOBAL_TEMPORARY_PRESERVE", rel_global_temp_preserve, nam_r_type)
TYPE ("GLOBAL_TEMPORARY_DELETE", rel_global_temp_delete, nam_r_type)
+TYPE ("USERS LIST", rel_vrt_users, nam_r_type)
TYPE ("LEGACY", prc_legacy, nam_prc_type)
TYPE ("SELECTABLE", prc_selectable, nam_prc_type)
Modified: firebird/trunk/src/msgs/facilities2.sql
===================================================================
--- firebird/trunk/src/msgs/facilities2.sql 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/msgs/facilities2.sql 2010-07-09 12:51:05 UTC (rev 51322)
@@ -27,7 +27,7 @@
--('1996-11-07 13:38:43', 'GJRN', 16, 241)
--
('2009-12-21 04:00:05', 'ISQL', 17, 173)
-('2009-11-13 17:49:54', 'GSEC', 18, 104)
+('2009-11-13 17:49:54', 'GSEC', 18, 105)
--
--('2002-03-05 02:30:12', 'LICENSE', 19, 60)
--('2002-03-05 02:31:54', 'DOS', 20, 74)
Modified: firebird/trunk/src/msgs/messages2.sql
===================================================================
--- firebird/trunk/src/msgs/messages2.sql 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/msgs/messages2.sql 2010-07-09 12:51:05 UTC (rev 51322)
@@ -2905,6 +2905,7 @@
('GsecMsg101', 'gsec', 'gsec.cpp', NULL, 18, 101, NULL, 'use gsec -? to get help', NULL, NULL);
('GsecMsg102', 'gsec', 'gsec.cpp', NULL, 18, 102, NULL, '-admin {yes|no}', NULL, NULL);
('GsecMsg103', 'gsec', 'gsec.cpp', NULL, 18, 103, NULL, 'invalid parameter for -ADMIN, only YES or NO is accepted', NULL, NULL);
+('GsecMsg104', 'SECURITY_exec_line', 'security.epp', NULL, 18, 104, NULL, 'not enough privileges to complete operation', NULL, NULL);
-- GSTAT
('gstat_unknown_switch', 'main', 'dba.e', NULL, 21, 1, NULL, 'found unknown switch', NULL, NULL);
('gstat_retry', 'main', 'dba.e', NULL, 21, 2, NULL, 'please retry, giving a database name', NULL, NULL);
Modified: firebird/trunk/src/utilities/gsec/gsec.cpp
===================================================================
--- firebird/trunk/src/utilities/gsec/gsec.cpp 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/utilities/gsec/gsec.cpp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -278,7 +278,8 @@
uSvc->started();
if (! useServices)
{
- ret = SECURITY_exec_line(status, db_handle, user_data, data_print, NULL);
+ ret = SECURITY_exec_line(status, tdsec->tsec_real_user,
+ db_handle, user_data, data_print, NULL);
if (ret)
{
GSEC_print(ret, user_data->user_name);
@@ -596,8 +597,7 @@
user_data->gid_entered = true;
break;
case IN_SW_GSEC_SYSUSER:
- fb_utils::copy_terminate(user_data->sys_user_name, string, sizeof(user_data->sys_user_name));
- user_data->sys_user_entered = true;
+ // ignore it
break;
case IN_SW_GSEC_GROUP:
fb_utils::copy_terminate(user_data->group_name, string, sizeof(user_data->group_name));
@@ -653,6 +653,10 @@
fb_utils::copy_terminate(user_data->dba_trust_user_name, string, sizeof(user_data->dba_trust_user_name));
user_data->dba_trust_user_name_entered = true;
break;
+ case IN_SW_GSEC_REAL_USER:
+ tdsec->utilSvc->checkService();
+ tdsec->tsec_real_user = string;
+ break;
case IN_SW_GSEC_MAPPING:
{
Firebird::string val(string);
@@ -808,13 +812,7 @@
user_data->gid = 0;
break;
case IN_SW_GSEC_SYSUSER:
- if (user_data->sys_user_specified)
- {
- err_msg_no = GsecMsg34;
- break;
- }
- user_data->sys_user_specified = true;
- user_data->sys_user_name[0] = '\0';
+ // ignore it
break;
case IN_SW_GSEC_GROUP:
if (user_data->group_name_specified)
@@ -932,6 +930,8 @@
GSEC_diag(GsecMsg41);
// gsec - ambiguous switch specified
return false;
+ case IN_SW_GSEC_REAL_USER:
+ break;
}
last_sw = in_sw;
}
@@ -940,7 +940,7 @@
// is valid, and if not, indicate why not
if (user_data->uid_entered || user_data->gid_entered ||
- user_data->sys_user_entered || user_data->group_name_entered ||
+ user_data->group_name_entered ||
user_data->password_entered || user_data->first_name_entered ||
user_data->middle_name_entered || user_data->last_name_entered)
{
Modified: firebird/trunk/src/utilities/gsec/gsec.h
===================================================================
--- firebird/trunk/src/utilities/gsec/gsec.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/utilities/gsec/gsec.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -65,9 +65,6 @@
int gid; // the user's group id
bool gid_entered; // GID entered flag
bool gid_specified; // GID specified flag
- TEXT sys_user_name [ALT_NAME_LEN]; // the sys_user's name
- bool sys_user_entered; // sys_user entered flag
- bool sys_user_specified; // sys_user specified flag
TEXT group_name [ALT_NAME_LEN]; // the group name
bool group_name_entered; // group_name entered flag
bool group_name_specified; // group_name specified flag
@@ -123,13 +120,15 @@
public:
explicit tsec(Firebird::UtilSvc* uf)
: ThreadData(ThreadData::tddSEC), utilSvc(uf),
- tsec_user_data(0), tsec_exit_code(0), tsec_throw(false),
+ tsec_user_data(0), tsec_real_user(NULL),
+ tsec_exit_code(0), tsec_throw(false),
tsec_interactive(false), tsec_sw_version(false)
{
}
Firebird::UtilSvc* utilSvc;
internal_user_data* tsec_user_data;
+ const char* tsec_real_user;
int tsec_exit_code;
bool tsec_throw;
bool tsec_interactive;
@@ -255,6 +254,7 @@
const USHORT GsecMsg101 = 101; // use gsec -? to get help
const USHORT GsecMsg102 = 102; // -adm(in) {yes|no}
const USHORT GsecMsg103 = 103; // invalid parameter for -ADMIN, only YES or NO is accepted
+const USHORT GsecMsg104 = 104; // not enough privileges to complete operation
#endif // UTILITIES_GSEC_H
Modified: firebird/trunk/src/utilities/gsec/gsecswi.h
===================================================================
--- firebird/trunk/src/utilities/gsec/gsecswi.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/utilities/gsec/gsecswi.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -34,7 +34,7 @@
const int IN_SW_GSEC_0 = 0; // not a known switch
const int IN_SW_GSEC_UID = 1; // uid is specified
const int IN_SW_GSEC_GID = 2; // gid is specified
-const int IN_SW_GSEC_SYSUSER = 3; // sys_user_name is specified
+const int IN_SW_GSEC_SYSUSER = 3; // sys_user name is specified
const int IN_SW_GSEC_GROUP = 4; // group is specified
const int IN_SW_GSEC_PASSWORD = 5; // password is specified
const int IN_SW_GSEC_FNAME = 6; // first name is specified
@@ -62,6 +62,7 @@
const int IN_SW_GSEC_MAPPING = 26; // Change auto admin mapping
const int IN_SW_GSEC_ADMIN = 27; // Grant/revoke RDB$ADMIN in security database
const int IN_SW_GSEC_DIS_ADM = 28; // display user(s) with admin info
+const int IN_SW_GSEC_REAL_USER = 29; // svc user, if not SYSDBA
static const struct Switches::in_sw_tab_t gsec_in_sw_table [] =
{
@@ -85,6 +86,7 @@
{IN_SW_GSEC_DBA_USER_NAME, 0, "USER", 0, 0, 0, false, 0, 1, NULL}, // Database Admin. User name
{IN_SW_GSEC_DBA_PASSWORD, 0, "PASSWORD", 0, 0, 0, false, 0, 2, NULL}, // Database Admin. Password
{IN_SW_GSEC_FETCH_PASSWORD, 0, "FETCH_PASSWORD", 0, 0, 0, false, 0, 2, NULL}, // Fetch Database Admin. Password
+ {IN_SW_GSEC_REAL_USER, 0, "REAL_USER", 0, 0, 0, false, 0, 9, NULL}, // name of real user, connected to services
{IN_SW_GSEC_SQL_ROLE_NAME, isc_spb_sql_role_name, "ROLE", 0, 0, 0, false, 0, 2, NULL}, // SQL Role to assume
{IN_SW_GSEC_DBA_TRUSTED_USER, 0, TRUSTED_USER_SWITCH, 0, 0, 0, false, 0,
TRUSTED_USER_SWITCH_LEN, NULL}, // Database Admin. Trusted User name
Modified: firebird/trunk/src/utilities/gsec/secur_proto.h
===================================================================
--- firebird/trunk/src/utilities/gsec/secur_proto.h 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/utilities/gsec/secur_proto.h 2010-07-09 12:51:05 UTC (rev 51322)
@@ -25,10 +25,10 @@
#define UTILITIES_SECUR_PROTO_H
typedef void (*FPTR_SECURITY_CALLBACK)(void*, const internal_user_data*, bool);
-SSHORT SECURITY_exec_line (ISC_STATUS* isc_status, FB_API_HANDLE DB, FB_API_HANDLE trans,
+SSHORT SECURITY_exec_line (ISC_STATUS* isc_status, const char* realUser, FB_API_HANDLE DB, FB_API_HANDLE trans,
internal_user_data* io_user_data, FPTR_SECURITY_CALLBACK display_func,
void* callback_arg);
-SSHORT SECURITY_exec_line (ISC_STATUS* isc_status, FB_API_HANDLE DB,
+SSHORT SECURITY_exec_line (ISC_STATUS* isc_status, const char* realUser, FB_API_HANDLE DB,
internal_user_data* io_user_data, FPTR_SECURITY_CALLBACK display_func,
void* callback_arg);
Modified: firebird/trunk/src/utilities/gsec/security.epp
===================================================================
--- firebird/trunk/src/utilities/gsec/security.epp 2010-07-09 11:33:28 UTC (rev 51321)
+++ firebird/trunk/src/utilities/gsec/security.epp 2010-07-09 12:51:05 UTC (rev 51322)
@@ -37,6 +37,7 @@
#include "../utilities/gsec/secur_proto.h"
#include "../common/utils_proto.h"
#include "../common/classes/init.h"
+#include "../common/classes/UserBlob.h"
DATABASE DB = STATIC FILENAME "security2.fdb";
@@ -84,7 +85,27 @@
}
+static bool storePasswd(ISC_STATUS* isc_status, FB_API_HANDLE DB, FB_API_HANDLE trans,
+ ISC_QUAD& blobId, const Firebird::string& passwd)
+{
+ UserBlob blob(isc_status);
+ const UCHAR blob_desc[] = {isc_bpb_version1, isc_bpb_type, 1, isc_blob_untyped};
+
+ if (!blob.create(DB, trans, blobId, sizeof(blob_desc), blob_desc))
+ {
+ return false;
+ }
+
+ if (!blob.putData(passwd.length(), passwd.c_str()))
+ {
+ return false;
+ }
+
+ return blob.close();
+}
+
SSHORT SECURITY_exec_line(ISC_STATUS* isc_status,
+ const char *realUser,
FB_API_HANDLE DB,
FB_API_HANDLE trans,
internal_user_data* io_user_data,
@@ -173,7 +194,12 @@
{
case MAP_DROP_OPER:
case MAP_SET_OPER:
+ if (realUser)
{
+ ret = GsecMsg104;
+ break;
+ }
+ {
Firebird::string sql;
sql.printf("ALTER ROLE RDB$ADMIN %s AUTO ADMIN MAPPING",
io_user_data->operation == MAP_SET_OPER ? "SET" : "DROP");
@@ -185,62 +211,71 @@
}
break;
case ADD_OPER:
+ if (realUser)
+ {
+ ret = GsecMsg104;
+ break;
+ }
// this checks the "entered" flags for each parameter (except the name)
// and makes all non-entered parameters null valued
- STORE (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN USERS USING
- strcpy(U.USER_NAME, io_user_data->user_name);
+ STORE (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS USING
+ strcpy(U.RDB$USER_NAME, io_user_data->user_name);
if (io_user_data->uid_entered)
{
- U.UID = io_user_data->uid;
- U.UID.NULL = ISC_FALSE;
+ U.RDB$UID = io_user_data->uid;
+ U.RDB$UID.NULL = ISC_FALSE;
}
else
- U.UID.NULL = ISC_TRUE;
+ U.RDB$UID.NULL = ISC_TRUE;
if (io_user_data->gid_entered)
{
- U.GID = io_user_data->gid;
- U.GID.NULL = ISC_FALSE;
+ U.RDB$GID = io_user_data->gid;
+ U.RDB$GID.NULL = ISC_FALSE;
}
else
- U.GID.NULL = ISC_TRUE;
+ U.RDB$GID.NULL = ISC_TRUE;
if (io_user_data->group_name_entered)
{
- strcpy(U.GROUP_NAME, io_user_data->group_name);
- U.GROUP_NAME.NULL = ISC_FALSE;
+ strcpy(U.RDB$GROUP_NAME, io_user_data->group_name);
+ U.RDB$GROUP_NAME.NULL = ISC_FALSE;
}
else
- U.GROUP_NAME.NULL = ISC_TRUE;
+ U.RDB$GROUP_NAME.NULL = ISC_TRUE;
if (io_user_data->password_entered)
{
ENC_crypt(encrypted1, sizeof encrypted1, io_user_data->password, Auth::PASSWORD_SALT);
Auth::SecurityDatabase::hash(encrypted2, io_user_data->user_name, &encrypted1[2]);
- strcpy(U.PASSWD, encrypted2.c_str());
- U.PASSWD.NULL = ISC_FALSE;
+ if (!storePasswd(isc_status, DB, trans, U.RDB$PASSWD, encrypted2))
+ {
+ ret = GsecMsg19;
+ break;
+ }
+ U.RDB$PASSWD.NULL = ISC_FALSE;
}
else
- U.PASSWD.NULL = ISC_TRUE;
+ U.RDB$PASSWD.NULL = ISC_TRUE;
if (io_user_data->first_name_entered)
{
- strcpy(U.FIRST_NAME, io_user_data->first_name);
- U.FIRST_NAME.NULL = ISC_FALSE;
+ strcpy(U.RDB$FIRST_NAME, io_user_data->first_name);
+ U.RDB$FIRST_NAME.NULL = ISC_FALSE;
}
else
- U.FIRST_NAME.NULL = ISC_TRUE;
+ U.RDB$FIRST_NAME.NULL = ISC_TRUE;
if (io_user_data->middle_name_entered)
{
- strcpy(U.MIDDLE_NAME, io_user_data->middle_name);
- U.MIDDLE_NAME.NULL = ISC_FALSE;
+ strcpy(U.RDB$MIDDLE_NAME, io_user_data->middle_name);
+ U.RDB$MIDDLE_NAME.NULL = ISC_FALSE;
}
else
- U.MIDDLE_NAME.NULL = ISC_TRUE;
+ U.RDB$MIDDLE_NAME.NULL = ISC_TRUE;
if (io_user_data->last_name_entered)
{
- strcpy(U.LAST_NAME, io_user_data->last_name);
- U.LAST_NAME.NULL = ISC_FALSE;
+ strcpy(U.RDB$LAST_NAME, io_user_data->last_name);
+ U.RDB$LAST_NAME.NULL = ISC_FALSE;
}
else
- U.LAST_NAME.NULL = ISC_TRUE;
+ U.RDB$LAST_NAME.NULL = ISC_TRUE;
END_STORE
ON_ERROR
ret = GsecMsg19; // gsec - add record error
@@ -252,66 +287,76 @@
break;
case MOD_OPER:
+ if (realUser && strcmp(realUser, io_user_data->user_name))
+ {
+ ret = GsecMsg104;
+ break;
+ }
+
// this updates an existing record, replacing all fields that are
// entered, and for those that were specified but not entered, it
// changes the current value to the null value
found = false;
- FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN USERS
- WITH U.USER_NAME EQ io_user_data->user_name
+ FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS
+ WITH U.RDB$USER_NAME EQ io_user_data->user_name
found = true;
MODIFY U USING
if (io_user_data->uid_entered)
{
- U.UID = io_user_data->uid;
- U.UID.NULL = ISC_FALSE;
+ U.RDB$UID = io_user_data->uid;
+ U.RDB$UID.NULL = ISC_FALSE;
}
else if (io_user_data->uid_specified)
- U.UID.NULL = ISC_TRUE;
+ U.RDB$UID.NULL = ISC_TRUE;
if (io_user_data->gid_entered)
{
- U.GID = io_user_data->gid;
- U.GID.NULL = ISC_FALSE;
+ U.RDB$GID = io_user_data->gid;
+ U.RDB$GID.NULL = ISC_FALSE;
}
else if (io_user_data->gid_specified)
- U.GID.NULL = ISC_TRUE;
+ U.RDB$GID.NULL = ISC_TRUE;
if (io_user_data->group_name_entered)
{
- strcpy(U.GROUP_NAME, io_user_data->group_name);
- U.GROUP_NAME.NULL = ISC_FALSE;
+ strcpy(U.RDB$GROUP_NAME, io_user_data->group_name);
+ U.RDB$GROUP_NAME.NULL = ISC_FALSE;
}
else if (io_user_data->group_name_specified)
- U.GROUP_NAME.NULL = ISC_TRUE;
+ U.RDB$GROUP_NAME.NULL = ISC_TRUE;
if (io_user_data->password_entered)
{
ENC_crypt(encrypted1, sizeof encrypted1, io_user_data->password, Auth::PASSWORD_SALT);
Auth::SecurityDatabase::hash(encrypted2, io_user_data->user_name, &encrypted1[2]);
- strcpy(U.PASSWD, encrypted2.c_str());
- U.PASSWD.NULL = ISC_FALSE;
+ if (!storePasswd(isc_status, DB, trans, U.RDB$PASSWD, encrypted2))
+ {
+ ret = GsecMsg21;
+ break;
+ }
+ U.RDB$PASSWD.NULL = ISC_FALSE;
}
else if (io_user_data->password_specified)
- U.PASSWD.NULL = ISC_TRUE;
+ U.RDB$PASSWD.NULL = ISC_TRUE;
if (io_user_data->first_name_entered)
{
- strcpy(U.FIRST_NAME, io_user_data->first_name);
- U.FIRST_NAME.NULL = ISC_FALSE;
+ strcpy(U.RDB$FIRST_NAME, io_user_data->first_name);
+ U.RDB$FIRST_NAME.NULL = ISC_FALSE;
}
else if (io_user_data->first_name_specified)
- U.FIRST_NAME.NULL = ISC_TRUE;
+ U.RDB$FIRST_NAME.NULL = ISC_TRUE;
if (io_user_data->middle_name_entered)
{
- strcpy(U.MIDDLE_NAME, io_user_data->middle_name);
- U.MIDDLE_NAME.NULL = ISC_FALSE;
+ strcpy(U.RDB$MIDDLE_NAME, io_user_data->middle_name);
+ U.RDB$MIDDLE_NAME.NULL = ISC_FALSE;
}
else if (io_user_data->middle_name_specified)
- U.MIDDLE_NAME.NULL = ISC_TRUE;
+ U.RDB$MIDDLE_NAME.NULL = ISC_TRUE;
if (io_user_data->last_name_entered)
{
- strcpy(U.LAST_NAME, io_user_data->last_name);
- U.LAST_NAME.NULL = ISC_FALSE;
+ strcpy(U.RDB$LAST_NAME, io_user_data->last_name);
+ U.RDB$LAST_NAME.NULL = ISC_FALSE;
}
else if (io_user_data->last_name_specified)
- U.LAST_NAME.NULL = ISC_TRUE;
+ U.RDB$LAST_NAME.NULL = ISC_TRUE;
END_MODIFY
ON_ERROR
ret = GsecMsg20;
@@ -329,6 +374,12 @@
break;
case DEL_OPER:
+ if (realUser)
+ {
+ ret = GsecMsg104;
+ break;
+ }
+
// looks up the specified user record and deletes it
found = false;
@@ -337,8 +388,8 @@
ret = GsecMsg23;
else
{
- FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN USERS
- WITH U.USER_NAME EQ io_user_data->user_name
+ FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS
+ WITH U.RDB$USER_NAME EQ io_user_data->user_name
found = true;
ERASE U
ON_ERROR
@@ -363,25 +414,51 @@
case DIS_OPER:
case OLD_DIS_OPER:
+ if (realUser)
+ {
+ if (io_user_data->user_name_entered && strcmp(realUser, io_user_data->user_name))
+ {
+ ret = GsecMsg104;
+ break;
+ }
+ if (!io_user_data->user_name_entered)
+ {
+ if (strlen(realUser) > sizeof(io_user_data->user_name) - 1)
+ {
+ ret = GsecMsg104;
+ break;
+ }
+ strcpy(io_user_data->user_name, realUser);
+ io_user_data->user_name_entered = true;
+ }
+ }
+
// gets either the desired record, or all records, and displays them
found = false;
if (!io_user_data->user_name_entered)
{
- FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN USERS
- io_user_data->uid = U.UID;
- io_user_data->gid = U.GID;
- *(io_user_data->sys_user_name) = '\0';
- strcpy(io_user_data->user_name, U.USER_NAME);
- strcpy(io_user_data->group_name, U.GROUP_NAME);
+ FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS
+ io_user_data->uid = U.RDB$UID;
+ io_user_data->uid_entered = !U.RDB$UID.NULL;
+ io_user_data->gid = U.RDB$GID;
+ io_user_data->gid_entered = !U.RDB$GID.NULL;
+ strcpy(io_user_data->user_name, U.RDB$USER_NAME);
+ io_user_data->user_name_entered = !U.RDB$USER_NAME.NULL;
+ strcpy(io_user_data->group_name, U.RDB$GROUP_NAME);
+ io_user_data->group_name_entered = !U.RDB$GROUP_NAME.NULL;
io_user_data->password[0] = 0;
- strcpy(io_user_data->first_name, U.FIRST_NAME);
- strcpy(io_user_data->middle_name, U.MIDDLE_NAME);
- strcpy(io_user_data->last_name, U.LAST_NAME);
+ io_user_data->password_entered = false;
+ strcpy(io_user_data->first_name, U.RDB$FIRST_NAME);
+ io_user_data->first_name_entered = !U.RDB$FIRST_NAME.NULL;
+ strcpy(io_user_data->middle_name, U.RDB$MIDDLE_NAME);
+ io_user_data->middle_name_entered = !U.RDB$MIDDLE_NAME.NULL;
+ strcpy(io_user_data->last_name, U.RDB$LAST_NAME);
+ io_user_data->last_name_entered = !U.RDB$LAST_NAME.NULL;
io_user_data->admin = 0;
FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request2) P IN RDB$USER_PRIVILEGES
- WITH P.RDB$USER EQ U.USER_NAME
+ WITH P.RDB$USER EQ U.RDB$USER_NAME
AND P.RDB$RELATION_NAME EQ 'RDB$ADMIN'
AND P.RDB$PRIVILEGE EQ 'M'
io_user_data->admin = 1;
@@ -397,21 +474,28 @@
}
else
{
- FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN USERS
- WITH U.USER_NAME EQ io_user_data->user_name
- io_user_data->uid = U.UID;
- io_user_data->gid = U.GID;
- *(io_user_data->sys_user_name) = '\0';
- strcpy(io_user_data->user_name, U.USER_NAME);
- strcpy(io_user_data->group_name, U.GROUP_NAME);
+ FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request) U IN RDB$USERS
+ WITH U.RDB$USER_NAME EQ io_user_data->user_name
+ io_user_data->uid = U.RDB$UID;
+ io_user_data->uid_entered = !U.RDB$UID.NULL;
+ io_user_data->gid = U.RDB$GID;
+ io_user_data->gid_entered = !U.RDB$GID.NULL;
+ strcpy(io_user_data->user_name, U.RDB$USER_NAME);
+ io_user_data->user_name_entered = !U.RDB$USER_NAME.NULL;
+ strcpy(io_user_data->group_name, U.RDB$GROUP_NAME);
+ io_user_data->group_name_entered = !U.RDB$GROUP_NAME.NULL;
io_user_data->password[0] = 0;
- strcpy(io_user_data->first_name, U.FIRST_NAME);
- strcpy(io_user_data->middle_name, U.MIDDLE_NAME);
- strcpy(io_user_data->last_name, U.LAST_NAME);
+ io_user_data->password_entered = false;
+ strcpy(io_user_data->first_name, U.RDB$FIRST_NAME);
+ io_user_data->first_name_entered = !U.RDB$FIRST_NAME.NULL;
+ strcpy(io_user_data->middle_name, U.RDB$MIDDLE_NAME);
+ io_user_data->middle_name_entered = !U.RDB$MIDDLE_NAME.NULL;
+ strcpy(io_user_data->last_name, U.RDB$LAST_NAME);
+ io_user_data->last_name_entered = !U.RDB$LAST_NAME.NULL;
io_user_data->admin = 0;
FOR (TRANSACTION_HANDLE trans REQUEST_HANDLE request2) P IN RDB$USER_PRIVILEGES
- WITH P.RDB$USER EQ U.USER_NAME
+ WITH P.RDB$USER EQ U.RDB$USER_NAME
AND P.RDB$RELATION_NAME EQ 'RDB$ADMIN'
AND P.RDB$PRIVILEGE EQ 'M'
io_user_data->admin = 1;
@@ -460,6 +544,7 @@
}
SSHORT SECURITY_exec_line(ISC_STATUS* isc_status,
+ const char *realUser,
FB_API_HANDLE DB,
internal_user_data* io_user_data,
FPTR_SECURITY_CALLBACK display_func,
@@ -472,7 +557,7 @@
return GsecMsg75; // gsec error
END_ERROR;
- SSHORT ret = SECURITY_exec_line(isc_status, DB, gds_trans, io_user_data, display_func, callback_arg);
+ SSHORT ret = SECURITY_exec_line(isc_status, realUser, DB, gds_trans, io_user_data, display_func, callback_arg);
// rollback if we have an error using tmp_status to avoid
// overwriting the error status which the caller wants to see
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|