1 /*
   2  * Copyright (c) 2000-2002, Boris Popov
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. All advertising materials mentioning features or use of this software
  14  *    must display the following acknowledgement:
  15  *    This product includes software developed by Boris Popov.
  16  * 4. Neither the name of the author nor the names of any co-contributors
  17  *    may be used to endorse or promote products derived from this software
  18  *    without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30  * SUCH DAMAGE.
  31  *
  32  * from: Id: view.c,v 1.9 2002/02/20 09:26:42 bp Exp
  33  */
  34 
  35 /*
  36  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  37  */
  38 
  39 #include <errno.h>
  40 #include <stdio.h>
  41 #include <stdlib.h>
  42 #include <string.h>
  43 
  44 #include <netsmb/mchain.h>        /* letohs, etc. */
  45 #include <netsmb/smb.h>
  46 #include <netsmb/smb_lib.h>
  47 #include <netsmb/smb_rap.h>
  48 
  49 #include "common.h"
  50 
  51 /*
  52  * Enumerate shares using Remote Administration Protocol (RAP)
  53  * Was in libsmbfs netshareenum.c
  54  */
  55 
  56 struct smb_share_info_1 {
  57         char            shi1_netname[13];
  58         char            shi1_pad;
  59         uint16_t        shi1_type;
  60         uint32_t        shi1_remark;            /* char * */
  61 };
  62 
  63 static int
  64 smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
  65         int *cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
  66 {
  67         struct smb_rap *rap;
  68         long lval = -1;
  69         int error;
  70 
  71         error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
  72         if (error)
  73                 return (error);
  74         smb_rap_setNparam(rap, sLevel);         /* W - sLevel */
  75         smb_rap_setPparam(rap, pbBuffer);       /* r - pbBuffer */
  76         smb_rap_setNparam(rap, *cbBuffer);      /* L - cbBuffer */
  77         error = smb_rap_request(rap, ctx);
  78         if (error == 0) {
  79                 *pcEntriesRead = rap->r_entries;
  80                 error = smb_rap_getNparam(rap, &lval);
  81                 *pcTotalAvail = lval;
  82                 /* Copy the data length into the IN/OUT variable. */
  83                 *cbBuffer = rap->r_rcvbuflen;
  84         }
  85         error = smb_rap_error(rap, error);
  86         smb_rap_done(rap);
  87         return (error);
  88 }
  89 
  90 int
  91 share_enum_rap(smb_ctx_t *ctx)
  92 {
  93         struct smb_share_info_1 *shi;
  94         void *rpbuf;
  95         char *cp;
  96         int error, bufsize, i, rcnt, total;
  97         int lbound, rbound;
  98         uint16_t type;
  99 
 100         bufsize = 0xffe0;       /* samba notes win2k bug for 65535 */
 101         rpbuf = malloc(bufsize);
 102         if (rpbuf == NULL)
 103                 return (errno);
 104 
 105         error = smb_rap_NetShareEnum(ctx, 1, rpbuf, &bufsize, &rcnt, &total);
 106         if (error &&
 107             error != (ERROR_MORE_DATA | SMB_RAP_ERROR))
 108                 goto out;
 109 
 110         /*
 111          * Bounds for offsets to comments strings.
 112          * After the array, and before the end.
 113          */
 114         lbound = rcnt * (sizeof (struct smb_share_info_1));
 115         rbound = bufsize;
 116 
 117         /* Print the header line. */
 118         view_print_share(NULL, 0, NULL);
 119 
 120         for (shi = rpbuf, i = 0; i < rcnt; i++, shi++) {
 121                 type = letohs(shi->shi1_type);
 122 
 123                 shi->shi1_pad = '\0'; /* ensure null termination */
 124 
 125                 /*
 126                  * Offsets to comment strings can be trash.
 127                  * Only print when the offset is valid.
 128                  */
 129                 if (shi->shi1_remark >= lbound &&
 130                     shi->shi1_remark < rbound) {
 131                         cp = (char *)rpbuf + shi->shi1_remark;
 132                 } else
 133                         cp = NULL;
 134 
 135                 /* Convert from OEM to local codeset? */
 136                 view_print_share(shi->shi1_netname, type, cp);
 137         }
 138         error = 0;
 139 
 140 out:
 141         free(rpbuf);
 142         return (error);
 143 }