#include "includes.h"
#include "lib/param/param.h"
-#include "popt_common.h"
+#include "lib/cmdline/cmdline.h"
#include "libcli/security/security.h"
#include "utils/ntlm_auth.h"
#include "../libcli/auth/libcli_auth.h"
#include "librpc/crypto/gse.h"
#include "smb_krb5.h"
#include "lib/util/tiniparser.h"
-#include "nsswitch/winbind_client.h"
#include "librpc/gen_ndr/krb5pac.h"
-#include "../lib/util/asn1.h"
#include "auth/common_auth.h"
#include "source3/include/auth.h"
#include "source3/auth/proto.h"
#include "nsswitch/libwbclient/wbclient.h"
+#include "nsswitch/winbind_struct_protocol.h"
+#include "nsswitch/libwbclient/wbclient_internal.h"
#include "lib/param/loadparm.h"
#include "lib/util/base64.h"
#include "cmdline_contexts.h"
+#include "lib/util/tevent_ntstatus.h"
+#include "lib/util/string_wrappers.h"
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
{
DATA_BLOB in;
if (strlen(buf) < 2) {
- DEBUG(1, ("query [%s] invalid", buf));
+ DEBUG(1, ("query [%s] invalid\n", buf));
printf("BH Query invalid\n");
return;
}
}
-DATA_BLOB get_challenge(void)
+DATA_BLOB get_challenge(void)
{
static DATA_BLOB chal;
if (opt_challenge.length)
* need to contact trusted domain
*/
-int get_pam_winbind_config()
+int get_pam_winbind_config(void)
{
int ctrl = 0;
struct tiniparser_dictionary *d = NULL;
{
struct winbindd_request request;
struct winbindd_response response;
- NSS_STATUS result;
+ wbcErr ret;
if (!get_require_membership_sid()) {
return False;
request.flags |= WBFLAG_PAM_CACHED_LOGIN;
}
- result = winbindd_request_response(NULL, WINBINDD_PAM_AUTH, &request, &response);
+ ret = wbcRequestResponse(NULL, WINBINDD_PAM_AUTH,
+ &request, &response);
/* Display response */
if (stdout_diagnostics) {
- if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
+ if (!WBC_ERROR_IS_OK(ret) && (response.data.auth.nt_status == 0)) {
d_fprintf(stderr, "Reading winbind reply failed! (0x01)\n");
}
response.data.auth.error_string,
response.data.auth.nt_status);
} else {
- if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
+ if (!WBC_ERROR_IS_OK(ret) && (response.data.auth.nt_status == 0)) {
DEBUG(1, ("Reading winbind reply failed! (0x01)\n"));
}
response.data.auth.nt_status));
}
- return (result == NSS_STATUS_SUCCESS);
+ return WBC_ERROR_IS_OK(ret);
}
/* authenticate a user with an encrypted username/password */
char **unix_name)
{
NTSTATUS nt_status;
- NSS_STATUS result;
+ wbcErr ret;
struct winbindd_request request;
struct winbindd_response response;
memcpy(request.data.auth_crap.chal, challenge->data, MIN(challenge->length, 8));
if (lm_response && lm_response->length) {
+ size_t capped_lm_response_len = MIN(
+ lm_response->length,
+ sizeof(request.data.auth_crap.lm_resp));
+
memcpy(request.data.auth_crap.lm_resp,
lm_response->data,
- MIN(lm_response->length, sizeof(request.data.auth_crap.lm_resp)));
- request.data.auth_crap.lm_resp_len = lm_response->length;
+ capped_lm_response_len);
+ request.data.auth_crap.lm_resp_len = capped_lm_response_len;
}
if (nt_response && nt_response->length) {
request.data.auth_crap.nt_resp_len = nt_response->length;
}
- result = winbindd_priv_request_response(
+ ret = wbcRequestResponsePriv(
NULL,
WINBINDD_PAM_AUTH_CRAP,
&request,
/* Display response */
- if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
+ if (!WBC_ERROR_IS_OK(ret) && (response.data.auth.nt_status == 0)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
if (error_string)
*error_string = smb_xstrdup("Reading winbind reply failed!");
char **error_string)
{
NTSTATUS nt_status;
- NSS_STATUS result;
+ wbcErr ret;
struct winbindd_request request;
struct winbindd_response response;
request.data.chng_pswd_auth_crap.old_lm_hash_enc_len = old_lm_hash_enc.length;
}
- result = winbindd_request_response(NULL, WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, &request, &response);
+ ret = wbcRequestResponse(NULL, WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,
+ &request, &response);
/* Display response */
- if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0))
+ if (!WBC_ERROR_IS_OK(ret) && (response.data.auth.nt_status == 0))
{
nt_status = NT_STATUS_UNSUCCESSFUL;
if (error_string)
nt_status = (NT_STATUS(response.data.auth.nt_status));
if (!NT_STATUS_IS_OK(nt_status))
{
- if (error_string)
+ if (error_string)
*error_string = smb_xstrdup(response.data.auth.error_string);
winbindd_free_response(&response);
return nt_status;
return nt_status;
}
+/*
+ * This function does not create a full auth_session_info, just enough
+ * for the caller to get the "unix" username
+ */
static NTSTATUS ntlm_auth_generate_session_info(struct auth4_context *auth_context,
TALLOC_CTX *mem_ctx,
void *server_returned_info,
return NT_STATUS_NO_MEMORY;
}
- session_info->security_token = talloc_zero(session_info, struct security_token);
+ /*
+ * This is not a full session_info - it is not created
+ * correctly and misses any claims etc, because all we
+ * actually use in the caller is the unix username.
+ *
+ * Therefore so no claims need to be added and
+ * se_access_check() will never run.
+ */
+ session_info->security_token
+ = security_token_initialise(talloc_tos(),
+ CLAIMS_EVALUATION_INVALID_STATE);
if (session_info->security_token == NULL) {
TALLOC_FREE(session_info);
return NT_STATUS_NO_MEMORY;
struct PAC_LOGON_INFO *logon_info = NULL;
char *unixuser;
NTSTATUS status;
- char *domain = NULL;
- char *realm = NULL;
- char *user = NULL;
- char *p;
+ const char *domain = "";
+ const char *user = "";
tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
+ } else {
+ status = NT_STATUS_ACCESS_DENIED;
+ DBG_WARNING("Kerberos ticket for[%s] has no PAC: %s\n",
+ princ_name, nt_errstr(status));
+ goto done;
}
- DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
-
- p = strchr_m(princ_name, '@');
- if (!p) {
- DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
- princ_name));
- return NT_STATUS_LOGON_FAILURE;
- }
-
- user = talloc_strndup(mem_ctx, princ_name, p - princ_name);
- if (!user) {
- return NT_STATUS_NO_MEMORY;
+ if (logon_info->info3.base.account_name.string != NULL) {
+ user = logon_info->info3.base.account_name.string;
+ } else {
+ user = "";
}
-
- realm = talloc_strdup(talloc_tos(), p + 1);
- if (!realm) {
- return NT_STATUS_NO_MEMORY;
+ if (logon_info->info3.base.logon_domain.string != NULL) {
+ domain = logon_info->info3.base.logon_domain.string;
+ } else {
+ domain = "";
}
- if (!strequal(realm, lp_realm())) {
- DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm));
- if (!lp_allow_trusted_domains()) {
- return NT_STATUS_LOGON_FAILURE;
- }
+ if (strlen(user) == 0 || strlen(domain) == 0) {
+ status = NT_STATUS_ACCESS_DENIED;
+ DBG_WARNING("Kerberos ticket for[%s] has invalid "
+ "account_name[%s]/logon_domain[%s]: %s\n",
+ princ_name,
+ logon_info->info3.base.account_name.string,
+ logon_info->info3.base.logon_domain.string,
+ nt_errstr(status));
+ goto done;
}
- if (logon_info && logon_info->info3.base.logon_domain.string) {
- domain = talloc_strdup(mem_ctx,
- logon_info->info3.base.logon_domain.string);
- if (!domain) {
- return NT_STATUS_NO_MEMORY;
- }
- DEBUG(10, ("Domain is [%s] (using PAC)\n", domain));
- } else {
-
- /* If we have winbind running, we can (and must) shorten the
- username by using the short netbios name. Otherwise we will
- have inconsistent user names. With Kerberos, we get the
- fully qualified realm, with ntlmssp we get the short
- name. And even w2k3 does use ntlmssp if you for example
- connect to an ip address. */
+ DBG_NOTICE("Kerberos ticket principal name is [%s] "
+ "account_name[%s]/logon_domain[%s]\n",
+ princ_name, user, domain);
- wbcErr wbc_status;
- struct wbcDomainInfo *info = NULL;
-
- DEBUG(10, ("Mapping [%s] to short name using winbindd\n",
- realm));
-
- wbc_status = wbcDomainInfo(realm, &info);
-
- if (WBC_ERROR_IS_OK(wbc_status)) {
- domain = talloc_strdup(mem_ctx,
- info->short_name);
- wbcFreeMemory(info);
- } else {
- DEBUG(3, ("Could not find short name: %s\n",
- wbcErrorString(wbc_status)));
- domain = talloc_strdup(mem_ctx, realm);
- }
- if (!domain) {
- return NT_STATUS_NO_MEMORY;
+ if (!strequal(domain, lp_workgroup())) {
+ if (!lp_allow_trusted_domains()) {
+ status = NT_STATUS_LOGON_FAILURE;
+ goto done;
}
- DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain));
}
unixuser = talloc_asprintf(tmp_ctx, "%s%c%s", domain, winbind_separator(), user);
/**
- * Return the challenge as determined by the authentication subsystem
+ * Return the challenge as determined by the authentication subsystem
* @return an 8 byte random challenge
*/
uint8_t chal[8])
{
if (auth_ctx->challenge.data.length == 8) {
- DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n",
+ DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n",
auth_ctx->challenge.set_by));
memcpy(chal, auth_ctx->challenge.data.data, 8);
return NT_STATUS_OK;
* Return the session keys used on the connection.
*/
-static NTSTATUS winbind_pw_check(struct auth4_context *auth4_context,
- TALLOC_CTX *mem_ctx,
- const struct auth_usersupplied_info *user_info,
- uint8_t *pauthoritative,
- void **server_returned_info,
- DATA_BLOB *session_key, DATA_BLOB *lm_session_key)
+struct winbind_pw_check_state {
+ uint8_t authoritative;
+ void *server_info;
+ DATA_BLOB nt_session_key;
+ DATA_BLOB lm_session_key;
+};
+
+static struct tevent_req *winbind_pw_check_send(
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct auth4_context *auth4_context,
+ const struct auth_usersupplied_info *user_info)
{
+ struct tevent_req *req = NULL;
+ struct winbind_pw_check_state *state = NULL;
NTSTATUS nt_status;
char *error_string = NULL;
uint8_t lm_key[8];
uint8_t user_sess_key[16];
char *unix_name = NULL;
- nt_status = contact_winbind_auth_crap(user_info->client.account_name, user_info->client.domain_name,
- user_info->workstation_name,
- &auth4_context->challenge.data,
- &user_info->password.response.lanman,
- &user_info->password.response.nt,
- WBFLAG_PAM_LMKEY | WBFLAG_PAM_USER_SESSION_KEY | WBFLAG_PAM_UNIX_NAME,
- 0,
- lm_key, user_sess_key,
- pauthoritative,
- &error_string, &unix_name);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- if (!all_zero(lm_key, 8)) {
- *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16);
- memcpy(lm_session_key->data, lm_key, 8);
- memset(lm_session_key->data+8, '\0', 8);
+ req = tevent_req_create(
+ mem_ctx, &state, struct winbind_pw_check_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ nt_status = contact_winbind_auth_crap(
+ user_info->client.account_name,
+ user_info->client.domain_name,
+ user_info->workstation_name,
+ &auth4_context->challenge.data,
+ &user_info->password.response.lanman,
+ &user_info->password.response.nt,
+ WBFLAG_PAM_LMKEY |
+ WBFLAG_PAM_USER_SESSION_KEY |
+ WBFLAG_PAM_UNIX_NAME,
+ 0,
+ lm_key, user_sess_key,
+ &state->authoritative,
+ &error_string,
+ &unix_name);
+
+ if (tevent_req_nterror(req, nt_status)) {
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
+ DBG_ERR("Login for user [%s]\\[%s]@[%s] failed due "
+ "to [%s]\n",
+ user_info->client.domain_name,
+ user_info->client.account_name,
+ user_info->workstation_name,
+ error_string ?
+ error_string :
+ "unknown error (NULL)");
+ } else {
+ DBG_NOTICE("Login for user [%s]\\[%s]@[%s] failed due "
+ "to [%s]\n",
+ user_info->client.domain_name,
+ user_info->client.account_name,
+ user_info->workstation_name,
+ error_string ?
+ error_string :
+ "unknown error (NULL)");
}
+ goto done;
+ }
- if (!all_zero(user_sess_key, 16)) {
- *session_key = data_blob_talloc(mem_ctx, user_sess_key, 16);
+ if (!all_zero(lm_key, 8)) {
+ state->lm_session_key = data_blob_talloc(state, NULL, 16);
+ if (tevent_req_nomem(state->lm_session_key.data, req)) {
+ goto done;
}
- *server_returned_info = talloc_strdup(mem_ctx,
- unix_name);
- } else {
- DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3,
- ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n",
- user_info->client.domain_name, user_info->client.account_name,
- user_info->workstation_name,
- error_string ? error_string : "unknown error (NULL)"));
+ memcpy(state->lm_session_key.data, lm_key, 8);
+ memset(state->lm_session_key.data+8, '\0', 8);
+ }
+ if (!all_zero(user_sess_key, 16)) {
+ state->nt_session_key = data_blob_talloc(
+ state, user_sess_key, 16);
+ if (tevent_req_nomem(state->nt_session_key.data, req)) {
+ goto done;
+ }
+ }
+ state->server_info = talloc_strdup(state, unix_name);
+ if (tevent_req_nomem(state->server_info, req)) {
+ goto done;
}
+ tevent_req_done(req);
+done:
SAFE_FREE(error_string);
SAFE_FREE(unix_name);
- return nt_status;
+ return tevent_req_post(req, ev);
}
-static NTSTATUS local_pw_check(struct auth4_context *auth4_context,
- TALLOC_CTX *mem_ctx,
- const struct auth_usersupplied_info *user_info,
- uint8_t *pauthoritative,
- void **server_returned_info,
- DATA_BLOB *session_key, DATA_BLOB *lm_session_key)
+static NTSTATUS winbind_pw_check_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ uint8_t *pauthoritative,
+ void **server_returned_info,
+ DATA_BLOB *nt_session_key,
+ DATA_BLOB *lm_session_key)
{
- NTSTATUS nt_status;
+ struct winbind_pw_check_state *state = tevent_req_data(
+ req, struct winbind_pw_check_state);
+ NTSTATUS status;
+
+ if (pauthoritative != NULL) {
+ *pauthoritative = state->authoritative;
+ }
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+
+ if (server_returned_info != NULL) {
+ *server_returned_info = talloc_move(
+ mem_ctx, &state->server_info);
+ }
+ if (nt_session_key != NULL) {
+ *nt_session_key = (DATA_BLOB) {
+ .data = talloc_move(
+ mem_ctx, &state->nt_session_key.data),
+ .length = state->nt_session_key.length,
+ };
+ }
+ if (lm_session_key != NULL) {
+ *lm_session_key = (DATA_BLOB) {
+ .data = talloc_move(
+ mem_ctx, &state->lm_session_key.data),
+ .length = state->lm_session_key.length,
+ };
+ }
+
+ return NT_STATUS_OK;
+}
+
+struct local_pw_check_state {
+ uint8_t authoritative;
+ void *server_info;
+ DATA_BLOB nt_session_key;
+ DATA_BLOB lm_session_key;
+};
+
+static struct tevent_req *local_pw_check_send(
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct auth4_context *auth4_context,
+ const struct auth_usersupplied_info *user_info)
+{
+ struct tevent_req *req = NULL;
+ struct local_pw_check_state *state = NULL;
struct samr_Password lm_pw, nt_pw;
+ NTSTATUS nt_status;
+
+ req = tevent_req_create(
+ mem_ctx, &state, struct local_pw_check_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->authoritative = 1;
nt_lm_owf_gen (opt_password, nt_pw.hash, lm_pw.hash);
- *pauthoritative = 1;
+ nt_status = ntlm_password_check(
+ state,
+ true,
+ NTLM_AUTH_ON,
+ 0,
+ &auth4_context->challenge.data,
+ &user_info->password.response.lanman,
+ &user_info->password.response.nt,
+ user_info->client.account_name,
+ user_info->client.account_name,
+ user_info->client.domain_name,
+ &lm_pw,
+ &nt_pw,
+ &state->nt_session_key,
+ &state->lm_session_key);
+
+ if (tevent_req_nterror(req, nt_status)) {
+ DBG_NOTICE("Login for user [%s]\\[%s]@[%s] failed due to "
+ "[%s]\n",
+ user_info->client.domain_name,
+ user_info->client.account_name,
+ user_info->workstation_name,
+ nt_errstr(nt_status));
+ return tevent_req_post(req, ev);
+ }
+
+ state->server_info = talloc_asprintf(
+ state,
+ "%s%c%s",
+ user_info->client.domain_name,
+ *lp_winbind_separator(),
+ user_info->client.account_name);
+ if (tevent_req_nomem(state->server_info, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+}
- nt_status = ntlm_password_check(mem_ctx,
- true, NTLM_AUTH_ON, 0,
- &auth4_context->challenge.data,
- &user_info->password.response.lanman,
- &user_info->password.response.nt,
- user_info->client.account_name,
- user_info->client.account_name,
- user_info->client.domain_name,
- &lm_pw, &nt_pw, session_key, lm_session_key);
-
- if (NT_STATUS_IS_OK(nt_status)) {
- *server_returned_info = talloc_asprintf(mem_ctx,
- "%s%c%s", user_info->client.domain_name,
- *lp_winbind_separator(),
- user_info->client.account_name);
- } else {
- DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n",
- user_info->client.domain_name, user_info->client.account_name,
- user_info->workstation_name,
- nt_errstr(nt_status)));
+static NTSTATUS local_pw_check_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ uint8_t *pauthoritative,
+ void **server_returned_info,
+ DATA_BLOB *nt_session_key,
+ DATA_BLOB *lm_session_key)
+{
+ struct local_pw_check_state *state = tevent_req_data(
+ req, struct local_pw_check_state);
+ NTSTATUS status;
+
+ if (pauthoritative != NULL) {
+ *pauthoritative = state->authoritative;
}
- return nt_status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+
+ if (server_returned_info != NULL) {
+ *server_returned_info = talloc_move(
+ mem_ctx, &state->server_info);
+ }
+ if (nt_session_key != NULL) {
+ *nt_session_key = (DATA_BLOB) {
+ .data = talloc_move(
+ mem_ctx, &state->nt_session_key.data),
+ .length = state->nt_session_key.length,
+ };
+ }
+ if (lm_session_key != NULL) {
+ *lm_session_key = (DATA_BLOB) {
+ .data = talloc_move(
+ mem_ctx, &state->lm_session_key.data),
+ .length = state->lm_session_key.length,
+ };
+ }
+
+ return NT_STATUS_OK;
}
static NTSTATUS ntlm_auth_prepare_gensec_client(TALLOC_CTX *mem_ctx,
/* These need to be in priority order, krb5 before NTLMSSP */
#if defined(HAVE_KRB5)
- backends[idx++] = &gensec_gse_krb5_security_ops;
+ backends[idx++] = gensec_gse_security_by_oid(GENSEC_OID_KERBEROS5);
#endif
backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
{
struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
if (auth4_context == NULL) {
- DEBUG(10, ("failed to allocate auth4_context failed\n"));
+ DEBUG(10, ("failed to allocate auth4_context\n"));
return NULL;
}
auth4_context->generate_session_info = ntlm_auth_generate_session_info;
auth4_context->get_ntlm_challenge = ntlm_auth_get_challenge;
auth4_context->set_ntlm_challenge = ntlm_auth_set_challenge;
if (local_pw) {
- auth4_context->check_ntlm_password = local_pw_check;
+ auth4_context->check_ntlm_password_send = local_pw_check_send;
+ auth4_context->check_ntlm_password_recv = local_pw_check_recv;
} else {
- auth4_context->check_ntlm_password = winbind_pw_check;
+ auth4_context->check_ntlm_password_send =
+ winbind_pw_check_send;
+ auth4_context->check_ntlm_password_recv =
+ winbind_pw_check_recv;
}
auth4_context->private_data = NULL;
return auth4_context;
/* These need to be in priority order, krb5 before NTLMSSP */
#if defined(HAVE_KRB5)
- backends[idx++] = &gensec_gse_krb5_security_ops;
+ backends[idx++] = gensec_gse_security_by_oid(GENSEC_OID_KERBEROS5);
#endif
backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
*/
server_credentials = cli_credentials_init_anon(tmp_ctx);
if (!server_credentials) {
- DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
+ DBG_ERR("Failed to init server credentials\n");
return NT_STATUS_NO_MEMORY;
}
cli_credentials_set_conf(server_credentials, lp_ctx);
if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
- cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS);
+ cli_credentials_set_kerberos_state(server_credentials,
+ CRED_USE_KERBEROS_DESIRED,
+ CRED_SPECIFIED);
} else {
- cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS);
+ cli_credentials_set_kerberos_state(server_credentials,
+ CRED_USE_KERBEROS_DISABLED,
+ CRED_SPECIFIED);
}
nt_status = gensec_server_start(tmp_ctx, gensec_settings,
static char *want_feature_list = NULL;
static DATA_BLOB session_key;
-
+ bool include_krb5_default_ccache = false;
TALLOC_CTX *mem_ctx;
mem_ctx = talloc_named(NULL, 0, "manage_gensec_request internal mem_ctx");
+ if (mem_ctx == NULL) {
+ printf("BH No Memory\n");
+ exit(1);
+ }
if (*private1) {
- state = (struct gensec_ntlm_state *)*private1;
+ state = talloc_get_type(*private1, struct gensec_ntlm_state);
+ if (state == NULL) {
+ DBG_WARNING("*private1 is of type %s\n",
+ talloc_get_name(*private1));
+ printf("BH *private1 is of type %s\n",
+ talloc_get_name(*private1));
+ exit(1);
+ }
} else {
state = talloc_zero(NULL, struct gensec_ntlm_state);
if (!state) {
}
if (strlen(buf) < 2) {
- DEBUG(1, ("query [%s] invalid", buf));
+ DEBUG(1, ("query [%s] invalid\n", buf));
printf("BH Query invalid\n");
talloc_free(mem_ctx);
return;
* NTLMSSP_CLIENT_1 for now.
*/
use_cached_creds = false;
+ if (opt_username == NULL && state->set_password == NULL) {
+ include_krb5_default_ccache = true;
+ }
FALL_THROUGH;
case NTLMSSP_CLIENT_1:
/* setup the client side */
GENSEC_FEATURE_NTLM_CCACHE);
} else if (state->set_password) {
cli_credentials_set_password(creds, state->set_password, CRED_SPECIFIED);
+ } else if (include_krb5_default_ccache) {
+ const char *error_string = NULL;
+ int rc;
+
+ rc = cli_credentials_set_ccache(creds,
+ lp_ctx,
+ NULL,
+ CRED_SPECIFIED,
+ &error_string);
+ if (rc != 0) {
+ fprintf(stderr,
+ "Warning reading default "
+ "krb5 credentials cache: %s\n",
+ error_string);
+ }
} else {
cli_credentials_set_password_callback(creds, get_password);
}
TALLOC_FREE(mem_ctx);
} else {
- uint8_t authoritative = 0;
+ uint8_t authoritative = 1;
if (!domain) {
domain = smb_xstrdup(get_winbind_domain());
printf("Authenticated: Yes\n");
- if (ntlm_server_1_lm_session_key
+ if (ntlm_server_1_lm_session_key
&& (!all_zero(lm_key,
sizeof(lm_key)))) {
hex_lm_key = hex_encode_talloc(NULL,
gnutls_cipher_deinit(cipher_hnd);
return;
}
- E_old_pw_hash(new_nt_hash, old_lm_hash,
+ rc = E_old_pw_hash(new_nt_hash, old_lm_hash,
old_lm_hash_enc.data);
+ if (rc != 0) {
+ DBG_ERR("E_old_pw_hash failed: %s\n",
+ gnutls_strerror(rc));
+ return;
+ }
} else {
new_lm_pswd.data = NULL;
new_lm_pswd.length = 0;
if (rc < 0) {
return;
}
- E_old_pw_hash(new_nt_hash, old_nt_hash,
+ rc = E_old_pw_hash(new_nt_hash, old_nt_hash,
old_nt_hash_enc.data);
+ if (rc != 0) {
+ DBG_ERR("E_old_pw_hash failed: %s\n",
+ gnutls_strerror(rc));
+ return;
+ }
ZERO_ARRAY(old_nt_hash);
ZERO_ARRAY(old_lm_hash);
char *hex_lm_key;
char *hex_user_session_key;
char *error_string;
- uint8_t authoritative = 0;
+ uint8_t authoritative = 1;
setbuf(stdout, NULL);
const char *hex_nt_response = NULL;
struct loadparm_context *lp_ctx;
poptContext pc;
+ bool ok;
/* NOTE: DO NOT change this interface without considering the implications!
This is an external interface, which other programs will use to interact
.argInfo = POPT_ARG_NONE,
.arg = &request_lm_key,
.val = OPT_LM_KEY,
- .descrip = "Retrieve LM session key"
+ .descrip = "Retrieve LM session key (or, with --diagnostics, expect LM support)"
},
{
.longName = "request-nt-key",
.val = OPT_TARGET_HOSTNAME,
.descrip = "Target hostname",
},
- POPT_COMMON_CONFIGFILE
+ POPT_COMMON_DEBUG_ONLY
+ POPT_COMMON_CONFIG_ONLY
+ POPT_COMMON_OPTION_ONLY
POPT_COMMON_VERSION
- POPT_COMMON_OPTION
POPT_TABLEEND
};
/* Samba client initialisation */
smb_init_locale();
- setup_logging("ntlm_auth", DEBUG_STDERR);
- fault_setup();
-
- /* Parse options */
-
- pc = poptGetContext("ntlm_auth", argc, argv, long_options, 0);
-
- /* Parse command line options */
-
- if (argc == 1) {
- poptPrintHelp(pc, stderr, 0);
- poptFreeContext(pc);
- return 1;
- }
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- /* Get generic config options like --configfile */
+ ok = samba_cmdline_init(frame,
+ SAMBA_CMDLINE_CONFIG_CLIENT,
+ false /* require_smbconf */);
+ if (!ok) {
+ DBG_ERR("Failed to init cmdline parser!\n");
+ TALLOC_FREE(frame);
+ exit(1);
}
- poptFreeContext(pc);
-
- if (!lp_load_global(get_dyn_CONFIGFILE())) {
- d_fprintf(stderr, "ntlm_auth: error opening config file %s. Error was %s\n",
- get_dyn_CONFIGFILE(), strerror(errno));
+ pc = samba_popt_get_context(getprogname(),
+ argc,
+ argv,
+ long_options,
+ POPT_CONTEXT_KEEP_FIRST);
+ if (pc == NULL) {
+ DBG_ERR("Failed to setup popt context!\n");
+ TALLOC_FREE(frame);
exit(1);
}
- pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
-
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case OPT_CHALLENGE:
opt_challenge = strhex_to_data_blob(NULL, hex_challenge);
if (opt_challenge.length != 8) {
fprintf(stderr, "hex decode of %s failed! "
- "(only got %d bytes)\n",
+ "(got %d bytes, expected 8)\n",
hex_challenge,
(int)opt_challenge.length);
exit(1);
opt_lm_response = strhex_to_data_blob(NULL, hex_lm_response);
if (opt_lm_response.length != 24) {
fprintf(stderr, "hex decode of %s failed! "
- "(only got %d bytes)\n",
+ "(got %d bytes, expected 24)\n",
hex_lm_response,
(int)opt_lm_response.length);
exit(1);
opt_nt_response = strhex_to_data_blob(NULL, hex_nt_response);
if (opt_nt_response.length < 24) {
fprintf(stderr, "hex decode of %s failed! "
- "(only got %d bytes)\n",
+ "(only got %d bytes, needed at least 24)\n",
hex_nt_response,
(int)opt_nt_response.length);
exit(1);
require_membership_of_sid = require_membership_of;
}
break;
+
+ case POPT_ERROR_BADOPT:
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ poptPrintUsage(pc, stderr, 0);
+ exit(1);
}
}
}
if (diagnostics) {
- if (!diagnose_ntlm_auth()) {
+ if (!diagnose_ntlm_auth(request_lm_key)) {
poptFreeContext(pc);
return 1;
}
}
/* Exit code */
-
+ gfree_all();
poptFreeContext(pc);
TALLOC_FREE(frame);
return 0;