Skip to content

Commit

Permalink
Frontported improvement CORE-2748: allow gsec to grant RDB$ADMIN role…
Browse files Browse the repository at this point in the history
… in the security database
  • Loading branch information
AlexPeshkoff committed Nov 13, 2009
1 parent 82a0d5c commit 4f54fd6
Show file tree
Hide file tree
Showing 15 changed files with 203 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/common/classes/ClumpletReader.cpp
Expand Up @@ -281,6 +281,7 @@ ClumpletReader::ClumpletType ClumpletReader::getClumpletType(UCHAR tag) const
return StringSpb;
case isc_spb_sec_userid:
case isc_spb_sec_groupid:
case isc_spb_sec_admin:
return IntSpb;
}
invalid_structure("unknown parameter for security database operation");
Expand Down
3 changes: 3 additions & 0 deletions src/dsql/ddl.cpp
Expand Up @@ -4859,6 +4859,9 @@ static void define_user(CompiledStatement* statement, UCHAR op)
case e_user_last:
statement->append_cstring(isc_dyn_user_last, ds->str_data);
break;
case e_user_admin:
statement->append_cstring(isc_dyn_user_admin, ds->str_data);
break;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/dsql/node.h
Expand Up @@ -923,6 +923,7 @@ enum node_args {
e_user_first,
e_user_middle,
e_user_last,
e_user_admin,
e_user_count,

e_hidden_var_expr = 0, // nod_hidden_var
Expand Down
37 changes: 31 additions & 6 deletions src/dsql/parse.y
Expand Up @@ -643,6 +643,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
%type <legacyNode> alter_udf_clause alter_user_clause alter_view_clause
%type <legacyNode> arg_desc arg_desc_list arg_desc_list1 array_element array_range
%type <legacyNode> array_spec array_type as_opt assignment assignments
%type <legacyStr> admin_opt

%type <legacyNode> begin_string begin_trigger between_predicate bit_length_expression
%type <legacyNode> blob_filter_subtype blob_io blob_segsize blob_subtype blob_subtype_io
Expand Down Expand Up @@ -696,6 +697,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
%type <legacyNode> generator_clause grant grant_option granted_by granted_by_text grantee grantee_list
%type <legacyNode> grantor group_by_item group_by_list group_clause gtt_recreate_clause gtt_scope
%type <legacyNode> gtt_table_clause
%type <legacyStr> grant_admin grant_admin_opt

%type <legacyNode> having_clause

Expand Down Expand Up @@ -746,6 +748,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
%type <legacyNode> rexception_clause role_admin_option role_clause role_grantee role_grantee_list
%type <legacyNode> role_name role_name_list rollback rows_clause rtable_clause
%type <legacyNode> rview_clause
%type <legacyStr> revoke_admin

%type <legacyNode> savepoint scroll_opt search_condition searched_case searched_when_clause sec_precision_opt
%type <legacyNode> sec_shadow_files segment_clause_io segment_length_io select select_expr
Expand Down Expand Up @@ -4828,14 +4831,14 @@ table_subquery : '(' column_select ')'

/* USER control SQL interface */

create_user_clause : symbol_user_name passwd_clause firstname_opt middlename_opt lastname_opt
{ $$ = make_node(nod_add_user, (int) e_user_count, $1, $2, $3, $4, $5); }
create_user_clause : symbol_user_name passwd_clause firstname_opt middlename_opt lastname_opt grant_admin_opt
{ $$ = make_node(nod_add_user, (int) e_user_count, $1, $2, $3, $4, $5, $6); }
;

alter_user_clause : symbol_user_name passwd_opt firstname_opt middlename_opt lastname_opt
{ $$ = make_node(nod_mod_user, (int) e_user_count, $1, $2, $3, $4, $5); }
| symbol_user_name SET passwd_opt firstname_opt middlename_opt lastname_opt
{ $$ = make_node(nod_mod_user, (int) e_user_count, $1, $3, $4, $5, $6); }
alter_user_clause : symbol_user_name passwd_opt firstname_opt middlename_opt lastname_opt admin_opt
{ $$ = make_node(nod_mod_user, (int) e_user_count, $1, $2, $3, $4, $5, $6); }
| symbol_user_name SET passwd_opt firstname_opt middlename_opt lastname_opt admin_opt
{ $$ = make_node(nod_mod_user, (int) e_user_count, $1, $3, $4, $5, $6, $7); }
;

drop_user_clause : symbol_user_name
Expand Down Expand Up @@ -4869,6 +4872,28 @@ lastname_opt : LASTNAME sql_string
{ $$ = NULL; }
;

admin_opt : revoke_admin
{ $$ = $1; }
| grant_admin
{ $$ = $1; }
|
{ $$ = NULL; }
;

grant_admin_opt : grant_admin
{ $$ = $1; }
|
{ $$ = NULL; }
;

revoke_admin: REVOKE ADMIN ROLE
{ $$ = MAKE_cstring("0"); }
;

grant_admin: GRANT ADMIN ROLE
{ $$ = MAKE_cstring("1"); }
;

/* value types */

value : column_name
Expand Down
2 changes: 2 additions & 0 deletions src/include/consts_pub.h
Expand Up @@ -331,6 +331,7 @@
#define isc_spb_sec_firstname 10
#define isc_spb_sec_middlename 11
#define isc_spb_sec_lastname 12
#define isc_spb_sec_admin 13

/*******************************************************
* Parameters for isc_action_svc_(add|remove)_license, *
Expand Down Expand Up @@ -894,6 +895,7 @@
#define isc_dyn_user_first 5
#define isc_dyn_user_middle 6
#define isc_dyn_user_last 7
#define isc_dyn_user_admin 8
#define isc_user_end 0

/****************************/
Expand Down
5 changes: 5 additions & 0 deletions src/jrd/dyn.epp
Expand Up @@ -2373,6 +2373,11 @@ static void dyn_user(Global* gbl, const UCHAR** ptr)
userData->last_name_specified = true;
}
break;

