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