📄 sdbms.cpp
字号:
CantUseRoleName(strRoleName, SYSTEM_ROLE_DBA);
CantUseRoleName(strRoleName, SYSTEM_ROLE_LOGIN);
CantUseRoleName(strRoleName, SYSTEM_ROLE_GUEST);
CantUseRoleName(strRoleName, SYSTEM_ROLE_OWNER);
CantUseTableName(strTableName, SYSTEM_TABLE_TEMP);
CantUseTableName(strTableName, SYSTEM_TABLE_AUDIT);
//检查当前是否有连接的数据库
if (m_pCurDB == NULL)
{
g_msg.ThrowErrorMsg("当前没有数据库被打开");
return FALSE;
}
ASSERT(m_pCurDB->m_bInit && m_pCurDB->m_pRole);
//判断当前用户是否有权执行对象权限GRANT命令
// if (!HaveSystemRight(SR_GRANT_OBJECT, m_pCurUser, m_pCurDB))
// return FALSE;
//应该不用判断
if (m_pCurDB->Grant(m_pCurUser, nObjectRight, strTableName, strFieldName,
strRoleName, bCanGrant, pCondition))
{
//设置审计记录中操作成功属性为真
if (bAuditSuccess)
m_audit.SetOperateSuccess();
return TRUE;
}
else
return FALSE;
}
/**********************************************************************
功能:收回某个角色上的在某个表的某些列上的对象权限
参数:nObjectRight--对象权限ID
strTableName--权限作用的表名
strFieldName--权限作用的表上的列名
strRoleName --被授权的角色名
bRevokeGrant--是否只收回授予权限,而不收回权限本身
bRestrict --如果为真表示如果要收回的权限已经授权给其他用户,则该语句不能执行
pCondition --权限起作用的谓词条件的语法树
***********************************************************************/
BOOL CSdbms::DoRevoke(ObjectRight nObjectRight, CString strTableName, CString strFieldName,
CString strRoleName, BOOL bRevokeGrant/*=FALSE*/, BOOL bRestrict/*=FALSE*/, CSdbms_Condition *pCondition/*=NULL*/)
{
ASSERT(m_pCurUser);
ASSERT(!strRoleName.IsEmpty());
//审计
BOOL bAuditSuccess = m_audit.Audit(m_pCurUser, SR_REVOKE_OBJECT, m_pCurDB);
CantUseRoleName(strRoleName, SYSTEM_ROLE_SYSTEM); //不能从系统预定义角色中收回授权
CantUseRoleName(strRoleName, SYSTEM_ROLE_DBSA);
CantUseRoleName(strRoleName, SYSTEM_ROLE_DBA);
CantUseRoleName(strRoleName, SYSTEM_ROLE_LOGIN);
CantUseRoleName(strRoleName, SYSTEM_ROLE_GUEST);
CantUseRoleName(strRoleName, SYSTEM_ROLE_OWNER);
CantUseTableName(strTableName, SYSTEM_TABLE_TEMP);
CantUseTableName(strTableName, SYSTEM_TABLE_AUDIT);
//检查当前是否有连接的数据库
if (m_pCurDB == NULL)
{
g_msg.ThrowErrorMsg("当前没有数据库被打开");
return FALSE;
}
ASSERT(m_pCurDB->m_bInit && m_pCurDB->m_pRole);
//判断当前用户是否有权执行对象权限REVOKE命令
if (!HaveSystemRight(SR_REVOKE_OBJECT, m_pCurUser, m_pCurDB))
return FALSE;
if (m_pCurDB->Revoke(m_pCurUser, nObjectRight, strTableName, strFieldName,
strRoleName, bRevokeGrant, bRestrict, pCondition))
{
//设置审计记录中操作成功属性为真
if (bAuditSuccess)
m_audit.SetOperateSuccess();
return TRUE;
}
else
return FALSE;
/*****************老版本*************************/
/*算法:查找用户当前所属的所有角色,并检查角色中是否含有该对象权限,若有则再检查其用户
角色关系如果是被取消权限的授权者之一,是则回收之
//检查被收回授权的角色名是否已存在
CSdbms_Role *pRole = NULL;
if (!m_pCurDB->GetRole(strRoleName, &pRole))
{
sprintf(g_strMsg, "角色%s不存在", strRoleName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
ASSERT(pRole);
//得到表内码
CSdbms_Table *pTable=NULL;
if (!m_pCurDB->GetTable(strTableName, &pTable))
{
sprintf(g_strMsg, "数据库%s中没有表名%s", m_pCurDB->m_strDBName, strTableName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
ASSERT(pTable);
//得到列内码。若列名为空,表示针对表中的所有列
CSdbms_Field *pField=NULL;
bool bOnlyOneField = false;
if (!strFieldName.IsEmpty())
{
if (!pTable->GetField(strFieldName, &pField))
{
sprintf(g_strMsg, "表%s中没有列名%s", strTableName, strFieldName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
bOnlyOneField = true;
ASSERT(pField);
}
CSdbms_RoleUser *pRoleUser1=NULL, *pRoleUser2=NULL;
if (IsOwnDbaRole(m_pCurUser->m_nUserID)) //当前用户属于DBA角色
pRoleUser1 = FindRoleUser(m_pCurUser, m_pDbaRole);
if (IsOwnSystemRole(m_pCurUser->m_nUserID)) //当前用户属于SYSTEM角色
pRoleUser2 = FindRoleUser(m_pCurUser, m_pSystemRole);
bool bRevoke = false;
int nCount = bOnlyOneField ? 1 : pTable->m_FieldArray.GetSize();//判断只有一列还是要针对所有列
for (int i=0; i<nCount; i++)
{
bRevoke = false;
if (bOnlyOneField) //只有一列
ASSERT(i == 0); //只会执行一次
else
pField = pTable->m_FieldArray[i];
//判断角色是否有该权限
POSITION pos = pRole->FindObjectRight(pTable->m_nTableID, pField->m_nFieldID, nObjectRight, pCondition);
CSdbms_RoleObjectRight *pObjectRight = pRole->m_ORList.GetAt(pos);
if (pObjectRight == NULL)
{
sprintf(g_strMsg, "因为角色%s没有作用在%s.%s.%s上的%s权限,所以该回收语句执行失败!",
strRoleName, m_pCurDB->m_strDBName, pTable->m_strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowErrorMsg(g_strMsg);
continue;
}
//如果bRstrict==TRUE,则判断是否该权限已经授予给其他用户了
if (bRestrict && (pObjectRight->m_ToRoleArray.GetSize() > 0))
{
sprintf(g_strMsg, "因为角色%s中的作用在%s.%s.%s上的%s权限已经授权给了其他用户,所以该回收语句不能执行!",
strRoleName, m_pCurDB->m_strDBName, pTable->m_strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowErrorMsg(g_strMsg);
continue;
}
//如果被收回授权的角色的某个子角色有此对象权限,收回授权失败
CSdbms_Role *pChild = pRole->m_pFirstChildRole;
while (pChild != NULL)
{
if (pChild->m_pParentRole->HaveObjectRight(pTable->m_nTableID, pField->m_nFieldID, nObjectRight))
{
sprintf(g_strMsg, "因为角色%s的子角色%s有在%s.%s.%s上的%s权限,所以不能收回授权",
strRoleName, pChild->m_strRoleName,
m_pCurDB->m_strDBName, pTable->m_strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowErrorMsg(g_strMsg);
break;
}
else
pChild = pChild->m_pNextBrotherRole;
}
if (pChild != NULL) //收回授权失败,进行下一个
continue;
if (pRoleUser1) //用户属于DBA角色
{
if (pRole->RemoveORList(nObjectRight, pTable->m_nTableID, pField->m_nFieldID, pRoleUser1, bRevokeGrant, pCondition))
{
bRevoke = true;
if (!bRevokeGrant)
{
CSdbms_RoleObjectRight *pRight = pRoleUser1->m_pRole->m_ORList.GetHead();
ASSERT(pRight);
VERIFY(pRight->RemoveToRoleArray(pRole)); //系统预定义角色都只有一个对象权限结点
}
sprintf(g_strMsg, "用户%s成功地以DBA身份收回了角色%s中的作用在%s.%s.%s上的%s权限",
m_pCurUser->m_strUserName, strRoleName, m_pCurDB->m_strDBName, pTable->m_strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowSuccessMsg(g_strMsg);
}
}
if (pRoleUser2) //用户属于SYSTEM角色
{
if (pRole->RemoveORList(nObjectRight, pTable->m_nTableID, pField->m_nFieldID, pRoleUser2, bRevokeGrant, pCondition))
{
bRevoke = true;
if (!bRevokeGrant)
{
CSdbms_RoleObjectRight *pRight = pRoleUser2->m_pRole->m_ORList.GetHead();
ASSERT(pRight);
VERIFY(pRight->RemoveToRoleArray(pRole)); //系统预定义角色都只有一个对象权限结点
}
sprintf(g_strMsg, "用户%s成功地以SYSTEM身份收回了角色%s中的作用在%s.%s.%s上的%s权限",
m_pCurUser->m_strUserName, strRoleName, m_pCurDB->m_strDBName, pTable->m_strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowSuccessMsg(g_strMsg);
}
}
if (m_pCurDB->Revoke(nObjectRight, pTable, pField, pRole, m_pCurUser, bRevokeGrant, bRestrict, pCondition))
bRevoke = true;
if (bRevoke)
{
sprintf(g_strMsg, "成功地从角色%s中收回作用在%s.%s.%s上的%s权限",
strRoleName, m_pCurDB->m_strDBName, pTable->m_strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowSuccessMsg(g_strMsg);
}
else
{
sprintf(g_strMsg, "失败地从角色%s中收回作用在%s.%s.%s上的%s权限",
strRoleName, m_pCurDB->m_strDBName, pTable->m_strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowErrorMsg(g_strMsg);
}
}
return bRevoke;
*/
}
/**********************************************************************
功能:设置用户最大安全级(只能设置密级)
***********************************************************************/
BOOL CSdbms::DoSetUserSecurityLevel(CString strUserName, UINT nClassifaction)
{
ASSERT(m_pCurUser);
//审计
BOOL bAuditSuccess = m_audit.Audit(m_pCurUser, SR_SET_USER_SECURITY_LEVEL, m_pCurDB);
//判断当前用户是否有权执行SET USER SECURITY LEVEL命令
if (!HaveSystemRight(SR_SET_USER_SECURITY_LEVEL, m_pCurUser, NULL))
return FALSE;
CSdbms_User *pUser;
if (!GetUser(strUserName, &pUser)) //检查用户名是否已存在
{
sprintf(g_strMsg, "用户名%s不存在", strUserName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
//密级必须在0-3之间
nClassifaction = nClassifaction < 0 ? 0 : nClassifaction;
nClassifaction = nClassifaction > 3 ? 3 : nClassifaction;
pUser->m_SecLevel.m_nClassifaction = nClassifaction;
/*************************待做********************************
//应遍历用户在各个表上的允许安全级及当前安全级,使之满足匹配关系
**************************************************************/
//设置审计记录中操作成功属性为真
if (bAuditSuccess)
m_audit.SetOperateSuccess();
g_msg.ThrowSuccessMsg("成功设置用户安全级");
return TRUE;
}
/**********************************************************************
功能:设置用户在表上的允许安全级
***********************************************************************/
BOOL CSdbms::DoSetAllowSecurityLevel(CString strUserName, CString strTableName, CSdbms_SecurityLevel slAllowSecLevel)
{
ASSERT(m_pCurUser);
//审计
BOOL bAuditSuccess = m_audit.Audit(m_pCurUser, SR_SET_USER_ALLOW_SECURITY_LEVEL, m_pCurDB);
CantUseTableName(strTableName, SYSTEM_TABLE_TEMP);
CantUseTableName(strTableName, SYSTEM_TABLE_AUDIT);
CSdbms_User *pUser;
if (!GetUser(strUserName, &pUser)) //检查用户名是否已存在
{
sprintf(g_strMsg, "用户名%s不存在", strUserName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
//检查当前是否有连接的数据库
if (m_pCurDB == NULL)
{
g_msg.ThrowErrorMsg("当前没有数据库被打开");
return FALSE;
}
ASSERT(m_pCurDB->m_bInit && m_pCurDB->m_pRole);
//判断当前用户是否有权执行SET ALLOW SECURITY LEVEL命令
if (!HaveSystemRight(SR_SET_USER_ALLOW_SECURITY_LEVEL, m_pCurUser, m_pCurDB, strTableName))
return FALSE;
//密级必须在0-3之间
int nClassifaction = slAllowSecLevel.m_nClassifaction;
nClassifaction = nClassifaction < 0 ? 0 : nClassifaction;
nClassifaction = nClassifaction > 3 ? 3 : nClassifaction;
slAllowSecLevel.m_nClassifaction = nClassifaction;
//允许安全级的密级必须<=用户最大安全级的密级
if (nClassifaction > pUser->m_SecLevel.m_nClassifaction)
{
g_msg.ThrowErrorMsg("允许安全级的密级不能大于用户安全级的密级,设置失败");
return FALSE;
}
if (m_pCurDB->SetAllowSecurityLevel(pUser, strTableName, slAllowSecLevel))
{
//设置审计记录中操作成功属性为真
if (bAuditSuccess)
m_audit.SetOperateSuccess();
return TRUE;
}
else
return FALSE;
}
/**********************************************************************
功能:设置用户在表上的当前安全级
***********************************************************************/
BOOL CSdbms::DoSetCurrentSecurityLevel(CString strUserName, CString strTableName, CSdbms_SecurityLevel slCurrentSecLevel)
{
ASSERT(m_pCurUser);
//审计
BOOL bAuditSuccess = m_audit.Audit(m_pCurUser, SR_SET_USER_CURRENT_SECURITY_LEVEL, m_pCurDB);
CantUseTableName(strTableName, SYSTEM_TABLE_TEMP);
CantUseTableName(strTableName, SYSTEM_TABLE_AUDIT);
CSdbms_User *pUser;
if (!GetUser(strUserName, &pUser)) //检查用户名是否已存在
{
sprintf(g_strMsg, "用户名%s不存在", strUserName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
//检查当前是否有连接的数据库
if (m_pCurDB == NULL)
{
g_msg.ThrowErrorMsg("当前没有数据库被打开");
return FALSE;
}
ASSERT(m_pCurDB->m_bInit && m_pCurDB->m_pRole);
//判断当前用户是否有权执行SET CURRENT SECURITY LEVEL命令
if (pUser->m_nUserID != m_pCurUser->m_nUserID)
{
if (!HaveSystemRight(SR_SET_USER_CURRENT_SECURITY_LEVEL, m_pCurUser, m_pCurDB))
return FALSE;
}
//密级必须在0-3之间
int nClassifaction = slCurrentSecLevel.m_nClassifaction;
nClassifaction = nClassifaction < 0 ? 0 : nClassifaction;
nClassifaction = nClassifaction > 3 ? 3 : nClassifaction;
slCurrentSecLevel.m_nClassifaction = nClassifaction;
//当前安全级的密级必须<=用户最大安全级的密级
if (nClassifaction > pUser->m_SecLevel.m_nClassifaction)
{
g_msg.ThrowErrorMsg("当前安全级的密级不能大于用户安全级的密级,设置失败");
return FALSE;
}
if (m_pCurDB->SetCurrentSecurityLevel(pUser, strTableName, slCurrentSecLevel))
{
//设置审计记录中操作成功属性为真
if (bAuditSuccess)
m_audit.SetOperateSucc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -