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: rap.c,v 1.5 2004/12/13 00:25:23 lindak Exp $ 33*4bff34e3Sthurlow * 34*4bff34e3Sthurlow * This is very simple implementation of RAP protocol. 35*4bff34e3Sthurlow */ 36*4bff34e3Sthurlow 37*4bff34e3Sthurlow #pragma ident "%Z%%M% %I% %E% SMI" 38*4bff34e3Sthurlow 39*4bff34e3Sthurlow #include <sys/param.h> 40*4bff34e3Sthurlow #include <sys/errno.h> 41*4bff34e3Sthurlow #include <sys/stat.h> 42*4bff34e3Sthurlow #include <sys/isa_defs.h> 43*4bff34e3Sthurlow 44*4bff34e3Sthurlow #include <ctype.h> 45*4bff34e3Sthurlow #include <stdio.h> 46*4bff34e3Sthurlow #include <unistd.h> 47*4bff34e3Sthurlow #include <strings.h> 48*4bff34e3Sthurlow #include <stdlib.h> 49*4bff34e3Sthurlow #include <libintl.h> 50*4bff34e3Sthurlow #include <sysexits.h> 51*4bff34e3Sthurlow 52*4bff34e3Sthurlow #include <netsmb/mchain.h> 53*4bff34e3Sthurlow #include <netsmb/smb_lib.h> 54*4bff34e3Sthurlow #include <netsmb/smb_rap.h> 55*4bff34e3Sthurlow 56*4bff34e3Sthurlow static int 57*4bff34e3Sthurlow smb_rap_parserqparam(const char *s, char **next, int *rlen) 58*4bff34e3Sthurlow { 59*4bff34e3Sthurlow char *np; 60*4bff34e3Sthurlow int len; 61*4bff34e3Sthurlow 62*4bff34e3Sthurlow switch (*s++) { 63*4bff34e3Sthurlow case 'L': 64*4bff34e3Sthurlow case 'T': 65*4bff34e3Sthurlow case 'W': 66*4bff34e3Sthurlow len = 2; 67*4bff34e3Sthurlow break; 68*4bff34e3Sthurlow case 'D': 69*4bff34e3Sthurlow case 'O': 70*4bff34e3Sthurlow len = 4; 71*4bff34e3Sthurlow break; 72*4bff34e3Sthurlow case 'b': 73*4bff34e3Sthurlow case 'F': 74*4bff34e3Sthurlow len = 1; 75*4bff34e3Sthurlow break; 76*4bff34e3Sthurlow case 'r': 77*4bff34e3Sthurlow case 's': 78*4bff34e3Sthurlow len = 0; 79*4bff34e3Sthurlow break; 80*4bff34e3Sthurlow default: 81*4bff34e3Sthurlow return (EINVAL); 82*4bff34e3Sthurlow } 83*4bff34e3Sthurlow if (isdigit(*s)) { 84*4bff34e3Sthurlow len *= strtoul(s, &np, 10); 85*4bff34e3Sthurlow s = np; 86*4bff34e3Sthurlow } 87*4bff34e3Sthurlow *rlen = len; 88*4bff34e3Sthurlow *(const char **)next = s; 89*4bff34e3Sthurlow return (0); 90*4bff34e3Sthurlow } 91*4bff34e3Sthurlow 92*4bff34e3Sthurlow static int 93*4bff34e3Sthurlow smb_rap_parserpparam(const char *s, char **next, int *rlen) 94*4bff34e3Sthurlow { 95*4bff34e3Sthurlow char *np; 96*4bff34e3Sthurlow int len = 0; 97*4bff34e3Sthurlow 98*4bff34e3Sthurlow switch (*s++) { 99*4bff34e3Sthurlow case 'e': 100*4bff34e3Sthurlow case 'h': 101*4bff34e3Sthurlow len = 2; 102*4bff34e3Sthurlow break; 103*4bff34e3Sthurlow case 'i': 104*4bff34e3Sthurlow len = 4; 105*4bff34e3Sthurlow break; 106*4bff34e3Sthurlow case 'g': 107*4bff34e3Sthurlow len = 1; 108*4bff34e3Sthurlow break; 109*4bff34e3Sthurlow default: 110*4bff34e3Sthurlow return (EINVAL); 111*4bff34e3Sthurlow } 112*4bff34e3Sthurlow if (isdigit(*s)) { 113*4bff34e3Sthurlow len *= strtoul(s, &np, 10); 114*4bff34e3Sthurlow s = np; 115*4bff34e3Sthurlow } 116*4bff34e3Sthurlow *rlen = len; 117*4bff34e3Sthurlow *(const char **)next = s; 118*4bff34e3Sthurlow return (0); 119*4bff34e3Sthurlow } 120*4bff34e3Sthurlow 121*4bff34e3Sthurlow static int 122*4bff34e3Sthurlow smb_rap_parserpdata(const char *s, char **next, int *rlen) 123*4bff34e3Sthurlow { 124*4bff34e3Sthurlow char *np; 125*4bff34e3Sthurlow int len; 126*4bff34e3Sthurlow 127*4bff34e3Sthurlow switch (*s++) { 128*4bff34e3Sthurlow case 'B': 129*4bff34e3Sthurlow len = 1; 130*4bff34e3Sthurlow break; 131*4bff34e3Sthurlow case 'W': 132*4bff34e3Sthurlow len = 2; 133*4bff34e3Sthurlow break; 134*4bff34e3Sthurlow case 'D': 135*4bff34e3Sthurlow case 'O': 136*4bff34e3Sthurlow case 'z': 137*4bff34e3Sthurlow len = 4; 138*4bff34e3Sthurlow break; 139*4bff34e3Sthurlow default: 140*4bff34e3Sthurlow return (EINVAL); 141*4bff34e3Sthurlow } 142*4bff34e3Sthurlow if (isdigit(*s)) { 143*4bff34e3Sthurlow len *= strtoul(s, &np, 10); 144*4bff34e3Sthurlow s = np; 145*4bff34e3Sthurlow } 146*4bff34e3Sthurlow *rlen = len; 147*4bff34e3Sthurlow *(const char **)next = s; 148*4bff34e3Sthurlow return (0); 149*4bff34e3Sthurlow } 150*4bff34e3Sthurlow 151*4bff34e3Sthurlow static int 152*4bff34e3Sthurlow smb_rap_rqparam_z(struct smb_rap *rap, const char *value) 153*4bff34e3Sthurlow { 154*4bff34e3Sthurlow int len = strlen(value) + 1; 155*4bff34e3Sthurlow 156*4bff34e3Sthurlow bcopy(value, rap->r_npbuf, len); 157*4bff34e3Sthurlow rap->r_npbuf += len; 158*4bff34e3Sthurlow rap->r_plen += len; 159*4bff34e3Sthurlow return (0); 160*4bff34e3Sthurlow } 161*4bff34e3Sthurlow 162*4bff34e3Sthurlow /* 163*4bff34e3Sthurlow * Marshal RAP request parameters. 164*4bff34e3Sthurlow * Note: value is in host order. 165*4bff34e3Sthurlow */ 166*4bff34e3Sthurlow static int 167*4bff34e3Sthurlow smb_rap_rqparam(struct smb_rap *rap, char ptype, char plen, int value) 168*4bff34e3Sthurlow { 169*4bff34e3Sthurlow char *p = rap->r_npbuf; 170*4bff34e3Sthurlow int len = 0; 171*4bff34e3Sthurlow uint_t uv = (uint_t)value; 172*4bff34e3Sthurlow 173*4bff34e3Sthurlow switch (ptype) { 174*4bff34e3Sthurlow case 'L': 175*4bff34e3Sthurlow case 'W': 176*4bff34e3Sthurlow /* LINTED */ 177*4bff34e3Sthurlow setwle(p, 0, uv); 178*4bff34e3Sthurlow len = 2; 179*4bff34e3Sthurlow break; 180*4bff34e3Sthurlow case 'D': 181*4bff34e3Sthurlow /* LINTED */ 182*4bff34e3Sthurlow setdle(p, 0, uv); 183*4bff34e3Sthurlow len = 4; 184*4bff34e3Sthurlow break; 185*4bff34e3Sthurlow case 'b': 186*4bff34e3Sthurlow memset(p, uv, plen); 187*4bff34e3Sthurlow len = plen; 188*4bff34e3Sthurlow default: 189*4bff34e3Sthurlow return (EINVAL); 190*4bff34e3Sthurlow } 191*4bff34e3Sthurlow rap->r_npbuf += len; 192*4bff34e3Sthurlow rap->r_plen += len; 193*4bff34e3Sthurlow return (0); 194*4bff34e3Sthurlow } 195*4bff34e3Sthurlow 196*4bff34e3Sthurlow int 197*4bff34e3Sthurlow smb_rap_create(int fn, const char *param, const char *data, 198*4bff34e3Sthurlow struct smb_rap **rapp) 199*4bff34e3Sthurlow { 200*4bff34e3Sthurlow struct smb_rap *rap; 201*4bff34e3Sthurlow char *p; 202*4bff34e3Sthurlow int plen = 0, len = 0; 203*4bff34e3Sthurlow int i; 204*4bff34e3Sthurlow 205*4bff34e3Sthurlow rap = malloc(sizeof (*rap)); 206*4bff34e3Sthurlow if (rap == NULL) 207*4bff34e3Sthurlow return (ENOMEM); 208*4bff34e3Sthurlow bzero(rap, sizeof (*rap)); 209*4bff34e3Sthurlow p = rap->r_sparam = rap->r_nparam = strdup(param); 210*4bff34e3Sthurlow rap->r_sdata = rap->r_ndata = strdup(data); 211*4bff34e3Sthurlow 212*4bff34e3Sthurlow /* 213*4bff34e3Sthurlow * Calculate length of request parameter block 214*4bff34e3Sthurlow */ 215*4bff34e3Sthurlow len = 2 + strlen(param) + 1 + strlen(data) + 1; 216*4bff34e3Sthurlow while (*p) { 217*4bff34e3Sthurlow if (smb_rap_parserqparam(p, &p, &plen) != 0) 218*4bff34e3Sthurlow break; 219*4bff34e3Sthurlow len += plen; 220*4bff34e3Sthurlow } 221*4bff34e3Sthurlow rap->r_pbuf = rap->r_npbuf = malloc(len); 222*4bff34e3Sthurlow smb_rap_rqparam(rap, 'W', 1, fn); 223*4bff34e3Sthurlow smb_rap_rqparam_z(rap, rap->r_sparam); 224*4bff34e3Sthurlow smb_rap_rqparam_z(rap, rap->r_sdata); 225*4bff34e3Sthurlow *rapp = rap; 226*4bff34e3Sthurlow return (0); 227*4bff34e3Sthurlow } 228*4bff34e3Sthurlow 229*4bff34e3Sthurlow void 230*4bff34e3Sthurlow smb_rap_done(struct smb_rap *rap) 231*4bff34e3Sthurlow { 232*4bff34e3Sthurlow if (rap->r_sparam) 233*4bff34e3Sthurlow free(rap->r_sparam); 234*4bff34e3Sthurlow if (rap->r_sdata) 235*4bff34e3Sthurlow free(rap->r_sdata); 236*4bff34e3Sthurlow if (rap->r_pbuf) 237*4bff34e3Sthurlow free(rap->r_pbuf); 238*4bff34e3Sthurlow #ifdef NOTYETDEFINED 239*4bff34e3Sthurlow if (rap->r_npbuf) 240*4bff34e3Sthurlow free(rap->r_npbuf); 241*4bff34e3Sthurlow if (rap->r_dbuf) 242*4bff34e3Sthurlow free(rap->r_dbuf); 243*4bff34e3Sthurlow if (rap->r_rcvbuf) 244*4bff34e3Sthurlow free(rap->r_rcvbuf); 245*4bff34e3Sthurlow #endif 246*4bff34e3Sthurlow free(rap); 247*4bff34e3Sthurlow } 248*4bff34e3Sthurlow 249*4bff34e3Sthurlow int 250*4bff34e3Sthurlow smb_rap_setNparam(struct smb_rap *rap, int value) 251*4bff34e3Sthurlow { 252*4bff34e3Sthurlow char *p = rap->r_nparam; 253*4bff34e3Sthurlow char ptype = *p; 254*4bff34e3Sthurlow int error, plen; 255*4bff34e3Sthurlow 256*4bff34e3Sthurlow error = smb_rap_parserqparam(p, &p, &plen); 257*4bff34e3Sthurlow if (error) 258*4bff34e3Sthurlow return (error); 259*4bff34e3Sthurlow switch (ptype) { 260*4bff34e3Sthurlow case 'L': 261*4bff34e3Sthurlow rap->r_rcvbuflen = value; 262*4bff34e3Sthurlow /* FALLTHROUGH */ 263*4bff34e3Sthurlow case 'W': 264*4bff34e3Sthurlow case 'D': 265*4bff34e3Sthurlow case 'b': 266*4bff34e3Sthurlow error = smb_rap_rqparam(rap, ptype, plen, value); 267*4bff34e3Sthurlow break; 268*4bff34e3Sthurlow default: 269*4bff34e3Sthurlow return (EINVAL); 270*4bff34e3Sthurlow } 271*4bff34e3Sthurlow rap->r_nparam = p; 272*4bff34e3Sthurlow return (0); 273*4bff34e3Sthurlow } 274*4bff34e3Sthurlow 275*4bff34e3Sthurlow int 276*4bff34e3Sthurlow smb_rap_setPparam(struct smb_rap *rap, void *value) 277*4bff34e3Sthurlow { 278*4bff34e3Sthurlow char *p = rap->r_nparam; 279*4bff34e3Sthurlow char ptype = *p; 280*4bff34e3Sthurlow int error, plen; 281*4bff34e3Sthurlow 282*4bff34e3Sthurlow error = smb_rap_parserqparam(p, &p, &plen); 283*4bff34e3Sthurlow if (error) 284*4bff34e3Sthurlow return (error); 285*4bff34e3Sthurlow switch (ptype) { 286*4bff34e3Sthurlow case 'r': 287*4bff34e3Sthurlow rap->r_rcvbuf = value; 288*4bff34e3Sthurlow break; 289*4bff34e3Sthurlow default: 290*4bff34e3Sthurlow return (EINVAL); 291*4bff34e3Sthurlow } 292*4bff34e3Sthurlow rap->r_nparam = p; 293*4bff34e3Sthurlow return (0); 294*4bff34e3Sthurlow } 295*4bff34e3Sthurlow 296*4bff34e3Sthurlow static int 297*4bff34e3Sthurlow smb_rap_getNparam(struct smb_rap *rap, long *value) 298*4bff34e3Sthurlow { 299*4bff34e3Sthurlow char *p = rap->r_nparam; 300*4bff34e3Sthurlow char ptype = *p; 301*4bff34e3Sthurlow int error, plen; 302*4bff34e3Sthurlow uint16_t *te; 303*4bff34e3Sthurlow 304*4bff34e3Sthurlow error = smb_rap_parserpparam(p, &p, &plen); 305*4bff34e3Sthurlow if (error) 306*4bff34e3Sthurlow return (error); 307*4bff34e3Sthurlow switch (ptype) { 308*4bff34e3Sthurlow case 'h': 309*4bff34e3Sthurlow /* LINTED */ 310*4bff34e3Sthurlow te = (uint16_t *)rap->r_npbuf; 311*4bff34e3Sthurlow *value = letohs(*te); 312*4bff34e3Sthurlow break; 313*4bff34e3Sthurlow default: 314*4bff34e3Sthurlow return (EINVAL); 315*4bff34e3Sthurlow } 316*4bff34e3Sthurlow rap->r_npbuf += plen; 317*4bff34e3Sthurlow rap->r_nparam = p; 318*4bff34e3Sthurlow return (0); 319*4bff34e3Sthurlow } 320*4bff34e3Sthurlow 321*4bff34e3Sthurlow int 322*4bff34e3Sthurlow smb_rap_request(struct smb_rap *rap, struct smb_ctx *ctx) 323*4bff34e3Sthurlow { 324*4bff34e3Sthurlow uint16_t *rp, conv, *tmp; 325*4bff34e3Sthurlow uint32_t *p32, ps1; 326*4bff34e3Sthurlow char *dp, *p = rap->r_nparam; 327*4bff34e3Sthurlow char ptype; 328*4bff34e3Sthurlow int error, rdatacnt, rparamcnt, entries, done, dlen, buffer_oflow, i; 329*4bff34e3Sthurlow 330*4bff34e3Sthurlow rdatacnt = rap->r_rcvbuflen; 331*4bff34e3Sthurlow rparamcnt = rap->r_plen; 332*4bff34e3Sthurlow error = smb_t2_request(ctx, 0, NULL, "\\PIPE\\LANMAN", 333*4bff34e3Sthurlow rap->r_plen, rap->r_pbuf, /* int tparamcnt,void *tparam */ 334*4bff34e3Sthurlow 0, NULL, /* int tdatacnt, void *tdata */ 335*4bff34e3Sthurlow &rparamcnt, rap->r_pbuf, /* rparamcnt, void *rparam */ 336*4bff34e3Sthurlow &rdatacnt, rap->r_rcvbuf, /* int *rdatacnt, void *rdata */ 337*4bff34e3Sthurlow &buffer_oflow); 338*4bff34e3Sthurlow if (error) 339*4bff34e3Sthurlow return (error); 340*4bff34e3Sthurlow 341*4bff34e3Sthurlow /* LINTED */ 342*4bff34e3Sthurlow rp = (uint16_t *)rap->r_pbuf; 343*4bff34e3Sthurlow 344*4bff34e3Sthurlow /* 345*4bff34e3Sthurlow * Note: First is a "LanMan API" error code. 346*4bff34e3Sthurlow * See: usr/src/uts/common/smbsrv/lmerr.h 347*4bff34e3Sthurlow */ 348*4bff34e3Sthurlow if (rparamcnt < 2) 349*4bff34e3Sthurlow return (EBADRPC); 350*4bff34e3Sthurlow rap->r_result = letohs(*rp); 351*4bff34e3Sthurlow rp++; rparamcnt -= 2; 352*4bff34e3Sthurlow 353*4bff34e3Sthurlow if (rap->r_result != 0) { 354*4bff34e3Sthurlow /* 355*4bff34e3Sthurlow * Could also return zero and let the caller 356*4bff34e3Sthurlow * come get r_result via smb_rap_error(), 357*4bff34e3Sthurlow * but in case they dont... 358*4bff34e3Sthurlow */ 359*4bff34e3Sthurlow return (rap->r_result | SMB_RAP_ERROR); 360*4bff34e3Sthurlow } 361*4bff34e3Sthurlow 362*4bff34e3Sthurlow if (rparamcnt < 2) 363*4bff34e3Sthurlow return (EBADRPC); 364*4bff34e3Sthurlow conv = letohs(*rp); 365*4bff34e3Sthurlow rp++; rparamcnt -= 2; 366*4bff34e3Sthurlow 367*4bff34e3Sthurlow rap->r_npbuf = (char *)rp; 368*4bff34e3Sthurlow rap->r_entries = entries = 0; 369*4bff34e3Sthurlow /* Save the returned data length */ 370*4bff34e3Sthurlow rap->r_rcvbuflen = rdatacnt; 371*4bff34e3Sthurlow done = 0; 372*4bff34e3Sthurlow 373*4bff34e3Sthurlow while (!done && *p) { 374*4bff34e3Sthurlow ptype = *p; 375*4bff34e3Sthurlow switch (ptype) { 376*4bff34e3Sthurlow case 'e': 377*4bff34e3Sthurlow if (rparamcnt < 2) 378*4bff34e3Sthurlow return (EBADRPC); 379*4bff34e3Sthurlow /* LINTED */ 380*4bff34e3Sthurlow tmp = (uint16_t *)rap->r_npbuf; 381*4bff34e3Sthurlow rap->r_entries = entries = letohs(*tmp); 382*4bff34e3Sthurlow rap->r_npbuf += 2; 383*4bff34e3Sthurlow rparamcnt -= 2; 384*4bff34e3Sthurlow p++; 385*4bff34e3Sthurlow break; 386*4bff34e3Sthurlow default: 387*4bff34e3Sthurlow done = 1; 388*4bff34e3Sthurlow } 389*4bff34e3Sthurlow #if 0 /* commented out in Darwin. Why? */ 390*4bff34e3Sthurlow error = smb_rap_parserpparam(p, &p, &plen); 391*4bff34e3Sthurlow if (error) { 392*4bff34e3Sthurlow smb_error(dgettext(TEXT_DOMAIN, 393*4bff34e3Sthurlow "reply parameter mismatch %s"), 0, p); 394*4bff34e3Sthurlow return (EBADRPC); 395*4bff34e3Sthurlow } 396*4bff34e3Sthurlow #endif 397*4bff34e3Sthurlow } 398*4bff34e3Sthurlow rap->r_nparam = p; 399*4bff34e3Sthurlow /* 400*4bff34e3Sthurlow * In general, unpacking entries we may need to relocate 401*4bff34e3Sthurlow * entries for proper aligning. For now use them as is. 402*4bff34e3Sthurlow */ 403*4bff34e3Sthurlow dp = rap->r_rcvbuf; 404*4bff34e3Sthurlow while (entries--) { 405*4bff34e3Sthurlow p = rap->r_sdata; 406*4bff34e3Sthurlow while (*p) { 407*4bff34e3Sthurlow ptype = *p; 408*4bff34e3Sthurlow error = smb_rap_parserpdata(p, &p, &dlen); 409*4bff34e3Sthurlow if (error) { 410*4bff34e3Sthurlow smb_error(dgettext(TEXT_DOMAIN, 411*4bff34e3Sthurlow "reply data mismatch %s"), 0, p); 412*4bff34e3Sthurlow return (EBADRPC); 413*4bff34e3Sthurlow } 414*4bff34e3Sthurlow if (rdatacnt < dlen) 415*4bff34e3Sthurlow return (EBADRPC); 416*4bff34e3Sthurlow switch (ptype) { 417*4bff34e3Sthurlow case 'z': 418*4bff34e3Sthurlow /* LINTED */ 419*4bff34e3Sthurlow p32 = (uint32_t *)dp; 420*4bff34e3Sthurlow *p32 = (letohl(*p32) & 0xffff) - conv; 421*4bff34e3Sthurlow break; 422*4bff34e3Sthurlow } 423*4bff34e3Sthurlow dp += dlen; 424*4bff34e3Sthurlow rdatacnt -= dlen; 425*4bff34e3Sthurlow } 426*4bff34e3Sthurlow } 427*4bff34e3Sthurlow return (error); 428*4bff34e3Sthurlow } 429*4bff34e3Sthurlow 430*4bff34e3Sthurlow int 431*4bff34e3Sthurlow smb_rap_error(struct smb_rap *rap, int error) 432*4bff34e3Sthurlow { 433*4bff34e3Sthurlow if (error) 434*4bff34e3Sthurlow return (error); 435*4bff34e3Sthurlow if (rap->r_result == 0) 436*4bff34e3Sthurlow return (0); 437*4bff34e3Sthurlow return (rap->r_result | SMB_RAP_ERROR); 438*4bff34e3Sthurlow } 439*4bff34e3Sthurlow 440*4bff34e3Sthurlow /* todo: move this function to libnetapi */ 441*4bff34e3Sthurlow int 442*4bff34e3Sthurlow smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer, 443*4bff34e3Sthurlow int *cbBuffer, int *pcEntriesRead, int *pcTotalAvail) 444*4bff34e3Sthurlow { 445*4bff34e3Sthurlow struct smb_rap *rap; 446*4bff34e3Sthurlow long lval = -1; 447*4bff34e3Sthurlow int error; 448*4bff34e3Sthurlow char *pass; 449*4bff34e3Sthurlow int i; 450*4bff34e3Sthurlow 451*4bff34e3Sthurlow error = smb_rap_create(0, "WrLeh", "B13BWz", &rap); 452*4bff34e3Sthurlow if (error) 453*4bff34e3Sthurlow return (error); 454*4bff34e3Sthurlow smb_rap_setNparam(rap, sLevel); /* W - sLevel */ 455*4bff34e3Sthurlow smb_rap_setPparam(rap, pbBuffer); /* r - pbBuffer */ 456*4bff34e3Sthurlow smb_rap_setNparam(rap, *cbBuffer); /* L - cbBuffer */ 457*4bff34e3Sthurlow error = smb_rap_request(rap, ctx); 458*4bff34e3Sthurlow if (error == 0) { 459*4bff34e3Sthurlow *pcEntriesRead = rap->r_entries; 460*4bff34e3Sthurlow error = smb_rap_getNparam(rap, &lval); 461*4bff34e3Sthurlow *pcTotalAvail = lval; 462*4bff34e3Sthurlow /* Copy the data length into the IN/OUT variable. */ 463*4bff34e3Sthurlow *cbBuffer = rap->r_rcvbuflen; 464*4bff34e3Sthurlow } 465*4bff34e3Sthurlow error = smb_rap_error(rap, error); 466*4bff34e3Sthurlow smb_rap_done(rap); 467*4bff34e3Sthurlow return (error); 468*4bff34e3Sthurlow } 469