xref: /titanic_51/usr/src/lib/libsmbfs/smb/rq.c (revision 4bff34e37def8a90f9194d81bc345c52ba20086a)
1*4bff34e3Sthurlow /*
2*4bff34e3Sthurlow  * Copyright (c) 2000, Boris Popov
3*4bff34e3Sthurlow  * All rights reserved.
4*4bff34e3Sthurlow  *
5*4bff34e3Sthurlow  * Redistribution and use in source and binary forms, with or without
6*4bff34e3Sthurlow  * modification, are permitted provided that the following conditions
7*4bff34e3Sthurlow  * are met:
8*4bff34e3Sthurlow  * 1. Redistributions of source code must retain the above copyright
9*4bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer.
10*4bff34e3Sthurlow  * 2. Redistributions in binary form must reproduce the above copyright
11*4bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer in the
12*4bff34e3Sthurlow  *    documentation and/or other materials provided with the distribution.
13*4bff34e3Sthurlow  * 3. All advertising materials mentioning features or use of this software
14*4bff34e3Sthurlow  *    must display the following acknowledgement:
15*4bff34e3Sthurlow  *    This product includes software developed by Boris Popov.
16*4bff34e3Sthurlow  * 4. Neither the name of the author nor the names of any co-contributors
17*4bff34e3Sthurlow  *    may be used to endorse or promote products derived from this software
18*4bff34e3Sthurlow  *    without specific prior written permission.
19*4bff34e3Sthurlow  *
20*4bff34e3Sthurlow  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21*4bff34e3Sthurlow  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*4bff34e3Sthurlow  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*4bff34e3Sthurlow  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24*4bff34e3Sthurlow  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25*4bff34e3Sthurlow  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26*4bff34e3Sthurlow  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*4bff34e3Sthurlow  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*4bff34e3Sthurlow  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29*4bff34e3Sthurlow  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*4bff34e3Sthurlow  * SUCH DAMAGE.
31*4bff34e3Sthurlow  *
32*4bff34e3Sthurlow  * $Id: rq.c,v 1.4 2004/12/13 00:25:23 lindak Exp $
33*4bff34e3Sthurlow  */
34*4bff34e3Sthurlow 
35*4bff34e3Sthurlow #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*4bff34e3Sthurlow 
37*4bff34e3Sthurlow #include <sys/types.h>
38*4bff34e3Sthurlow #include <sys/param.h>
39*4bff34e3Sthurlow #include <sys/ioctl.h>
40*4bff34e3Sthurlow #include <sys/errno.h>
41*4bff34e3Sthurlow #include <sys/stat.h>
42*4bff34e3Sthurlow 
43*4bff34e3Sthurlow #include <ctype.h>
44*4bff34e3Sthurlow #include <errno.h>
45*4bff34e3Sthurlow #include <stdio.h>
46*4bff34e3Sthurlow #include <unistd.h>
47*4bff34e3Sthurlow #include <strings.h>
48*4bff34e3Sthurlow #include <stdlib.h>
49*4bff34e3Sthurlow #include <sysexits.h>
50*4bff34e3Sthurlow #include <libintl.h>
51*4bff34e3Sthurlow 
52*4bff34e3Sthurlow #include <netsmb/smb_lib.h>
53*4bff34e3Sthurlow 
54*4bff34e3Sthurlow extern uid_t real_uid, eff_uid;
55*4bff34e3Sthurlow 
56*4bff34e3Sthurlow 
57*4bff34e3Sthurlow int
58*4bff34e3Sthurlow smb_rq_init(struct smb_ctx *ctx, uchar_t cmd, size_t rpbufsz,
59*4bff34e3Sthurlow     struct smb_rq **rqpp)
60*4bff34e3Sthurlow {
61*4bff34e3Sthurlow 	struct smb_rq *rqp;
62*4bff34e3Sthurlow 
63*4bff34e3Sthurlow 	rqp = malloc(sizeof (*rqp));
64*4bff34e3Sthurlow 	if (rqp == NULL)
65*4bff34e3Sthurlow 		return (ENOMEM);
66*4bff34e3Sthurlow 	bzero(rqp, sizeof (*rqp));
67*4bff34e3Sthurlow 	rqp->rq_cmd = cmd;
68*4bff34e3Sthurlow 	rqp->rq_ctx = ctx;
69*4bff34e3Sthurlow 	mb_init(&rqp->rq_rq, M_MINSIZE);
70*4bff34e3Sthurlow 	mb_init(&rqp->rq_rp, rpbufsz);
71*4bff34e3Sthurlow 	*rqpp = rqp;
72*4bff34e3Sthurlow 	return (0);
73*4bff34e3Sthurlow }
74*4bff34e3Sthurlow 
75*4bff34e3Sthurlow void
76*4bff34e3Sthurlow smb_rq_done(struct smb_rq *rqp)
77*4bff34e3Sthurlow {
78*4bff34e3Sthurlow 	mb_done(&rqp->rq_rp);
79*4bff34e3Sthurlow 	mb_done(&rqp->rq_rq);
80*4bff34e3Sthurlow 	free(rqp);
81*4bff34e3Sthurlow }
82*4bff34e3Sthurlow 
83*4bff34e3Sthurlow void
84*4bff34e3Sthurlow smb_rq_wend(struct smb_rq *rqp)
85*4bff34e3Sthurlow {
86*4bff34e3Sthurlow 	if (rqp->rq_rq.mb_count & 1)
87*4bff34e3Sthurlow 		smb_error(dgettext(TEXT_DOMAIN,
88*4bff34e3Sthurlow 		    "smbrq_wend: odd word count\n"), 0);
89*4bff34e3Sthurlow 	rqp->rq_wcount = rqp->rq_rq.mb_count / 2;
90*4bff34e3Sthurlow 	rqp->rq_rq.mb_count = 0;
91*4bff34e3Sthurlow }
92*4bff34e3Sthurlow 
93*4bff34e3Sthurlow int
94*4bff34e3Sthurlow smb_rq_dmem(struct mbdata *mbp, const char *src, size_t size)
95*4bff34e3Sthurlow {
96*4bff34e3Sthurlow 	struct mbuf *m;
97*4bff34e3Sthurlow 	char  *dst;
98*4bff34e3Sthurlow 	int cplen, error;
99*4bff34e3Sthurlow 
100*4bff34e3Sthurlow 	if (size == 0)
101*4bff34e3Sthurlow 		return (0);
102*4bff34e3Sthurlow 	m = mbp->mb_cur;
103*4bff34e3Sthurlow 	if ((error = m_getm(m, size, &m)) != 0)
104*4bff34e3Sthurlow 		return (error);
105*4bff34e3Sthurlow 	while (size > 0) {
106*4bff34e3Sthurlow 		cplen = M_TRAILINGSPACE(m);
107*4bff34e3Sthurlow 		if (cplen == 0) {
108*4bff34e3Sthurlow 			m = m->m_next;
109*4bff34e3Sthurlow 			continue;
110*4bff34e3Sthurlow 		}
111*4bff34e3Sthurlow 		if (cplen > (int)size)
112*4bff34e3Sthurlow 			cplen = size;
113*4bff34e3Sthurlow 		dst = mtod(m, char *) + m->m_len;
114*4bff34e3Sthurlow 		nls_mem_toext(dst, src, cplen);
115*4bff34e3Sthurlow 		size -= cplen;
116*4bff34e3Sthurlow 		src += cplen;
117*4bff34e3Sthurlow 		m->m_len += cplen;
118*4bff34e3Sthurlow 		mbp->mb_count += cplen;
119*4bff34e3Sthurlow 	}
120*4bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
121*4bff34e3Sthurlow 	mbp->mb_cur = m;
122*4bff34e3Sthurlow 	return (0);
123*4bff34e3Sthurlow }
124*4bff34e3Sthurlow 
125*4bff34e3Sthurlow int
126*4bff34e3Sthurlow smb_rq_dstring(struct mbdata *mbp, const char *s)
127*4bff34e3Sthurlow {
128*4bff34e3Sthurlow 	return (smb_rq_dmem(mbp, s, strlen(s) + 1));
129*4bff34e3Sthurlow }
130*4bff34e3Sthurlow 
131*4bff34e3Sthurlow int
132*4bff34e3Sthurlow smb_rq_simple(struct smb_rq *rqp)
133*4bff34e3Sthurlow {
134*4bff34e3Sthurlow 	struct smbioc_rq krq;
135*4bff34e3Sthurlow 	struct mbdata *mbp;
136*4bff34e3Sthurlow 	char *data;
137*4bff34e3Sthurlow 	int i;
138*4bff34e3Sthurlow 
139*4bff34e3Sthurlow 	mbp = smb_rq_getrequest(rqp);
140*4bff34e3Sthurlow 	m_lineup(mbp->mb_top, &mbp->mb_top);
141*4bff34e3Sthurlow 	data = mtod(mbp->mb_top, char *);
142*4bff34e3Sthurlow 	bzero(&krq, sizeof (krq));
143*4bff34e3Sthurlow 	krq.ioc_cmd = rqp->rq_cmd;
144*4bff34e3Sthurlow 	krq.ioc_twc = rqp->rq_wcount;
145*4bff34e3Sthurlow 	krq.ioc_twords = data;
146*4bff34e3Sthurlow 	krq.ioc_tbc = mbp->mb_count;
147*4bff34e3Sthurlow 	krq.ioc_tbytes = data + rqp->rq_wcount * 2;
148*4bff34e3Sthurlow 
149*4bff34e3Sthurlow 	mbp = smb_rq_getreply(rqp);
150*4bff34e3Sthurlow 	krq.ioc_rpbufsz = mbp->mb_top->m_maxlen;
151*4bff34e3Sthurlow 	krq.ioc_rpbuf = mtod(mbp->mb_top, char *);
152*4bff34e3Sthurlow 	seteuid(eff_uid);
153*4bff34e3Sthurlow 	if (ioctl(rqp->rq_ctx->ct_fd, SMBIOC_REQUEST, &krq) == -1) {
154*4bff34e3Sthurlow 		seteuid(real_uid); /* and back to real user */
155*4bff34e3Sthurlow 		return (errno);
156*4bff34e3Sthurlow 	}
157*4bff34e3Sthurlow 	mbp->mb_top->m_len = krq.ioc_rwc * 2 + krq.ioc_rbc;
158*4bff34e3Sthurlow 	rqp->rq_wcount = krq.ioc_rwc;
159*4bff34e3Sthurlow 	rqp->rq_bcount = krq.ioc_rbc;
160*4bff34e3Sthurlow 	seteuid(real_uid); /* and back to real user */
161*4bff34e3Sthurlow 	return (0);
162*4bff34e3Sthurlow }
163*4bff34e3Sthurlow 
164*4bff34e3Sthurlow 
165*4bff34e3Sthurlow int
166*4bff34e3Sthurlow smb_t2_request(struct smb_ctx *ctx, int setupcount, uint16_t *setup,
167*4bff34e3Sthurlow 	const char *name,
168*4bff34e3Sthurlow 	int tparamcnt, void *tparam,
169*4bff34e3Sthurlow 	int tdatacnt, void *tdata,
170*4bff34e3Sthurlow 	int *rparamcnt, void *rparam,
171*4bff34e3Sthurlow 	int *rdatacnt, void *rdata,
172*4bff34e3Sthurlow 	int *buffer_oflow)
173*4bff34e3Sthurlow {
174*4bff34e3Sthurlow 	smbioc_t2rq_t *krq;
175*4bff34e3Sthurlow 	int i;
176*4bff34e3Sthurlow 	char *pass;
177*4bff34e3Sthurlow 
178*4bff34e3Sthurlow 
179*4bff34e3Sthurlow 	krq = (smbioc_t2rq_t *)malloc(sizeof (smbioc_t2rq_t));
180*4bff34e3Sthurlow 	bzero(krq, sizeof (*krq));
181*4bff34e3Sthurlow 
182*4bff34e3Sthurlow 	if (setupcount < 0 || setupcount >= SMB_MAXSETUPWORDS) {
183*4bff34e3Sthurlow 		/* Bogus setup count, or too many setup words */
184*4bff34e3Sthurlow 		return (EINVAL);
185*4bff34e3Sthurlow 	}
186*4bff34e3Sthurlow 	for (i = 0; i < setupcount; i++)
187*4bff34e3Sthurlow 		krq->ioc_setup[i] = setup[i];
188*4bff34e3Sthurlow 	krq->ioc_setupcnt = setupcount;
189*4bff34e3Sthurlow 	strcpy(krq->ioc_name, name);
190*4bff34e3Sthurlow 	krq->ioc_tparamcnt = tparamcnt;
191*4bff34e3Sthurlow 	krq->ioc_tparam = tparam;
192*4bff34e3Sthurlow 	krq->ioc_tdatacnt = tdatacnt;
193*4bff34e3Sthurlow 	krq->ioc_tdata = tdata;
194*4bff34e3Sthurlow 
195*4bff34e3Sthurlow 	krq->ioc_rparamcnt = *rparamcnt;
196*4bff34e3Sthurlow 	krq->ioc_rdatacnt = *rdatacnt;
197*4bff34e3Sthurlow 	krq->ioc_rparam = rparam;
198*4bff34e3Sthurlow 	krq->ioc_rdata  = rdata;
199*4bff34e3Sthurlow 
200*4bff34e3Sthurlow 	seteuid(eff_uid);
201*4bff34e3Sthurlow 	if (ioctl(ctx->ct_fd, SMBIOC_T2RQ, krq) == -1) {
202*4bff34e3Sthurlow 		seteuid(real_uid); /* and back to real user */
203*4bff34e3Sthurlow 		return (errno);
204*4bff34e3Sthurlow 	}
205*4bff34e3Sthurlow 
206*4bff34e3Sthurlow 	*rparamcnt = krq->ioc_rparamcnt;
207*4bff34e3Sthurlow 	*rdatacnt = krq->ioc_rdatacnt;
208*4bff34e3Sthurlow 	*buffer_oflow = (krq->ioc_rpflags2 & SMB_FLAGS2_ERR_STATUS) &&
209*4bff34e3Sthurlow 	    (krq->ioc_error == NT_STATUS_BUFFER_OVERFLOW);
210*4bff34e3Sthurlow 	seteuid(real_uid); /* and back to real user */
211*4bff34e3Sthurlow 	free(krq);
212*4bff34e3Sthurlow 	return (0);
213*4bff34e3Sthurlow }
214