static int _my_mbstowcs(__u16 *dst, const unsigned char *src, int len) { /* BB not a very good conversion routine - change/fix */ int i; __u16 val; for (i = 0; i < len; i++) { val = *src; SSVAL(dst, 0, val); dst++; src++; if (val == 0) break; } return i; }
/**************************************************************************** Delete a file - async interface ****************************************************************************/ struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree, union smb_unlink *parms) { struct smbcli_request *req; SETUP_REQUEST(SMBunlink, 1, 0); SSVAL(req->out.vwv, VWV(0), parms->unlink.in.attrib); smbcli_req_append_ascii4(req, parms->unlink.in.pattern, STR_TERMINATE); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
static int _my_mbstowcs(int16 * dst, uchar * src, int len) { int i; int16 val; for (i = 0; i < len; i++) { val = *src; SSVAL(dst, 0, val); dst++; src++; if (val == 0) break; } return i; }
/* * reply to a SMB negprot request with dialect "SMB 2.002" */ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req) { struct smb2srv_request *req; uint32_t body_fixed_size = 0x26; req = talloc_zero(smb_req->smb_conn, struct smb2srv_request); if (!req) goto nomem; req->smb_conn = smb_req->smb_conn; req->request_time = smb_req->request_time; talloc_steal(req, smb_req); req->in.size = NBT_HDR_SIZE+SMB2_HDR_BODY+body_fixed_size; req->in.allocated = req->in.size; req->in.buffer = talloc_array(req, uint8_t, req->in.allocated); if (!req->in.buffer) goto nomem; req->in.hdr = req->in.buffer + NBT_HDR_SIZE; req->in.body = req->in.hdr + SMB2_HDR_BODY; req->in.body_size = body_fixed_size; req->in.dynamic = NULL; smb2srv_setup_bufinfo(req); SIVAL(req->in.hdr, 0, SMB2_MAGIC); SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0); SIVAL(req->in.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->in.hdr, SMB2_HDR_OPCODE, SMB2_OP_NEGPROT); SSVAL(req->in.hdr, SMB2_HDR_CREDIT, 0); SIVAL(req->in.hdr, SMB2_HDR_FLAGS, 0); SIVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND, 0); SBVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID, 0); SIVAL(req->in.hdr, SMB2_HDR_PID, 0); SIVAL(req->in.hdr, SMB2_HDR_TID, 0); SBVAL(req->in.hdr, SMB2_HDR_SESSION_ID, 0); memset(req->in.hdr+SMB2_HDR_SIGNATURE, 0, 16); /* this seems to be a bug, they use 0x24 but the length is 0x26 */ SSVAL(req->in.body, 0x00, 0x24); SSVAL(req->in.body, 0x02, 1); memset(req->in.body+0x04, 0, 32); SSVAL(req->in.body, 0x24, SMB2_DIALECT_REVISION_202); smb2srv_negprot_recv(req); return; nomem: smbsrv_terminate_connection(smb_req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY)); talloc_free(req); return; }
/* * reply to a SMB negprot request with dialect "SMB 2.001" */ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req) { struct smb2srv_request *req; uint32_t body_fixed_size = 0x26; /* create a fake SMB2 negprot request */ req = talloc_zero(smb_req->smb_conn, struct smb2srv_request); if (!req) goto nomem; req->smb_conn = smb_req->smb_conn; req->request_time = smb_req->request_time; talloc_steal(req, smb_req); req->in.size = NBT_HDR_SIZE+SMB2_HDR_BODY+body_fixed_size; req->in.allocated = req->in.size; req->in.buffer = talloc_size(req, req->in.allocated); if (!req->in.buffer) goto nomem; req->in.hdr = req->in.buffer + NBT_HDR_SIZE; req->in.body = req->in.hdr + SMB2_HDR_BODY; req->in.body_size = body_fixed_size; req->in.dynamic = NULL; SIVAL(req->in.hdr, 0, SMB2_MAGIC); SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); SSVAL(req->in.hdr, SMB2_HDR_PAD1, 0); SIVAL(req->in.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->in.hdr, SMB2_HDR_OPCODE, SMB2_OP_NEGPROT); SSVAL(req->in.hdr, SMB2_HDR_UNKNOWN1, 0); SIVAL(req->in.hdr, SMB2_HDR_FLAGS, 0); SIVAL(req->in.hdr, SMB2_HDR_CHAIN_OFFSET, 0); SBVAL(req->in.hdr, SMB2_HDR_SEQNUM, 0); SIVAL(req->in.hdr, SMB2_HDR_PID, 0); SIVAL(req->in.hdr, SMB2_HDR_TID, 0); SBVAL(req->in.hdr, SMB2_HDR_UID, 0); memset(req->in.hdr+SMB2_HDR_SIG, 0, 16); /* this seems to be a bug, they use 0x24 but the length is 0x26 */ SSVAL(req->in.body, 0x00, 0x24); SSVAL(req->in.body, 0x02, 1); memset(req->in.body+0x04, 0, 32); SSVAL(req->in.body, 0x24, 0); smb2srv_negprot_recv(req); return; nomem: smbsrv_terminate_connection(smb_req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY)); talloc_free(req); return; }
static char *form_name(struct smb_iconv_convenience *iconv_convenience, int c) { static char fname[256]; uint8_t c2[4]; char *p; size_t len; strncpy(fname, "\\utable\\", sizeof(fname)-1); p = fname+strlen(fname); SSVAL(c2, 0, c); convert_string_convenience(iconv_convenience, CH_UTF16, CH_UNIX, c2, 2, p, sizeof(fname)-strlen(fname), &len, false); p[len] = 0; return fname; }
/* fill in the reply from a qpathinfo or qfileinfo call */ static NTSTATUS trans2_fileinfo_send(struct trans_op *op) { struct smbsrv_request *req = op->req; struct smb_trans2 *trans = op->trans; union smb_fileinfo *st; TRANS2_CHECK_ASYNC_STATUS(st, union smb_fileinfo); TRANS2_CHECK(trans2_setup_reply(trans, 2, 0, 0)); SSVAL(trans->out.params.data, 0, 0); TRANS2_CHECK(trans2_push_fileinfo(req->smb_conn, trans, &trans->out.data, st, SMBSRV_REQ_DEFAULT_STR_FLAGS(req))); return NT_STATUS_OK; }
BOOL cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) { uint16 setup = TRANSACT2_SETPATHINFO; unsigned int param_len = 0; char param[sizeof(pstring)+6]; size_t srclen = 2*(strlen(path)+1); char *p; memset(param, 0, sizeof(param)); SSVAL(param,0,SMB_INFO_SET_EA); p = ¶m[6]; p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE); param_len = PTR_DIFF(p, param); return cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len); }
BOOL create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void (*free_fn)(void *), void *data_ptr) { static uint32 pol_hnd_low = 0; static uint32 pol_hnd_high = 0; struct policy *pol; if (p->pipe_handles->count > MAX_OPEN_POLS) { DEBUG(0,("create_policy_hnd: ERROR: too many handles (%d) on this pipe.\n", (int)p->pipe_handles->count)); return False; } pol = (struct policy *)malloc(sizeof(*p)); if (!pol) { DEBUG(0,("create_policy_hnd: ERROR: out of memory!\n")); return False; } ZERO_STRUCTP(pol); pol->data_ptr = data_ptr; pol->free_fn = free_fn; pol_hnd_low++; if (pol_hnd_low == 0) (pol_hnd_high)++; SIVAL(&pol->pol_hnd.data1, 0 , 0); /* first bit must be null */ SIVAL(&pol->pol_hnd.data2, 0 , pol_hnd_low ); /* second bit is incrementing */ SSVAL(&pol->pol_hnd.data3, 0 , pol_hnd_high); /* second bit is incrementing */ SSVAL(&pol->pol_hnd.data4, 0 , (pol_hnd_high>>16)); /* second bit is incrementing */ SIVAL(pol->pol_hnd.data5, 0, time(NULL)); /* something random */ SIVAL(pol->pol_hnd.data5, 4, sys_getpid()); /* something more random */ DLIST_ADD(p->pipe_handles->Policy, pol); p->pipe_handles->count++; *hnd = pol->pol_hnd; DEBUG(4,("Opened policy hnd[%d] ", (int)p->pipe_handles->count)); dump_data(4, (char *)hnd, sizeof(*hnd)); return True; }
static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid) { unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; char data[100]; char *rparam=NULL, *rdata=NULL; char *p; memset(param, 0, sizeof(param)); memset(data, 0, sizeof(data)); SSVAL(param,0,SMB_SET_FILE_UNIX_BASIC); p = ¶m[6]; p += clistr_push(cli, p, fname, -1, STR_TERMINATE); param_len = PTR_DIFF(p, param); SIVAL(data,40,uid); SIVAL(data,48,gid); SIVAL(data,84,mode); data_len = 100; if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ (char *)&data, data_len, cli->max_xmit /* data, length, max */ )) { return False; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { return False; } SAFE_FREE(rdata); SAFE_FREE(rparam); return True; }
static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len, const char *ea_name, const char *ea_val, size_t ea_len) { unsigned int data_len = 0; char *data = NULL; char *rparam=NULL, *rdata=NULL; char *p; size_t ea_namelen = strlen(ea_name); data_len = 4 + 4 + ea_namelen + 1 + ea_len; data = malloc(data_len); if (!data) { return False; } p = data; SIVAL(p,0,data_len); p += 4; SCVAL(p, 0, 0); /* EA flags. */ SCVAL(p, 1, ea_namelen); SSVAL(p, 2, ea_len); memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ memcpy(p+4+ea_namelen+1, ea_val, ea_len); if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ data, data_len, cli->max_xmit /* data, length, max */ )) { return False; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { return False; } SAFE_FREE(data); SAFE_FREE(rdata); SAFE_FREE(rparam); return True; }
/* grow the data buffer portion of a reply packet. Note that as this can reallocate the packet buffer this invalidates any local pointers into the packet. To cope with this req->out.ptr is supplied. This will be updated to point at the same offset into the packet as before this call */ void req_grow_data(struct smbsrv_request *req, size_t new_size) { int delta; if (!(req->control_flags & SMBSRV_REQ_CONTROL_LARGE) && new_size > req_max_data(req)) { smb_panic("reply buffer too large!"); } req_grow_allocation(req, new_size); delta = new_size - req->out.data_size; req->out.size += delta; req->out.data_size += delta; /* set the BCC to the new data size */ SSVAL(req->out.vwv, VWV(req->out.wct), new_size); }
static void reply_lanman1(struct smb_request *req, uint16 choice) { int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); int secword=0; time_t t = time(NULL); struct smbd_server_connection *sconn = req->sconn; sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords(); if (lp_security()>=SEC_USER) { secword |= NEGOTIATE_SECURITY_USER_LEVEL; } if (sconn->smb1.negprot.encrypted_passwords) { secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; } reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0); SSVAL(req->outbuf,smb_vwv0,choice); SSVAL(req->outbuf,smb_vwv1,secword); /* Create a token value and add it to the outgoing packet. */ if (sconn->smb1.negprot.encrypted_passwords) { get_challenge(sconn, (uint8 *)smb_buf(req->outbuf)); SSVAL(req->outbuf,smb_vwv11, 8); } set_Protocol(PROTOCOL_LANMAN1); /* Reply, SMBlockread, SMBwritelock supported. */ SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); SSVAL(req->outbuf,smb_vwv2,sconn->smb1.negprot.max_recv); SSVAL(req->outbuf,smb_vwv3,lp_maxmux()); /* maxmux */ SSVAL(req->outbuf,smb_vwv4,1); SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support readbraw writebraw (possibly) */ SIVAL(req->outbuf,smb_vwv6,sys_getpid()); SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60); srv_put_dos_date((char *)req->outbuf,smb_vwv8,t); return; }
static void reply_lanman2(struct smb_request *req, uint16 choice) { int secword=0; time_t t = time(NULL); struct smbd_server_connection *sconn = req->sconn; uint16_t raw; if (lp_async_smb_echo_handler()) { raw = 0; } else { raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0); } sconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords(); secword |= NEGOTIATE_SECURITY_USER_LEVEL; if (sconn->smb1.negprot.encrypted_passwords) { secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; } reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0); SSVAL(req->outbuf,smb_vwv0, choice); SSVAL(req->outbuf,smb_vwv1, secword); SIVAL(req->outbuf,smb_vwv6, getpid()); /* Create a token value and add it to the outgoing packet. */ if (sconn->smb1.negprot.encrypted_passwords) { get_challenge(sconn, (uint8 *)smb_buf(req->outbuf)); SSVAL(req->outbuf,smb_vwv11, 8); } smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_LANMAN2); /* Reply, SMBlockread, SMBwritelock supported. */ SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); SSVAL(req->outbuf,smb_vwv2,sconn->smb1.negprot.max_recv); SSVAL(req->outbuf,smb_vwv3,lp_max_mux()); SSVAL(req->outbuf,smb_vwv4,1); SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */ SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60); srv_put_dos_date((char *)req->outbuf,smb_vwv8,t); }
static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, BOOL hard_link) { unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; pstring data; char *rparam=NULL, *rdata=NULL; char *p; size_t oldlen = 2*(strlen(oldname)+1); size_t newlen = 2*(strlen(newname)+1); memset(param, 0, sizeof(param)); SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK); p = ¶m[6]; p += clistr_push(cli, p, newname, MIN(newlen, sizeof(param)-6), STR_TERMINATE); param_len = PTR_DIFF(p, param); p = data; p += clistr_push(cli, p, oldname, MIN(oldlen,sizeof(data)), STR_TERMINATE); data_len = PTR_DIFF(p, data); if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ (char *)&data, data_len, cli->max_xmit /* data, length, max */ )) { return False; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { return False; } SAFE_FREE(rdata); SAFE_FREE(rparam); return True; }
void init_valid_table(void) { static int mapped_file; int i; const char *allowed = ".!#$%&'()_-@^`~"; uint8 *valid_file; if (mapped_file) { /* Can't unmap files, so stick with what we have */ return; } valid_file = (uint8 *)map_file(data_path("valid.dat"), 0x10000); if (valid_file) { valid_table = valid_file; mapped_file = 1; valid_table_use_unmap = True; return; } /* Otherwise, we're using a dynamically created valid_table. * It might need to be regenerated if the code page changed. * We know that we're not using a mapped file, so we can * free() the old one. */ SAFE_FREE(valid_table); /* use free rather than unmap */ valid_table_use_unmap = False; DEBUG(2,("creating default valid table\n")); valid_table = (uint8 *)SMB_MALLOC(0x10000); SMB_ASSERT(valid_table != NULL); for (i=0;i<128;i++) { valid_table[i] = isalnum(i) || strchr(allowed,i); } lazy_initialize_conv(); for (;i<0x10000;i++) { smb_ucs2_t c; SSVAL(&c, 0, i); valid_table[i] = check_dos_char_slowly(c); } }
BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf) { unsigned int param_len = 0; unsigned int data_len = 0; uint16 setup = TRANSACT2_QPATHINFO; char param[sizeof(pstring)+6]; char *rparam=NULL, *rdata=NULL; char *p; p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_POSIX_ACL); p += 6; p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ NULL, 0, cli->max_xmit /* data, length, max */ )) { return False; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { return False; } if (data_len < 6) { SAFE_FREE(rdata); SAFE_FREE(rparam); return False; } SAFE_FREE(rparam); *retbuf = rdata; *prb_size = (size_t)data_len; return True; }
BOOL cli_getatr(struct cli_state *cli, const char *fname, uint16 *attr, size_t *size, time_t *t) { char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBgetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; p += clistr_push(cli, p, fname, -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (cli_is_error(cli)) { return False; } if (size) { *size = IVAL(cli->inbuf, smb_vwv3); } if (t) { *t = make_unix_date3(cli->inbuf+smb_vwv1); } if (attr) { *attr = SVAL(cli->inbuf,smb_vwv0); } return True; }
BOOL cli_get_ea_list_path(struct cli_state *cli, const char *path, TALLOC_CTX *ctx, size_t *pnum_eas, struct ea_struct **pea_list) { uint16 setup = TRANSACT2_QPATHINFO; unsigned int param_len = 0; char param[sizeof(pstring)+6]; char *p; p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); p += 6; p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); return cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list); }
BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBdskattr); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2); *total = SVAL(cli->inbuf,smb_vwv0); *avail = SVAL(cli->inbuf,smb_vwv3); return True; }
/**************************************************************************** set the security descriptor for a open file ****************************************************************************/ NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum, struct security_descriptor *sd) { uint8_t param[8]; uint32 sec_info = 0; uint8 *data; size_t len; NTSTATUS status; status = marshall_sec_desc(talloc_tos(), sd, &data, &len); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("marshall_sec_desc failed: %s\n", nt_errstr(status))); return status; } SIVAL(param, 0, fnum); if (sd->dacl) sec_info |= SECINFO_DACL; if (sd->owner_sid) sec_info |= SECINFO_OWNER; if (sd->group_sid) sec_info |= SECINFO_GROUP; SSVAL(param, 4, sec_info); status = cli_trans(talloc_tos(), cli, SMBnttrans, NULL, -1, /* name, fid */ NT_TRANSACT_SET_SECURITY_DESC, 0, NULL, 0, 0, /* setup */ param, 8, 0, /* param */ data, len, 0, /* data */ NULL, /* recv_flags2 */ NULL, 0, NULL, /* rsetup */ NULL, 0, NULL, /* rparam */ NULL, 0, NULL); /* rdata */ TALLOC_FREE(data); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to send NT_TRANSACT_SET_SECURITY_DESC: %s\n", nt_errstr(status))); } return status; }
static char *form_name(int c) { static char fname[256]; uint8_t c2[4]; char *p; size_t len = 0; strncpy(fname, "\\utable\\", sizeof(fname)-1); p = fname+strlen(fname); SSVAL(c2, 0, c); if (!convert_string(CH_UTF16, CH_UNIX, c2, 2, p, sizeof(fname)-strlen(fname), &len)) { return NULL; } p[len] = 0; return fname; }
NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeout, size_t maxlen, size_t *p_len) { size_t len; NTSTATUS status; status = read_smb_length_return_keepalive(fd,buffer,timeout,&len); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("read_fd_with_timeout failed, read " "error = %s.\n", nt_errstr(status))); return status; } if (len > buflen) { DEBUG(0,("Invalid packet length! (%lu bytes).\n", (unsigned long)len)); return NT_STATUS_INVALID_PARAMETER; } if(len > 0) { if (maxlen) { len = MIN(len,maxlen); } status = read_fd_with_timeout( fd, buffer+4, len, len, timeout, &len); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("read_fd_with_timeout failed, read error = " "%s.\n", nt_errstr(status))); return status; } /* not all of samba3 properly checks for packet-termination * of strings. This ensures that we don't run off into * empty space. */ SSVAL(buffer+4,len, 0); } *p_len = len; return NT_STATUS_OK; }
void smb_signing_sign_pdu(struct smb_signing_state *si, uint8_t *outbuf, uint32_t seqnum) { uint8_t calc_md5_mac[16]; uint16_t flags2; if (si->mac_key.length == 0) { if (!si->bsrspyl) { return; } } /* JRA Paranioa test - we should be able to get rid of this... */ if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { DEBUG(1,("smb_signing_sign_pdu: Logic error. " "Can't check signature on short packet! smb_len = %u\n", smb_len(outbuf))); abort(); } /* mark the packet as signed - BEFORE we sign it...*/ flags2 = SVAL(outbuf,smb_flg2); flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(outbuf, smb_flg2, flags2); if (si->bsrspyl) { /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ memcpy(calc_md5_mac, "BSRSPYL ", 8); } else { smb_signing_md5(&si->mac_key, outbuf, seqnum, calc_md5_mac); } DEBUG(10, ("smb_signing_sign_pdu: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); /* outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ }
static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io) { if (NT_STATUS_IS_OK(req->status)) { /* nothing */ } else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* nothing */ } else { smb2srv_send_error(req, req->status); return; } SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, io->smb2.out.secblob.length)); SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, io->smb2.out.uid); SSVAL(req->out.body, 0x02, io->smb2.out.session_flags); SMB2SRV_CHECK(smb2_push_o16s16_blob(&req->out, 0x04, io->smb2.out.secblob)); smb2srv_send_reply(req); }
static void smb2srv_close_send(struct ntvfs_request *ntvfs) { struct smb2srv_request *req; union smb_close *io; SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_close); SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x3C, False, 0)); SSVAL(req->out.body, 0x02, io->smb2.out.flags); SIVAL(req->out.body, 0x04, io->smb2.out._pad); SBVAL(req->out.body, 0x08, io->smb2.out.create_time); SBVAL(req->out.body, 0x10, io->smb2.out.access_time); SBVAL(req->out.body, 0x18, io->smb2.out.write_time); SBVAL(req->out.body, 0x20, io->smb2.out.change_time); SBVAL(req->out.body, 0x28, io->smb2.out.alloc_size); SBVAL(req->out.body, 0x30, io->smb2.out.size); SIVAL(req->out.body, 0x38, io->smb2.out.file_attr); smb2srv_send_reply(req); }
static void smb2srv_keepalive_send(struct smb2srv_request *req) { NTSTATUS status; if (NT_STATUS_IS_ERR(req->status)) { smb2srv_send_error(req, req->status); return; } status = smb2srv_setup_reply(req, 0x04, false, 0); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } SSVAL(req->out.body, 0x02, 0); smb2srv_send_reply(req); }
static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negprot *io) { NTSTATUS status; if (NT_STATUS_IS_ERR(req->status)) { smb2srv_send_error(req, req->status); /* TODO: is this correct? */ return; } status = smb2srv_setup_reply(req, 0x40, true, io->out.secblob.length); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } SSVAL(req->out.body, 0x02, io->out.security_mode); SIVAL(req->out.body, 0x04, io->out.dialect_revision); SIVAL(req->out.body, 0x06, io->out.reserved); status = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } SIVAL(req->out.body, 0x18, io->out.capabilities); SIVAL(req->out.body, 0x1C, io->out.max_transact_size); SIVAL(req->out.body, 0x20, io->out.max_read_size); SIVAL(req->out.body, 0x24, io->out.max_write_size); push_nttime(req->out.body, 0x28, io->out.system_time); push_nttime(req->out.body, 0x30, io->out.server_start_time); SIVAL(req->out.body, 0x3C, io->out.reserved2); status = smb2_push_o16s16_blob(&req->out, 0x38, io->out.secblob); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } smb2srv_send_reply(req); }
/**************************************************************************** Send an SMBecho (async send) *****************************************************************************/ _PUBLIC_ struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport, struct smb_echo *p) { struct smbcli_request *req; req = smbcli_request_setup_transport(transport, SMBecho, 1, p->in.size); if (!req) return NULL; SSVAL(req->out.vwv, VWV(0), p->in.repeat_count); memcpy(req->out.data, p->in.data, p->in.size); ZERO_STRUCT(p->out); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** start a message sequence ****************************************************************************/ int cli_message_start_build(struct cli_state *cli, char *host, char *username) { char *p; /* construct a SMBsendstrt command */ memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBsendstrt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; p += clistr_push(cli, p, username, -1, STR_ASCII|STR_TERMINATE); *p++ = 4; p += clistr_push(cli, p, host, -1, STR_ASCII|STR_TERMINATE); cli_setup_bcc(cli, p); return(PTR_DIFF(p, cli->outbuf)); }