4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copyright (c) 2000, Boris Popov
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Redistribution and use in source and binary forms, with or without
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * modification, are permitted provided that the following conditions
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * are met:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 1. Redistributions of source code must retain the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 2. Redistributions in binary form must reproduce the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer in the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * documentation and/or other materials provided with the distribution.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 3. All advertising materials mentioning features or use of this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * must display the following acknowledgement:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This product includes software developed by Boris Popov.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 4. Neither the name of the author nor the names of any co-contributors
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * may be used to endorse or promote products derived from this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * without specific prior written permission.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SUCH DAMAGE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * $Id: rap.c,v 1.5 2004/12/13 00:25:23 lindak Exp $
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This is very simple implementation of RAP protocol.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/param.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/errno.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/stat.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/isa_defs.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <ctype.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdio.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <unistd.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <strings.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdlib.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <libintl.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sysexits.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/mchain.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_lib.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_rap.h>
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross#include "private.h"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_parserqparam(const char *s, char **next, int *rlen)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *np;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (*s++) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'L':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'T':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'W':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'D':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'O':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 4;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'b':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'F':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'r':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 's':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EINVAL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (isdigit(*s)) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len *= strtoul(s, &np, 10);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow s = np;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *rlen = len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *(const char **)next = s;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_parserpparam(const char *s, char **next, int *rlen)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *np;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int len = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (*s++) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'e':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'h':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'i':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 4;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'g':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EINVAL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (isdigit(*s)) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len *= strtoul(s, &np, 10);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow s = np;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *rlen = len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *(const char **)next = s;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_parserpdata(const char *s, char **next, int *rlen)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *np;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (*s++) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'B':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'W':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'D':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'O':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'z':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 4;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EINVAL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (isdigit(*s)) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len *= strtoul(s, &np, 10);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow s = np;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *rlen = len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *(const char **)next = s;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_rqparam_z(struct smb_rap *rap, const char *value)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int len = strlen(value) + 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow bcopy(value, rap->r_npbuf, len);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_npbuf += len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_plen += len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Marshal RAP request parameters.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note: value is in host order.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_rqparam(struct smb_rap *rap, char ptype, char plen, int value)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int len = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow uint_t uv = (uint_t)value;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t *lp;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint16_t *sp;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross char *p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (ptype) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'L':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'W':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* LINTED */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross sp = (uint16_t *)rap->r_npbuf;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross *sp = htoles(uv);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross len = sizeof (*sp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'D':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* LINTED */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross lp = (uint32_t *)rap->r_npbuf;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross *lp = htolel(uv);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross len = sizeof (*lp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'b':
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross p = rap->r_npbuf;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow memset(p, uv, plen);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = plen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EINVAL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_npbuf += len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_plen += len;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_create(int fn, const char *param, const char *data,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_rap **rapp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_rap *rap;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int plen = 0, len = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap = malloc(sizeof (*rap));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap == NULL)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (ENOMEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow bzero(rap, sizeof (*rap));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow p = rap->r_sparam = rap->r_nparam = strdup(param);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_sdata = rap->r_ndata = strdup(data);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Calculate length of request parameter block
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len = 2 + strlen(param) + 1 + strlen(data) + 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (*p) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (smb_rap_parserqparam(p, &p, &plen) != 0)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow len += plen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_pbuf = rap->r_npbuf = malloc(len);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (rap->r_pbuf == NULL)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross return (ENOMEM);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (void) smb_rap_rqparam(rap, 'W', 1, fn);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (void) smb_rap_rqparam_z(rap, rap->r_sparam);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (void) smb_rap_rqparam_z(rap, rap->r_sdata);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *rapp = rap;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_done(struct smb_rap *rap)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap->r_sparam)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free(rap->r_sparam);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap->r_sdata)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free(rap->r_sdata);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap->r_pbuf)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free(rap->r_pbuf);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#ifdef NOTYETDEFINED
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap->r_npbuf)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free(rap->r_npbuf);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap->r_dbuf)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free(rap->r_dbuf);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap->r_rcvbuf)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free(rap->r_rcvbuf);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#endif
4bff34e37def8a90f9194d81bc345c52ba20086athurlow free(rap);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_setNparam(struct smb_rap *rap, int value)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *p = rap->r_nparam;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char ptype = *p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error, plen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rap_parserqparam(p, &p, &plen);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (ptype) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'L':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_rcvbuflen = value;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* FALLTHROUGH */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'W':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'D':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'b':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rap_rqparam(rap, ptype, plen, value);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EINVAL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_nparam = p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_setPparam(struct smb_rap *rap, void *value)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *p = rap->r_nparam;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char ptype = *p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error, plen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rap_parserqparam(p, &p, &plen);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (ptype) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'r':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_rcvbuf = value;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EINVAL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_nparam = p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Rossint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_getNparam(struct smb_rap *rap, long *value)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *p = rap->r_nparam;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char ptype = *p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error, plen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow uint16_t *te;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rap_parserpparam(p, &p, &plen);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (ptype) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'h':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* LINTED */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow te = (uint16_t *)rap->r_npbuf;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *value = letohs(*te);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EINVAL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_npbuf += plen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_nparam = p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_request(struct smb_rap *rap, struct smb_ctx *ctx)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow uint16_t *rp, conv, *tmp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint32_t *p32;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *dp, *p = rap->r_nparam;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char ptype;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int error, rdatacnt, rparamcnt, entries, done, dlen, buffer_oflow;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rdatacnt = rap->r_rcvbuflen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rparamcnt = rap->r_plen;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_t2_request(ctx->ct_dev_fd,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross 0, NULL, "\\PIPE\\LANMAN",
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_plen, rap->r_pbuf, /* int tparamcnt,void *tparam */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow 0, NULL, /* int tdatacnt, void *tdata */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &rparamcnt, rap->r_pbuf, /* rparamcnt, void *rparam */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &rdatacnt, rap->r_rcvbuf, /* int *rdatacnt, void *rdata */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow &buffer_oflow);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* LINTED */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rp = (uint16_t *)rap->r_pbuf;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note: First is a "LanMan API" error code.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * See: usr/src/uts/common/smbsrv/lmerr.h
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rparamcnt < 2)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EBADRPC);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_result = letohs(*rp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rp++; rparamcnt -= 2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap->r_result != 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Could also return zero and let the caller
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * come get r_result via smb_rap_error(),
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * but in case they dont...
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (rap->r_result | SMB_RAP_ERROR);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rparamcnt < 2)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EBADRPC);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow conv = letohs(*rp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rp++; rparamcnt -= 2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_npbuf = (char *)rp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_entries = entries = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Save the returned data length */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_rcvbuflen = rdatacnt;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow done = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (!done && *p) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ptype = *p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (ptype) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'e':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rparamcnt < 2)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EBADRPC);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* LINTED */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow tmp = (uint16_t *)rap->r_npbuf;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_entries = entries = letohs(*tmp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_npbuf += 2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rparamcnt -= 2;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow p++;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow done = 1;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#if 0 /* commented out in Darwin. Why? */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rap_parserpparam(p, &p, &plen);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_error(dgettext(TEXT_DOMAIN,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow "reply parameter mismatch %s"), 0, p);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EBADRPC);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#endif
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rap->r_nparam = p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * In general, unpacking entries we may need to relocate
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * entries for proper aligning. For now use them as is.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow dp = rap->r_rcvbuf;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (entries--) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow p = rap->r_sdata;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (*p) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ptype = *p;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rap_parserpdata(p, &p, &dlen);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_error(dgettext(TEXT_DOMAIN,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow "reply data mismatch %s"), 0, p);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EBADRPC);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rdatacnt < dlen)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (EBADRPC);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (ptype) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'z':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* LINTED */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow p32 = (uint32_t *)dp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *p32 = (letohl(*p32) & 0xffff) - conv;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow dp += dlen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rdatacnt -= dlen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rap_error(struct smb_rap *rap, int error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rap->r_result == 0)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (rap->r_result | SMB_RAP_ERROR);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}