blob: 2b6831f77efca2ed67a86bf1d6ba62500cf8ce16 [file] [log] [blame]
/* -*-C++-*-
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
*****************************************************************************
*
* File: ComUser
* Description: Implements methods for user management
*
* Contains methods for classes:
* ComUser
* ComUserVerifyObj
* ComUserVerifyAuth
*
*****************************************************************************
*/
#define SQLPARSERGLOBALS_FLAGS // must precede all #include's
#define SQLPARSERGLOBALS_NADEFAULTS
#include "ComUser.h"
#include "CmpSeabaseDDL.h"
#include "CmpDDLCatErrorCodes.h"
#include "sqlcli.h"
#include "SQLCLIdev.h"
#include "ExExeUtilCli.h"
#include "Context.h"
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class ComUser methods
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ----------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------
ComUser::ComUser()
{ }
// ----------------------------------------------------------------------------
// method: getCurrentUser
//
// Returns currentUser from the Cli context
// ----------------------------------------------------------------------------
Int32 ComUser::getCurrentUser(void)
{
Int32 dbUserID = 0;
Int32 rc = 0;
SQL_EXEC_ClearDiagnostics(NULL);
rc = SQL_EXEC_GetSessionAttr(SESSION_DATABASE_USER_ID,
&dbUserID,
NULL, 0, NULL);
assert(rc >= 0);
assert(dbUserID >= SUPER_USER);
return dbUserID;
}
// ----------------------------------------------------------------------------
// method: getCurrentUsername
//
// Returns size of username
// ----------------------------------------------------------------------------
bool ComUser::getCurrentUsername(
char * username,
Int32 maxUsernameLength)
{
SQL_EXEC_ClearDiagnostics(NULL);
Int32 usernameLength = 0;
Int32 rc = SQL_EXEC_GetSessionAttr(SESSION_DATABASE_USER_ID,NULL,
username,maxUsernameLength,&usernameLength);
assert(rc >= 0);
if (usernameLength > maxUsernameLength)
return false;
return true;
}
// ----------------------------------------------------------------------------
// method: getCurrentUsername
//
// Returns a pointer to the current database username
// ----------------------------------------------------------------------------
const char * ComUser::getCurrentUsername()
{
return GetCliGlobals()->currContext()->getDatabaseUserName();
}
// ----------------------------------------------------------------------------
// method: getSessionUser
//
// Returns sessionUser from the Cli context
// ----------------------------------------------------------------------------
Int32 ComUser::getSessionUser(void)
{
Int32 dbUserID = 0;
Int32 rc = 0;
SQL_EXEC_ClearDiagnostics(NULL);
rc = SQL_EXEC_GetSessionAttr(SESSION_DATABASE_USER_ID,
&dbUserID,
NULL, 0, NULL);
assert(rc >= 0);
assert(dbUserID >= SUPER_USER);
return dbUserID;
}
// ----------------------------------------------------------------------------
// method: isRootUserID
//
// Returns true if current userID is the root user
// ----------------------------------------------------------------------------
bool ComUser::isRootUserID()
{
return isRootUserID(getCurrentUser());
}
// ----------------------------------------------------------------------------
// method: isRootUserID
//
// Returns true if passed in userID is the root user
// ----------------------------------------------------------------------------
bool ComUser::isRootUserID(Int32 userID)
{
return (userID == SUPER_USER) ? true : false;
}
// ----------------------------------------------------------------------------
// method: getAuthType
//
// returns the type of authorization ID given the passed in authID
// ----------------------------------------------------------------------------
char ComUser::getAuthType(Int32 authID)
{
if (authID == PUBLIC_USER)
return AUTH_PUBLIC;
if (authID == SYSTEM_USER)
return AUTH_SYSTEM;
if (authID >= MIN_USERID && authID <= MAX_USERID)
return AUTH_USER;
if (authID >= MAX_USERID && authID <= MAX_ROLEID)
return AUTH_ROLE;
return AUTH_UNKNOWN;
}
// -----------------------------------------------------------------------
// getUserNameFromUserID
//
// Reads the USERS table to get the user name associated with the passed
// in userID
//
// <userID> Int32 In
// is the numeric ID to be mapped to a name.
//
// <userName> char * In
// passes back the name that the numeric ID mapped to. If the ID does
// not map to a name, the ASCII equivalent of the ID is passed back.
//
// <maxLen> Int32 In
// is the size of <authName>.
//
// <actualLen> Int32 & Out
// is the size of the auth name in the table. If larger than <maxLen>,
// caller needs to supply a larger buffer.
//
// Returns:
// FEOK -- Found. User name written to userName. Length
// returned in actualLen.
// FENOTFOUND -- Not found
// FEBUFTOOSMALL -- Found but output buffer is too small. Required
// length returned in actualLen.
// Other -- Unexpected error
// -----------------------------------------------------------------------
Int16 ComUser::getUserNameFromUserID(Int32 userID,
char *userName,
Int32 maxLen,
Int32 &actualLen)
{
Int16 result = FEOK;
actualLen = 0;
Int16 retcode = SQL_EXEC_GetDatabaseUserName_Internal(userID,
userName,
maxLen,
&actualLen);
if (retcode < 0)
{
if (actualLen > 0)
result = FEBUFTOOSMALL;
else
result = FENOTFOUND;
}
if (retcode != 0)
SQL_EXEC_ClearDiagnostics(NULL);
// On success, CLI does not return the length of the string in
// actualLen. This function however is supposed to return a value in
// actualLen even when the mapping is successful. The value returned
// should not account for a null terminator.
if (result == FEOK)
actualLen = strlen(userName);
return result;
}
// ----------------------------------------------------------------------------
// method: getUserIDFromUserName
//
// Reads the AUTHS table to get the userID associated with the passed
// in user name
//
// Returns: FEOK -- found
// FENOTFOUND -- user not defined
// other -- unexpected error
// ----------------------------------------------------------------------------
Int16 ComUser::getUserIDFromUserName(const char *userName, Int32 &userID)
{
Int16 result = FEOK;
Int16 retcode = SQL_EXEC_GetDatabaseUserID_Internal((char *) userName,
&userID);
if (retcode < 0)
result = FENOTFOUND;
if (retcode != 0)
SQL_EXEC_ClearDiagnostics(NULL);
return result;
}
// ----------------------------------------------------------------------------
// method: getAuthIDFromAuthName
//
// Reads the AUTHS table to get the authID associated with the passed
// in authorization name
//
// Returns: FEOK -- found
// FENOTFOUND -- auth name not defined
// other -- unexpected error
// ----------------------------------------------------------------------------
Int16 ComUser::getAuthIDFromAuthName(const char *authName, Int32 &authID)
{
Int16 result = FEOK;
Int16 retcode = SQL_EXEC_GetAuthID(authName,authID);
if (retcode < 0)
result = FENOTFOUND;
if (retcode != 0)
SQL_EXEC_ClearDiagnostics(NULL);
return result;
}
// ----------------------------------------------------------------------------
// method: getAuthNameFromAuthID
//
// Maps an integer authentication ID to a name. If the number cannot be
// mapped to a name, the numeric ID is converted to a string.
//
// <authID> Int32 In
// is the numeric ID to be mapped to a name.
//
// <authName> char * In
// passes back the name that the numeric ID mapped to. If the ID does
// not map to a name, the ASCII equivalent of the ID is passed back.
//
// <maxLen> Int32 In
// is the size of <authName>.
//
// <actualLen> Int32 & Out
// is the size of the auth name in the table. If larger than <maxLen>,
// caller needs to supply a larger buffer.
//
// Returns: Int16
//
// FEOK -- Found. User name written to userName. Length
// returned in actualLen.
// FENOTFOUND -- Not found
// FEBUFTOOSMALL -- Found but output buffer is too small. Required
// length returned in actualLen.
// Other -- Unexpected error
// ----------------------------------------------------------------------------
Int16 ComUser::getAuthNameFromAuthID(Int32 authID,
char * authName,
Int32 maxLen,
Int32 & actualLen)
{
actualLen = 0;
int retcode = SQL_EXEC_GetAuthName_Internal(authID,authName,maxLen,actualLen);
if (retcode < 0) // ERROR == -1
{
if (actualLen > 0)
return FEBUFTOOSMALL;
return FENOTFOUND; //Should not happen
}
if (retcode != 0)
SQL_EXEC_ClearDiagnostics(NULL);
return FEOK;
}
// ----------------------------------------------------------------------------
// method: currentUserHasRole
//
// Searches the list of roles stored for the user to see if passed in role ID
// is found
//
// Returns: true - role found
// false - role not found
// ----------------------------------------------------------------------------
bool ComUser::currentUserHasRole(Int32 roleID)
{
Int32 numRoles = 0;
Int32 *roleIDs = 0;
if (SQL_EXEC_GetRoleList(numRoles, roleIDs) < 0)
return false;
for (Int32 i = 0; i < numRoles; i++)
{
Int32 userRole = roleIDs[i];
if (userRole == roleID)
return true;
}
return false;
}
void ComUser::getCurrentUserRoles(NAList <Int32> &roleList)
{
Int32 numRoles = 0;
Int32 *roleIDs = 0;
Int32 retcode = SQL_EXEC_GetRoleList(numRoles, roleIDs);
assert(retcode == 0);
for (Int32 i = 0; i < numRoles; i++)
roleList.insert (roleIDs[i]);
}
// ----------------------------------------------------------------------------
// method: getRoleList
//
// Returns the list of system roles
// Params:
// (out) roleList - the list of roles, space is managed by the caller
// (out) actualLen - the length of the returned role list
// ( in) maxLen - the size of the roleList allocated by the caller
// ( in) delimited - delimiter to use (defaults to single quote)
// ( in) separator - specified what separator to use (defaults to comma)
// ( in) includeSpecialAuths - includes the special auths (PUBLIC and _SYSTEM)
//
// Returns: FEOK -- found
// FEBUFTOOSMALL -- space allocated for role list is too small
// ----------------------------------------------------------------------------
Int32 ComUser::getRoleList (char * roleList,
Int32 &actualLen,
const Int32 maxLen,
const char delimiter,
const char separator,
const bool includeSpecialAuths)
{
Int32 numberRoles = sizeof(systemRoles)/sizeof(SystemAuthsStruct);
Int32 roleListLen = (MAX_AUTHNAME_LEN*numberRoles)+(numberRoles * 4); // 4 = 2 del + 2 sep
char generatedRoleList[roleListLen];
char *pRoles = generatedRoleList;
char roleName[MAX_AUTHNAME_LEN + 4];
char currentSeparator = ' ';
for (Int32 i = 0; i < numberRoles; i++)
{
const SystemAuthsStruct &roleDefinition = systemRoles[i];
if (!includeSpecialAuths && roleDefinition.isSpecialAuth)
continue;
// str_sprintf does not support the %c format
sprintf(roleName, "%c%c%s%c",
currentSeparator, delimiter, roleDefinition.authName, delimiter);
str_cpy_all(pRoles, roleName, sizeof(roleName)-1); // don't copy null terminator
currentSeparator = separator;
pRoles = pRoles + strlen(roleName);
}
pRoles = '\0'; // null terminate string
pRoles = generatedRoleList;
actualLen = strlen(pRoles);
if (actualLen > maxLen)
return FEBUFTOOSMALL;
str_cpy_all(roleList, pRoles, strlen(pRoles));
roleList[strlen(pRoles)] = 0; // null terminate string
return FEOK;
}