*/
#include "includes.h"
+#include "../lib/tsocket/tsocket.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/auth/spnego.h"
#include "auth.h"
#include "messages.h"
#include "smbprofile.h"
+#include "../libcli/security/security.h"
/* For split krb5 SPNEGO blobs. */
struct pending_auth_data {
DATA_BLOB partial_data;
};
-/*
- on a logon error possibly map the error to success if "map to guest"
- is set approriately
-*/
-NTSTATUS do_map_to_guest(NTSTATUS status,
- struct auth_serversupplied_info **server_info,
- const char *user, const char *domain)
-{
- user = user ? user : "";
- domain = domain ? domain : "";
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
- if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
- (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
- DEBUG(3,("No such user %s [%s] - using guest account\n",
- user, domain));
- status = make_server_info_guest(NULL, server_info);
- }
- }
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
- if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
- DEBUG(3,("Registered username %s for guest access\n",
- user));
- status = make_server_info_guest(NULL, server_info);
- }
- }
-
- return status;
-}
-
/****************************************************************************
Add the standard 'Samba' signature to the end of the session setup.
****************************************************************************/
Do a 'guest' logon, getting back the
****************************************************************************/
-static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
+static NTSTATUS check_guest_password(const struct tsocket_address *remote_address,
+ struct auth_serversupplied_info **server_info)
{
struct auth_context *auth_context;
struct auth_usersupplied_info *user_info = NULL;
return nt_status;
}
- if (!make_user_info_guest(&user_info)) {
+ if (!make_user_info_guest(remote_address, &user_info)) {
TALLOC_FREE(auth_context);
return NT_STATUS_NO_MEMORY;
}
return False;
}
/* Create server principal. */
- asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
+ asprintf(&host_princ_s, "%s$@%s", lp_netbios_name(), lp_realm());
if (!host_princ_s) {
goto out;
}
int sess_vuid = req->vuid;
NTSTATUS ret = NT_STATUS_OK;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
- struct auth_serversupplied_info *session_info = NULL;
+ struct auth_session_info *session_info = NULL;
DATA_BLOB session_key = data_blob_null;
uint8 tok_id[2];
DATA_BLOB nullblob = data_blob_null;
}
ret = get_user_from_kerberos_info(talloc_tos(),
- sconn->client_id.name,
+ sconn->remote_hostname,
principal, logon_info,
&username_was_mapped,
&map_domainuser_to_guest,
SSVAL(req->outbuf, smb_vwv3, 0);
- if (session_info->guest) {
+ if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
SSVAL(req->outbuf,smb_vwv2,1);
}
{
bool do_invalidate = true;
DATA_BLOB response;
- struct auth_serversupplied_info *session_info = NULL;
+ struct auth_session_info *session_info = NULL;
struct smbd_server_connection *sconn = req->sconn;
if (NT_STATUS_IS_OK(nt_status)) {
nt_status = auth_ntlmssp_steal_session_info(talloc_tos(),
(*auth_ntlmssp_state), &session_info);
- } else {
- /* Note that this session_info won't have a session
- * key. But for map to guest, that's exactly the right
- * thing - we can't reasonably guess the key the
- * client wants, as the password was wrong */
- nt_status = do_map_to_guest(nt_status,
- &session_info,
- auth_ntlmssp_get_username(*auth_ntlmssp_state),
- auth_ntlmssp_get_domain(*auth_ntlmssp_state));
}
reply_outbuf(req, 4, 0);
SSVAL(req->outbuf, smb_vwv3, 0);
- if (session_info->guest) {
+ if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
SSVAL(req->outbuf,smb_vwv2,1);
}
}
return;
}
- status = auth_ntlmssp_start(auth_ntlmssp_state);
+ status = auth_ntlmssp_start(sconn->remote_address,
+ auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
data_blob_free(&secblob);
if (!*auth_ntlmssp_state) {
- status = auth_ntlmssp_start(auth_ntlmssp_state);
+ status = auth_ntlmssp_start(sconn->remote_address,
+ auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
}
asn1_load(data, *pblob);
- asn1_start_tag(data, pblob->data[0]);
- if (data->has_error || data->nesting == NULL) {
+ if (asn1_start_tag(data, pblob->data[0])) {
+ /* asn1_start_tag checks if the given
+ length of the blob is enough to complete
+ the tag. If it returns true we know
+ there is nothing to do - the blob is
+ complete. */
asn1_free(data);
- /* Let caller catch. */
return NT_STATUS_OK;
}
+ if (data->nesting == NULL) {
+ /* Incorrect tag, allocation failed,
+ or reading the tag length failed.
+ Let the caller catch. */
+ asn1_free(data);
+ return NT_STATUS_OK;
+ }
+
+ /* Here we know asn1_start_tag() has set data->has_error to true.
+ asn1_tag_remaining() will have failed due to the given blob
+ being too short. We need to work out how short. */
+
/* Integer wrap paranoia.... */
if (data->nesting->taglen + data->nesting->start < data->nesting->taglen ||
if (needed_len <= pblob->length) {
/* Nothing to do - blob is complete. */
+ /* THIS SHOULD NOT HAPPEN - asn1_start_tag()
+ above should have caught this !!! */
+ DEBUG(0,("check_spnego_blob_complete: logic "
+ "error (needed_len = %u, "
+ "pblob->length = %u).\n",
+ (unsigned int)needed_len,
+ (unsigned int)pblob->length ));
return NT_STATUS_OK;
}
file_save("negotiate.dat", blob1.data, blob1.length);
#endif
- p2 = (char *)req->buf + blob1.length;
+ p2 = (const char *)req->buf + blob1.length;
p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
STR_TERMINATE);
DATA_BLOB chal;
if (!vuser->auth_ntlmssp_state) {
- status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
+ status = auth_ntlmssp_start(sconn->remote_address,
+ &vuser->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
struct shutdown_state *state = (struct shutdown_state *)private_data;
DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
- procid_str(talloc_tos(), &crec->pid), crec->addr));
+ server_id_str(talloc_tos(), &crec->pid), crec->addr));
if (!process_exists(crec->pid)) {
DEBUG(10, ("process does not exist\n"));
const char *primary_domain;
struct auth_usersupplied_info *user_info = NULL;
struct auth_serversupplied_info *server_info = NULL;
- struct auth_serversupplied_info *session_info = NULL;
+ struct auth_session_info *session_info = NULL;
uint16 smb_flag2 = req->flags2;
NTSTATUS nt_status;
if (!*user) {
- nt_status = check_guest_password(&server_info);
+ nt_status = check_guest_password(sconn->remote_address, &server_info);
} else if (doencrypt) {
struct auth_context *negprot_auth_context = NULL;
}
nt_status = make_user_info_for_reply_enc(&user_info, user,
domain,
+ sconn->remote_address,
lm_resp, nt_resp);
if (NT_STATUS_IS_OK(nt_status)) {
nt_status = negprot_auth_context->check_ntlm_password(
plaintext_auth_context, chal);
if (!make_user_info_for_reply(&user_info,
- user, domain, chal,
+ user, domain,
+ sconn->remote_address,
+ chal,
plaintext_password)) {
nt_status = NT_STATUS_NO_MEMORY;
}
free_user_info(&user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
- nt_status = do_map_to_guest(nt_status, &server_info,
- user, domain);
+ nt_status = do_map_to_guest_server_info(nt_status, &server_info,
+ user, domain);
}
if (!NT_STATUS_IS_OK(nt_status)) {
/* perhaps grab OS version here?? */
}
- if (session_info->guest) {
+ if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
SSVAL(req->outbuf,smb_vwv2,1);
}
data_blob_free(&lm_resp);
SSVAL(req->outbuf,smb_uid,sess_vuid);
- SSVAL(req->inbuf,smb_uid,sess_vuid);
+ SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
req->vuid = sess_vuid;
if (!sconn->smb1.sessions.done_sesssetup) {