summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am39
-rw-r--r--configure.ac1
-rw-r--r--contrib/sssd.spec.in26
-rw-r--r--src/sss_client/libwbclient/libwbclient.h46
-rw-r--r--src/sss_client/libwbclient/wbc_err_internal.h44
-rw-r--r--src/sss_client/libwbclient/wbc_guid.c100
-rw-r--r--src/sss_client/libwbclient/wbc_idmap_common.c89
-rw-r--r--src/sss_client/libwbclient/wbc_idmap_sssd.c205
-rw-r--r--src/sss_client/libwbclient/wbc_pam_sssd.c147
-rw-r--r--src/sss_client/libwbclient/wbc_pwd_sssd.c659
-rw-r--r--src/sss_client/libwbclient/wbc_sid_common.c199
-rw-r--r--src/sss_client/libwbclient/wbc_sid_sssd.c283
-rw-r--r--src/sss_client/libwbclient/wbc_sssd_internal.h41
-rw-r--r--src/sss_client/libwbclient/wbc_util_common.c97
-rw-r--r--src/sss_client/libwbclient/wbc_util_sssd.c160
-rw-r--r--src/sss_client/libwbclient/wbclient.exports90
-rw-r--r--src/sss_client/libwbclient/wbclient.h1372
-rw-r--r--src/sss_client/libwbclient/wbclient.pc.in11
-rw-r--r--src/sss_client/libwbclient/wbclient_common.c178
-rw-r--r--src/sss_client/libwbclient/wbclient_internal.h44
-rw-r--r--src/sss_client/libwbclient/wbclient_sssd.c40
-rw-r--r--src/tests/dlopen-tests.c1
22 files changed, 3870 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 670771105..4c3dc35d2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -574,6 +574,10 @@ dist_noinst_HEADERS = \
src/tests/cmocka/common_mock_sysdb_objects.h \
src/sss_client/ssh/sss_ssh_client.h \
src/sss_client/sudo/sss_sudo.h \
+ src/sss_client/libwbclient/libwbclient.h \
+ src/sss_client/libwbclient/wbc_err_internal.h \
+ src/sss_client/libwbclient/wbclient_internal.h \
+ src/sss_client/libwbclient/wbc_sssd_internal.h \
src/lib/idmap/sss_idmap_private.h \
src/lib/sifp/sss_sifp_private.h \
src/tests/cmocka/test_utils.h \
@@ -718,7 +722,12 @@ libsss_config_la_LDFLAGS = \
endif # BUILD_CONFIG_LIB
endif # BUILD_IFP
-lib_LTLIBRARIES = libipa_hbac.la libsss_idmap.la libsss_nss_idmap.la
+lib_LTLIBRARIES = libipa_hbac.la \
+ libsss_idmap.la \
+ libsss_nss_idmap.la \
+ libwbclient.la \
+ $(NULL)
+
pkgconfig_DATA += src/providers/ipa/ipa_hbac.pc
libipa_hbac_la_DEPENDENCIES = src/providers/ipa/ipa_hbac.exports
libipa_hbac_la_SOURCES = \
@@ -758,11 +767,37 @@ libsss_nss_idmap_la_LDFLAGS = \
dist_noinst_DATA += src/sss_client/idmap/sss_nss_idmap.exports
+pkgconfig_DATA += src/sss_client/libwbclient/wbclient.pc
+EXTRA_libwbclient_la_DEPENDENCIES = src/sss_client/libwbclient/wbclient.exports
+libwbclient_la_SOURCES = \
+ src/sss_client/libwbclient/wbc_guid.c \
+ src/sss_client/libwbclient/wbc_idmap_common.c \
+ src/sss_client/libwbclient/wbc_idmap_sssd.c \
+ src/sss_client/libwbclient/wbclient_common.c \
+ src/sss_client/libwbclient/wbclient_sssd.c \
+ src/sss_client/libwbclient/wbc_pam_sssd.c \
+ src/sss_client/libwbclient/wbc_pwd_sssd.c \
+ src/sss_client/libwbclient/wbc_sid_common.c \
+ src/sss_client/libwbclient/wbc_sid_sssd.c \
+ src/sss_client/libwbclient/wbc_sssd_internal.h \
+ src/sss_client/libwbclient/wbc_util_common.c \
+ src/sss_client/libwbclient/wbc_util_sssd.c
+libwbclient_la_LIBADD = \
+ libsss_nss_idmap.la \
+ $(CLIENT_LIBS)
+libwbclient_la_LDFLAGS = \
+ -Wl,--version-script,$(srcdir)/src/sss_client/libwbclient/wbclient.exports \
+ -version-info 11:0:11
+
+dist_noinst_DATA += src/sss_client/libwbclient/wbclient.exports
+
include_HEADERS = \
src/providers/ipa/ipa_hbac.h \
src/lib/idmap/sss_idmap.h \
- src/sss_client/idmap/sss_nss_idmap.h
+ src/sss_client/idmap/sss_nss_idmap.h \
+ src/sss_client/libwbclient/wbclient.h \
+ $(NULL)
if BUILD_IFP
lib_LTLIBRARIES += libsss_simpleifp.la
diff --git a/configure.ac b/configure.ac
index 38654219b..d20cb9ca2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -323,6 +323,7 @@ AC_CONFIG_FILES([Makefile contrib/sssd.spec src/examples/rwtab src/doxy.config
src/sss_client/sudo/sss_sudo.doxy
src/sss_client/idmap/sss_nss_idmap.pc
src/sss_client/idmap/sss_nss_idmap.doxy
+ src/sss_client/libwbclient/wbclient.pc
src/lib/sifp/sss_simpleifp.pc
src/lib/sifp/sss_simpleifp.doxy
src/config/setup.py
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 1429c263d..770a0c7d6 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -427,6 +427,22 @@ Requires: libsss_simpleifp = %{version}-%{release}
%description -n libsss_simpleifp-devel
Provides library that simplifies D-Bus API for the SSSD InfoPipe responder.
+%package libwbclient
+Summary: The SSSD libwbclient implementation
+Group: Applications/System
+License: GPLv3+ and LGPLv3+
+
+%description libwbclient
+The SSSD libwbclient implementation.
+
+%package libwbclient-devel
+Summary: Development libraries for the SSSD libwbclient implementation
+Group: Development/Libraries
+License: GPLv3+ and LGPLv3+
+
+%description libwbclient-devel
+Development libraries for the SSSD libwbclient implementation.
+
%prep
%setup -q -n %{name}-%{version}
@@ -821,6 +837,16 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root,-)
%{python_sitearch}/pyhbac.so
+%files libwbclient
+%defattr(-,root,root,-)
+%{_libdir}/libwbclient.so.*
+
+%files libwbclient-devel
+%defattr(-,root,root,-)
+%{_includedir}/wbclient.h
+%{_libdir}/libwbclient.so
+%{_libdir}/pkgconfig/wbclient.pc
+
%if (0%{?use_systemd} == 1)
# systemd
%post common
diff --git a/src/sss_client/libwbclient/libwbclient.h b/src/sss_client/libwbclient/libwbclient.h
new file mode 100644
index 000000000..79d9be280
--- /dev/null
+++ b/src/sss_client/libwbclient/libwbclient.h
@@ -0,0 +1,46 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API
+
+ Copyright (C) Gerald (Jerry) Carter 2007
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _LIBWBCLIENT_H
+#define _LIBWBCLIENT_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* Super header including necessary public and private header files
+ for building the wbclient library. __DO NOT__ define anything
+ in this file. Only include other headers. */
+
+/* Public headers */
+
+#include "wbclient.h"
+
+/* Private headers */
+
+#include "wbc_err_internal.h"
+#include "wbclient_internal.h"
+
+
+#endif /* _LIBWBCLIENT_H */
diff --git a/src/sss_client/libwbclient/wbc_err_internal.h b/src/sss_client/libwbclient/wbc_err_internal.h
new file mode 100644
index 000000000..65970a9fe
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_err_internal.h
@@ -0,0 +1,44 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API
+
+ Copyright (C) Gerald (Jerry) Carter 2007
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WBC_ERR_INTERNAL_H
+#define _WBC_ERR_INTERNAL_H
+
+/* Private macros */
+
+#define BAIL_ON_WBC_ERROR(x) \
+ do { \
+ if (!WBC_ERROR_IS_OK(x)) { \
+ goto done; \
+ } \
+ } while(0)
+
+#define BAIL_ON_PTR_ERROR(x, status) \
+ do { \
+ if ((x) == NULL) { \
+ status = WBC_ERR_NO_MEMORY; \
+ goto done; \
+ } else { \
+ status = WBC_ERR_SUCCESS; \
+ } \
+ } while (0)
+
+#endif /* _WBC_ERR_INTERNAL_H */
diff --git a/src/sss_client/libwbclient/wbc_guid.c b/src/sss_client/libwbclient/wbc_guid.c
new file mode 100644
index 000000000..22f772508
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_guid.c
@@ -0,0 +1,100 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API
+
+ Copyright (C) Gerald (Jerry) Carter 2007
+
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Required Headers */
+
+#include "libwbclient.h"
+
+/* Convert a binary GUID to a character string */
+wbcErr wbcGuidToString(const struct wbcGuid *guid,
+ char **guid_string)
+{
+ char *result;
+
+ result = (char *)wbcAllocateMemory(37, 1, NULL);
+ if (result == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+ snprintf(result, 37,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ guid->time_low, guid->time_mid,
+ guid->time_hi_and_version,
+ guid->clock_seq[0],
+ guid->clock_seq[1],
+ guid->node[0], guid->node[1],
+ guid->node[2], guid->node[3],
+ guid->node[4], guid->node[5]);
+ *guid_string = result;
+
+ return WBC_ERR_SUCCESS;
+}
+
+/* @brief Convert a character string to a binary GUID */
+wbcErr wbcStringToGuid(const char *str,
+ struct wbcGuid *guid)
+{
+ uint32_t time_low;
+ uint32_t time_mid, time_hi_and_version;
+ uint32_t clock_seq[2];
+ uint32_t node[6];
+ int i;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+
+ if (!guid) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (!str) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (11 == sscanf(str, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ &time_low, &time_mid, &time_hi_and_version,
+ &clock_seq[0], &clock_seq[1],
+ &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
+ wbc_status = WBC_ERR_SUCCESS;
+ } else if (11 == sscanf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ &time_low, &time_mid, &time_hi_and_version,
+ &clock_seq[0], &clock_seq[1],
+ &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
+ wbc_status = WBC_ERR_SUCCESS;
+ }
+
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ guid->time_low = time_low;
+ guid->time_mid = time_mid;
+ guid->time_hi_and_version = time_hi_and_version;
+ guid->clock_seq[0] = clock_seq[0];
+ guid->clock_seq[1] = clock_seq[1];
+
+ for (i=0;i<6;i++) {
+ guid->node[i] = node[i];
+ }
+
+ wbc_status = WBC_ERR_SUCCESS;
+
+done:
+ return wbc_status;
+}
diff --git a/src/sss_client/libwbclient/wbc_idmap_common.c b/src/sss_client/libwbclient/wbc_idmap_common.c
new file mode 100644
index 000000000..ef30d27c4
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_idmap_common.c
@@ -0,0 +1,89 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API
+
+ Copyright (C) Gerald (Jerry) Carter 2007
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Required Headers */
+
+#include "libwbclient.h"
+
+/* Convert a Windows SID to a Unix uid if there already is a mapping */
+wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
+ uid_t *puid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/* Convert a Unix uid to a Windows SID if there already is a mapping */
+wbcErr wbcQueryUidToSid(uid_t uid,
+ struct wbcDomainSid *sid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/* Convert a Windows SID to a Unix gid if there already is a mapping */
+wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
+ gid_t *pgid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+
+/* Convert a Unix gid to a Windows SID if there already is a mapping */
+wbcErr wbcQueryGidToSid(gid_t gid,
+ struct wbcDomainSid *sid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/* Set an user id mapping - not implemented any more */
+wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/* Set a group id mapping - not implemented any more */
+wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/* Remove a user id mapping - not implemented any more */
+wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/* Remove a group id mapping - not implemented any more */
+wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/* Set the highwater mark for allocated uids - not implemented any more */
+wbcErr wbcSetUidHwm(uid_t uid_hwm)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/* Set the highwater mark for allocated gids - not implemented any more */
+wbcErr wbcSetGidHwm(gid_t gid_hwm)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
diff --git a/src/sss_client/libwbclient/wbc_idmap_sssd.c b/src/sss_client/libwbclient/wbc_idmap_sssd.c
new file mode 100644
index 000000000..1b0e2e10a
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_idmap_sssd.c
@@ -0,0 +1,205 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API - SSSD version
+
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2014
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Required Headers */
+
+#include "sss_client/idmap/sss_nss_idmap.h"
+
+#include "libwbclient.h"
+#include "wbc_sssd_internal.h"
+
+/* Convert a Windows SID to a Unix uid, allocating an uid if needed */
+wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
+{
+ int ret;
+ char *sid_str;
+ uint32_t id;
+ enum sss_id_type type;
+ wbcErr wbc_status;
+
+ wbc_status = wbcSidToString(sid, &sid_str);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ ret = sss_nss_getidbysid(sid_str, &id, &type);
+ wbcFreeMemory(sid_str);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ if (type != SSS_ID_TYPE_UID && type != SSS_ID_TYPE_BOTH) {
+ return WBC_ERR_UNKNOWN_GROUP;
+ }
+
+ *puid = (uid_t) id;
+
+ return WBC_ERR_SUCCESS;
+}
+
+/* Convert a Unix uid to a Windows SID, allocating a SID if needed */
+wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid)
+{
+ int ret;
+ char *str_sid;
+ enum sss_id_type type;
+ wbcErr wbc_status;
+
+ ret = sss_nss_getsidbyid(uid, &str_sid, &type);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ if (type != SSS_ID_TYPE_UID && type != SSS_ID_TYPE_BOTH) {
+ free(str_sid);
+ return WBC_ERR_UNKNOWN_USER;
+ }
+
+ wbc_status = wbcStringToSid(str_sid, sid);
+ free(str_sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ return WBC_ERR_SUCCESS;
+}
+
+/** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
+ *
+ * @param *sid Pointer to the domain SID to be resolved
+ * @param *pgid Pointer to the resolved gid_t value
+ *
+ * @return #wbcErr
+ *
+ **/
+
+wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
+{
+ int ret;
+ char *sid_str;
+ uint32_t id;
+ enum sss_id_type type;
+ wbcErr wbc_status;
+
+ wbc_status = wbcSidToString(sid, &sid_str);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ ret = sss_nss_getidbysid(sid_str, &id, &type);
+ wbcFreeMemory(sid_str);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ if (type != SSS_ID_TYPE_GID && type != SSS_ID_TYPE_BOTH) {
+ return WBC_ERR_UNKNOWN_GROUP;
+ }
+
+ *pgid = (gid_t) id;
+
+ return WBC_ERR_SUCCESS;
+}
+
+/* Convert a Unix gid to a Windows SID, allocating a SID if needed */
+wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid)
+{
+ int ret;
+ char *str_sid;
+ enum sss_id_type type;
+ wbcErr wbc_status;
+
+ ret = sss_nss_getsidbyid(gid, &str_sid, &type);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ if (type != SSS_ID_TYPE_GID && type != SSS_ID_TYPE_BOTH) {
+ free(str_sid);
+ return WBC_ERR_UNKNOWN_USER;
+ }
+
+ wbc_status = wbcStringToSid(str_sid, sid);
+ free(str_sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ return WBC_ERR_SUCCESS;
+}
+
+/* Obtain a new uid from Winbind */
+wbcErr wbcAllocateUid(uid_t *puid)
+{
+ /* Not supported by SSSD */
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Obtain a new gid from Winbind */
+wbcErr wbcAllocateGid(gid_t *pgid)
+{
+ /* Not supported by SSSD */
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Convert a list of SIDs */
+wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
+ struct wbcUnixId *ids)
+{
+ int ret;
+ char *sid_str;
+ uint32_t id;
+ enum sss_id_type type;
+ size_t c;
+ wbcErr wbc_status;
+
+ for (c = 0; c < num_sids; c++) {
+ wbc_status = wbcSidToString(&sids[c], &sid_str);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ ret = sss_nss_getidbysid(sid_str, &id, &type);
+ wbcFreeMemory(sid_str);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ switch (type) {
+ case SSS_ID_TYPE_UID:
+ ids[c].type = WBC_ID_TYPE_UID;
+ ids[c].id.uid = (uid_t) id;
+ break;
+ case SSS_ID_TYPE_GID:
+ ids[c].type = WBC_ID_TYPE_GID;
+ ids[c].id.gid = (gid_t) id;
+ break;
+ case SSS_ID_TYPE_BOTH:
+ ids[c].type = WBC_ID_TYPE_BOTH;
+ ids[c].id.uid = (uid_t) id;
+ break;
+ default:
+ ids[c].type = WBC_ID_TYPE_NOT_SPECIFIED;
+ }
+ }
+
+ return WBC_ERR_SUCCESS;
+}
diff --git a/src/sss_client/libwbclient/wbc_pam_sssd.c b/src/sss_client/libwbclient/wbc_pam_sssd.c
new file mode 100644
index 000000000..893a5c16c
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_pam_sssd.c
@@ -0,0 +1,147 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API - SSSD version
+
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2014
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Required Headers */
+#include "libwbclient.h"
+#include "wbc_sssd_internal.h"
+
+/* Authenticate a username/password pair */
+wbcErr wbcAuthenticateUser(const char *username,
+ const char *password)
+{
+ wbcErr wbc_status = WBC_ERR_SUCCESS;
+ struct wbcAuthUserParams params = {0};
+
+ params.account_name = username;
+ params.level = WBC_AUTH_USER_LEVEL_PLAIN;
+ params.password.plaintext = password;
+
+ wbc_status = wbcAuthenticateUserEx(&params, NULL, NULL);
+
+ return wbc_status;
+}
+
+
+/* Authenticate with more detailed information */
+wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
+ struct wbcAuthUserInfo **info,
+ struct wbcAuthErrorInfo **error)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Trigger a verification of the trust credentials of a specific domain */
+wbcErr wbcCheckTrustCredentials(const char *domain,
+ struct wbcAuthErrorInfo **error)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Trigger a change of the trust credentials for a specific domain */
+wbcErr wbcChangeTrustCredentials(const char *domain,
+ struct wbcAuthErrorInfo **error)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/*
+ * Trigger a no-op NETLOGON call. Lightweight version of
+ * wbcCheckTrustCredentials
+ */
+wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error)
+{
+ return wbcPingDc2(domain, error, NULL);
+}
+
+/*
+ * Trigger a no-op NETLOGON call. Lightweight version of
+ * wbcCheckTrustCredentials, optionally return attempted DC
+ */
+wbcErr wbcPingDc2(const char *domain, struct wbcAuthErrorInfo **error,
+ char **dcname)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Trigger an extended logoff notification to Winbind for a specific user */
+wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params,
+ struct wbcAuthErrorInfo **error)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Trigger a logoff notification to Winbind for a specific user */
+wbcErr wbcLogoffUser(const char *username,
+ uid_t uid,
+ const char *ccfilename)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Change a password for a user with more detailed information upon failure */
+wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
+ struct wbcAuthErrorInfo **error,
+ enum wbcPasswordChangeRejectReason *reject_reason,
+ struct wbcUserPasswordPolicyInfo **policy)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Change a password for a user */
+wbcErr wbcChangeUserPassword(const char *username,
+ const char *old_password,
+ const char *new_password)
+{
+ wbcErr wbc_status = WBC_ERR_SUCCESS;
+ struct wbcChangePasswordParams params = {0};
+
+ params.account_name = username;
+ params.level = WBC_CHANGE_PASSWORD_LEVEL_PLAIN;
+ params.old_password.plaintext = old_password;
+ params.new_password.plaintext = new_password;
+
+ wbc_status = wbcChangeUserPasswordEx(&params, NULL, NULL, NULL);
+
+ return wbc_status;
+}
+
+/* Logon a User */
+wbcErr wbcLogonUser(const struct wbcLogonUserParams *params,
+ struct wbcLogonUserInfo **info,
+ struct wbcAuthErrorInfo **error,
+ struct wbcUserPasswordPolicyInfo **policy)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Authenticate a user with cached credentials */
+wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
+ struct wbcCredentialCacheInfo **info,
+ struct wbcAuthErrorInfo **error)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Authenticate a user with cached credentials */
+wbcErr wbcCredentialSave(const char *user, const char *password)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
diff --git a/src/sss_client/libwbclient/wbc_pwd_sssd.c b/src/sss_client/libwbclient/wbc_pwd_sssd.c
new file mode 100644
index 000000000..6cdea1c03
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_pwd_sssd.c
@@ -0,0 +1,659 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API - SSSD version
+
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2014
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/* Required Headers */
+
+#include <nss.h>
+#include <dlfcn.h>
+#include <errno.h>
+
+#include "libwbclient.h"
+#include "wbc_sssd_internal.h"
+
+#define DEFAULT_BUFSIZE_HALF 2048
+#define DEFAULT_BUFSIZE (2 * DEFAULT_BUFSIZE_HALF)
+#define MAX_BUFSIZE (1024*1204)
+
+struct nss_ops_ctx {
+ void *dl_handle;
+
+ enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
+ char *buffer, size_t buflen, int *errnop);
+ enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
+ char *buffer, size_t buflen, int *errnop);
+ enum nss_status (*setpwent)(void);
+ enum nss_status (*getpwent_r)(struct passwd *result,
+ char *buffer, size_t buflen, int *errnop);
+ enum nss_status (*endpwent)(void);
+
+ enum nss_status (*getgrnam_r)(const char *name, struct group *result,
+ char *buffer, size_t buflen, int *errnop);
+ enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
+ char *buffer, size_t buflen, int *errnop);
+ enum nss_status (*setgrent)(void);
+ enum nss_status (*getgrent_r)(struct group *result,
+ char *buffer, size_t buflen, int *errnop);
+ enum nss_status (*endgrent)(void);
+
+ enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
+ long int *start, long int *size,
+ gid_t **groups, long int limit,
+ int *errnop);
+};
+
+struct nss_ops_ctx *ctx = NULL;
+
+static bool open_libnss_sss(void)
+{
+ ctx = calloc(1, sizeof(struct nss_ops_ctx));
+ if (ctx == NULL) {
+ return false;
+ }
+
+ ctx->dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW);
+ if (ctx->dl_handle == NULL) {
+ goto fail;
+ }
+
+ ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_sss_getpwnam_r");
+ if (ctx->getpwnam_r == NULL) {
+ goto fail;
+ }
+
+ ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_sss_getpwuid_r");
+ if (ctx->getpwuid_r == NULL) {
+ goto fail;
+ }
+
+ ctx->setpwent = dlsym(ctx->dl_handle, "_nss_sss_setpwent");
+ if (ctx->setpwent == NULL) {
+ goto fail;
+ }
+
+ ctx->getpwent_r = dlsym(ctx->dl_handle, "_nss_sss_getpwent_r");
+ if (ctx->getpwent_r == NULL) {
+ goto fail;
+ }
+
+ ctx->endpwent = dlsym(ctx->dl_handle, "_nss_sss_endpwent");
+ if (ctx->endpwent == NULL) {
+ goto fail;
+ }
+
+ ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_sss_getgrnam_r");
+ if (ctx->getgrnam_r == NULL) {
+ goto fail;
+ }
+
+ ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_sss_getgrgid_r");
+ if (ctx->getgrgid_r == NULL) {
+ goto fail;
+ }
+
+ ctx->setgrent = dlsym(ctx->dl_handle, "_nss_sss_setgrent");
+ if (ctx->setgrent == NULL) {
+ goto fail;
+ }
+
+ ctx->getgrent_r = dlsym(ctx->dl_handle, "_nss_sss_getgrent_r");
+ if (ctx->getgrent_r == NULL) {
+ goto fail;
+ }
+
+ ctx->endgrent = dlsym(ctx->dl_handle, "_nss_sss_endgrent");
+ if (ctx->endgrent == NULL) {
+ goto fail;
+ }
+
+ ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_sss_initgroups_dyn");
+ if (ctx->initgroups_dyn == NULL) {
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ if (ctx->dl_handle != NULL) {
+ dlclose(ctx->dl_handle);
+ }
+
+ free(ctx);
+ ctx = NULL;
+
+ return false;
+}
+
+static void wbcPasswdDestructor(void *ptr)
+{
+ struct passwd *pw = (struct passwd *)ptr;
+ free(pw->pw_name);
+ free(pw->pw_passwd);
+ free(pw->pw_gecos);
+ free(pw->pw_shell);
+ free(pw->pw_dir);
+}
+
+static wbcErr copy_pwd(struct passwd *in, struct passwd **out)
+{
+ struct passwd *pw;
+
+ pw = (struct passwd *)wbcAllocateMemory(1, sizeof(struct passwd),
+ wbcPasswdDestructor);
+ if (pw == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ pw->pw_name = strdup(in->pw_name);
+ if (pw->pw_name == NULL) {
+ goto fail;
+ }
+
+ pw->pw_passwd = strdup(in->pw_passwd);
+ if (pw->pw_passwd == NULL) {
+ goto fail;
+ }
+
+ pw->pw_uid = in->pw_uid;
+ pw->pw_gid = in->pw_gid;
+
+ pw->pw_gecos = strdup(in->pw_gecos);
+ if (pw->pw_gecos == NULL) {
+ goto fail;
+ }
+
+ pw->pw_shell = strdup(in->pw_shell);
+ if (pw->pw_shell == NULL) {
+ goto fail;
+ }
+
+ pw->pw_dir = strdup(in->pw_dir);
+ if (pw->pw_dir == NULL) {
+ goto fail;
+ }
+
+ *out = pw;
+ return WBC_ERR_SUCCESS;
+fail:
+ wbcFreeMemory(pw);
+
+ return WBC_ERR_NO_MEMORY;
+}
+
+static wbcErr nss_to_wbc(enum nss_status status)
+{
+ wbcErr wbc_status;
+
+ switch (status) {
+ case NSS_STATUS_SUCCESS:
+ wbc_status = WBC_ERR_SUCCESS;
+ break;
+ case NSS_STATUS_NOTFOUND:
+ wbc_status = WBC_ERR_UNKNOWN_USER;
+ break;
+ case NSS_STATUS_UNAVAIL:
+ wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
+ break;
+ default:
+ wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ return wbc_status;
+}
+
+/* Fill in a struct passwd* for a domain user based on username */
+wbcErr wbcGetpwnam(const char *name, struct passwd **pwd)
+{
+ struct passwd lpwd = {0};
+ enum nss_status status;
+ char *buffer = NULL;
+ size_t buflen;
+ wbcErr wbc_status;
+ int nss_errno;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ if (name == NULL || pwd == NULL) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ buflen = DEFAULT_BUFSIZE;
+ buffer = malloc(buflen);
+ if (buffer == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ status = ctx->getpwnam_r(name, &lpwd, buffer, buflen, &nss_errno);
+ wbc_status = nss_to_wbc(status);
+ if (WBC_ERROR_IS_OK(wbc_status)) {
+ wbc_status = copy_pwd(&lpwd, pwd);
+ }
+
+ free(buffer);
+
+ return wbc_status;
+}
+
+/* Fill in a struct passwd* for a domain user based on uid */
+wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd)
+{
+ struct passwd lpwd = {0};
+ enum nss_status status;
+ char *buffer = NULL;
+ size_t buflen;
+ wbcErr wbc_status;
+ int nss_errno;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ if (pwd == NULL) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ buflen = DEFAULT_BUFSIZE;
+ buffer = malloc(buflen);
+ if (buffer == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ status = ctx->getpwuid_r(uid, &lpwd, buffer, buflen, &nss_errno);
+ wbc_status = nss_to_wbc(status);
+ if (WBC_ERROR_IS_OK(wbc_status)) {
+ wbc_status = copy_pwd(&lpwd, pwd);
+ }
+
+ free(buffer);
+
+ return wbc_status;
+}
+
+/* Fill in a struct passwd* for a domain user based on sid */
+wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd)
+{
+ wbcErr wbc_status;
+ uid_t uid;
+
+ wbc_status = wbcSidToUid(sid, &uid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ wbc_status = wbcGetpwuid(uid, pwd);
+
+ return wbc_status;
+
+}
+
+static void wbcGroupDestructor(void *ptr)
+{
+ struct group *gr = (struct group *)ptr;
+ size_t c;
+
+ free(gr->gr_name);
+ free(gr->gr_passwd);
+
+ /* if the array was partly created this can be NULL */
+ if (gr->gr_mem == NULL) {
+ return;
+ }
+
+ for (c=0; gr->gr_mem[c] != NULL; c++) {
+ free(gr->gr_mem[c]);
+ }
+ free(gr->gr_mem);
+}
+
+static wbcErr copy_grp(struct group *in, struct group **out)
+{
+ struct group *gr;
+ size_t members;
+ size_t c;
+
+ gr = (struct group *)wbcAllocateMemory(1, sizeof(struct group),
+ wbcGroupDestructor);
+ if (gr == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ gr->gr_name = strdup(in->gr_name);
+ if (gr->gr_name == NULL) {
+ goto fail;
+ }
+
+ gr->gr_passwd = strdup(in->gr_passwd);
+ if (gr->gr_passwd == NULL) {
+ goto fail;
+ }
+
+ gr->gr_gid = in->gr_gid;
+
+ for (members = 0; in->gr_mem[members] != NULL; members++);
+
+ gr->gr_mem = (char **)calloc(members+1, sizeof(char *));
+ if (gr->gr_mem == NULL) {
+ goto fail;
+ }
+
+ for (c = 0; c < members; c++) {
+ gr->gr_mem[c] = strdup(in->gr_mem[c]);
+ if (gr->gr_mem[c] == NULL) {
+ goto fail;
+ }
+ }
+
+ *out = gr;
+ return WBC_ERR_SUCCESS;
+fail:
+ wbcFreeMemory(gr);
+
+ return WBC_ERR_NO_MEMORY;
+}
+/* Fill in a struct passwd* for a domain user based on username */
+wbcErr wbcGetgrnam(const char *name, struct group **grp)
+{
+ struct group lgrp;
+ enum nss_status status;
+ char *newbuffer = NULL;
+ char *buffer = NULL;
+ size_t buflen = 0;
+ wbcErr wbc_status;
+ int nss_errno;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ if (name == NULL || grp == NULL) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ buflen = DEFAULT_BUFSIZE_HALF;
+ do {
+ buflen *= 2;
+
+ newbuffer = realloc(buffer, buflen);
+ if (newbuffer == NULL) {
+ free(buffer);
+ return WBC_ERR_NO_MEMORY;
+ }
+ buffer = newbuffer;
+
+ memset(grp, 0, sizeof(struct group));
+ status = ctx->getgrnam_r(name, &lgrp, buffer, buflen, &nss_errno);
+ wbc_status = nss_to_wbc(status);
+ if (WBC_ERROR_IS_OK(wbc_status)) {
+ wbc_status = copy_grp(&lgrp, grp);
+ }
+ } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
+ && buflen < MAX_BUFSIZE);
+
+ free(buffer);
+
+ return wbc_status;
+}
+
+/* Fill in a struct passwd* for a domain user based on uid */
+wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
+{
+ struct group lgrp;
+ enum nss_status status;
+ char *newbuffer = NULL;
+ char *buffer = NULL;
+ size_t buflen = 0;
+ wbcErr wbc_status;
+ int nss_errno;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ if (grp == NULL) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ buflen = DEFAULT_BUFSIZE_HALF;
+ do {
+ buflen *= 2;
+
+ newbuffer = realloc(buffer, buflen);
+ if (newbuffer == NULL) {
+ free(buffer);
+ return WBC_ERR_NO_MEMORY;
+ }
+ buffer = newbuffer;
+
+ memset(grp, 0, sizeof(struct group));
+ status = ctx->getgrgid_r(gid, &lgrp, buffer, buflen, &nss_errno);
+ wbc_status = nss_to_wbc(status);
+ if (WBC_ERROR_IS_OK(wbc_status)) {
+ wbc_status = copy_grp(&lgrp, grp);
+ }
+ } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
+ && buflen < MAX_BUFSIZE);
+
+ free(buffer);
+
+ return wbc_status;
+}
+
+/* Reset the passwd iterator */
+wbcErr wbcSetpwent(void)
+{
+ enum nss_status status;
+ wbcErr wbc_status;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ status = ctx->setpwent();
+ wbc_status = nss_to_wbc(status);
+
+ return wbc_status;
+}
+
+/* Close the passwd iterator */
+wbcErr wbcEndpwent(void)
+{
+ enum nss_status status;
+ wbcErr wbc_status;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ status = ctx->endpwent();
+ wbc_status = nss_to_wbc(status);
+
+ return wbc_status;
+}
+
+/* Return the next struct passwd* entry from the pwent iterator */
+wbcErr wbcGetpwent(struct passwd **pwd)
+{
+ struct passwd lpwd = {0};
+ enum nss_status status;
+ char *buffer = NULL;
+ size_t buflen;
+ wbcErr wbc_status;
+ int nss_errno;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ if (pwd == NULL) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ buflen = DEFAULT_BUFSIZE;
+ buffer = malloc(buflen);
+ if (buffer == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ status = ctx->getpwent_r(&lpwd, buffer, buflen, &nss_errno);
+ wbc_status = nss_to_wbc(status);
+ if (WBC_ERROR_IS_OK(wbc_status)) {
+ wbc_status = copy_pwd(&lpwd, pwd);
+ }
+
+ free(buffer);
+
+ return wbc_status;
+}
+
+/* Reset the group iterator */
+wbcErr wbcSetgrent(void)
+{
+ enum nss_status status;
+ wbcErr wbc_status;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ status = ctx->setgrent();
+ wbc_status = nss_to_wbc(status);
+
+ return wbc_status;
+}
+
+/* Close the group iterator */
+wbcErr wbcEndgrent(void)
+{
+ enum nss_status status;
+ wbcErr wbc_status;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ status = ctx->endgrent();
+ wbc_status = nss_to_wbc(status);
+
+ return wbc_status;
+}
+
+/* Return the next struct group* entry from the pwent iterator */
+wbcErr wbcGetgrent(struct group **grp)
+{
+ struct group lgrp;
+ enum nss_status status;
+ char *newbuffer = NULL;
+ char *buffer = NULL;
+ size_t buflen = 0;
+ wbcErr wbc_status;
+ int nss_errno;
+
+ if (ctx == NULL && !open_libnss_sss()) {
+ return WBC_ERR_NSS_ERROR;
+ }
+
+ if (grp == NULL) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ buflen = DEFAULT_BUFSIZE_HALF;
+ do {
+ buflen *= 2;
+
+ newbuffer = realloc(buffer, buflen);
+ if (newbuffer == NULL) {
+ free(buffer);
+ return WBC_ERR_NO_MEMORY;
+ }
+ buffer = newbuffer;
+
+ memset(grp, 0, sizeof(struct group));
+ status = ctx->getgrent_r(&lgrp, buffer, buflen, &nss_errno);
+ wbc_status = nss_to_wbc(status);
+ if (WBC_ERROR_IS_OK(wbc_status)) {
+ wbc_status = copy_grp(&lgrp, grp);
+ }
+ } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
+ && buflen < MAX_BUFSIZE);
+
+ free(buffer);
+
+ return wbc_status;
+}
+
+/* Return the next struct group* entry from the pwent iterator */
+wbcErr wbcGetgrlist(struct group **grp)
+{
+ /* Not used anywhere */
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Return the unix group array belonging to the given user */
+wbcErr wbcGetGroups(const char *account,
+ uint32_t *num_groups,
+ gid_t **_groups)
+{
+ wbcErr wbc_status;
+ enum nss_status status;
+ struct passwd *pwd;
+ long int gr_size = 0;
+ long int start = 0;
+ gid_t *gids = NULL;
+ int nss_errno;
+
+ wbc_status = wbcGetpwnam(account, &pwd);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ gr_size = DEFAULT_BUFSIZE;
+ gids = calloc(gr_size, sizeof(gid_t));
+ if (gids == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ /* nss modules may skip the primary group when we pass it in so always
+ * add it in advance */
+ gids[0] = pwd->pw_gid;
+ start++;
+
+ status = ctx->initgroups_dyn(pwd->pw_name, pwd->pw_gid, &start,
+ &gr_size, &gids, -1, &nss_errno);
+ wbc_status = nss_to_wbc(status);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ goto done;
+ }
+
+ *_groups = gids;
+ *num_groups = start;
+
+ wbc_status = WBC_ERR_SUCCESS;
+
+done:
+ wbcFreeMemory(pwd);
+
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ free(gids);
+ }
+
+ return wbc_status;
+}
diff --git a/src/sss_client/libwbclient/wbc_sid_common.c b/src/sss_client/libwbclient/wbc_sid_common.c
new file mode 100644
index 000000000..60ddbddac
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_sid_common.c
@@ -0,0 +1,199 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API
+
+ Copyright (C) Gerald (Jerry) Carter 2007
+ Copyright (C) Volker Lendecke 2010
+
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Required Headers */
+
+#include <stdio.h>
+
+#include "libwbclient.h"
+
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+/* Convert a sid to a string into a buffer. Return the string
+ * length. If buflen is too small, return the string length that would
+ * result if it was long enough. */
+int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen)
+{
+ uint64_t id_auth;
+ int i, ofs;
+
+ if (!sid) {
+ strncpy(buf, "(NULL SID)", buflen);
+ buf[buflen < 10 ? buflen :10] = '\0';
+ return 10; /* strlen("(NULL SID)") */
+ }
+
+ id_auth = (uint64_t)sid->id_auth[5] +
+ ((uint64_t)sid->id_auth[4] << 8) +
+ ((uint64_t)sid->id_auth[3] << 16) +
+ ((uint64_t)sid->id_auth[2] << 24) +
+ ((uint64_t)sid->id_auth[1] << 32) +
+ ((uint64_t)sid->id_auth[0] << 40);
+
+ ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num);
+ if (id_auth >= UINT32_MAX) {
+ ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx",
+ (unsigned long long)id_auth);
+ } else {
+ ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu",
+ (unsigned long long)id_auth);
+ }
+
+ for (i = 0; i < sid->num_auths; i++) {
+ ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u",
+ (unsigned int)sid->sub_auths[i]);
+ }
+ return ofs;
+}
+
+/* Convert a binary SID to a character string */
+wbcErr wbcSidToString(const struct wbcDomainSid *sid,
+ char **sid_string)
+{
+ char buf[WBC_SID_STRING_BUFLEN];
+ char *result;
+ int len;
+
+ if (!sid) {
+ return WBC_ERR_INVALID_SID;
+ }
+
+ len = wbcSidToStringBuf(sid, buf, sizeof(buf));
+
+ if (len+1 > sizeof(buf)) {
+ return WBC_ERR_INVALID_SID;
+ }
+
+ result = (char *)wbcAllocateMemory(len+1, 1, NULL);
+ if (result == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+ memcpy(result, buf, len+1);
+
+ *sid_string = result;
+ return WBC_ERR_SUCCESS;
+}
+
+#define AUTHORITY_MASK (~(0xffffffffffffULL))
+
+/* Convert a character string to a binary SID */
+wbcErr wbcStringToSid(const char *str,
+ struct wbcDomainSid *sid)
+{
+ const char *p;
+ char *q;
+ uint64_t x;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+
+ if (!sid) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ /* Sanity check for either "S-" or "s-" */
+
+ if (!str
+ || (str[0]!='S' && str[0]!='s')
+ || (str[1]!='-'))
+ {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ /* Get the SID revision number */
+
+ p = str+2;
+ x = (uint64_t)strtoul(p, &q, 10);
+ if (x==0 || x > UINT8_MAX || !q || *q!='-') {
+ wbc_status = WBC_ERR_INVALID_SID;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ sid->sid_rev_num = (uint8_t)x;
+
+ /*
+ * Next the Identifier Authority. This is stored big-endian in a
+ * 6 byte array. If the authority value is >= UINT_MAX, then it should
+ * be expressed as a hex value, according to MS-DTYP.
+ */
+ p = q+1;
+ x = strtoull(p, &q, 0);
+ if (!q || *q!='-' || (x & AUTHORITY_MASK)) {
+ wbc_status = WBC_ERR_INVALID_SID;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ sid->id_auth[5] = (x & 0x0000000000ffULL);
+ sid->id_auth[4] = (x & 0x00000000ff00ULL) >> 8;
+ sid->id_auth[3] = (x & 0x000000ff0000ULL) >> 16;
+ sid->id_auth[2] = (x & 0x0000ff000000ULL) >> 24;
+ sid->id_auth[1] = (x & 0x00ff00000000ULL) >> 32;
+ sid->id_auth[0] = (x & 0xff0000000000ULL) >> 40;
+
+ /* now read the the subauthorities */
+ p = q +1;
+ sid->num_auths = 0;
+ while (sid->num_auths < WBC_MAXSUBAUTHS) {
+ x = strtoull(p, &q, 10);
+ if (p == q)
+ break;
+ if (x > UINT32_MAX) {
+ wbc_status = WBC_ERR_INVALID_SID;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ sid->sub_auths[sid->num_auths++] = x;
+
+ if (*q != '-') {
+ break;
+ }
+ p = q + 1;
+ }
+
+ /* IF we ended early, then the SID could not be converted */
+
+ if (q && *q!='\0') {
+ wbc_status = WBC_ERR_INVALID_SID;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ wbc_status = WBC_ERR_SUCCESS;
+
+done:
+ return wbc_status;
+
+}
+
+const char* wbcSidTypeString(enum wbcSidType type)
+{
+ switch (type) {
+ case WBC_SID_NAME_USE_NONE: return "SID_NONE";
+ case WBC_SID_NAME_USER: return "SID_USER";
+ case WBC_SID_NAME_DOM_GRP: return "SID_DOM_GROUP";
+ case WBC_SID_NAME_DOMAIN: return "SID_DOMAIN";
+ case WBC_SID_NAME_ALIAS: return "SID_ALIAS";
+ case WBC_SID_NAME_WKN_GRP: return "SID_WKN_GROUP";
+ case WBC_SID_NAME_DELETED: return "SID_DELETED";
+ case WBC_SID_NAME_INVALID: return "SID_INVALID";
+ case WBC_SID_NAME_UNKNOWN: return "SID_UNKNOWN";
+ case WBC_SID_NAME_COMPUTER: return "SID_COMPUTER";
+ default: return "Unknown type";
+ }
+}
diff --git a/src/sss_client/libwbclient/wbc_sid_sssd.c b/src/sss_client/libwbclient/wbc_sid_sssd.c
new file mode 100644
index 000000000..cde65fa03
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_sid_sssd.c
@@ -0,0 +1,283 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API - SSSD version
+
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2014
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Required Headers */
+#include "config.h"
+
+#include <stdio.h>
+
+#include <errno.h>
+
+#include "sss_client/idmap/sss_nss_idmap.h"
+
+#include "libwbclient.h"
+#include "wbc_sssd_internal.h"
+
+#define MAX_NAME_LEN 1024
+
+static int sss_id_type_to_wbcSidType(enum sss_id_type sss_type,
+ enum wbcSidType *name_type)
+{
+ switch (sss_type) {
+ case SSS_ID_TYPE_NOT_SPECIFIED:
+ *name_type = WBC_SID_NAME_USE_NONE;
+ break;
+ case SSS_ID_TYPE_UID:
+ case SSS_ID_TYPE_BOTH:
+ *name_type = WBC_SID_NAME_USER;
+ break;
+ case SSS_ID_TYPE_GID:
+ *name_type = WBC_SID_NAME_DOM_GRP;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+};
+
+/* Convert a domain and name to SID */
+wbcErr wbcLookupName(const char *domain,
+ const char *name,
+ struct wbcDomainSid *sid,
+ enum wbcSidType *name_type)
+{
+ char *fq_name = NULL;
+ char *str_sid;
+ enum sss_id_type type;
+ int ret;
+ wbcErr wbc_status;
+
+ if (domain == NULL || name == NULL
+ || strnlen(domain, MAX_NAME_LEN) == MAX_NAME_LEN
+ || strnlen(name, MAX_NAME_LEN) == MAX_NAME_LEN) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+ ret = asprintf(&fq_name, "%s@%s", name, domain);
+ if (ret == -1) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ ret = sss_nss_getsidbyname(fq_name, &str_sid, &type);
+ free(fq_name);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ ret = sss_id_type_to_wbcSidType(type, name_type);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ wbc_status = wbcStringToSid(str_sid, sid);
+ free(str_sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ return WBC_ERR_SUCCESS;
+}
+
+
+/* Convert a SID to a domain and name */
+wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
+ char **pdomain,
+ char **pname,
+ enum wbcSidType *pname_type)
+{
+ char *str_sid;
+ char *fq_name = NULL;
+ enum sss_id_type type;
+ int ret;
+ char *p;
+ wbcErr wbc_status;
+
+ wbc_status = wbcSidToString(sid, &str_sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ ret = sss_nss_getnamebysid(str_sid, &fq_name, &type);
+ wbcFreeMemory(str_sid);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ ret = sss_id_type_to_wbcSidType(type, pname_type);
+ if (ret != 0) {
+ wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ goto done;
+ }
+
+ /* TODO: it would be nice to have a sss_nss_getnamebysid() call which
+ * return name and domain separately. */
+ p = strchr(fq_name, '@');
+ if (p == NULL) {
+ wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ goto done;
+ }
+
+ *p = '\0';
+ *pname = wbcStrDup(fq_name);
+ if (*pname == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ *pdomain = wbcStrDup(p + 1);
+ if (*pdomain == NULL) {
+ wbcFreeMemory(*pname);
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ wbc_status = WBC_ERR_SUCCESS;
+done:
+ free(fq_name);
+ return wbc_status;
+}
+
+wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids,
+ struct wbcDomainInfo **pdomains, int *pnum_domains,
+ struct wbcTranslatedName **pnames)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Translate a collection of RIDs within a domain to names */
+
+wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
+ int num_rids,
+ uint32_t *rids,
+ const char **pp_domain_name,
+ const char ***pnames,
+ enum wbcSidType **ptypes)
+{
+ struct wbcDomainSid obj_sid = {0};
+ size_t c;
+ wbcErr err;
+ char *domain;
+ char *name;
+ enum wbcSidType type;
+ const char **names = NULL;
+ enum wbcSidType *types = NULL;
+
+ obj_sid.sid_rev_num = dom_sid->sid_rev_num;
+ obj_sid.num_auths = dom_sid->num_auths + 1;
+ for (c = 0; c < 6; c++) {
+ obj_sid.id_auth[c] = dom_sid->id_auth[c];
+ }
+ for (c = 0; c < WBC_MAXSUBAUTHS; c++) {
+ obj_sid.sub_auths[c] = dom_sid->sub_auths[c];
+ }
+
+ names = wbcAllocateStringArray(num_rids + 1);
+ if (names == NULL) {
+ err = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ types = wbcAllocateMemory(num_rids + 1, sizeof(enum wbcSidType), NULL);
+ if (types == NULL) {
+ err = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ for (c = 0; c < num_rids; c++) {
+ obj_sid.sub_auths[obj_sid.num_auths - 1] = rids[c];
+
+ err = wbcLookupSid(&obj_sid, &domain, &name, &type);
+ if (err != WBC_ERR_SUCCESS) {
+ goto done;
+ }
+
+ names[c] = strdup(name);
+ wbcFreeMemory(name);
+ if (names[c] == NULL) {
+ err = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+ types[c] = type;
+
+ if (c == 0) {
+ *pp_domain_name = domain;
+ } else {
+ wbcFreeMemory(domain);
+ }
+ }
+
+ *pnames = names;
+ *ptypes = types;
+
+ err = WBC_ERR_SUCCESS;
+
+done:
+ if (err != WBC_ERR_SUCCESS) {
+ wbcFreeMemory(types);
+ wbcFreeMemory(names);
+ }
+
+ return err;
+}
+
+/* Get the groups a user belongs to */
+wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
+ bool domain_groups_only,
+ uint32_t *num_sids,
+ struct wbcDomainSid **_sids)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Get alias membership for sids */
+wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
+ struct wbcDomainSid *sids,
+ uint32_t num_sids,
+ uint32_t **alias_rids,
+ uint32_t *num_alias_rids)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+
+/* Lists Users */
+wbcErr wbcListUsers(const char *domain_name,
+ uint32_t *_num_users,
+ const char ***_users)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Lists Groups */
+wbcErr wbcListGroups(const char *domain_name,
+ uint32_t *_num_groups,
+ const char ***_groups)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
+ char **pdomain,
+ char **pfullname,
+ enum wbcSidType *pname_type)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
diff --git a/src/sss_client/libwbclient/wbc_sssd_internal.h b/src/sss_client/libwbclient/wbc_sssd_internal.h
new file mode 100644
index 000000000..e20de482a
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_sssd_internal.h
@@ -0,0 +1,41 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API - SSSD version
+
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2014
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WBC_SSSD_INTERNAL_H
+#define _WBC_SSSD_INTERNAL_H
+
+#include <syslog.h>
+
+#include "libwbclient.h"
+
+#if defined(DEVELOPER)
+#define WBC_SSSD_DEV_LOG syslog(LOG_DEBUG, "libwbclient_sssd: %s", __FUNCTION__);
+#else
+#define WBC_SSSD_DEV_LOG
+#endif
+
+#define WBC_SSSD_NOT_IMPLEMENTED \
+ do { \
+ WBC_SSSD_DEV_LOG; \
+ return WBC_ERR_NOT_IMPLEMENTED; \
+ } while(0)
+
+#endif /* _WBC_SSSD_INTERNAL_H */
diff --git a/src/sss_client/libwbclient/wbc_util_common.c b/src/sss_client/libwbclient/wbc_util_common.c
new file mode 100644
index 000000000..25ff1f8a2
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_util_common.c
@@ -0,0 +1,97 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client asynchronous API, utility functions
+
+ Copyright (C) Gerald (Jerry) Carter 2007-2008
+
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Required Headers */
+
+#include "libwbclient.h"
+
+#include "util/util.h"
+
+static void wbcNamedBlobDestructor(void *ptr)
+{
+ struct wbcNamedBlob *b = (struct wbcNamedBlob *)ptr;
+
+ while (b->name != NULL) {
+ free(discard_const_p(char, b->name));
+ free(b->blob.data);
+ b += 1;
+ }
+}
+
+/* Initialize a named blob and add to list of blobs */
+wbcErr wbcAddNamedBlob(size_t *num_blobs,
+ struct wbcNamedBlob **pblobs,
+ const char *name,
+ uint32_t flags,
+ uint8_t *data,
+ size_t length)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcNamedBlob *blobs, *blob;
+
+ if (name == NULL) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ /*
+ * Overallocate the b->name==NULL terminator for
+ * wbcNamedBlobDestructor
+ */
+ blobs = (struct wbcNamedBlob *)wbcAllocateMemory(
+ *num_blobs + 2, sizeof(struct wbcNamedBlob),
+ wbcNamedBlobDestructor);
+
+ if (blobs == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ if (*pblobs != NULL) {
+ struct wbcNamedBlob *old = *pblobs;
+ memcpy(blobs, old, sizeof(struct wbcNamedBlob) * (*num_blobs));
+ if (*num_blobs != 0) {
+ /* end indicator for wbcNamedBlobDestructor */
+ old[0].name = NULL;
+ }
+ wbcFreeMemory(old);
+ }
+ *pblobs = blobs;
+
+ blob = &blobs[*num_blobs];
+
+ blob->name = strdup(name);
+ BAIL_ON_PTR_ERROR(blob->name, wbc_status);
+ blob->flags = flags;
+
+ blob->blob.length = length;
+ blob->blob.data = (uint8_t *)malloc(length);
+ BAIL_ON_PTR_ERROR(blob->blob.data, wbc_status);
+ memcpy(blob->blob.data, data, length);
+
+ *num_blobs += 1;
+ *pblobs = blobs;
+ blobs = NULL;
+
+ wbc_status = WBC_ERR_SUCCESS;
+done:
+ wbcFreeMemory(blobs);
+ return wbc_status;
+}
diff --git a/src/sss_client/libwbclient/wbc_util_sssd.c b/src/sss_client/libwbclient/wbc_util_sssd.c
new file mode 100644
index 000000000..667b79bdb
--- /dev/null
+++ b/src/sss_client/libwbclient/wbc_util_sssd.c
@@ -0,0 +1,160 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API - SSSD version
+
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2014
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/* Required Headers */
+
+#include "libwbclient.h"
+#include "wbc_sssd_internal.h"
+
+#define WINBIND_INTERFACE_VERSION 27
+
+/** @brief Ping winbindd to see if the daemon is running
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcPing(void)
+{
+ /* TODO: add real check */
+ return WBC_ERR_SUCCESS;
+}
+
+static void wbcInterfaceDetailsDestructor(void *ptr)
+{
+ struct wbcInterfaceDetails *i = (struct wbcInterfaceDetails *)ptr;
+ free(i->winbind_version);
+ free(i->netbios_name);
+ free(i->netbios_domain);
+ free(i->dns_domain);
+}
+
+/**
+ * @brief Query useful information about the winbind service
+ *
+ * @param *_details pointer to hold the struct wbcInterfaceDetails
+ *
+ * @return #wbcErr
+ */
+
+wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcInterfaceDetails *info;
+ info = (struct wbcInterfaceDetails *)wbcAllocateMemory(
+ 1, sizeof(struct wbcInterfaceDetails),
+ wbcInterfaceDetailsDestructor);
+ if (info == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ /* TODO: currently this call just returns a suitable winbind_separator
+ * for wbinfo. */
+
+ info->interface_version = WINBIND_INTERFACE_VERSION;
+ info->winbind_version = strdup("libwbclient for SSSD");
+ if (info->winbind_version == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ info->winbind_separator = '\\';
+
+ info->netbios_name = strdup("-not available-");
+ if (info->netbios_name == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ info->netbios_domain = strdup("-not available-");
+ if (info->netbios_domain == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ info->dns_domain = strdup("-not available-");
+ if (info->dns_domain == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ *_details = info;
+ info = NULL;
+ wbc_status = WBC_ERR_SUCCESS;
+done:
+ wbcFreeMemory(info);
+ return wbc_status;
+}
+
+/** @brief Lookup the current status of a trusted domain, sync wrapper
+ *
+ * @param domain Domain to query
+ * @param *dinfo Pointer to returned struct wbcDomainInfo
+ *
+ * @return #wbcErr
+ */
+
+wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Get the list of current DCs */
+wbcErr wbcDcInfo(const char *domain, size_t *num_dcs,
+ const char ***dc_names, const char ***dc_ips)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Resolve a NetbiosName via WINS */
+wbcErr wbcResolveWinsByName(const char *name, char **ip)
+{
+ /* SSSD does not support WINS */
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Resolve an IP address via WINS into a NetbiosName */
+wbcErr wbcResolveWinsByIP(const char *ip, char **name)
+{
+ /* SSSD does not support WINS */
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Enumerate the domain trusts known by Winbind */
+wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Enumerate the domain trusts known by Winbind */
+wbcErr wbcLookupDomainController(const char *domain,
+ uint32_t flags,
+ struct wbcDomainControllerInfo **dc_info)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+/* Get extended domain controller information */
+wbcErr wbcLookupDomainControllerEx(const char *domain,
+ struct wbcGuid *guid,
+ const char *site,
+ uint32_t flags,
+ struct wbcDomainControllerInfoEx **dc_info)
+{
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
diff --git a/src/sss_client/libwbclient/wbclient.exports b/src/sss_client/libwbclient/wbclient.exports
new file mode 100644
index 000000000..a3cd1165b
--- /dev/null
+++ b/src/sss_client/libwbclient/wbclient.exports
@@ -0,0 +1,90 @@
+WBCLIENT_0.9 {
+ global:
+ wbcGetpwuid;
+ wbcLogoffUser;
+ wbcSidToStringBuf;
+ wbcLogonUser;
+ wbcGetgrgid;
+ wbcSetGidMapping;
+ wbcQueryGidToSid;
+ wbcListTrusts;
+ wbcGetGroups;
+ wbcDomainInfo;
+ wbcSidToGid;
+ wbcLookupRids;
+ wbcCredentialCache;
+ wbcDcInfo;
+ wbcAuthenticateUserEx;
+ wbcGetpwent;
+ wbcGetSidAliases;
+ wbcGetDisplayName;
+ wbcAllocateUid;
+ wbcSidToUid;
+ wbcChangeTrustCredentials;
+ wbcGetpwsid;
+ wbcPingDc;
+ wbcAllocateStringArray;
+ wbcErrorString;
+ wbcStringToGuid;
+ wbcStrDup;
+ wbcGetgrnam;
+ wbcGetgrlist;
+ wbcListUsers;
+ wbcRemoveUidMapping;
+ wbcLookupDomainController;
+ wbcRemoveGidMapping;
+ wbcSidTypeString;
+ wbcAllocateMemory;
+ wbcInterfaceDetails;
+ wbcCheckTrustCredentials;
+ wbcListGroups;
+ wbcLookupUserSids;
+ wbcResolveWinsByName;
+ wbcSetpwent;
+ wbcSetUidHwm;
+ wbcSidsToUnixIds;
+ wbcQuerySidToGid;
+ wbcChangeUserPasswordEx;
+ wbcPing;
+ wbcQueryUidToSid;
+ wbcEndpwent;
+ wbcLibraryDetails;
+ wbcSetgrent;
+ wbcLookupName;
+ wbcChangeUserPassword;
+ wbcSetGidHwm;
+ wbcAddNamedBlob;
+ wbcGuidToString;
+ wbcLookupSids;
+ wbcRequestResponsePriv;
+ wbcAllocateGid;
+ wbcFreeMemory;
+ wbcResolveWinsByIP;
+ wbcRequestResponse;
+ wbcStringToSid;
+ wbcLookupSid;
+ wbcCredentialSave;
+ wbcGidToSid;
+ wbcQuerySidToUid;
+ wbcEndgrent;
+ wbcGetgrent;
+ wbcAuthenticateUser;
+ wbcGetpwnam;
+ wbcLookupDomainControllerEx;
+ wbcLogoffUserEx;
+ wbcSetUidMapping;
+ wbcSidToString;
+ wbcUidToSid;
+};
+
+WBCLIENT_0.10 {
+ global:
+ wbcPingDc2;
+} WBCLIENT_0.9;
+
+WBCLIENT_0.11 {
+ global:
+ wbc*;
+ local:
+ *;
+};
diff --git a/src/sss_client/libwbclient/wbclient.h b/src/sss_client/libwbclient/wbclient.h
new file mode 100644
index 000000000..4f0e957a7
--- /dev/null
+++ b/src/sss_client/libwbclient/wbclient.h
@@ -0,0 +1,1372 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API
+
+ Copyright (C) Gerald (Jerry) Carter 2007
+ Copyright (C) Volker Lendecke 2009
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WBCLIENT_H
+#define _WBCLIENT_H
+
+#include <pwd.h>
+#include <grp.h>
+
+/* Define error types */
+
+/**
+ * @brief Status codes returned from wbc functions
+ **/
+
+enum _wbcErrType {
+ WBC_ERR_SUCCESS = 0, /**< Successful completion **/
+ WBC_ERR_NOT_IMPLEMENTED, /**< Function not implemented **/
+ WBC_ERR_UNKNOWN_FAILURE, /**< General failure **/
+ WBC_ERR_NO_MEMORY, /**< Memory allocation error **/
+ WBC_ERR_INVALID_SID, /**< Invalid SID format **/
+ WBC_ERR_INVALID_PARAM, /**< An Invalid parameter was supplied **/
+ WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/
+ WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/
+ WBC_ERR_INVALID_RESPONSE, /**< Winbind returned an invalid response **/
+ WBC_ERR_NSS_ERROR, /**< NSS_STATUS error **/
+ WBC_ERR_AUTH_ERROR, /**< Authentication failed **/
+ WBC_ERR_UNKNOWN_USER, /**< User account cannot be found */
+ WBC_ERR_UNKNOWN_GROUP, /**< Group account cannot be found */
+ WBC_ERR_PWD_CHANGE_FAILED /**< Password Change has failed */
+};
+
+typedef enum _wbcErrType wbcErr;
+
+#define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS)
+
+const char *wbcErrorString(wbcErr error);
+
+/**
+ * @brief Some useful details about the wbclient library
+ *
+ * 0.1: Initial version
+ * 0.2: Added wbcRemoveUidMapping()
+ * Added wbcRemoveGidMapping()
+ * 0.3: Added wbcGetpwsid()
+ * Added wbcGetSidAliases()
+ * 0.4: Added wbcSidTypeString()
+ * 0.5: Added wbcChangeTrustCredentials()
+ * 0.6: Made struct wbcInterfaceDetails char* members non-const
+ * 0.7: Added wbcSidToStringBuf()
+ * 0.8: Added wbcSidsToUnixIds() and wbcLookupSids()
+ * 0.9: Added support for WBC_ID_TYPE_BOTH
+ * 0.10: Added wbcPingDc2()
+ * 0.11: Extended wbcAuthenticateUserEx to provide PAC parsing
+ **/
+#define WBCLIENT_MAJOR_VERSION 0
+#define WBCLIENT_MINOR_VERSION 11
+#define WBCLIENT_VENDOR_VERSION "Samba libwbclient"
+struct wbcLibraryDetails {
+ uint16_t major_version;
+ uint16_t minor_version;
+ const char *vendor_version;
+};
+
+/**
+ * @brief Some useful details about the running winbindd
+ *
+ **/
+struct wbcInterfaceDetails {
+ uint32_t interface_version;
+ char *winbind_version;
+ char winbind_separator;
+ char *netbios_name;
+ char *netbios_domain;
+ char *dns_domain;
+};
+
+/*
+ * Data types used by the Winbind Client API
+ */
+
+#ifndef WBC_MAXSUBAUTHS
+#define WBC_MAXSUBAUTHS 15 /* max sub authorities in a SID */
+#endif
+
+/**
+ * @brief Windows Security Identifier
+ *
+ **/
+
+struct wbcDomainSid {
+ uint8_t sid_rev_num;
+ uint8_t num_auths;
+ uint8_t id_auth[6];
+ uint32_t sub_auths[WBC_MAXSUBAUTHS];
+};
+
+/**
+ * @brief Security Identifier type
+ **/
+
+enum wbcSidType {
+ WBC_SID_NAME_USE_NONE=0,
+ WBC_SID_NAME_USER=1,
+ WBC_SID_NAME_DOM_GRP=2,
+ WBC_SID_NAME_DOMAIN=3,
+ WBC_SID_NAME_ALIAS=4,
+ WBC_SID_NAME_WKN_GRP=5,
+ WBC_SID_NAME_DELETED=6,
+ WBC_SID_NAME_INVALID=7,
+ WBC_SID_NAME_UNKNOWN=8,
+ WBC_SID_NAME_COMPUTER=9
+};
+
+/**
+ * @brief Security Identifier with attributes
+ **/
+
+struct wbcSidWithAttr {
+ struct wbcDomainSid sid;
+ uint32_t attributes;
+};
+
+/* wbcSidWithAttr->attributes */
+
+#define WBC_SID_ATTR_GROUP_MANDATORY 0x00000001
+#define WBC_SID_ATTR_GROUP_ENABLED_BY_DEFAULT 0x00000002
+#define WBC_SID_ATTR_GROUP_ENABLED 0x00000004
+#define WBC_SID_ATTR_GROUP_OWNER 0x00000008
+#define WBC_SID_ATTR_GROUP_USEFOR_DENY_ONLY 0x00000010
+#define WBC_SID_ATTR_GROUP_RESOURCE 0x20000000
+#define WBC_SID_ATTR_GROUP_LOGON_ID 0xC0000000
+
+/**
+ * @brief Windows GUID
+ *
+ **/
+
+struct wbcGuid {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint8_t clock_seq[2];
+ uint8_t node[6];
+};
+
+/**
+ * @brief Domain Information
+ **/
+
+struct wbcDomainInfo {
+ char *short_name;
+ char *dns_name;
+ struct wbcDomainSid sid;
+ uint32_t domain_flags;
+ uint32_t trust_flags;
+ uint32_t trust_type;
+};
+
+/* wbcDomainInfo->domain_flags */
+
+#define WBC_DOMINFO_DOMAIN_UNKNOWN 0x00000000
+#define WBC_DOMINFO_DOMAIN_NATIVE 0x00000001
+#define WBC_DOMINFO_DOMAIN_AD 0x00000002
+#define WBC_DOMINFO_DOMAIN_PRIMARY 0x00000004
+#define WBC_DOMINFO_DOMAIN_OFFLINE 0x00000008
+
+/* wbcDomainInfo->trust_flags */
+
+#define WBC_DOMINFO_TRUST_TRANSITIVE 0x00000001
+#define WBC_DOMINFO_TRUST_INCOMING 0x00000002
+#define WBC_DOMINFO_TRUST_OUTGOING 0x00000004
+
+/* wbcDomainInfo->trust_type */
+
+#define WBC_DOMINFO_TRUSTTYPE_NONE 0x00000000
+#define WBC_DOMINFO_TRUSTTYPE_FOREST 0x00000001
+#define WBC_DOMINFO_TRUSTTYPE_IN_FOREST 0x00000002
+#define WBC_DOMINFO_TRUSTTYPE_EXTERNAL 0x00000003
+
+/**
+ * @brief Generic Blob
+ **/
+
+struct wbcBlob {
+ uint8_t *data;
+ size_t length;
+};
+
+/**
+ * @brief Named Blob
+ **/
+
+struct wbcNamedBlob {
+ const char *name;
+ uint32_t flags;
+ struct wbcBlob blob;
+};
+
+/**
+ * @brief Auth User Parameters
+ **/
+
+struct wbcAuthUserParams {
+ const char *account_name;
+ const char *domain_name;
+ const char *workstation_name;
+
+ uint32_t flags;
+
+ uint32_t parameter_control;
+
+ enum wbcAuthUserLevel {
+ WBC_AUTH_USER_LEVEL_PLAIN = 1,
+ WBC_AUTH_USER_LEVEL_HASH = 2,
+ WBC_AUTH_USER_LEVEL_RESPONSE = 3,
+ WBC_AUTH_USER_LEVEL_PAC = 4
+ } level;
+ union {
+ const char *plaintext;
+ struct {
+ uint8_t nt_hash[16];
+ uint8_t lm_hash[16];
+ } hash;
+ struct {
+ uint8_t challenge[8];
+ uint32_t nt_length;
+ uint8_t *nt_data;
+ uint32_t lm_length;
+ uint8_t *lm_data;
+ } response;
+ struct wbcBlob pac;
+ } password;
+};
+
+/**
+ * @brief Logon User Parameters
+ **/
+
+struct wbcLogonUserParams {
+ const char *username;
+ const char *password;
+ size_t num_blobs;
+ struct wbcNamedBlob *blobs;
+};
+
+/**
+ * @brief ChangePassword Parameters
+ **/
+
+struct wbcChangePasswordParams {
+ const char *account_name;
+ const char *domain_name;
+
+ uint32_t flags;
+
+ enum wbcChangePasswordLevel {
+ WBC_CHANGE_PASSWORD_LEVEL_PLAIN = 1,
+ WBC_CHANGE_PASSWORD_LEVEL_RESPONSE = 2
+ } level;
+
+ union {
+ const char *plaintext;
+ struct {
+ uint32_t old_nt_hash_enc_length;
+ uint8_t *old_nt_hash_enc_data;
+ uint32_t old_lm_hash_enc_length;
+ uint8_t *old_lm_hash_enc_data;
+ } response;
+ } old_password;
+ union {
+ const char *plaintext;
+ struct {
+ uint32_t nt_length;
+ uint8_t *nt_data;
+ uint32_t lm_length;
+ uint8_t *lm_data;
+ } response;
+ } new_password;
+};
+
+/* wbcAuthUserParams->parameter_control */
+
+#define WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED 0x00000002
+#define WBC_MSV1_0_UPDATE_LOGON_STATISTICS 0x00000004
+#define WBC_MSV1_0_RETURN_USER_PARAMETERS 0x00000008
+#define WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT 0x00000020
+#define WBC_MSV1_0_RETURN_PROFILE_PATH 0x00000200
+#define WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT 0x00000800
+
+/* wbcAuthUserParams->flags */
+
+#define WBC_AUTH_PARAM_FLAGS_INTERACTIVE_LOGON 0x00000001
+
+/**
+ * @brief Auth User Information
+ *
+ * Some of the strings are maybe NULL
+ **/
+
+struct wbcAuthUserInfo {
+ uint32_t user_flags;
+
+ char *account_name;
+ char *user_principal;
+ char *full_name;
+ char *domain_name;
+ char *dns_domain_name;
+
+ uint32_t acct_flags;
+ uint8_t user_session_key[16];
+ uint8_t lm_session_key[8];
+
+ uint16_t logon_count;
+ uint16_t bad_password_count;
+
+ uint64_t logon_time;
+ uint64_t logoff_time;
+ uint64_t kickoff_time;
+ uint64_t pass_last_set_time;
+ uint64_t pass_can_change_time;
+ uint64_t pass_must_change_time;
+
+ char *logon_server;
+ char *logon_script;
+ char *profile_path;
+ char *home_directory;
+ char *home_drive;
+
+ /*
+ * the 1st one is the account sid
+ * the 2nd one is the primary_group sid
+ * followed by the rest of the groups
+ */
+ uint32_t num_sids;
+ struct wbcSidWithAttr *sids;
+};
+
+/**
+ * @brief Logon User Information
+ *
+ * Some of the strings are maybe NULL
+ **/
+
+struct wbcLogonUserInfo {
+ struct wbcAuthUserInfo *info;
+ size_t num_blobs;
+ struct wbcNamedBlob *blobs;
+};
+
+/* wbcAuthUserInfo->user_flags */
+
+#define WBC_AUTH_USER_INFO_GUEST 0x00000001
+#define WBC_AUTH_USER_INFO_NOENCRYPTION 0x00000002
+#define WBC_AUTH_USER_INFO_CACHED_ACCOUNT 0x00000004
+#define WBC_AUTH_USER_INFO_USED_LM_PASSWORD 0x00000008
+#define WBC_AUTH_USER_INFO_EXTRA_SIDS 0x00000020
+#define WBC_AUTH_USER_INFO_SUBAUTH_SESSION_KEY 0x00000040
+#define WBC_AUTH_USER_INFO_SERVER_TRUST_ACCOUNT 0x00000080
+#define WBC_AUTH_USER_INFO_NTLMV2_ENABLED 0x00000100
+#define WBC_AUTH_USER_INFO_RESOURCE_GROUPS 0x00000200
+#define WBC_AUTH_USER_INFO_PROFILE_PATH_RETURNED 0x00000400
+#define WBC_AUTH_USER_INFO_GRACE_LOGON 0x01000000
+
+/* wbcAuthUserInfo->acct_flags */
+
+#define WBC_ACB_DISABLED 0x00000001 /* 1 User account disabled */
+#define WBC_ACB_HOMDIRREQ 0x00000002 /* 1 Home directory required */
+#define WBC_ACB_PWNOTREQ 0x00000004 /* 1 User password not required */
+#define WBC_ACB_TEMPDUP 0x00000008 /* 1 Temporary duplicate account */
+#define WBC_ACB_NORMAL 0x00000010 /* 1 Normal user account */
+#define WBC_ACB_MNS 0x00000020 /* 1 MNS logon user account */
+#define WBC_ACB_DOMTRUST 0x00000040 /* 1 Interdomain trust account */
+#define WBC_ACB_WSTRUST 0x00000080 /* 1 Workstation trust account */
+#define WBC_ACB_SVRTRUST 0x00000100 /* 1 Server trust account */
+#define WBC_ACB_PWNOEXP 0x00000200 /* 1 User password does not expire */
+#define WBC_ACB_AUTOLOCK 0x00000400 /* 1 Account auto locked */
+#define WBC_ACB_ENC_TXT_PWD_ALLOWED 0x00000800 /* 1 Encryped text password is allowed */
+#define WBC_ACB_SMARTCARD_REQUIRED 0x00001000 /* 1 Smart Card required */
+#define WBC_ACB_TRUSTED_FOR_DELEGATION 0x00002000 /* 1 Trusted for Delegation */
+#define WBC_ACB_NOT_DELEGATED 0x00004000 /* 1 Not delegated */
+#define WBC_ACB_USE_DES_KEY_ONLY 0x00008000 /* 1 Use DES key only */
+#define WBC_ACB_DONT_REQUIRE_PREAUTH 0x00010000 /* 1 Preauth not required */
+#define WBC_ACB_PW_EXPIRED 0x00020000 /* 1 Password Expired */
+#define WBC_ACB_NO_AUTH_DATA_REQD 0x00080000 /* 1 = No authorization data required */
+
+struct wbcAuthErrorInfo {
+ uint32_t nt_status;
+ char *nt_string;
+ int32_t pam_error;
+ char *display_string;
+};
+
+/**
+ * @brief User Password Policy Information
+ **/
+
+/* wbcUserPasswordPolicyInfo->password_properties */
+
+#define WBC_DOMAIN_PASSWORD_COMPLEX 0x00000001
+#define WBC_DOMAIN_PASSWORD_NO_ANON_CHANGE 0x00000002
+#define WBC_DOMAIN_PASSWORD_NO_CLEAR_CHANGE 0x00000004
+#define WBC_DOMAIN_PASSWORD_LOCKOUT_ADMINS 0x00000008
+#define WBC_DOMAIN_PASSWORD_STORE_CLEARTEXT 0x00000010
+#define WBC_DOMAIN_REFUSE_PASSWORD_CHANGE 0x00000020
+
+struct wbcUserPasswordPolicyInfo {
+ uint32_t min_length_password;
+ uint32_t password_history;
+ uint32_t password_properties;
+ uint64_t expire;
+ uint64_t min_passwordage;
+};
+
+/**
+ * @brief Change Password Reject Reason
+ **/
+
+enum wbcPasswordChangeRejectReason {
+ WBC_PWD_CHANGE_NO_ERROR=0,
+ WBC_PWD_CHANGE_PASSWORD_TOO_SHORT=1,
+ WBC_PWD_CHANGE_PWD_IN_HISTORY=2,
+ WBC_PWD_CHANGE_USERNAME_IN_PASSWORD=3,
+ WBC_PWD_CHANGE_FULLNAME_IN_PASSWORD=4,
+ WBC_PWD_CHANGE_NOT_COMPLEX=5,
+ WBC_PWD_CHANGE_MACHINE_NOT_DEFAULT=6,
+ WBC_PWD_CHANGE_FAILED_BY_FILTER=7,
+ WBC_PWD_CHANGE_PASSWORD_TOO_LONG=8
+};
+
+/* Note: this defines exist for compatibility reasons with existing code */
+#define WBC_PWD_CHANGE_REJECT_OTHER WBC_PWD_CHANGE_NO_ERROR
+#define WBC_PWD_CHANGE_REJECT_TOO_SHORT WBC_PWD_CHANGE_PASSWORD_TOO_SHORT
+#define WBC_PWD_CHANGE_REJECT_IN_HISTORY WBC_PWD_CHANGE_PWD_IN_HISTORY
+#define WBC_PWD_CHANGE_REJECT_COMPLEXITY WBC_PWD_CHANGE_NOT_COMPLEX
+
+/**
+ * @brief Logoff User Parameters
+ **/
+
+struct wbcLogoffUserParams {
+ const char *username;
+ size_t num_blobs;
+ struct wbcNamedBlob *blobs;
+};
+
+/** @brief Credential cache log-on parameters
+ *
+ */
+
+struct wbcCredentialCacheParams {
+ const char *account_name;
+ const char *domain_name;
+ enum wbcCredentialCacheLevel {
+ WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP = 1
+ } level;
+ size_t num_blobs;
+ struct wbcNamedBlob *blobs;
+};
+
+
+/** @brief Info returned by credential cache auth
+ *
+ */
+
+struct wbcCredentialCacheInfo {
+ size_t num_blobs;
+ struct wbcNamedBlob *blobs;
+};
+
+/*
+ * DomainControllerInfo struct
+ */
+struct wbcDomainControllerInfo {
+ char *dc_name;
+};
+
+/*
+ * DomainControllerInfoEx struct
+ */
+struct wbcDomainControllerInfoEx {
+ const char *dc_unc;
+ const char *dc_address;
+ uint16_t dc_address_type;
+ struct wbcGuid *domain_guid;
+ const char *domain_name;
+ const char *forest_name;
+ uint32_t dc_flags;
+ const char *dc_site_name;
+ const char *client_site_name;
+};
+
+/**********************************************************
+ * Memory Management
+ **********************************************************/
+
+/**
+ * @brief Free library allocated memory
+ *
+ * @param * Pointer to free
+ *
+ * @return void
+ **/
+void wbcFreeMemory(void*);
+
+
+/*
+ * Utility functions for dealing with SIDs
+ */
+
+/**
+ * @brief Get a string representation of the SID type
+ *
+ * @param type type of the SID
+ *
+ * @return string representation of the SID type
+ */
+const char* wbcSidTypeString(enum wbcSidType type);
+
+#define WBC_SID_STRING_BUFLEN (15*11+25)
+
+/*
+ * @brief Print a sid into a buffer
+ *
+ * @param sid Binary Security Identifier
+ * @param buf Target buffer
+ * @param buflen Target buffer length
+ *
+ * @return Resulting string length.
+ */
+int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen);
+
+/**
+ * @brief Convert a binary SID to a character string
+ *
+ * @param sid Binary Security Identifier
+ * @param **sid_string Resulting character string
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcSidToString(const struct wbcDomainSid *sid,
+ char **sid_string);
+
+/**
+ * @brief Convert a character string to a binary SID
+ *
+ * @param *sid_string Character string in the form of S-...
+ * @param sid Resulting binary SID
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcStringToSid(const char *sid_string,
+ struct wbcDomainSid *sid);
+
+/*
+ * Utility functions for dealing with GUIDs
+ */
+
+/**
+ * @brief Convert a binary GUID to a character string
+ *
+ * @param guid Binary Guid
+ * @param **guid_string Resulting character string
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGuidToString(const struct wbcGuid *guid,
+ char **guid_string);
+
+/**
+ * @brief Convert a character string to a binary GUID
+ *
+ * @param *guid_string Character string
+ * @param guid Resulting binary GUID
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcStringToGuid(const char *guid_string,
+ struct wbcGuid *guid);
+
+/**
+ * @brief Ping winbindd to see if the daemon is running
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcPing(void);
+
+wbcErr wbcLibraryDetails(struct wbcLibraryDetails **details);
+
+wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **details);
+
+/**********************************************************
+ * Name/SID conversion
+ **********************************************************/
+
+/**
+ * @brief Convert a domain and name to SID
+ *
+ * @param dom_name Domain name (possibly "")
+ * @param name User or group name
+ * @param *sid Pointer to the resolved domain SID
+ * @param *name_type Pointer to the SID type
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcLookupName(const char *dom_name,
+ const char *name,
+ struct wbcDomainSid *sid,
+ enum wbcSidType *name_type);
+
+/**
+ * @brief Convert a SID to a domain and name
+ *
+ * @param *sid Pointer to the domain SID to be resolved
+ * @param domain Resolved Domain name (possibly "")
+ * @param name Resolved User or group name
+ * @param *name_type Pointer to the resolved SID type
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
+ char **domain,
+ char **name,
+ enum wbcSidType *name_type);
+
+struct wbcTranslatedName {
+ enum wbcSidType type;
+ char *name;
+ int domain_index;
+};
+
+wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids,
+ struct wbcDomainInfo **domains, int *num_domains,
+ struct wbcTranslatedName **names);
+
+/**
+ * @brief Translate a collection of RIDs within a domain to names
+ */
+wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
+ int num_rids,
+ uint32_t *rids,
+ const char **domain_name,
+ const char ***names,
+ enum wbcSidType **types);
+
+/*
+ * @brief Get the groups a user belongs to
+ **/
+wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
+ bool domain_groups_only,
+ uint32_t *num_sids,
+ struct wbcDomainSid **sids);
+
+/*
+ * @brief Get alias membership for sids
+ **/
+wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
+ struct wbcDomainSid *sids,
+ uint32_t num_sids,
+ uint32_t **alias_rids,
+ uint32_t *num_alias_rids);
+
+/**
+ * @brief Lists Users
+ **/
+wbcErr wbcListUsers(const char *domain_name,
+ uint32_t *num_users,
+ const char ***users);
+
+/**
+ * @brief Lists Groups
+ **/
+wbcErr wbcListGroups(const char *domain_name,
+ uint32_t *num_groups,
+ const char ***groups);
+
+wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
+ char **pdomain,
+ char **pfullname,
+ enum wbcSidType *pname_type);
+
+/**********************************************************
+ * SID/uid/gid Mappings
+ **********************************************************/
+
+/**
+ * @brief Convert a Windows SID to a Unix uid, allocating an uid if needed
+ *
+ * @param *sid Pointer to the domain SID to be resolved
+ * @param *puid Pointer to the resolved uid_t value
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcSidToUid(const struct wbcDomainSid *sid,
+ uid_t *puid);
+
+/**
+ * @brief Convert a Windows SID to a Unix uid if there already is a mapping
+ *
+ * @param *sid Pointer to the domain SID to be resolved
+ * @param *puid Pointer to the resolved uid_t value
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
+ uid_t *puid);
+
+/**
+ * @brief Convert a Unix uid to a Windows SID, allocating a SID if needed
+ *
+ * @param uid Unix uid to be resolved
+ * @param *sid Pointer to the resolved domain SID
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcUidToSid(uid_t uid,
+ struct wbcDomainSid *sid);
+
+/**
+ * @brief Convert a Unix uid to a Windows SID if there already is a mapping
+ *
+ * @param uid Unix uid to be resolved
+ * @param *sid Pointer to the resolved domain SID
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcQueryUidToSid(uid_t uid,
+ struct wbcDomainSid *sid);
+
+/**
+ * @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
+ *
+ * @param *sid Pointer to the domain SID to be resolved
+ * @param *pgid Pointer to the resolved gid_t value
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcSidToGid(const struct wbcDomainSid *sid,
+ gid_t *pgid);
+
+/**
+ * @brief Convert a Windows SID to a Unix gid if there already is a mapping
+ *
+ * @param *sid Pointer to the domain SID to be resolved
+ * @param *pgid Pointer to the resolved gid_t value
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
+ gid_t *pgid);
+
+/**
+ * @brief Convert a Unix gid to a Windows SID, allocating a SID if needed
+ *
+ * @param gid Unix gid to be resolved
+ * @param *sid Pointer to the resolved domain SID
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcGidToSid(gid_t gid,
+ struct wbcDomainSid *sid);
+
+/**
+ * @brief Convert a Unix gid to a Windows SID if there already is a mapping
+ *
+ * @param gid Unix gid to be resolved
+ * @param *sid Pointer to the resolved domain SID
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcQueryGidToSid(gid_t gid,
+ struct wbcDomainSid *sid);
+
+enum wbcIdType {
+ WBC_ID_TYPE_NOT_SPECIFIED,
+ WBC_ID_TYPE_UID,
+ WBC_ID_TYPE_GID,
+ WBC_ID_TYPE_BOTH
+};
+
+union wbcUnixIdContainer {
+ uid_t uid;
+ gid_t gid;
+};
+
+struct wbcUnixId {
+ enum wbcIdType type;
+ union wbcUnixIdContainer id;
+};
+
+/**
+ * @brief Convert a list of sids to unix ids
+ *
+ * @param sids Pointer to an array of SIDs to convert
+ * @param num_sids Number of SIDs
+ * @param ids Preallocated output array for translated IDs
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
+ struct wbcUnixId *ids);
+
+/**
+ * @brief Obtain a new uid from Winbind
+ *
+ * @param *puid *pointer to the allocated uid
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcAllocateUid(uid_t *puid);
+
+/**
+ * @brief Obtain a new gid from Winbind
+ *
+ * @param *pgid Pointer to the allocated gid
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcAllocateGid(gid_t *pgid);
+
+/**
+ * @brief Set an user id mapping
+ *
+ * @param uid Uid of the desired mapping.
+ * @param *sid Pointer to the sid of the desired mapping.
+ *
+ * @return #wbcErr
+ *
+ * @deprecated This method is not impemented any more and should
+ * be removed in the next major version change.
+ **/
+wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid);
+
+/**
+ * @brief Set a group id mapping
+ *
+ * @param gid Gid of the desired mapping.
+ * @param *sid Pointer to the sid of the desired mapping.
+ *
+ * @return #wbcErr
+ *
+ * @deprecated This method is not impemented any more and should
+ * be removed in the next major version change.
+ **/
+wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid);
+
+/**
+ * @brief Remove a user id mapping
+ *
+ * @param uid Uid of the mapping to remove.
+ * @param *sid Pointer to the sid of the mapping to remove.
+ *
+ * @return #wbcErr
+ *
+ * @deprecated This method is not impemented any more and should
+ * be removed in the next major version change.
+ **/
+wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid);
+
+/**
+ * @brief Remove a group id mapping
+ *
+ * @param gid Gid of the mapping to remove.
+ * @param *sid Pointer to the sid of the mapping to remove.
+ *
+ * @return #wbcErr
+ *
+ * @deprecated This method is not impemented any more and should
+ * be removed in the next major version change.
+ **/
+wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid);
+
+/**
+ * @brief Set the highwater mark for allocated uids.
+ *
+ * @param uid_hwm The new uid highwater mark value
+ *
+ * @return #wbcErr
+ *
+ * @deprecated This method is not impemented any more and should
+ * be removed in the next major version change.
+ **/
+wbcErr wbcSetUidHwm(uid_t uid_hwm);
+
+/**
+ * @brief Set the highwater mark for allocated gids.
+ *
+ * @param gid_hwm The new gid highwater mark value
+ *
+ * @return #wbcErr
+ *
+ * @deprecated This method is not impemented any more and should
+ * be removed in the next major version change.
+ **/
+wbcErr wbcSetGidHwm(gid_t gid_hwm);
+
+/**********************************************************
+ * NSS Lookup User/Group details
+ **********************************************************/
+
+/**
+ * @brief Fill in a struct passwd* for a domain user based
+ * on username
+ *
+ * @param *name Username to lookup
+ * @param **pwd Pointer to resulting struct passwd* from the query.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetpwnam(const char *name, struct passwd **pwd);
+
+/**
+ * @brief Fill in a struct passwd* for a domain user based
+ * on uid
+ *
+ * @param uid Uid to lookup
+ * @param **pwd Pointer to resulting struct passwd* from the query.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd);
+
+/**
+ * @brief Fill in a struct passwd* for a domain user based
+ * on sid
+ *
+ * @param sid Sid to lookup
+ * @param **pwd Pointer to resulting struct passwd* from the query.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetpwsid(struct wbcDomainSid * sid, struct passwd **pwd);
+
+/**
+ * @brief Fill in a struct passwd* for a domain user based
+ * on username
+ *
+ * @param *name Username to lookup
+ * @param **grp Pointer to resulting struct group* from the query.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetgrnam(const char *name, struct group **grp);
+
+/**
+ * @brief Fill in a struct passwd* for a domain user based
+ * on uid
+ *
+ * @param gid Uid to lookup
+ * @param **grp Pointer to resulting struct group* from the query.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetgrgid(gid_t gid, struct group **grp);
+
+/**
+ * @brief Reset the passwd iterator
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcSetpwent(void);
+
+/**
+ * @brief Close the passwd iterator
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcEndpwent(void);
+
+/**
+ * @brief Return the next struct passwd* entry from the pwent iterator
+ *
+ * @param **pwd Pointer to resulting struct passwd* from the query.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetpwent(struct passwd **pwd);
+
+/**
+ * @brief Reset the group iterator
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcSetgrent(void);
+
+/**
+ * @brief Close the group iterator
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcEndgrent(void);
+
+/**
+ * @brief Return the next struct group* entry from the pwent iterator
+ *
+ * @param **grp Pointer to resulting struct group* from the query.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetgrent(struct group **grp);
+
+/**
+ * @brief Return the next struct group* entry from the pwent iterator
+ *
+ * This is similar to #wbcGetgrent, just that the member list is empty
+ *
+ * @param **grp Pointer to resulting struct group* from the query.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetgrlist(struct group **grp);
+
+/**
+ * @brief Return the unix group array belonging to the given user
+ *
+ * @param *account The given user name
+ * @param *num_groups Number of elements returned in the groups array
+ * @param **_groups Pointer to resulting gid_t array.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcGetGroups(const char *account,
+ uint32_t *num_groups,
+ gid_t **_groups);
+
+
+/**********************************************************
+ * Lookup Domain information
+ **********************************************************/
+
+/**
+ * @brief Lookup the current status of a trusted domain
+ *
+ * @param domain The domain to query
+ *
+ * @param dinfo A pointer to store the returned domain_info struct.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcDomainInfo(const char *domain,
+ struct wbcDomainInfo **dinfo);
+
+/**
+ * @brief Lookup the currently contacted DCs
+ *
+ * @param domain The domain to query
+ *
+ * @param num_dcs Number of DCs currently known
+ * @param dc_names Names of the currently known DCs
+ * @param dc_ips IP addresses of the currently known DCs
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcDcInfo(const char *domain, size_t *num_dcs,
+ const char ***dc_names, const char ***dc_ips);
+
+/**
+ * @brief Enumerate the domain trusts known by Winbind
+ *
+ * @param **domains Pointer to the allocated domain list array
+ * @param *num_domains Pointer to number of domains returned
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcListTrusts(struct wbcDomainInfo **domains,
+ size_t *num_domains);
+
+/* Flags for wbcLookupDomainController */
+
+#define WBC_LOOKUP_DC_FORCE_REDISCOVERY 0x00000001
+#define WBC_LOOKUP_DC_DS_REQUIRED 0x00000010
+#define WBC_LOOKUP_DC_DS_PREFERRED 0x00000020
+#define WBC_LOOKUP_DC_GC_SERVER_REQUIRED 0x00000040
+#define WBC_LOOKUP_DC_PDC_REQUIRED 0x00000080
+#define WBC_LOOKUP_DC_BACKGROUND_ONLY 0x00000100
+#define WBC_LOOKUP_DC_IP_REQUIRED 0x00000200
+#define WBC_LOOKUP_DC_KDC_REQUIRED 0x00000400
+#define WBC_LOOKUP_DC_TIMESERV_REQUIRED 0x00000800
+#define WBC_LOOKUP_DC_WRITABLE_REQUIRED 0x00001000
+#define WBC_LOOKUP_DC_GOOD_TIMESERV_PREFERRED 0x00002000
+#define WBC_LOOKUP_DC_AVOID_SELF 0x00004000
+#define WBC_LOOKUP_DC_ONLY_LDAP_NEEDED 0x00008000
+#define WBC_LOOKUP_DC_IS_FLAT_NAME 0x00010000
+#define WBC_LOOKUP_DC_IS_DNS_NAME 0x00020000
+#define WBC_LOOKUP_DC_TRY_NEXTCLOSEST_SITE 0x00040000
+#define WBC_LOOKUP_DC_DS_6_REQUIRED 0x00080000
+#define WBC_LOOKUP_DC_RETURN_DNS_NAME 0x40000000
+#define WBC_LOOKUP_DC_RETURN_FLAT_NAME 0x80000000
+
+/**
+ * @brief Enumerate the domain trusts known by Winbind
+ *
+ * @param domain Name of the domain to query for a DC
+ * @param flags Bit flags used to control the domain location query
+ * @param *dc_info Pointer to the returned domain controller information
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcLookupDomainController(const char *domain,
+ uint32_t flags,
+ struct wbcDomainControllerInfo **dc_info);
+
+/**
+ * @brief Get extended domain controller information
+ *
+ * @param domain Name of the domain to query for a DC
+ * @param guid Guid of the domain to query for a DC
+ * @param site Site of the domain to query for a DC
+ * @param flags Bit flags used to control the domain location query
+ * @param *dc_info Pointer to the returned extended domain controller information
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcLookupDomainControllerEx(const char *domain,
+ struct wbcGuid *guid,
+ const char *site,
+ uint32_t flags,
+ struct wbcDomainControllerInfoEx **dc_info);
+
+/**********************************************************
+ * Athenticate functions
+ **********************************************************/
+
+/**
+ * @brief Authenticate a username/password pair
+ *
+ * @param username Name of user to authenticate
+ * @param password Clear text password os user
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcAuthenticateUser(const char *username,
+ const char *password);
+
+/**
+ * @brief Authenticate with more detailed information
+ *
+ * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH
+ * is not supported yet
+ * @param info Output details on WBC_ERR_SUCCESS
+ * @param error Output details on WBC_ERR_AUTH_ERROR
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
+ struct wbcAuthUserInfo **info,
+ struct wbcAuthErrorInfo **error);
+
+/**
+ * @brief Logon a User
+ *
+ * @param[in] params Pointer to a wbcLogonUserParams structure
+ * @param[out] info Pointer to a pointer to a wbcLogonUserInfo structure
+ * @param[out] error Pointer to a pointer to a wbcAuthErrorInfo structure
+ * @param[out] policy Pointer to a pointer to a wbcUserPasswordPolicyInfo structure
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcLogonUser(const struct wbcLogonUserParams *params,
+ struct wbcLogonUserInfo **info,
+ struct wbcAuthErrorInfo **error,
+ struct wbcUserPasswordPolicyInfo **policy);
+
+/**
+ * @brief Trigger a logoff notification to Winbind for a specific user
+ *
+ * @param username Name of user to remove from Winbind's list of
+ * logged on users.
+ * @param uid Uid assigned to the username
+ * @param ccfilename Absolute path to the Krb5 credentials cache to
+ * be removed
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcLogoffUser(const char *username,
+ uid_t uid,
+ const char *ccfilename);
+
+/**
+ * @brief Trigger an extended logoff notification to Winbind for a specific user
+ *
+ * @param params A wbcLogoffUserParams structure
+ * @param error User output details on error
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params,
+ struct wbcAuthErrorInfo **error);
+
+/**
+ * @brief Change a password for a user
+ *
+ * @param username Name of user to authenticate
+ * @param old_password Old clear text password of user
+ * @param new_password New clear text password of user
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcChangeUserPassword(const char *username,
+ const char *old_password,
+ const char *new_password);
+
+/**
+ * @brief Change a password for a user with more detailed information upon
+ * failure
+ *
+ * @param params Input parameters
+ * @param error User output details on WBC_ERR_PWD_CHANGE_FAILED
+ * @param reject_reason New password reject reason on WBC_ERR_PWD_CHANGE_FAILED
+ * @param policy Password policy output details on WBC_ERR_PWD_CHANGE_FAILED
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
+ struct wbcAuthErrorInfo **error,
+ enum wbcPasswordChangeRejectReason *reject_reason,
+ struct wbcUserPasswordPolicyInfo **policy);
+
+/**
+ * @brief Authenticate a user with cached credentials
+ *
+ * @param *params Pointer to a wbcCredentialCacheParams structure
+ * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure
+ * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
+ struct wbcCredentialCacheInfo **info,
+ struct wbcAuthErrorInfo **error);
+
+/**
+ * @brief Save a password with winbind for doing wbcCredentialCache() later
+ *
+ * @param *user Username
+ * @param *password Password
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcCredentialSave(const char *user, const char *password);
+
+/**********************************************************
+ * Resolve functions
+ **********************************************************/
+
+/**
+ * @brief Resolve a NetbiosName via WINS
+ *
+ * @param name Name to resolve
+ * @param *ip Pointer to the ip address string
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcResolveWinsByName(const char *name, char **ip);
+
+/**
+ * @brief Resolve an IP address via WINS into a NetbiosName
+ *
+ * @param ip The ip address string
+ * @param *name Pointer to the name
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcResolveWinsByIP(const char *ip, char **name);
+
+/**********************************************************
+ * Trusted domain functions
+ **********************************************************/
+
+/**
+ * @brief Trigger a verification of the trust credentials of a specific domain
+ *
+ * @param *domain The name of the domain.
+ * @param error Output details on WBC_ERR_AUTH_ERROR
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcCheckTrustCredentials(const char *domain,
+ struct wbcAuthErrorInfo **error);
+
+/**
+ * @brief Trigger a change of the trust credentials for a specific domain
+ *
+ * @param *domain The name of the domain.
+ * @param error Output details on WBC_ERR_AUTH_ERROR
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcChangeTrustCredentials(const char *domain,
+ struct wbcAuthErrorInfo **error);
+
+/**
+ * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost
+ * version of wbcCheckTrustCredentials
+ *
+ * @param *domain The name of the domain, only NULL for the default domain is
+ * supported yet. Other values than NULL will result in
+ * WBC_ERR_NOT_IMPLEMENTED.
+ * @param error Output details on WBC_ERR_AUTH_ERROR
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error);
+
+/**
+ * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost
+ * version of wbcCheckTrustCredentials
+ *
+ * @param *domain The name of the domain, only NULL for the default domain is
+ * supported yet. Other values than NULL will result in
+ * WBC_ERR_NOT_IMPLEMENTED.
+ * @param error Output details on WBC_ERR_AUTH_ERROR
+ * @param dcname DC that was attempted to ping
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcPingDc2(const char *domain, struct wbcAuthErrorInfo **error,
+ char **dcname);
+
+/**********************************************************
+ * Helper functions
+ **********************************************************/
+
+/**
+ * @brief Initialize a named blob and add to list of blobs
+ *
+ * @param[in,out] num_blobs Pointer to the number of blobs
+ * @param[in,out] blobs Pointer to an array of blobs
+ * @param[in] name Name of the new named blob
+ * @param[in] flags Flags of the new named blob
+ * @param[in] data Blob data of new blob
+ * @param[in] length Blob data length of new blob
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcAddNamedBlob(size_t *num_blobs,
+ struct wbcNamedBlob **blobs,
+ const char *name,
+ uint32_t flags,
+ uint8_t *data,
+ size_t length);
+
+#endif /* _WBCLIENT_H */
diff --git a/src/sss_client/libwbclient/wbclient.pc.in b/src/sss_client/libwbclient/wbclient.pc.in
new file mode 100644
index 000000000..83ae79471
--- /dev/null
+++ b/src/sss_client/libwbclient/wbclient.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: wbclient
+Description: SSSD implementation of Samba wbclient API
+Version: 0.11
+Libs: -L${libdir} -lwbclient
+Cflags:
+URL: http://fedorahosted.org/sssd/, http://www.samba.org
diff --git a/src/sss_client/libwbclient/wbclient_common.c b/src/sss_client/libwbclient/wbclient_common.c
new file mode 100644
index 000000000..4189a349c
--- /dev/null
+++ b/src/sss_client/libwbclient/wbclient_common.c
@@ -0,0 +1,178 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API
+
+ Copyright (C) Gerald (Jerry) Carter 2007
+
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Required Headers */
+
+#include "libwbclient.h"
+
+/** @brief Translate an error value into a string
+ *
+ * @param error
+ *
+ * @return a pointer to a static string
+ **/
+const char *wbcErrorString(wbcErr error)
+{
+ switch (error) {
+ case WBC_ERR_SUCCESS:
+ return "WBC_ERR_SUCCESS";
+ case WBC_ERR_NOT_IMPLEMENTED:
+ return "WBC_ERR_NOT_IMPLEMENTED";
+ case WBC_ERR_UNKNOWN_FAILURE:
+ return "WBC_ERR_UNKNOWN_FAILURE";
+ case WBC_ERR_NO_MEMORY:
+ return "WBC_ERR_NO_MEMORY";
+ case WBC_ERR_INVALID_SID:
+ return "WBC_ERR_INVALID_SID";
+ case WBC_ERR_INVALID_PARAM:
+ return "WBC_ERR_INVALID_PARAM";
+ case WBC_ERR_WINBIND_NOT_AVAILABLE:
+ return "WBC_ERR_WINBIND_NOT_AVAILABLE";
+ case WBC_ERR_DOMAIN_NOT_FOUND:
+ return "WBC_ERR_DOMAIN_NOT_FOUND";
+ case WBC_ERR_INVALID_RESPONSE:
+ return "WBC_ERR_INVALID_RESPONSE";
+ case WBC_ERR_NSS_ERROR:
+ return "WBC_ERR_NSS_ERROR";
+ case WBC_ERR_UNKNOWN_USER:
+ return "WBC_ERR_UNKNOWN_USER";
+ case WBC_ERR_UNKNOWN_GROUP:
+ return "WBC_ERR_UNKNOWN_GROUP";
+ case WBC_ERR_AUTH_ERROR:
+ return "WBC_ERR_AUTH_ERROR";
+ case WBC_ERR_PWD_CHANGE_FAILED:
+ return "WBC_ERR_PWD_CHANGE_FAILED";
+ }
+
+ return "unknown wbcErr value";
+}
+
+#define WBC_MAGIC (0x7a2b0e1e)
+#define WBC_MAGIC_FREE (0x875634fe)
+
+struct wbcMemPrefix {
+ uint32_t magic;
+ void (*destructor)(void *ptr);
+};
+
+static size_t wbcPrefixLen(void)
+{
+ size_t result = sizeof(struct wbcMemPrefix);
+ return (result + 15) & ~15;
+}
+
+static struct wbcMemPrefix *wbcMemToPrefix(void *ptr)
+{
+ return (struct wbcMemPrefix *)((void *)(((char *)ptr) - wbcPrefixLen()));
+}
+
+void *wbcAllocateMemory(size_t nelem, size_t elsize,
+ void (*destructor)(void *ptr))
+{
+ struct wbcMemPrefix *result;
+
+ if (nelem >= (2<<24)/elsize) {
+ /* basic protection against integer wrap */
+ return NULL;
+ }
+
+ result = (struct wbcMemPrefix *)calloc(
+ 1, nelem*elsize + wbcPrefixLen());
+ if (result == NULL) {
+ return NULL;
+ }
+ result->magic = WBC_MAGIC;
+ result->destructor = destructor;
+ return ((char *)result) + wbcPrefixLen();
+}
+
+/* Free library allocated memory */
+void wbcFreeMemory(void *p)
+{
+ struct wbcMemPrefix *wbcMem;
+
+ if (p == NULL) {
+ return;
+ }
+ wbcMem = wbcMemToPrefix(p);
+ if (wbcMem->magic != WBC_MAGIC) {
+ return;
+ }
+
+ /* paranoid check to ensure we don't double free */
+ wbcMem->magic = WBC_MAGIC_FREE;
+
+ if (wbcMem->destructor != NULL) {
+ wbcMem->destructor(p);
+ }
+ free(wbcMem);
+ return;
+}
+
+char *wbcStrDup(const char *str)
+{
+ char *result;
+ size_t len;
+
+ len = strlen(str);
+ result = (char *)wbcAllocateMemory(len+1, sizeof(char), NULL);
+ if (result == NULL) {
+ return NULL;
+ }
+ memcpy(result, str, len+1);
+ return result;
+}
+
+static void wbcStringArrayDestructor(void *ptr)
+{
+ char **p = (char **)ptr;
+ while (*p != NULL) {
+ free(*p);
+ p += 1;
+ }
+}
+
+const char **wbcAllocateStringArray(int num_strings)
+{
+ return (const char **)wbcAllocateMemory(
+ num_strings + 1, sizeof(const char *),
+ wbcStringArrayDestructor);
+}
+
+wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details)
+{
+ struct wbcLibraryDetails *info;
+
+ info = (struct wbcLibraryDetails *)wbcAllocateMemory(
+ 1, sizeof(struct wbcLibraryDetails), NULL);
+
+ if (info == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ info->major_version = WBCLIENT_MAJOR_VERSION;
+ info->minor_version = WBCLIENT_MINOR_VERSION;
+ info->vendor_version = WBCLIENT_VENDOR_VERSION;
+
+ *_details = info;
+ return WBC_ERR_SUCCESS;
+}
diff --git a/src/sss_client/libwbclient/wbclient_internal.h b/src/sss_client/libwbclient/wbclient_internal.h
new file mode 100644
index 000000000..20e2c63a5
--- /dev/null
+++ b/src/sss_client/libwbclient/wbclient_internal.h
@@ -0,0 +1,44 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API
+
+ Copyright (C) Gerald (Jerry) Carter 2007
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WBCLIENT_INTERNAL_H
+#define _WBCLIENT_INTERNAL_H
+
+/* Private functions */
+
+struct winbindd_request;
+struct winbindd_response;
+
+wbcErr wbcRequestResponse(int cmd,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+
+wbcErr wbcRequestResponsePriv(int cmd,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+
+void *wbcAllocateMemory(size_t nelem, size_t elsize,
+ void (*destructor)(void *ptr));
+
+char *wbcStrDup(const char *str);
+const char **wbcAllocateStringArray(int num_strings);
+
+#endif /* _WBCLIENT_INTERNAL_H */
diff --git a/src/sss_client/libwbclient/wbclient_sssd.c b/src/sss_client/libwbclient/wbclient_sssd.c
new file mode 100644
index 000000000..28cc9853d
--- /dev/null
+++ b/src/sss_client/libwbclient/wbclient_sssd.c
@@ -0,0 +1,40 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client API - SSSD version
+
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2014
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/* Required Headers */
+
+#include "libwbclient.h"
+#include "wbc_sssd_internal.h"
+
+wbcErr wbcRequestResponse(int cmd,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
+{
+ /* Helper to make API check happy */
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
+
+wbcErr wbcRequestResponsePriv(int cmd,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
+{
+ /* Helper to make API check happy */
+ WBC_SSSD_NOT_IMPLEMENTED;
+}
diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c
index 11cc5934f..52d9c02e1 100644
--- a/src/tests/dlopen-tests.c
+++ b/src/tests/dlopen-tests.c
@@ -43,6 +43,7 @@ struct so {
{ "libsss_nss_idmap.so", { LIBPFX"libsss_nss_idmap.so", NULL } },
{ "libnss_sss.so", { LIBPFX"libnss_sss.so", NULL } },
{ "pam_sss.so", { LIBPFX"pam_sss.so", NULL } },
+ { "libwbclient.so", { LIBPFX"libwbclient.so", NULL } },
#ifdef BUILD_IFP
{ "libsss_simpleifp.so", { LIBPFX"libsss_simpleifp.so", NULL } },
#endif /* BUILD_IFP */