[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3-desktop' - extensions/Library_WinUserInfoBe.mk extensions/Module_extensions.mk extensions/source officecfg/Package_misc.mk officecfg/registry postprocess/Rdb_services.mk Repository.mk

Mike Kaganski mike.kaganski at collabora.com
Mon May 7 20:08:19 UTC 2018


 Repository.mk                                                |    1 
 extensions/Library_WinUserInfoBe.mk                          |   42 
 extensions/Module_extensions.mk                              |    1 
 extensions/source/config/WinUserInfo/WinUserInfoBe.component |   15 
 extensions/source/config/WinUserInfo/WinUserInfoBe.cxx       |  477 +++++++++++
 extensions/source/config/WinUserInfo/WinUserInfoBe.hxx       |  115 ++
 extensions/source/config/WinUserInfo/componentdef.cxx        |   35 
 officecfg/Package_misc.mk                                    |    3 
 officecfg/registry/schema/oo-winuser.xcd.sample              |   95 ++
 officecfg/registry/schema/org/openoffice/UserProfile.xcs     |   11 
 postprocess/Rdb_services.mk                                  |    3 
 11 files changed, 798 insertions(+)

New commits:
commit 61e1cc419557144b0707abfa202fd53ff15c0c44
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Sat Apr 28 09:16:15 2018 +0300

    WinUserInfoBe: a new config backend for user data provided by Windows
    
    This backend provides Active Directory details for current user. If
    the system is not part of Active Directory domain, GetUserNameEx is
    used instead, so at least user (given) name is configured.
    
    Unlike ldap backend, this one doesn't need connection configuration,
    as the used API works with current user security context.
    
    Reviewed-on: https://gerrit.libreoffice.org/53590
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit f154f63cb662f02415d5cb0051011bdb5d0d523c)
    
    Change-Id: I74bcc79591a658dc5121df1f09caa15d272fbe12
    Reviewed-on: https://gerrit.libreoffice.org/53747
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/Repository.mk b/Repository.mk
index 1c72fc1abb61..a01bca514758 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -347,6 +347,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,ooo, \
     icg \
 	$(if $(ENABLE_JAVA),jdbc) \
 	ldapbe2 \
+	$(if $(filter WNT,$(OS)),WinUserInfoBe) \
 	localebe1 \
 	log \
 	lng \
diff --git a/extensions/Library_WinUserInfoBe.mk b/extensions/Library_WinUserInfoBe.mk
new file mode 100644
index 000000000000..e7160bbbabca
--- /dev/null
+++ b/extensions/Library_WinUserInfoBe.mk
@@ -0,0 +1,42 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#
+
+$(eval $(call gb_Library_Library,WinUserInfoBe))
+
+$(eval $(call gb_Library_set_componentfile,WinUserInfoBe,extensions/source/config/WinUserInfo/WinUserInfoBe))
+
+$(eval $(call gb_Library_use_sdk_api,WinUserInfoBe))
+
+$(eval $(call gb_Library_add_exception_objects,WinUserInfoBe,\
+	extensions/source/config/WinUserInfo/componentdef \
+	extensions/source/config/WinUserInfo/WinUserInfoBe \
+))
+
+$(eval $(call gb_Library_use_libraries,WinUserInfoBe,\
+	comphelper \
+	cppuhelper \
+	cppu \
+	sal \
+))
+
+$(eval $(call gb_Library_use_externals,WinUserInfoBe,\
+	boost_headers \
+))
+
+$(eval $(call gb_Library_use_system_win32_libs,WinUserInfoBe,\
+	Ole32 \
+	OleAut32 \
+	Activeds \
+	Adsiid \
+	Secur32 \
+))
+
+# vim:set noet sw=4 ts=4:
diff --git a/extensions/Module_extensions.mk b/extensions/Module_extensions.mk
index b322b833faac..68360ff43bee 100644
--- a/extensions/Module_extensions.mk
+++ b/extensions/Module_extensions.mk
@@ -25,6 +25,7 @@ ifneq ($(filter-out IOS ANDROID,$(OS)),)
 $(eval $(call gb_Module_add_targets,extensions,\
 	Library_abp \
 	Library_ldapbe2 \
+	$(if $(filter WNT,$(OS)),Library_WinUserInfoBe) \
 	Library_log \
 	Library_scn \
 ))
