summaryrefslogtreecommitdiff
path: root/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'nsswitch')
-rw-r--r--nsswitch/libwbclient/tests/wbclient.c289
-rw-r--r--nsswitch/libwbclient/wbc_pam.c46
-rw-r--r--nsswitch/libwbclient/wbc_sid.c4
-rw-r--r--nsswitch/libwbclient/wbclient.c4
-rw-r--r--nsswitch/libwbclient/wbclient.h37
-rw-r--r--nsswitch/pam_winbind.c15
-rw-r--r--nsswitch/wbinfo.c57
-rw-r--r--nsswitch/winbind_struct_protocol.h1
8 files changed, 425 insertions, 28 deletions
diff --git a/nsswitch/libwbclient/tests/wbclient.c b/nsswitch/libwbclient/tests/wbclient.c
new file mode 100644
index 0000000000..5a55a43ceb
--- /dev/null
+++ b/nsswitch/libwbclient/tests/wbclient.c
@@ -0,0 +1,289 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB torture tester
+ Copyright (C) Guenther Deschner 2009
+
+ 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
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "nsswitch/libwbclient/wbclient.h"
+#include "torture/smbtorture.h"
+#include "torture/winbind/proto.h"
+
+#define WBC_ERROR_EQUAL(x,y) (x == y)
+
+#define torture_assert_wbc_equal(torture_ctx, got, expected, cmt) \
+ do { wbcErr __got = got, __expected = expected; \
+ if (!WBC_ERROR_EQUAL(__got, __expected)) { \
+ torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", wbcErrorString(__got), wbcErrorString(__expected), cmt); \
+ return false; \
+ } \
+ } while (0)
+
+#define torture_assert_wbc_ok(torture_ctx,expr,cmt) \
+ torture_assert_wbc_equal(torture_ctx,expr,WBC_ERR_SUCCESS,cmt)
+
+static bool test_wbc_ping(struct torture_context *tctx)
+{
+ torture_assert_wbc_ok(tctx, wbcPing(),
+ "wbcPing failed");
+
+ return true;
+}
+
+static bool test_wbc_library_details(struct torture_context *tctx)
+{
+ struct wbcLibraryDetails *details;
+
+ torture_assert_wbc_ok(tctx, wbcLibraryDetails(&details),
+ "wbcLibraryDetails failed");
+ torture_assert(tctx, details,
+ "wbcLibraryDetails returned NULL pointer");
+
+ wbcFreeMemory(details);
+
+ return true;
+}
+
+static bool test_wbc_interface_details(struct torture_context *tctx)
+{
+ struct wbcInterfaceDetails *details;
+
+ torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
+ "wbcInterfaceDetails failed");
+ torture_assert(tctx, details,
+ "wbcInterfaceDetails returned NULL pointer");
+
+ wbcFreeMemory(details);
+
+ return true;
+}
+
+static bool test_wbc_sidtypestring(struct torture_context *tctx)
+{
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_USE_NONE),
+ "SID_NONE", "SID_NONE failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_USER),
+ "SID_USER", "SID_USER failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DOM_GRP),
+ "SID_DOM_GROUP", "SID_DOM_GROUP failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DOMAIN),
+ "SID_DOMAIN", "SID_DOMAIN failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_ALIAS),
+ "SID_ALIAS", "SID_ALIAS failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_WKN_GRP),
+ "SID_WKN_GROUP", "SID_WKN_GROUP failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DELETED),
+ "SID_DELETED", "SID_DELETED failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_INVALID),
+ "SID_INVALID", "SID_INVALID failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_UNKNOWN),
+ "SID_UNKNOWN", "SID_UNKNOWN failed");
+ torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_COMPUTER),
+ "SID_COMPUTER", "SID_COMPUTER failed");
+ return true;
+}
+
+static bool test_wbc_sidtostring(struct torture_context *tctx)
+{
+ struct wbcDomainSid sid;
+ const char *sid_string = "S-1-5-32";
+ char *sid_string2;
+
+ torture_assert_wbc_ok(tctx, wbcStringToSid(sid_string, &sid),
+ "wbcStringToSid failed");
+ torture_assert_wbc_ok(tctx, wbcSidToString(&sid, &sid_string2),
+ "wbcSidToString failed");
+ torture_assert_str_equal(tctx, sid_string, sid_string2,
+ "sid strings differ");
+
+ return true;
+}
+
+static bool test_wbc_guidtostring(struct torture_context *tctx)
+{
+ struct wbcGuid guid;
+ const char *guid_string = "f7cf07b4-1487-45c7-824d-8b18cc580811";
+ char *guid_string2;
+
+ torture_assert_wbc_ok(tctx, wbcStringToGuid(guid_string, &guid),
+ "wbcStringToGuid failed");
+ torture_assert_wbc_ok(tctx, wbcGuidToString(&guid, &guid_string2),
+ "wbcGuidToString failed");
+ torture_assert_str_equal(tctx, guid_string, guid_string2,
+ "guid strings differ");
+
+ 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);
+ wbcFreeMemory(details);
+
+ torture_assert_wbc_ok(tctx, wbcDomainInfo(domain_name, &info),
+ "wbcDomainInfo failed");
+ torture_assert(tctx, info,
+ "wbcDomainInfo returned NULL pointer");
+
+ return true;
+}
+
+static bool test_wbc_users(struct torture_context *tctx)
+{
+ const char *domain_name = NULL;
+ uint32_t num_users;
+ const char **users;
+ int i;
+ struct wbcInterfaceDetails *details;
+
+ torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
+ "wbcInterfaceDetails failed");
+
+ domain_name = talloc_strdup(tctx, details->netbios_domain);
+ wbcFreeMemory(details);
+
+ torture_assert_wbc_ok(tctx, wbcListUsers(domain_name, &num_users, &users),
+ "wbcListUsers failed");
+ torture_assert(tctx, !(num_users > 0 && !users),
+ "wbcListUsers returned invalid results");
+
+ for (i=0; i < MIN(num_users,100); i++) {
+
+ struct wbcDomainSid sid, *sids;
+ enum wbcSidType name_type;
+ char *domain;
+ char *name;
+ uint32_t num_sids;
+
+ torture_assert_wbc_ok(tctx, wbcLookupName(domain_name, users[i], &sid, &name_type),
+ "wbcLookupName failed");
+ torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_USER,
+ "wbcLookupName expected WBC_SID_NAME_USER");
+ torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
+ "wbcLookupSid failed");
+ torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_USER,
+ "wbcLookupSid expected WBC_SID_NAME_USER");
+ torture_assert(tctx, name,
+ "wbcLookupSid returned no name");
+ torture_assert_wbc_ok(tctx, wbcLookupUserSids(&sid, true, &num_sids, &sids),
+ "wbcLookupUserSids failed");
+ }
+
+ return true;
+}
+
+static bool test_wbc_groups(struct torture_context *tctx)
+{
+ const char *domain_name = NULL;
+ uint32_t num_groups;
+ const char **groups;
+ int i;
+ struct wbcInterfaceDetails *details;
+
+ torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
+ "wbcInterfaceDetails failed");
+
+ domain_name = talloc_strdup(tctx, details->netbios_domain);
+ wbcFreeMemory(details);
+
+ torture_assert_wbc_ok(tctx, wbcListGroups(domain_name, &num_groups, &groups),
+ "wbcListGroups failed");
+ torture_assert(tctx, !(num_groups > 0 && !groups),
+ "wbcListGroups returned invalid results");
+
+ for (i=0; i < MIN(num_groups,100); i++) {
+
+ struct wbcDomainSid sid;
+ enum wbcSidType name_type;
+ char *domain;
+ char *name;
+
+ torture_assert_wbc_ok(tctx, wbcLookupName(domain_name, groups[i], &sid, &name_type),
+ "wbcLookupName failed");
+ torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
+ "wbcLookupSid failed");
+ torture_assert(tctx, name,
+ "wbcLookupSid returned no name");
+ }
+
+ return true;
+}
+
+static bool test_wbc_trusts(struct torture_context *tctx)
+{
+ struct wbcDomainInfo *domains;
+ size_t num_domains;
+ int i;
+
+ torture_assert_wbc_ok(tctx, wbcListTrusts(&domains, &num_domains),
+ "wbcListTrusts failed");
+ torture_assert(tctx, !(num_domains > 0 && !domains),
+ "wbcListTrusts returned invalid results");
+
+ for (i=0; i < MIN(num_domains,100); i++) {
+
+ struct wbcAuthErrorInfo *error;
+ /*
+ struct wbcDomainSid sid;
+ enum wbcSidType name_type;
+ char *domain;
+ char *name;
+ */
+ torture_assert_wbc_ok(tctx, wbcCheckTrustCredentials(domains[i].short_name, &error),
+ "wbcCheckTrustCredentials failed");
+ /*
+ torture_assert_wbc_ok(tctx, wbcLookupName(domains[i].short_name, NULL, &sid, &name_type),
+ "wbcLookupName failed");
+ torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_DOMAIN,
+ "wbcLookupName expected WBC_SID_NAME_DOMAIN");
+ torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
+ "wbcLookupSid failed");
+ torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_DOMAIN,
+ "wbcLookupSid expected WBC_SID_NAME_DOMAIN");
+ torture_assert(tctx, name,
+ "wbcLookupSid returned no name");
+ */
+ }
+
+ return true;
+}
+
+
+
+struct torture_suite *torture_wbclient(void)
+{
+ 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, "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);
+ torture_suite_add_simple_test(suite, "wbcSidToString", test_wbc_sidtostring);
+ torture_suite_add_simple_test(suite, "wbcGuidToString", test_wbc_guidtostring);
+ torture_suite_add_simple_test(suite, "wbcDomainInfo", test_wbc_domain_info);
+ torture_suite_add_simple_test(suite, "wbcListUsers", test_wbc_users);
+ torture_suite_add_simple_test(suite, "wbcListGroups", test_wbc_groups);
+ torture_suite_add_simple_test(suite, "wbcListTrusts", test_wbc_trusts);
+
+ return suite;
+}
diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c
index 33044b2df7..7a66a7fe82 100644
--- a/nsswitch/libwbclient/wbc_pam.c
+++ b/nsswitch/libwbclient/wbc_pam.c
@@ -502,21 +502,55 @@ wbcErr wbcCheckTrustCredentials(const char *domain,
struct winbindd_response response;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
if (domain) {
- /*
- * the current protocol doesn't support
- * specifying a domain
- */
- wbc_status = WBC_ERR_NOT_IMPLEMENTED;
+ strncpy(request.domain_name, domain,
+ sizeof(request.domain_name)-1);
+ }
+
+ /* Send request */
+
+ wbc_status = wbcRequestResponse(WINBINDD_CHECK_MACHACC,
+ &request,
+ &response);
+ if (response.data.auth.nt_status != 0) {
+ if (error) {
+ wbc_status = wbc_create_error_info(NULL,
+ &response,
+ error);
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ wbc_status = WBC_ERR_AUTH_ERROR;
BAIL_ON_WBC_ERROR(wbc_status);
}
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ done:
+ return wbc_status;
+}
+
+/* Trigger a change of the trust credentials for a specific domain */
+wbcErr wbcChangeTrustCredentials(const char *domain,
+ struct wbcAuthErrorInfo **error)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
ZERO_STRUCT(request);
ZERO_STRUCT(response);
+ if (domain) {
+ strncpy(request.domain_name, domain,
+ sizeof(request.domain_name)-1);
+ }
+
/* Send request */
- wbc_status = wbcRequestResponse(WINBINDD_CHECK_MACHACC,
+ wbc_status = wbcRequestResponse(WINBINDD_CHANGE_MACHACC,
&request,
&response);
if (response.data.auth.nt_status != 0) {
diff --git a/nsswitch/libwbclient/wbc_sid.c b/nsswitch/libwbclient/wbc_sid.c
index b1ecba3f6d..99c9d8e152 100644
--- a/nsswitch/libwbclient/wbc_sid.c
+++ b/nsswitch/libwbclient/wbc_sid.c
@@ -248,9 +248,13 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
if (WBC_ERROR_IS_OK(wbc_status)) {
if (pdomain != NULL) {
*pdomain = domain;
+ } else {
+ TALLOC_FREE(domain);
}
if (pname != NULL) {
*pname = name;
+ } else {
+ TALLOC_FREE(name);
}
if (pname_type != NULL) {
*pname_type = name_type;
diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c
index f4620ff002..9a1e770690 100644
--- a/nsswitch/libwbclient/wbclient.c
+++ b/nsswitch/libwbclient/wbclient.c
@@ -23,8 +23,8 @@
/* Required Headers */
#include "replace.h"
-#include "lib/talloc/talloc.h"
-#include "lib/tevent/tevent.h"
+#include "talloc.h"
+#include "tevent.h"
#include "libwbclient.h"
/* From wb_common.c */
diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index a87cad3b21..eea71ab86b 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -63,9 +63,10 @@ const char *wbcErrorString(wbcErr error);
* 0.3: Added wbcGetpwsid()
* Added wbcGetSidAliases()
* 0.4: Added wbcSidTypeString()
+ * 0.5: Added wbcChangeTrustCredentials()
**/
#define WBCLIENT_MAJOR_VERSION 0
-#define WBCLIENT_MINOR_VERSION 4
+#define WBCLIENT_MINOR_VERSION 5
#define WBCLIENT_VENDOR_VERSION "Samba libwbclient"
struct wbcLibraryDetails {
uint16_t major_version;
@@ -427,12 +428,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
**/
@@ -1183,9 +1195,7 @@ wbcErr wbcResolveWinsByIP(const char *ip, char **name);
/**
* @brief Trigger a verification of the trust credentials of a specific domain
*
- * @param *domain The name of the domain, only NULL for the default domain is
- * supported yet. Other values than NULL will result in
- * WBC_ERR_NOT_IMPLEMENTED.
+ * @param *domain The name of the domain.
* @param error Output details on WBC_ERR_AUTH_ERROR
*
* @return #wbcErr
@@ -1193,6 +1203,17 @@ wbcErr wbcResolveWinsByIP(const char *ip, char **name);
wbcErr wbcCheckTrustCredentials(const char *domain,
struct wbcAuthErrorInfo **error);
+/**
+ * @brief Trigger a change of the trust credentials for a specific domain
+ *
+ * @param *domain The name of the domain.
+ * @param error Output details on WBC_ERR_AUTH_ERROR
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcChangeTrustCredentials(const char *domain,
+ struct wbcAuthErrorInfo **error);
+
/**********************************************************
* Helper functions
**********************************************************/
diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c
index 324bede9ea..fdb5be3223 100644
--- a/nsswitch/pam_winbind.c
+++ b/nsswitch/pam_winbind.c
@@ -980,7 +980,8 @@ static bool winbind_name_to_sid_string(struct pwb_context *ctx,
char *sid_list_buffer,
int sid_list_buffer_size)
{
- const char* sid_string;
+ const char* sid_string = NULL;
+ char *sid_str = NULL;
/* lookup name? */
if (IS_SID_STRING(name)) {
@@ -989,7 +990,6 @@ static bool winbind_name_to_sid_string(struct pwb_context *ctx,
wbcErr wbc_status;
struct wbcDomainSid sid;
enum wbcSidType type;
- char *sid_str;
_pam_log_debug(ctx, LOG_DEBUG,
"no sid given, looking up: %s\n", name);
@@ -1006,15 +1006,16 @@ static bool winbind_name_to_sid_string(struct pwb_context *ctx,
return false;
}
- wbcFreeMemory(sid_str);
sid_string = sid_str;
}
if (!safe_append_string(sid_list_buffer, sid_string,
sid_list_buffer_size)) {
+ wbcFreeMemory(sid_str);
return false;
}
+ wbcFreeMemory(sid_str);
return true;
}
@@ -1862,22 +1863,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"));
diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index a80b69f2b6..219ec24fba 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -724,15 +724,55 @@ static bool wbinfo_dsgetdcname(const char *domain_name, uint32_t flags)
/* Check trust account password */
-static bool wbinfo_check_secret(void)
+static bool wbinfo_check_secret(const char *domain)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcAuthErrorInfo *error = NULL;
+ const char *domain_name;
- wbc_status = wbcCheckTrustCredentials(NULL, &error);
+ if (domain) {
+ domain_name = domain;
+ } else {
+ domain_name = get_winbind_domain();
+ }
- d_printf("checking the trust secret via RPC calls %s\n",
- WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
+ wbc_status = wbcCheckTrustCredentials(domain_name, &error);
+
+ d_printf("checking the trust secret for domain %s via RPC calls %s\n",
+ domain_name,
+ WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
+
+ if (wbc_status == WBC_ERR_AUTH_ERROR) {
+ d_fprintf(stderr, "error code was %s (0x%x)\n",
+ error->nt_string, error->nt_status);
+ wbcFreeMemory(error);
+ }
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ return true;
+}
+
+/* Change trust account password */
+
+static bool wbinfo_change_secret(const char *domain)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcAuthErrorInfo *error = NULL;
+ const char *domain_name;
+
+ if (domain) {
+ domain_name = domain;
+ } else {
+ domain_name = get_winbind_domain();
+ }
+
+ wbc_status = wbcChangeTrustCredentials(domain_name, &error);
+
+ d_printf("changing the trust secret for domain %s via RPC calls %s\n",
+ domain_name,
+ WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
if (wbc_status == WBC_ERR_AUTH_ERROR) {
d_fprintf(stderr, "error code was %s (0x%x)\n",
@@ -1725,6 +1765,7 @@ int main(int argc, char **argv, char **envp)
{ "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" },
{ "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
+ { "change-secret", 'c', POPT_ARG_NONE, 0, 'c', "Change shared secret" },
{ "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" },
@@ -1950,11 +1991,17 @@ int main(int argc, char **argv, char **envp)
}
break;
case 't':
- if (!wbinfo_check_secret()) {
+ if (!wbinfo_check_secret(opt_domain_name)) {
d_fprintf(stderr, "Could not check secret\n");
goto done;
}
break;
+ case 'c':
+ if (!wbinfo_change_secret(opt_domain_name)) {
+ d_fprintf(stderr, "Could not change secret\n");
+ goto done;
+ }
+ break;
case 'm':
if (!wbinfo_list_domains(false, verbose)) {
d_fprintf(stderr,
diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index bd144101f2..3056e25905 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -118,6 +118,7 @@ enum winbindd_cmd {
/* Miscellaneous other stuff */
WINBINDD_CHECK_MACHACC, /* Check machine account pw works */
+ WINBINDD_CHANGE_MACHACC, /* Change machine account pw */
WINBINDD_PING, /* Just tell me winbind is running */
WINBINDD_INFO, /* Various bit of info. Currently just tidbits */
WINBINDD_DOMAIN_NAME, /* The domain this winbind server is a member of (lp_workgroup()) */