1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  *
  26  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 /*
  30  * Show information about the remote server, as offered by
  31  * NetServerGetInfo with SERVER_INFO_101
  32  */
  33 
  34 #include <sys/types.h>
  35 
  36 #include <errno.h>
  37 #include <stdio.h>
  38 #include <stdlib.h>
  39 #include <string.h>
  40 #include <libintl.h>
  41 
  42 #include <libmlrpc/libmlrpc.h>
  43 #include <netsmb/smb_lib.h>
  44 #include "srvsvc1_clnt.h"
  45 #include "common.h"
  46 
  47 
  48 static int get_info(smb_ctx_t *);
  49 
  50 void
  51 info_usage(void)
  52 {
  53         printf(gettext("usage: smbutil info [connection options] //"
  54             "[workgroup;][user[:password]@]server\n"));
  55         exit(1);
  56 }
  57 
  58 int
  59 cmd_info(int argc, char *argv[])
  60 {
  61         struct smb_ctx *ctx;
  62         int error, err2, opt;
  63 
  64         if (argc < 2)
  65                 info_usage();
  66 
  67         error = smb_ctx_alloc(&ctx);
  68         if (error)
  69                 return (error);
  70 
  71         error = smb_ctx_scan_argv(ctx, argc, argv,
  72             SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
  73         if (error)
  74                 goto out;
  75 
  76         error = smb_ctx_readrc(ctx);
  77         if (error)
  78                 goto out;
  79 
  80         while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
  81                 if (opt == '?')
  82                         info_usage();
  83                 error = smb_ctx_opt(ctx, opt, optarg);
  84                 if (error)
  85                         goto out;
  86         }
  87 
  88         smb_ctx_setshare(ctx, "IPC$", USE_IPC);
  89 
  90         /*
  91          * Resolve the server address,
  92          * setup derived defaults.
  93          */
  94         error = smb_ctx_resolve(ctx);
  95         if (error)
  96                 goto out;
  97 
  98         /*
  99          * Have server, share, etc. from above:
 100          * smb_ctx_scan_argv, option settings.
 101          * Get the session and tree.
 102          */
 103 again:
 104         error = smb_ctx_get_ssn(ctx);
 105         if (error == EAUTH) {
 106                 err2 = smb_get_authentication(ctx);
 107                 if (err2 == 0)
 108                         goto again;
 109         }
 110         if (error) {
 111                 smb_error(gettext("//%s: login failed"),
 112                     error, ctx->ct_fullserver);
 113                 goto out;
 114         }
 115 
 116         error = smb_ctx_get_tree(ctx);
 117         if (error) {
 118                 smb_error(gettext("//%s/%s: tree connect failed"),
 119                     error, ctx->ct_fullserver, ctx->ct_origshare);
 120                 goto out;
 121         }
 122 
 123         /*
 124          * Have IPC$ tcon.  Get the server info.
 125          */
 126         error = get_info(ctx);
 127         if (error)
 128                 smb_error("cannot get server info.", error);
 129 
 130 out:
 131         smb_ctx_free(ctx);
 132         return (error);
 133 }
 134 
 135 int
 136 get_info(smb_ctx_t *ctx)
 137 {
 138         char pf_unk[32];
 139         mlrpc_handle_t handle;
 140         ndr_service_t *svc;
 141         union mslm_NetServerGetInfo_ru res;
 142         struct mslm_SERVER_INFO_101 *sv101;
 143         char *platform_name;
 144         int err;
 145 
 146         /*
 147          * Create an RPC handle using the smb_ctx we already have.
 148          * Just local allocation and initialization.
 149          */
 150         srvsvc1_initialize();
 151         svc = ndr_svc_lookup_name("srvsvc");
 152         if (svc == NULL)
 153                 return (ENOENT);
 154 
 155         err = mlrpc_clh_create(&handle, ctx);
 156         if (err)
 157                 return (err);
 158 
 159         /*
 160          * Try to bind to the RPC service.  If it fails,
 161          * just return the error and the caller will
 162          * fall back to RAP.
 163          */
 164         err = mlrpc_clh_bind(&handle, svc);
 165         if (err)
 166                 goto out;
 167 
 168         err = srvsvc_net_server_getinfo(&handle,
 169             ctx->ct_fullserver, 101, &res);
 170         if (err)
 171                 goto out;
 172 
 173         sv101 = res.info101;
 174 
 175         switch (sv101->sv101_platform_id) {
 176         case SV_PLATFORM_ID_DOS:
 177                 platform_name = "DOS";
 178                 break;
 179         case SV_PLATFORM_ID_OS2:
 180                 platform_name = "OS2";
 181                 break;
 182         case SV_PLATFORM_ID_NT:
 183                 platform_name = "NT";
 184                 break;
 185         case SV_PLATFORM_ID_OSF:
 186                 platform_name = "OSF";
 187                 break;
 188         case SV_PLATFORM_ID_VMS:
 189                 platform_name = "VMS";
 190                 break;
 191         default:
 192                 platform_name = pf_unk;
 193                 snprintf(pf_unk, sizeof (pf_unk), "(%d)",
 194                     sv101->sv101_platform_id);
 195                 break;
 196         }
 197 
 198         printf("server info:\n");
 199         printf(" platform_id %s\n", platform_name);
 200         printf(" vers.major  %d\n", sv101->sv101_version_major);
 201         printf(" vers.minor  %d\n", sv101->sv101_version_minor);
 202 
 203         if (smb_verbose)
 204                 printf(" type_flags  0x%x\n", sv101->sv101_type);
 205 
 206         printf(" name    \"%s\"\n", sv101->sv101_name);
 207         printf(" comment \"%s\"\n", sv101->sv101_comment);
 208 
 209 out:
 210         (void) mlrpc_clh_free(&handle);
 211         return (err);
 212 }