⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdbms.cpp

📁 使用yacc的一个例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	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 + -