LibreOffice Module connectivity (master) 1
YUser.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <mysql/YUser.hxx>
21#include <com/sun/star/sdbc/XRow.hpp>
22#include <com/sun/star/sdbc/XResultSet.hpp>
25#include <com/sun/star/sdbcx/Privilege.hpp>
26#include <com/sun/star/sdbcx/PrivilegeObject.hpp>
27#include <TConnection.hxx>
28#include <strings.hrc>
29#include <comphelper/types.hxx>
30#include <utility>
31
32using namespace connectivity;
33using namespace connectivity::mysql;
34using namespace ::com::sun::star::uno;
35using namespace ::com::sun::star::beans;
36using namespace ::com::sun::star::sdbcx;
37using namespace ::com::sun::star::sdbc;
38using namespace ::com::sun::star::container;
39using namespace ::com::sun::star::lang;
40
41OMySQLUser::OMySQLUser(css::uno::Reference<css::sdbc::XConnection> _xConnection)
42 : connectivity::sdbcx::OUser(true)
43 , m_xConnection(std::move(_xConnection))
44{
45 construct();
46}
47
48OMySQLUser::OMySQLUser(css::uno::Reference<css::sdbc::XConnection> _xConnection,
49 const OUString& Name)
50 : connectivity::sdbcx::OUser(Name, true)
51 , m_xConnection(std::move(_xConnection))
52{
53 construct();
54}
55
57
58OUserExtend::OUserExtend(const css::uno::Reference<css::sdbc::XConnection>& _xConnection)
59 : OMySQLUser(_xConnection)
60{
61 construct();
62}
63
65{
68}
69
71{
72 Sequence<Property> aProps;
73 describeProperties(aProps);
74 return new cppu::OPropertyArrayHelper(aProps);
75}
76
78{
80}
82
83sal_Int32 SAL_CALL OMySQLUser::getPrivileges(const OUString& objName, sal_Int32 objType)
84{
85 ::osl::MutexGuard aGuard(m_aMutex);
86 checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed);
87
88 sal_Int32 nRights, nRightsWithGrant;
89 findPrivilegesAndGrantPrivileges(objName, objType, nRights, nRightsWithGrant);
90 return nRights;
91}
92
93void OMySQLUser::findPrivilegesAndGrantPrivileges(const OUString& objName, sal_Int32 objType,
94 sal_Int32& nRights, sal_Int32& nRightsWithGrant)
95{
96 nRightsWithGrant = nRights = 0;
97 // first we need to create the sql stmt to select the privs
98 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
99 OUString sCatalog, sSchema, sTable;
100 ::dbtools::qualifiedNameComponents(xMeta, objName, sCatalog, sSchema, sTable,
101 ::dbtools::EComposeRule::InDataManipulation);
102 Reference<XResultSet> xRes;
103 switch (objType)
104 {
105 case PrivilegeObject::TABLE:
106 case PrivilegeObject::VIEW:
107 {
108 Any aCatalog;
109 if (!sCatalog.isEmpty())
110 aCatalog <<= sCatalog;
111 xRes = xMeta->getTablePrivileges(aCatalog, sSchema, sTable);
112 }
113 break;
114
115 case PrivilegeObject::COLUMN:
116 {
117 Any aCatalog;
118 if (!sCatalog.isEmpty())
119 aCatalog <<= sCatalog;
120 xRes = xMeta->getColumnPrivileges(aCatalog, sSchema, sTable, "%");
121 }
122 break;
123 }
124
125 if (!xRes.is())
126 return;
127
128 static const char sYes[] = "YES";
129
130 nRightsWithGrant = nRights = 0;
131
132 Reference<XRow> xCurrentRow(xRes, UNO_QUERY);
133 while (xCurrentRow.is() && xRes->next())
134 {
135 OUString sGrantee = xCurrentRow->getString(5);
136 OUString sPrivilege = xCurrentRow->getString(6);
137 OUString sGrantable = xCurrentRow->getString(7);
138
139 if (!m_Name.equalsIgnoreAsciiCase(sGrantee))
140 continue;
141
142 if (sPrivilege.equalsIgnoreAsciiCase("SELECT"))
143 {
144 nRights |= Privilege::SELECT;
145 if (sGrantable.equalsIgnoreAsciiCase(sYes))
146 nRightsWithGrant |= Privilege::SELECT;
147 }
148 else if (sPrivilege.equalsIgnoreAsciiCase("INSERT"))
149 {
150 nRights |= Privilege::INSERT;
151 if (sGrantable.equalsIgnoreAsciiCase(sYes))
152 nRightsWithGrant |= Privilege::INSERT;
153 }
154 else if (sPrivilege.equalsIgnoreAsciiCase("UPDATE"))
155 {
156 nRights |= Privilege::UPDATE;
157 if (sGrantable.equalsIgnoreAsciiCase(sYes))
158 nRightsWithGrant |= Privilege::UPDATE;
159 }
160 else if (sPrivilege.equalsIgnoreAsciiCase("DELETE"))
161 {
162 nRights |= Privilege::DELETE;
163 if (sGrantable.equalsIgnoreAsciiCase(sYes))
164 nRightsWithGrant |= Privilege::DELETE;
165 }
166 else if (sPrivilege.equalsIgnoreAsciiCase("READ"))
167 {
168 nRights |= Privilege::READ;
169 if (sGrantable.equalsIgnoreAsciiCase(sYes))
170 nRightsWithGrant |= Privilege::READ;
171 }
172 else if (sPrivilege.equalsIgnoreAsciiCase("CREATE"))
173 {
174 nRights |= Privilege::CREATE;
175 if (sGrantable.equalsIgnoreAsciiCase(sYes))
176 nRightsWithGrant |= Privilege::CREATE;
177 }
178 else if (sPrivilege.equalsIgnoreAsciiCase("ALTER"))
179 {
180 nRights |= Privilege::ALTER;
181 if (sGrantable.equalsIgnoreAsciiCase(sYes))
182 nRightsWithGrant |= Privilege::ALTER;
183 }
184 else if (sPrivilege.equalsIgnoreAsciiCase("REFERENCES"))
185 {
186 nRights |= Privilege::REFERENCE;
187 if (sGrantable.equalsIgnoreAsciiCase(sYes))
188 nRightsWithGrant |= Privilege::REFERENCE;
189 }
190 else if (sPrivilege.equalsIgnoreAsciiCase("DROP"))
191 {
192 nRights |= Privilege::DROP;
193 if (sGrantable.equalsIgnoreAsciiCase(sYes))
194 nRightsWithGrant |= Privilege::DROP;
195 }
196 }
197 ::comphelper::disposeComponent(xRes);
198}
199
200sal_Int32 SAL_CALL OMySQLUser::getGrantablePrivileges(const OUString& objName, sal_Int32 objType)
201{
202 ::osl::MutexGuard aGuard(m_aMutex);
203 checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed);
204
205 sal_Int32 nRights, nRightsWithGrant;
206 findPrivilegesAndGrantPrivileges(objName, objType, nRights, nRightsWithGrant);
207 return nRightsWithGrant;
208}
209
210void SAL_CALL OMySQLUser::grantPrivileges(const OUString& objName, sal_Int32 objType,
211 sal_Int32 objPrivileges)
212{
213 if (objType != PrivilegeObject::TABLE)
214 {
216 const OUString sError(aResources.getResourceString(STR_PRIVILEGE_NOT_GRANTED));
218 } // if ( objType != PrivilegeObject::TABLE )
219
220 ::osl::MutexGuard aGuard(m_aMutex);
221
222 OUString sPrivs = getPrivilegeString(objPrivileges);
223 if (sPrivs.isEmpty())
224 return;
225
226 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
227 OUString sGrant
228 = "GRANT " + sPrivs + " ON "
229 + ::dbtools::quoteTableName(xMeta, objName, ::dbtools::EComposeRule::InDataManipulation)
230 + " TO " + m_Name;
231
232 Reference<XStatement> xStmt = m_xConnection->createStatement();
233 if (xStmt.is())
234 xStmt->execute(sGrant);
235 ::comphelper::disposeComponent(xStmt);
236}
237
238void SAL_CALL OMySQLUser::revokePrivileges(const OUString& objName, sal_Int32 objType,
239 sal_Int32 objPrivileges)
240{
241 if (objType != PrivilegeObject::TABLE)
242 {
244 const OUString sError(aResources.getResourceString(STR_PRIVILEGE_NOT_REVOKED));
246 }
247
248 ::osl::MutexGuard aGuard(m_aMutex);
249 checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed);
250 OUString sPrivs = getPrivilegeString(objPrivileges);
251 if (sPrivs.isEmpty())
252 return;
253
254 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
255 OUString sGrant
256 = "REVOKE " + sPrivs + " ON "
257 + ::dbtools::quoteTableName(xMeta, objName, ::dbtools::EComposeRule::InDataManipulation)
258 + " FROM " + m_Name;
259
260 Reference<XStatement> xStmt = m_xConnection->createStatement();
261 if (xStmt.is())
262 xStmt->execute(sGrant);
263 ::comphelper::disposeComponent(xStmt);
264}
265
266// XUser
267void SAL_CALL OMySQLUser::changePassword(const OUString& /*oldPassword*/,
268 const OUString& newPassword)
269{
270 ::osl::MutexGuard aGuard(m_aMutex);
271 checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed);
272 OUString sAlterPwd = "SET PASSWORD FOR " + m_Name + "@\"%\" = PASSWORD('" + newPassword + "')";
273
274 Reference<XStatement> xStmt = m_xConnection->createStatement();
275 if (xStmt.is())
276 {
277 xStmt->execute(sAlterPwd);
278 ::comphelper::disposeComponent(xStmt);
279 }
280}
281
282OUString OMySQLUser::getPrivilegeString(sal_Int32 nRights)
283{
284 OUString sPrivs;
285 if ((nRights & Privilege::INSERT) == Privilege::INSERT)
286 sPrivs += "INSERT";
287
288 if ((nRights & Privilege::DELETE) == Privilege::DELETE)
289 {
290 if (!sPrivs.isEmpty())
291 sPrivs += ",";
292 sPrivs += "DELETE";
293 }
294
295 if ((nRights & Privilege::UPDATE) == Privilege::UPDATE)
296 {
297 if (!sPrivs.isEmpty())
298 sPrivs += ",";
299 sPrivs += "UPDATE";
300 }
301
302 if ((nRights & Privilege::ALTER) == Privilege::ALTER)
303 {
304 if (!sPrivs.isEmpty())
305 sPrivs += ",";
306 sPrivs += "ALTER";
307 }
308
309 if ((nRights & Privilege::SELECT) == Privilege::SELECT)
310 {
311 if (!sPrivs.isEmpty())
312 sPrivs += ",";
313 sPrivs += "SELECT";
314 }
315
316 if ((nRights & Privilege::REFERENCE) == Privilege::REFERENCE)
317 {
318 if (!sPrivs.isEmpty())
319 sPrivs += ",";
320 sPrivs += "REFERENCES";
321 }
322
323 return sPrivs;
324}
325
326/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sSchema
OptionalString sCatalog
connectivity::sdbcx::OUser_BASE OUser_BASE_RBHELPER
Definition: YUser.cxx:81
::cppu::IPropertyArrayHelper * getArrayHelper()
void describeProperties(css::uno::Sequence< css::beans::Property > &_rProps) const
void registerProperty(const OUString &_rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void *_pPointerToMember, const css::uno::Type &_rMemberType)
::dbtools::OPropertyMap & getPropMap()
Definition: TConnection.cxx:68
helper class for accessing resources shared by different libraries in the connectivity module
OUString getResourceString(TranslateId pResId) const
loads a string from the shared resource file
virtual void refreshGroups() override
Definition: YUser.cxx:56
virtual void SAL_CALL revokePrivileges(const OUString &objName, sal_Int32 objType, sal_Int32 objPrivileges) override
Definition: YUser.cxx:238
virtual void SAL_CALL grantPrivileges(const OUString &objName, sal_Int32 objType, sal_Int32 objPrivileges) override
Definition: YUser.cxx:210
virtual sal_Int32 SAL_CALL getGrantablePrivileges(const OUString &objName, sal_Int32 objType) override
Definition: YUser.cxx:200
virtual sal_Int32 SAL_CALL getPrivileges(const OUString &objName, sal_Int32 objType) override
Definition: YUser.cxx:83
static OUString getPrivilegeString(sal_Int32 nRights)
Definition: YUser.cxx:282
OMySQLUser(css::uno::Reference< css::sdbc::XConnection > _xConnection)
Definition: YUser.cxx:41
void findPrivilegesAndGrantPrivileges(const OUString &objName, sal_Int32 objType, sal_Int32 &nRights, sal_Int32 &nRightsWithGrant)
Definition: YUser.cxx:93
virtual void SAL_CALL changePassword(const OUString &objPassword, const OUString &newPassword) override
Definition: YUser.cxx:267
css::uno::Reference< css::sdbc::XConnection > m_xConnection
Definition: YUser.hxx:31
virtual ::cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
virtual void construct() override
OUserExtend(const css::uno::Reference< css::sdbc::XConnection > &_xConnection)
virtual ::cppu::IPropertyArrayHelper * createArrayHelper() const override
mutable::osl::Mutex m_aMutex
::cppu::WeakComponentImplHelper< css::sdbcx::XUser, css::sdbcx::XGroupsSupplier, css::container::XNamed, css::lang::XServiceInfo > OUser_BASE
Definition: VUser.hxx:41
void checkDisposed(bool _bThrow)
Definition: dbtools.cxx:1951
OUString quoteTableName(const Reference< XDatabaseMetaData > &_rxMeta, const OUString &_rName, EComposeRule _eComposeRule)
Definition: dbtools.cxx:853
void qualifiedNameComponents(const Reference< XDatabaseMetaData > &_rxConnMetaData, const OUString &_rQualifiedName, OUString &_rCatalog, OUString &_rSchema, OUString &_rName, EComposeRule _eComposeRule)
Definition: dbtools.cxx:862
void throwGenericSQLException(const OUString &_rMsg, const css::uno::Reference< css::uno::XInterface > &_rxSource)
throw a generic SQLException, i.e.
Reference< XConnection > m_xConnection
#define PROPERTY_ID_PASSWORD
Definition: propertyids.hxx:74
OUString Name