*/
#include "includes.h"
+#include "smbd/globals.h"
-extern struct auth_context *negprot_global_auth_context;
-extern bool global_encrypted_passwords_negotiated;
-extern bool global_spnego_negotiated;
extern enum protocol_types Protocol;
-extern int max_send;
-
-uint32 global_client_caps = 0;
/*
on a logon error possibly map the error to success if "map to guest"
if (tmp == -1) return -1;
result += tmp;
- if (asprintf(&lanman, "Samba %s", SAMBA_VERSION_STRING) != -1) {
+ if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
SAFE_FREE(lanman);
}
if (!NT_STATUS_IS_OK(nt_status) &&
!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
reply_nterror(req, nt_status_squash(nt_status));
- } else {
- nt_status = nt_status_squash(nt_status);
- SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
- SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
- SSVAL(req->outbuf, smb_vwv3, blob.length);
-
- if ((message_push_blob(&req->outbuf, blob) == -1)
- || (push_signature(&req->outbuf) == -1)) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- }
+ return;
}
- show_msg((char *)req->outbuf);
- srv_send_smb(smbd_server_fd(),(char *)req->outbuf,req->encrypted);
- TALLOC_FREE(req->outbuf);
+ nt_status = nt_status_squash(nt_status);
+ SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status));
+ SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
+ SSVAL(req->outbuf, smb_vwv3, blob.length);
+
+ if ((message_push_blob(&req->outbuf, blob) == -1)
+ || (push_signature(&req->outbuf) == -1)) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ }
}
/****************************************************************************
}
}
- /* register_existing_vuid keeps the server info */
- /* register_existing_vuid takes ownership of session_key on success,
- * no need to free after this on success. A better interface would copy
- * it.... */
-
if (!is_partial_auth_vuid(sess_vuid)) {
sess_vuid = register_initial_vuid();
}
server_info->user_session_key = session_key;
session_key = data_blob_null;
+ /* register_existing_vuid keeps the server info */
+ /* register_existing_vuid takes ownership of session_key on success,
+ * no need to free after this on success. A better interface would copy
+ * it.... */
+
sess_vuid = register_existing_vuid(sess_vuid,
server_info,
nullblob,
for (i=0;OIDs[i];i++) {
DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
- free(OIDs[i]);
+ talloc_free(OIDs[i]);
}
return ret;
}
#ifdef HAVE_KRB5
if (kerb_mech && ((lp_security()==SEC_ADS) ||
- lp_use_kerberos_keytab()) ) {
+ USE_KERBEROS_KEYTAB) ) {
bool destroy_vuid = True;
reply_spnego_kerberos(req, &secblob, kerb_mech,
vuid, &destroy_vuid);
(unsigned long)secblob.length));
#ifdef HAVE_KRB5
if (kerb_mech && ((lp_security()==SEC_ADS) ||
- lp_use_kerberos_keytab()) ) {
+ USE_KERBEROS_KEYTAB)) {
bool destroy_vuid = True;
reply_spnego_kerberos(req, &secblob, kerb_mech,
vuid, &destroy_vuid);
DEBUG(3,("reply_spnego_auth: network "
"misconfiguration, client sent us a "
"krb5 ticket and kerberos security "
- "not enabled"));
+ "not enabled\n"));
reply_nterror(req, nt_status_squash(
NT_STATUS_LOGON_FAILURE));
SAFE_FREE(kerb_mech);
return;
}
-/****************************************************************************
- List to store partial SPNEGO auth fragments.
-****************************************************************************/
-
-static struct pending_auth_data *pd_list;
-
/****************************************************************************
Delete an entry on the list.
****************************************************************************/
DATA_BLOB *pblob)
{
struct pending_auth_data *pad = NULL;
- ASN1_DATA data;
+ ASN1_DATA *data;
size_t needed_len = 0;
pad = get_pending_auth_data(smbpid);
* the data given in this blob is enough.
*/
- asn1_load(&data, *pblob);
- asn1_start_tag(&data, pblob->data[0]);
- if (data.has_error || data.nesting == NULL) {
- asn1_free(&data);
+ data = asn1_init(NULL);
+ if (data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ asn1_load(data, *pblob);
+ asn1_start_tag(data, pblob->data[0]);
+ if (data->has_error || data->nesting == NULL) {
+ asn1_free(data);
/* Let caller catch. */
return NT_STATUS_OK;
}
/* Integer wrap paranoia.... */
- if (data.nesting->taglen + data.nesting->start < data.nesting->taglen ||
- data.nesting->taglen + data.nesting->start < data.nesting->start) {
+ if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
+ data->nesting->taglen + data->nesting->start < data->nesting->start) {
DEBUG(2,("check_spnego_blob_complete: integer wrap "
"data.nesting->taglen = %u, "
"data.nesting->start = %u\n",
- (unsigned int)data.nesting->taglen,
- (unsigned int)data.nesting->start ));
+ (unsigned int)data->nesting->taglen,
+ (unsigned int)data->nesting->start ));
- asn1_free(&data);
+ asn1_free(data);
return NT_STATUS_INVALID_PARAMETER;
}
/* Total length of the needed asn1 is the tag length
* plus the current offset. */
- needed_len = data.nesting->taglen + data.nesting->start;
- asn1_free(&data);
+ needed_len = data->nesting->taglen + data->nesting->start;
+ asn1_free(data);
DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
"pblob->length = %u\n",
static void reply_sesssetup_and_X_spnego(struct smb_request *req)
{
- uint8 *p;
+ const uint8 *p;
DATA_BLOB blob1;
size_t bufrem;
- fstring native_os, native_lanman, primary_domain;
+ char *tmp;
+ const char *native_os;
+ const char *native_lanman;
+ const char *primary_domain;
const char *p2;
- uint16 data_blob_len = SVAL(req->inbuf, smb_vwv7);
+ uint16 data_blob_len = SVAL(req->vwv+7, 0);
enum remote_arch_types ra_type = get_remote_arch();
- int vuid = SVAL(req->inbuf,smb_uid);
+ int vuid = req->vuid;
user_struct *vuser = NULL;
NTSTATUS status = NT_STATUS_OK;
uint16 smbpid = req->smbpid;
- uint16 smb_flag2 = req->flags2;
DEBUG(3,("Doing spnego session setup\n"));
if (global_client_caps == 0) {
- global_client_caps = IVAL(req->inbuf,smb_vwv10);
+ global_client_caps = IVAL(req->vwv+10, 0);
if (!(global_client_caps & CAP_STATUS32)) {
remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
}
- p = (uint8 *)smb_buf(req->inbuf);
+ p = req->buf;
if (data_blob_len == 0) {
/* an invalid request */
return;
}
- bufrem = smb_bufrem(req->inbuf, p);
+ bufrem = smbreq_bufrem(req, p);
/* pull the spnego blob */
blob1 = data_blob(p, MIN(bufrem, data_blob_len));
file_save("negotiate.dat", blob1.data, blob1.length);
#endif
- p2 = (char *)req->inbuf + smb_vwv13 + data_blob_len;
- p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_os, p2,
- sizeof(native_os), STR_TERMINATE);
- p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_lanman, p2,
- sizeof(native_lanman), STR_TERMINATE);
- p2 += srvstr_pull_buf(req->inbuf, smb_flag2, primary_domain, p2,
- sizeof(primary_domain), STR_TERMINATE);
+ p2 = (char *)req->buf + data_blob_len;
+
+ p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
+ STR_TERMINATE);
+ native_os = tmp ? tmp : "";
+
+ p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
+ STR_TERMINATE);
+ native_lanman = tmp ? tmp : "";
+
+ p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
+ STR_TERMINATE);
+ primary_domain = tmp ? tmp : "";
+
DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
native_os, native_lanman, primary_domain));
return 0;
}
- DEBUG(0,("shutdown_other_smbds: shutting down pid %d "
- "(IP %s)\n", procid_to_pid(&crec->pid), ip));
+ DEBUG(0,("shutdown_other_smbds: shutting down pid %u "
+ "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid), ip));
messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN,
&data_blob_null);
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
DATA_BLOB plaintext_password;
- fstring user;
+ char *tmp;
+ const char *user;
fstring sub_user; /* Sainitised username for substituion */
- fstring domain;
- fstring native_os;
- fstring native_lanman;
- fstring primary_domain;
- static bool done_sesssetup = False;
+ const char *domain;
+ const char *native_os;
+ const char *native_lanman;
+ const char *primary_domain;
auth_usersupplied_info *user_info = NULL;
auth_serversupplied_info *server_info = NULL;
uint16 smb_flag2 = req->flags2;
return;
}
- if (SVAL(req->inbuf,smb_vwv4) == 0) {
+ if (SVAL(req->vwv+4, 0) == 0) {
setup_new_vc_session();
}
return;
}
- smb_bufsize = SVAL(req->inbuf,smb_vwv2);
+ smb_bufsize = SVAL(req->vwv+2, 0);
if (Protocol < PROTOCOL_NT1) {
- uint16 passlen1 = SVAL(req->inbuf,smb_vwv7);
+ uint16 passlen1 = SVAL(req->vwv+7, 0);
/* Never do NT status codes with protocols before NT1 as we
* don't get client caps. */
remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
- if ((passlen1 > MAX_PASS_LEN)
- || (passlen1 > smb_bufrem(req->inbuf,
- smb_buf(req->inbuf)))) {
+ if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
reply_nterror(req, nt_status_squash(
NT_STATUS_INVALID_PARAMETER));
END_PROFILE(SMBsesssetupX);
}
if (doencrypt) {
- lm_resp = data_blob(smb_buf(req->inbuf), passlen1);
+ lm_resp = data_blob(req->buf, passlen1);
} else {
- plaintext_password = data_blob(smb_buf(req->inbuf),
- passlen1+1);
+ plaintext_password = data_blob(req->buf, passlen1+1);
/* Ensure null termination */
plaintext_password.data[passlen1] = 0;
}
- srvstr_pull_buf(req->inbuf, req->flags2, user,
- smb_buf(req->inbuf)+passlen1, sizeof(user),
- STR_TERMINATE);
- *domain = 0;
+ srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
+ req->buf + passlen1, STR_TERMINATE);
+ user = tmp ? tmp : "";
+
+ domain = "";
} else {
- uint16 passlen1 = SVAL(req->inbuf,smb_vwv7);
- uint16 passlen2 = SVAL(req->inbuf,smb_vwv8);
+ uint16 passlen1 = SVAL(req->vwv+7, 0);
+ uint16 passlen2 = SVAL(req->vwv+8, 0);
enum remote_arch_types ra_type = get_remote_arch();
- char *p = smb_buf(req->inbuf);
- char *save_p = smb_buf(req->inbuf);
+ const uint8_t *p = req->buf;
+ const uint8_t *save_p = req->buf;
uint16 byte_count;
if(global_client_caps == 0) {
- global_client_caps = IVAL(req->inbuf,smb_vwv11);
+ global_client_caps = IVAL(req->vwv+11, 0);
if (!(global_client_caps & CAP_STATUS32)) {
remove_from_common_flags2(
/* check for nasty tricks */
if (passlen1 > MAX_PASS_LEN
- || passlen1 > smb_bufrem(req->inbuf, p)) {
+ || passlen1 > smbreq_bufrem(req, p)) {
reply_nterror(req, nt_status_squash(
NT_STATUS_INVALID_PARAMETER));
END_PROFILE(SMBsesssetupX);
}
if (passlen2 > MAX_PASS_LEN
- || passlen2 > smb_bufrem(req->inbuf, p+passlen1)) {
+ || passlen2 > smbreq_bufrem(req, p+passlen1)) {
reply_nterror(req, nt_status_squash(
NT_STATUS_INVALID_PARAMETER));
END_PROFILE(SMBsesssetupX);
req->inbuf,
req->flags2,
&pass,
- smb_buf(req->inbuf),
+ req->buf,
passlen1,
STR_TERMINATE|STR_ASCII);
} else {
req->inbuf,
req->flags2,
&pass,
- smb_buf(req->inbuf),
+ req->buf,
unic ? passlen2 : passlen1,
STR_TERMINATE);
}
}
p += passlen1 + passlen2;
- p += srvstr_pull_buf(req->inbuf, req->flags2, user, p,
- sizeof(user), STR_TERMINATE);
- p += srvstr_pull_buf(req->inbuf, req->flags2, domain, p,
- sizeof(domain), STR_TERMINATE);
- p += srvstr_pull_buf(req->inbuf, req->flags2, native_os,
- p, sizeof(native_os), STR_TERMINATE);
- p += srvstr_pull_buf(req->inbuf, req->flags2,
- native_lanman, p, sizeof(native_lanman),
- STR_TERMINATE);
+
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ user = tmp ? tmp : "";
+
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ domain = tmp ? tmp : "";
+
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ native_os = tmp ? tmp : "";
+
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ native_lanman = tmp ? tmp : "";
/* not documented or decoded by Ethereal but there is one more
* string in the extra bytes which is the same as the
* Windows 9x does not include a string here at all so we have
* to check if we have any extra bytes left */
- byte_count = SVAL(req->inbuf, smb_vwv13);
+ byte_count = SVAL(req->vwv+13, 0);
if ( PTR_DIFF(p, save_p) < byte_count) {
- p += srvstr_pull_buf(req->inbuf, req->flags2,
- primary_domain, p,
- sizeof(primary_domain),
- STR_TERMINATE);
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ primary_domain = tmp ? tmp : "";
} else {
- fstrcpy( primary_domain, "null" );
+ primary_domain = talloc_strdup(talloc_tos(), "null");
}
DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
}
- if (SVAL(req->inbuf,smb_vwv4) == 0) {
+ if (SVAL(req->vwv+4, 0) == 0) {
setup_new_vc_session();
}
add_session_user(sub_user);
add_session_workgroup(domain);
/* Then force it to null for the benfit of the code below */
- *user = 0;
+ user = "";
}
if (!*user) {
}
} else {
struct auth_context *plaintext_auth_context = NULL;
- const uint8 *chal;
nt_status = make_auth_context_subsystem(
&plaintext_auth_context);
if (NT_STATUS_IS_OK(nt_status)) {
- chal = plaintext_auth_context->get_ntlm_challenge(
- plaintext_auth_context);
+ uint8_t chal[8];
+
+ plaintext_auth_context->get_ntlm_challenge(
+ plaintext_auth_context, chal);
if (!make_user_info_for_reply(&user_info,
user, domain, chal,