Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #5
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);
}
Beispiel #6
0
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;
}
Beispiel #7
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #10
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;
}
Beispiel #11
0
/*
 * 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);
}
Beispiel #12
0
/*
 * 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);
}