xref: /titanic_51/usr/src/lib/libsmbfs/smb/rq.c (revision 9c9af2590af49bb395bc8d2eace0f2d4ea16d165)
14bff34e3Sthurlow /*
24bff34e3Sthurlow  * Copyright (c) 2000, Boris Popov
34bff34e3Sthurlow  * All rights reserved.
44bff34e3Sthurlow  *
54bff34e3Sthurlow  * Redistribution and use in source and binary forms, with or without
64bff34e3Sthurlow  * modification, are permitted provided that the following conditions
74bff34e3Sthurlow  * are met:
84bff34e3Sthurlow  * 1. Redistributions of source code must retain the above copyright
94bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer.
104bff34e3Sthurlow  * 2. Redistributions in binary form must reproduce the above copyright
114bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer in the
124bff34e3Sthurlow  *    documentation and/or other materials provided with the distribution.
134bff34e3Sthurlow  * 3. All advertising materials mentioning features or use of this software
144bff34e3Sthurlow  *    must display the following acknowledgement:
154bff34e3Sthurlow  *    This product includes software developed by Boris Popov.
164bff34e3Sthurlow  * 4. Neither the name of the author nor the names of any co-contributors
174bff34e3Sthurlow  *    may be used to endorse or promote products derived from this software
184bff34e3Sthurlow  *    without specific prior written permission.
194bff34e3Sthurlow  *
204bff34e3Sthurlow  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
214bff34e3Sthurlow  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
224bff34e3Sthurlow  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234bff34e3Sthurlow  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
244bff34e3Sthurlow  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254bff34e3Sthurlow  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
264bff34e3Sthurlow  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274bff34e3Sthurlow  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
284bff34e3Sthurlow  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
294bff34e3Sthurlow  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
304bff34e3Sthurlow  * SUCH DAMAGE.
314bff34e3Sthurlow  *
324bff34e3Sthurlow  * $Id: rq.c,v 1.4 2004/12/13 00:25:23 lindak Exp $
334bff34e3Sthurlow  */
344bff34e3Sthurlow 
354bff34e3Sthurlow #include <sys/types.h>
364bff34e3Sthurlow #include <sys/param.h>
374bff34e3Sthurlow #include <sys/ioctl.h>
384bff34e3Sthurlow #include <sys/errno.h>
394bff34e3Sthurlow #include <sys/stat.h>
404bff34e3Sthurlow 
414bff34e3Sthurlow #include <ctype.h>
424bff34e3Sthurlow #include <errno.h>
434bff34e3Sthurlow #include <stdio.h>
444bff34e3Sthurlow #include <unistd.h>
454bff34e3Sthurlow #include <strings.h>
464bff34e3Sthurlow #include <stdlib.h>
474bff34e3Sthurlow #include <sysexits.h>
484bff34e3Sthurlow #include <libintl.h>
494bff34e3Sthurlow 
504bff34e3Sthurlow #include <netsmb/smb_lib.h>
51*9c9af259SGordon Ross #include "private.h"
524bff34e3Sthurlow 
534bff34e3Sthurlow 
544bff34e3Sthurlow int
554bff34e3Sthurlow smb_rq_init(struct smb_ctx *ctx, uchar_t cmd, size_t rpbufsz,
564bff34e3Sthurlow     struct smb_rq **rqpp)
574bff34e3Sthurlow {
584bff34e3Sthurlow 	struct smb_rq *rqp;
594bff34e3Sthurlow 
604bff34e3Sthurlow 	rqp = malloc(sizeof (*rqp));
614bff34e3Sthurlow 	if (rqp == NULL)
624bff34e3Sthurlow 		return (ENOMEM);
634bff34e3Sthurlow 	bzero(rqp, sizeof (*rqp));
644bff34e3Sthurlow 	rqp->rq_cmd = cmd;
654bff34e3Sthurlow 	rqp->rq_ctx = ctx;
664bff34e3Sthurlow 	mb_init(&rqp->rq_rq, M_MINSIZE);
674bff34e3Sthurlow 	mb_init(&rqp->rq_rp, rpbufsz);
684bff34e3Sthurlow 	*rqpp = rqp;
694bff34e3Sthurlow 	return (0);
704bff34e3Sthurlow }
714bff34e3Sthurlow 
724bff34e3Sthurlow void
734bff34e3Sthurlow smb_rq_done(struct smb_rq *rqp)
744bff34e3Sthurlow {
754bff34e3Sthurlow 	mb_done(&rqp->rq_rp);
764bff34e3Sthurlow 	mb_done(&rqp->rq_rq);
774bff34e3Sthurlow 	free(rqp);
784bff34e3Sthurlow }
794bff34e3Sthurlow 
804bff34e3Sthurlow void
814bff34e3Sthurlow smb_rq_wend(struct smb_rq *rqp)
824bff34e3Sthurlow {
834bff34e3Sthurlow 	if (rqp->rq_rq.mb_count & 1)
844bff34e3Sthurlow 		smb_error(dgettext(TEXT_DOMAIN,
854bff34e3Sthurlow 		    "smbrq_wend: odd word count\n"), 0);
864bff34e3Sthurlow 	rqp->rq_wcount = rqp->rq_rq.mb_count / 2;
874bff34e3Sthurlow 	rqp->rq_rq.mb_count = 0;
884bff34e3Sthurlow }
894bff34e3Sthurlow 
904bff34e3Sthurlow int
914bff34e3Sthurlow smb_rq_dmem(struct mbdata *mbp, const char *src, size_t size)
924bff34e3Sthurlow {
934bff34e3Sthurlow 	struct mbuf *m;
944bff34e3Sthurlow 	char  *dst;
954bff34e3Sthurlow 	int cplen, error;
964bff34e3Sthurlow 
974bff34e3Sthurlow 	if (size == 0)
984bff34e3Sthurlow 		return (0);
994bff34e3Sthurlow 	m = mbp->mb_cur;
1004bff34e3Sthurlow 	if ((error = m_getm(m, size, &m)) != 0)
1014bff34e3Sthurlow 		return (error);
1024bff34e3Sthurlow 	while (size > 0) {
1034bff34e3Sthurlow 		cplen = M_TRAILINGSPACE(m);
1044bff34e3Sthurlow 		if (cplen == 0) {
1054bff34e3Sthurlow 			m = m->m_next;
1064bff34e3Sthurlow 			continue;
1074bff34e3Sthurlow 		}
1084bff34e3Sthurlow 		if (cplen > (int)size)
1094bff34e3Sthurlow 			cplen = size;
1104bff34e3Sthurlow 		dst = mtod(m, char *) + m->m_len;
1114bff34e3Sthurlow 		nls_mem_toext(dst, src, cplen);
1124bff34e3Sthurlow 		size -= cplen;
1134bff34e3Sthurlow 		src += cplen;
1144bff34e3Sthurlow 		m->m_len += cplen;
1154bff34e3Sthurlow 		mbp->mb_count += cplen;
1164bff34e3Sthurlow 	}
1174bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
1184bff34e3Sthurlow 	mbp->mb_cur = m;
1194bff34e3Sthurlow 	return (0);
1204bff34e3Sthurlow }
1214bff34e3Sthurlow 
1224bff34e3Sthurlow int
1234bff34e3Sthurlow smb_rq_dstring(struct mbdata *mbp, const char *s)
1244bff34e3Sthurlow {
1254bff34e3Sthurlow 	return (smb_rq_dmem(mbp, s, strlen(s) + 1));
1264bff34e3Sthurlow }
1274bff34e3Sthurlow 
1284bff34e3Sthurlow int
1294bff34e3Sthurlow smb_rq_simple(struct smb_rq *rqp)
1304bff34e3Sthurlow {
1314bff34e3Sthurlow 	struct smbioc_rq krq;
1324bff34e3Sthurlow 	struct mbdata *mbp;
1334bff34e3Sthurlow 	char *data;
1344bff34e3Sthurlow 	int i;
1354bff34e3Sthurlow 
1364bff34e3Sthurlow 	mbp = smb_rq_getrequest(rqp);
1374bff34e3Sthurlow 	m_lineup(mbp->mb_top, &mbp->mb_top);
1384bff34e3Sthurlow 	data = mtod(mbp->mb_top, char *);
1394bff34e3Sthurlow 	bzero(&krq, sizeof (krq));
1404bff34e3Sthurlow 	krq.ioc_cmd = rqp->rq_cmd;
1414bff34e3Sthurlow 	krq.ioc_twc = rqp->rq_wcount;
1424bff34e3Sthurlow 	krq.ioc_twords = data;
1434bff34e3Sthurlow 	krq.ioc_tbc = mbp->mb_count;
1444bff34e3Sthurlow 	krq.ioc_tbytes = data + rqp->rq_wcount * 2;
1454bff34e3Sthurlow 
1464bff34e3Sthurlow 	mbp = smb_rq_getreply(rqp);
1474bff34e3Sthurlow 	krq.ioc_rpbufsz = mbp->mb_top->m_maxlen;
1484bff34e3Sthurlow 	krq.ioc_rpbuf = mtod(mbp->mb_top, char *);
1494bff34e3Sthurlow 	if (ioctl(rqp->rq_ctx->ct_fd, SMBIOC_REQUEST, &krq) == -1) {
1504bff34e3Sthurlow 		return (errno);
1514bff34e3Sthurlow 	}
1524bff34e3Sthurlow 	mbp->mb_top->m_len = krq.ioc_rwc * 2 + krq.ioc_rbc;
1534bff34e3Sthurlow 	rqp->rq_wcount = krq.ioc_rwc;
1544bff34e3Sthurlow 	rqp->rq_bcount = krq.ioc_rbc;
1554bff34e3Sthurlow 	return (0);
1564bff34e3Sthurlow }
1574bff34e3Sthurlow 
1584bff34e3Sthurlow 
1594bff34e3Sthurlow int
1604bff34e3Sthurlow smb_t2_request(struct smb_ctx *ctx, int setupcount, uint16_t *setup,
1614bff34e3Sthurlow 	const char *name,
1624bff34e3Sthurlow 	int tparamcnt, void *tparam,
1634bff34e3Sthurlow 	int tdatacnt, void *tdata,
1644bff34e3Sthurlow 	int *rparamcnt, void *rparam,
1654bff34e3Sthurlow 	int *rdatacnt, void *rdata,
1664bff34e3Sthurlow 	int *buffer_oflow)
1674bff34e3Sthurlow {
1684bff34e3Sthurlow 	smbioc_t2rq_t *krq;
1694bff34e3Sthurlow 	int i;
1704bff34e3Sthurlow 	char *pass;
1714bff34e3Sthurlow 
1724bff34e3Sthurlow 
1734bff34e3Sthurlow 	krq = (smbioc_t2rq_t *)malloc(sizeof (smbioc_t2rq_t));
1744bff34e3Sthurlow 	bzero(krq, sizeof (*krq));
1754bff34e3Sthurlow 
1764bff34e3Sthurlow 	if (setupcount < 0 || setupcount >= SMB_MAXSETUPWORDS) {
1774bff34e3Sthurlow 		/* Bogus setup count, or too many setup words */
1784bff34e3Sthurlow 		return (EINVAL);
1794bff34e3Sthurlow 	}
1804bff34e3Sthurlow 	for (i = 0; i < setupcount; i++)
1814bff34e3Sthurlow 		krq->ioc_setup[i] = setup[i];
1824bff34e3Sthurlow 	krq->ioc_setupcnt = setupcount;
1834bff34e3Sthurlow 	strcpy(krq->ioc_name, name);
1844bff34e3Sthurlow 	krq->ioc_tparamcnt = tparamcnt;
1854bff34e3Sthurlow 	krq->ioc_tparam = tparam;
1864bff34e3Sthurlow 	krq->ioc_tdatacnt = tdatacnt;
1874bff34e3Sthurlow 	krq->ioc_tdata = tdata;
1884bff34e3Sthurlow 
1894bff34e3Sthurlow 	krq->ioc_rparamcnt = *rparamcnt;
1904bff34e3Sthurlow 	krq->ioc_rdatacnt = *rdatacnt;
1914bff34e3Sthurlow 	krq->ioc_rparam = rparam;
1924bff34e3Sthurlow 	krq->ioc_rdata  = rdata;
1934bff34e3Sthurlow 
1944bff34e3Sthurlow 	if (ioctl(ctx->ct_fd, SMBIOC_T2RQ, krq) == -1) {
1954bff34e3Sthurlow 		return (errno);
1964bff34e3Sthurlow 	}
1974bff34e3Sthurlow 
1984bff34e3Sthurlow 	*rparamcnt = krq->ioc_rparamcnt;
1994bff34e3Sthurlow 	*rdatacnt = krq->ioc_rdatacnt;
2004bff34e3Sthurlow 	*buffer_oflow = (krq->ioc_rpflags2 & SMB_FLAGS2_ERR_STATUS) &&
2014bff34e3Sthurlow 	    (krq->ioc_error == NT_STATUS_BUFFER_OVERFLOW);
2024bff34e3Sthurlow 	free(krq);
2034bff34e3Sthurlow 	return (0);
2044bff34e3Sthurlow }
205