1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 
27 #include "ldapaccess.hxx"
28 #include "ldapuserprofilebe.hxx"
29 #include <osl/file.hxx>
30 #include <osl/module.hxx>
31 #include <osl/process.h>
32 #include <rtl/ustrbuf.hxx>
33 #include <rtl/byteseq.h>
34 
35 #ifndef INCLUDED_RTL_INSTANCE_HXX_
36 #include <rtl/instance.hxx>
37 #endif
38 #include <com/sun/star/beans/NamedValue.hpp>
39 #include <com/sun/star/beans/Optional.hpp>
40 #include <osl/security.hxx>
41 
42 //==============================================================================
43 namespace extensions { namespace config { namespace ldap {
44 
LdapUserProfileBe(const uno::Reference<uno::XComponentContext> & xContext)45 LdapUserProfileBe::LdapUserProfileBe( const uno::Reference<uno::XComponentContext>& xContext)
46 : LdapProfileMutexHolder(),
47   BackendBase(mMutex)
48 {
49     LdapDefinition aDefinition;
50     rtl::OUString loggedOnUser;
51 
52     // This whole rigmarole is to prevent an infinite recursion where reading
53     // the configuration for the backend would create another instance of the
54     // backend, which would try and read the configuration which would...
55     {
56         osl::Mutex & aInitMutex = rtl::Static< osl::Mutex, LdapUserProfileBe >::get();
57         osl::MutexGuard aInitGuard(aInitMutex);
58 
59         static bool bReentrantCall; // = false
60         OSL_ENSURE(!bReentrantCall, "configuration: Ldap Backend constructor called reentrantly - probably a registration error.");
61 
62         if (!bReentrantCall)
63         {
64             try
65             {
66                 bReentrantCall = true ;
67                 if (!readLdapConfiguration(
68                         css::uno::Reference< css::lang::XMultiServiceFactory >(
69                             xContext->getServiceManager(),
70                             css::uno::UNO_QUERY_THROW),
71                         &aDefinition, &loggedOnUser))
72                 {
73                     throw css::uno::RuntimeException(
74                         rtl::OUString::createFromAscii("LdapUserProfileBe- LDAP not configured"),
75                         NULL);
76                 }
77 
78                 bReentrantCall = false ;
79             }
80             catch (...)
81             {
82                 bReentrantCall = false;
83                 throw;
84             }
85         }
86     }
87 
88     LdapConnection connection;
89     connection.loadModule();
90     connection.connectSimple(aDefinition);
91     connection.getUserProfile(loggedOnUser, &data_);
92 }
93 //------------------------------------------------------------------------------
~LdapUserProfileBe()94 LdapUserProfileBe::~LdapUserProfileBe()
95 {
96 }
97 //------------------------------------------------------------------------------
98 
readLdapConfiguration(css::uno::Reference<css::lang::XMultiServiceFactory> const & factory,LdapDefinition * definition,rtl::OUString * loggedOnUser)99 bool LdapUserProfileBe::readLdapConfiguration(
100     css::uno::Reference< css::lang::XMultiServiceFactory > const & factory,
101     LdapDefinition * definition, rtl::OUString * loggedOnUser)
102 {
103     OSL_ASSERT(factory.is() && definition != 0 && loggedOnUser != 0);
104     const rtl::OUString kConfigurationProviderService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider")) ;
105     const rtl::OUString kReadOnlyViewService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")) ;
106     const rtl::OUString kComponent( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.LDAP/UserDirectory"));
107     const rtl::OUString kServerDefiniton(RTL_CONSTASCII_USTRINGPARAM ("ServerDefinition"));
108     const rtl::OUString kServer(RTL_CONSTASCII_USTRINGPARAM ("Server"));
109     const rtl::OUString kPort(RTL_CONSTASCII_USTRINGPARAM("Port"));
110     const rtl::OUString kBaseDN(RTL_CONSTASCII_USTRINGPARAM("BaseDN"));
111     const rtl::OUString kUser(RTL_CONSTASCII_USTRINGPARAM("SearchUser"));
112     const rtl::OUString kPassword(RTL_CONSTASCII_USTRINGPARAM("SearchPassword"));
113     const rtl::OUString kUserObjectClass(RTL_CONSTASCII_USTRINGPARAM("UserObjectClass"));
114     const rtl::OUString kUserUniqueAttr(RTL_CONSTASCII_USTRINGPARAM("UserUniqueAttribute"));
115 
116 	uno::Reference< XInterface > xIface;
117     try
118     {
119         uno::Reference< lang::XMultiServiceFactory > xCfgProvider(
120                                                         factory->createInstance(kConfigurationProviderService),
121                                                         uno::UNO_QUERY);
122 	    OSL_ENSURE(xCfgProvider.is(),"LdapUserProfileBe: could not create the configuration provider");
123 	    if (!xCfgProvider.is())
124             return false;
125 
126         css::beans::NamedValue aPath(rtl::OUString::createFromAscii("nodepath"), uno::makeAny(kComponent) );
127 
128         uno::Sequence< uno::Any > aArgs(1);
129         aArgs[0] <<=  aPath;
130 
131         xIface = xCfgProvider->createInstanceWithArguments(kReadOnlyViewService, aArgs);
132 
133         uno::Reference<container::XNameAccess > xAccess(xIface, uno::UNO_QUERY_THROW);
134         xAccess->getByName(kServerDefiniton) >>= xIface;
135 
136         uno::Reference<container::XNameAccess > xChildAccess(xIface, uno::UNO_QUERY_THROW);
137 
138         if (!getLdapStringParam(xChildAccess, kServer, definition->mServer))
139             return false;
140         if (!getLdapStringParam(xChildAccess, kBaseDN, definition->mBaseDN))
141             return false;
142 
143         definition->mPort=0;
144         xChildAccess->getByName(kPort) >>= definition->mPort ;
145 	    if (definition->mPort == 0)
146 		    return false;
147 
148         if (!getLdapStringParam(xAccess, kUserObjectClass, definition->mUserObjectClass))
149             return false;
150         if (!getLdapStringParam(xAccess, kUserUniqueAttr, definition->mUserUniqueAttr))
151             return false;
152 
153         getLdapStringParam(xAccess, kUser, definition->mAnonUser);
154         getLdapStringParam(xAccess, kPassword, definition->mAnonCredentials);
155     }
156     catch (uno::Exception & e)
157     {
158         OSL_TRACE("LdapUserProfileBackend: access to configuration data failed: %s",
159                 rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
160         return false;
161     }
162 
163     osl::Security aSecurityContext;
164 	if (!aSecurityContext.getUserName(*loggedOnUser))
165 		OSL_TRACE("LdapUserProfileBackend - could not get Logged on user from system");
166 
167     sal_Int32 nIndex = loggedOnUser->indexOf('/');
168 	if (nIndex > 0)
169 		*loggedOnUser = loggedOnUser->copy(nIndex+1);
170 
171     //Remember to remove
172     OSL_TRACE("Logged on user is %s", rtl::OUStringToOString(*loggedOnUser,RTL_TEXTENCODING_ASCII_US).getStr());
173 
174     return true;
175 }
176 
177 //------------------------------------------------------------------------------
getLdapStringParam(uno::Reference<container::XNameAccess> & xAccess,const rtl::OUString & aLdapSetting,rtl::OString & aServerParameter)178 bool LdapUserProfileBe::getLdapStringParam(
179 	uno::Reference<container::XNameAccess>& xAccess,
180 	const rtl::OUString& aLdapSetting,
181 	rtl::OString& aServerParameter)
182 {
183     rtl::OUString sParam;
184     xAccess->getByName(aLdapSetting) >>= sParam;
185     aServerParameter = rtl::OUStringToOString(sParam, RTL_TEXTENCODING_ASCII_US);
186 
187     return aServerParameter.getLength() != 0;
188 }
189 //------------------------------------------------------------------------------
setPropertyValue(rtl::OUString const &,css::uno::Any const &)190 void LdapUserProfileBe::setPropertyValue(
191     rtl::OUString const &, css::uno::Any const &)
192     throw (
193         css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
194         css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
195         css::uno::RuntimeException)
196 {
197     throw css::lang::IllegalArgumentException(
198         rtl::OUString(
199             RTL_CONSTASCII_USTRINGPARAM("setPropertyValue not supported")),
200         static_cast< cppu::OWeakObject * >(this), -1);
201 }
202 
getPropertyValue(rtl::OUString const & PropertyName)203 css::uno::Any LdapUserProfileBe::getPropertyValue(
204     rtl::OUString const & PropertyName)
205     throw (
206         css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
207         css::uno::RuntimeException)
208 {
209     for (sal_Int32 i = 0;;) {
210         sal_Int32 j = PropertyName.indexOf(',', i);
211         if (j == -1) {
212             j = PropertyName.getLength();
213         }
214         if (j == i) {
215             throw css::beans::UnknownPropertyException(
216                 PropertyName, static_cast< cppu::OWeakObject * >(this));
217         }
218         LdapData::iterator k(data_.find(PropertyName.copy(i, j - i)));
219         if (k != data_.end()) {
220             return css::uno::makeAny(
221                 css::beans::Optional< css::uno::Any >(
222                     true, css::uno::makeAny(k->second)));
223         }
224         if (j == PropertyName.getLength()) {
225             break;
226         }
227         i = j + 1;
228     }
229     return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
230 }
231 
232 //------------------------------------------------------------------------------
getLdapUserProfileBeName(void)233 rtl::OUString SAL_CALL LdapUserProfileBe::getLdapUserProfileBeName(void) {
234 	return rtl::OUString::createFromAscii("com.sun.star.comp.configuration.backend.LdapUserProfileBe") ;
235 }
236 //------------------------------------------------------------------------------
237 
getImplementationName(void)238 rtl::OUString SAL_CALL LdapUserProfileBe::getImplementationName(void)
239     throw (uno::RuntimeException)
240 {
241     return getLdapUserProfileBeName() ;
242 }
243 //------------------------------------------------------------------------------
244 
getLdapUserProfileBeServiceNames(void)245 uno::Sequence<rtl::OUString> SAL_CALL LdapUserProfileBe::getLdapUserProfileBeServiceNames(void)
246 {
247     uno::Sequence<rtl::OUString> aServices(1) ;
248     aServices[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.LdapUserProfileBe")) ;
249     return aServices ;
250 }
251 //------------------------------------------------------------------------------
252 
supportsService(const rtl::OUString & aServiceName)253 sal_Bool SAL_CALL LdapUserProfileBe::supportsService(const rtl::OUString& aServiceName)
254     throw (uno::RuntimeException)
255 {
256     uno::Sequence< rtl::OUString > const svc = getLdapUserProfileBeServiceNames();
257 
258 	for(sal_Int32 i = 0; i < svc.getLength(); ++i )
259 		if(svc[i] == aServiceName)
260 			return true;
261 	return false;
262 }
263 
264 //------------------------------------------------------------------------------
265 
266 uno::Sequence<rtl::OUString>
getSupportedServiceNames(void)267 SAL_CALL LdapUserProfileBe::getSupportedServiceNames(void)
268     throw (uno::RuntimeException)
269 {
270     return getLdapUserProfileBeServiceNames() ;
271 }
272 // ---------------------------------------------------------------------------------------
273 }}}
274 // ---------------------------------------------------------------------------------------
275 
276 
277