xref: /onnv-gate/usr/src/lib/libsmbfs/smb/rq.c (revision 8271:792589b3384f)
16007Sthurlow /*
26007Sthurlow  * Copyright (c) 2000, Boris Popov
36007Sthurlow  * All rights reserved.
46007Sthurlow  *
56007Sthurlow  * Redistribution and use in source and binary forms, with or without
66007Sthurlow  * modification, are permitted provided that the following conditions
76007Sthurlow  * are met:
86007Sthurlow  * 1. Redistributions of source code must retain the above copyright
96007Sthurlow  *    notice, this list of conditions and the following disclaimer.
106007Sthurlow  * 2. Redistributions in binary form must reproduce the above copyright
116007Sthurlow  *    notice, this list of conditions and the following disclaimer in the
126007Sthurlow  *    documentation and/or other materials provided with the distribution.
136007Sthurlow  * 3. All advertising materials mentioning features or use of this software
146007Sthurlow  *    must display the following acknowledgement:
156007Sthurlow  *    This product includes software developed by Boris Popov.
166007Sthurlow  * 4. Neither the name of the author nor the names of any co-contributors
176007Sthurlow  *    may be used to endorse or promote products derived from this software
186007Sthurlow  *    without specific prior written permission.
196007Sthurlow  *
206007Sthurlow  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
216007Sthurlow  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
226007Sthurlow  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
236007Sthurlow  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
246007Sthurlow  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
256007Sthurlow  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
266007Sthurlow  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
276007Sthurlow  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
286007Sthurlow  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
296007Sthurlow  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
306007Sthurlow  * SUCH DAMAGE.
316007Sthurlow  *
326007Sthurlow  * $Id: rq.c,v 1.4 2004/12/13 00:25:23 lindak Exp $
336007Sthurlow  */
346007Sthurlow 
356007Sthurlow #include <sys/types.h>
366007Sthurlow #include <sys/param.h>
376007Sthurlow #include <sys/ioctl.h>
386007Sthurlow #include <sys/errno.h>
396007Sthurlow #include <sys/stat.h>
406007Sthurlow 
416007Sthurlow #include <ctype.h>
426007Sthurlow #include <errno.h>
436007Sthurlow #include <stdio.h>
446007Sthurlow #include <unistd.h>
456007Sthurlow #include <strings.h>
466007Sthurlow #include <stdlib.h>
476007Sthurlow #include <sysexits.h>
486007Sthurlow #include <libintl.h>
496007Sthurlow 
506007Sthurlow #include <netsmb/smb_lib.h>
51*8271SGordon.Ross@Sun.COM #include "private.h"
526007Sthurlow 
536007Sthurlow 
546007Sthurlow int
556007Sthurlow smb_rq_init(struct smb_ctx *ctx, uchar_t cmd, size_t rpbufsz,
566007Sthurlow     struct smb_rq **rqpp)
576007Sthurlow {
586007Sthurlow 	struct smb_rq *rqp;
596007Sthurlow 
606007Sthurlow 	rqp = malloc(sizeof (*rqp));
616007Sthurlow 	if (rqp == NULL)
626007Sthurlow 		return (ENOMEM);
636007Sthurlow 	bzero(rqp, sizeof (*rqp));
646007Sthurlow 	rqp->rq_cmd = cmd;
656007Sthurlow 	rqp->rq_ctx = ctx;
666007Sthurlow 	mb_init(&rqp->rq_rq, M_MINSIZE);
676007Sthurlow 	mb_init(&rqp->rq_rp, rpbufsz);
686007Sthurlow 	*rqpp = rqp;
696007Sthurlow 	return (0);
706007Sthurlow }
716007Sthurlow 
726007Sthurlow void
736007Sthurlow smb_rq_done(struct smb_rq *rqp)
746007Sthurlow {
756007Sthurlow 	mb_done(&rqp->rq_rp);
766007Sthurlow 	mb_done(&rqp->rq_rq);
776007Sthurlow 	free(rqp);
786007Sthurlow }
796007Sthurlow 
806007Sthurlow void
816007Sthurlow smb_rq_wend(struct smb_rq *rqp)
826007Sthurlow {
836007Sthurlow 	if (rqp->rq_rq.mb_count & 1)
846007Sthurlow 		smb_error(dgettext(TEXT_DOMAIN,
856007Sthurlow 		    "smbrq_wend: odd word count\n"), 0);
866007Sthurlow 	rqp->rq_wcount = rqp->rq_rq.mb_count / 2;
876007Sthurlow 	rqp->rq_rq.mb_count = 0;
886007Sthurlow }
896007Sthurlow 
906007Sthurlow int
916007Sthurlow smb_rq_dmem(struct mbdata *mbp, const char *src, size_t size)
926007Sthurlow {
936007Sthurlow 	struct mbuf *m;
946007Sthurlow 	char  *dst;
956007Sthurlow 	int cplen, error;
966007Sthurlow 
976007Sthurlow 	if (size == 0)
986007Sthurlow 		return (0);
996007Sthurlow 	m = mbp->mb_cur;
1006007Sthurlow 	if ((error = m_getm(m, size, &m)) != 0)
1016007Sthurlow 		return (error);
1026007Sthurlow 	while (size > 0) {
1036007Sthurlow 		cplen = M_TRAILINGSPACE(m);
1046007Sthurlow 		if (cplen == 0) {
1056007Sthurlow 			m = m->m_next;
1066007Sthurlow 			continue;
1076007Sthurlow 		}
1086007Sthurlow 		if (cplen > (int)size)
1096007Sthurlow 			cplen = size;
1106007Sthurlow 		dst = mtod(m, char *) + m->m_len;
1116007Sthurlow 		nls_mem_toext(dst, src, cplen);
1126007Sthurlow 		size -= cplen;
1136007Sthurlow 		src += cplen;
1146007Sthurlow 		m->m_len += cplen;
1156007Sthurlow 		mbp->mb_count += cplen;
1166007Sthurlow 	}
1176007Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
1186007Sthurlow 	mbp->mb_cur = m;
1196007Sthurlow 	return (0);
1206007Sthurlow }
1216007Sthurlow 
1226007Sthurlow int
1236007Sthurlow smb_rq_dstring(struct mbdata *mbp, const char *s)
1246007Sthurlow {
1256007Sthurlow 	return (smb_rq_dmem(mbp, s, strlen(s) + 1));
1266007Sthurlow }
1276007Sthurlow 
1286007Sthurlow int
1296007Sthurlow smb_rq_simple(struct smb_rq *rqp)
1306007Sthurlow {
1316007Sthurlow 	struct smbioc_rq krq;
1326007Sthurlow 	struct mbdata *mbp;
1336007Sthurlow 	char *data;
1346007Sthurlow 	int i;
1356007Sthurlow 
1366007Sthurlow 	mbp = smb_rq_getrequest(rqp);
1376007Sthurlow 	m_lineup(mbp->mb_top, &mbp->mb_top);
1386007Sthurlow 	data = mtod(mbp->mb_top, char *);
1396007Sthurlow 	bzero(&krq, sizeof (krq));
1406007Sthurlow 	krq.ioc_cmd = rqp->rq_cmd;
1416007Sthurlow 	krq.ioc_twc = rqp->rq_wcount;
1426007Sthurlow 	krq.ioc_twords = data;
1436007Sthurlow 	krq.ioc_tbc = mbp->mb_count;
1446007Sthurlow 	krq.ioc_tbytes = data + rqp->rq_wcount * 2;
1456007Sthurlow 
1466007Sthurlow 	mbp = smb_rq_getreply(rqp);
1476007Sthurlow 	krq.ioc_rpbufsz = mbp->mb_top->m_maxlen;
1486007Sthurlow 	krq.ioc_rpbuf = mtod(mbp->mb_top, char *);
1496007Sthurlow 	if (ioctl(rqp->rq_ctx->ct_fd, SMBIOC_REQUEST, &krq) == -1) {
1506007Sthurlow 		return (errno);
1516007Sthurlow 	}
1526007Sthurlow 	mbp->mb_top->m_len = krq.ioc_rwc * 2 + krq.ioc_rbc;
1536007Sthurlow 	rqp->rq_wcount = krq.ioc_rwc;
1546007Sthurlow 	rqp->rq_bcount = krq.ioc_rbc;
1556007Sthurlow 	return (0);
1566007Sthurlow }
1576007Sthurlow 
1586007Sthurlow 
1596007Sthurlow int
1606007Sthurlow smb_t2_request(struct smb_ctx *ctx, int setupcount, uint16_t *setup,
1616007Sthurlow 	const char *name,
1626007Sthurlow 	int tparamcnt, void *tparam,
1636007Sthurlow 	int tdatacnt, void *tdata,
1646007Sthurlow 	int *rparamcnt, void *rparam,
1656007Sthurlow 	int *rdatacnt, void *rdata,
1666007Sthurlow 	int *buffer_oflow)
1676007Sthurlow {
1686007Sthurlow 	smbioc_t2rq_t *krq;
1696007Sthurlow 	int i;
1706007Sthurlow 	char *pass;
1716007Sthurlow 
1726007Sthurlow 
1736007Sthurlow 	krq = (smbioc_t2rq_t *)malloc(sizeof (smbioc_t2rq_t));
1746007Sthurlow 	bzero(krq, sizeof (*krq));
1756007Sthurlow 
1766007Sthurlow 	if (setupcount < 0 || setupcount >= SMB_MAXSETUPWORDS) {
1776007Sthurlow 		/* Bogus setup count, or too many setup words */
1786007Sthurlow 		return (EINVAL);
1796007Sthurlow 	}
1806007Sthurlow 	for (i = 0; i < setupcount; i++)
1816007Sthurlow 		krq->ioc_setup[i] = setup[i];
1826007Sthurlow 	krq->ioc_setupcnt = setupcount;
1836007Sthurlow 	strcpy(krq->ioc_name, name);
1846007Sthurlow 	krq->ioc_tparamcnt = tparamcnt;
1856007Sthurlow 	krq->ioc_tparam = tparam;
1866007Sthurlow 	krq->ioc_tdatacnt = tdatacnt;
1876007Sthurlow 	krq->ioc_tdata = tdata;
1886007Sthurlow 
1896007Sthurlow 	krq->ioc_rparamcnt = *rparamcnt;
1906007Sthurlow 	krq->ioc_rdatacnt = *rdatacnt;
1916007Sthurlow 	krq->ioc_rparam = rparam;
1926007Sthurlow 	krq->ioc_rdata  = rdata;
1936007Sthurlow 
1946007Sthurlow 	if (ioctl(ctx->ct_fd, SMBIOC_T2RQ, krq) == -1) {
1956007Sthurlow 		return (errno);
1966007Sthurlow 	}
1976007Sthurlow 
1986007Sthurlow 	*rparamcnt = krq->ioc_rparamcnt;
1996007Sthurlow 	*rdatacnt = krq->ioc_rdatacnt;
2006007Sthurlow 	*buffer_oflow = (krq->ioc_rpflags2 & SMB_FLAGS2_ERR_STATUS) &&
2016007Sthurlow 	    (krq->ioc_error == NT_STATUS_BUFFER_OVERFLOW);
2026007Sthurlow 	free(krq);
2036007Sthurlow 	return (0);
2046007Sthurlow }
205