From 9b6b01aab6a6a0ebb34798bb78febb2df17b302d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Dec 2009 21:50:43 +0100 Subject: s3:winbind: Add a lower-cost alternative to wbinfo -t: wbinfo --ping-dc This just does a NULL RPC call through an existing NETLOGON connection. If someone knows an operation that "just works" and does not return NOT_SUPPORTED, please tell me :-) --- nsswitch/libwbclient/wbc_pam.c | 45 ++++++++++++++++++++++++++++++++++++++ nsswitch/libwbclient/wbclient.h | 14 ++++++++++++ nsswitch/wbinfo.c | 34 ++++++++++++++++++++++++++++ nsswitch/winbind_struct_protocol.h | 4 +++- 4 files changed, 96 insertions(+), 1 deletion(-) (limited to 'nsswitch') diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c index 7a66a7fe82..00863a0d54 100644 --- a/nsswitch/libwbclient/wbc_pam.c +++ b/nsswitch/libwbclient/wbc_pam.c @@ -5,6 +5,7 @@ Copyright (C) Gerald (Jerry) Carter 2007 Copyright (C) Guenther Deschner 2008 + Copyright (C) Volker Lendecke 2009 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -570,6 +571,50 @@ wbcErr wbcChangeTrustCredentials(const char *domain, return wbc_status; } +/* + * Trigger a no-op NETLOGON call. Lightweight version of + * wbcCheckTrustCredentials + */ +wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error) +{ + struct winbindd_request request; + struct winbindd_response response; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + + if (domain) { + /* + * the current protocol doesn't support + * specifying a domain + */ + wbc_status = WBC_ERR_NOT_IMPLEMENTED; + BAIL_ON_WBC_ERROR(wbc_status); + } + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + /* Send request */ + + wbc_status = wbcRequestResponse(WINBINDD_PING_DC, + &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 an extended logoff notification to Winbind for a specific user */ wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params, struct wbcAuthErrorInfo **error) diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h index eea71ab86b..33a4ace75c 100644 --- a/nsswitch/libwbclient/wbclient.h +++ b/nsswitch/libwbclient/wbclient.h @@ -4,6 +4,7 @@ Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 + Copyright (C) Volker Lendecke 2009 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -1214,6 +1215,19 @@ wbcErr wbcCheckTrustCredentials(const char *domain, wbcErr wbcChangeTrustCredentials(const char *domain, struct wbcAuthErrorInfo **error); +/** + * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost + * version of wbcCheckTrustCredentials + * + * @param *domain The name of the domain, only NULL for the default domain is + * supported yet. Other values than NULL will result in + * WBC_ERR_NOT_IMPLEMENTED. + * @param error Output details on WBC_ERR_AUTH_ERROR + * + * @return #wbcErr + **/ +wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error); + /********************************************************** * Helper functions **********************************************************/ diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c index d3d9250e81..45d8684bad 100644 --- a/nsswitch/wbinfo.c +++ b/nsswitch/wbinfo.c @@ -5,6 +5,7 @@ Copyright (C) Tim Potter 2000-2003 Copyright (C) Andrew Bartlett 2002-2007 + Copyright (C) Volker Lendecke 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 @@ -779,6 +780,30 @@ static bool wbinfo_change_secret(const char *domain) return true; } +/* Check DC connection */ + +static bool wbinfo_ping_dc(void) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcAuthErrorInfo *error = NULL; + + wbc_status = wbcPingDc(NULL, &error); + + d_printf("checking the NETLOGON dc connection %s\n", + 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; +} + /* Convert uid to sid */ static bool wbinfo_uid_to_sid(uid_t uid) @@ -1710,6 +1735,7 @@ enum { OPT_VERBOSE, OPT_ONLINESTATUS, OPT_CHANGE_USER_PASSWORD, + OPT_PING_DC, OPT_SID_TO_FULLNAME, OPT_NTLMV2, OPT_LANMAN @@ -1759,6 +1785,8 @@ int main(int argc, char **argv, char **envp) { "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" }, + { "ping-dc", 0, POPT_ARG_NONE, 0, OPT_PING_DC, + "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" }, @@ -1995,6 +2023,12 @@ int main(int argc, char **argv, char **envp) goto done; } break; + case OPT_PING_DC: + if (!wbinfo_ping_dc()) { + d_fprintf(stderr, "Could not ping our DC\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 3056e25905..4d27d5283c 100644 --- a/nsswitch/winbind_struct_protocol.h +++ b/nsswitch/winbind_struct_protocol.h @@ -47,8 +47,9 @@ typedef char fstring[FSTRING_LEN]; /* Update this when you change the interface. * 21: added WINBINDD_GETPWSID * added WINBINDD_GETSIDALIASES + * 22: added WINBINDD_PING_DC */ -#define WINBIND_INTERFACE_VERSION 21 +#define WINBIND_INTERFACE_VERSION 22 /* 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 @@ -119,6 +120,7 @@ enum winbindd_cmd { WINBINDD_CHECK_MACHACC, /* Check machine account pw works */ WINBINDD_CHANGE_MACHACC, /* Change machine account pw */ + WINBINDD_PING_DC, /* Ping the DC through NETLOGON */ 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()) */ -- cgit