Jeremy.
char *OIDs[ASN1_MAX_OIDS],
char **principal,
DATA_BLOB *secblob);
-DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob);
-DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2]);
-bool spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]);
+DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8 tok_id[2]);
+bool spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]);
int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx,
const char *principal, int time_offset,
DATA_BLOB *targ,
DATA_BLOB *session_key_krb5, uint32 extra_ap_opts,
time_t *expire_time);
-bool spnego_parse_challenge(const DATA_BLOB blob,
+bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob,
DATA_BLOB *chal1, DATA_BLOB *chal2);
-DATA_BLOB spnego_gen_auth(DATA_BLOB blob);
-bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth);
-DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status,
+DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob);
+bool spnego_parse_auth(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *auth);
+DATA_BLOB spnego_gen_auth_response(TALLOC_CTX *ctx, DATA_BLOB *reply, NTSTATUS nt_status,
const char *mechOID);
-bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
+bool spnego_parse_auth_response(TALLOC_CTX *ctx,
+ DATA_BLOB blob, NTSTATUS nt_status,
const char *mechOID,
DATA_BLOB *auth);
OIDs_ntlm, &blob_out, NULL);
} else {
/* wrap it in SPNEGO */
- msg1 = spnego_gen_auth(blob_out);
+ msg1 = spnego_gen_auth(talloc_tos(), blob_out);
}
data_blob_free(&blob_out);
(rc == LDAP_SASL_BIND_IN_PROGRESS)) {
DATA_BLOB tmp_blob = data_blob_null;
/* the server might give us back two challenges */
- if (!spnego_parse_challenge(blob, &blob_in,
+ if (!spnego_parse_challenge(talloc_tos(), blob, &blob_in,
&tmp_blob)) {
TALLOC_FREE(ntlmssp_state);
}
data_blob_free(&tmp_blob);
} else if (rc == LDAP_SASL_BIND_IN_PROGRESS) {
- if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
+ if (!spnego_parse_auth_response(talloc_tos(), blob, nt_status, OID_NTLMSSP,
&blob_in)) {
TALLOC_FREE(ntlmssp_state);
wrapped = data_blob_null;
}
- ok = spnego_parse_auth_response(wrapped, NT_STATUS_OK,
+ ok = spnego_parse_auth_response(talloc_tos(), wrapped, NT_STATUS_OK,
OID_KERBEROS5_OLD,
&unwrapped);
if (scred) ber_bvfree(scred);
&& NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
DATA_BLOB tmp_blob = data_blob_null;
/* the server might give us back two challenges */
- parse_ret = spnego_parse_challenge(blob_in, &msg_in,
+ parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
&tmp_blob);
data_blob_free(&tmp_blob);
} else {
- parse_ret = spnego_parse_auth_response(blob_in, status,
+ parse_ret = spnego_parse_auth_response(state, blob_in, status,
OID_NTLMSSP, &msg_in);
}
state->turn += 1;
return;
}
- state->blob_out = spnego_gen_auth(blob_out);
+ state->blob_out = spnego_gen_auth(state, blob_out);
TALLOC_FREE(subreq);
if (tevent_req_nomem(state->blob_out.data, req)) {
return;
p_tok_in = GSS_C_NO_BUFFER;
} else {
/* Remove the SPNEGO wrapper */
- if (!spnego_parse_auth_response(spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) {
+ if (!spnego_parse_auth_response(ctx, spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) {
status = NT_STATUS_UNSUCCESSFUL;
goto fail;
}
/*
generate a krb5 GSS-API wrapper packet given a ticket
*/
-DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2])
+DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8 tok_id[2])
{
ASN1_DATA *data;
DATA_BLOB ret;
DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs));
}
- ret = data_blob(data->data, data->length);
+ ret = data_blob_talloc(ctx, data->data, data->length);
asn1_free(data);
return ret;
/*
parse a krb5 GSS-API wrapper packet giving a ticket
*/
-bool spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
+bool spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
{
bool ret;
ASN1_DATA *data;
} else {
asn1_read(data, tok_id, 2);
data_remaining -= 2;
- *ticket = data_blob(NULL, data_remaining);
+ *ticket = data_blob_talloc(ctx, NULL, data_remaining);
asn1_read(data, ticket->data, ticket->length);
}
return retval;
/* wrap that up in a nice GSS-API wrapping */
- tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
+ tkt_wrapped = spnego_gen_krb5_wrap(ctx, tkt, TOK_ID_KRB_AP_REQ);
/* and wrap that in a shiny SPNEGO wrapper */
*targ = spnego_gen_negTokenInit(ctx, krb_mechs, &tkt_wrapped, NULL);
/*
parse a spnego NTLMSSP challenge packet giving two security blobs
*/
-bool spnego_parse_challenge(const DATA_BLOB blob,
+bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob,
DATA_BLOB *chal1, DATA_BLOB *chal2)
{
bool ret;
asn1_end_tag(data);
asn1_start_tag(data,ASN1_CONTEXT(2));
- asn1_read_OctetString(data, talloc_autofree_context(), chal1);
+ asn1_read_OctetString(data, ctx, chal1);
asn1_end_tag(data);
/* the second challenge is optional (XP doesn't send it) */
if (asn1_tag_remaining(data)) {
asn1_start_tag(data,ASN1_CONTEXT(3));
- asn1_read_OctetString(data, talloc_autofree_context(), chal2);
+ asn1_read_OctetString(data, ctx, chal2);
asn1_end_tag(data);
}
/*
generate a SPNEGO auth packet. This will contain the encrypted passwords
*/
-DATA_BLOB spnego_gen_auth(DATA_BLOB blob)
+DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob)
{
ASN1_DATA *data;
DATA_BLOB ret;
asn1_pop_tag(data);
asn1_pop_tag(data);
- ret = data_blob(data->data, data->length);
+ ret = data_blob_talloc(ctx, data->data, data->length);
asn1_free(data);
/*
parse a SPNEGO auth packet. This contains the encrypted passwords
*/
-bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
+bool spnego_parse_auth(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *auth)
{
ssize_t len;
struct spnego_data token;
return false;
}
- *auth = data_blob_talloc(talloc_tos(),
+ *auth = data_blob_talloc(ctx,
token.negTokenTarg.responseToken.data,
token.negTokenTarg.responseToken.length);
spnego_free_data(&token);
/*
generate a minimal SPNEGO response packet. Doesn't contain much.
*/
-DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status,
+DATA_BLOB spnego_gen_auth_response(TALLOC_CTX *ctx,
+ DATA_BLOB *reply, NTSTATUS nt_status,
const char *mechOID)
{
ASN1_DATA *data;
asn1_pop_tag(data);
asn1_pop_tag(data);
- ret = data_blob(data->data, data->length);
+ ret = data_blob_talloc(ctx, data->data, data->length);
asn1_free(data);
return ret;
}
/*
parse a SPNEGO auth packet. This contains the encrypted passwords
*/
-bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
+bool spnego_parse_auth_response(TALLOC_CTX *ctx,
+ DATA_BLOB blob, NTSTATUS nt_status,
const char *mechOID,
DATA_BLOB *auth)
{
if (asn1_tag_remaining(data)) {
asn1_start_tag(data,ASN1_CONTEXT(2));
- asn1_read_OctetString(data, talloc_autofree_context(), auth);
+ asn1_read_OctetString(data, ctx, auth);
asn1_end_tag(data);
}
} else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) {
if (asn1_tag_remaining(data)) {
DATA_BLOB mechList = data_blob_null;
asn1_start_tag(data, ASN1_CONTEXT(3));
- asn1_read_OctetString(data, talloc_autofree_context(), &mechList);
+ asn1_read_OctetString(data, ctx, &mechList);
asn1_end_tag(data);
data_blob_free(&mechList);
DEBUG(5,("spnego_parse_auth_response received mechListMIC, "
}
/* wrap that up in a nice GSS-API wrapping */
- tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
+ tkt_wrapped = spnego_gen_krb5_wrap(talloc_tos(), tkt, TOK_ID_KRB_AP_REQ);
data_blob_free(&tkt);
* The server might give us back two challenges - tmp_blob is for the
* second.
*/
- if (!spnego_parse_challenge(auth_info.credentials,
+ if (!spnego_parse_challenge(state, auth_info.credentials,
&server_ntlm_response, &tmp_blob)) {
data_blob_free(&server_ntlm_response);
data_blob_free(&tmp_blob);
}
/* SPNEGO wrap the client reply. */
- tmp_blob = spnego_gen_auth(client_reply);
+ tmp_blob = spnego_gen_auth(state, client_reply);
data_blob_free(&client_reply);
client_reply = tmp_blob;
tmp_blob = data_blob_null;
}
/* Check we got a valid auth response. */
- if (!spnego_parse_auth_response(auth.credentials,
+ if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
NT_STATUS_OK,
OID_NTLMSSP, &tmp_blob)) {
data_blob_free(&tmp_blob);
}
/* Generate the response blob we need for step 2 of the bind. */
- *response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
+ *response = spnego_gen_auth_response(mem_ctx, &chal, status, OID_NTLMSSP);
} else {
/*
* SPNEGO negotiate down to NTLMSSP. The subsequent
* code to process follow-up packets is not complete
* yet. JRA.
*/
- *response = spnego_gen_auth_response(NULL,
+ *response = spnego_gen_auth_response(mem_ctx, NULL,
NT_STATUS_MORE_PROCESSING_REQUIRED,
OID_NTLMSSP);
}
- /* Make sure data is bound to the memctx, to be freed the caller */
- talloc_steal(mem_ctx, response->data);
-
/* auth_pad_len will be handled by the caller */
p->auth.a_u.auth_ntlmssp_state = a;
goto err;
}
- if (!spnego_parse_auth(pauth_info->credentials, &auth_blob)) {
+ if (!spnego_parse_auth(talloc_tos(), pauth_info->credentials, &auth_blob)) {
DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));
goto err;
}
data_blob_free(&auth_blob);
/* Generate the spnego "accept completed" blob - no incoming data. */
- *response = spnego_gen_auth_response(&auth_reply, NT_STATUS_OK, OID_NTLMSSP);
-
- /* Make sure data is bound to the memctx, to be freed the caller */
- talloc_steal(mem_ctx, response->data);
+ *response = spnego_gen_auth_response(mem_ctx, &auth_reply, NT_STATUS_OK, OID_NTLMSSP);
data_blob_free(&auth_reply);
gss_release_buffer(&min, &out_buf);
/* Wrap in SPNEGO. */
- response = spnego_gen_auth_response(&auth_reply, status, OID_KERBEROS5);
+ response = spnego_gen_auth_response(talloc_tos(), &auth_reply, status, OID_KERBEROS5);
data_blob_free(&auth_reply);
SAFE_FREE(*ppdata);
* for success ... */
if (spnego_wrap) {
- response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
+ response = spnego_gen_auth_response(talloc_tos(), &chal, status, OID_NTLMSSP);
data_blob_free(&chal);
} else {
/* Return the raw blob. */
}
blob = data_blob_const(*ppdata, *p_data_size);
- if (!spnego_parse_auth(blob, &auth)) {
+ if (!spnego_parse_auth(talloc_tos(), blob, &auth)) {
srv_free_encryption_context(&partial_srv_trans_enc_ctx);
return NT_STATUS_INVALID_PARAMETER;
}
* So set mechOID to NULL here.
*/
- response = spnego_gen_auth_response(&auth_reply, status, NULL);
+ response = spnego_gen_auth_response(talloc_tos(), &auth_reply, status, NULL);
data_blob_free(&auth_reply);
if (NT_STATUS_IS_OK(status)) {
return;
}
- if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
+ if (!spnego_parse_krb5_wrap(mem_ctx, *secblob, &ticket, tok_id)) {
talloc_destroy(mem_ctx);
reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
return;
/* wrap that up in a nice GSS-API wrapping */
if (NT_STATUS_IS_OK(ret)) {
- ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
+ ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
TOK_ID_KRB_AP_REP);
} else {
ap_rep_wrapped = data_blob_null;
}
- response = spnego_gen_auth_response(&ap_rep_wrapped, ret,
+ response = spnego_gen_auth_response(talloc_tos(), &ap_rep_wrapped, ret,
mechOID);
reply_sesssetup_blob(req, response, ret);
out:
if (wrap) {
- response = spnego_gen_auth_response(ntlmssp_blob,
+ response = spnego_gen_auth_response(talloc_tos(),
+ ntlmssp_blob,
nt_status, OID);
} else {
response = *ntlmssp_blob;
DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
"but set to downgrade to NTLMSSP\n"));
- response = spnego_gen_auth_response(NULL,
+ response = spnego_gen_auth_response(talloc_tos(), NULL,
NT_STATUS_MORE_PROCESSING_REQUIRED,
OID_NTLMSSP);
reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
NTSTATUS status = NT_STATUS_LOGON_FAILURE;
struct smbd_server_connection *sconn = req->sconn;
- if (!spnego_parse_auth(blob1, &auth)) {
+ if (!spnego_parse_auth(talloc_tos(), blob1, &auth)) {
#if 0
file_save("auth.dat", blob1.data, blob1.length);
#endif
bool username_was_mapped = false;
bool map_domainuser_to_guest = false;
- if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
+ if (!spnego_parse_krb5_wrap(talloc_tos(), *secblob, &ticket, tok_id)) {
status = NT_STATUS_LOGON_FAILURE;
goto fail;
}
status = NT_STATUS_OK;
/* wrap that up in a nice GSS-API wrapping */
- ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep,
+ ap_rep_wrapped = spnego_gen_krb5_wrap(talloc_tos(), ap_rep,
TOK_ID_KRB_AP_REP);
secblob_out = spnego_gen_auth_response(
+ talloc_tos(),
&ap_rep_wrapped,
status,
mechOID);
ap_rep_wrapped = data_blob_null;
secblob_out = spnego_gen_auth_response(
+ talloc_tos(),
&ap_rep_wrapped,
status,
mechOID);
{
DATA_BLOB secblob_in = data_blob_null;
DATA_BLOB chal_out = data_blob_null;
- DATA_BLOB secblob_out = data_blob_null;
char *kerb_mech = NULL;
NTSTATUS status;
goto out;
}
- secblob_out = spnego_gen_auth_response(&chal_out,
+ *out_security_buffer = spnego_gen_auth_response(smb2req,
+ &chal_out,
status,
OID_NTLMSSP);
- *out_security_buffer = data_blob_talloc(smb2req,
- secblob_out.data,
- secblob_out.length);
- if (secblob_out.data && out_security_buffer->data == NULL) {
+ if (out_security_buffer->data == NULL) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
out:
data_blob_free(&secblob_in);
- data_blob_free(&secblob_out);
data_blob_free(&chal_out);
TALLOC_FREE(kerb_mech);
if (!NT_STATUS_IS_OK(status) &&
{
DATA_BLOB auth = data_blob_null;
DATA_BLOB auth_out = data_blob_null;
- DATA_BLOB secblob_out = data_blob_null;
NTSTATUS status;
- if (!spnego_parse_auth(in_security_buffer, &auth)) {
+ if (!spnego_parse_auth(talloc_tos(), in_security_buffer, &auth)) {
TALLOC_FREE(session);
return NT_STATUS_LOGON_FAILURE;
}
data_blob_free(&auth);
- secblob_out = spnego_gen_auth_response(&auth_out,
- status, NULL);
+ *out_security_buffer = spnego_gen_auth_response(smb2req,
+ &auth_out, status, NULL);
- *out_security_buffer = data_blob_talloc(smb2req,
- secblob_out.data,
- secblob_out.length);
- if (secblob_out.data && out_security_buffer->data == NULL) {
+ if (out_security_buffer->data == NULL) {
TALLOC_FREE(session->auth_ntlmssp_state);
TALLOC_FREE(session);
return NT_STATUS_NO_MEMORY;