diff options
Diffstat (limited to 'nsswitch/libwbclient')
-rw-r--r-- | nsswitch/libwbclient/tests/wbclient.c | 289 | ||||
-rw-r--r-- | nsswitch/libwbclient/wbc_pam.c | 46 | ||||
-rw-r--r-- | nsswitch/libwbclient/wbc_sid.c | 4 | ||||
-rw-r--r-- | nsswitch/libwbclient/wbclient.c | 4 | ||||
-rw-r--r-- | nsswitch/libwbclient/wbclient.h | 37 |
5 files changed, 364 insertions, 16 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 **********************************************************/ |