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
info_usage(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
cmd_info(int argc,char * argv[])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
get_info(smb_ctx_t * ctx)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 }
213