case isc_dyn_user_admin:
userData->admin = text[0] - '0';
userData->admin_entered = true;
break;
}
}

Expand Down
12 changes: 11 additions & 1 deletion src/jrd/svc.cpp
Expand Up @@ -2433,7 +2433,9 @@ bool Service::process_switches(ClumpletReader& spb, string& switches)
break;
}

if (spb.getClumpTag() != isc_spb_sec_username && spb.getClumpTag() != isc_spb_dbname)
if (spb.getClumpTag() != isc_spb_sec_username &&
spb.getClumpTag() != isc_spb_dbname &&
spb.getClumpTag() != isc_spb_sql_role_name)
{
// unexpected item in service parameter block, expected @1
status_exception::raise(Arg::Gds(isc_unexp_spb_form) << Arg::Str(SPB_SEC_USERNAME));
Expand Down Expand Up @@ -2487,6 +2489,14 @@ bool Service::process_switches(ClumpletReader& spb, string& switches)
get_action_svc_data(spb, switches);
break;

case isc_spb_sec_admin:
if (!get_action_svc_parameter(spb.getClumpTag(), gsec_in_sw_table, switches))
{
return false;
}
switches += (spb.getInt() ? "Yes " : "No ");
break;

case isc_spb_sql_role_name:
case isc_spb_sec_password:
case isc_spb_sec_groupname:
Expand Down
2 changes: 1 addition & 1 deletion src/msgs/facilities2.sql
Expand Up @@ -25,7 +25,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM
--('1996-11-07 13:38:43', 'GJRN', 16, 241)
--
('2009-11-13 08:37:53', 'ISQL', 17, 173)
('2009-06-25 05:05:43', 'GSEC', 18, 102)
('2009-11-13 17:49:54', 'GSEC', 18, 104)
('2002-03-05 02:30:12', 'LICENSE', 19, 60)
('2002-03-05 02:31:54', 'DOS', 20, 74)
('2009-06-22 05:57:59', 'GSTAT', 21, 46)
Expand Down
6 changes: 4 additions & 2 deletions src/msgs/messages2.sql
Expand Up @@ -3140,8 +3140,8 @@ Fetches = !f', NULL, NULL);
('gsec_err_delete', 'exec_line', 'gsec.e', NULL, 18, 23, NULL, 'delete record error', NULL, NULL);
('gsec_err_find_del', 'exec_line', 'gsec.e', NULL, 18, 24, NULL, 'find/delete record error', NULL, NULL);
('GsecMsg25', 'exec_line', 'gsec.e', NULL, 18, 25, NULL, 'users defined for node', NULL, NULL);
('GsecMsg26', 'exec.line', 'gsec', NULL, 18, 26, NULL, ' user name uid gid full name', NULL, NULL);
('GsecMsg27', 'exec_line', 'gsec.e', NULL, 18, 27, NULL, '------------------------------------------------------------------------------------------', NULL, NULL);
('GsecMsg26', 'exec.line', 'gsec', NULL, 18, 26, NULL, ' user name uid gid admin full name', NULL, NULL);
('GsecMsg27', 'exec_line', 'gsec.e', NULL, 18, 27, NULL, '------------------------------------------------------------------------------------------------', NULL, NULL);
('gsec_err_find_disp', 'exec_line', 'gsec.e', NULL, 18, 28, NULL, 'find/display record error', NULL, NULL);
('gsec_inv_param', 'get_switches', 'gsec.e', NULL, 18, 29, NULL, 'invalid parameter, no switch defined', NULL, NULL);
('gsec_op_specified', 'get_switches', 'gsec.e', NULL, 18, 30, NULL, 'operation already specified', NULL, NULL);
Expand Down Expand Up @@ -3218,6 +3218,8 @@ Fetches = !f', NULL, NULL);
('GsecMsg99', 'get_switches', 'gsec.cpp', NULL, 18, 99, NULL, 'invalid parameter for -MAPPING, only SET or DROP is accepted', NULL, NULL);
('GsecMsg100', 'printhelp', 'gsec.cpp', NULL, 18, 100, NULL, 'mapping {set|drop}', NULL, NULL);
('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);
-- LICENSE
('license_no_file', 'NODE_license', 'jrd/node.c', NULL, 19, 0, NULL, 'The license file does not exist or could not be opened for read', NULL, NULL);
('stop_stop_1', 'not_licensed', 'jrd/node.c', 'This message has 20 leading space characters (2 tab chars and 4 '' '') in
Expand Down
14 changes: 10 additions & 4 deletions src/utilities/fbsvcmgr.cpp
Expand Up @@ -443,6 +443,7 @@ const SvcSwitches addmodOptions[] =
{"sec_lastname", putStringArgument, 0, isc_spb_sec_lastname, 0},
{"sec_userid", putNumericArgument, 0, isc_spb_sec_userid, 0},
{"sec_groupid", putNumericArgument, 0, isc_spb_sec_groupid, 0},
{"sec_admin", putNumericArgument, 0, isc_spb_sec_admin, 0},
{0, 0, 0, 0, 0}
};

Expand Down Expand Up @@ -568,7 +569,7 @@ class UserPrint
{
public:
string login, first, middle, last;
int gid, uid;
int gid, uid, admin;

private:
bool hasData;
Expand All @@ -588,18 +589,20 @@ class UserPrint
void clear()
{
login = first = middle = last = "";
gid = uid = 0;
gid = uid = admin = 0;
}

void newUser()
{
if (!hasData)
{
hasData = true;
printf("%-28.28s %-40.40s %4.4s %4.4s %3.3s\n", "Login",
"Full name", "uid", "gid", "adm");
return;
}
printf("%-28.28s %-40.40s %4d %4d\n", login.c_str(),
(first + " " + middle + " " + last).c_str(), uid, gid);
printf("%-28.28s %-40.40s %4d %4d %3.3s\n", login.c_str(),
(first + " " + middle + " " + last).c_str(), uid, gid, admin ? "yes" : "no");
clear();
}
};
Expand Down Expand Up @@ -748,6 +751,9 @@ bool printInfo(const char* p, UserPrint& up)
case isc_spb_sec_userid:
up.uid = getNumeric(p);
break;
case isc_spb_sec_admin:
up.admin = getNumeric(p);
break;

case isc_info_svc_line:
ret = printLine(p);
Expand Down
19 changes: 19 additions & 0 deletions src/utilities/gsec/call_service.cpp
Expand Up @@ -271,6 +271,9 @@ static void userInfoToSpb(char*& spb, const internal_user_data& userInfo)
stuffSpbByte(spb, isc_spb_sec_groupid);
stuffSpbLong(spb, userInfo.gid);
}
if (userInfo.sql_role_name_entered) {
stuffSpb2(spb, isc_spb_sql_role_name, userInfo.sql_role_name);
}
if (userInfo.group_name_entered) {
stuffSpb2(spb, isc_spb_sec_groupname, userInfo.group_name);
}
Expand All @@ -295,6 +298,11 @@ static void userInfoToSpb(char*& spb, const internal_user_data& userInfo)
else if (userInfo.last_name_specified) {
stuffSpb2(spb, isc_spb_sec_lastname, "");
}
if (userInfo.admin_entered)
{
stuffSpbByte(spb, isc_spb_sec_admin);
stuffSpbLong(spb, userInfo.admin);
}
}


