summaryrefslogtreecommitdiff
path: root/nsswitch
diff options
context:
space:
mode:
authorbubulle <bubulle@alioth.debian.org>2012-01-26 19:58:37 +0000
committerbubulle <bubulle@alioth.debian.org>2012-01-26 19:58:37 +0000
commitcb25bc5ca98dff7a896f596f9f1586a4739ad8ec (patch)
tree31bd310956a0c533e3e46cb88aec6e00b5eedf53 /nsswitch
parent5f021ee1efe415ba8fe4281d0622204a68074ea8 (diff)
downloadsamba-cb25bc5ca98dff7a896f596f9f1586a4739ad8ec.tar.gz
Load samba-3.6.2 into branches/samba/upstream.upstream/3.6.2
git-svn-id: svn://svn.debian.org/svn/pkg-samba/branches/samba/upstream@3992 fc4039ab-9d04-0410-8cac-899223bdd6b0
Diffstat (limited to 'nsswitch')
-rw-r--r--nsswitch/config.m411
-rw-r--r--nsswitch/config.mk41
-rw-r--r--nsswitch/libwbclient/config.mk15
-rw-r--r--nsswitch/libwbclient/libwbclient.h3
-rw-r--r--nsswitch/libwbclient/tests/wbclient.c402
-rw-r--r--nsswitch/libwbclient/wbc_async.c774
-rw-r--r--nsswitch/libwbclient/wbc_guid.c36
-rw-r--r--nsswitch/libwbclient/wbc_idmap.c266
-rw-r--r--nsswitch/libwbclient/wbc_pam.c257
-rw-r--r--nsswitch/libwbclient/wbc_pwd.c201
-rw-r--r--nsswitch/libwbclient/wbc_sid.c549
-rw-r--r--nsswitch/libwbclient/wbc_util.c356
-rw-r--r--nsswitch/libwbclient/wbclient.c132
-rw-r--r--nsswitch/libwbclient/wbclient.h124
-rw-r--r--nsswitch/libwbclient/wbclient_internal.h6
-rw-r--r--nsswitch/libwbclient/wscript_build8
-rw-r--r--nsswitch/nsstest.c139
-rw-r--r--nsswitch/nsstest.m48
-rw-r--r--nsswitch/pam_winbind.c51
-rw-r--r--nsswitch/pam_winbind.h49
-rwxr-xr-xnsswitch/tests/test_wbinfo.sh22
-rw-r--r--nsswitch/wb_common.c136
-rw-r--r--nsswitch/wb_reqtrans.c (renamed from nsswitch/libwbclient/wb_reqtrans.c)2
-rw-r--r--nsswitch/wb_reqtrans.h (renamed from nsswitch/libwbclient/wbc_async.h)42
-rw-r--r--nsswitch/wbinfo.c479
-rw-r--r--nsswitch/winbind_client.h36
-rw-r--r--nsswitch/winbind_nss_hpux.h7
-rw-r--r--nsswitch/winbind_nss_linux.c25
-rw-r--r--nsswitch/winbind_nss_solaris.h26
-rw-r--r--nsswitch/winbind_struct_protocol.h18
-rw-r--r--nsswitch/wins.c99
-rw-r--r--nsswitch/wscript_build41
-rw-r--r--nsswitch/wscript_configure6
33 files changed, 2371 insertions, 1996 deletions
diff --git a/nsswitch/config.m4 b/nsswitch/config.m4
deleted file mode 100644
index 2c8fa17ad9..0000000000
--- a/nsswitch/config.m4
+++ /dev/null
@@ -1,11 +0,0 @@
-AC_CHECK_HEADERS(nss.h nss_common.h ns_api.h )
-
-case "$host_os" in
- *linux*)
- SMB_LIBRARY(nss_winbind,
- [../nsswitch/winbind_nss_linux.o],
- [LIBWINBIND-CLIENT])
- ;;
- *)
- ;;
-esac
diff --git a/nsswitch/config.mk b/nsswitch/config.mk
deleted file mode 100644
index 9ad873bed1..0000000000
--- a/nsswitch/config.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-[SUBSYSTEM::LIBWINBIND-CLIENT]
-PRIVATE_DEPENDENCIES = SOCKET_WRAPPER
-
-LIBWINBIND-CLIENT_OBJ_FILES = $(nsswitchsrcdir)/wb_common.o
-$(LIBWINBIND-CLIENT_OBJ_FILES): CFLAGS+=-DWINBINDD_SOCKET_DIR=\"$(winbindd_socket_dir)\"
-
-#################################
-# Start BINARY nsstest
-[BINARY::nsstest]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBSAMBA-UTIL \
- LIBREPLACE_EXT \
- LIBSAMBA-HOSTCONFIG
-# End BINARY nsstest
-#################################
-
-nsstest_OBJ_FILES = $(nsswitchsrcdir)/nsstest.o
-
-#################################
-# Start BINARY wbinfo
-[BINARY::wbinfo]
-INSTALLDIR = BINDIR
-PRIVATE_DEPENDENCIES = \
- LIBSAMBA-UTIL \
- LIBREPLACE_EXT \
- LIBCLI_AUTH \
- LIBPOPT \
- POPT_SAMBA \
- LIBWINBIND-CLIENT \
- LIBWBCLIENT \
- LIBTEVENT \
- UTIL_TEVENT \
- LIBASYNC_REQ \
- UID_WRAPPER
-# End BINARY nsstest
-#################################
-
-wbinfo_OBJ_FILES = \
- $(nsswitchsrcdir)/wbinfo.o
-$(wbinfo_OBJ_FILES): CFLAGS+=-DWINBINDD_SOCKET_DIR=\"$(winbindd_socket_dir)\"
diff --git a/nsswitch/libwbclient/config.mk b/nsswitch/libwbclient/config.mk
deleted file mode 100644
index ffdab159f8..0000000000
--- a/nsswitch/libwbclient/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-[SUBSYSTEM::LIBWBCLIENT]
-PUBLIC_DEPENDENCIES = LIBASYNC_REQ \
- LIBTEVENT \
- LIBTALLOC \
- UTIL_TEVENT
-
-LIBWBCLIENT_OBJ_FILES = $(addprefix $(libwbclientsrcdir)/, wbc_async.o \
- wbc_guid.o \
- wbc_idmap.o \
- wbclient.o \
- wbc_pam.o \
- wbc_pwd.o \
- wbc_sid.o \
- wbc_util.o \
- wb_reqtrans.o )
diff --git a/nsswitch/libwbclient/libwbclient.h b/nsswitch/libwbclient/libwbclient.h
index 5a25cf462c..867eb4d7c8 100644
--- a/nsswitch/libwbclient/libwbclient.h
+++ b/nsswitch/libwbclient/libwbclient.h
@@ -31,12 +31,9 @@
#include "nsswitch/winbind_nss_config.h"
#include "nsswitch/winbind_struct_protocol.h"
-#include <talloc.h>
-
/* Public headers */
#include "wbclient.h"
-#include "wbc_async.h"
/* Private headers */
diff --git a/nsswitch/libwbclient/tests/wbclient.c b/nsswitch/libwbclient/tests/wbclient.c
index 23fad63025..c6ee531481 100644
--- a/nsswitch/libwbclient/tests/wbclient.c
+++ b/nsswitch/libwbclient/tests/wbclient.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
SMB torture tester
- Copyright (C) Guenther Deschner 2009
+ Copyright (C) Guenther Deschner 2009-2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,10 +17,20 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
+#include "lib/replace/replace.h"
+#include "libcli/util/ntstatus.h"
+#include "libcli/util/werror.h"
+#include "lib/util/data_blob.h"
+#include "lib/util/time.h"
#include "nsswitch/libwbclient/wbclient.h"
#include "torture/smbtorture.h"
#include "torture/winbind/proto.h"
+#include "lib/util/util_net.h"
+#include "lib/util/charset/charset.h"
+#include "libcli/auth/libcli_auth.h"
+#include "source4/param/param.h"
+#include "lib/util/util.h"
+#include "lib/crypto/arcfour.h"
#define WBC_ERROR_EQUAL(x,y) (x == y)
@@ -43,6 +53,16 @@ static bool test_wbc_ping(struct torture_context *tctx)
return true;
}
+static bool test_wbc_pingdc(struct torture_context *tctx)
+{
+ torture_assert_wbc_equal(tctx, wbcPingDc("random_string", NULL), WBC_ERR_NOT_IMPLEMENTED,
+ "wbcPingDc failed");
+ torture_assert_wbc_ok(tctx, wbcPingDc(NULL, NULL),
+ "wbcPingDc failed");
+
+ return true;
+}
+
static bool test_wbc_library_details(struct torture_context *tctx)
{
struct wbcLibraryDetails *details;
@@ -108,6 +128,7 @@ static bool test_wbc_sidtostring(struct torture_context *tctx)
"wbcSidToString failed");
torture_assert_str_equal(tctx, sid_string, sid_string2,
"sid strings differ");
+ wbcFreeMemory(sid_string2);
return true;
}
@@ -124,26 +145,26 @@ static bool test_wbc_guidtostring(struct torture_context *tctx)
"wbcGuidToString failed");
torture_assert_str_equal(tctx, guid_string, guid_string2,
"guid strings differ");
+ wbcFreeMemory(guid_string2);
return true;
}
static bool test_wbc_domain_info(struct torture_context *tctx)
{
- const char *domain_name = NULL;
struct wbcDomainInfo *info;
struct wbcInterfaceDetails *details;
torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
"wbcInterfaceDetails failed");
-
- domain_name = talloc_strdup(tctx, details->netbios_domain);
+ torture_assert_wbc_ok(
+ tctx, wbcDomainInfo(details->netbios_domain, &info),
+ "wbcDomainInfo failed");
wbcFreeMemory(details);
- torture_assert_wbc_ok(tctx, wbcDomainInfo(domain_name, &info),
- "wbcDomainInfo failed");
torture_assert(tctx, info,
"wbcDomainInfo returned NULL pointer");
+ wbcFreeMemory(info);
return true;
}
@@ -185,9 +206,19 @@ static bool test_wbc_users(struct torture_context *tctx)
"wbcLookupSid expected WBC_SID_NAME_USER");
torture_assert(tctx, name,
"wbcLookupSid returned no name");
+ wbcFreeMemory(domain);
+ wbcFreeMemory(name);
torture_assert_wbc_ok(tctx, wbcLookupUserSids(&sid, true, &num_sids, &sids),
"wbcLookupUserSids failed");
+ torture_assert_wbc_ok(
+ tctx, wbcGetDisplayName(&sid, &domain, &name,
+ &name_type),
+ "wbcGetDisplayName failed");
+ wbcFreeMemory(domain);
+ wbcFreeMemory(name);
+ wbcFreeMemory(sids);
}
+ wbcFreeMemory(users);
return true;
}
@@ -225,6 +256,7 @@ static bool test_wbc_groups(struct torture_context *tctx)
torture_assert(tctx, name,
"wbcLookupSid returned no name");
}
+ wbcFreeMemory(groups);
return true;
}
@@ -264,6 +296,7 @@ static bool test_wbc_trusts(struct torture_context *tctx)
"wbcLookupSid returned no name");
*/
}
+ wbcFreeMemory(domains);
return true;
}
@@ -282,6 +315,7 @@ static bool test_wbc_lookupdc(struct torture_context *tctx)
torture_assert_wbc_ok(tctx, wbcLookupDomainController(domain_name, 0, &dc_info),
"wbcLookupDomainController failed");
+ wbcFreeMemory(dc_info);
return true;
}
@@ -300,16 +334,354 @@ static bool test_wbc_lookupdcex(struct torture_context *tctx)
torture_assert_wbc_ok(tctx, wbcLookupDomainControllerEx(domain_name, NULL, NULL, 0, &dc_info),
"wbcLookupDomainControllerEx failed");
+ wbcFreeMemory(dc_info);
+
+ return true;
+}
+
+static bool test_wbc_resolve_winsbyname(struct torture_context *tctx)
+{
+ const char *name;
+ char *ip;
+ wbcErr ret;
+
+ name = torture_setting_string(tctx, "host", NULL);
+
+ ret = wbcResolveWinsByName(name, &ip);
+
+ if (is_ipaddress(name)) {
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_DOMAIN_NOT_FOUND, "wbcResolveWinsByName failed");
+ } else {
+ torture_assert_wbc_ok(tctx, ret, "wbcResolveWinsByName failed");
+ }
+
+ return true;
+}
+
+static bool test_wbc_resolve_winsbyip(struct torture_context *tctx)
+{
+ const char *ip;
+ char *name;
+ wbcErr ret;
+
+ ip = torture_setting_string(tctx, "host", NULL);
+
+ ret = wbcResolveWinsByIP(ip, &name);
+
+ torture_assert_wbc_ok(tctx, ret, "wbcResolveWinsByIP failed");
+
+ wbcFreeMemory(name);
+
+ return true;
+}
+
+static bool test_wbc_lookup_rids(struct torture_context *tctx)
+{
+ struct wbcDomainSid builtin;
+ uint32_t rids[2] = { 544, 545 };
+ const char *domain_name, **names;
+ enum wbcSidType *types;
+ wbcErr ret;
+
+ wbcStringToSid("S-1-5-32", &builtin);
+
+ ret = wbcLookupRids(&builtin, 2, rids, &domain_name, &names,
+ &types);
+ torture_assert_wbc_ok(tctx, ret, "wbcLookupRids failed");
+
+ torture_assert_str_equal(
+ tctx, names[0], "Administrators",
+ "S-1-5-32-544 not mapped to 'Administrators'");
+ torture_assert_str_equal(
+ tctx, names[1], "Users", "S-1-5-32-545 not mapped to 'Users'");
+
+ wbcFreeMemory((char *)domain_name);
+ wbcFreeMemory(names);
+ wbcFreeMemory(types);
+
+ return true;
+}
+
+static bool test_wbc_get_sidaliases(struct torture_context *tctx)
+{
+ struct wbcDomainSid builtin;
+ struct wbcDomainInfo *info;
+ struct wbcInterfaceDetails *details;
+ struct wbcDomainSid sids[2];
+ uint32_t *rids;
+ uint32_t num_rids;
+ wbcErr ret;
+
+ torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
+ "wbcInterfaceDetails failed");
+ torture_assert_wbc_ok(
+ tctx, wbcDomainInfo(details->netbios_domain, &info),
+ "wbcDomainInfo failed");
+ wbcFreeMemory(details);
+
+ sids[0] = info->sid;
+ sids[0].sub_auths[sids[0].num_auths++] = 500;
+ sids[1] = info->sid;
+ sids[1].sub_auths[sids[1].num_auths++] = 512;
+ wbcFreeMemory(info);
+
+ torture_assert_wbc_ok(
+ tctx, wbcStringToSid("S-1-5-32", &builtin),
+ "wbcStringToSid failed");
+
+ ret = wbcGetSidAliases(&builtin, sids, 2, &rids, &num_rids);
+ torture_assert_wbc_ok(tctx, ret, "wbcGetSidAliases failed");
+
+ wbcFreeMemory(rids);
+
+ return true;
+}
+
+static bool test_wbc_authenticate_user_int(struct torture_context *tctx,
+ const char *correct_password)
+{
+ struct wbcAuthUserParams params;
+ struct wbcAuthUserInfo *info = NULL;
+ struct wbcAuthErrorInfo *error = NULL;
+ wbcErr ret;
+
+ ret = wbcAuthenticateUser(getenv("USERNAME"), correct_password);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcAuthenticateUser failed");
+
+ ZERO_STRUCT(params);
+ params.account_name = getenv("USERNAME");
+ params.level = WBC_AUTH_USER_LEVEL_PLAIN;
+ params.password.plaintext = correct_password;
+
+ ret = wbcAuthenticateUserEx(&params, &info, &error);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcAuthenticateUserEx failed");
+ wbcFreeMemory(info);
+ info = NULL;
+
+ wbcFreeMemory(error);
+ error = NULL;
+
+ params.password.plaintext = "wrong";
+ ret = wbcAuthenticateUserEx(&params, &info, &error);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
+ "wbcAuthenticateUserEx succeeded where it "
+ "should have failed");
+ wbcFreeMemory(info);
+ info = NULL;
+
+ wbcFreeMemory(error);
+ error = NULL;
+
+ return true;
+}
+
+static bool test_wbc_authenticate_user(struct torture_context *tctx)
+{
+ return test_wbc_authenticate_user_int(tctx, getenv("PASSWORD"));
+}
+
+static bool test_wbc_change_password(struct torture_context *tctx)
+{
+ wbcErr ret;
+ const char *oldpass = getenv("PASSWORD");
+ const char *newpass = "Koo8irei";
+
+ struct samr_CryptPassword new_nt_password;
+ struct samr_CryptPassword new_lm_password;
+ struct samr_Password old_nt_hash_enc;
+ struct samr_Password old_lanman_hash_enc;
+
+ uint8_t old_nt_hash[16];
+ uint8_t old_lanman_hash[16];
+ uint8_t new_nt_hash[16];
+ uint8_t new_lanman_hash[16];
+
+ struct wbcChangePasswordParams params;
+
+ if (oldpass == NULL) {
+ torture_skip(tctx,
+ "skipping wbcChangeUserPassword test as old password cannot be retrieved\n");
+ }
+
+ ZERO_STRUCT(params);
+
+ E_md4hash(oldpass, old_nt_hash);
+ E_md4hash(newpass, new_nt_hash);
+
+ if (lpcfg_client_lanman_auth(tctx->lp_ctx) &&
+ E_deshash(newpass, new_lanman_hash) &&
+ E_deshash(oldpass, old_lanman_hash)) {
+
+ /* E_deshash returns false for 'long' passwords (> 14
+ DOS chars). This allows us to match Win2k, which
+ does not store a LM hash for these passwords (which
+ would reduce the effective password length to 14) */
+
+ encode_pw_buffer(new_lm_password.data, newpass, STR_UNICODE);
+ arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
+ E_old_pw_hash(new_nt_hash, old_lanman_hash,
+ old_lanman_hash_enc.hash);
+
+ params.old_password.response.old_lm_hash_enc_length =
+ sizeof(old_lanman_hash_enc.hash);
+ params.old_password.response.old_lm_hash_enc_data =
+ old_lanman_hash_enc.hash;
+ params.new_password.response.lm_length =
+ sizeof(new_lm_password.data);
+ params.new_password.response.lm_data =
+ new_lm_password.data;
+ } else {
+ ZERO_STRUCT(new_lm_password);
+ ZERO_STRUCT(old_lanman_hash_enc);
+ }
+
+ encode_pw_buffer(new_nt_password.data, newpass, STR_UNICODE);
+
+ arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
+ E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
+
+ params.old_password.response.old_nt_hash_enc_length =
+ sizeof(old_nt_hash_enc.hash);
+ params.old_password.response.old_nt_hash_enc_data =
+ old_nt_hash_enc.hash;
+ params.new_password.response.nt_length = sizeof(new_nt_password.data);
+ params.new_password.response.nt_data = new_nt_password.data;
+
+ params.level = WBC_CHANGE_PASSWORD_LEVEL_RESPONSE;
+ params.account_name = getenv("USERNAME");
+ params.domain_name = "SAMBA-TEST";
+
+ ret = wbcChangeUserPasswordEx(&params, NULL, NULL, NULL);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcChangeUserPassword failed");
+
+ if (!test_wbc_authenticate_user_int(tctx, "Koo8irei")) {
+ return false;
+ }
+
+ ret = wbcChangeUserPassword(getenv("USERNAME"), "Koo8irei",
+ getenv("PASSWORD"));
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcChangeUserPassword failed");
+
+ return test_wbc_authenticate_user_int(tctx, getenv("PASSWORD"));
+}
+
+static bool test_wbc_logon_user(struct torture_context *tctx)
+{
+ struct wbcLogonUserParams params;
+ struct wbcLogonUserInfo *info = NULL;
+ struct wbcAuthErrorInfo *error = NULL;
+ struct wbcUserPasswordPolicyInfo *policy = NULL;
+ struct wbcInterfaceDetails *iface;
+ struct wbcDomainSid sid;
+ enum wbcSidType sidtype;
+ char *sidstr;
+ wbcErr ret;
+
+ ZERO_STRUCT(params);
+
+ ret = wbcLogonUser(&params, &info, &error, &policy);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_INVALID_PARAM,
+ "wbcLogonUser succeeded where it should "
+ "have failed");
+
+ params.username = getenv("USERNAME");
+ params.password = getenv("PASSWORD");
+
+ ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
+ "foo", 0, discard_const_p(uint8_t, "bar"), 4);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcAddNamedBlob failed");
+
+ ret = wbcLogonUser(&params, &info, &error, &policy);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcLogonUser failed");
+ wbcFreeMemory(info); info = NULL;
+ wbcFreeMemory(error); error = NULL;
+ wbcFreeMemory(policy); policy = NULL;
+
+ params.password = "wrong";
+
+ ret = wbcLogonUser(&params, &info, &error, &policy);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
+ "wbcLogonUser should have failed with "
+ "WBC_ERR_AUTH_ERROR");
+ wbcFreeMemory(info); info = NULL;
+ wbcFreeMemory(error); error = NULL;
+ wbcFreeMemory(policy); policy = NULL;
+
+ ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
+ "membership_of", 0,
+ discard_const_p(uint8_t, "S-1-2-3-4"),
+ strlen("S-1-2-3-4")+1);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcAddNamedBlob failed");
+ params.password = getenv("PASSWORD");
+ ret = wbcLogonUser(&params, &info, &error, &policy);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
+ "wbcLogonUser should have failed with "
+ "WBC_ERR_AUTH_ERROR");
+ wbcFreeMemory(info); info = NULL;
+ wbcFreeMemory(error); error = NULL;
+ wbcFreeMemory(policy); policy = NULL;
+ wbcFreeMemory(params.blobs);
+ params.blobs = NULL; params.num_blobs = 0;
+
+ ret = wbcInterfaceDetails(&iface);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcInterfaceDetails failed");
+
+ ret = wbcLookupName(iface->netbios_domain, getenv("USERNAME"), &sid,
+ &sidtype);
+ wbcFreeMemory(iface);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcLookupName failed");
+
+ ret = wbcSidToString(&sid, &sidstr);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcSidToString failed");
+
+ ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
+ "membership_of", 0,
+ (uint8_t *)sidstr, strlen(sidstr)+1);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcAddNamedBlob failed");
+ wbcFreeMemory(sidstr);
+ params.password = getenv("PASSWORD");
+ ret = wbcLogonUser(&params, &info, &error, &policy);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcLogonUser failed");
+ wbcFreeMemory(info); info = NULL;
+ wbcFreeMemory(error); error = NULL;
+ wbcFreeMemory(policy); policy = NULL;
+ wbcFreeMemory(params.blobs);
+ params.blobs = NULL; params.num_blobs = 0;
return true;
}
+static bool test_wbc_getgroups(struct torture_context *tctx)
+{
+ wbcErr ret;
+ uint32_t num_groups;
+ gid_t *groups;
+
+ ret = wbcGetGroups(getenv("USERNAME"), &num_groups, &groups);
+ torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
+ "wbcGetGroups failed");
+ wbcFreeMemory(groups);
+ return true;
+}
struct torture_suite *torture_wbclient(void)
{
- struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "WBCLIENT");
+ struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "wbclient");
torture_suite_add_simple_test(suite, "wbcPing", test_wbc_ping);
+ torture_suite_add_simple_test(suite, "wbcPingDc", test_wbc_pingdc);
torture_suite_add_simple_test(suite, "wbcLibraryDetails", test_wbc_library_details);
torture_suite_add_simple_test(suite, "wbcInterfaceDetails", test_wbc_interface_details);
torture_suite_add_simple_test(suite, "wbcSidTypeString", test_wbc_sidtypestring);
@@ -321,6 +693,20 @@ struct torture_suite *torture_wbclient(void)
torture_suite_add_simple_test(suite, "wbcListTrusts", test_wbc_trusts);
torture_suite_add_simple_test(suite, "wbcLookupDomainController", test_wbc_lookupdc);
torture_suite_add_simple_test(suite, "wbcLookupDomainControllerEx", test_wbc_lookupdcex);
+ torture_suite_add_simple_test(suite, "wbcResolveWinsByName", test_wbc_resolve_winsbyname);
+ torture_suite_add_simple_test(suite, "wbcResolveWinsByIP", test_wbc_resolve_winsbyip);
+ torture_suite_add_simple_test(suite, "wbcLookupRids",
+ test_wbc_lookup_rids);
+ torture_suite_add_simple_test(suite, "wbcGetSidAliases",
+ test_wbc_get_sidaliases);
+ torture_suite_add_simple_test(suite, "wbcAuthenticateUser",
+ test_wbc_authenticate_user);
+ torture_suite_add_simple_test(suite, "wbcLogonUser",
+ test_wbc_logon_user);
+ torture_suite_add_simple_test(suite, "wbcChangeUserPassword",
+ test_wbc_change_password);
+ torture_suite_add_simple_test(suite, "wbcGetGroups",
+ test_wbc_getgroups);
return suite;
}
diff --git a/nsswitch/libwbclient/wbc_async.c b/nsswitch/libwbclient/wbc_async.c
deleted file mode 100644
index bb95b91740..0000000000
--- a/nsswitch/libwbclient/wbc_async.c
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Infrastructure for async winbind requests
- Copyright (C) Volker Lendecke 2008
-
- ** NOTE! The following LGPL license applies to the wbclient
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- 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/>.
-*/
-
-#include "replace.h"
-#include "system/filesys.h"
-#include "system/network.h"
-#include <talloc.h>
-#include <tevent.h>
-#include "lib/async_req/async_sock.h"
-#include "nsswitch/winbind_struct_protocol.h"
-#include "nsswitch/libwbclient/wbclient.h"
-#include "nsswitch/libwbclient/wbc_async.h"
-
-wbcErr map_wbc_err_from_errno(int error)
-{
- switch(error) {
- case EPERM:
- case EACCES:
- return WBC_ERR_AUTH_ERROR;
- case ENOMEM:
- return WBC_ERR_NO_MEMORY;
- case EIO:
- default:
- return WBC_ERR_UNKNOWN_FAILURE;
- }
-}
-
-bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err)
-{
- enum tevent_req_state state;
- uint64_t error;
- if (!tevent_req_is_error(req, &state, &error)) {
- *pwbc_err = WBC_ERR_SUCCESS;
- return false;
- }
-
- switch (state) {
- case TEVENT_REQ_USER_ERROR:
- *pwbc_err = error;
- break;
- case TEVENT_REQ_TIMED_OUT:
- *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
- break;
- case TEVENT_REQ_NO_MEMORY:
- *pwbc_err = WBC_ERR_NO_MEMORY;
- break;
- default:
- *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
- break;
- }
- return true;
-}
-
-wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req)
-{
- wbcErr wbc_err;
-
- if (tevent_req_is_wbcerr(req, &wbc_err)) {
- return wbc_err;
- }
-
- return WBC_ERR_SUCCESS;
-}
-
-struct wbc_debug_ops {
- void (*debug)(void *context, enum wbcDebugLevel level,
- const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
- void *context;
-};
-
-struct wb_context {
- struct tevent_queue *queue;
- int fd;
- bool is_priv;
- const char *dir;
- struct wbc_debug_ops debug_ops;
-};
-
-static int make_nonstd_fd(int fd)
-{
- int i;
- int sys_errno = 0;
- int fds[3];
- int num_fds = 0;
-
- if (fd == -1) {
- return -1;
- }
- while (fd < 3) {
- fds[num_fds++] = fd;
- fd = dup(fd);
- if (fd == -1) {
- sys_errno = errno;
- break;
- }
- }
- for (i=0; i<num_fds; i++) {
- close(fds[i]);
- }
- if (fd == -1) {
- errno = sys_errno;
- }
- return fd;
-}
-
-/****************************************************************************
- Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
- else
- if SYSV use O_NDELAY
- if BSD use FNDELAY
- Set close on exec also.
-****************************************************************************/
-
-static int make_safe_fd(int fd)
-{
- int result, flags;
- int new_fd = make_nonstd_fd(fd);
-
- if (new_fd == -1) {
- goto fail;
- }
-
- /* Socket should be nonblocking. */
-
-#ifdef O_NONBLOCK
-#define FLAG_TO_SET O_NONBLOCK
-#else
-#ifdef SYSV
-#define FLAG_TO_SET O_NDELAY
-#else /* BSD */
-#define FLAG_TO_SET FNDELAY
-#endif
-#endif
-
- if ((flags = fcntl(new_fd, F_GETFL)) == -1) {
- goto fail;
- }
-
- flags |= FLAG_TO_SET;
- if (fcntl(new_fd, F_SETFL, flags) == -1) {
- goto fail;
- }
-
-#undef FLAG_TO_SET
-
- /* Socket should be closed on exec() */
-#ifdef FD_CLOEXEC
- result = flags = fcntl(new_fd, F_GETFD, 0);
- if (flags >= 0) {
- flags |= FD_CLOEXEC;
- result = fcntl( new_fd, F_SETFD, flags );
- }
- if (result < 0) {
- goto fail;
- }
-#endif
- return new_fd;
-
- fail:
- if (new_fd != -1) {
- int sys_errno = errno;
- close(new_fd);
- errno = sys_errno;
- }
- return -1;
-}
-
-/* Just put a prototype to avoid moving the whole function around */
-static const char *winbindd_socket_dir(void);
-
-struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx, const char* dir)
-{
- struct wb_context *result;
-
- result = talloc(mem_ctx, struct wb_context);
- if (result == NULL) {
- return NULL;
- }
- result->queue = tevent_queue_create(result, "wb_trans");
- if (result->queue == NULL) {
- TALLOC_FREE(result);
- return NULL;
- }
- result->fd = -1;
- result->is_priv = false;
-
- if (dir != NULL) {
- result->dir = talloc_strdup(result, dir);
- } else {
- result->dir = winbindd_socket_dir();
- }
- if (result->dir == NULL) {
- TALLOC_FREE(result);
- return NULL;
- }
- return result;
-}
-
-struct wb_connect_state {
- int dummy;
-};
-
-static void wbc_connect_connected(struct tevent_req *subreq);
-
-static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx,
- const char *dir)
-{
- struct tevent_req *result, *subreq;
- struct wb_connect_state *state;
- struct sockaddr_un sunaddr;
- struct stat st;
- char *path = NULL;
- wbcErr wbc_err;
-
- result = tevent_req_create(mem_ctx, &state, struct wb_connect_state);
- if (result == NULL) {
- return NULL;
- }
-
- if (wb_ctx->fd != -1) {
- close(wb_ctx->fd);
- wb_ctx->fd = -1;
- }
-
- /* Check permissions on unix socket directory */
-
- if (lstat(dir, &st) == -1) {
- wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
- goto post_status;
- }
-
- if (!S_ISDIR(st.st_mode) ||
- (st.st_uid != 0 && st.st_uid != geteuid())) {
- wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
- goto post_status;
- }
-
- /* Connect to socket */
-
- path = talloc_asprintf(mem_ctx, "%s/%s", dir,
- WINBINDD_SOCKET_NAME);
- if (path == NULL) {
- goto nomem;
- }
-
- sunaddr.sun_family = AF_UNIX;
- strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
- TALLOC_FREE(path);
-
- /* If socket file doesn't exist, don't bother trying to connect
- with retry. This is an attempt to make the system usable when
- the winbindd daemon is not running. */
-
- if ((lstat(sunaddr.sun_path, &st) == -1)
- || !S_ISSOCK(st.st_mode)
- || (st.st_uid != 0 && st.st_uid != geteuid())) {
- wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
- goto post_status;
- }
-
- wb_ctx->fd = make_safe_fd(socket(AF_UNIX, SOCK_STREAM, 0));
- if (wb_ctx->fd == -1) {
- wbc_err = map_wbc_err_from_errno(errno);
- goto post_status;
- }
-
- subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd,
- (struct sockaddr *)(void *)&sunaddr,
- sizeof(sunaddr));
- if (subreq == NULL) {
- goto nomem;
- }
- tevent_req_set_callback(subreq, wbc_connect_connected, result);
- return result;
-
- post_status:
- tevent_req_error(result, wbc_err);
- return tevent_req_post(result, ev);
- nomem:
- TALLOC_FREE(result);
- return NULL;
-}
-
-static void wbc_connect_connected(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- int res, err;
-
- res = async_connect_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (res == -1) {
- tevent_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
- tevent_req_done(req);
-}
-
-static wbcErr wb_connect_recv(struct tevent_req *req)
-{
- return tevent_req_simple_recv_wbcerr(req);
-}
-
-static const char *winbindd_socket_dir(void)
-{
-#ifdef SOCKET_WRAPPER
- const char *env_dir;
-
- env_dir = getenv(WINBINDD_SOCKET_DIR_ENVVAR);
- if (env_dir) {
- return env_dir;
- }
-#endif
-
- return WINBINDD_SOCKET_DIR;
-}
-
-struct wb_open_pipe_state {
- struct wb_context *wb_ctx;
- struct tevent_context *ev;
- bool need_priv;
- struct winbindd_request wb_req;
-};
-
-static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq);
-static void wb_open_pipe_ping_done(struct tevent_req *subreq);
-static void wb_open_pipe_getpriv_done(struct tevent_req *subreq);
-static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq);
-
-static struct tevent_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx,
- bool need_priv)
-{
- struct tevent_req *result, *subreq;
- struct wb_open_pipe_state *state;
-
- result = tevent_req_create(mem_ctx, &state, struct wb_open_pipe_state);
- if (result == NULL) {
- return NULL;
- }
- state->wb_ctx = wb_ctx;
- state->ev = ev;
- state->need_priv = need_priv;
-
- if (wb_ctx->fd != -1) {
- close(wb_ctx->fd);
- wb_ctx->fd = -1;
- }
-
- subreq = wb_connect_send(state, ev, wb_ctx, wb_ctx->dir);
- if (subreq == NULL) {
- goto fail;
- }
- tevent_req_set_callback(subreq, wb_open_pipe_connect_nonpriv_done,
- result);
- return result;
-
- fail:
- TALLOC_FREE(result);
- return NULL;
-}
-
-static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_open_pipe_state *state = tevent_req_data(
- req, struct wb_open_pipe_state);
- wbcErr wbc_err;
-
- wbc_err = wb_connect_recv(subreq);
- TALLOC_FREE(subreq);
- if (!WBC_ERROR_IS_OK(wbc_err)) {
- state->wb_ctx->is_priv = true;
- tevent_req_error(req, wbc_err);
- return;
- }
-
- ZERO_STRUCT(state->wb_req);
- state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
- state->wb_req.pid = getpid();
-
- subreq = wb_simple_trans_send(state, state->ev, NULL,
- state->wb_ctx->fd, &state->wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_open_pipe_ping_done, req);
-}
-
-static void wb_open_pipe_ping_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_open_pipe_state *state = tevent_req_data(
- req, struct wb_open_pipe_state);
- struct winbindd_response *wb_resp;
- int ret, err;
-
- ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err);
- TALLOC_FREE(subreq);
- if (ret == -1) {
- tevent_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- if (!state->need_priv) {
- tevent_req_done(req);
- return;
- }
-
- state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
- state->wb_req.pid = getpid();
-
- subreq = wb_simple_trans_send(state, state->ev, NULL,
- state->wb_ctx->fd, &state->wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_open_pipe_getpriv_done, req);
-}
-
-static void wb_open_pipe_getpriv_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_open_pipe_state *state = tevent_req_data(
- req, struct wb_open_pipe_state);
- struct winbindd_response *wb_resp = NULL;
- int ret, err;
-
- ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err);
- TALLOC_FREE(subreq);
- if (ret == -1) {
- tevent_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- close(state->wb_ctx->fd);
- state->wb_ctx->fd = -1;
-
- subreq = wb_connect_send(state, state->ev, state->wb_ctx,
- (char *)wb_resp->extra_data.data);
- TALLOC_FREE(wb_resp);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_open_pipe_connect_priv_done, req);
-}
-
-static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_open_pipe_state *state = tevent_req_data(
- req, struct wb_open_pipe_state);
- wbcErr wbc_err;
-
- wbc_err = wb_connect_recv(subreq);
- TALLOC_FREE(subreq);
- if (!WBC_ERROR_IS_OK(wbc_err)) {
- tevent_req_error(req, wbc_err);
- return;
- }
- state->wb_ctx->is_priv = true;
- tevent_req_done(req);
-}
-
-static wbcErr wb_open_pipe_recv(struct tevent_req *req)
-{
- return tevent_req_simple_recv_wbcerr(req);
-}
-
-struct wb_trans_state {
- struct wb_trans_state *prev, *next;
- struct wb_context *wb_ctx;
- struct tevent_context *ev;
- struct winbindd_request *wb_req;
- struct winbindd_response *wb_resp;
- bool need_priv;
-};
-
-static bool closed_fd(int fd)
-{
- struct timeval tv;
- fd_set r_fds;
- int selret;
-
- if (fd < 0 || fd >= FD_SETSIZE) {
- return true;
- }
-
- FD_ZERO(&r_fds);
- FD_SET(fd, &r_fds);
- ZERO_STRUCT(tv);
-
- selret = select(fd+1, &r_fds, NULL, NULL, &tv);
- if (selret == -1) {
- return true;
- }
- if (selret == 0) {
- return false;
- }
- return (FD_ISSET(fd, &r_fds));
-}
-
-static void wb_trans_trigger(struct tevent_req *req, void *private_data);
-static void wb_trans_connect_done(struct tevent_req *subreq);
-static void wb_trans_done(struct tevent_req *subreq);
-static void wb_trans_retry_wait_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx, bool need_priv,
- struct winbindd_request *wb_req)
-{
- struct tevent_req *req;
- struct wb_trans_state *state;
-
- req = tevent_req_create(mem_ctx, &state, struct wb_trans_state);
- if (req == NULL) {
- return NULL;
- }
- state->wb_ctx = wb_ctx;
- state->ev = ev;
- state->wb_req = wb_req;
- state->need_priv = need_priv;
-
- if (!tevent_queue_add(wb_ctx->queue, ev, req, wb_trans_trigger,
- NULL)) {
- tevent_req_nomem(NULL, req);
- return tevent_req_post(req, ev);
- }
- return req;
-}
-
-static void wb_trans_trigger(struct tevent_req *req, void *private_data)
-{
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- struct tevent_req *subreq;
-
- if ((state->wb_ctx->fd != -1) && closed_fd(state->wb_ctx->fd)) {
- close(state->wb_ctx->fd);
- state->wb_ctx->fd = -1;
- }
-
- if ((state->wb_ctx->fd == -1)
- || (state->need_priv && !state->wb_ctx->is_priv)) {
- subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
- state->need_priv);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_trans_connect_done, req);
- return;
- }
-
- state->wb_req->pid = getpid();
-
- subreq = wb_simple_trans_send(state, state->ev, NULL,
- state->wb_ctx->fd, state->wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_trans_done, req);
-}
-
-static bool wb_trans_retry(struct tevent_req *req,
- struct wb_trans_state *state,
- wbcErr wbc_err)
-{
- struct tevent_req *subreq;
-
- if (WBC_ERROR_IS_OK(wbc_err)) {
- return false;
- }
-
- if (wbc_err == WBC_ERR_WINBIND_NOT_AVAILABLE) {
- /*
- * Winbind not around or we can't connect to the pipe. Fail
- * immediately.
- */
- tevent_req_error(req, wbc_err);
- return true;
- }
-
- /*
- * The transfer as such failed, retry after one second
- */
-
- if (state->wb_ctx->fd != -1) {
- close(state->wb_ctx->fd);
- state->wb_ctx->fd = -1;
- }
-
- subreq = tevent_wakeup_send(state, state->ev,
- tevent_timeval_current_ofs(1, 0));
- if (tevent_req_nomem(subreq, req)) {
- return true;
- }
- tevent_req_set_callback(subreq, wb_trans_retry_wait_done, req);
- return true;
-}
-
-static void wb_trans_retry_wait_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- bool ret;
-
- ret = tevent_wakeup_recv(subreq);
- TALLOC_FREE(subreq);
- if (!ret) {
- tevent_req_error(req, WBC_ERR_UNKNOWN_FAILURE);
- return;
- }
-
- subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
- state->need_priv);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_trans_connect_done, req);
-}
-
-static void wb_trans_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- wbcErr wbc_err;
-
- wbc_err = wb_open_pipe_recv(subreq);
- TALLOC_FREE(subreq);
-
- if (wb_trans_retry(req, state, wbc_err)) {
- return;
- }
-
- subreq = wb_simple_trans_send(state, state->ev, NULL,
- state->wb_ctx->fd, state->wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_trans_done, req);
-}
-
-static void wb_trans_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- int ret, err;
-
- ret = wb_simple_trans_recv(subreq, state, &state->wb_resp, &err);
- TALLOC_FREE(subreq);
- if ((ret == -1)
- && wb_trans_retry(req, state, map_wbc_err_from_errno(err))) {
- return;
- }
-
- tevent_req_done(req);
-}
-
-wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presponse)
-{
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- wbcErr wbc_err;
-
- if (tevent_req_is_wbcerr(req, &wbc_err)) {
- return wbc_err;
- }
-
- *presponse = talloc_move(mem_ctx, &state->wb_resp);
- return WBC_ERR_SUCCESS;
-}
-
-/********************************************************************
- * Debug wrapper functions, modeled (with lot's of code copied as is)
- * after the tevent debug wrapper functions
- ********************************************************************/
-
-/*
- this allows the user to choose their own debug function
-*/
-int wbcSetDebug(struct wb_context *wb_ctx,
- void (*debug)(void *context,
- enum wbcDebugLevel level,
- const char *fmt,
- va_list ap) PRINTF_ATTRIBUTE(3,0),
- void *context)
-{
- wb_ctx->debug_ops.debug = debug;
- wb_ctx->debug_ops.context = context;
- return 0;
-}
-
-/*
- debug function for wbcSetDebugStderr
-*/
-static void wbcDebugStderr(void *private_data,
- enum wbcDebugLevel level,
- const char *fmt,
- va_list ap) PRINTF_ATTRIBUTE(3,0);
-static void wbcDebugStderr(void *private_data,
- enum wbcDebugLevel level,
- const char *fmt, va_list ap)
-{
- if (level <= WBC_DEBUG_WARNING) {
- vfprintf(stderr, fmt, ap);
- }
-}
-
-/*
- convenience function to setup debug messages on stderr
- messages of level WBC_DEBUG_WARNING and higher are printed
-*/
-int wbcSetDebugStderr(struct wb_context *wb_ctx)
-{
- return wbcSetDebug(wb_ctx, wbcDebugStderr, wb_ctx);
-}
-
-/*
- * log a message
- *
- * The default debug action is to ignore debugging messages.
- * This is the most appropriate action for a library.
- * Applications using the library must decide where to
- * redirect debugging messages
-*/
-void wbcDebug(struct wb_context *wb_ctx, enum wbcDebugLevel level,
- const char *fmt, ...)
-{
- va_list ap;
- if (!wb_ctx) {
- return;
- }
- if (wb_ctx->debug_ops.debug == NULL) {
- return;
- }
- va_start(ap, fmt);
- wb_ctx->debug_ops.debug(wb_ctx->debug_ops.context, level, fmt, ap);
- va_end(ap);
-}
diff --git a/nsswitch/libwbclient/wbc_guid.c b/nsswitch/libwbclient/wbc_guid.c
index d55a197973..52a64ca580 100644
--- a/nsswitch/libwbclient/wbc_guid.c
+++ b/nsswitch/libwbclient/wbc_guid.c
@@ -29,28 +29,24 @@
wbcErr wbcGuidToString(const struct wbcGuid *guid,
char **guid_string)
{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ char *result;
- if (!guid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ result = (char *)wbcAllocateMemory(37, 1, NULL);
+ if (result == NULL) {
+ return WBC_ERR_NO_MEMORY;
}
-
- *guid_string = talloc_asprintf(NULL,
- "%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]);
- BAIL_ON_PTR_ERROR((*guid_string), wbc_status);
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- return wbc_status;
+ 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 */
diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
index bde14411ab..ad3cfe6770 100644
--- a/nsswitch/libwbclient/wbc_idmap.c
+++ b/nsswitch/libwbclient/wbc_idmap.c
@@ -5,7 +5,6 @@
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
@@ -24,13 +23,13 @@
#include "replace.h"
#include "libwbclient.h"
+#include "../winbind_client.h"
/* Convert a Windows SID to a Unix uid, allocating an uid if needed */
wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
{
struct winbindd_request request;
struct winbindd_response response;
- char *sid_string = NULL;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
if (!sid || !puid) {
@@ -43,11 +42,7 @@ wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
+ wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
/* Make request */
@@ -125,7 +120,6 @@ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
struct winbindd_request request;
struct winbindd_response response;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
if (!sid || !pgid) {
wbc_status = WBC_ERR_INVALID_PARAM;
@@ -137,11 +131,7 @@ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
+ wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
/* Make request */
@@ -158,6 +148,7 @@ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
return wbc_status;
}
+
/* Convert a Windows SID to a Unix gid if there already is a mapping */
wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
@@ -166,6 +157,7 @@ wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
return WBC_ERR_NOT_IMPLEMENTED;
}
+
/* Convert a Unix gid to a Windows SID, allocating a SID if needed */
wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid)
{
@@ -270,200 +262,130 @@ wbcErr wbcAllocateGid(gid_t *pgid)
#define _ID_TYPE_UID 1
#define _ID_TYPE_GID 2
-/* Set an user id mapping */
+/* Set an user id mapping - not implemented any more */
wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid)
{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid) {
- return WBC_ERR_INVALID_PARAM;
- }
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = uid;
- request.data.dual_idmapset.type = _ID_TYPE_UID;
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dual_idmapset.sid, sid_string,
- sizeof(request.data.dual_idmapset.sid)-1);
- wbcFreeMemory(sid_string);
-
- wbc_status = wbcRequestResponsePriv(WINBINDD_SET_MAPPING,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
+ return WBC_ERR_NOT_IMPLEMENTED;
}
-/* Set a group id mapping */
+/* Set a group id mapping - not implemented any more */
wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid)
{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid) {
- return WBC_ERR_INVALID_PARAM;
- }
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = gid;
- request.data.dual_idmapset.type = _ID_TYPE_GID;
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dual_idmapset.sid, sid_string,
- sizeof(request.data.dual_idmapset.sid)-1);
- wbcFreeMemory(sid_string);
-
- wbc_status = wbcRequestResponsePriv(WINBINDD_SET_MAPPING,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
+ return WBC_ERR_NOT_IMPLEMENTED;
}
-/* Remove a user id mapping */
+/* Remove a user id mapping - not implemented any more */
wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid)
{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid) {
- return WBC_ERR_INVALID_PARAM;
- }
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = uid;
- request.data.dual_idmapset.type = _ID_TYPE_UID;
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dual_idmapset.sid, sid_string,
- sizeof(request.data.dual_idmapset.sid)-1);
- wbcFreeMemory(sid_string);
-
- wbc_status = wbcRequestResponsePriv(WINBINDD_REMOVE_MAPPING,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- done:
- return wbc_status;
+ return WBC_ERR_NOT_IMPLEMENTED;
}
-/* Remove a group id mapping */
+/* Remove a group id mapping - not implemented any more */
wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid)
{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
-
- if (!sid) {
- return WBC_ERR_INVALID_PARAM;
- }
-
- /* Initialise request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
-
- /* Make request */
-
- request.data.dual_idmapset.id = gid;
- request.data.dual_idmapset.type = _ID_TYPE_GID;
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.dual_idmapset.sid, sid_string,
- sizeof(request.data.dual_idmapset.sid)-1);
- wbcFreeMemory(sid_string);
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
- wbc_status = wbcRequestResponsePriv(WINBINDD_REMOVE_MAPPING,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
+/* Set the highwater mark for allocated uids - not implemented any more */
+wbcErr wbcSetUidHwm(uid_t uid_hwm)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
- done:
- return wbc_status;
+/* Set the highwater mark for allocated gids - not implemented any more */
+wbcErr wbcSetGidHwm(gid_t gid_hwm)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
}
-/* Set the highwater mark for allocated uids. */
-wbcErr wbcSetUidHwm(uid_t uid_hwm)
+/* Convert a list of SIDs */
+wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
+ struct wbcUnixId *ids)
{
struct winbindd_request request;
struct winbindd_response response;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ int buflen, extra_len;
+ uint32_t i;
+ char *sidlist, *p, *extra_data;
- /* Initialise request */
+ buflen = num_sids * (WBC_SID_STRING_BUFLEN + 1) + 1;
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
+ sidlist = (char *)malloc(buflen);
+ if (sidlist == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
- /* Make request */
+ p = sidlist;
- request.data.dual_idmapset.id = uid_hwm;
- request.data.dual_idmapset.type = _ID_TYPE_UID;
+ for (i=0; i<num_sids; i++) {
+ int remaining;
+ int len;
- wbc_status = wbcRequestResponsePriv(WINBINDD_SET_HWM,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
+ remaining = buflen - (p - sidlist);
- done:
- return wbc_status;
-}
+ len = wbcSidToStringBuf(&sids[i], p, remaining);
+ if (len > remaining) {
+ free(sidlist);
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
-/* Set the highwater mark for allocated gids. */
-wbcErr wbcSetGidHwm(gid_t gid_hwm)
-{
- struct winbindd_request request;
- struct winbindd_response response;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- /* Initialise request */
+ p += len;
+ *p++ = '\n';
+ }
+ *p++ = '\0';
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- /* Make request */
+ request.extra_data.data = sidlist;
+ request.extra_len = p - sidlist;
- request.data.dual_idmapset.id = gid_hwm;
- request.data.dual_idmapset.type = _ID_TYPE_GID;
+ wbc_status = wbcRequestResponse(WINBINDD_SIDS_TO_XIDS,
+ &request, &response);
+ free(sidlist);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
- wbc_status = wbcRequestResponsePriv(WINBINDD_SET_HWM,
- &request, &response);
- BAIL_ON_WBC_ERROR(wbc_status);
+ extra_len = response.length - sizeof(struct winbindd_response);
+ extra_data = (char *)response.extra_data.data;
- done:
+ if ((extra_len <= 0) || (extra_data[extra_len-1] != '\0')) {
+ goto wbc_err_invalid;
+ }
+
+ p = extra_data;
+
+ for (i=0; i<num_sids; i++) {
+ struct wbcUnixId *id = &ids[i];
+ char *q;
+
+ switch (p[0]) {
+ case 'U':
+ id->type = WBC_ID_TYPE_UID;
+ id->id.uid = strtoul(p+1, &q, 10);
+ break;
+ case 'G':
+ id->type = WBC_ID_TYPE_GID;
+ id->id.gid = strtoul(p+1, &q, 10);
+ break;
+ default:
+ id->type = WBC_ID_TYPE_NOT_SPECIFIED;
+ q = p;
+ break;
+ };
+ if (q[0] != '\n') {
+ goto wbc_err_invalid;
+ }
+ p = q+1;
+ }
+ wbc_status = WBC_ERR_SUCCESS;
+ goto done;
+
+wbc_err_invalid:
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+done:
+ winbindd_free_response(&response);
return wbc_status;
}
diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c
index 8c725d2fca..21f2c5d050 100644
--- a/nsswitch/libwbclient/wbc_pam.c
+++ b/nsswitch/libwbclient/wbc_pam.c
@@ -25,6 +25,7 @@
#include "replace.h"
#include "libwbclient.h"
+#include "../winbind_client.h"
/* Authenticate a username/password pair */
wbcErr wbcAuthenticateUser(const char *username,
@@ -46,8 +47,36 @@ done:
return wbc_status;
}
-static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
+static bool sid_attr_compose(struct wbcSidWithAttr *s,
+ const struct wbcDomainSid *d,
+ uint32_t rid, uint32_t attr)
+{
+ if (d->num_auths >= WBC_MAXSUBAUTHS) {
+ return false;
+ }
+ s->sid = *d;
+ s->sid.sub_auths[s->sid.num_auths++] = rid;
+ s->attributes = attr;
+ return true;
+}
+
+static void wbcAuthUserInfoDestructor(void *ptr)
+{
+ struct wbcAuthUserInfo *i = (struct wbcAuthUserInfo *)ptr;
+ free(i->account_name);
+ free(i->user_principal);
+ free(i->full_name);
+ free(i->domain_name);
+ free(i->dns_domain_name);
+ free(i->logon_server);
+ free(i->logon_script);
+ free(i->profile_path);
+ free(i->home_directory);
+ free(i->home_drive);
+ free(i->sids);
+}
+
+static wbcErr wbc_create_auth_info(const struct winbindd_response *resp,
struct wbcAuthUserInfo **_i)
{
wbcErr wbc_status = WBC_ERR_SUCCESS;
@@ -57,17 +86,19 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
uint32_t sn = 0;
uint32_t j;
- i = talloc(mem_ctx, struct wbcAuthUserInfo);
+ i = (struct wbcAuthUserInfo *)wbcAllocateMemory(
+ 1, sizeof(struct wbcAuthUserInfo),
+ wbcAuthUserInfoDestructor);
BAIL_ON_PTR_ERROR(i, wbc_status);
i->user_flags = resp->data.auth.info3.user_flgs;
- i->account_name = talloc_strdup(i, resp->data.auth.info3.user_name);
+ i->account_name = strdup(resp->data.auth.info3.user_name);
BAIL_ON_PTR_ERROR(i->account_name, wbc_status);
i->user_principal= NULL;
- i->full_name = talloc_strdup(i, resp->data.auth.info3.full_name);
+ i->full_name = strdup(resp->data.auth.info3.full_name);
BAIL_ON_PTR_ERROR(i->full_name, wbc_status);
- i->domain_name = talloc_strdup(i, resp->data.auth.info3.logon_dom);
+ i->domain_name = strdup(resp->data.auth.info3.logon_dom);
BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
i->dns_domain_name= NULL;
@@ -89,47 +120,41 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
i->pass_can_change_time = resp->data.auth.info3.pass_can_change_time;
i->pass_must_change_time= resp->data.auth.info3.pass_must_change_time;
- i->logon_server = talloc_strdup(i, resp->data.auth.info3.logon_srv);
+ i->logon_server = strdup(resp->data.auth.info3.logon_srv);
BAIL_ON_PTR_ERROR(i->logon_server, wbc_status);
- i->logon_script = talloc_strdup(i, resp->data.auth.info3.logon_script);
+ i->logon_script = strdup(resp->data.auth.info3.logon_script);
BAIL_ON_PTR_ERROR(i->logon_script, wbc_status);
- i->profile_path = talloc_strdup(i, resp->data.auth.info3.profile_path);
+ i->profile_path = strdup(resp->data.auth.info3.profile_path);
BAIL_ON_PTR_ERROR(i->profile_path, wbc_status);
- i->home_directory= talloc_strdup(i, resp->data.auth.info3.home_dir);
+ i->home_directory= strdup(resp->data.auth.info3.home_dir);
BAIL_ON_PTR_ERROR(i->home_directory, wbc_status);
- i->home_drive = talloc_strdup(i, resp->data.auth.info3.dir_drive);
+ i->home_drive = strdup(resp->data.auth.info3.dir_drive);
BAIL_ON_PTR_ERROR(i->home_drive, wbc_status);
i->num_sids = 2;
i->num_sids += resp->data.auth.info3.num_groups;
i->num_sids += resp->data.auth.info3.num_other_sids;
- i->sids = talloc_array(i, struct wbcSidWithAttr, i->num_sids);
+ i->sids = (struct wbcSidWithAttr *)calloc(
+ sizeof(struct wbcSidWithAttr), i->num_sids);
BAIL_ON_PTR_ERROR(i->sids, wbc_status);
wbc_status = wbcStringToSid(resp->data.auth.info3.dom_sid,
&domain_sid);
BAIL_ON_WBC_ERROR(wbc_status);
-#define _SID_COMPOSE(s, d, r, a) { \
- (s).sid = d; \
- if ((s).sid.num_auths < WBC_MAXSUBAUTHS) { \
- (s).sid.sub_auths[(s).sid.num_auths++] = r; \
- } else { \
- wbc_status = WBC_ERR_INVALID_SID; \
- BAIL_ON_WBC_ERROR(wbc_status); \
- } \
- (s).attributes = a; \
-} while (0)
-
sn = 0;
- _SID_COMPOSE(i->sids[sn], domain_sid,
- resp->data.auth.info3.user_rid,
- 0);
+ if (!sid_attr_compose(&i->sids[sn], &domain_sid,
+ resp->data.auth.info3.user_rid, 0)) {
+ wbc_status = WBC_ERR_INVALID_SID;
+ goto done;
+ }
sn++;
- _SID_COMPOSE(i->sids[sn], domain_sid,
- resp->data.auth.info3.group_rid,
- 0);
+ if (!sid_attr_compose(&i->sids[sn], &domain_sid,
+ resp->data.auth.info3.group_rid, 0)) {
+ wbc_status = WBC_ERR_INVALID_SID;
+ goto done;
+ }
sn++;
p = (char *)resp->extra_data.data;
@@ -157,8 +182,11 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
BAIL_ON_WBC_ERROR(wbc_status);
}
- _SID_COMPOSE(i->sids[sn], domain_sid,
- rid, attrs);
+ if (!sid_attr_compose(&i->sids[sn], &domain_sid,
+ rid, attrs)) {
+ wbc_status = WBC_ERR_INVALID_SID;
+ goto done;
+ }
sn++;
}
@@ -202,44 +230,52 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
*_i = i;
i = NULL;
done:
- talloc_free(i);
+ wbcFreeMemory(i);
return wbc_status;
}
-static wbcErr wbc_create_error_info(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
- struct wbcAuthErrorInfo **_e)
+static void wbcAuthErrorInfoDestructor(void *ptr)
+{
+ struct wbcAuthErrorInfo *e = (struct wbcAuthErrorInfo *)ptr;
+ free(e->nt_string);
+ free(e->display_string);
+}
+
+static wbcErr wbc_create_error_info(const struct winbindd_response *resp,
+ struct wbcAuthErrorInfo **_e)
{
wbcErr wbc_status = WBC_ERR_SUCCESS;
struct wbcAuthErrorInfo *e;
- e = talloc(mem_ctx, struct wbcAuthErrorInfo);
+ e = (struct wbcAuthErrorInfo *)wbcAllocateMemory(
+ 1, sizeof(struct wbcAuthErrorInfo),
+ wbcAuthErrorInfoDestructor);
BAIL_ON_PTR_ERROR(e, wbc_status);
e->nt_status = resp->data.auth.nt_status;
e->pam_error = resp->data.auth.pam_error;
- e->nt_string = talloc_strdup(e, resp->data.auth.nt_status_string);
+ e->nt_string = strdup(resp->data.auth.nt_status_string);
BAIL_ON_PTR_ERROR(e->nt_string, wbc_status);
- e->display_string = talloc_strdup(e, resp->data.auth.error_string);
+ e->display_string = strdup(resp->data.auth.error_string);
BAIL_ON_PTR_ERROR(e->display_string, wbc_status);
*_e = e;
e = NULL;
done:
- talloc_free(e);
+ wbcFreeMemory(e);
return wbc_status;
}
-static wbcErr wbc_create_password_policy_info(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
+static wbcErr wbc_create_password_policy_info(const struct winbindd_response *resp,
struct wbcUserPasswordPolicyInfo **_i)
{
wbcErr wbc_status = WBC_ERR_SUCCESS;
struct wbcUserPasswordPolicyInfo *i;
- i = talloc(mem_ctx, struct wbcUserPasswordPolicyInfo);
+ i = (struct wbcUserPasswordPolicyInfo *)wbcAllocateMemory(
+ 1, sizeof(struct wbcUserPasswordPolicyInfo), NULL);
BAIL_ON_PTR_ERROR(i, wbc_status);
i->min_passwordage = resp->data.auth.policy.min_passwordage;
@@ -252,25 +288,32 @@ static wbcErr wbc_create_password_policy_info(TALLOC_CTX *mem_ctx,
i = NULL;
done:
- talloc_free(i);
+ wbcFreeMemory(i);
return wbc_status;
}
-static wbcErr wbc_create_logon_info(TALLOC_CTX *mem_ctx,
- struct winbindd_response *resp,
+static void wbcLogonUserInfoDestructor(void *ptr)
+{
+ struct wbcLogonUserInfo *i = (struct wbcLogonUserInfo *)ptr;
+ wbcFreeMemory(i->info);
+ wbcFreeMemory(i->blobs);
+}
+
+static wbcErr wbc_create_logon_info(struct winbindd_response *resp,
struct wbcLogonUserInfo **_i)
{
wbcErr wbc_status = WBC_ERR_SUCCESS;
struct wbcLogonUserInfo *i;
- i = talloc_zero(mem_ctx, struct wbcLogonUserInfo);
+ i = (struct wbcLogonUserInfo *)wbcAllocateMemory(
+ 1, sizeof(struct wbcLogonUserInfo),
+ wbcLogonUserInfoDestructor);
BAIL_ON_PTR_ERROR(i, wbc_status);
- wbc_status = wbc_create_auth_info(i, resp, &i->info);
+ wbc_status = wbc_create_auth_info(resp, &i->info);
BAIL_ON_WBC_ERROR(wbc_status);
- if (resp->data.auth.krb5ccname &&
- strlen(resp->data.auth.krb5ccname)) {
+ if (resp->data.auth.krb5ccname[0] != '\0') {
wbc_status = wbcAddNamedBlob(&i->num_blobs,
&i->blobs,
"krb5ccname",
@@ -280,8 +323,7 @@ static wbcErr wbc_create_logon_info(TALLOC_CTX *mem_ctx,
BAIL_ON_WBC_ERROR(wbc_status);
}
- if (resp->data.auth.unix_username &&
- strlen(resp->data.auth.unix_username)) {
+ if (resp->data.auth.unix_username[0] != '\0') {
wbc_status = wbcAddNamedBlob(&i->num_blobs,
&i->blobs,
"unix_username",
@@ -294,14 +336,11 @@ static wbcErr wbc_create_logon_info(TALLOC_CTX *mem_ctx,
*_i = i;
i = NULL;
done:
- if (!WBC_ERROR_IS_OK(wbc_status) && i) {
- wbcFreeMemory(i->blobs);
- }
-
- talloc_free(i);
+ wbcFreeMemory(i);
return wbc_status;
}
+
/* Authenticate with more detailed information */
wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
struct wbcAuthUserInfo **info,
@@ -436,7 +475,8 @@ wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
if (params->password.response.nt_length > sizeof(request.data.auth_crap.nt_resp)) {
request.flags |= WBFLAG_BIG_NTLMV2_BLOB;
request.extra_len = params->password.response.nt_length;
- request.extra_data.data = talloc_zero_array(NULL, char, request.extra_len);
+ request.extra_data.data = (char *)malloc(
+ request.extra_len);
if (request.extra_data.data == NULL) {
wbc_status = WBC_ERR_NO_MEMORY;
BAIL_ON_WBC_ERROR(wbc_status);
@@ -470,8 +510,7 @@ wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
}
if (response.data.auth.nt_status != 0) {
if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
+ wbc_status = wbc_create_error_info(&response,
error);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -482,17 +521,14 @@ wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
BAIL_ON_WBC_ERROR(wbc_status);
if (info) {
- wbc_status = wbc_create_auth_info(NULL,
- &response,
- info);
+ wbc_status = wbc_create_auth_info(&response, info);
BAIL_ON_WBC_ERROR(wbc_status);
}
done:
- if (response.extra_data.data)
- free(response.extra_data.data);
+ winbindd_free_response(&response);
- talloc_free(request.extra_data.data);
+ free(request.extra_data.data);
return wbc_status;
}
@@ -519,8 +555,7 @@ wbcErr wbcCheckTrustCredentials(const char *domain,
&request, &response);
if (response.data.auth.nt_status != 0) {
if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
+ wbc_status = wbc_create_error_info(&response,
error);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -556,8 +591,7 @@ wbcErr wbcChangeTrustCredentials(const char *domain,
&request, &response);
if (response.data.auth.nt_status != 0) {
if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
+ wbc_status = wbc_create_error_info(&response,
error);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -600,8 +634,7 @@ wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error)
&response);
if (response.data.auth.nt_status != 0) {
if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
+ wbc_status = wbc_create_error_info(&response,
error);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -687,8 +720,7 @@ wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params,
/* Take the response above and return it to the caller */
if (response.data.auth.nt_status != 0) {
if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
+ wbc_status = wbc_create_error_info(&response,
error);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -757,7 +789,7 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
if (!params->account_name) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (error) {
@@ -781,7 +813,7 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
if (!params->account_name) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
strncpy(request.data.chauthtok.user, params->account_name,
@@ -805,55 +837,55 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
if (!params->account_name || !params->domain_name) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (params->old_password.response.old_lm_hash_enc_length &&
!params->old_password.response.old_lm_hash_enc_data) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (params->old_password.response.old_lm_hash_enc_length == 0 &&
params->old_password.response.old_lm_hash_enc_data) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (params->old_password.response.old_nt_hash_enc_length &&
!params->old_password.response.old_nt_hash_enc_data) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (params->old_password.response.old_nt_hash_enc_length == 0 &&
params->old_password.response.old_nt_hash_enc_data) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (params->new_password.response.lm_length &&
!params->new_password.response.lm_data) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (params->new_password.response.lm_length == 0 &&
params->new_password.response.lm_data) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (params->new_password.response.nt_length &&
!params->new_password.response.nt_data) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
if (params->new_password.response.nt_length == 0 &&
params->new_password.response.nt_data) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
strncpy(request.data.chng_pswd_auth_crap.user,
@@ -899,7 +931,7 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
break;
default:
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
break;
}
@@ -916,8 +948,7 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
if (response.data.auth.nt_status != 0) {
if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
+ wbc_status = wbc_create_error_info(&response,
error);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -925,8 +956,7 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
}
if (policy) {
- wbc_status = wbc_create_password_policy_info(NULL,
- &response,
+ wbc_status = wbc_create_password_policy_info(&response,
policy);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -974,7 +1004,6 @@ wbcErr wbcLogonUser(const struct wbcLogonUserParams *params,
struct wbcUserPasswordPolicyInfo **policy)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- int cmd = 0;
struct winbindd_request request;
struct winbindd_response response;
uint32_t i;
@@ -1013,7 +1042,6 @@ wbcErr wbcLogonUser(const struct wbcLogonUserParams *params,
/* Initialize request */
- cmd = WINBINDD_PAM_AUTH;
request.flags = WBFLAG_PAM_INFO3_TEXT |
WBFLAG_PAM_USER_SESSION_KEY |
WBFLAG_PAM_LMKEY;
@@ -1075,14 +1103,13 @@ wbcErr wbcLogonUser(const struct wbcLogonUserParams *params,
}
}
- wbc_status = wbcRequestResponse(cmd,
+ wbc_status = wbcRequestResponse(WINBINDD_PAM_AUTH,
&request,
&response);
if (response.data.auth.nt_status != 0) {
if (error) {
- wbc_status = wbc_create_error_info(NULL,
- &response,
+ wbc_status = wbc_create_error_info(&response,
error);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -1093,26 +1120,30 @@ wbcErr wbcLogonUser(const struct wbcLogonUserParams *params,
BAIL_ON_WBC_ERROR(wbc_status);
if (info) {
- wbc_status = wbc_create_logon_info(NULL,
- &response,
+ wbc_status = wbc_create_logon_info(&response,
info);
BAIL_ON_WBC_ERROR(wbc_status);
}
if (policy) {
- wbc_status = wbc_create_password_policy_info(NULL,
- &response,
+ wbc_status = wbc_create_password_policy_info(&response,
policy);
BAIL_ON_WBC_ERROR(wbc_status);
}
done:
- if (response.extra_data.data)
- free(response.extra_data.data);
+ winbindd_free_response(&response);
return wbc_status;
}
+static void wbcCredentialCacheInfoDestructor(void *ptr)
+{
+ struct wbcCredentialCacheInfo *i =
+ (struct wbcCredentialCacheInfo *)ptr;
+ wbcFreeMemory(i->blobs);
+}
+
/* Authenticate a user with cached credentials */
wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
struct wbcCredentialCacheInfo **info,
@@ -1186,8 +1217,7 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
}
if (request.extra_len != 0) {
- request.extra_data.data = talloc_array(
- NULL, char, request.extra_len);
+ request.extra_data.data = (char *)malloc(request.extra_len);
if (request.extra_data.data == NULL) {
status = WBC_ERR_NO_MEMORY;
goto fail;
@@ -1210,17 +1240,15 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
goto fail;
}
- result = talloc(NULL, struct wbcCredentialCacheInfo);
+ result = (struct wbcCredentialCacheInfo *)wbcAllocateMemory(
+ 1, sizeof(struct wbcCredentialCacheInfo),
+ wbcCredentialCacheInfoDestructor);
if (result == NULL) {
status = WBC_ERR_NO_MEMORY;
goto fail;
}
result->num_blobs = 0;
- result->blobs = talloc(result, struct wbcNamedBlob);
- if (result->blobs == NULL) {
- status = WBC_ERR_NO_MEMORY;
- goto fail;
- }
+ result->blobs = NULL;
status = wbcAddNamedBlob(&result->num_blobs, &result->blobs,
"auth_blob", 0,
(uint8_t *)response.extra_data.data,
@@ -1236,16 +1264,13 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
goto fail;
}
- if (response.extra_data.data)
- free(response.extra_data.data);
*info = result;
- return WBC_ERR_SUCCESS;
-
+ result = NULL;
+ status = WBC_ERR_SUCCESS;
fail:
- TALLOC_FREE(request.extra_data.data);
- if (response.extra_data.data)
- free(response.extra_data.data);
- talloc_free(result);
+ free(request.extra_data.data);
+ winbindd_free_response(&response);
+ wbcFreeMemory(result);
return status;
}
diff --git a/nsswitch/libwbclient/wbc_pwd.c b/nsswitch/libwbclient/wbc_pwd.c
index 897bf1f5c3..6df694dcac 100644
--- a/nsswitch/libwbclient/wbc_pwd.c
+++ b/nsswitch/libwbclient/wbc_pwd.c
@@ -24,6 +24,7 @@
#include "replace.h"
#include "libwbclient.h"
+#include "../winbind_client.h"
/** @brief The maximum number of pwent structs to get from winbindd
*
@@ -39,74 +40,116 @@
*
**/
-static struct passwd *copy_passwd_entry(struct winbindd_pw *p)
+static void wbcPasswdDestructor(void *ptr)
{
- struct passwd *pwd = NULL;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
-
- pwd = talloc(NULL, struct passwd);
- BAIL_ON_PTR_ERROR(pwd, wbc_status);
+ 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);
+}
- pwd->pw_name = talloc_strdup(pwd,p->pw_name);
- BAIL_ON_PTR_ERROR(pwd->pw_name, wbc_status);
+static struct passwd *copy_passwd_entry(struct winbindd_pw *p)
+{
+ struct passwd *pw = NULL;
- pwd->pw_passwd = talloc_strdup(pwd, p->pw_passwd);
- BAIL_ON_PTR_ERROR(pwd->pw_passwd, wbc_status);
+ pw = (struct passwd *)wbcAllocateMemory(1, sizeof(struct passwd),
+ wbcPasswdDestructor);
+ if (pw == NULL) {
+ return NULL;
+ }
+ pw->pw_name = strdup(p->pw_name);
+ if (pw->pw_name == NULL) {
+ goto fail;
+ }
+ pw->pw_passwd = strdup(p->pw_passwd);
+ if (pw->pw_passwd == NULL) {
+ goto fail;
+ }
+ pw->pw_gecos = strdup(p->pw_gecos);
+ if (pw->pw_gecos == NULL) {
+ goto fail;
+ }
+ pw->pw_shell = strdup(p->pw_shell);
+ if (pw->pw_shell == NULL) {
+ goto fail;
+ }
+ pw->pw_dir = strdup(p->pw_dir);
+ if (pw->pw_dir == NULL) {
+ goto fail;
+ }
+ pw->pw_uid = p->pw_uid;
+ pw->pw_gid = p->pw_gid;
+ return pw;
- pwd->pw_gecos = talloc_strdup(pwd, p->pw_gecos);
- BAIL_ON_PTR_ERROR(pwd->pw_gecos, wbc_status);
+fail:
+ wbcFreeMemory(pw);
+ return NULL;
+}
- pwd->pw_shell = talloc_strdup(pwd, p->pw_shell);
- BAIL_ON_PTR_ERROR(pwd->pw_shell, wbc_status);
+/**
+ *
+ **/
- pwd->pw_dir = talloc_strdup(pwd, p->pw_dir);
- BAIL_ON_PTR_ERROR(pwd->pw_dir, wbc_status);
+static void wbcGroupDestructor(void *ptr)
+{
+ struct group *gr = (struct group *)ptr;
+ int i;
- pwd->pw_uid = p->pw_uid;
- pwd->pw_gid = p->pw_gid;
+ free(gr->gr_name);
+ free(gr->gr_passwd);
-done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- talloc_free(pwd);
- pwd = NULL;
+ /* if the array was partly created this can be NULL */
+ if (gr->gr_mem == NULL) {
+ return;
}
- return pwd;
+ for (i=0; gr->gr_mem[i] != NULL; i++) {
+ free(gr->gr_mem[i]);
+ }
+ free(gr->gr_mem);
}
-/**
- *
- **/
-
static struct group *copy_group_entry(struct winbindd_gr *g,
char *mem_buf)
{
- struct group *grp = NULL;
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct group *gr = NULL;
int i;
char *mem_p, *mem_q;
- grp = talloc(NULL, struct group);
- BAIL_ON_PTR_ERROR(grp, wbc_status);
-
- grp->gr_name = talloc_strdup(grp, g->gr_name);
- BAIL_ON_PTR_ERROR(grp->gr_name, wbc_status);
-
- grp->gr_passwd = talloc_strdup(grp, g->gr_passwd);
- BAIL_ON_PTR_ERROR(grp->gr_passwd, wbc_status);
+ gr = (struct group *)wbcAllocateMemory(
+ 1, sizeof(struct group), wbcGroupDestructor);
+ if (gr == NULL) {
+ return NULL;
+ }
- grp->gr_gid = g->gr_gid;
+ gr->gr_name = strdup(g->gr_name);
+ if (gr->gr_name == NULL) {
+ goto fail;
+ }
+ gr->gr_passwd = strdup(g->gr_passwd);
+ if (gr->gr_passwd == NULL) {
+ goto fail;
+ }
+ gr->gr_gid = g->gr_gid;
- grp->gr_mem = talloc_array(grp, char*, g->num_gr_mem+1);
+ gr->gr_mem = (char **)calloc(g->num_gr_mem+1, sizeof(char *));
+ if (gr->gr_mem == NULL) {
+ goto fail;
+ }
mem_p = mem_q = mem_buf;
for (i=0; i<g->num_gr_mem && mem_p; i++) {
- if ((mem_q = strchr(mem_p, ',')) != NULL) {
+ mem_q = strchr(mem_p, ',');
+ if (mem_q != NULL) {
*mem_q = '\0';
}
- grp->gr_mem[i] = talloc_strdup(grp, mem_p);
- BAIL_ON_PTR_ERROR(grp->gr_mem[i], wbc_status);
+ gr->gr_mem[i] = strdup(mem_p);
+ if (gr->gr_mem[i] == NULL) {
+ goto fail;
+ }
if (mem_q == NULL) {
i += 1;
@@ -114,17 +157,13 @@ static struct group *copy_group_entry(struct winbindd_gr *g,
}
mem_p = mem_q + 1;
}
- grp->gr_mem[i] = NULL;
+ gr->gr_mem[i] = NULL;
- wbc_status = WBC_ERR_SUCCESS;
+ return gr;
-done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- talloc_free(grp);
- grp = NULL;
- }
-
- return grp;
+fail:
+ wbcFreeMemory(gr);
+ return NULL;
}
/* Fill in a struct passwd* for a domain user based on username */
@@ -197,22 +236,18 @@ wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd)
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct winbindd_request request;
struct winbindd_response response;
- char * sid_string = NULL;
if (!pwd) {
wbc_status = WBC_ERR_INVALID_PARAM;
BAIL_ON_WBC_ERROR(wbc_status);
}
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
/* Initialize request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid));
+ wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
wbc_status = wbcRequestResponse(WINBINDD_GETPWSID,
&request,
@@ -223,10 +258,6 @@ wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd)
BAIL_ON_PTR_ERROR(*pwd, wbc_status);
done:
- if (sid_string) {
- wbcFreeMemory(sid_string);
- }
-
return wbc_status;
}
@@ -261,8 +292,7 @@ wbcErr wbcGetgrnam(const char *name, struct group **grp)
BAIL_ON_PTR_ERROR(*grp, wbc_status);
done:
- if (response.extra_data.data)
- free(response.extra_data.data);
+ winbindd_free_response(&response);
return wbc_status;
}
@@ -296,8 +326,7 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
BAIL_ON_PTR_ERROR(*grp, wbc_status);
done:
- if (response.extra_data.data)
- free(response.extra_data.data);
+ winbindd_free_response(&response);
return wbc_status;
}
@@ -324,9 +353,7 @@ wbcErr wbcSetpwent(void)
if (pw_cache_size > 0) {
pw_cache_idx = pw_cache_size = 0;
- if (pw_response.extra_data.data) {
- free(pw_response.extra_data.data);
- }
+ winbindd_free_response(&pw_response);
}
ZERO_STRUCT(pw_response);
@@ -346,9 +373,7 @@ wbcErr wbcEndpwent(void)
if (pw_cache_size > 0) {
pw_cache_idx = pw_cache_size = 0;
- if (pw_response.extra_data.data) {
- free(pw_response.extra_data.data);
- }
+ winbindd_free_response(&pw_response);
}
wbc_status = wbcRequestResponse(WINBINDD_ENDPWENT,
@@ -375,10 +400,7 @@ wbcErr wbcGetpwent(struct passwd **pwd)
pw_cache_idx = 0;
- if (pw_response.extra_data.data) {
- free(pw_response.extra_data.data);
- ZERO_STRUCT(pw_response);
- }
+ winbindd_free_response(&pw_response);
ZERO_STRUCT(request);
request.data.num_entries = MAX_GETPWENT_USERS;
@@ -426,9 +448,7 @@ wbcErr wbcSetgrent(void)
if (gr_cache_size > 0) {
gr_cache_idx = gr_cache_size = 0;
- if (gr_response.extra_data.data) {
- free(gr_response.extra_data.data);
- }
+ winbindd_free_response(&gr_response);
}
ZERO_STRUCT(gr_response);
@@ -448,9 +468,7 @@ wbcErr wbcEndgrent(void)
if (gr_cache_size > 0) {
gr_cache_idx = gr_cache_size = 0;
- if (gr_response.extra_data.data) {
- free(gr_response.extra_data.data);
- }
+ winbindd_free_response(&gr_response);
}
wbc_status = wbcRequestResponse(WINBINDD_ENDGRENT,
@@ -478,10 +496,7 @@ wbcErr wbcGetgrent(struct group **grp)
gr_cache_idx = 0;
- if (gr_response.extra_data.data) {
- free(gr_response.extra_data.data);
- ZERO_STRUCT(gr_response);
- }
+ winbindd_free_response(&gr_response);
ZERO_STRUCT(request);
request.data.num_entries = MAX_GETGRENT_GROUPS;
@@ -527,10 +542,8 @@ wbcErr wbcGetgrlist(struct group **grp)
gr_cache_idx = 0;
- if (gr_response.extra_data.data) {
- free(gr_response.extra_data.data);
- ZERO_STRUCT(gr_response);
- }
+ winbindd_free_response(&gr_response);
+ ZERO_STRUCT(gr_response);
ZERO_STRUCT(request);
request.data.num_entries = MAX_GETGRENT_GROUPS;
@@ -586,7 +599,8 @@ wbcErr wbcGetGroups(const char *account,
&response);
BAIL_ON_WBC_ERROR(wbc_status);
- groups = talloc_array(NULL, gid_t, response.data.num_entries);
+ groups = (gid_t *)wbcAllocateMemory(
+ response.data.num_entries, sizeof(gid_t), NULL);
BAIL_ON_PTR_ERROR(groups, wbc_status);
for (i = 0; i < response.data.num_entries; i++) {
@@ -600,12 +614,7 @@ wbcErr wbcGetGroups(const char *account,
wbc_status = WBC_ERR_SUCCESS;
done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
- if (groups) {
- talloc_free(groups);
- }
-
+ winbindd_free_response(&response);
+ wbcFreeMemory(groups);
return wbc_status;
}
diff --git a/nsswitch/libwbclient/wbc_sid.c b/nsswitch/libwbclient/wbc_sid.c
index 99c9d8e152..6df8a3c375 100644
--- a/nsswitch/libwbclient/wbc_sid.c
+++ b/nsswitch/libwbclient/wbc_sid.c
@@ -4,6 +4,7 @@
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
@@ -24,47 +25,67 @@
#include "replace.h"
#include "libwbclient.h"
+#include "../winbind_client.h"
-
-/* Convert a binary SID to a character string */
-wbcErr wbcSidToString(const struct wbcDomainSid *sid,
- char **sid_string)
+/* 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)
{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
uint32_t id_auth;
- int i;
- char *tmp = NULL;
+ int i, ofs;
if (!sid) {
- wbc_status = WBC_ERR_INVALID_SID;
- BAIL_ON_WBC_ERROR(wbc_status);
+ strlcpy(buf, "(NULL SID)", buflen);
+ return 10; /* strlen("(NULL SID)") */
}
+ /*
+ * BIG NOTE: this function only does SIDS where the identauth is not
+ * >= ^32 in a range of 2^48.
+ */
+
id_auth = sid->id_auth[5] +
(sid->id_auth[4] << 8) +
(sid->id_auth[3] << 16) +
(sid->id_auth[2] << 24);
- tmp = talloc_asprintf(NULL, "S-%d-%d", sid->sid_rev_num, id_auth);
- BAIL_ON_PTR_ERROR(tmp, wbc_status);
+ ofs = snprintf(buf, buflen, "S-%u-%lu",
+ (unsigned int)sid->sid_rev_num, (unsigned long)id_auth);
- for (i=0; i<sid->num_auths; i++) {
- char *tmp2;
- tmp2 = talloc_asprintf_append(tmp, "-%u", sid->sub_auths[i]);
- BAIL_ON_PTR_ERROR(tmp2, wbc_status);
+ for (i = 0; i < sid->num_auths; i++) {
+ ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%lu",
+ (unsigned long)sid->sub_auths[i]);
+ }
+ return ofs;
+}
- tmp = tmp2;
+/* 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;
}
- *sid_string = tmp;
- tmp = NULL;
+ len = wbcSidToStringBuf(sid, buf, sizeof(buf));
- wbc_status = WBC_ERR_SUCCESS;
+ if (len+1 > sizeof(buf)) {
+ return WBC_ERR_INVALID_SID;
+ }
-done:
- talloc_free(tmp);
+ result = (char *)wbcAllocateMemory(len+1, 1, NULL);
+ if (result == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+ memcpy(result, buf, len+1);
- return wbc_status;
+ *sid_string = result;
+ return WBC_ERR_SUCCESS;
}
/* Convert a character string to a binary SID */
@@ -131,8 +152,9 @@ wbcErr wbcStringToSid(const char *str,
}
sid->sub_auths[sid->num_auths++] = x;
- if ((*q!='-') || (*q=='\0'))
+ if (*q != '-') {
break;
+ }
p = q + 1;
}
@@ -150,6 +172,7 @@ done:
}
+
/* Convert a domain and name to SID */
wbcErr wbcLookupName(const char *domain,
const char *name,
@@ -193,6 +216,7 @@ wbcErr wbcLookupName(const char *domain,
return wbc_status;
}
+
/* Convert a SID to a domain and name */
wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
char **pdomain,
@@ -202,14 +226,10 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
struct winbindd_request request;
struct winbindd_response response;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *sid_string = NULL;
- char *domain = NULL;
- char *name = NULL;
- enum wbcSidType name_type = WBC_SID_NAME_USE_NONE;
+ char *domain, *name;
if (!sid) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ return WBC_ERR_INVALID_PARAM;
}
/* Initialize request */
@@ -217,67 +237,228 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- /* dst is already null terminated from the memset above */
-
- wbc_status = wbcSidToString(sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
+ wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
/* Make request */
- wbc_status = wbcRequestResponse(WINBINDD_LOOKUPSID,
- &request,
- &response);
- BAIL_ON_WBC_ERROR(wbc_status);
+ wbc_status = wbcRequestResponse(WINBINDD_LOOKUPSID, &request,
+ &response);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
/* Copy out result */
- domain = talloc_strdup(NULL, response.data.name.dom_name);
- BAIL_ON_PTR_ERROR(domain, wbc_status);
+ wbc_status = WBC_ERR_NO_MEMORY;
+ domain = NULL;
+ name = NULL;
- name = talloc_strdup(NULL, response.data.name.name);
- BAIL_ON_PTR_ERROR(name, wbc_status);
+ domain = wbcStrDup(response.data.name.dom_name);
+ if (domain == NULL) {
+ goto done;
+ }
+ name = wbcStrDup(response.data.name.name);
+ if (name == NULL) {
+ goto done;
+ }
+ if (pdomain != NULL) {
+ *pdomain = domain;
+ domain = NULL;
+ }
+ if (pname != NULL) {
+ *pname = name;
+ name = NULL;
+ }
+ if (pname_type != NULL) {
+ *pname_type = (enum wbcSidType)response.data.name.type;
+ }
+ wbc_status = WBC_ERR_SUCCESS;
+done:
+ wbcFreeMemory(name);
+ wbcFreeMemory(domain);
+ return wbc_status;
+}
- name_type = (enum wbcSidType)response.data.name.type;
+static void wbcDomainInfosDestructor(void *ptr)
+{
+ struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr;
- wbc_status = WBC_ERR_SUCCESS;
+ while (i->short_name != NULL) {
+ wbcFreeMemory(i->short_name);
+ wbcFreeMemory(i->dns_name);
+ i += 1;
+ }
+}
- done:
- if (WBC_ERROR_IS_OK(wbc_status)) {
- if (pdomain != NULL) {
- *pdomain = domain;
- } else {
- TALLOC_FREE(domain);
+static void wbcTranslatedNamesDestructor(void *ptr)
+{
+ struct wbcTranslatedName *n = (struct wbcTranslatedName *)ptr;
+
+ while (n->name != NULL) {
+ free(n->name);
+ n += 1;
+ }
+}
+
+wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids,
+ struct wbcDomainInfo **pdomains, int *pnum_domains,
+ struct wbcTranslatedName **pnames)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ int buflen, i, extra_len, num_domains, num_names;
+ char *sidlist, *p, *q, *extra_data;
+ struct wbcDomainInfo *domains = NULL;
+ struct wbcTranslatedName *names = NULL;
+
+ buflen = num_sids * (WBC_SID_STRING_BUFLEN + 1) + 1;
+
+ sidlist = (char *)malloc(buflen);
+ if (sidlist == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ p = sidlist;
+
+ for (i=0; i<num_sids; i++) {
+ int remaining;
+ int len;
+
+ remaining = buflen - (p - sidlist);
+
+ len = wbcSidToStringBuf(&sids[i], p, remaining);
+ if (len > remaining) {
+ free(sidlist);
+ return WBC_ERR_UNKNOWN_FAILURE;
}
- if (pname != NULL) {
- *pname = name;
- } else {
- TALLOC_FREE(name);
+
+ p += len;
+ *p++ = '\n';
+ }
+ *p++ = '\0';
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ request.extra_data.data = sidlist;
+ request.extra_len = p - sidlist;
+
+ wbc_status = wbcRequestResponse(WINBINDD_LOOKUPSIDS,
+ &request, &response);
+ free(sidlist);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ extra_len = response.length - sizeof(struct winbindd_response);
+ extra_data = (char *)response.extra_data.data;
+
+ if ((extra_len <= 0) || (extra_data[extra_len-1] != '\0')) {
+ goto wbc_err_invalid;
+ }
+
+ p = extra_data;
+
+ num_domains = strtoul(p, &q, 10);
+ if (*q != '\n') {
+ goto wbc_err_invalid;
+ }
+ p = q+1;
+
+ domains = (struct wbcDomainInfo *)wbcAllocateMemory(
+ num_domains+1, sizeof(struct wbcDomainInfo),
+ wbcDomainInfosDestructor);
+ if (domains == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto fail;
+ }
+
+ for (i=0; i<num_domains; i++) {
+
+ q = strchr(p, ' ');
+ if (q == NULL) {
+ goto wbc_err_invalid;
}
- if (pname_type != NULL) {
- *pname_type = name_type;
+ *q = '\0';
+ wbc_status = wbcStringToSid(p, &domains[i].sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ goto fail;
}
+ p = q+1;
+
+ q = strchr(p, '\n');
+ if (q == NULL) {
+ goto wbc_err_invalid;
+ }
+ *q = '\0';
+ domains[i].short_name = wbcStrDup(p);
+ if (domains[i].short_name == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto fail;
+ }
+ p = q+1;
}
- else {
-#if 0
- /*
- * Found by Coverity: In this particular routine we can't end
- * up here with a non-NULL name. Further up there are just two
- * exit paths that lead here, neither of which leave an
- * allocated name. If you add more paths up there, re-activate
- * this.
- */
- if (name != NULL) {
- talloc_free(name);
+
+ num_names = strtoul(p, &q, 10);
+ if (*q != '\n') {
+ goto wbc_err_invalid;
+ }
+ p = q+1;
+
+ if (num_names != num_sids) {
+ goto wbc_err_invalid;
+ }
+
+ names = (struct wbcTranslatedName *)wbcAllocateMemory(
+ num_names+1, sizeof(struct wbcTranslatedName),
+ wbcTranslatedNamesDestructor);
+ if (names == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto fail;
+ }
+
+ for (i=0; i<num_names; i++) {
+
+ names[i].domain_index = strtoul(p, &q, 10);
+ if (*q != ' ') {
+ goto wbc_err_invalid;
}
-#endif
- if (domain != NULL) {
- talloc_free(domain);
+ p = q+1;
+
+ names[i].type = strtoul(p, &q, 10);
+ if (*q != ' ') {
+ goto wbc_err_invalid;
}
+ p = q+1;
+
+ q = strchr(p, '\n');
+ if (q == NULL) {
+ goto wbc_err_invalid;
+ }
+ *q = '\0';
+ names[i].name = wbcStrDup(p);
+ if (names[i].name == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto fail;
+ }
+ p = q+1;
}
+ if (*p != '\0') {
+ goto wbc_err_invalid;
+ }
+
+ *pdomains = domains;
+ *pnames = names;
+ winbindd_free_response(&response);
+ return WBC_ERR_SUCCESS;
+wbc_err_invalid:
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+fail:
+ winbindd_free_response(&response);
+ wbcFreeMemory(domains);
+ wbcFreeMemory(names);
return wbc_status;
}
@@ -295,7 +476,6 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
char *p;
struct winbindd_request request;
struct winbindd_response response;
- char *sid_string = NULL;
char *domain_name = NULL;
const char **names = NULL;
enum wbcSidType *types = NULL;
@@ -311,11 +491,7 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
BAIL_ON_WBC_ERROR(wbc_status);
}
- wbc_status = wbcSidToString(dom_sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
+ wbcSidToStringBuf(dom_sid, request.data.sid, sizeof(request.data.sid));
/* Even if all the Rids were of maximum 32bit values,
we would only have 11 bytes per rid in the final array
@@ -324,36 +500,34 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
ridbuf_size = (sizeof(char)*11) * num_rids + 1;
- ridlist = talloc_zero_array(NULL, char, ridbuf_size);
+ ridlist = (char *)malloc(ridbuf_size);
BAIL_ON_PTR_ERROR(ridlist, wbc_status);
len = 0;
- for (i=0; i<num_rids && (len-1)>0; i++) {
- char ridstr[12];
-
- len = strlen(ridlist);
- p = ridlist + len;
-
- snprintf( ridstr, sizeof(ridstr)-1, "%u\n", rids[i]);
- strncat(p, ridstr, ridbuf_size-len-1);
+ for (i=0; i<num_rids; i++) {
+ len += snprintf(ridlist + len, ridbuf_size - len, "%u\n",
+ rids[i]);
}
+ ridlist[len] = '\0';
+ len += 1;
request.extra_data.data = ridlist;
- request.extra_len = strlen(ridlist)+1;
+ request.extra_len = len;
wbc_status = wbcRequestResponse(WINBINDD_LOOKUPRIDS,
&request,
&response);
- talloc_free(ridlist);
+ free(ridlist);
BAIL_ON_WBC_ERROR(wbc_status);
- domain_name = talloc_strdup(NULL, response.data.domain_name);
+ domain_name = wbcStrDup(response.data.domain_name);
BAIL_ON_PTR_ERROR(domain_name, wbc_status);
- names = talloc_array(NULL, const char*, num_rids);
+ names = wbcAllocateStringArray(num_rids);
BAIL_ON_PTR_ERROR(names, wbc_status);
- types = talloc_array(NULL, enum wbcSidType, num_rids);
+ types = (enum wbcSidType *)wbcAllocateMemory(
+ num_rids, sizeof(enum wbcSidType), NULL);
BAIL_ON_PTR_ERROR(types, wbc_status);
p = (char *)response.extra_data.data;
@@ -363,26 +537,26 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
if (*p == '\0') {
wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
types[i] = (enum wbcSidType)strtoul(p, &q, 10);
if (*q != ' ') {
wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
p = q+1;
if ((q = strchr(p, '\n')) == NULL) {
wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
*q = '\0';
- names[i] = talloc_strdup(names, p);
+ names[i] = strdup(p);
BAIL_ON_PTR_ERROR(names[i], wbc_status);
p = q+1;
@@ -390,15 +564,13 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
if (*p != '\0') {
wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
wbc_status = WBC_ERR_SUCCESS;
done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
+ winbindd_free_response(&response);
if (WBC_ERROR_IS_OK(wbc_status)) {
*pp_domain_name = domain_name;
@@ -406,12 +578,9 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
*ptypes = types;
}
else {
- if (domain_name)
- talloc_free(domain_name);
- if (names)
- talloc_free(names);
- if (types)
- talloc_free(types);
+ wbcFreeMemory(domain_name);
+ wbcFreeMemory(names);
+ wbcFreeMemory(types);
}
return wbc_status;
@@ -427,7 +596,6 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
const char *s;
struct winbindd_request request;
struct winbindd_response response;
- char *sid_string = NULL;
struct wbcDomainSid *sids = NULL;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
int cmd;
@@ -442,11 +610,7 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
BAIL_ON_WBC_ERROR(wbc_status);
}
- wbc_status = wbcSidToString(user_sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
+ wbcSidToStringBuf(user_sid, request.data.sid, sizeof(request.data.sid));
if (domain_groups_only) {
cmd = WINBINDD_GETUSERDOMGROUPS;
@@ -465,8 +629,9 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
BAIL_ON_WBC_ERROR(wbc_status);
}
- sids = talloc_array(NULL, struct wbcDomainSid,
- response.data.num_entries);
+ sids = (struct wbcDomainSid *)wbcAllocateMemory(
+ response.data.num_entries, sizeof(struct wbcDomainSid),
+ NULL);
BAIL_ON_PTR_ERROR(sids, wbc_status);
s = (const char *)response.extra_data.data;
@@ -486,11 +651,9 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
wbc_status = WBC_ERR_SUCCESS;
done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
+ winbindd_free_response(&response);
if (sids) {
- talloc_free(sids);
+ wbcFreeMemory(sids);
}
return wbc_status;
@@ -518,8 +681,6 @@ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
const char *s;
struct winbindd_request request;
struct winbindd_response response;
- char *sid_string = NULL;
- ssize_t sid_len;
ssize_t extra_data_len = 0;
char * extra_data = NULL;
ssize_t buflen = 0;
@@ -534,52 +695,43 @@ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
if (!dom_sid) {
wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
- wbc_status = wbcSidToString(dom_sid, &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
-
- strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
- wbcFreeMemory(sid_string);
- sid_string = NULL;
+ wbcSidToStringBuf(dom_sid, request.data.sid, sizeof(request.data.sid));
- /* Lets assume each sid is around 54 characters
- * S-1-5-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */
- buflen = 54 * num_sids;
- extra_data = talloc_array(NULL, char, buflen);
+ /* Lets assume each sid is around 57 characters
+ * S-1-5-21-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */
+ buflen = 57 * num_sids;
+ extra_data = (char *)malloc(buflen);
if (!extra_data) {
wbc_status = WBC_ERR_NO_MEMORY;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
/* Build the sid list */
for (i=0; i<num_sids; i++) {
- if (sid_string) {
- wbcFreeMemory(sid_string);
- sid_string = NULL;
- }
- wbc_status = wbcSidToString(&sids[i], &sid_string);
- BAIL_ON_WBC_ERROR(wbc_status);
+ char sid_str[WBC_SID_STRING_BUFLEN];
+ size_t sid_len;
- sid_len = strlen(sid_string);
+ sid_len = wbcSidToStringBuf(&sids[i], sid_str, sizeof(sid_str));
if (buflen < extra_data_len + sid_len + 2) {
buflen *= 2;
- extra_data = talloc_realloc(NULL, extra_data,
- char, buflen);
+ extra_data = (char *)realloc(extra_data, buflen);
if (!extra_data) {
wbc_status = WBC_ERR_NO_MEMORY;
BAIL_ON_WBC_ERROR(wbc_status);
}
}
- strncpy(&extra_data[extra_data_len], sid_string,
+ strncpy(&extra_data[extra_data_len], sid_str,
buflen - extra_data_len);
extra_data_len += sid_len;
extra_data[extra_data_len++] = '\n';
extra_data[extra_data_len] = '\0';
}
+ extra_data_len += 1;
request.extra_data.data = extra_data;
request.extra_len = extra_data_len;
@@ -592,11 +744,11 @@ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
if (response.data.num_entries &&
!response.extra_data.data) {
wbc_status = WBC_ERR_INVALID_RESPONSE;
- BAIL_ON_WBC_ERROR(wbc_status);
+ goto done;
}
- rids = talloc_array(NULL, uint32_t,
- response.data.num_entries);
+ rids = (uint32_t *)wbcAllocateMemory(response.data.num_entries,
+ sizeof(uint32_t), NULL);
BAIL_ON_PTR_ERROR(sids, wbc_status);
s = (const char *)response.extra_data.data;
@@ -618,19 +770,9 @@ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
wbc_status = WBC_ERR_SUCCESS;
done:
- if (sid_string) {
- wbcFreeMemory(sid_string);
- }
- if (extra_data) {
- talloc_free(extra_data);
- }
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
- if (rids) {
- talloc_free(rids);
- }
-
+ free(extra_data);
+ winbindd_free_response(&response);
+ wbcFreeMemory(rids);
return wbc_status;
}
@@ -662,13 +804,26 @@ wbcErr wbcListUsers(const char *domain_name,
&response);
BAIL_ON_WBC_ERROR(wbc_status);
+ users = wbcAllocateStringArray(response.data.num_entries);
+ if (users == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
/* Look through extra data */
next = (const char *)response.extra_data.data;
while (next) {
- const char **tmp;
- const char *current = next;
- char *k = strchr(next, ',');
+ const char *current;
+ char *k;
+
+ if (num_users >= response.data.num_entries) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ goto done;
+ }
+
+ current = next;
+ k = strchr(next, ',');
+
if (k) {
k[0] = '\0';
next = k+1;
@@ -676,30 +831,23 @@ wbcErr wbcListUsers(const char *domain_name,
next = NULL;
}
- tmp = talloc_realloc(NULL, users,
- const char *,
- num_users+1);
- BAIL_ON_PTR_ERROR(tmp, wbc_status);
- users = tmp;
-
- users[num_users] = talloc_strdup(users, current);
+ users[num_users] = strdup(current);
BAIL_ON_PTR_ERROR(users[num_users], wbc_status);
-
- num_users++;
+ num_users += 1;
+ }
+ if (num_users != response.data.num_entries) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ goto done;
}
- *_num_users = num_users;
+ *_num_users = response.data.num_entries;
*_users = users;
users = NULL;
wbc_status = WBC_ERR_SUCCESS;
done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
- if (users) {
- talloc_free(users);
- }
+ winbindd_free_response(&response);
+ wbcFreeMemory(users);
return wbc_status;
}
@@ -730,13 +878,26 @@ wbcErr wbcListGroups(const char *domain_name,
&response);
BAIL_ON_WBC_ERROR(wbc_status);
+ groups = wbcAllocateStringArray(response.data.num_entries);
+ if (groups == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
/* Look through extra data */
next = (const char *)response.extra_data.data;
while (next) {
- const char **tmp;
- const char *current = next;
- char *k = strchr(next, ',');
+ const char *current;
+ char *k;
+
+ if (num_groups >= response.data.num_entries) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ goto done;
+ }
+
+ current = next;
+ k = strchr(next, ',');
+
if (k) {
k[0] = '\0';
next = k+1;
@@ -744,30 +905,23 @@ wbcErr wbcListGroups(const char *domain_name,
next = NULL;
}
- tmp = talloc_realloc(NULL, groups,
- const char *,
- num_groups+1);
- BAIL_ON_PTR_ERROR(tmp, wbc_status);
- groups = tmp;
-
- groups[num_groups] = talloc_strdup(groups, current);
+ groups[num_groups] = strdup(current);
BAIL_ON_PTR_ERROR(groups[num_groups], wbc_status);
-
- num_groups++;
+ num_groups += 1;
+ }
+ if (num_groups != response.data.num_entries) {
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+ goto done;
}
- *_num_groups = num_groups;
+ *_num_groups = response.data.num_entries;
*_groups = groups;
groups = NULL;
wbc_status = WBC_ERR_SUCCESS;
done:
- if (response.extra_data.data) {
- free(response.extra_data.data);
- }
- if (groups) {
- talloc_free(groups);
- }
+ winbindd_free_response(&response);
+ wbcFreeMemory(groups);
return wbc_status;
}
@@ -796,7 +950,8 @@ wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
wbcFreeMemory(name);
- name = talloc_strdup(NULL, pwd->pw_gecos);
+ name = wbcStrDup(pwd->pw_gecos);
+ wbcFreeMemory(pwd);
BAIL_ON_PTR_ERROR(name, wbc_status);
}
diff --git a/nsswitch/libwbclient/wbc_util.c b/nsswitch/libwbclient/wbc_util.c
index 16828ae5df..d783ba36d8 100644
--- a/nsswitch/libwbclient/wbc_util.c
+++ b/nsswitch/libwbclient/wbc_util.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
- Winbind client API
+ Winbind client asynchronous API, utility functions
Copyright (C) Gerald (Jerry) Carter 2007-2008
@@ -24,14 +24,12 @@
#include "replace.h"
#include "libwbclient.h"
-
-
+#include "../winbind_client.h"
/** @brief Ping winbindd to see if the daemon is running
*
* @return #wbcErr
**/
-
wbcErr wbcPing(void)
{
struct winbindd_request request;
@@ -45,6 +43,23 @@ wbcErr wbcPing(void)
return wbcRequestResponse(WINBINDD_PING, &request, &response);
}
+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;
@@ -58,7 +73,9 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- info = talloc(NULL, struct wbcInterfaceDetails);
+ info = (struct wbcInterfaceDetails *)wbcAllocateMemory(
+ 1, sizeof(struct wbcInterfaceDetails),
+ wbcInterfaceDetailsDestructor);
BAIL_ON_PTR_ERROR(info, wbc_status);
/* first the interface version */
@@ -70,8 +87,7 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
wbc_status = wbcRequestResponse(WINBINDD_INFO, NULL, &response);
BAIL_ON_WBC_ERROR(wbc_status);
- info->winbind_version = talloc_strdup(info,
- response.data.info.samba_version);
+ info->winbind_version = strdup(response.data.info.samba_version);
BAIL_ON_PTR_ERROR(info->winbind_version, wbc_status);
info->winbind_separator = response.data.info.winbind_separator;
@@ -79,16 +95,14 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
wbc_status = wbcRequestResponse(WINBINDD_NETBIOS_NAME, NULL, &response);
BAIL_ON_WBC_ERROR(wbc_status);
- info->netbios_name = talloc_strdup(info,
- response.data.netbios_name);
+ info->netbios_name = strdup(response.data.netbios_name);
BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status);
/* then the local workgroup name */
wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_NAME, NULL, &response);
BAIL_ON_WBC_ERROR(wbc_status);
- info->netbios_domain = talloc_strdup(info,
- response.data.domain_name);
+ info->netbios_domain = strdup(response.data.domain_name);
BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status);
wbc_status = wbcDomainInfo(info->netbios_domain, &domain);
@@ -101,8 +115,7 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
}
if (domain) {
- info->dns_domain = talloc_strdup(info,
- domain->dns_name);
+ info->dns_domain = strdup(domain->dns_name);
wbcFreeMemory(domain);
BAIL_ON_PTR_ERROR(info->dns_domain, wbc_status);
} else {
@@ -115,12 +128,25 @@ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
wbc_status = WBC_ERR_SUCCESS;
done:
- talloc_free(info);
+ wbcFreeMemory(info);
return wbc_status;
}
+static void wbcDomainInfoDestructor(void *ptr)
+{
+ struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr;
+ free(i->short_name);
+ free(i->dns_name);
+}
+
+/** @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
+ */
-/* Lookup the current status of a trusted domain */
wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
{
struct winbindd_request request;
@@ -146,15 +172,14 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
&response);
BAIL_ON_WBC_ERROR(wbc_status);
- info = talloc(NULL, struct wbcDomainInfo);
+ info = (struct wbcDomainInfo *)wbcAllocateMemory(
+ 1, sizeof(struct wbcDomainInfo), wbcDomainInfoDestructor);
BAIL_ON_PTR_ERROR(info, wbc_status);
- info->short_name = talloc_strdup(info,
- response.data.domain_info.name);
+ info->short_name = strdup(response.data.domain_info.name);
BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
- info->dns_name = talloc_strdup(info,
- response.data.domain_info.alt_name);
+ info->dns_name = strdup(response.data.domain_info.alt_name);
BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
wbc_status = wbcStringToSid(response.data.domain_info.sid,
@@ -169,18 +194,102 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
*dinfo = info;
+ info = NULL;
wbc_status = WBC_ERR_SUCCESS;
done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- talloc_free(info);
+ wbcFreeMemory(info);
+ return wbc_status;
+}
+
+/* Get the list of current DCs */
+wbcErr wbcDcInfo(const char *domain, size_t *num_dcs,
+ const char ***dc_names, const char ***dc_ips)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ const char **names = NULL;
+ const char **ips = NULL;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ size_t extra_len;
+ int i;
+ char *p;
+
+ /* Initialise request */
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ if (domain != NULL) {
+ strncpy(request.domain_name, domain,
+ sizeof(request.domain_name) - 1);
}
+ wbc_status = wbcRequestResponse(WINBINDD_DC_INFO,
+ &request, &response);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ names = wbcAllocateStringArray(response.data.num_entries);
+ BAIL_ON_PTR_ERROR(names, wbc_status);
+
+ ips = wbcAllocateStringArray(response.data.num_entries);
+ BAIL_ON_PTR_ERROR(ips, wbc_status);
+
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+
+ p = (char *)response.extra_data.data;
+
+ if (response.length < (sizeof(struct winbindd_response)+1)) {
+ goto done;
+ }
+
+ extra_len = response.length - sizeof(struct winbindd_response);
+
+ if (p[extra_len-1] != '\0') {
+ goto done;
+ }
+
+ for (i=0; i<response.data.num_entries; i++) {
+ char *q;
+
+ q = strchr(p, '\n');
+ if (q == NULL) {
+ goto done;
+ }
+ names[i] = strndup(p, q-p);
+ BAIL_ON_PTR_ERROR(names[i], wbc_status);
+ p = q+1;
+
+ q = strchr(p, '\n');
+ if (q == NULL) {
+ goto done;
+ }
+ ips[i] = strndup(p, q-p);
+ BAIL_ON_PTR_ERROR(ips[i], wbc_status);
+ p = q+1;
+ }
+ if (p[0] != '\0') {
+ goto done;
+ }
+
+ wbc_status = WBC_ERR_SUCCESS;
+done:
+ if (response.extra_data.data)
+ free(response.extra_data.data);
+
+ if (WBC_ERROR_IS_OK(wbc_status)) {
+ *num_dcs = response.data.num_entries;
+ *dc_names = names;
+ names = NULL;
+ *dc_ips = ips;
+ ips = NULL;
+ }
+ wbcFreeMemory(names);
+ wbcFreeMemory(ips);
return wbc_status;
}
-
/* Resolve a NetbiosName via WINS */
wbcErr wbcResolveWinsByName(const char *name, char **ip)
{
@@ -204,7 +313,7 @@ wbcErr wbcResolveWinsByName(const char *name, char **ip)
/* Display response */
- ipaddr = talloc_strdup(NULL, response.data.winsresp);
+ ipaddr = wbcStrDup(response.data.winsresp);
BAIL_ON_PTR_ERROR(ipaddr, wbc_status);
*ip = ipaddr;
@@ -237,7 +346,7 @@ wbcErr wbcResolveWinsByIP(const char *ip, char **name)
/* Display response */
- name_str = talloc_strdup(NULL, response.data.winsresp);
+ name_str = wbcStrDup(response.data.winsresp);
BAIL_ON_PTR_ERROR(name_str, wbc_status);
*name = name_str;
@@ -250,21 +359,13 @@ wbcErr wbcResolveWinsByIP(const char *ip, char **name)
/**
*/
-static wbcErr process_domain_info_string(TALLOC_CTX *ctx,
- struct wbcDomainInfo *info,
+static wbcErr process_domain_info_string(struct wbcDomainInfo *info,
char *info_string)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
char *r = NULL;
char *s = NULL;
- if (!info || !info_string) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
- ZERO_STRUCTP(info);
-
r = info_string;
/* Short Name */
@@ -275,7 +376,7 @@ static wbcErr process_domain_info_string(TALLOC_CTX *ctx,
*s = '\0';
s++;
- info->short_name = talloc_strdup(ctx, r);
+ info->short_name = strdup(r);
BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
@@ -288,7 +389,7 @@ static wbcErr process_domain_info_string(TALLOC_CTX *ctx,
*s = '\0';
s++;
- info->dns_name = talloc_strdup(ctx, r);
+ info->dns_name = strdup(r);
BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
/* SID */
@@ -381,15 +482,24 @@ static wbcErr process_domain_info_string(TALLOC_CTX *ctx,
return wbc_status;
}
+static void wbcDomainInfoListDestructor(void *ptr)
+{
+ struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr;
+
+ while (i->short_name != NULL) {
+ free(i->short_name);
+ free(i->dns_name);
+ i += 1;
+ }
+}
+
/* Enumerate the domain trusts known by Winbind */
wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
{
struct winbindd_response response;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
char *p = NULL;
- char *q = NULL;
char *extra_data = NULL;
- int count = 0;
struct wbcDomainInfo *d_list = NULL;
int i = 0;
@@ -417,18 +527,9 @@ wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
BAIL_ON_WBC_ERROR(wbc_status);
}
- /* Count number of domains */
-
- count = 0;
- while (p) {
- count++;
-
- if ((q = strchr(p, '\n')) != NULL)
- q++;
- p = q;
- }
-
- d_list = talloc_array(NULL, struct wbcDomainInfo, count);
+ d_list = (struct wbcDomainInfo *)wbcAllocateMemory(
+ response.data.num_entries + 1,sizeof(struct wbcDomainInfo),
+ wbcDomainInfoListDestructor);
BAIL_ON_PTR_ERROR(d_list, wbc_status);
extra_data = strdup((char*)response.extra_data.data);
@@ -438,7 +539,7 @@ wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
/* Outer loop processes the list of domain information */
- for (i=0; i<count && p; i++) {
+ for (i=0; i<response.data.num_entries && p; i++) {
char *next = strchr(p, '\n');
if (next) {
@@ -446,26 +547,30 @@ wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
next++;
}
- wbc_status = process_domain_info_string(d_list, &d_list[i], p);
+ wbc_status = process_domain_info_string(&d_list[i], p);
BAIL_ON_WBC_ERROR(wbc_status);
p = next;
}
*domains = d_list;
+ d_list = NULL;
*num_domains = i;
done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- if (d_list)
- talloc_free(d_list);
- if (extra_data)
- free(extra_data);
- }
-
+ winbindd_free_response(&response);
+ wbcFreeMemory(d_list);
+ free(extra_data);
return wbc_status;
}
+static void wbcDomainControllerInfoDestructor(void *ptr)
+{
+ struct wbcDomainControllerInfo *i =
+ (struct wbcDomainControllerInfo *)ptr;
+ free(i->dc_name);
+}
+
/* Enumerate the domain trusts known by Winbind */
wbcErr wbcLookupDomainController(const char *domain,
uint32_t flags,
@@ -491,7 +596,9 @@ wbcErr wbcLookupDomainController(const char *domain,
request.flags = flags;
- dc = talloc(NULL, struct wbcDomainControllerInfo);
+ dc = (struct wbcDomainControllerInfo *)wbcAllocateMemory(
+ 1, sizeof(struct wbcDomainControllerInfo),
+ wbcDomainControllerInfoDestructor);
BAIL_ON_PTR_ERROR(dc, wbc_status);
/* Send request */
@@ -501,82 +608,87 @@ wbcErr wbcLookupDomainController(const char *domain,
&response);
BAIL_ON_WBC_ERROR(wbc_status);
- dc->dc_name = talloc_strdup(dc, response.data.dsgetdcname.dc_unc);
+ dc->dc_name = strdup(response.data.dsgetdcname.dc_unc);
BAIL_ON_PTR_ERROR(dc->dc_name, wbc_status);
*dc_info = dc;
+ dc = NULL;
done:
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- talloc_free(dc);
- }
-
+ wbcFreeMemory(dc);
return wbc_status;
}
-static wbcErr wbc_create_domain_controller_info_ex(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
+static void wbcDomainControllerInfoExDestructor(void *ptr)
+{
+ struct wbcDomainControllerInfoEx *i =
+ (struct wbcDomainControllerInfoEx *)ptr;
+ free((char *)(i->dc_unc));
+ free((char *)(i->dc_address));
+ free((char *)(i->domain_guid));
+ free((char *)(i->domain_name));
+ free((char *)(i->forest_name));
+ free((char *)(i->dc_site_name));
+ free((char *)(i->client_site_name));
+}
+
+static wbcErr wbc_create_domain_controller_info_ex(const struct winbindd_response *resp,
struct wbcDomainControllerInfoEx **_i)
{
wbcErr wbc_status = WBC_ERR_SUCCESS;
struct wbcDomainControllerInfoEx *i;
struct wbcGuid guid;
- i = talloc(mem_ctx, struct wbcDomainControllerInfoEx);
+ i = (struct wbcDomainControllerInfoEx *)wbcAllocateMemory(
+ 1, sizeof(struct wbcDomainControllerInfoEx),
+ wbcDomainControllerInfoExDestructor);
BAIL_ON_PTR_ERROR(i, wbc_status);
- i->dc_unc = talloc_strdup(i, resp->data.dsgetdcname.dc_unc);
+ i->dc_unc = strdup(resp->data.dsgetdcname.dc_unc);
BAIL_ON_PTR_ERROR(i->dc_unc, wbc_status);
- i->dc_address = talloc_strdup(i, resp->data.dsgetdcname.dc_address);
+ i->dc_address = strdup(resp->data.dsgetdcname.dc_address);
BAIL_ON_PTR_ERROR(i->dc_address, wbc_status);
i->dc_address_type = resp->data.dsgetdcname.dc_address_type;
wbc_status = wbcStringToGuid(resp->data.dsgetdcname.domain_guid, &guid);
if (WBC_ERROR_IS_OK(wbc_status)) {
- i->domain_guid = talloc(i, struct wbcGuid);
+ i->domain_guid = (struct wbcGuid *)malloc(
+ sizeof(struct wbcGuid));
BAIL_ON_PTR_ERROR(i->domain_guid, wbc_status);
*i->domain_guid = guid;
- } else {
- i->domain_guid = NULL;
}
- i->domain_name = talloc_strdup(i, resp->data.dsgetdcname.domain_name);
+ i->domain_name = strdup(resp->data.dsgetdcname.domain_name);
BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
if (resp->data.dsgetdcname.forest_name[0] != '\0') {
- i->forest_name = talloc_strdup(i,
- resp->data.dsgetdcname.forest_name);
+ i->forest_name = strdup(resp->data.dsgetdcname.forest_name);
BAIL_ON_PTR_ERROR(i->forest_name, wbc_status);
- } else {
- i->forest_name = NULL;
}
i->dc_flags = resp->data.dsgetdcname.dc_flags;
if (resp->data.dsgetdcname.dc_site_name[0] != '\0') {
- i->dc_site_name = talloc_strdup(i,
- resp->data.dsgetdcname.dc_site_name);
+ i->dc_site_name = strdup(resp->data.dsgetdcname.dc_site_name);
BAIL_ON_PTR_ERROR(i->dc_site_name, wbc_status);
- } else {
- i->dc_site_name = NULL;
}
if (resp->data.dsgetdcname.client_site_name[0] != '\0') {
- i->client_site_name = talloc_strdup(i,
+ i->client_site_name = strdup(
resp->data.dsgetdcname.client_site_name);
BAIL_ON_PTR_ERROR(i->client_site_name, wbc_status);
- } else {
- i->client_site_name = NULL;
}
*_i = i;
i = NULL;
done:
- talloc_free(i);
+ if (i != NULL) {
+ wbcFreeMemory(i);
+ }
return wbc_status;
}
@@ -631,8 +743,7 @@ wbcErr wbcLookupDomainControllerEx(const char *domain,
BAIL_ON_WBC_ERROR(wbc_status);
if (dc_info) {
- wbc_status = wbc_create_domain_controller_info_ex(NULL,
- &response,
+ wbc_status = wbc_create_domain_controller_info_ex(&response,
dc_info);
BAIL_ON_WBC_ERROR(wbc_status);
}
@@ -642,35 +753,72 @@ done:
return wbc_status;
}
+static void wbcNamedBlobDestructor(void *ptr)
+{
+ struct wbcNamedBlob *b = (struct wbcNamedBlob *)ptr;
+
+ while (b->name != NULL) {
+ free((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 **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 blob;
+ 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];
- *blobs = talloc_realloc(NULL, *blobs, struct wbcNamedBlob,
- *(num_blobs)+1);
- BAIL_ON_PTR_ERROR(*blobs, wbc_status);
+ blob->name = strdup(name);
+ BAIL_ON_PTR_ERROR(blob->name, wbc_status);
+ blob->flags = flags;
- blob.name = talloc_strdup(*blobs, name);
- BAIL_ON_PTR_ERROR(blob.name, wbc_status);
- blob.flags = flags;
- blob.blob.length = length;
- blob.blob.data = (uint8_t *)talloc_memdup(*blobs, data, length);
- BAIL_ON_PTR_ERROR(blob.blob.data, wbc_status);
+ 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);
- (*(blobs))[*num_blobs] = blob;
- *(num_blobs) += 1;
+ *num_blobs += 1;
+ *pblobs = blobs;
+ blobs = NULL;
wbc_status = WBC_ERR_SUCCESS;
done:
- if (!WBC_ERROR_IS_OK(wbc_status) && blobs) {
- wbcFreeMemory(*blobs);
- }
+ wbcFreeMemory(blobs);
return wbc_status;
}
diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c
index ec8d205647..19bb3e9e0a 100644
--- a/nsswitch/libwbclient/wbclient.c
+++ b/nsswitch/libwbclient/wbclient.c
@@ -23,8 +23,6 @@
/* Required Headers */
#include "replace.h"
-#include "talloc.h"
-#include "tevent.h"
#include "libwbclient.h"
/* From wb_common.c */
@@ -36,16 +34,7 @@ NSS_STATUS winbindd_priv_request_response(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
-/** @brief Wrapper around Winbind's send/receive API call
- *
- * @param cmd Winbind command operation to perform
- * @param request Send structure
- * @param response Receive structure
- *
- * @return #wbcErr
- **/
-
-/**********************************************************************
+/*
result == NSS_STATUS_UNAVAIL: winbind not around
result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
@@ -56,7 +45,7 @@ NSS_STATUS winbindd_priv_request_response(int req_type,
(as far as I have seen) with the callers of is_trusted_domains.
--Volker
-**********************************************************************/
+*/
static wbcErr wbcRequestResponseInt(
int cmd,
@@ -91,6 +80,15 @@ static wbcErr wbcRequestResponseInt(
return wbc_status;
}
+/**
+ * @brief Wrapper around Winbind's send/receive API call
+ *
+ * @param cmd Winbind command operation to perform
+ * @param request Send structure
+ * @param response Receive structure
+ *
+ * @return #wbcErr
+ */
wbcErr wbcRequestResponse(int cmd,
struct winbindd_request *request,
struct winbindd_response *response)
@@ -149,35 +147,113 @@ const char *wbcErrorString(wbcErr error)
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 *)(((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)
{
- if (p)
- talloc_free(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)
{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcLibraryDetails *info;
- info = talloc(NULL, struct wbcLibraryDetails);
- BAIL_ON_PTR_ERROR(info, wbc_status);
+ 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 = talloc_strdup(info,
- WBCLIENT_VENDOR_VERSION);
- BAIL_ON_PTR_ERROR(info->vendor_version, wbc_status);
+ info->vendor_version = WBCLIENT_VENDOR_VERSION;
*_details = info;
- info = NULL;
-
- wbc_status = WBC_ERR_SUCCESS;
-
-done:
- talloc_free(info);
- return wbc_status;
+ return WBC_ERR_SUCCESS;
}
diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index ac206909b0..c5f3b77ed8 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -65,9 +65,12 @@ const char *wbcErrorString(wbcErr error);
* 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()
**/
#define WBCLIENT_MAJOR_VERSION 0
-#define WBCLIENT_MINOR_VERSION 5
+#define WBCLIENT_MINOR_VERSION 8
#define WBCLIENT_VENDOR_VERSION "Samba libwbclient"
struct wbcLibraryDetails {
uint16_t major_version;
@@ -81,11 +84,11 @@ struct wbcLibraryDetails {
**/
struct wbcInterfaceDetails {
uint32_t interface_version;
- const char *winbind_version;
+ char *winbind_version;
char winbind_separator;
- const char *netbios_name;
- const char *netbios_domain;
- const char *dns_domain;
+ char *netbios_name;
+ char *netbios_domain;
+ char *dns_domain;
};
/*
@@ -191,7 +194,6 @@ struct wbcDomainInfo {
#define WBC_DOMINFO_TRUSTTYPE_IN_FOREST 0x00000002
#define WBC_DOMINFO_TRUSTTYPE_EXTERNAL 0x00000003
-
/**
* @brief Auth User Parameters
**/
@@ -429,12 +431,23 @@ struct wbcUserPasswordPolicyInfo {
**/
enum wbcPasswordChangeRejectReason {
- WBC_PWD_CHANGE_REJECT_OTHER=0,
- WBC_PWD_CHANGE_REJECT_TOO_SHORT=1,
- WBC_PWD_CHANGE_REJECT_IN_HISTORY=2,
- WBC_PWD_CHANGE_REJECT_COMPLEXITY=5
+ 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
**/
@@ -518,6 +531,19 @@ void wbcFreeMemory(void*);
*/
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
*
@@ -611,6 +637,16 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
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
*/
@@ -757,6 +793,35 @@ wbcErr wbcGidToSid(gid_t gid,
wbcErr wbcQueryGidToSid(gid_t gid,
struct wbcDomainSid *sid);
+enum wbcIdType {
+ WBC_ID_TYPE_NOT_SPECIFIED,
+ WBC_ID_TYPE_UID,
+ WBC_ID_TYPE_GID
+};
+
+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
*
@@ -782,6 +847,9 @@ wbcErr wbcAllocateGid(gid_t *pgid);
* @param *sid Pointer to the sid of the diresired 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);
@@ -792,6 +860,9 @@ wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid);
* @param *sid Pointer to the sid of the diresired 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);
@@ -802,6 +873,9 @@ wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid);
* @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);
@@ -812,6 +886,9 @@ wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid);
* @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);
@@ -821,6 +898,9 @@ wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid);
* @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);
@@ -830,6 +910,9 @@ wbcErr wbcSetUidHwm(uid_t uid_hwm);
* @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);
@@ -970,13 +1053,28 @@ wbcErr wbcGetGroups(const char *account,
/**
* @brief Lookup the current status of a trusted domain
*
- * @param domain Domain to query
- * @param *info Pointer to returned domain_info struct
+ * @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 **info);
+ 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
diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h
index 5ce820785e..31f413057e 100644
--- a/nsswitch/libwbclient/wbclient_internal.h
+++ b/nsswitch/libwbclient/wbclient_internal.h
@@ -32,4 +32,10 @@ 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/nsswitch/libwbclient/wscript_build b/nsswitch/libwbclient/wscript_build
new file mode 100644
index 0000000000..d9255159d0
--- /dev/null
+++ b/nsswitch/libwbclient/wscript_build
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+bld.SAMBA_LIBRARY('wbclient',
+ source='wbc_guid.c wbc_idmap.c wbclient.c wbc_pam.c wbc_pwd.c wbc_sid.c wbc_util.c',
+ deps='winbind-client',
+ public_headers='wbclient.h',
+ vnum='0'
+ )
diff --git a/nsswitch/nsstest.c b/nsswitch/nsstest.c
index 26f816f5d1..d84e028513 100644
--- a/nsswitch/nsstest.c
+++ b/nsswitch/nsstest.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
nss tester for winbindd
Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Tim Potter 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,8 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
-
+#include "replace.h"
#include "nsswitch/nsstest.h"
static const char *so_path = "/lib/libnss_winbind.so";
@@ -29,11 +29,13 @@ static int total_errors;
static void *find_fn(const char *name)
{
- char s[1024];
+ char *s;
static void *h;
void *res;
- snprintf(s,sizeof(s), "_nss_%s_%s", nss_name, name);
+ if (asprintf(&s, "_nss_%s_%s", nss_name, name) < 0) {
+ exit(1);
+ }
if (!h) {
h = dlopen(so_path, RTLD_LAZY);
@@ -45,8 +47,11 @@ static void *find_fn(const char *name)
res = dlsym(h, s);
if (!res) {
printf("Can't find function %s\n", s);
+ total_errors++;
+ free(s);
return NULL;
}
+ free(s);
return res;
}
@@ -61,11 +66,16 @@ static void report_nss_error(const char *who, NSS_STATUS status)
static struct passwd *nss_getpwent(void)
{
NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *,
- size_t , int *) = find_fn("getpwent_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(struct passwd *, char *,
+ size_t, int *))find_fn("getpwent_r");
static struct passwd pwd;
static char buf[1000];
NSS_STATUS status;
+ if (!_nss_getpwent_r)
+ return NULL;
+
status = _nss_getpwent_r(&pwd, buf, sizeof(buf), &nss_errno);
if (status == NSS_STATUS_NOTFOUND) {
return NULL;
@@ -80,11 +90,16 @@ static struct passwd *nss_getpwent(void)
static struct passwd *nss_getpwnam(const char *name)
{
NSS_STATUS (*_nss_getpwnam_r)(const char *, struct passwd *, char *,
- size_t , int *) = find_fn("getpwnam_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(const char *, struct passwd *, char *,
+ size_t, int *))find_fn("getpwnam_r");
static struct passwd pwd;
static char buf[1000];
NSS_STATUS status;
+ if (!_nss_getpwnam_r)
+ return NULL;
+
status = _nss_getpwnam_r(name, &pwd, buf, sizeof(buf), &nss_errno);
if (status == NSS_STATUS_NOTFOUND) {
return NULL;
@@ -99,11 +114,16 @@ static struct passwd *nss_getpwnam(const char *name)
static struct passwd *nss_getpwuid(uid_t uid)
{
NSS_STATUS (*_nss_getpwuid_r)(uid_t , struct passwd *, char *,
- size_t , int *) = find_fn("getpwuid_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(uid_t, struct passwd *, char *,
+ size_t, int *))find_fn("getpwuid_r");
static struct passwd pwd;
static char buf[1000];
NSS_STATUS status;
+ if (!_nss_getpwuid_r)
+ return NULL;
+
status = _nss_getpwuid_r(uid, &pwd, buf, sizeof(buf), &nss_errno);
if (status == NSS_STATUS_NOTFOUND) {
return NULL;
@@ -117,8 +137,13 @@ static struct passwd *nss_getpwuid(uid_t uid)
static void nss_setpwent(void)
{
- NSS_STATUS (*_nss_setpwent)(void) = find_fn("setpwent");
+ NSS_STATUS (*_nss_setpwent)(void) =
+ (NSS_STATUS(*)(void))find_fn("setpwent");
NSS_STATUS status;
+
+ if (!_nss_setpwent)
+ return;
+
status = _nss_setpwent();
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("setpwent", status);
@@ -127,8 +152,13 @@ static void nss_setpwent(void)
static void nss_endpwent(void)
{
- NSS_STATUS (*_nss_endpwent)(void) = find_fn("endpwent");
+ NSS_STATUS (*_nss_endpwent)(void) =
+ (NSS_STATUS (*)(void))find_fn("endpwent");
NSS_STATUS status;
+
+ if (!_nss_endpwent)
+ return;
+
status = _nss_endpwent();
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("endpwent", status);
@@ -139,26 +169,37 @@ static void nss_endpwent(void)
static struct group *nss_getgrent(void)
{
NSS_STATUS (*_nss_getgrent_r)(struct group *, char *,
- size_t , int *) = find_fn("getgrent_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(struct group *, char *,
+ size_t, int *))find_fn("getgrent_r");
static struct group grp;
static char *buf;
static int buflen = 1024;
NSS_STATUS status;
- if (!buf) buf = malloc_array_p(char, buflen);
+ if (!_nss_getgrent_r)
+ return NULL;
+
+ if (!buf)
+ buf = (char *)malloc(buflen);
again:
status = _nss_getgrent_r(&grp, buf, buflen, &nss_errno);
if (status == NSS_STATUS_TRYAGAIN) {
buflen *= 2;
- buf = realloc_p(buf, char, buflen);
+ buf = (char *)realloc(buf, buflen);
+ if (!buf) {
+ return NULL;
+ }
goto again;
}
if (status == NSS_STATUS_NOTFOUND) {
+ free(buf);
return NULL;
}
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("getgrent", status);
+ free(buf);
return NULL;
}
return &grp;
@@ -167,25 +208,36 @@ again:
static struct group *nss_getgrnam(const char *name)
{
NSS_STATUS (*_nss_getgrnam_r)(const char *, struct group *, char *,
- size_t , int *) = find_fn("getgrnam_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(const char *, struct group *, char *,
+ size_t, int *))find_fn("getgrnam_r");
static struct group grp;
static char *buf;
static int buflen = 1000;
NSS_STATUS status;
- if (!buf) buf = malloc_array_p(char, buflen);
+ if (!_nss_getgrnam_r)
+ return NULL;
+
+ if (!buf)
+ buf = (char *)malloc(buflen);
again:
status = _nss_getgrnam_r(name, &grp, buf, buflen, &nss_errno);
if (status == NSS_STATUS_TRYAGAIN) {
buflen *= 2;
- buf = realloc_p(buf, char, buflen);
+ buf = (char *)realloc(buf, buflen);
+ if (!buf) {
+ return NULL;
+ }
goto again;
}
if (status == NSS_STATUS_NOTFOUND) {
+ free(buf);
return NULL;
}
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("getgrnam", status);
+ free(buf);
return NULL;
}
return &grp;
@@ -194,25 +246,37 @@ again:
static struct group *nss_getgrgid(gid_t gid)
{
NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *,
- size_t , int *) = find_fn("getgrgid_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(gid_t, struct group *, char *,
+ size_t, int *))find_fn("getgrgid_r");
static struct group grp;
static char *buf;
static int buflen = 1000;
NSS_STATUS status;
- if (!buf) buf = malloc_array_p(char, buflen);
+ if (!_nss_getgrgid_r)
+ return NULL;
+
+ if (!buf)
+ buf = (char *)malloc(buflen);
+
again:
status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno);
if (status == NSS_STATUS_TRYAGAIN) {
buflen *= 2;
- buf = realloc_p(buf, char, buflen);
+ buf = (char *)realloc(buf, buflen);
+ if (!buf) {
+ return NULL;
+ }
goto again;
}
if (status == NSS_STATUS_NOTFOUND) {
+ free(buf);
return NULL;
}
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("getgrgid", status);
+ free(buf);
return NULL;
}
return &grp;
@@ -220,8 +284,13 @@ again:
static void nss_setgrent(void)
{
- NSS_STATUS (*_nss_setgrent)(void) = find_fn("setgrent");
+ NSS_STATUS (*_nss_setgrent)(void) =
+ (NSS_STATUS (*)(void))find_fn("setgrent");
NSS_STATUS status;
+
+ if (!_nss_setgrent)
+ return;
+
status = _nss_setgrent();
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("setgrent", status);
@@ -230,8 +299,13 @@ static void nss_setgrent(void)
static void nss_endgrent(void)
{
- NSS_STATUS (*_nss_endgrent)(void) = find_fn("endgrent");
+ NSS_STATUS (*_nss_endgrent)(void) =
+ (NSS_STATUS (*)(void))find_fn("endgrent");
NSS_STATUS status;
+
+ if (!_nss_endgrent)
+ return;
+
status = _nss_endgrent();
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("endgrent", status);
@@ -242,10 +316,13 @@ static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *sta
{
NSS_STATUS (*_nss_initgroups)(char *, gid_t , long int *,
long int *, gid_t **, long int , int *) =
- find_fn("initgroups_dyn");
+ (NSS_STATUS (*)(char *, gid_t, long int *,
+ long int *, gid_t **,
+ long int, int *))find_fn("initgroups_dyn");
NSS_STATUS status;
- if (!_nss_initgroups) return NSS_STATUS_UNAVAIL;
+ if (!_nss_initgroups)
+ return NSS_STATUS_UNAVAIL;
status = _nss_initgroups(user, group, start, size, groups, 0, &nss_errno);
if (status != NSS_STATUS_SUCCESS) {
@@ -256,11 +333,11 @@ static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *sta
static void print_passwd(struct passwd *pwd)
{
- printf("%s:%s:%d:%d:%s:%s:%s\n",
+ printf("%s:%s:%lu:%lu:%s:%s:%s\n",
pwd->pw_name,
pwd->pw_passwd,
- pwd->pw_uid,
- pwd->pw_gid,
+ (unsigned long)pwd->pw_uid,
+ (unsigned long)pwd->pw_gid,
pwd->pw_gecos,
pwd->pw_dir,
pwd->pw_shell);
@@ -269,10 +346,10 @@ static void print_passwd(struct passwd *pwd)
static void print_group(struct group *grp)
{
int i;
- printf("%s:%s:%d: ",
+ printf("%s:%s:%lu:",
grp->gr_name,
grp->gr_passwd,
- grp->gr_gid);
+ (unsigned long)grp->gr_gid);
if (!grp->gr_mem[0]) {
printf("\n");
@@ -280,7 +357,7 @@ static void print_group(struct group *grp)
}
for (i=0; grp->gr_mem[i+1]; i++) {
- printf("%s, ", grp->gr_mem[i]);
+ printf("%s,", grp->gr_mem[i]);
}
printf("%s\n", grp->gr_mem[i]);
}
@@ -293,7 +370,7 @@ static void nss_test_initgroups(char *name, gid_t gid)
int i;
NSS_STATUS status;
- groups = (gid_t *)malloc_array_p(gid_t, size);
+ groups = (gid_t *)malloc(size);
groups[0] = gid;
status = nss_initgroups(name, gid, &groups, &start, &size);
@@ -303,9 +380,9 @@ static void nss_test_initgroups(char *name, gid_t gid)
}
for (i=0; i<start-1; i++) {
- printf("%d, ", groups[i]);
+ printf("%lu, ", (unsigned long)groups[i]);
}
- printf("%d\n", groups[i]);
+ printf("%lu\n", (unsigned long)groups[i]);
}
diff --git a/nsswitch/nsstest.m4 b/nsswitch/nsstest.m4
deleted file mode 100644
index 37596489c0..0000000000
--- a/nsswitch/nsstest.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-case "$host_os" in
- *linux*)
- SMB_ENABLE(nsstest,YES)
- ;;
- *)
- SMB_ENABLE(nsstest,NO)
- ;;
-esac
diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c
index b80203674b..7005c25fae 100644
--- a/nsswitch/pam_winbind.c
+++ b/nsswitch/pam_winbind.c
@@ -156,7 +156,7 @@ static inline void textdomain_init(void);
static inline void textdomain_init(void)
{
if (!initialized) {
- bindtextdomain(MODULE_NAME, dyn_LOCALEDIR);
+ bindtextdomain(MODULE_NAME, LOCALEDIR);
initialized = 1;
}
return;
@@ -1077,12 +1077,11 @@ static bool winbind_name_to_sid_string(struct pwb_context *ctx,
char *sid_list_buffer,
int sid_list_buffer_size)
{
- const char* sid_string = NULL;
- char *sid_str = NULL;
+ char sid_string[WBC_SID_STRING_BUFLEN];
/* lookup name? */
if (IS_SID_STRING(name)) {
- sid_string = name;
+ strlcpy(sid_string, name, sizeof(sid_string));
} else {
wbcErr wbc_status;
struct wbcDomainSid sid;
@@ -1098,21 +1097,13 @@ static bool winbind_name_to_sid_string(struct pwb_context *ctx,
return false;
}
- wbc_status = wbcSidToString(&sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
-
- sid_string = sid_str;
+ wbcSidToStringBuf(&sid, sid_string, sizeof(sid_string));
}
if (!safe_append_string(sid_list_buffer, sid_string,
sid_list_buffer_size)) {
- wbcFreeMemory(sid_str);
return false;
}
-
- wbcFreeMemory(sid_str);
return true;
}
@@ -1144,7 +1135,7 @@ static bool winbind_name_list_to_sid_string_list(struct pwb_context *ctx,
}
search_location = name_list;
- while ((comma = strstr(search_location, ",")) != NULL) {
+ while ((comma = strchr(search_location, ',')) != NULL) {
current_name = strndup(search_location,
comma - search_location);
if (NULL == current_name) {
@@ -1199,10 +1190,8 @@ static bool winbind_name_list_to_sid_string_list(struct pwb_context *ctx,
* It is malformated parameter here, overwrite the last ','.
*/
len = strlen(sid_list_buffer);
- if (len) {
- if (sid_list_buffer[len - 1] == ',') {
- sid_list_buffer[len - 1] = '\0';
- }
+ if ((len != 0) && (sid_list_buffer[len - 1] == ',')) {
+ sid_list_buffer[len - 1] = '\0';
}
}
@@ -1434,12 +1423,12 @@ static void _pam_warn_krb5_failure(struct pwb_context *ctx,
static bool _pam_check_remark_auth_err(struct pwb_context *ctx,
const struct wbcAuthErrorInfo *e,
const char *nt_status_string,
- int *pam_error)
+ int *pam_err)
{
const char *ntstatus = NULL;
const char *error_string = NULL;
- if (!e || !pam_error) {
+ if (!e || !pam_err) {
return false;
}
@@ -1453,18 +1442,18 @@ static bool _pam_check_remark_auth_err(struct pwb_context *ctx,
error_string = _get_ntstatus_error_string(nt_status_string);
if (error_string) {
_make_remark(ctx, PAM_ERROR_MSG, error_string);
- *pam_error = e->pam_error;
+ *pam_err = e->pam_error;
return true;
}
if (e->display_string) {
- _make_remark(ctx, PAM_ERROR_MSG, e->display_string);
- *pam_error = e->pam_error;
+ _make_remark(ctx, PAM_ERROR_MSG, _(e->display_string));
+ *pam_err = e->pam_error;
return true;
}
_make_remark(ctx, PAM_ERROR_MSG, nt_status_string);
- *pam_error = e->pam_error;
+ *pam_err = e->pam_error;
return true;
}
@@ -1901,9 +1890,7 @@ static int winbind_auth_request(struct pwb_context *ctx,
}
done:
- if (logon.blobs) {
- wbcFreeMemory(logon.blobs);
- }
+ wbcFreeMemory(logon.blobs);
if (info && info->blobs && !p_info) {
wbcFreeMemory(info->blobs);
}
@@ -2000,22 +1987,22 @@ static int winbind_chauthtok_request(struct pwb_context *ctx,
switch (reject_reason) {
case -1:
break;
- case WBC_PWD_CHANGE_REJECT_OTHER:
+ case WBC_PWD_CHANGE_NO_ERROR:
if ((min_pwd_age > 0) &&
(pwd_last_set + min_pwd_age > time(NULL))) {
PAM_WB_REMARK_DIRECT(ctx,
"NT_STATUS_PWD_TOO_RECENT");
}
break;
- case WBC_PWD_CHANGE_REJECT_TOO_SHORT:
+ case WBC_PWD_CHANGE_PASSWORD_TOO_SHORT:
PAM_WB_REMARK_DIRECT(ctx,
"NT_STATUS_PWD_TOO_SHORT");
break;
- case WBC_PWD_CHANGE_REJECT_IN_HISTORY:
+ case WBC_PWD_CHANGE_PWD_IN_HISTORY:
PAM_WB_REMARK_DIRECT(ctx,
"NT_STATUS_PWD_HISTORY_CONFLICT");
break;
- case WBC_PWD_CHANGE_REJECT_COMPLEXITY:
+ case WBC_PWD_CHANGE_NOT_COMPLEX:
_make_remark(ctx, PAM_ERROR_MSG,
_("Password does not meet "
"complexity requirements"));
@@ -2424,7 +2411,7 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainSid sid;
enum wbcSidType type;
- char *domain;
+ char *domain = NULL;
char *name;
char *p;
diff --git a/nsswitch/pam_winbind.h b/nsswitch/pam_winbind.h
index 25d673e231..0d9529e726 100644
--- a/nsswitch/pam_winbind.h
+++ b/nsswitch/pam_winbind.h
@@ -1,15 +1,60 @@
+/*
+ * Copyright (c) Andrew Tridgell <tridge@samba.org> 2000
+ * Copyright (c) Tim Potter <tpot@samba.org> 2000
+ * Copyright (c) Andrew Bartlettt <abartlet@samba.org> 2002
+ * Copyright (c) Guenther Deschner <gd@samba.org> 2005-2008
+ * Copyright (c) Jan Rêkorajski 1999.
+ * Copyright (c) Andrew G. Morgan 1996-8.
+ * Copyright (c) Alex O. Yuriev, 1996.
+ * Copyright (c) Cristian Gafton 1996.
+ * Copyright (C) Elliot Lee <sopwith@redhat.com> 1996, Red Hat Software.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
/* pam_winbind header file
(Solaris needs some macros from Linux for common PAM code)
Shirish Kalele 2000
*/
+#ifndef _NSSWITCH_PAM_WINBIND_H_
+#define _NSSWITCH_PAM_WINBIND_H_
+
#include "../lib/replace/replace.h"
#include "system/syslog.h"
#include "system/time.h"
#include <talloc.h>
#include "libwbclient/wbclient.h"
-#include "localedir.h"
#define MODULE_NAME "pam_winbind"
#define PAM_SM_AUTH
@@ -176,3 +221,5 @@ struct pwb_context {
#endif
#define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
#define TALLOC_P(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
+
+#endif /* _NSSWITCH_PAM_WINBIND_H_ */
diff --git a/nsswitch/tests/test_wbinfo.sh b/nsswitch/tests/test_wbinfo.sh
index 8d8f116e70..b344f718c5 100755
--- a/nsswitch/tests/test_wbinfo.sh
+++ b/nsswitch/tests/test_wbinfo.sh
@@ -15,7 +15,7 @@ shift 4
failed=0
samba4bindir="$BUILDDIR/bin"
-wbinfo="$samba4bindir/wbinfo$EXEEXT"
+wbinfo="$VALGRIND $samba4bindir/wbinfo$EXEEXT"
. `dirname $0`/../../testprogs/blackbox/subunit.sh
@@ -163,6 +163,7 @@ if test x$own_domain = x$DOMAIN; then
else
echo "Own domain reported as $own_domain instead of $DOMAIN"
echo "failure: wbinfo --own-domain against $TARGET check output"
+ failed=`expr $failed + 1`
fi
# this does not work
@@ -173,12 +174,21 @@ testit "wbinfo -D against $TARGET" $wbinfo -D $DOMAIN || failed=`expr $failed +
testit "wbinfo -i against $TARGET" $wbinfo -i "$DOMAIN/$USERNAME" || failed=`expr $failed + 1`
-testit "wbinfo --uid-info against $TARGET" $wbinfo --uid-info $admin_uid
+testit "wbinfo --uid-info against $TARGET" $wbinfo --uid-info $admin_uid || failed=`expr $failed + 1`
-# this does not work
-knownfail "wbinfo --group-info against $TARGET" $wbinfo --group-info "S-1-22-2-0"
-knownfail "wbinfo --gid-info against $TARGET" $wbinfo --gid-info 30001
-knownfail "wbinfo -r against $TARGET" $wbinfo -r "$DOMAIN/$USERNAME"
+echo "test: wbinfo --group-info against $TARGET"
+rawgid=`$wbinfo --group-info "Domain admins" | sed 's/.*:\([0-9][0-9]*\):/\1/'`
+if test x$? = x0; then
+ echo "success: wbinfo --group-info against $TARGET"
+else
+ echo "failure: wbinfo --group-info against $TARGET"
+ failed=`expr $failed + 1`
+fi
+
+gid=`echo $rawgid | sed 's/.*:\([0-9][0-9]*\):/\1/'`
+testit "wbinfo --gid-info against $TARGET" $wbinfo --gid-info $gid || failed=`expr $failed + 1`
+
+testit "wbinfo -r against $TARGET" $wbinfo -r "$DOMAIN/$USERNAME" || failed=`expr $failed + 1`
testit "wbinfo --user-domgroups against $TARGET" $wbinfo --user-domgroups $admin_sid || failed=`expr $failed + 1`
diff --git a/nsswitch/wb_common.c b/nsswitch/wb_common.c
index def41d5cea..dcfc8a5156 100644
--- a/nsswitch/wb_common.c
+++ b/nsswitch/wb_common.c
@@ -22,6 +22,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "replace.h"
+#include "system/select.h"
#include "winbind_client.h"
/* Global variables. These are effectively the client state information */
@@ -41,7 +43,8 @@ void winbindd_free_response(struct winbindd_response *response)
/* Initialise a request structure */
-void winbindd_init_request(struct winbindd_request *request, int request_type)
+static void winbindd_init_request(struct winbindd_request *request,
+ int request_type)
{
request->length = sizeof(struct winbindd_request);
@@ -64,7 +67,7 @@ static void init_response(struct winbindd_response *response)
#if HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR
__attribute__((destructor))
#endif
-void winbind_close_sock(void)
+static void winbind_close_sock(void)
{
if (winbindd_fd != -1) {
close(winbindd_fd);
@@ -232,8 +235,7 @@ static int winbind_named_pipe_sock(const char *dir)
for (wait_time = 0; connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1;
wait_time += slept) {
- struct timeval tv;
- fd_set w_fds;
+ struct pollfd pfd;
int ret;
int connect_errno = 0;
socklen_t errnosize;
@@ -243,16 +245,10 @@ static int winbind_named_pipe_sock(const char *dir)
switch (errno) {
case EINPROGRESS:
- FD_ZERO(&w_fds);
- if (fd < 0 || fd >= FD_SETSIZE) {
- errno = EBADF;
- goto error_out;
- }
- FD_SET(fd, &w_fds);
- tv.tv_sec = CONNECT_TIMEOUT - wait_time;
- tv.tv_usec = 0;
+ pfd.fd = fd;
+ pfd.events = POLLOUT;
- ret = select(fd + 1, NULL, &w_fds, NULL, &tv);
+ ret = poll(&pfd, 1, (CONNECT_TIMEOUT - wait_time) * 1000);
if (ret > 0) {
errnosize = sizeof(connect_errno);
@@ -370,7 +366,8 @@ static int winbind_open_pipe_sock(int recursing, int need_priv)
/* Write data to winbindd socket */
-int winbind_write_sock(void *buffer, int count, int recursing, int need_priv)
+static int winbind_write_sock(void *buffer, int count, int recursing,
+ int need_priv)
{
int result, nwritten;
@@ -388,53 +385,46 @@ int winbind_write_sock(void *buffer, int count, int recursing, int need_priv)
nwritten = 0;
while(nwritten < count) {
- struct timeval tv;
- fd_set r_fds;
+ struct pollfd pfd;
+ int ret;
/* Catch pipe close on other end by checking if a read()
- call would not block by calling select(). */
+ call would not block by calling poll(). */
- FD_ZERO(&r_fds);
- if (winbindd_fd < 0 || winbindd_fd >= FD_SETSIZE) {
- errno = EBADF;
- winbind_close_sock();
- return -1;
- }
- FD_SET(winbindd_fd, &r_fds);
- ZERO_STRUCT(tv);
+ pfd.fd = winbindd_fd;
+ pfd.events = POLLIN|POLLHUP;
- if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) {
+ ret = poll(&pfd, 1, 0);
+ if (ret == -1) {
winbind_close_sock();
- return -1; /* Select error */
+ return -1; /* poll error */
}
/* Write should be OK if fd not available for reading */
- if (!FD_ISSET(winbindd_fd, &r_fds)) {
+ if ((ret == 1) && (pfd.revents & (POLLIN|POLLHUP|POLLERR))) {
- /* Do the write */
-
- result = write(winbindd_fd,
- (char *)buffer + nwritten,
- count - nwritten);
-
- if ((result == -1) || (result == 0)) {
+ /* Pipe has closed on remote end */
- /* Write failed */
+ winbind_close_sock();
+ goto restart;
+ }
- winbind_close_sock();
- return -1;
- }
+ /* Do the write */
- nwritten += result;
+ result = write(winbindd_fd,
+ (char *)buffer + nwritten,
+ count - nwritten);
- } else {
+ if ((result == -1) || (result == 0)) {
- /* Pipe has closed on remote end */
+ /* Write failed */
winbind_close_sock();
- goto restart;
+ return -1;
}
+
+ nwritten += result;
}
return nwritten;
@@ -442,10 +432,10 @@ int winbind_write_sock(void *buffer, int count, int recursing, int need_priv)
/* Read data from winbindd socket */
-int winbind_read_sock(void *buffer, int count)
+static int winbind_read_sock(void *buffer, int count)
{
int nread = 0;
- int total_time = 0, selret;
+ int total_time = 0;
if (winbindd_fd == -1) {
return -1;
@@ -453,29 +443,24 @@ int winbind_read_sock(void *buffer, int count)
/* Read data from socket */
while(nread < count) {
- struct timeval tv;
- fd_set r_fds;
+ struct pollfd pfd;
+ int ret;
/* Catch pipe close on other end by checking if a read()
- call would not block by calling select(). */
+ call would not block by calling poll(). */
+
+ pfd.fd = winbindd_fd;
+ pfd.events = POLLIN|POLLHUP;
- FD_ZERO(&r_fds);
- if (winbindd_fd < 0 || winbindd_fd >= FD_SETSIZE) {
- errno = EBADF;
- winbind_close_sock();
- return -1;
- }
- FD_SET(winbindd_fd, &r_fds);
- ZERO_STRUCT(tv);
/* Wait for 5 seconds for a reply. May need to parameterise this... */
- tv.tv_sec = 5;
- if ((selret = select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv)) == -1) {
+ ret = poll(&pfd, 1, 5000);
+ if (ret == -1) {
winbind_close_sock();
- return -1; /* Select error */
+ return -1; /* poll error */
}
- if (selret == 0) {
+ if (ret == 0) {
/* Not ready for read yet... */
if (total_time >= 30) {
/* Timeout */
@@ -486,7 +471,7 @@ int winbind_read_sock(void *buffer, int count)
continue;
}
- if (FD_ISSET(winbindd_fd, &r_fds)) {
+ if ((ret == 1) && (pfd.revents & (POLLIN|POLLHUP|POLLERR))) {
/* Do the Read */
@@ -513,7 +498,7 @@ int winbind_read_sock(void *buffer, int count)
/* Read reply */
-int winbindd_read_reply(struct winbindd_response *response)
+static int winbindd_read_reply(struct winbindd_response *response)
{
int result1, result2 = 0;
@@ -529,6 +514,10 @@ int winbindd_read_reply(struct winbindd_response *response)
return -1;
}
+ if (response->length < sizeof(struct winbindd_response)) {
+ return -1;
+ }
+
/* We actually send the pointer value of the extra_data field from
the server. This has no meaning in the client's address space
so we clear it out. */
@@ -682,26 +671,3 @@ NSS_STATUS winbindd_priv_request_response(int req_type,
return status;
}
-
-/*************************************************************************
- ************************************************************************/
-
-const char *nss_err_str(NSS_STATUS ret)
-{
- switch (ret) {
- case NSS_STATUS_TRYAGAIN:
- return "NSS_STATUS_TRYAGAIN";
- case NSS_STATUS_SUCCESS:
- return "NSS_STATUS_SUCCESS";
- case NSS_STATUS_NOTFOUND:
- return "NSS_STATUS_NOTFOUND";
- case NSS_STATUS_UNAVAIL:
- return "NSS_STATUS_UNAVAIL";
-#ifdef NSS_STATUS_RETURN
- case NSS_STATUS_RETURN:
- return "NSS_STATUS_RETURN";
-#endif
- default:
- return "UNKNOWN RETURN CODE!!!!!!!";
- }
-}
diff --git a/nsswitch/libwbclient/wb_reqtrans.c b/nsswitch/wb_reqtrans.c
index 6dc429bb7d..779ef52a92 100644
--- a/nsswitch/libwbclient/wb_reqtrans.c
+++ b/nsswitch/wb_reqtrans.c
@@ -32,7 +32,7 @@
#include "lib/util/tevent_unix.h"
#include "nsswitch/winbind_struct_protocol.h"
#include "nsswitch/libwbclient/wbclient.h"
-#include "nsswitch/libwbclient/wbc_async.h"
+#include "nsswitch/wb_reqtrans.h"
/* can't use DEBUG here... */
#define DEBUG(a,b)
diff --git a/nsswitch/libwbclient/wbc_async.h b/nsswitch/wb_reqtrans.h
index 76e02cadf2..941edf659a 100644
--- a/nsswitch/libwbclient/wbc_async.h
+++ b/nsswitch/wb_reqtrans.h
@@ -21,46 +21,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _WBC_ASYNC_H_
-#define _WBC_ASYNC_H_
+#ifndef _WB_REQTRANS_H_
+#define _WB_REQTRANS_H_
#include <talloc.h>
#include <tevent.h>
-#include "nsswitch/libwbclient/wbclient.h"
-
-struct wb_context;
-struct winbindd_request;
-struct winbindd_response;
-
-enum wbcDebugLevel {
- WBC_DEBUG_FATAL,
- WBC_DEBUG_ERROR,
- WBC_DEBUG_WARNING,
- WBC_DEBUG_TRACE
-};
-
-struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx, bool need_priv,
- struct winbindd_request *wb_req);
-wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presponse);
-struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx, const char* dir);
-int wbcSetDebug(struct wb_context *wb_ctx,
- void (*debug)(void *context,
- enum wbcDebugLevel level,
- const char *fmt,
- va_list ap) PRINTF_ATTRIBUTE(3,0),
- void *context);
-int wbcSetDebugStderr(struct wb_context *wb_ctx);
-void wbcDebug(struct wb_context *wb_ctx, enum wbcDebugLevel level,
- const char *fmt, ...) PRINTF_ATTRIBUTE(3,0);
-
-/* Definitions from wb_reqtrans.c */
-wbcErr map_wbc_err_from_errno(int error);
-
-bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err);
-wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req);
+#include "nsswitch/winbind_struct_protocol.h"
struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -92,4 +58,4 @@ struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx,
int wb_simple_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_response **presponse, int *err);
-#endif /*_WBC_ASYNC_H_*/
+#endif /*_WB_REQTRANS_H_*/
diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index a43ce8f4c9..ac07175022 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -22,11 +22,12 @@
*/
#include "includes.h"
+#include "popt_common.h"
#include "winbind_client.h"
#include "libwbclient/wbclient.h"
#include "lib/popt/popt.h"
#include "../libcli/auth/libcli_auth.h"
-#if !(_SAMBA_VERSION_) < 4
+#if (_SAMBA_BUILD_) >= 4
#include "lib/cmdline/popt_common.h"
#endif
@@ -47,7 +48,7 @@ static struct wbcInterfaceDetails *init_interface_details(void)
wbc_status = wbcInterfaceDetails(&details);
if (!WBC_ERROR_IS_OK(wbc_status)) {
d_fprintf(stderr, "could not obtain winbind interface "
- "details!\n");
+ "details: %s\n", wbcErrorString(wbc_status));
}
return details;
@@ -172,6 +173,8 @@ static bool wbinfo_get_userinfo(char *user)
wbc_status = wbcGetpwnam(user, &pwd);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcGetpwnam: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -184,6 +187,8 @@ static bool wbinfo_get_userinfo(char *user)
pwd->pw_dir,
pwd->pw_shell);
+ wbcFreeMemory(pwd);
+
return true;
}
@@ -195,6 +200,8 @@ static bool wbinfo_get_uidinfo(int uid)
wbc_status = wbcGetpwuid(uid, &pwd);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcGetpwuid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -207,6 +214,8 @@ static bool wbinfo_get_uidinfo(int uid)
pwd->pw_dir,
pwd->pw_shell);
+ wbcFreeMemory(pwd);
+
return true;
}
@@ -219,6 +228,8 @@ static bool wbinfo_get_user_sidinfo(const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
wbc_status = wbcGetpwsid(&sid, &pwd);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcGetpwsid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -244,6 +255,8 @@ static bool wbinfo_get_groupinfo(const char *group)
wbc_status = wbcGetgrnam(group, &grp);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcGetgrnam: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -273,6 +286,8 @@ static bool wbinfo_get_gidinfo(int gid)
wbc_status = wbcGetgrgid(gid, &grp);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcGetgrgid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -306,6 +321,8 @@ static bool wbinfo_get_usergroups(const char *user)
wbc_status = wbcGetGroups(user, &num_groups, &groups);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcGetGroups: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -331,23 +348,22 @@ static bool wbinfo_get_usersids(const char *user_sid_str)
wbc_status = wbcStringToSid(user_sid_str, &user_sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcLookupUserSids(&user_sid, false, &num_sids, &sids);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcLookupUserSids: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
for (i = 0; i < num_sids; i++) {
- char *str = NULL;
- wbc_status = wbcSidToString(&sids[i], &str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- wbcFreeMemory(sids);
- return false;
- }
+ char str[WBC_SID_STRING_BUFLEN];
+ wbcSidToStringBuf(&sids[i], str, sizeof(str));
d_printf("%s\n", str);
- wbcFreeMemory(str);
}
wbcFreeMemory(sids);
@@ -366,23 +382,22 @@ static bool wbinfo_get_userdomgroups(const char *user_sid_str)
wbc_status = wbcStringToSid(user_sid_str, &user_sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcLookupUserSids(&user_sid, true, &num_sids, &sids);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcLookupUserSids: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
for (i = 0; i < num_sids; i++) {
- char *str = NULL;
- wbc_status = wbcSidToString(&sids[i], &str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- wbcFreeMemory(sids);
- return false;
- }
+ char str[WBC_SID_STRING_BUFLEN];
+ wbcSidToStringBuf(&sids[i], str, sizeof(str));
d_printf("%s\n", str);
- wbcFreeMemory(str);
}
wbcFreeMemory(sids);
@@ -399,7 +414,7 @@ static bool wbinfo_get_sidaliases(const char *domain,
struct wbcDomainSid user_sid;
uint32_t *alias_rids = NULL;
uint32_t num_alias_rids;
- char *domain_sid_str = NULL;
+ char domain_sid_str[WBC_SID_STRING_BUFLEN];
/* Send request */
if ((domain == NULL) || (strequal(domain, ".")) ||
@@ -411,8 +426,8 @@ static bool wbinfo_get_sidaliases(const char *domain,
wbc_status = wbcDomainInfo(domain, &dinfo);
if (!WBC_ERROR_IS_OK(wbc_status)) {
- d_printf("wbcDomainInfo(%s) failed: %s\n", domain,
- wbcErrorString(wbc_status));
+ d_fprintf(stderr, "wbcDomainInfo(%s) failed: %s\n", domain,
+ wbcErrorString(wbc_status));
goto done;
}
wbc_status = wbcStringToSid(user_sid_str, &user_sid);
@@ -426,10 +441,7 @@ static bool wbinfo_get_sidaliases(const char *domain,
goto done;
}
- wbc_status = wbcSidToString(&dinfo->sid, &domain_sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto done;
- }
+ wbcSidToStringBuf(&dinfo->sid, domain_sid_str, sizeof(domain_sid_str));
for (i = 0; i < num_alias_rids; i++) {
d_printf("%s-%d\n", domain_sid_str, alias_rids[i]);
@@ -438,12 +450,7 @@ static bool wbinfo_get_sidaliases(const char *domain,
wbcFreeMemory(alias_rids);
done:
- if (domain_sid_str) {
- wbcFreeMemory(domain_sid_str);
- }
- if (dinfo) {
- wbcFreeMemory(dinfo);
- }
+ wbcFreeMemory(dinfo);
return (WBC_ERR_SUCCESS == wbc_status);
}
@@ -457,6 +464,8 @@ static bool wbinfo_wins_byname(const char *name)
wbc_status = wbcResolveWinsByName(name, &ip);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcResolveWinsByName: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -478,6 +487,8 @@ static bool wbinfo_wins_byip(const char *ip)
wbc_status = wbcResolveWinsByIP(ip, &name);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcResolveWinsByIP: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -502,6 +513,8 @@ static bool wbinfo_list_domains(bool list_all_domains, bool verbose)
wbc_status = wbcListTrusts(&domain_list, &num_domains);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcListTrusts: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -558,6 +571,8 @@ static bool wbinfo_list_domains(bool list_all_domains, bool verbose)
d_printf("\n");
}
+ wbcFreeMemory(domain_list);
+
return true;
}
@@ -588,6 +603,8 @@ static bool wbinfo_show_onlinestatus(const char *domain)
wbc_status = wbcListTrusts(&domain_list, &num_domains);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcListTrusts: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -608,6 +625,8 @@ static bool wbinfo_show_onlinestatus(const char *domain)
is_offline ? "offline" : "online" );
}
+ wbcFreeMemory(domain_list);
+
return true;
}
@@ -618,7 +637,7 @@ static bool wbinfo_domain_info(const char *domain)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainInfo *dinfo = NULL;
- char *sid_str = NULL;
+ char sid_str[WBC_SID_STRING_BUFLEN];
if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')){
domain = get_winbind_domain();
@@ -628,14 +647,12 @@ static bool wbinfo_domain_info(const char *domain)
wbc_status = wbcDomainInfo(domain, &dinfo);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcDomainInfo: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
- wbc_status = wbcSidToString(&dinfo->sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- wbcFreeMemory(dinfo);
- return false;
- }
+ wbcSidToStringBuf(&dinfo->sid, sid_str, sizeof(sid_str));
/* Display response */
@@ -654,7 +671,6 @@ static bool wbinfo_domain_info(const char *domain)
(dinfo->domain_flags & WBC_DOMINFO_DOMAIN_PRIMARY) ?
"Yes" : "No");
- wbcFreeMemory(sid_str);
wbcFreeMemory(dinfo);
return true;
@@ -742,12 +758,39 @@ static bool wbinfo_check_secret(const char *domain)
wbcFreeMemory(error);
}
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcCheckTrustCredentials: "
+ "%s\n", wbcErrorString(wbc_status));
return false;
}
return true;
}
+/* Find the currently connected DCs */
+
+static bool wbinfo_dc_info(const char *domain_name)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ size_t i, num_dcs;
+ const char **dc_names, **dc_ips;
+
+ wbc_status = wbcDcInfo(domain_name, &num_dcs,
+ &dc_names, &dc_ips);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ printf("Could not find dc info %s\n",
+ domain_name ? domain_name : "our domain");
+ return false;
+ }
+
+ for (i=0; i<num_dcs; i++) {
+ printf("%s (%s)\n", dc_names[i], dc_ips[i]);
+ }
+ wbcFreeMemory(dc_names);
+ wbcFreeMemory(dc_ips);
+
+ return true;
+}
+
/* Change trust account password */
static bool wbinfo_change_secret(const char *domain)
@@ -774,6 +817,8 @@ static bool wbinfo_change_secret(const char *domain)
wbcFreeMemory(error);
}
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcChangeTrustCredentials: "
+ "%s\n", wbcErrorString(wbc_status));
return false;
}
@@ -798,6 +843,8 @@ static bool wbinfo_ping_dc(void)
wbcFreeMemory(error);
}
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcPingDc: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -810,26 +857,23 @@ static bool wbinfo_uid_to_sid(uid_t uid)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainSid sid;
- char *sid_str = NULL;
+ char sid_str[WBC_SID_STRING_BUFLEN];
/* Send request */
wbc_status = wbcUidToSid(uid, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcUidToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
- wbc_status = wbcSidToString(&sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
+ wbcSidToStringBuf(&sid, sid_str, sizeof(sid_str));
/* Display response */
d_printf("%s\n", sid_str);
- wbcFreeMemory(sid_str);
-
return true;
}
@@ -839,26 +883,23 @@ static bool wbinfo_gid_to_sid(gid_t gid)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainSid sid;
- char *sid_str = NULL;
+ char sid_str[WBC_SID_STRING_BUFLEN];
/* Send request */
wbc_status = wbcGidToSid(gid, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcGidToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
- wbc_status = wbcSidToString(&sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
+ wbcSidToStringBuf(&sid, sid_str, sizeof(sid_str));
/* Display response */
d_printf("%s\n", sid_str);
- wbcFreeMemory(sid_str);
-
return true;
}
@@ -874,11 +915,15 @@ static bool wbinfo_sid_to_uid(const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcSidToUid(&sid, &uid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcSidToUid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -899,11 +944,15 @@ static bool wbinfo_sid_to_gid(const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcSidToGid(&sid, &gid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcSidToGid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -914,6 +963,74 @@ static bool wbinfo_sid_to_gid(const char *sid_str)
return true;
}
+static bool wbinfo_sids_to_unix_ids(const char *arg)
+{
+ char sidstr[WBC_SID_STRING_BUFLEN];
+ struct wbcDomainSid *sids;
+ struct wbcUnixId *unix_ids;
+ int i, num_sids;
+ const char *p;
+ wbcErr wbc_status;
+
+
+ num_sids = 0;
+ sids = NULL;
+ p = arg;
+
+ while (next_token(&p, sidstr, LIST_SEP, sizeof(sidstr))) {
+ sids = talloc_realloc(talloc_tos(), sids, struct wbcDomainSid,
+ num_sids+1);
+ if (sids == NULL) {
+ d_fprintf(stderr, "talloc failed\n");
+ return false;
+ }
+ wbc_status = wbcStringToSid(sidstr, &sids[num_sids]);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "wbcSidToString(%s) failed: %s\n",
+ sidstr, wbcErrorString(wbc_status));
+ TALLOC_FREE(sids);
+ return false;
+ }
+ num_sids += 1;
+ }
+
+ unix_ids = talloc_array(talloc_tos(), struct wbcUnixId, num_sids);
+ if (unix_ids == NULL) {
+ TALLOC_FREE(sids);
+ return false;
+ }
+
+ wbc_status = wbcSidsToUnixIds(sids, num_sids, unix_ids);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "wbcSidsToUnixIds failed: %s\n",
+ wbcErrorString(wbc_status));
+ TALLOC_FREE(sids);
+ return false;
+ }
+
+ for (i=0; i<num_sids; i++) {
+
+ wbcSidToStringBuf(&sids[i], sidstr, sizeof(sidstr));
+
+ switch(unix_ids[i].type) {
+ case WBC_ID_TYPE_UID:
+ d_printf("%s -> uid %d\n", sidstr, unix_ids[i].id.uid);
+ break;
+ case WBC_ID_TYPE_GID:
+ d_printf("%s -> gid %d\n", sidstr, unix_ids[i].id.gid);
+ break;
+ default:
+ d_printf("%s -> unmapped\n", sidstr);
+ break;
+ }
+ }
+
+ TALLOC_FREE(sids);
+ TALLOC_FREE(unix_ids);
+
+ return true;
+}
+
static bool wbinfo_allocate_uid(void)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
@@ -923,6 +1040,8 @@ static bool wbinfo_allocate_uid(void)
wbc_status = wbcAllocateUid(&uid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcAllocateUid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -942,6 +1061,8 @@ static bool wbinfo_allocate_gid(void)
wbc_status = wbcAllocateGid(&gid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcAllocateGid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -961,11 +1082,15 @@ static bool wbinfo_set_uid_mapping(uid_t uid, const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcSetUidMapping(uid, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcSetUidMapping: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -986,11 +1111,15 @@ static bool wbinfo_set_gid_mapping(gid_t gid, const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcSetGidMapping(gid, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcSetGidMapping: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -1011,11 +1140,15 @@ static bool wbinfo_remove_uid_mapping(uid_t uid, const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcRemoveUidMapping(uid, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcRemoveUidMapping: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -1036,11 +1169,15 @@ static bool wbinfo_remove_gid_mapping(gid_t gid, const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcRemoveGidMapping(gid, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcRemoveGidMapping: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -1066,11 +1203,15 @@ static bool wbinfo_lookupsid(const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcLookupSid(&sid, &domain, &name, &type);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcLookupSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -1096,11 +1237,15 @@ static bool wbinfo_lookupsid_fullname(const char *sid_str)
wbc_status = wbcStringToSid(sid_str, &sid);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
wbc_status = wbcGetDisplayName(&sid, &domain, &name, &type);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcGetDisplayName: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -1184,20 +1329,64 @@ static bool wbinfo_lookuprids(const char *domain, const char *arg)
ret = true;
done:
- if (dinfo) {
- wbcFreeMemory(dinfo);
- }
- if (domain_name) {
- wbcFreeMemory(domain_name);
+ wbcFreeMemory(dinfo);
+ wbcFreeMemory(domain_name);
+ wbcFreeMemory(names);
+ wbcFreeMemory(types);
+ TALLOC_FREE(mem_ctx);
+ return ret;
+}
+
+static bool wbinfo_lookup_sids(const char *arg)
+{
+ char sidstr[WBC_SID_STRING_BUFLEN];
+ struct wbcDomainSid *sids;
+ struct wbcDomainInfo *domains;
+ struct wbcTranslatedName *names;
+ int num_domains;
+ int i, num_sids;
+ const char *p;
+ wbcErr wbc_status;
+
+
+ num_sids = 0;
+ sids = NULL;
+ p = arg;
+
+ while (next_token(&p, sidstr, LIST_SEP, sizeof(sidstr))) {
+ sids = talloc_realloc(talloc_tos(), sids, struct wbcDomainSid,
+ num_sids+1);
+ if (sids == NULL) {
+ d_fprintf(stderr, "talloc failed\n");
+ return false;
+ }
+ wbc_status = wbcStringToSid(sidstr, &sids[num_sids]);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "wbcSidToString(%s) failed: %s\n",
+ sidstr, wbcErrorString(wbc_status));
+ TALLOC_FREE(sids);
+ return false;
+ }
+ num_sids += 1;
}
- if (names) {
- wbcFreeMemory(names);
+
+ wbc_status = wbcLookupSids(sids, num_sids, &domains, &num_domains,
+ &names);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "wbcLookupSids failed: %s\n",
+ wbcErrorString(wbc_status));
+ TALLOC_FREE(sids);
+ return false;
}
- if (types) {
- wbcFreeMemory(types);
+
+ for (i=0; i<num_sids; i++) {
+ wbcSidToStringBuf(&sids[i], sidstr, sizeof(sidstr));
+
+ d_printf("%s -> %s\\%s %d\n", sidstr,
+ domains[names[i].domain_index].short_name,
+ names[i].name, names[i].type);
}
- TALLOC_FREE(mem_ctx);
- return ret;
+ return true;
}
/* Convert string to sid */
@@ -1206,7 +1395,7 @@ static bool wbinfo_lookupname(const char *full_name)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainSid sid;
- char *sid_str;
+ char sid_str[WBC_SID_STRING_BUFLEN];
enum wbcSidType type;
fstring domain_name;
fstring account_name;
@@ -1219,20 +1408,17 @@ static bool wbinfo_lookupname(const char *full_name)
wbc_status = wbcLookupName(domain_name, account_name,
&sid, &type);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcLookupName: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
- wbc_status = wbcSidToString(&sid, &sid_str);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- return false;
- }
+ wbcSidToStringBuf(&sid, sid_str, sizeof(sid_str));
/* Display response */
d_printf("%s %s (%d)\n", sid_str, wbcSidTypeString(type), type);
- wbcFreeMemory(sid_str);
-
return true;
}
@@ -1311,6 +1497,8 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags)
(uint8_t *)&flags,
sizeof(flags));
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n",
+ wbcErrorString(wbc_status));
goto done;
}
@@ -1321,6 +1509,8 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags)
(uint8_t *)&uid,
sizeof(uid));
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n",
+ wbcErrorString(wbc_status));
goto done;
}
@@ -1331,6 +1521,8 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags)
(uint8_t *)local_cctype,
strlen(cctype)+1);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n",
+ wbcErrorString(wbc_status));
goto done;
}
@@ -1343,7 +1535,7 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags)
if (error) {
d_fprintf(stderr,
- "error code was %s (0x%x)\nerror messsage was: %s\n",
+ "error code was %s (0x%x)\nerror message was: %s\n",
error->nt_string,
error->nt_status,
error->display_string);
@@ -1414,7 +1606,7 @@ static bool wbinfo_auth(char *username)
#if 0
if (response.data.auth.nt_status)
d_fprintf(stderr,
- "error code was %s (0x%x)\nerror messsage was: %s\n",
+ "error code was %s (0x%x)\nerror message was: %s\n",
response.data.auth.nt_status_string,
response.data.auth.nt_status,
response.data.auth.error_string);
@@ -1515,7 +1707,7 @@ static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman)
if (wbc_status == WBC_ERR_AUTH_ERROR) {
d_fprintf(stderr,
- "error code was %s (0x%x)\nerror messsage was: %s\n",
+ "error code was %s (0x%x)\nerror message was: %s\n",
err->nt_string,
err->nt_status,
err->display_string);
@@ -1530,6 +1722,75 @@ static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman)
return WBC_ERROR_IS_OK(wbc_status);
}
+/* Authenticate a user with a plaintext password */
+
+static bool wbinfo_pam_logon(char *username)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcLogonUserParams params;
+ struct wbcAuthErrorInfo *error;
+ char *s = NULL;
+ char *p = NULL;
+ TALLOC_CTX *frame = talloc_tos();
+ uint32_t flags;
+ uint32_t uid;
+
+ ZERO_STRUCT(params);
+
+ if ((s = talloc_strdup(frame, username)) == NULL) {
+ return false;
+ }
+
+ if ((p = strchr(s, '%')) != NULL) {
+ *p = 0;
+ p++;
+ params.password = talloc_strdup(frame, p);
+ } else {
+ params.password = wbinfo_prompt_pass(frame, NULL, username);
+ }
+ params.username = s;
+
+ flags = WBFLAG_PAM_CACHED_LOGIN;
+
+ wbc_status = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
+ "flags", 0,
+ (uint8_t *)&flags, sizeof(flags));
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_printf("wbcAddNamedBlob failed: %s\n",
+ wbcErrorString(wbc_status));
+ return false;
+ }
+
+ uid = getuid();
+
+ wbc_status = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
+ "user_uid", 0,
+ (uint8_t *)&uid, sizeof(uid));
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_printf("wbcAddNamedBlob failed: %s\n",
+ wbcErrorString(wbc_status));
+ return false;
+ }
+
+ wbc_status = wbcLogonUser(&params, NULL, &error, NULL);
+
+ wbcFreeMemory(params.blobs);
+
+ d_printf("plaintext password authentication %s\n",
+ WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
+
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr,
+ "error code was %s (0x%x)\nerror message was: %s\n",
+ error->nt_string,
+ (int)error->nt_status,
+ error->display_string);
+ wbcFreeMemory(error);
+ return false;
+ }
+ return true;
+}
+
/* Save creds with winbind */
static bool wbinfo_ccache_save(char *username)
@@ -1606,7 +1867,7 @@ static bool wbinfo_klog(char *username)
if (response.data.auth.nt_status)
d_fprintf(stderr,
- "error code was %s (0x%x)\nerror messsage was: %s\n",
+ "error code was %s (0x%x)\nerror message was: %s\n",
response.data.auth.nt_status_string,
response.data.auth.nt_status,
response.data.auth.error_string);
@@ -1683,6 +1944,8 @@ static bool print_domain_groups(const char *domain)
wbc_status = wbcListGroups(domain, &num_groups, &groups);
if (!WBC_ERROR_IS_OK(wbc_status)) {
+ d_fprintf(stderr, "failed to call wbcListGroups: %s\n",
+ wbcErrorString(wbc_status));
return false;
}
@@ -1753,15 +2016,18 @@ enum {
OPT_SEQUENCE,
OPT_GETDCNAME,
OPT_DSGETDCNAME,
+ OPT_DC_INFO,
OPT_USERDOMGROUPS,
OPT_SIDALIASES,
OPT_USERSIDS,
+ OPT_LOOKUP_SIDS,
OPT_ALLOCATE_UID,
OPT_ALLOCATE_GID,
OPT_SET_UID_MAPPING,
OPT_SET_GID_MAPPING,
OPT_REMOVE_UID_MAPPING,
OPT_REMOVE_GID_MAPPING,
+ OPT_SIDS_TO_XIDS,
OPT_SEPARATOR,
OPT_LIST_ALL_DOMAINS,
OPT_LIST_OWN_DOMAIN,
@@ -1772,10 +2038,13 @@ enum {
OPT_VERBOSE,
OPT_ONLINESTATUS,
OPT_CHANGE_USER_PASSWORD,
- OPT_PING_DC,
OPT_CCACHE_SAVE,
OPT_SID_TO_FULLNAME,
OPT_NTLMV2,
+ OPT_PAM_LOGON,
+ OPT_LOGOFF,
+ OPT_LOGOFF_USER,
+ OPT_LOGOFF_UID,
OPT_LANMAN
};
@@ -1793,6 +2062,8 @@ int main(int argc, char **argv, char **envp)
bool verbose = false;
bool use_ntlmv2 = false;
bool use_lanman = false;
+ char *logoff_user = getenv("USER");
+ int logoff_uid = geteuid();
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -1809,6 +2080,9 @@ int main(int argc, char **argv, char **envp)
{ "sid-to-fullname", 0, POPT_ARG_STRING, &string_arg,
OPT_SID_TO_FULLNAME, "Converts sid to fullname", "SID" },
{ "lookup-rids", 'R', POPT_ARG_STRING, &string_arg, 'R', "Converts RIDs to names", "RIDs" },
+ { "lookup-sids", 0, POPT_ARG_STRING, &string_arg,
+ OPT_LOOKUP_SIDS, "Converts SIDs to types and names",
+ "Sid-List"},
{ "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" },
{ "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" },
{ "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" },
@@ -1821,14 +2095,16 @@ int main(int argc, char **argv, char **envp)
{ "set-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_GID_MAPPING, "Create or modify gid to sid mapping in idmap", "GID,SID" },
{ "remove-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_UID_MAPPING, "Remove uid to sid mapping in idmap", "UID,SID" },
{ "remove-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_GID_MAPPING, "Remove gid to sid mapping in idmap", "GID,SID" },
+ { "sids-to-unix-ids", 0, POPT_ARG_STRING, &string_arg,
+ OPT_SIDS_TO_XIDS, "Translate SIDs to Unix IDs", "Sid-List" },
{ "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
{ "change-secret", 'c', POPT_ARG_NONE, 0, 'c', "Change shared secret" },
- { "ping-dc", 0, POPT_ARG_NONE, 0, OPT_PING_DC,
+ { "ping-dc", 'P', POPT_ARG_NONE, 0, 'P',
"Check the NETLOGON connection" },
{ "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
{ "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" },
{ "own-domain", 0, POPT_ARG_NONE, 0, OPT_LIST_OWN_DOMAIN, "List own domain" },
- { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" },
+ { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Deprecated command, see --online-status" },
{ "online-status", 0, POPT_ARG_NONE, 0, OPT_ONLINESTATUS, "Show whether domains are marked as online or offline"},
{ "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" },
{ "user-info", 'i', POPT_ARG_STRING, &string_arg, 'i', "Get user info", "USER" },
@@ -1842,6 +2118,14 @@ int main(int argc, char **argv, char **envp)
{ "sid-aliases", 0, POPT_ARG_STRING, &string_arg, OPT_SIDALIASES, "Get sid aliases", "SID" },
{ "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
{ "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
+ { "pam-logon", 0, POPT_ARG_STRING, &string_arg, OPT_PAM_LOGON,
+ "do a pam logon equivalent", "user%password" },
+ { "logoff", 0, POPT_ARG_NONE, NULL, OPT_LOGOFF,
+ "log off user", "uid" },
+ { "logoff-user", 0, POPT_ARG_STRING, &logoff_user,
+ OPT_LOGOFF_USER, "username to log off" },
+ { "logoff-uid", 0, POPT_ARG_INT, &logoff_uid,
+ OPT_LOGOFF_UID, "uid to log off" },
{ "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
{ "ccache-save", 0, POPT_ARG_STRING, &string_arg,
OPT_CCACHE_SAVE, "Store user and password for ccache "
@@ -1849,6 +2133,8 @@ int main(int argc, char **argv, char **envp)
{ "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME,
"Get a DC name for a foreign domain", "domainname" },
{ "dsgetdcname", 0, POPT_ARG_STRING, &string_arg, OPT_DSGETDCNAME, "Find a DC for a domain", "domainname" },
+ { "dc-info", 0, POPT_ARG_STRING, &string_arg, OPT_DC_INFO,
+ "Find the currently known DCs", "domainname" },
{ "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
{ "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
{ "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" },
@@ -1943,6 +2229,13 @@ int main(int argc, char **argv, char **envp)
goto done;
}
break;
+ case OPT_LOOKUP_SIDS:
+ if (!wbinfo_lookup_sids(string_arg)) {
+ d_fprintf(stderr, "Could not lookup SIDs %s\n",
+ string_arg);
+ goto done;
+ }
+ break;
case 'n':
if (!wbinfo_lookupname(string_arg)) {
d_fprintf(stderr, "Could not lookup name %s\n",
@@ -2052,6 +2345,13 @@ int main(int argc, char **argv, char **envp)
goto done;
}
break;
+ case OPT_SIDS_TO_XIDS:
+ if (!wbinfo_sids_to_unix_ids(string_arg)) {
+ d_fprintf(stderr, "wbinfo_sids_to_unix_ids "
+ "failed\n");
+ goto done;
+ }
+ break;
case 't':
if (!wbinfo_check_secret(opt_domain_name)) {
d_fprintf(stderr, "Could not check secret\n");
@@ -2064,7 +2364,7 @@ int main(int argc, char **argv, char **envp)
goto done;
}
break;
- case OPT_PING_DC:
+ case 'P':
if (!wbinfo_ping_dc()) {
d_fprintf(stderr, "Could not ping our DC\n");
goto done;
@@ -2191,6 +2491,23 @@ int main(int argc, char **argv, char **envp)
goto done;
break;
}
+ case OPT_PAM_LOGON:
+ if (!wbinfo_pam_logon(string_arg)) {
+ d_fprintf(stderr, "pam_logon failed for %s\n",
+ string_arg);
+ goto done;
+ }
+ break;
+ case OPT_LOGOFF:
+ {
+ wbcErr wbc_status;
+
+ wbc_status = wbcLogoffUser(logoff_user, logoff_uid,
+ "");
+ d_printf("Logoff %s (%d): %s\n", logoff_user,
+ logoff_uid, wbcErrorString(wbc_status));
+ break;
+ }
case 'K': {
uint32_t flags = WBFLAG_PAM_KRB5 |
WBFLAG_PAM_CACHED_LOGIN |
@@ -2245,6 +2562,11 @@ int main(int argc, char **argv, char **envp)
goto done;
}
break;
+ case OPT_DC_INFO:
+ if (!wbinfo_dc_info(string_arg)) {
+ goto done;
+ }
+ break;
case OPT_SEPARATOR: {
const char sep = winbind_separator();
if ( !sep ) {
@@ -2274,12 +2596,11 @@ int main(int argc, char **argv, char **envp)
/* generic configuration options */
case OPT_DOMAIN_NAME:
- break;
case OPT_VERBOSE:
- break;
case OPT_NTLMV2:
- break;
case OPT_LANMAN:
+ case OPT_LOGOFF_USER:
+ case OPT_LOGOFF_UID:
break;
default:
d_fprintf(stderr, "Invalid option\n");
diff --git a/nsswitch/winbind_client.h b/nsswitch/winbind_client.h
index b004d9c2c0..905a189c82 100644
--- a/nsswitch/winbind_client.h
+++ b/nsswitch/winbind_client.h
@@ -1,7 +1,33 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ winbind client common code
+
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Andrew Tridgell 2000
+ Copyright (C) Andrew Bartlett 2002
+
+
+ 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 _NSSWITCH_WINBIND_CLIENT_H_
+#define _NSSWITCH_WINBIND_CLIENT_H_
+
#include "winbind_nss_config.h"
#include "winbind_struct_protocol.h"
-void winbindd_init_request(struct winbindd_request *req,int rq_type);
void winbindd_free_response(struct winbindd_response *response);
NSS_STATUS winbindd_send_request(int req_type, int need_priv,
struct winbindd_request *request);
@@ -12,8 +38,6 @@ NSS_STATUS winbindd_request_response(int req_type,
NSS_STATUS winbindd_priv_request_response(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
-int winbindd_read_reply(struct winbindd_response *response);
-
#define winbind_env_set() \
(strcmp(getenv(WINBINDD_DONT_ENV)?getenv(WINBINDD_DONT_ENV):"0","1") == 0)
@@ -23,8 +47,4 @@ int winbindd_read_reply(struct winbindd_response *response);
#define winbind_on() \
(setenv(WINBINDD_DONT_ENV, "0", 1) == 0)
-int winbind_write_sock(void *buffer, int count, int recursing, int need_priv);
-int winbind_read_sock(void *buffer, int count);
-void winbind_close_sock(void);
-
-const char *nss_err_str(NSS_STATUS ret);
+#endif /* _NSSWITCH_WINBIND_CLIENT_H_ */
diff --git a/nsswitch/winbind_nss_hpux.h b/nsswitch/winbind_nss_hpux.h
index 40a352d4d3..dba70a7657 100644
--- a/nsswitch/winbind_nss_hpux.h
+++ b/nsswitch/winbind_nss_hpux.h
@@ -130,7 +130,12 @@ typedef struct nss_XbyY_args {
void *returnval;
int erange;
- int h_errno;
+ /*
+ * h_errno is defined as function call macro for multithreaded applications
+ * in HP-UX. *this* h_errno is not used in the HP-UX codepath of our nss
+ * modules, so let's simply rename it:
+ */
+ int h_errno_unused;
nss_status_t status;
} nss_XbyY_args_t;
diff --git a/nsswitch/winbind_nss_linux.c b/nsswitch/winbind_nss_linux.c
index 4a7943278e..7b16752043 100644
--- a/nsswitch/winbind_nss_linux.c
+++ b/nsswitch/winbind_nss_linux.c
@@ -71,6 +71,31 @@ NSS_STATUS _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
NSS_STATUS _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
size_t buflen, int *errnop);
+/*************************************************************************
+ ************************************************************************/
+
+#ifdef DEBUG_NSS
+static const char *nss_err_str(NSS_STATUS ret)
+{
+ switch (ret) {
+ case NSS_STATUS_TRYAGAIN:
+ return "NSS_STATUS_TRYAGAIN";
+ case NSS_STATUS_SUCCESS:
+ return "NSS_STATUS_SUCCESS";
+ case NSS_STATUS_NOTFOUND:
+ return "NSS_STATUS_NOTFOUND";
+ case NSS_STATUS_UNAVAIL:
+ return "NSS_STATUS_UNAVAIL";
+#ifdef NSS_STATUS_RETURN
+ case NSS_STATUS_RETURN:
+ return "NSS_STATUS_RETURN";
+#endif
+ default:
+ return "UNKNOWN RETURN CODE!!!!!!!";
+ }
+}
+#endif
+
/* Prototypes from wb_common.c */
/* Allocate some space from the nss static buffer. The buffer and buflen
diff --git a/nsswitch/winbind_nss_solaris.h b/nsswitch/winbind_nss_solaris.h
index f805542f75..011330576d 100644
--- a/nsswitch/winbind_nss_solaris.h
+++ b/nsswitch/winbind_nss_solaris.h
@@ -22,33 +22,7 @@
#ifndef _WINBIND_NSS_SOLARIS_H
#define _WINBIND_NSS_SOLARIS_H
-/* Solaris has a broken nss_common header file containing C++ reserved names. */
-#ifndef __cplusplus
-#undef class
-#undef private
-#undef public
-#undef protected
-#undef template
-#undef this
-#undef new
-#undef delete
-#undef friend
-#endif
-
#include <nss_common.h>
-
-#ifndef __cplusplus
-#define class #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define private #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define public #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define protected #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define template #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define this #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define new #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define delete #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define friend #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#endif
-
#include <nss_dbdefs.h>
#include <nsswitch.h>
diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index 2e0751f79a..e5ed8e1b3a 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -50,12 +50,18 @@ typedef char fstring[FSTRING_LEN];
* 22: added WINBINDD_PING_DC
* 23: added session_key to ccache_ntlm_auth response
* added WINBINDD_CCACHE_SAVE
+ * 24: Fill in num_entries WINBINDD_LIST_USERS and WINBINDD_LIST_GROUPS
+ * 25: removed WINBINDD_SET_HWM
+ * removed WINBINDD_SET_MAPPING
+ * removed WINBINDD_REMOVE_MAPPING
+ * 26: added WINBINDD_DC_INFO
+ * 27: added WINBINDD_LOOKUPSIDS
*/
-#define WINBIND_INTERFACE_VERSION 23
+#define WINBIND_INTERFACE_VERSION 27
/* Have to deal with time_t being 4 or 8 bytes due to structure alignment.
On a 64bit Linux box, we have to support a constant structure size
- between /lib/libnss_winbind.so.2 and /li64/libnss_winbind.so.2.
+ between /lib/libnss_winbind.so.2 and /lib64/libnss_winbind.so.2.
The easiest way to do this is to always use 8byte values for time_t. */
#define SMB_TIME_T int64_t
@@ -103,6 +109,7 @@ enum winbindd_cmd {
WINBINDD_LOOKUPSID,
WINBINDD_LOOKUPNAME,
WINBINDD_LOOKUPRIDS,
+ WINBINDD_LOOKUPSIDS,
/* Lookup functions */
@@ -114,9 +121,6 @@ enum winbindd_cmd {
WINBINDD_ALLOCATE_UID,
WINBINDD_ALLOCATE_GID,
- WINBINDD_SET_MAPPING,
- WINBINDD_REMOVE_MAPPING,
- WINBINDD_SET_HWM,
/* Miscellaneous other stuff */
@@ -131,6 +135,7 @@ enum winbindd_cmd {
struct winbindd_domain */
WINBINDD_GETDCNAME, /* Issue a GetDCName Request */
WINBINDD_DSGETDCNAME, /* Issue a DsGetDCName Request */
+ WINBINDD_DC_INFO, /* Which DC are we connected to? */
WINBINDD_SHOW_SEQUENCE, /* display sequence numbers of domains */
@@ -166,9 +171,6 @@ enum winbindd_cmd {
WINBINDD_DUAL_SIDS2XIDS,
WINBINDD_DUAL_UID2SID,
WINBINDD_DUAL_GID2SID,
- WINBINDD_DUAL_SET_MAPPING,
- WINBINDD_DUAL_REMOVE_MAPPING,
- WINBINDD_DUAL_SET_HWM,
/* Wrapper around possibly blocking unix nss calls */
WINBINDD_DUAL_USERINFO,
diff --git a/nsswitch/wins.c b/nsswitch/wins.c
index aa95ec7340..f5fd7a775e 100644
--- a/nsswitch/wins.c
+++ b/nsswitch/wins.c
@@ -19,6 +19,8 @@
*/
#include "includes.h"
+#include "nsswitch/winbind_nss.h"
+
#ifdef HAVE_NS_API_H
#include <ns_daemon.h>
@@ -38,76 +40,28 @@ static pthread_mutex_t wins_nss_mutex = PTHREAD_MUTEX_INITIALIZER;
static int initialised;
-extern bool AllowDebugChange;
-
NSS_STATUS _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
char *buffer, size_t buflen, int *h_errnop);
NSS_STATUS _nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he,
char *buffer, size_t buflen, int *h_errnop);
-/* Use our own create socket code so we don't recurse.... */
-
-static int wins_lookup_open_socket_in(void)
-{
- struct sockaddr_in sock;
- int val=1;
- int res;
-
- memset((char *)&sock,'\0',sizeof(sock));
-
-#ifdef HAVE_SOCK_SIN_LEN
- sock.sin_len = sizeof(sock);
-#endif
- sock.sin_port = 0;
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = interpret_addr("0.0.0.0");
- res = socket(AF_INET, SOCK_DGRAM, 0);
- if (res == -1)
- return -1;
-
- if (setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) != 0) {
- close(res);
- return -1;
- }
-#ifdef SO_REUSEPORT
- if (setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) != 0) {
- close(res);
- return -1;
- }
-#endif /* SO_REUSEPORT */
-
- /* now we've got a socket - we need to bind it */
-
- if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) {
- close(res);
- return(-1);
- }
-
- set_socket_options(res,"SO_BROADCAST");
-
- return res;
-}
-
-
static void nss_wins_init(void)
{
initialised = 1;
- DEBUGLEVEL = 0;
- AllowDebugChange = False;
+ load_case_tables_library();
+ lp_set_cmdline("log level", "0");
TimeInit();
setup_logging("nss_wins",False);
- load_case_tables();
lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
load_interfaces();
}
static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
- int fd = -1;
struct ip_service *address = NULL;
struct in_addr *ret = NULL;
- int j, flags = 0;
+ int j;
if (!initialised) {
nss_wins_init();
@@ -126,64 +80,61 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
free(ret);
return NULL;
}
- *ret = ((struct sockaddr_in *)&address[0].ss)->sin_addr;
+ *ret = ((struct sockaddr_in *)(void *)&address[0].ss)
+ ->sin_addr;
free( address );
return ret;
}
- fd = wins_lookup_open_socket_in();
- if (fd == -1) {
- return NULL;
- }
-
/* uggh, we have to broadcast to each interface in turn */
for (j=iface_count() - 1;j >= 0;j--) {
const struct in_addr *bcast = iface_n_bcast_v4(j);
struct sockaddr_storage ss;
struct sockaddr_storage *pss;
+ NTSTATUS status;
+
if (!bcast) {
continue;
}
in_addr_to_sockaddr_storage(&ss, *bcast);
- pss = name_query(fd,name,0x00,True,True,&ss,count, &flags, NULL);
- if (pss) {
+ status = name_query(name, 0x00, True, True, &ss,
+ NULL, &pss, count, NULL);
+ if (NT_STATUS_IS_OK(status) && (*count > 0)) {
if ((ret = SMB_MALLOC_P(struct in_addr)) == NULL) {
return NULL;
}
*ret = ((struct sockaddr_in *)pss)->sin_addr;
+ TALLOC_FREE(pss);
break;
}
}
- close(fd);
return ret;
}
#ifdef HAVE_NS_API_H
-static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
+static struct node_status *lookup_byaddr_backend(char *addr, int *count)
{
- int fd;
struct sockaddr_storage ss;
struct nmb_name nname;
- NODE_STATUS_STRUCT *status;
+ struct node_status *result;
+ NTSTATUS status;
if (!initialised) {
nss_wins_init();
}
- fd = wins_lookup_open_socket_in();
- if (fd == -1)
- return NULL;
-
make_nmb_name(&nname, "*", 0);
if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
return NULL;
}
- status = node_status_query(fd, &nname, &ss, count, NULL);
+ status = node_status_query(NULL, &nname, &ss, &result, count, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ return NULL;
+ }
- close(fd);
- return status;
+ return result;
}
/* IRIX version */
@@ -201,7 +152,7 @@ int lookup(nsd_file_t *rq)
char *key;
char *addr;
struct in_addr *ip_list;
- NODE_STATUS_STRUCT *status;
+ struct node_status *status;
int i, count, len, size;
char response[1024];
bool found = False;
@@ -233,7 +184,7 @@ int lookup(nsd_file_t *rq)
if ( status = lookup_byaddr_backend(key, &count)) {
size = strlen(key) + 1;
if (size > len) {
- free(status);
+ talloc_free(status);
return NSD_ERROR;
}
len -= size;
@@ -245,7 +196,7 @@ int lookup(nsd_file_t *rq)
if (status[i].type == 0x20) {
size = sizeof(status[i].name) + 1;
if (size > len) {
- free(status);
+ talloc_free(status);
return NSD_ERROR;
}
len -= size;
@@ -255,7 +206,7 @@ int lookup(nsd_file_t *rq)
}
}
response[strlen(response)-1] = '\n';
- free(status);
+ talloc_free(status);
}
} else if (StrCaseCmp(map,"hosts.byname") == 0) {
if (ip_list = lookup_byname_backend(key, &count)) {
diff --git a/nsswitch/wscript_build b/nsswitch/wscript_build
new file mode 100644
index 0000000000..83b10a7969
--- /dev/null
+++ b/nsswitch/wscript_build
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+bld.SAMBA_LIBRARY('winbind-client',
+ source='wb_common.c',
+ deps='replace',
+ cflags='-DSOCKET_WRAPPER_DISABLE=1 -DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR,
+ private_library=True
+ )
+
+
+bld.SAMBA_BINARY('nsstest',
+ source='nsstest.c',
+ deps='replace dl'
+ )
+
+
+bld.SAMBA_LIBRARY('nss_winbind',
+ source='winbind_nss_linux.c',
+ deps='winbind-client',
+ realname='libnss_winbind.so.2',
+ vnum='2')
+
+
+if bld.CONFIG_SET('WITH_PAM_MODULES') or bld.CONFIG_SET('HAVE_PAM_START'):
+ bld.SAMBA_LIBRARY('pamwinbind',
+ source='pam_winbind.c',
+ deps='intl talloc wbclient winbind-client LIBINIPARSER pam',
+ cflags='-DLOCALEDIR=\"%s/locale\"' % bld.env.DATADIR,
+ realname='pam_winbind.so',
+ )
+
+if bld.CONFIG_SET('HAVE_KRB5_LOCATE_PLUGIN_H'):
+ bld.SAMBA_LIBRARY('winbind_krb5_locator',
+ source='winbind_krb5_locator.c',
+ deps='wbclient krb5',
+ realname='winbind_krb5_locator.so')
+
+bld.SAMBA_SUBSYSTEM('WB_REQTRANS',
+ source='wb_reqtrans.c',
+ deps='talloc tevent LIBASYNC_REQ'
+ )
diff --git a/nsswitch/wscript_configure b/nsswitch/wscript_configure
new file mode 100644
index 0000000000..7d6ea82879
--- /dev/null
+++ b/nsswitch/wscript_configure
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+
+conf.CHECK_HEADERS('nss.h nss_common.h ns_api.h')
+
+conf.CHECK_HEADERS('security/pam_appl.h security/pam_modules.h pam/pam_modules.h', together=True)
+conf.CHECK_FUNCS_IN('pam_start', 'pam', checklibc=True, headers='security/pam_appl.h')