xref: /titanic_50/usr/src/lib/libsmbfs/smb/rap.c (revision 430b4c467020edf2445feb0c21db01c88b86243a)
14bff34e3Sthurlow /*
2*430b4c46SGordon Ross  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
34bff34e3Sthurlow  * Copyright (c) 2000, Boris Popov
44bff34e3Sthurlow  * All rights reserved.
54bff34e3Sthurlow  *
64bff34e3Sthurlow  * Redistribution and use in source and binary forms, with or without
74bff34e3Sthurlow  * modification, are permitted provided that the following conditions
84bff34e3Sthurlow  * are met:
94bff34e3Sthurlow  * 1. Redistributions of source code must retain the above copyright
104bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer.
114bff34e3Sthurlow  * 2. Redistributions in binary form must reproduce the above copyright
124bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer in the
134bff34e3Sthurlow  *    documentation and/or other materials provided with the distribution.
144bff34e3Sthurlow  * 3. All advertising materials mentioning features or use of this software
154bff34e3Sthurlow  *    must display the following acknowledgement:
164bff34e3Sthurlow  *    This product includes software developed by Boris Popov.
174bff34e3Sthurlow  * 4. Neither the name of the author nor the names of any co-contributors
184bff34e3Sthurlow  *    may be used to endorse or promote products derived from this software
194bff34e3Sthurlow  *    without specific prior written permission.
204bff34e3Sthurlow  *
214bff34e3Sthurlow  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
224bff34e3Sthurlow  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
234bff34e3Sthurlow  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
244bff34e3Sthurlow  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
254bff34e3Sthurlow  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
264bff34e3Sthurlow  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
274bff34e3Sthurlow  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
284bff34e3Sthurlow  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
294bff34e3Sthurlow  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
304bff34e3Sthurlow  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
314bff34e3Sthurlow  * SUCH DAMAGE.
324bff34e3Sthurlow  *
334bff34e3Sthurlow  * $Id: rap.c,v 1.5 2004/12/13 00:25:23 lindak Exp $
344bff34e3Sthurlow  *
354bff34e3Sthurlow  * This is very simple implementation of RAP protocol.
364bff34e3Sthurlow  */
374bff34e3Sthurlow 
384bff34e3Sthurlow #include <sys/param.h>
394bff34e3Sthurlow #include <sys/errno.h>
404bff34e3Sthurlow #include <sys/stat.h>
414bff34e3Sthurlow #include <sys/isa_defs.h>
424bff34e3Sthurlow 
434bff34e3Sthurlow #include <ctype.h>
444bff34e3Sthurlow #include <stdio.h>
454bff34e3Sthurlow #include <unistd.h>
464bff34e3Sthurlow #include <strings.h>
474bff34e3Sthurlow #include <stdlib.h>
484bff34e3Sthurlow #include <libintl.h>
494bff34e3Sthurlow #include <sysexits.h>
504bff34e3Sthurlow 
514bff34e3Sthurlow #include <netsmb/mchain.h>
524bff34e3Sthurlow #include <netsmb/smb_lib.h>
534bff34e3Sthurlow #include <netsmb/smb_rap.h>
549c9af259SGordon Ross #include "private.h"
554bff34e3Sthurlow 
564bff34e3Sthurlow static int
smb_rap_parserqparam(const char * s,char ** next,int * rlen)574bff34e3Sthurlow smb_rap_parserqparam(const char *s, char **next, int *rlen)
584bff34e3Sthurlow {
594bff34e3Sthurlow 	char *np;
604bff34e3Sthurlow 	int len;
614bff34e3Sthurlow 
624bff34e3Sthurlow 	switch (*s++) {
634bff34e3Sthurlow 	case 'L':
644bff34e3Sthurlow 	case 'T':
654bff34e3Sthurlow 	case 'W':
664bff34e3Sthurlow 		len = 2;
674bff34e3Sthurlow 		break;
684bff34e3Sthurlow 	case 'D':
694bff34e3Sthurlow 	case 'O':
704bff34e3Sthurlow 		len = 4;
714bff34e3Sthurlow 		break;
724bff34e3Sthurlow 	case 'b':
734bff34e3Sthurlow 	case 'F':
744bff34e3Sthurlow 		len = 1;
754bff34e3Sthurlow 		break;
764bff34e3Sthurlow 	case 'r':
774bff34e3Sthurlow 	case 's':
784bff34e3Sthurlow 		len = 0;
794bff34e3Sthurlow 		break;
804bff34e3Sthurlow 	default:
814bff34e3Sthurlow 		return (EINVAL);
824bff34e3Sthurlow 	}
834bff34e3Sthurlow 	if (isdigit(*s)) {
844bff34e3Sthurlow 		len *= strtoul(s, &np, 10);
854bff34e3Sthurlow 		s = np;
864bff34e3Sthurlow 	}
874bff34e3Sthurlow 	*rlen = len;
884bff34e3Sthurlow 	*(const char **)next = s;
894bff34e3Sthurlow 	return (0);
904bff34e3Sthurlow }
914bff34e3Sthurlow 
924bff34e3Sthurlow static int
smb_rap_parserpparam(const char * s,char ** next,int * rlen)934bff34e3Sthurlow smb_rap_parserpparam(const char *s, char **next, int *rlen)
944bff34e3Sthurlow {
954bff34e3Sthurlow 	char *np;
964bff34e3Sthurlow 	int len = 0;
974bff34e3Sthurlow 
984bff34e3Sthurlow 	switch (*s++) {
994bff34e3Sthurlow 	case 'e':
1004bff34e3Sthurlow 	case 'h':
1014bff34e3Sthurlow 		len = 2;
1024bff34e3Sthurlow 		break;
1034bff34e3Sthurlow 	case 'i':
1044bff34e3Sthurlow 		len = 4;
1054bff34e3Sthurlow 		break;
1064bff34e3Sthurlow 	case 'g':
1074bff34e3Sthurlow 		len = 1;
1084bff34e3Sthurlow 		break;
1094bff34e3Sthurlow 	default:
1104bff34e3Sthurlow 		return (EINVAL);
1114bff34e3Sthurlow 	}
1124bff34e3Sthurlow 	if (isdigit(*s)) {
1134bff34e3Sthurlow 		len *= strtoul(s, &np, 10);
1144bff34e3Sthurlow 		s = np;
1154bff34e3Sthurlow 	}
1164bff34e3Sthurlow 	*rlen = len;
1174bff34e3Sthurlow 	*(const char **)next = s;
1184bff34e3Sthurlow 	return (0);
1194bff34e3Sthurlow }
1204bff34e3Sthurlow 
1214bff34e3Sthurlow static int
smb_rap_parserpdata(const char * s,char ** next,int * rlen)1224bff34e3Sthurlow smb_rap_parserpdata(const char *s, char **next, int *rlen)
1234bff34e3Sthurlow {
1244bff34e3Sthurlow 	char *np;
1254bff34e3Sthurlow 	int len;
1264bff34e3Sthurlow 
1274bff34e3Sthurlow 	switch (*s++) {
1284bff34e3Sthurlow 	case 'B':
1294bff34e3Sthurlow 		len = 1;
1304bff34e3Sthurlow 		break;
1314bff34e3Sthurlow 	case 'W':
1324bff34e3Sthurlow 		len = 2;
1334bff34e3Sthurlow 		break;
1344bff34e3Sthurlow 	case 'D':
1354bff34e3Sthurlow 	case 'O':
1364bff34e3Sthurlow 	case 'z':
1374bff34e3Sthurlow 		len = 4;
1384bff34e3Sthurlow 		break;
1394bff34e3Sthurlow 	default:
1404bff34e3Sthurlow 		return (EINVAL);
1414bff34e3Sthurlow 	}
1424bff34e3Sthurlow 	if (isdigit(*s)) {
1434bff34e3Sthurlow 		len *= strtoul(s, &np, 10);
1444bff34e3Sthurlow 		s = np;
1454bff34e3Sthurlow 	}
1464bff34e3Sthurlow 	*rlen = len;
1474bff34e3Sthurlow 	*(const char **)next = s;
1484bff34e3Sthurlow 	return (0);
1494bff34e3Sthurlow }
1504bff34e3Sthurlow 
1514bff34e3Sthurlow static int
smb_rap_rqparam_z(struct smb_rap * rap,const char * value)1524bff34e3Sthurlow smb_rap_rqparam_z(struct smb_rap *rap, const char *value)
1534bff34e3Sthurlow {
1544bff34e3Sthurlow 	int len = strlen(value) + 1;
1554bff34e3Sthurlow 
1564bff34e3Sthurlow 	bcopy(value, rap->r_npbuf, len);
1574bff34e3Sthurlow 	rap->r_npbuf += len;
1584bff34e3Sthurlow 	rap->r_plen += len;
1594bff34e3Sthurlow 	return (0);
1604bff34e3Sthurlow }
1614bff34e3Sthurlow 
1624bff34e3Sthurlow /*
1634bff34e3Sthurlow  * Marshal RAP request parameters.
1644bff34e3Sthurlow  * Note: value is in host order.
1654bff34e3Sthurlow  */
1664bff34e3Sthurlow static int
smb_rap_rqparam(struct smb_rap * rap,char ptype,char plen,int value)1674bff34e3Sthurlow smb_rap_rqparam(struct smb_rap *rap, char ptype, char plen, int value)
1684bff34e3Sthurlow {
1694bff34e3Sthurlow 	int len = 0;
1704bff34e3Sthurlow 	uint_t uv = (uint_t)value;
1719c9af259SGordon Ross 	uint32_t *lp;
1729c9af259SGordon Ross 	uint16_t *sp;
1739c9af259SGordon Ross 	char *p;
1744bff34e3Sthurlow 
1754bff34e3Sthurlow 	switch (ptype) {
1764bff34e3Sthurlow 	case 'L':
1774bff34e3Sthurlow 	case 'W':
1784bff34e3Sthurlow 		/* LINTED */
1799c9af259SGordon Ross 		sp = (uint16_t *)rap->r_npbuf;
1809c9af259SGordon Ross 		*sp = htoles(uv);
1819c9af259SGordon Ross 		len = sizeof (*sp);
1824bff34e3Sthurlow 		break;
1834bff34e3Sthurlow 	case 'D':
1844bff34e3Sthurlow 		/* LINTED */
1859c9af259SGordon Ross 		lp = (uint32_t *)rap->r_npbuf;
1869c9af259SGordon Ross 		*lp = htolel(uv);
1879c9af259SGordon Ross 		len = sizeof (*lp);
1884bff34e3Sthurlow 		break;
1894bff34e3Sthurlow 	case 'b':
1909c9af259SGordon Ross 		p = rap->r_npbuf;
1914bff34e3Sthurlow 		memset(p, uv, plen);
1924bff34e3Sthurlow 		len = plen;
1934bff34e3Sthurlow 	default:
1944bff34e3Sthurlow 		return (EINVAL);
1954bff34e3Sthurlow 	}
1964bff34e3Sthurlow 	rap->r_npbuf += len;
1974bff34e3Sthurlow 	rap->r_plen += len;
1984bff34e3Sthurlow 	return (0);
1994bff34e3Sthurlow }
2004bff34e3Sthurlow 
2014bff34e3Sthurlow int
smb_rap_create(int fn,const char * param,const char * data,struct smb_rap ** rapp)2024bff34e3Sthurlow smb_rap_create(int fn, const char *param, const char *data,
2034bff34e3Sthurlow 	struct smb_rap **rapp)
2044bff34e3Sthurlow {
2054bff34e3Sthurlow 	struct smb_rap *rap;
2064bff34e3Sthurlow 	char *p;
2074bff34e3Sthurlow 	int plen = 0, len = 0;
2084bff34e3Sthurlow 
2094bff34e3Sthurlow 	rap = malloc(sizeof (*rap));
2104bff34e3Sthurlow 	if (rap == NULL)
2114bff34e3Sthurlow 		return (ENOMEM);
2124bff34e3Sthurlow 	bzero(rap, sizeof (*rap));
2134bff34e3Sthurlow 	p = rap->r_sparam = rap->r_nparam = strdup(param);
2144bff34e3Sthurlow 	rap->r_sdata = rap->r_ndata = strdup(data);
2154bff34e3Sthurlow 
2164bff34e3Sthurlow 	/*
2174bff34e3Sthurlow 	 * Calculate length of request parameter block
2184bff34e3Sthurlow 	 */
2194bff34e3Sthurlow 	len = 2 + strlen(param) + 1 + strlen(data) + 1;
2204bff34e3Sthurlow 	while (*p) {
2214bff34e3Sthurlow 		if (smb_rap_parserqparam(p, &p, &plen) != 0)
2224bff34e3Sthurlow 			break;
2234bff34e3Sthurlow 		len += plen;
2244bff34e3Sthurlow 	}
2254bff34e3Sthurlow 	rap->r_pbuf = rap->r_npbuf = malloc(len);
22602d09e03SGordon Ross 	if (rap->r_pbuf == NULL)
22702d09e03SGordon Ross 		return (ENOMEM);
22802d09e03SGordon Ross 	(void) smb_rap_rqparam(rap, 'W', 1, fn);
22902d09e03SGordon Ross 	(void) smb_rap_rqparam_z(rap, rap->r_sparam);
23002d09e03SGordon Ross 	(void) smb_rap_rqparam_z(rap, rap->r_sdata);
2314bff34e3Sthurlow 	*rapp = rap;
2324bff34e3Sthurlow 	return (0);
2334bff34e3Sthurlow }
2344bff34e3Sthurlow 
2354bff34e3Sthurlow void
smb_rap_done(struct smb_rap * rap)2364bff34e3Sthurlow smb_rap_done(struct smb_rap *rap)
2374bff34e3Sthurlow {
2384bff34e3Sthurlow 	if (rap->r_sparam)
2394bff34e3Sthurlow 		free(rap->r_sparam);
2404bff34e3Sthurlow 	if (rap->r_sdata)
2414bff34e3Sthurlow 		free(rap->r_sdata);
2424bff34e3Sthurlow 	if (rap->r_pbuf)
2434bff34e3Sthurlow 		free(rap->r_pbuf);
2444bff34e3Sthurlow #ifdef NOTYETDEFINED
2454bff34e3Sthurlow 	if (rap->r_npbuf)
2464bff34e3Sthurlow 		free(rap->r_npbuf);
2474bff34e3Sthurlow 	if (rap->r_dbuf)
2484bff34e3Sthurlow 		free(rap->r_dbuf);
2494bff34e3Sthurlow 	if (rap->r_rcvbuf)
2504bff34e3Sthurlow 		free(rap->r_rcvbuf);
2514bff34e3Sthurlow #endif
2524bff34e3Sthurlow 	free(rap);
2534bff34e3Sthurlow }
2544bff34e3Sthurlow 
2554bff34e3Sthurlow int
smb_rap_setNparam(struct smb_rap * rap,int value)2564bff34e3Sthurlow smb_rap_setNparam(struct smb_rap *rap, int value)
2574bff34e3Sthurlow {
2584bff34e3Sthurlow 	char *p = rap->r_nparam;
2594bff34e3Sthurlow 	char ptype = *p;
2604bff34e3Sthurlow 	int error, plen;
2614bff34e3Sthurlow 
2624bff34e3Sthurlow 	error = smb_rap_parserqparam(p, &p, &plen);
2634bff34e3Sthurlow 	if (error)
2644bff34e3Sthurlow 		return (error);
2654bff34e3Sthurlow 	switch (ptype) {
2664bff34e3Sthurlow 	case 'L':
2674bff34e3Sthurlow 		rap->r_rcvbuflen = value;
2684bff34e3Sthurlow 		/* FALLTHROUGH */
2694bff34e3Sthurlow 	case 'W':
2704bff34e3Sthurlow 	case 'D':
2714bff34e3Sthurlow 	case 'b':
2724bff34e3Sthurlow 		error = smb_rap_rqparam(rap, ptype, plen, value);
2734bff34e3Sthurlow 		break;
2744bff34e3Sthurlow 	default:
2754bff34e3Sthurlow 		return (EINVAL);
2764bff34e3Sthurlow 	}
2774bff34e3Sthurlow 	rap->r_nparam = p;
2784bff34e3Sthurlow 	return (0);
2794bff34e3Sthurlow }
2804bff34e3Sthurlow 
2814bff34e3Sthurlow int
smb_rap_setPparam(struct smb_rap * rap,void * value)2824bff34e3Sthurlow smb_rap_setPparam(struct smb_rap *rap, void *value)
2834bff34e3Sthurlow {
2844bff34e3Sthurlow 	char *p = rap->r_nparam;
2854bff34e3Sthurlow 	char ptype = *p;
2864bff34e3Sthurlow 	int error, plen;
2874bff34e3Sthurlow 
2884bff34e3Sthurlow 	error = smb_rap_parserqparam(p, &p, &plen);
2894bff34e3Sthurlow 	if (error)
2904bff34e3Sthurlow 		return (error);
2914bff34e3Sthurlow 	switch (ptype) {
2924bff34e3Sthurlow 	case 'r':
2934bff34e3Sthurlow 		rap->r_rcvbuf = value;
2944bff34e3Sthurlow 		break;
2954bff34e3Sthurlow 	default:
2964bff34e3Sthurlow 		return (EINVAL);
2974bff34e3Sthurlow 	}
2984bff34e3Sthurlow 	rap->r_nparam = p;
2994bff34e3Sthurlow 	return (0);
3004bff34e3Sthurlow }
3014bff34e3Sthurlow 
3029c9af259SGordon Ross int
smb_rap_getNparam(struct smb_rap * rap,long * value)3034bff34e3Sthurlow smb_rap_getNparam(struct smb_rap *rap, long *value)
3044bff34e3Sthurlow {
3054bff34e3Sthurlow 	char *p = rap->r_nparam;
3064bff34e3Sthurlow 	char ptype = *p;
3074bff34e3Sthurlow 	int error, plen;
3084bff34e3Sthurlow 	uint16_t	*te;
3094bff34e3Sthurlow 
3104bff34e3Sthurlow 	error = smb_rap_parserpparam(p, &p, &plen);
3114bff34e3Sthurlow 	if (error)
3124bff34e3Sthurlow 		return (error);
3134bff34e3Sthurlow 	switch (ptype) {
3144bff34e3Sthurlow 	case 'h':
3154bff34e3Sthurlow 		/* LINTED */
3164bff34e3Sthurlow 		te = (uint16_t *)rap->r_npbuf;
3174bff34e3Sthurlow 		*value = letohs(*te);
3184bff34e3Sthurlow 		break;
3194bff34e3Sthurlow 	default:
3204bff34e3Sthurlow 		return (EINVAL);
3214bff34e3Sthurlow 	}
3224bff34e3Sthurlow 	rap->r_npbuf += plen;
3234bff34e3Sthurlow 	rap->r_nparam = p;
3244bff34e3Sthurlow 	return (0);
3254bff34e3Sthurlow }
3264bff34e3Sthurlow 
3274bff34e3Sthurlow int
smb_rap_request(struct smb_rap * rap,struct smb_ctx * ctx)3284bff34e3Sthurlow smb_rap_request(struct smb_rap *rap, struct smb_ctx *ctx)
3294bff34e3Sthurlow {
3304bff34e3Sthurlow 	uint16_t *rp, conv, *tmp;
331613a2f6bSGordon Ross 	uint32_t *p32;
3324bff34e3Sthurlow 	char *dp, *p = rap->r_nparam;
3334bff34e3Sthurlow 	char ptype;
334613a2f6bSGordon Ross 	int error, rdatacnt, rparamcnt, entries, done, dlen, buffer_oflow;
3354bff34e3Sthurlow 
3364bff34e3Sthurlow 	rdatacnt = rap->r_rcvbuflen;
3374bff34e3Sthurlow 	rparamcnt = rap->r_plen;
338*430b4c46SGordon Ross 	error = smb_t2_request(ctx->ct_dev_fd,
339*430b4c46SGordon Ross 	    0, NULL, "\\PIPE\\LANMAN",
3404bff34e3Sthurlow 	    rap->r_plen, rap->r_pbuf,		/* int tparamcnt,void *tparam */
3414bff34e3Sthurlow 	    0, NULL,				/* int tdatacnt, void *tdata */
3424bff34e3Sthurlow 	    &rparamcnt, rap->r_pbuf,		/* rparamcnt, void *rparam */
3434bff34e3Sthurlow 	    &rdatacnt, rap->r_rcvbuf,		/* int *rdatacnt, void *rdata */
3444bff34e3Sthurlow 	    &buffer_oflow);
3454bff34e3Sthurlow 	if (error)
3464bff34e3Sthurlow 		return (error);
3474bff34e3Sthurlow 
3484bff34e3Sthurlow 	/* LINTED */
3494bff34e3Sthurlow 	rp = (uint16_t *)rap->r_pbuf;
3504bff34e3Sthurlow 
3514bff34e3Sthurlow 	/*
3524bff34e3Sthurlow 	 * Note: First is a "LanMan API" error code.
3534bff34e3Sthurlow 	 * See: usr/src/uts/common/smbsrv/lmerr.h
3544bff34e3Sthurlow 	 */
3554bff34e3Sthurlow 	if (rparamcnt < 2)
3564bff34e3Sthurlow 		return (EBADRPC);
3574bff34e3Sthurlow 	rap->r_result = letohs(*rp);
3584bff34e3Sthurlow 	rp++; rparamcnt -= 2;
3594bff34e3Sthurlow 
3604bff34e3Sthurlow 	if (rap->r_result != 0) {
3614bff34e3Sthurlow 		/*
3624bff34e3Sthurlow 		 * Could also return zero and let the caller
3634bff34e3Sthurlow 		 * come get r_result via smb_rap_error(),
3644bff34e3Sthurlow 		 * but in case they dont...
3654bff34e3Sthurlow 		 */
3664bff34e3Sthurlow 		return (rap->r_result | SMB_RAP_ERROR);
3674bff34e3Sthurlow 	}
3684bff34e3Sthurlow 
3694bff34e3Sthurlow 	if (rparamcnt < 2)
3704bff34e3Sthurlow 		return (EBADRPC);
3714bff34e3Sthurlow 	conv = letohs(*rp);
3724bff34e3Sthurlow 	rp++; rparamcnt -= 2;
3734bff34e3Sthurlow 
3744bff34e3Sthurlow 	rap->r_npbuf = (char *)rp;
3754bff34e3Sthurlow 	rap->r_entries = entries = 0;
3764bff34e3Sthurlow 	/* Save the returned data length */
3774bff34e3Sthurlow 	rap->r_rcvbuflen = rdatacnt;
3784bff34e3Sthurlow 	done = 0;
3794bff34e3Sthurlow 
3804bff34e3Sthurlow 	while (!done && *p) {
3814bff34e3Sthurlow 		ptype = *p;
3824bff34e3Sthurlow 		switch (ptype) {
3834bff34e3Sthurlow 		case 'e':
3844bff34e3Sthurlow 			if (rparamcnt < 2)
3854bff34e3Sthurlow 				return (EBADRPC);
3864bff34e3Sthurlow 			/* LINTED */
3874bff34e3Sthurlow 			tmp = (uint16_t *)rap->r_npbuf;
3884bff34e3Sthurlow 			rap->r_entries = entries = letohs(*tmp);
3894bff34e3Sthurlow 			rap->r_npbuf += 2;
3904bff34e3Sthurlow 			rparamcnt -= 2;
3914bff34e3Sthurlow 			p++;
3924bff34e3Sthurlow 			break;
3934bff34e3Sthurlow 		default:
3944bff34e3Sthurlow 			done = 1;
3954bff34e3Sthurlow 		}
3964bff34e3Sthurlow #if 0	/* commented out in Darwin. Why? */
3974bff34e3Sthurlow 		error = smb_rap_parserpparam(p, &p, &plen);
3984bff34e3Sthurlow 		if (error) {
3994bff34e3Sthurlow 			smb_error(dgettext(TEXT_DOMAIN,
4004bff34e3Sthurlow 			    "reply parameter mismatch %s"), 0, p);
4014bff34e3Sthurlow 			return (EBADRPC);
4024bff34e3Sthurlow 		}
4034bff34e3Sthurlow #endif
4044bff34e3Sthurlow 	}
4054bff34e3Sthurlow 	rap->r_nparam = p;
4064bff34e3Sthurlow 	/*
4074bff34e3Sthurlow 	 * In general, unpacking entries we may need to relocate
4084bff34e3Sthurlow 	 * entries for proper aligning. For now use them as is.
4094bff34e3Sthurlow 	 */
4104bff34e3Sthurlow 	dp = rap->r_rcvbuf;
4114bff34e3Sthurlow 	while (entries--) {
4124bff34e3Sthurlow 		p = rap->r_sdata;
4134bff34e3Sthurlow 		while (*p) {
4144bff34e3Sthurlow 			ptype = *p;
4154bff34e3Sthurlow 			error = smb_rap_parserpdata(p, &p, &dlen);
4164bff34e3Sthurlow 			if (error) {
4174bff34e3Sthurlow 				smb_error(dgettext(TEXT_DOMAIN,
4184bff34e3Sthurlow 				    "reply data mismatch %s"), 0, p);
4194bff34e3Sthurlow 				return (EBADRPC);
4204bff34e3Sthurlow 			}
4214bff34e3Sthurlow 			if (rdatacnt < dlen)
4224bff34e3Sthurlow 				return (EBADRPC);
4234bff34e3Sthurlow 			switch (ptype) {
4244bff34e3Sthurlow 			case 'z':
4254bff34e3Sthurlow 				/* LINTED */
4264bff34e3Sthurlow 				p32 = (uint32_t *)dp;
4274bff34e3Sthurlow 				*p32 = (letohl(*p32) & 0xffff) - conv;
4284bff34e3Sthurlow 				break;
4294bff34e3Sthurlow 			}
4304bff34e3Sthurlow 			dp += dlen;
4314bff34e3Sthurlow 			rdatacnt -= dlen;
4324bff34e3Sthurlow 		}
4334bff34e3Sthurlow 	}
4344bff34e3Sthurlow 	return (error);
4354bff34e3Sthurlow }
4364bff34e3Sthurlow 
4374bff34e3Sthurlow int
smb_rap_error(struct smb_rap * rap,int error)4384bff34e3Sthurlow smb_rap_error(struct smb_rap *rap, int error)
4394bff34e3Sthurlow {
4404bff34e3Sthurlow 	if (error)
4414bff34e3Sthurlow 		return (error);
4424bff34e3Sthurlow 	if (rap->r_result == 0)
4434bff34e3Sthurlow 		return (0);
4444bff34e3Sthurlow 	return (rap->r_result | SMB_RAP_ERROR);
4454bff34e3Sthurlow }
446