Expand Down Expand Up @@ -345,6 +353,10 @@ void callRemoteServiceManager(ISC_STATUS* status,
case DEL_OPER:
stuffSpbByte(spb, isc_action_svc_delete_user);
stuffSpb2(spb, isc_spb_sec_username, userInfo.user_name);
if (userInfo.sql_role_name_entered)
{
stuffSpb2(spb, isc_spb_sql_role_name, userInfo.sql_role_name);
}
break;

case DIS_OPER:
Expand All @@ -353,6 +365,10 @@ void callRemoteServiceManager(ISC_STATUS* status,
{
stuffSpb2(spb, isc_spb_sec_username, userInfo.user_name);
}
if (userInfo.sql_role_name_entered)
{
stuffSpb2(spb, isc_spb_sql_role_name, userInfo.sql_role_name);
}
break;

case MAP_SET_OPER:
Expand Down Expand Up @@ -609,6 +625,9 @@ static int typeBuffer(ISC_STATUS* status, char* buf, int offset,
case isc_spb_sec_userid:
parseLong(p, uData.uid, loop);
break;
case isc_spb_sec_admin:
parseLong(p, uData.admin, loop);
break;
default: // give up - treat it as gsec error
text = Firebird::string(p - 1, loop + 1);
return -1;
Expand Down
42 changes: 37 additions & 5 deletions src/utilities/gsec/gsec.cpp
Expand Up @@ -162,6 +162,8 @@ int gsec(Firebird::UtilSvc* uSvc)
databaseName = database_name;
}

Firebird::string sqlRoleName(user_data->sql_role_name_entered ? user_data->sql_role_name : "");

Firebird::PathName serverName;
const bool useServices = !uSvc->isService();

Expand Down Expand Up @@ -328,6 +330,10 @@ int gsec(Firebird::UtilSvc* uSvc)

databaseName.copyTo(user_data->database_name, sizeof(user_data->database_name));
user_data->database_name_entered = databaseNameEntered;
sqlRoleName.copyTo(user_data->sql_role_name, sizeof(user_data->sql_role_name));
user_data->sql_role_name_entered = sqlRoleName.hasData();
user_data->sql_role_name_specified = user_data->sql_role_name_entered;

if (ret == 0)
{
callRemoteServiceManager(status, sHandle, *user_data, data_print, NULL);
Expand Down Expand Up @@ -413,21 +419,22 @@ static void data_print(void* /*arg*/, const internal_user_data* data, bool first
tdsec->utilSvc->putLine(isc_spb_sec_lastname, data->last_name);
tdsec->utilSvc->putSLong(isc_spb_sec_userid, data->uid);
tdsec->utilSvc->putSLong(isc_spb_sec_groupid, data->gid);
tdsec->utilSvc->putSLong(isc_spb_sec_admin, data->admin);
}
else
{
if (first)
{
GSEC_print(GsecMsg26);
GSEC_print(GsecMsg27);
// msg26: " user name uid gid full name"
// msg27: "-------------------------------------------------------------------------------------------"
// msg26: " user name uid gid admin full name"
// msg27: "-------------------------------------------------------------------------------------------------"
}

util_output("%-*.*s %5d %5d %s %s %s\n",
util_output("%-*.*s %5d %5d %-5.5s %s %s %s\n",
USERNAME_LENGTH, USERNAME_LENGTH, data->user_name,
data->uid, data->gid, data->first_name, data->middle_name,
data->last_name);
data->uid, data->gid, data->admin ? "admin" : "",
data->first_name, data->middle_name, data->last_name);
}
}

Expand Down Expand Up @@ -662,6 +669,27 @@ static bool get_switches(Firebird::UtilSvc::ArgvType& argv,
}
}
break;
case IN_SW_GSEC_ADMIN:
{
Firebird::string val(string);
val.upper();

if (val == "YES")
{
user_data->admin = 1;
}
else if (val == "NO") {
user_data->admin = 0;
}
else
{
GSEC_diag(GsecMsg103);
// invalid parameter for -ADMIN, only YES or NO is accepted
return false;
}
user_data->admin_entered = true;
}
break;
case IN_SW_GSEC_Z:
case IN_SW_GSEC_0:
GSEC_diag(GsecMsg29);
Expand Down Expand Up @@ -1114,6 +1142,10 @@ static void printhelp()
util_output("%s", " ");
GSEC_print(GsecMsg73);
// -lname <lastname>

util_output("%s", " ");
GSEC_print(GsecMsg102);
// -adm(in) {yes|no}
util_output("\n", NULL);
}

Expand Down
5 changes: 5 additions & 0 deletions src/utilities/gsec/gsec.h
Expand Up @@ -101,6 +101,9 @@ struct internal_user_data
#ifdef TRUSTED_AUTH
bool trusted_auth; // use trusted authentication
#endif
int admin; // the user is admin of security DB
bool admin_entered; // admin entered flag
bool admin_specified; // admin specified flag

// force NULLs in this ugly structure to avoid foolish bugs
internal_user_data()
Expand Down Expand Up @@ -249,6 +252,8 @@ const USHORT GsecMsg98 = 98; // changing admins mapping to SYSDBA:\n
const USHORT GsecMsg99 = 99; // invalid parameter for -MAPPING, only SET or DROP is accepted
const USHORT GsecMsg100 = 100; // -ma(pping) {set|drop}
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

#endif // UTILITIES_GSEC_H

0 comments on commit 4f54fd6

Please sign in to comment.