diff --git a/extensions/source/config/WinUserInfo/WinUserInfoBe.component b/extensions/source/config/WinUserInfo/WinUserInfoBe.component
new file mode 100644
index 000000000000..90c3e0060685
--- /dev/null
+++ b/extensions/source/config/WinUserInfo/WinUserInfoBe.component
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ -->
+
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+    prefix="WinUserInfoBe" xmlns="http://openoffice.org/2010/uno-components">
+  <implementation name="com.sun.star.comp.configuration.backend.WinUserInfoBe">
+    <service name="com.sun.star.configuration.backend.WinUserInfoBe"/>
+  </implementation>
+</component>
diff --git a/extensions/source/config/WinUserInfo/WinUserInfoBe.cxx b/extensions/source/config/WinUserInfo/WinUserInfoBe.cxx
new file mode 100644
index 000000000000..4c49c7259642
--- /dev/null
+++ b/extensions/source/config/WinUserInfo/WinUserInfoBe.cxx
@@ -0,0 +1,477 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "WinUserInfoBe.hxx"
+
+#include <com/sun/star/beans/Optional.hpp>
+#include <comphelper/configurationhelper.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <cppuhelper/supportsservice.hxx>
+#include <map>
+#include <sax/tools/converter.hxx>
+
+#include <Iads.h>
+#include <Adshlp.h>
+#include <Lmcons.h>
+#define SECURITY_WIN32
+#include <Security.h>
+
+namespace extensions
+{
+namespace config
+{
+namespace WinUserInfo
+{
+class WinUserInfoBe_Impl
+{
+public:
+    virtual ~WinUserInfoBe_Impl(){};
+    virtual OUString GetGivenName() = 0;
+    virtual OUString GetSn() { return ""; }
+    virtual OUString GetFathersname() { return ""; }
+    virtual OUString GetInitials() { return ""; }
+    virtual OUString GetStreet() { return ""; }
+    virtual OUString GetCity() { return ""; }
+    virtual OUString GetState() { return ""; }
+    virtual OUString GetApartment() { return ""; }
+    virtual OUString GetPostalCode() { return ""; }
+    virtual OUString GetCountry() { return ""; }
+    virtual OUString GetOrganization() { return ""; }
+    virtual OUString GetPosition() { return ""; }
+    virtual OUString GetTitle() { return ""; }
+    virtual OUString GetHomePhone() { return ""; }
+    virtual OUString GetTelephoneNumber() { return ""; }
+    virtual OUString GetFaxNumber() { return ""; }
+    virtual OUString GetMail() { return ""; }
+};
+}
+}
+}
+
+namespace
+{
+const char givenname[]("givenname");
+const char sn[]("sn");
+const char fathersname[]("fathersname");
+const char initials[]("initials");
+const char street[]("street");
+const char l[]("l");
+const char st[]("st");
+const char apartment[]("apartment");
+const char postalcode[]("postalcode");
+const char c[]("c");
+const char o[]("o");
+const char position[]("position");
+const char title[]("title");
+const char homephone[]("homephone");
+const char telephonenumber[]("telephonenumber");
+const char facsimiletelephonenumber[]("facsimiletelephonenumber");
+const char mail[]("mail");
+
+// Backend class implementing access to Active Directory user data. It caches its encoded data
+// in a configuration entry, to allow reusing it when user later doesn't have access to AD DC
+// (otherwise the user would get different data when connected vs not connected).
+class ADsUserAccess : public extensions::config::WinUserInfo::WinUserInfoBe_Impl
+{
+public:
+    ADsUserAccess(const css::uno::Reference<css::uno::XComponentContext>& xContext)
+    {
+        try
+        {
+            struct CoInitializeGuard
+            {
+                CoInitializeGuard()
+                {
+                    if (FAILED(CoInitialize(nullptr)))
+                        throw css::uno::RuntimeException();
+                }
+                ~CoInitializeGuard() { CoUninitialize(); }
+            } aCoInitializeGuard;
+
+            IADsADSystemInfo* pADsys;
+            HRESULT hr = CoCreateInstance(CLSID_ADSystemInfo, nullptr, CLSCTX_INPROC_SERVER,
+                                          IID_IADsADSystemInfo, (void**)&pADsys);
+            if (FAILED(hr))
+                throw css::uno::RuntimeException();
+            CoIfPtr<IADsADSystemInfo> aADsysGuard(pADsys);
+
+            BSTR sUserDN;
+            hr = pADsys->get_UserName(&sUserDN);
+            if (FAILED(hr))
+                throw css::uno::RuntimeException();
+            BSTRGuard aUserNameGuard(sUserDN, SysFreeString);
+            // If this user is an AD user, then without an active connection to the domain, all the
+            // above will succeed, and m_sUserDN will be correctly initialized, but the following
+            // call to ADsGetObject will fail, and we will attempt reading cached values.
+            m_sUserDN = reinterpret_cast<const sal_Unicode*>(sUserDN);
+            OUString sLdapUserDN = "LDAP://" + m_sUserDN;
+            IADsUser* pUser;
+            hr = ADsGetObject(reinterpret_cast<const wchar_t*>(sLdapUserDN.getStr()), IID_IADsUser, (void**)&pUser);
+            if (FAILED(hr))
+                throw css::uno::RuntimeException();
+            CoIfPtr<IADsUser> pUserGuard(pUser);
+            // Fetch all the required information right now, when we know to have access to AD
+            // (later the connection may already be lost)
+            m_aMap[givenname] = Str(pUser, &IADsUser::get_FirstName);
+            m_aMap[sn] = Str(pUser, &IADsUser::get_LastName);
+            m_aMap[initials] = Str(pUser, L"initials");
+            m_aMap[street] = Str(pUser, L"streetAddress");
+            m_aMap[l] = Str(pUser, L"l");
+            m_aMap[st] = Str(pUser, L"st");
+            m_aMap[postalcode] = Str(pUser, L"postalCode");
+            m_aMap[c] = Str(pUser, L"co");
+            m_aMap[o] = Str(pUser, L"company");
+            m_aMap[title] = Str(pUser, &IADsUser::get_Title);
+            m_aMap[homephone] = Str(pUser, L"homePhone");
+            m_aMap[telephonenumber] = Str(pUser, L"TelephoneNumber");
+            m_aMap[facsimiletelephonenumber] = Str(pUser, L"facsimileTelephoneNumber");
+            m_aMap[mail] = Str(pUser, &IADsUser::get_EmailAddress);
+
+            CacheData(xContext);
+        }
+        catch (css::uno::Exception&)
+        {
+            // Maybe we temporarily lost connection to AD; try to get cached data
+            GetCachedData(xContext);
+        }
+    }
+    ~ADsUserAccess() {}
+
+    virtual OUString GetGivenName() override { return m_aMap[givenname]; }
+    virtual OUString GetSn() override { return m_aMap[sn]; }
+    virtual OUString GetInitials() override { return m_aMap[initials]; }
+    virtual OUString GetStreet() override { return m_aMap[street]; }
+    virtual OUString GetCity() override { return m_aMap[l]; }
+    virtual OUString GetState() override { return m_aMap[st]; }
+    virtual OUString GetPostalCode() override { return m_aMap[postalcode]; }
+    virtual OUString GetCountry() override { return m_aMap[c]; }
+    virtual OUString GetOrganization() override { return m_aMap[o]; }
+    virtual OUString GetTitle() override { return m_aMap[title]; }
+    virtual OUString GetHomePhone() override { return m_aMap[homephone]; }
+    virtual OUString GetTelephoneNumber() override { return m_aMap[telephonenumber]; }
+    virtual OUString GetFaxNumber() override { return m_aMap[facsimiletelephonenumber]; }
+    virtual OUString GetMail() override { return m_aMap[mail]; }
+
+private:
+    static void ReleaseIUnknown(IUnknown* p)
+    {
+        if (p)
+            p->Release();
+    }
+    template <class If> class CoIfPtr : public std::unique_ptr<If, decltype(&ReleaseIUnknown)>
+    {
+    public:
+        CoIfPtr(If* p = nullptr)
+            : std::unique_ptr<If, decltype(&ReleaseIUnknown)>(p, ReleaseIUnknown)
+        {
+        }
+    };
+    typedef std::unique_ptr<OLECHAR, decltype(&SysFreeString)> BSTRGuard;
+
+    typedef HRESULT (__stdcall IADsUser::*getstrfunc)(BSTR*);
+    static OUString Str(IADsUser* pUser, getstrfunc func)
+    {
+        BSTR sBstr;
+        if (FAILED((pUser->*func)(&sBstr)))
+            return "";
+        BSTRGuard aBstrGuard(sBstr, SysFreeString);
+        return reinterpret_cast<const sal_Unicode*>(sBstr);
+    }
+    static OUString Str(IADsUser* pUser, const wchar_t* property)
+    {
+        BSTRGuard sBstrProp(SysAllocString(property), SysFreeString);
+        struct AutoVariant : public VARIANT
+        {
+            AutoVariant() { VariantInit(this); }
+            ~AutoVariant() { VariantClear(this); }
+        } varArr;
+        if (FAILED(pUser->GetEx(sBstrProp.get(), &varArr)))
+            return "";
+        SAFEARRAY* sa = V_ARRAY(&varArr);
+        LONG nStart, nEnd;
+        if (FAILED(SafeArrayGetLBound(sa, 1, &nStart)) || FAILED(SafeArrayGetUBound(sa, 1, &nEnd)))
+            return "";
+        AutoVariant varItem;
+        for (LONG i = nStart; i <= nEnd; i++)
+        {
+            if (FAILED(SafeArrayGetElement(sa, &i, &varItem)))
+                continue;
+            if (varItem.vt == VT_BSTR)
+                return reinterpret_cast<const sal_Unicode*>(V_BSTR(&varItem));
+            VariantClear(&varItem);
+        }
+        return "";
+    }
+
+    void CacheData(const css::uno::Reference<css::uno::XComponentContext>& xContext)
+    {
+        try
+        {
+            const OUString sNul('\0');
+            OUStringBuffer sCachedData(200);
+            sCachedData.append("user=" + m_sUserDN);
+            sCachedData.append(sNul + givenname + "=" + GetGivenName());
+            sCachedData.append(sNul + sn + "=" + GetSn());
+            sCachedData.append(sNul + initials + "=" + GetInitials());
+            sCachedData.append(sNul + street + "=" + GetStreet());
+            sCachedData.append(sNul + l + "=" + GetCity());
+            sCachedData.append(sNul + st + "=" + GetState());
+            sCachedData.append(sNul + postalcode + "=" + GetPostalCode());
+            sCachedData.append(sNul + c + "=" + GetCountry());
+            sCachedData.append(sNul + o + "=" + GetOrganization());
+            sCachedData.append(sNul + title + "=" + GetTitle());
+            sCachedData.append(sNul + homephone + "=" + GetHomePhone());
+            sCachedData.append(sNul + telephonenumber + "=" + GetTelephoneNumber());
+            sCachedData.append(sNul + facsimiletelephonenumber + "=" + GetFaxNumber());
+            sCachedData.append(sNul + mail + "=" + GetMail());
+            const css::uno::Sequence<sal_Int8> seqCachedData(
+                reinterpret_cast<const sal_Int8*>(sCachedData.getStr()),
+                sCachedData.getLength() * sizeof(sal_Unicode));
+            OUStringBuffer sOutBuf;
+            sax::Converter::encodeBase64(sOutBuf, seqCachedData);
+
+            auto xIface = comphelper::ConfigurationHelper::openConfig(
+                xContext, "org.openoffice.UserProfile/WinUserInfo",
+                comphelper::EConfigurationModes::Standard);
+            css::uno::Reference<css::container::XNameReplace> xNameReplace(
+                xIface, css::uno::UNO_QUERY_THROW);
+            xNameReplace->replaceByName("Cache", css::uno::makeAny(sOutBuf.makeStringAndClear()));
+
+            css::uno::Reference<css::util::XChangesBatch> xChangesBatch(xIface,
+                                                                        css::uno::UNO_QUERY_THROW);
+            xChangesBatch->commitChanges();
+        }
+        catch (const css::uno::Exception& e)
+        {
+            OSL_TRACE("ADsUserAccess: access to configuration data failed: %s",
+                OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
+        }
+    }
+
+    void GetCachedData(const css::uno::Reference<css::uno::XComponentContext>& xContext)
+    {
+        if (m_sUserDN.isEmpty())
+            throw css::uno::RuntimeException();
+
+        auto xIface = comphelper::ConfigurationHelper::openConfig(
+            xContext, "org.openoffice.UserProfile/WinUserInfo",
+            comphelper::EConfigurationModes::ReadOnly);
+        css::uno::Reference<css::container::XNameAccess> xNameAccess(xIface,
+                                                                     css::uno::UNO_QUERY_THROW);
+        OUString sCache;
+        xNameAccess->getByName("Cache") >>= sCache;
+        if (sCache.isEmpty())
+            throw css::uno::RuntimeException();
+
+        {
+            css::uno::Sequence<sal_Int8> seqCachedData;
+            sax::Converter::decodeBase64(seqCachedData, sCache);
+            sCache = OUString(reinterpret_cast<const sal_Unicode*>(seqCachedData.getConstArray()),
+                              seqCachedData.getLength() / sizeof(sal_Unicode));
+        }
+
+        OUString sUserDN;
+        std::map<const OUString, OUString> aMap;
+        sal_Int32 nIndex = 0;
+        do
+        {
+            const OUString sEntry = sCache.getToken(0, '\0', nIndex);
+            sal_Int32 nEqIndex = 0;
+            const OUString sEntryName = sEntry.getToken(0, '=', nEqIndex);
+            OUString sEntryVal;
+            if (nEqIndex >= 0)
+                sEntryVal = sEntry.copy(nEqIndex);
+            if (sEntryName == "user")
+                sUserDN = sEntryVal;
+            else
+                aMap[sEntryName] = sEntryVal;
+        } while (nIndex >= 0);
+
+        if (sUserDN != m_sUserDN)
+            throw css::uno::RuntimeException();
+        m_aMap = std::move(aMap);
+    }
+
+    OUString m_sUserDN; // used to check if the cached data is for current user
+    std::map<const OUString, OUString> m_aMap;
+};
+
+class SysInfoUserAccess : public extensions::config::WinUserInfo::WinUserInfoBe_Impl
+{
+public:
+    SysInfoUserAccess()
+    {
+        try
+        {
+            ULONG nSize = 0;
+            GetUserNameExW(NameDisplay, nullptr, &nSize);
+            if (GetLastError() != ERROR_MORE_DATA)
+                throw css::uno::RuntimeException();
+            std::unique_ptr<wchar_t[]> pNameBuf(new wchar_t[nSize]);
+            if (!GetUserNameExW(NameDisplay, pNameBuf.get(), &nSize))
+                throw css::uno::RuntimeException();
+            m_sName = reinterpret_cast<const sal_Unicode*>(pNameBuf.get());
+        }
+        catch (css::uno::RuntimeException&)
+        {
+            // GetUserNameEx may fail in some cases (e.g., for built-in AD domain
+            // administrator account on non-DC systems), where GetUserName will
+            // still give a name.
+            DWORD nSize = UNLEN + 1;
+            std::unique_ptr<wchar_t[]> pNameBuf(new wchar_t[nSize]);
+            if (!GetUserNameW(pNameBuf.get(), &nSize))
+                throw css::uno::RuntimeException();
+            m_sName = reinterpret_cast<const sal_Unicode*>(pNameBuf.get());
+        }
+    }
+
+    virtual OUString GetGivenName() override { return m_sName; }
+
+private:
+    OUString m_sName;
+};
+}
+
+namespace extensions
+{
+namespace config
+{
+namespace WinUserInfo
+{
+WinUserInfoBe::WinUserInfoBe(const css::uno::Reference<css::uno::XComponentContext>& xContext)
+    : WinUserInfoMutexHolder()
+    , BackendBase(mMutex)
+{
+    try
+    {
+        m_pImpl.reset(new ADsUserAccess(xContext));
+    }
+    catch (css::uno::RuntimeException&)
+    {
+        m_pImpl.reset(new SysInfoUserAccess);
+    }
+}
+
+WinUserInfoBe::~WinUserInfoBe() {}
+
+void WinUserInfoBe::setPropertyValue(OUString const&, css::uno::Any const&)
+{
+    throw css::lang::IllegalArgumentException("setPropertyValue not supported",
+                                              static_cast<cppu::OWeakObject*>(this), -1);
+}
+
+css::uno::Any WinUserInfoBe::getPropertyValue(OUString const& PropertyName)
+{
+    OUString sValue;
+    // Only process the first argument of possibly multiple space- or comma-separated arguments
+    OUString sToken = PropertyName.getToken(0, ' ').getToken(0, ',');
+    if (sToken == givenname)
+    {
+        sValue = m_pImpl->GetGivenName();
+    }
+    else if (sToken == sn)
+    {
+        sValue = m_pImpl->GetSn();
+    }
+    else if (sToken == fathersname)
+    {
+        sValue = m_pImpl->GetFathersname();
+    }
+    else if (sToken == initials)
+    {
+        sValue = m_pImpl->GetInitials();
+    }
+    else if (sToken == street)
+    {
+        sValue = m_pImpl->GetStreet();
+    }
+    else if (sToken == l)
+    {
+        sValue = m_pImpl->GetCity();
+    }
+    else if (sToken == st)
+    {
+        sValue = m_pImpl->GetState();
+    }
+    else if (sToken == apartment)
+    {
+        sValue = m_pImpl->GetApartment();
+    }
+    else if (sToken == postalcode)
+    {
+        sValue = m_pImpl->GetPostalCode();
+    }
+    else if (sToken == c)
+    {
+        sValue = m_pImpl->GetCountry();
+    }
+    else if (sToken == o)
+    {
+        sValue = m_pImpl->GetOrganization();
+    }
+    else if (sToken == position)
+    {
+        sValue = m_pImpl->GetPosition();
+    }
+    else if (sToken == title)
+    {
+        sValue = m_pImpl->GetTitle();
+    }
+    else if (sToken == homephone)
+    {
+        sValue = m_pImpl->GetHomePhone();
+    }
+    else if (sToken == telephonenumber)
+    {
+        sValue = m_pImpl->GetTelephoneNumber();
+    }
+    else if (sToken == facsimiletelephonenumber)
+    {
+        sValue = m_pImpl->GetFaxNumber();
+    }
+    else if (sToken == mail)
+    {
+        sValue = m_pImpl->GetMail();
+    }
+    else
+        throw css::beans::UnknownPropertyException(sToken, static_cast<cppu::OWeakObject*>(this));
+
+    return css::uno::makeAny(css::beans::Optional<css::uno::Any>(
+        !sValue.isEmpty(), sValue.isEmpty() ? css::uno::Any() : css::uno::makeAny(sValue)));
+}
+
+OUString WinUserInfoBe::getWinUserInfoBeName()
+{
+    return OUString("com.sun.star.comp.configuration.backend.WinUserInfoBe");
+}
+
+OUString SAL_CALL WinUserInfoBe::getImplementationName() { return getWinUserInfoBeName(); }
+
+css::uno::Sequence<OUString> WinUserInfoBe::getWinUserInfoBeServiceNames()
+{
+    css::uno::Sequence<OUString> aServices{ "com.sun.star.configuration.backend.WinUserInfoBe" };
+    return aServices;
+}
+
+sal_Bool SAL_CALL WinUserInfoBe::supportsService(const OUString& aServiceName)
+{
+    return cppu::supportsService(this, aServiceName);
+}
+
+css::uno::Sequence<OUString> SAL_CALL WinUserInfoBe::getSupportedServiceNames()
+{
+    return getWinUserInfoBeServiceNames();
+}
+}
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/config/WinUserInfo/WinUserInfoBe.hxx b/extensions/source/config/WinUserInfo/WinUserInfoBe.hxx
new file mode 100644
index 000000000000..766b88c41227
--- /dev/null
+++ b/extensions/source/config/WinUserInfo/WinUserInfoBe.hxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_EXTENSIONS_SOURCE_CONFIG_WINUSERINFO_WINUSERINFOBE_HXX
+#define INCLUDED_EXTENSIONS_SOURCE_CONFIG_WINUSERINFO_WINUSERINFOBE_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/compbase.hxx>
+#include <memory>
+
+namespace com
+{
+namespace sun
+{
+namespace star
+{
+namespace uno
+{
+class XComponentContext;
+}
+}
+}
+}
+
+namespace extensions
+{
+namespace config
+{
+namespace WinUserInfo
+{
+class WinUserInfoBe_Impl;
+
+typedef cppu::WeakComponentImplHelper<css::beans::XPropertySet, css::lang::XServiceInfo>
+    BackendBase;
+
+struct WinUserInfoMutexHolder
+{
+    osl::Mutex mMutex;
+};
+/**
+  Implements the PlatformBackend service, a specialization of the
+  XPropertySet service for retrieving Active Directory user profile
+  configuration settings.
+*/
+class WinUserInfoBe : private WinUserInfoMutexHolder, public BackendBase
+{
+public:
+    explicit WinUserInfoBe(const css::uno::Reference<css::uno::XComponentContext>& xContext);
+    virtual ~WinUserInfoBe() override;
+
+    // XServiceInfo
+    virtual OUString SAL_CALL getImplementationName() override;
+
+    virtual sal_Bool SAL_CALL supportsService(const OUString& aServiceName) override;
+
+    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+    // XPropertySet
+    virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override
+    {
+        return css::uno::Reference<css::beans::XPropertySetInfo>();
+    }
+
+    virtual void SAL_CALL setPropertyValue(OUString const&, css::uno::Any const&) override;
+
+    virtual css::uno::Any SAL_CALL getPropertyValue(OUString const& PropertyName) override;
+
+    virtual void SAL_CALL addPropertyChangeListener(
+        OUString const&, css::uno::Reference<css::beans::XPropertyChangeListener> const&) override
+    {
+    }
+
+    virtual void SAL_CALL removePropertyChangeListener(
+        OUString const&, css::uno::Reference<css::beans::XPropertyChangeListener> const&) override
+    {
+    }
+
+    virtual void SAL_CALL addVetoableChangeListener(
+        OUString const&, css::uno::Reference<css::beans::XVetoableChangeListener> const&) override
+    {
+    }
+
+    virtual void SAL_CALL removeVetoableChangeListener(
+        OUString const&, css::uno::Reference<css::beans::XVetoableChangeListener> const&) override
+    {
+    }
+
+    /**
+      Provides the implementation name.
+      @return   implementation name
+    */
+    static OUString getWinUserInfoBeName();
+    /**
+      Provides the supported services names
+      @return   service names
+    */
+    static css::uno::Sequence<OUString> getWinUserInfoBeServiceNames();
+
+private:
+    std::unique_ptr<WinUserInfoBe_Impl> m_pImpl;
+};
+}
+}
+}
+
+#endif // INCLUDED_EXTENSIONS_SOURCE_CONFIG_WINUSERINFO_WINUSERINFOBE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/config/WinUserInfo/componentdef.cxx b/extensions/source/config/WinUserInfo/componentdef.cxx
new file mode 100644
index 000000000000..7d8ff550445d
--- /dev/null
+++ b/extensions/source/config/WinUserInfo/componentdef.cxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "WinUserInfoBe.hxx"
+#include <cppuhelper/implementationentry.hxx>
+
+using namespace extensions::config::WinUserInfo;
+
+static css::uno::Reference<css::uno::XInterface>
+createWinUserInfoBe(const css::uno::Reference<css::uno::XComponentContext>& aContext)
+{
+    return *new WinUserInfoBe(aContext);
+}
+
+static const cppu::ImplementationEntry kImplementations_entries[]
+    = { { createWinUserInfoBe, WinUserInfoBe::getWinUserInfoBeName,
+          WinUserInfoBe::getWinUserInfoBeServiceNames, cppu::createSingleComponentFactory, nullptr,
+          0 },
+        { nullptr, nullptr, nullptr, nullptr, nullptr, 0 } };
+
+extern "C" SAL_DLLPUBLIC_EXPORT void*
+WinUserInfoBe_component_getFactory(const sal_Char* aImplementationName, void* aServiceManager,
+                                   void* aRegistryKey)
+{
+    return cppu::component_getFactoryHelper(aImplementationName, aServiceManager, aRegistryKey,
+                                            kImplementations_entries);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/officecfg/Package_misc.mk b/officecfg/Package_misc.mk
index bfe742c11423..f873586a1770 100644
--- a/officecfg/Package_misc.mk
+++ b/officecfg/Package_misc.mk
@@ -21,5 +21,8 @@ $(eval $(call gb_Package_Package,officecfg_misc,$(SRCDIR)/officecfg))
 
 $(eval $(call gb_Package_add_file,officecfg_misc,$(LIBO_SHARE_FOLDER)/registry/oo-ldap.xcd.sample,registry/schema/oo-ldap.xcd.sample))
 $(eval $(call gb_Package_add_file,officecfg_misc,$(LIBO_SHARE_FOLDER)/registry/oo-ad-ldap.xcd.sample,registry/schema/oo-ad-ldap.xcd.sample))
+ifeq ($(OS),WNT)
+$(eval $(call gb_Package_add_file,officecfg_misc,$(LIBO_SHARE_FOLDER)/registry/oo-winuser.xcd.sample,registry/schema/oo-winuser.xcd.sample))
+endif
 
 # vim: set noet sw=4 ts=4:
diff --git a/officecfg/registry/schema/oo-winuser.xcd.sample b/officecfg/registry/schema/oo-winuser.xcd.sample
new file mode 100644
index 000000000000..57c9b5b777c1
--- /dev/null
+++ b/officecfg/registry/schema/oo-winuser.xcd.sample
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+-->
+
+<!-- This is a fully functional configuration for WinUserInfo configuration backend.
+
+     Removing the ".sample" from the file name allows to get user data from Windows:
+     first, domain data (from Active Directory) is attempted; if unsuccessful, then
+     only given name is configured that is taken from system information.
+     In the latter case, display name (like "John Smith") would be used if present;
+     if it's not configured, then user logon name would be used.
+
+     Any properties that are not required to be set may be commented out as needed.
+-->
+
+<oor:data xmlns:oor="http://openoffice.org/2001/registry">
+  <dependency file="main"/>
+  <oor:component-data oor:package="org.openoffice" oor:name="UserProfile">
+    <node oor:name="Data">
+      <prop oor:name="o" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe o"/>
+      </prop>
+      <prop oor:name="givenname" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe givenname"/>
+      </prop>
+      <prop oor:name="sn" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe sn"/>
+      </prop>
+      <prop oor:name="initials" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe initials"/>
+      </prop>
+      <prop oor:name="street" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe street"/>
+      </prop>
+      <prop oor:name="l" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe l"/>
+      </prop>
+      <prop oor:name="st" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe st"/>
+      </prop>
+      <prop oor:name="postalcode" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe postalcode"/>
+      </prop>
+      <prop oor:name="c" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe c"/>
+      </prop>
+      <prop oor:name="title" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe title"/>
+      </prop>
+      <prop oor:name="position" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe position"/>
+      </prop>
+      <prop oor:name="homephone" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe homephone"/>
+      </prop>
+      <prop oor:name="telephonenumber" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe telephonenumber"/>
+      </prop>
+      <prop oor:name="facsimiletelephonenumber" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe facsimiletelephonenumber"/>
+      </prop>
+      <prop oor:name="mail" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe mail"/>
+      </prop>
+      <prop oor:name="fathersname" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe fathersname"/>
+      </prop>
+      <prop oor:name="apartment" oor:finalized="true">
+        <value oor:external=
+            "com.sun.star.configuration.backend.WinUserInfoBe apartment"/>
+      </prop>
+    </node>
+  </oor:component-data>
+</oor:data>
diff --git a/officecfg/registry/schema/org/openoffice/UserProfile.xcs b/officecfg/registry/schema/org/openoffice/UserProfile.xcs
index 4398968b8774..fe581285bc4f 100644
--- a/officecfg/registry/schema/org/openoffice/UserProfile.xcs
+++ b/officecfg/registry/schema/org/openoffice/UserProfile.xcs
@@ -200,5 +200,16 @@
         <value/>
       </prop>
     </group>
+    <group oor:name="WinUserInfo">
+      <info>
+        <desc>Contains user information cached from Active Directory.</desc>
+      </info>
+      <prop oor:name="Cache" oor:type="xs:string" oor:nillable="false">
+        <info>
+          <desc>Cache data.</desc>
+        </info>
+        <value/>
+      </prop>
+    </group>
   </component>
 </oor:component-schema>
diff --git a/postprocess/Rdb_services.mk b/postprocess/Rdb_services.mk
index 9fce3c6c37f5..80d599aa834b 100644
--- a/postprocess/Rdb_services.mk
+++ b/postprocess/Rdb_services.mk
@@ -303,6 +303,9 @@ $(eval $(call gb_Rdb_add_components,services,\
 	$(if $(ENABLE_HEADLESS),,desktop/source/splash/spl) \
 	extensions/source/abpilot/abp \
 	extensions/source/config/ldap/ldapbe2 \
+	$(if $(filter WNT,$(OS)),\
+		extensions/source/config/WinUserInfo/WinUserInfoBe \
+	) \
 	extensions/source/logging/log \
 	extensions/source/resource/res \
 	extensions/source/scanner/scn \


More information about the Libreoffice-commits mailing list