static int smb_rq_new(struct smb_rq *rqp, u_char cmd) { struct smb_vc *vcp = rqp->sr_vc; struct mbchain *mbp = &rqp->sr_rq; int error; rqp->sr_sendcnt = 0; mb_done(mbp); md_done(&rqp->sr_rp); error = mb_init(mbp); if (error) return error; mb_put_mem(mbp, SMB_SIGNATURE, SMB_SIGLEN, MB_MSYSTEM); mb_put_uint8(mbp, cmd); mb_put_uint32le(mbp, 0); /* DosError */ mb_put_uint8(mbp, vcp->vc_hflags); mb_put_uint16le(mbp, vcp->vc_hflags2); mb_put_mem(mbp, tzero, 12, MB_MSYSTEM); rqp->sr_rqtid = (u_int16_t*)mb_reserve(mbp, sizeof(u_int16_t)); mb_put_uint16le(mbp, 1 /*scred->sc_p->p_pid & 0xffff*/); rqp->sr_rquid = (u_int16_t*)mb_reserve(mbp, sizeof(u_int16_t)); mb_put_uint16le(mbp, rqp->sr_mid); return 0; }
static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv) { struct mbuf *mb; struct ethhdr *ethh; unsigned char *packet; unsigned int packet_size = MLX4_LOOPBACK_TEST_PAYLOAD; unsigned int i; int err; /* build the pkt before xmit */ mb = netdev_alloc_mb(priv->dev, MLX4_LOOPBACK_TEST_PAYLOAD + ETH_HLEN + NET_IP_ALIGN); if (!mb) { en_err(priv, "-LOOPBACK_TEST_XMIT- failed to create mb for xmit\n"); return -ENOMEM; } mb_reserve(mb, NET_IP_ALIGN); ethh = (struct ethhdr *)mb_put(mb, sizeof(struct ethhdr)); packet = (unsigned char *)mb_put(mb, packet_size); memcpy(ethh->h_dest, priv->dev->dev_addr, ETH_ALEN); memset(ethh->h_source, 0, ETH_ALEN); ethh->h_proto = htons(ETH_P_ARP); mb_set_mac_header(mb, 0); for (i = 0; i < packet_size; ++i) /* fill our packet */ packet[i] = (unsigned char)(i & 0xff); /* xmit the pkt */ err = mlx4_en_xmit(mb, priv->dev); return err; }
static int mb_put_acl(mbchain_t *mbp, i_ntacl_t *acl) { i_ntace_t **acep; uint16_t acl_len, *acl_len_p; int i, cnt0, error; cnt0 = mbp->mb_count; ERRCHK(mb_put_uint8(mbp, acl->acl_revision)); ERRCHK(mb_put_uint8(mbp, 0)); /* pad1 */ acl_len_p = mb_reserve(mbp, sizeof (*acl_len_p)); if (acl_len_p == NULL) { error = ENOMEM; goto errout; } ERRCHK(mb_put_uint16le(mbp, acl->acl_acecount)); ERRCHK(mb_put_uint16le(mbp, 0)); /* pad2 */ acep = &acl->acl_acevec[0]; for (i = 0; i < acl->acl_acecount; i++) { ERRCHK(mb_put_ace(mbp, *acep)); acep++; } /* Fill in acl_len_p */ acl_len = mbp->mb_count - cnt0; *acl_len_p = htoles(acl_len); /* Success! */ return (0); errout: return (error); }
static int smb_rq_new(struct smb_rq *rqp, u_char cmd) { struct smb_vc *vcp = rqp->sr_vc; struct mbchain *mbp = &rqp->sr_rq; int error; u_int16_t flags2; rqp->sr_sendcnt = 0; mb_done(mbp); md_done(&rqp->sr_rp); error = mb_init(mbp); if (error) return error; mb_put_mem(mbp, SMB_SIGNATURE, SMB_SIGLEN, MB_MSYSTEM); mb_put_uint8(mbp, cmd); mb_put_uint32le(mbp, 0); /* DosError */ mb_put_uint8(mbp, vcp->vc_hflags); flags2 = vcp->vc_hflags2; if (cmd == SMB_COM_TRANSACTION || cmd == SMB_COM_TRANSACTION_SECONDARY) flags2 &= ~SMB_FLAGS2_UNICODE; if (cmd == SMB_COM_NEGOTIATE) flags2 &= ~SMB_FLAGS2_SECURITY_SIGNATURE; mb_put_uint16le(mbp, flags2); if ((flags2 & SMB_FLAGS2_SECURITY_SIGNATURE) == 0) { mb_put_mem(mbp, tzero, 12, MB_MSYSTEM); rqp->sr_rqsig = NULL; } else { mb_put_uint16le(mbp, 0 /*scred->sc_p->p_pid >> 16*/); rqp->sr_rqsig = (u_int8_t *)mb_reserve(mbp, 8); mb_put_uint16le(mbp, 0); } rqp->sr_rqtid = mb_reserve(mbp, sizeof(u_int16_t)); mb_put_uint16le(mbp, 1 /*scred->sc_p->p_pid & 0xffff*/); rqp->sr_rquid = mb_reserve(mbp, sizeof(u_int16_t)); mb_put_uint16le(mbp, rqp->sr_mid); return 0; }
static int mb_put_ace(mbchain_t *mbp, i_ntace_t *ace) { int cnt0, error; uint16_t ace_len, *ace_len_p; if (ace == NULL) return (EINVAL); cnt0 = mbp->mb_count; /* * Put the (fixed-size) ACE header * Will fill in the length later. */ ERRCHK(mb_put_uint8(mbp, ace->ace_hdr.ace_type)); ERRCHK(mb_put_uint8(mbp, ace->ace_hdr.ace_flags)); ace_len_p = mb_reserve(mbp, sizeof (*ace_len_p)); if (ace_len_p == NULL) { error = ENOMEM; goto errout; } switch (ace->ace_hdr.ace_type) { case ACCESS_ALLOWED_ACE_TYPE: case ACCESS_DENIED_ACE_TYPE: case SYSTEM_AUDIT_ACE_TYPE: case SYSTEM_ALARM_ACE_TYPE: /* Put type-specific data. */ ERRCHK(mb_put_uint32le(mbp, ace->ace_v2.ace_rights)); ERRCHK(mb_put_sid(mbp, ace->ace_v2.ace_sid)); break; /* other types todo */ default: error = EIO; goto errout; } /* Fill in the (OtW) ACE length. */ ace_len = mbp->mb_count - cnt0; *ace_len_p = htoles(ace_len); /* Success! */ return (0); errout: return (error); }
int ncp_rq_init_any(struct ncp_rq *rqp, u_int32_t ptype, u_int8_t fn, struct ncp_conn *ncp, struct thread *td, struct ucred *cred) { struct ncp_rqhdr *rq; struct ncp_bursthdr *brq; struct mbchain *mbp; int error; bzero(rqp, sizeof(*rqp)); error = ncp_conn_access(ncp, cred, NCPM_EXECUTE); if (error) return error; rqp->nr_td = td; rqp->nr_cred = cred; rqp->nr_conn = ncp; mbp = &rqp->rq; if (mb_init(mbp) != 0) return ENOBUFS; switch(ptype) { case NCP_PACKET_BURST: brq = (struct ncp_bursthdr*)mb_reserve(mbp, sizeof(*brq)); brq->bh_type = ptype; brq->bh_streamtype = 0x2; break; default: rq = (struct ncp_rqhdr*)mb_reserve(mbp, sizeof(*rq)); rq->type = ptype; rq->seq = 0; /* filled later */ rq->fn = fn; break; } rqp->nr_minrplen = -1; return 0; }
int ncp_rq_alloc_subfn(u_int8_t fn, u_int8_t subfn, struct ncp_conn *ncp, struct thread *td, struct ucred *cred, struct ncp_rq **rqpp) { struct ncp_rq *rqp; int error; error = ncp_rq_alloc_any(NCP_REQUEST, fn, ncp, td, cred, &rqp); if (error) return error; mb_reserve(&rqp->rq, 2); mb_put_uint8(&rqp->rq, subfn); *rqpp = rqp; return 0; }
void smb_rq_bstart(struct smb_rq *rqp) { rqp->sr_bcount = mb_reserve(&rqp->sr_rq, sizeof(u_short)); rqp->sr_rq.mb_count = 0; }
void smb_rq_wstart(struct smb_rq *rqp) { rqp->sr_wcount = mb_reserve(&rqp->sr_rq, sizeof(u_int8_t)); rqp->sr_rq.mb_count = 0; }
/* * Generic routine that handles open/creates. */ int smbio_ntcreatex(void *smbctx, const char *path, const char *streamName, struct open_inparms *inparms, struct open_outparm *outparms, int *fid) { uint16_t *namelenp; struct smb_usr_rq *rqp; mbchain_t mbp; mdchain_t mdp; uint8_t wc; size_t nmlen; int error; u_int16_t fid16; /* * Since the reply will fit in one mbuf, pass zero which will cause a normal * mbuf to get created. */ error = smb_usr_rq_init(smbctx, SMB_COM_NT_CREATE_ANDX, 0, &rqp); if (error != 0) { return error; } mbp = smb_usr_rq_getrequest(rqp); smb_usr_rq_wstart(rqp); mb_put_uint8(mbp, 0xff); /* secondary command */ mb_put_uint8(mbp, 0); /* MBZ */ mb_put_uint16le(mbp, 0); /* offset to next command (none) */ mb_put_uint8(mbp, 0); /* MBZ */ namelenp = (uint16_t *)mb_reserve(mbp, sizeof(uint16_t)); /* * XP to W2K Server never sets the NTCREATEX_FLAGS_OPEN_DIRECTORY * for creating nor for opening a directory. Samba ignores the bit. * * Request the extended reply to get maximal access */ mb_put_uint32le(mbp, NTCREATEX_FLAGS_EXTENDED); /* NTCREATEX_FLAGS_* */ mb_put_uint32le(mbp, 0); /* FID - basis for path if not root */ mb_put_uint32le(mbp, inparms->rights); mb_put_uint64le(mbp, inparms->allocSize); /* "initial allocation size" */ mb_put_uint32le(mbp, inparms->attrs); /* attributes */ mb_put_uint32le(mbp, inparms->shareMode); mb_put_uint32le(mbp, inparms->disp); mb_put_uint32le(mbp, inparms->createOptions); mb_put_uint32le(mbp, NTCREATEX_IMPERSONATION_IMPERSONATION); /* (?) */ mb_put_uint8(mbp, 0); /* security flags (?) */ smb_usr_rq_wend(rqp); smb_usr_rq_bstart(rqp); nmlen = 0; if (streamName) { size_t snmlen = 0; error = smb_usr_put_dmem(smbctx, mbp, path, strlen(path), SMB_UTF_SFM_CONVERSIONS | SMB_FULLPATH_CONVERSIONS, &nmlen); if (!error) { /* Make sure the stream name starts with a colon */ if (*streamName != ':') { mb_put_uint16le(mbp, ':'); nmlen += 2; } error = smb_usr_rq_put_dstring(smbctx, mbp, streamName, strlen(streamName), NO_SFM_CONVERSIONS, &snmlen); } nmlen += snmlen; } else { error = smb_usr_rq_put_dstring(smbctx, mbp, path, strlen(path), SMB_UTF_SFM_CONVERSIONS | SMB_FULLPATH_CONVERSIONS, &nmlen); } if (error) { smb_log_info("%s: smb_usr_rq_put_dstring failed syserr = %s", ASL_LEVEL_DEBUG, __FUNCTION__, strerror(error)); goto done; } /* Now the network name length into the reserved location */ *namelenp = htoles((uint16_t)nmlen); smb_usr_rq_bend(rqp); error = smb_usr_rq_simple(rqp); if (error != 0) { smb_log_info("%s: smb_usr_rq_simple failed, syserr = %s", ASL_LEVEL_DEBUG, __FUNCTION__, strerror(error)); goto done; } mdp = smb_usr_rq_getreply(rqp); /* * Spec say 26 for word count, but 34 words are defined and observed from * all servers. * * The spec is wrong and word count should always be 34 unless we request * the extended reply. Now some server will always return 42 even it the * NTCREATEX_FLAGS_EXTENDED flag is not set. * * From the MS-SMB document concern the extend response: * * The word count for this response MUST be 0x2A (42). WordCount in this * case is not used as the count of parameter words but is just a number. */ if (md_get_uint8(mdp, &wc) != 0 || ((wc != NTCREATEX_NORMAL_WDCNT) && (wc != NTCREATEX_EXTENDED_WDCNT))) { error = EIO; smb_log_info("%s: bad word count, syserr = %s", ASL_LEVEL_DEBUG, __FUNCTION__, strerror(error)); goto done; } md_get_uint8(mdp, NULL); /* secondary cmd */ md_get_uint8(mdp, NULL); /* mbz */ md_get_uint16le(mdp, NULL); /* andxoffset */ md_get_uint8(mdp, NULL); /* oplock lvl granted */ md_get_uint16le(mdp, &fid16); /* FID */ *fid = fid16; error = md_get_uint32le(mdp, NULL); /* create_action */ /* Only get the rest of the parameter values if they want request them */ if (outparms) { /* Should we convert the time, current we don't */ md_get_uint64le(mdp, &outparms->createTime); md_get_uint64le(mdp, &outparms->accessTime); md_get_uint64le(mdp, &outparms->writeTime); md_get_uint64le(mdp, &outparms->changeTime); md_get_uint32le(mdp, &outparms->attributes); md_get_uint64le(mdp, &outparms->allocationSize); md_get_uint64le(mdp, &outparms->fileSize); md_get_uint16le(mdp, NULL); /* file type */ md_get_uint16le(mdp, NULL); /* device state */ error = md_get_uint8(mdp, NULL); /* directory (boolean) */ /* Supports extended word count, so lets get them */ if (wc == NTCREATEX_EXTENDED_WDCNT) { md_get_mem(mdp, (caddr_t)outparms->volumeGID, sizeof(outparms->volumeGID), MB_MSYSTEM); md_get_uint64le(mdp, &outparms->fileInode); md_get_uint32le(mdp, &outparms->maxAccessRights); error = md_get_uint32le(mdp, &outparms->maxGuessAccessRights); } } done: smb_usr_rq_done(rqp); return error; }
/* * Export an "internal" SD into an raw SD (mb chain). * (a.k.a "self-relative" form per. NT docs) * Returns allocated mbchain in mbp. */ int mb_put_ntsd(mbchain_t *mbp, i_ntsd_t *sd) { uint32_t *owneroffp, *groupoffp, *sacloffp, *dacloffp; uint32_t owneroff, groupoff, sacloff, dacloff; uint16_t flags; int cnt0, error; cnt0 = mbp->mb_count; owneroff = groupoff = sacloff = dacloff = 0; /* The SD is "self-relative" on the wire. */ flags = sd->sd_flags | SD_SELF_RELATIVE; ERRCHK(mb_put_uint8(mbp, sd->sd_revision)); ERRCHK(mb_put_uint8(mbp, sd->sd_rmctl)); ERRCHK(mb_put_uint16le(mbp, flags)); owneroffp = mb_reserve(mbp, sizeof (*owneroffp)); groupoffp = mb_reserve(mbp, sizeof (*groupoffp)); sacloffp = mb_reserve(mbp, sizeof (*sacloffp)); dacloffp = mb_reserve(mbp, sizeof (*dacloffp)); if (owneroffp == NULL || groupoffp == NULL || sacloffp == NULL || dacloffp == NULL) { error = ENOMEM; goto errout; } /* * These could be marshalled in any order, but * are normally found in the order shown here. */ if (sd->sd_sacl) { sacloff = mbp->mb_count - cnt0; ERRCHK(mb_put_acl(mbp, sd->sd_sacl)); } if (sd->sd_dacl) { dacloff = mbp->mb_count - cnt0; ERRCHK(mb_put_acl(mbp, sd->sd_dacl)); } if (sd->sd_owner) { owneroff = mbp->mb_count - cnt0; ERRCHK(mb_put_sid(mbp, sd->sd_owner)); } if (sd->sd_group) { groupoff = mbp->mb_count - cnt0; ERRCHK(mb_put_sid(mbp, sd->sd_group)); } /* Fill in the offsets */ *owneroffp = htolel(owneroff); *groupoffp = htolel(groupoff); *sacloffp = htolel(sacloff); *dacloffp = htolel(dacloff); /* Success! */ return (0); errout: return (error); }
/* * This call is used to fetch FID for directories. For normal files, * SMB_COM_OPEN is used. */ int smbfs_smb_ntcreatex(struct smbnode *np, int accmode, struct smb_cred *scred) { struct smb_rq *rqp; struct smb_share *ssp = np->n_mount->sm_share; struct mbchain *mbp; struct mdchain *mdp; int error; u_int8_t wc; u_int8_t *nmlen; u_int16_t flen; KASSERT(SMBTOV(np)->v_type == VDIR); error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_NT_CREATE_ANDX, scred, &rqp); if (error) return error; smb_rq_getrequest(rqp, &mbp); smb_rq_wstart(rqp); mb_put_uint8(mbp, 0xff); /* Secondary command; 0xFF = None */ mb_put_uint8(mbp, 0); /* Reserved (must be 0) */ mb_put_uint16le(mbp, 0); /* Off to next cmd WordCount */ mb_put_uint8(mbp, 0); /* Reserved (must be 0) */ nmlen = mb_reserve(mbp, sizeof(u_int16_t)); /* Length of Name[] in bytes */ mb_put_uint32le(mbp, SMB_FL_CANONICAL_PATHNAMES); /* Flags - Create bit set */ mb_put_uint32le(mbp, 0); /* If nonzero, open relative to this */ mb_put_uint32le(mbp, NT_FILE_LIST_DIRECTORY); /* Access mask */ mb_put_uint32le(mbp, 0); /* Low 32bit */ mb_put_uint32le(mbp, 0); /* Hi 32bit */ /* Initial allocation size */ mb_put_uint32le(mbp, 0); /* File attributes */ mb_put_uint32le(mbp, NT_FILE_SHARE_READ|NT_FILE_SHARE_WRITE); /* Type of share access */ mb_put_uint32le(mbp, NT_OPEN_EXISTING); /* Create disposition - just open */ mb_put_uint32le(mbp, NT_FILE_DIRECTORY_FILE); /* Options to use if creating a file */ mb_put_uint32le(mbp, 0); /* Security QOS information */ mb_put_uint8(mbp, 0); /* Security tracking mode flags */ smb_rq_wend(rqp); smb_rq_bstart(rqp); error = smbfs_fullpath(mbp, SSTOVC(ssp), np, NULL, 0); if (error) return error; /* Windows XP seems to include the final zero. Better do that too. */ mb_put_uint8(mbp, 0); flen = mbp->mb_count; SMBRQ_PUTLE16(nmlen, flen); smb_rq_bend(rqp); error = smb_rq_simple(rqp); if (error) goto bad; smb_rq_getreply(rqp, &mdp); md_get_uint8(mdp, &wc); /* WordCount - check? */ md_get_uint8(mdp, NULL); /* AndXCommand */ md_get_uint8(mdp, NULL); /* Reserved - must be zero */ md_get_uint16(mdp, NULL); /* Offset to next cmd WordCount */ md_get_uint8(mdp, NULL); /* Oplock level granted */ md_get_uint16(mdp, &np->n_fid); /* FID */ /* ignore rest */ bad: smb_rq_done(rqp); return (error); }