📄 negprot.c
字号:
/* Unix SMB/CIFS implementation. negprot reply code Copyright (C) Andrew Tridgell 1992-1998 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 the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "auth/credentials/credentials.h"#include "auth/gensec/gensec.h"#include "auth/auth.h"#include "smb_server/smb_server.h"#include "libcli/smb2/smb2.h"#include "smb_server/smb2/smb2_server.h"#include "smb_server/service_smb_proto.h"#include "smbd/service_stream.h"#include "lib/stream/packet.h"#include "param/param.h"/* initialise the auth_context for this server and return the cryptkey */static NTSTATUS get_challenge(struct smbsrv_connection *smb_conn, uint8_t buff[8]) { NTSTATUS nt_status; const uint8_t *challenge; /* muliple negprots are not premitted */ if (smb_conn->negotiate.auth_context) { DEBUG(3,("get challenge: is this a secondary negprot? auth_context is non-NULL!\n")); return NT_STATUS_FOOBAR; } DEBUG(10, ("get challenge: creating negprot_global_auth_context\n")); nt_status = auth_context_create(smb_conn, smb_conn->connection->event.ctx, smb_conn->connection->msg_ctx, smb_conn->lp_ctx, &smb_conn->negotiate.auth_context); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("auth_context_create() returned %s", nt_errstr(nt_status))); return nt_status; } nt_status = auth_get_challenge(smb_conn->negotiate.auth_context, &challenge); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("auth_get_challenge() returned %s", nt_errstr(nt_status))); return nt_status; } memcpy(buff, challenge, 8); return NT_STATUS_OK;}/**************************************************************************** Reply for the core protocol.****************************************************************************/static void reply_corep(struct smbsrv_request *req, uint16_t choice){ smbsrv_setup_reply(req, 1, 0); SSVAL(req->out.vwv, VWV(0), choice); req->smb_conn->negotiate.protocol = PROTOCOL_CORE; if (req->smb_conn->signing.mandatory_signing) { smbsrv_terminate_connection(req->smb_conn, "CORE does not support SMB signing, and it is mandatory\n"); return; } smbsrv_send_reply(req);}/**************************************************************************** Reply for the coreplus protocol.this is quite incomplete - we only fill in a small part of the reply, but as nobody usesthis any more it probably doesn't matter****************************************************************************/static void reply_coreplus(struct smbsrv_request *req, uint16_t choice){ uint16_t raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0); smbsrv_setup_reply(req, 13, 0); /* Reply, SMBlockread, SMBwritelock supported. */ SCVAL(req->out.hdr,HDR_FLG, CVAL(req->out.hdr, HDR_FLG) | FLAG_SUPPORT_LOCKREAD); SSVAL(req->out.vwv, VWV(0), choice); SSVAL(req->out.vwv, VWV(1), 0x1); /* user level security, don't encrypt */ /* tell redirector we support readbraw and writebraw (possibly) */ SSVAL(req->out.vwv, VWV(5), raw); req->smb_conn->negotiate.protocol = PROTOCOL_COREPLUS; if (req->smb_conn->signing.mandatory_signing) { smbsrv_terminate_connection(req->smb_conn, "COREPLUS does not support SMB signing, and it is mandatory\n"); return; } smbsrv_send_reply(req);}/**************************************************************************** Reply for the lanman 1.0 protocol.****************************************************************************/static void reply_lanman1(struct smbsrv_request *req, uint16_t choice){ int raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0); int secword=0; time_t t = req->request_time.tv_sec; req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx); if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) secword |= NEGOTIATE_SECURITY_USER_LEVEL; if (req->smb_conn->negotiate.encrypted_passwords) secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; req->smb_conn->negotiate.protocol = PROTOCOL_LANMAN1; smbsrv_setup_reply(req, 13, req->smb_conn->negotiate.encrypted_passwords ? 8 : 0); /* SMBlockread, SMBwritelock supported. */ SCVAL(req->out.hdr,HDR_FLG, CVAL(req->out.hdr, HDR_FLG) | FLAG_SUPPORT_LOCKREAD); SSVAL(req->out.vwv, VWV(0), choice); SSVAL(req->out.vwv, VWV(1), secword); SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv); SSVAL(req->out.vwv, VWV(3), lp_maxmux(req->smb_conn->lp_ctx)); SSVAL(req->out.vwv, VWV(4), 1); SSVAL(req->out.vwv, VWV(5), raw); SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id); srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t); SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60); SIVAL(req->out.vwv, VWV(11), 0); /* reserved */ /* Create a token value and add it to the outgoing packet. */ if (req->smb_conn->negotiate.encrypted_passwords) { NTSTATUS nt_status; SSVAL(req->out.vwv, VWV(11), 8); nt_status = get_challenge(req->smb_conn, req->out.data); if (!NT_STATUS_IS_OK(nt_status)) { smbsrv_terminate_connection(req->smb_conn, "LANMAN1 get_challenge failed\n"); return; } } if (req->smb_conn->signing.mandatory_signing) { smbsrv_terminate_connection(req->smb_conn, "LANMAN1 does not support SMB signing, and it is mandatory\n"); return; } smbsrv_send_reply(req); }/**************************************************************************** Reply for the lanman 2.0 protocol.****************************************************************************/static void reply_lanman2(struct smbsrv_request *req, uint16_t choice){ int raw = (lp_readraw(req->smb_conn->lp_ctx)?1:0) | (lp_writeraw(req->smb_conn->lp_ctx)?2:0); int secword=0; time_t t = req->request_time.tv_sec; req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx); if (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) secword |= NEGOTIATE_SECURITY_USER_LEVEL; if (req->smb_conn->negotiate.encrypted_passwords) secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; req->smb_conn->negotiate.protocol = PROTOCOL_LANMAN2; smbsrv_setup_reply(req, 13, 0); SSVAL(req->out.vwv, VWV(0), choice); SSVAL(req->out.vwv, VWV(1), secword); SSVAL(req->out.vwv, VWV(2), req->smb_conn->negotiate.max_recv); SSVAL(req->out.vwv, VWV(3), lp_maxmux(req->smb_conn->lp_ctx)); SSVAL(req->out.vwv, VWV(4), 1); SSVAL(req->out.vwv, VWV(5), raw); SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id.id); srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t); SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60); SIVAL(req->out.vwv, VWV(11), 0); /* Create a token value and add it to the outgoing packet. */ if (req->smb_conn->negotiate.encrypted_passwords) { SSVAL(req->out.vwv, VWV(11), 8); req_grow_data(req, 8); get_challenge(req->smb_conn, req->out.data); } req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_TERMINATE); if (req->smb_conn->signing.mandatory_signing) { smbsrv_terminate_connection(req->smb_conn, "LANMAN2 does not support SMB signing, and it is mandatory\n"); return; } smbsrv_send_reply(req);}static void reply_nt1_orig(struct smbsrv_request *req){ /* Create a token value and add it to the outgoing packet. */ if (req->smb_conn->negotiate.encrypted_passwords) { req_grow_data(req, 8); /* note that we do not send a challenge at all if we are using plaintext */ get_challenge(req->smb_conn, req->out.ptr); req->out.ptr += 8; SCVAL(req->out.vwv+1, VWV(16), 8); } req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); req_push_str(req, NULL, lp_netbios_name(req->smb_conn->lp_ctx), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); DEBUG(3,("not using extended security (SPNEGO or NTLMSSP)\n"));}/**************************************************************************** Reply for the nt protocol.****************************************************************************/static void reply_nt1(struct smbsrv_request *req, uint16_t choice){ /* dual names + lock_and_read + nt SMBs + remote API calls */ int capabilities; int secword=0; time_t t = req->request_time.tv_sec; NTTIME nttime; bool negotiate_spnego = false; char *large_test_path; unix_to_nt_time(&nttime, t); capabilities = CAP_NT_FIND | CAP_LOCK_AND_READ | CAP_LEVEL_II_OPLOCKS | CAP_NT_SMBS | CAP_RPC_REMOTE_APIS; req->smb_conn->negotiate.encrypted_passwords = lp_encrypted_passwords(req->smb_conn->lp_ctx); /* do spnego in user level security if the client supports it and we can do encrypted passwords */ if (req->smb_conn->negotiate.encrypted_passwords && (lp_security(req->smb_conn->lp_ctx) != SEC_SHARE) && lp_use_spnego(req->smb_conn->lp_ctx) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -