wkssvc_svc.c revision 12508:edb7861a1533
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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26#include <netdb.h>
27#include <sys/types.h>
28#include <string.h>
29#include <strings.h>
30#include <smbsrv/libsmb.h>
31#include <smbsrv/libmlsvc.h>
32#include <smbsrv/smbinfo.h>
33#include <smbsrv/nmpipes.h>
34#include <smbsrv/ndl/srvsvc.ndl>
35
36static int wkssvc_s_NetWkstaGetInfo(void *, ndr_xa_t *);
37static int wkssvc_s_NetWkstaTransportEnum(void *, ndr_xa_t *);
38
39static ndr_stub_table_t wkssvc_stub_table[] = {
40	{ wkssvc_s_NetWkstaGetInfo,	WKSSVC_OPNUM_NetWkstaGetInfo },
41	{ wkssvc_s_NetWkstaTransportEnum, WKSSVC_OPNUM_NetWkstaTransportEnum },
42	{0}
43};
44
45static ndr_service_t wkssvc_service = {
46	"Workstation",			/* name (WKSSVC or WKSTA) */
47	"Workstation services",		/* desc */
48	"\\wkssvc",			/* endpoint */
49	PIPE_NTSVCS,			/* sec_addr_port */
50	"6bffd098-a112-3610-9833-46c3f87e345a", 1,	/* abstract */
51	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
52	0,				/* no bind_instance_size */
53	0,				/* no bind_req() */
54	0,				/* no unbind_and_close() */
55	0,				/* use generic_call_stub() */
56	&TYPEINFO(wkssvc_interface),	/* interface ti */
57	wkssvc_stub_table		/* stub_table */
58};
59
60void
61wkssvc_initialize(void)
62{
63	(void) ndr_svc_register(&wkssvc_service);
64}
65
66/*
67 * WKSSVC NetWkstaGetInfo
68 */
69static int
70wkssvc_s_NetWkstaGetInfo(void *arg, ndr_xa_t *mxa)
71{
72	struct mslm_NetWkstaGetInfo *param = arg;
73	mslm_NetWkstaGetInfo_rb *rb;
74	char hostname[MAXHOSTNAMELEN];
75	char resource_domain[SMB_PI_MAX_DOMAIN];
76	smb_version_t version;
77	char *name;
78	char *domain;
79	DWORD status;
80	int rc;
81
82	(void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN);
83
84	rb = NDR_NEW(mxa, mslm_NetWkstaGetInfo_rb);
85
86	if ((rc = smb_getnetbiosname(hostname, MAXHOSTNAMELEN)) == 0) {
87		name = NDR_STRDUP(mxa, hostname);
88		domain = NDR_STRDUP(mxa, resource_domain);
89	}
90
91	if ((rc != 0) || (rb == NULL) || (name == NULL) || (domain == NULL)) {
92		bzero(param, sizeof (struct mslm_NetWkstaGetInfo));
93		param->status = ERROR_NOT_ENOUGH_MEMORY;
94		return (NDR_DRC_OK);
95	}
96
97	smb_config_get_version(&version);
98
99	param->result.level = param->level;
100	param->result.bufptr.nullptr = (void *)rb;
101
102	switch (param->level) {
103	case 100:
104		rb->buf100.wki100_platform_id = SV_PLATFORM_ID_NT;
105		rb->buf100.wki100_ver_major = version.sv_major;
106		rb->buf100.wki100_ver_minor = version.sv_minor;
107		rb->buf100.wki100_computername = (unsigned char *)name;
108		rb->buf100.wki100_langroup = (unsigned char *)domain;
109		status = ERROR_SUCCESS;
110		break;
111
112	case 101:
113		rb->buf101.wki101_platform_id = SV_PLATFORM_ID_NT;
114		rb->buf101.wki101_ver_major = version.sv_major;
115		rb->buf101.wki101_ver_minor = version.sv_minor;
116		rb->buf101.wki101_computername = (unsigned char *)name;
117		rb->buf101.wki101_langroup = (unsigned char *)domain;
118		rb->buf101.wki101_lanroot = (unsigned char *)"";
119		status = ERROR_SUCCESS;
120		break;
121
122	case 102:
123		rb->buf102.wki102_platform_id = SV_PLATFORM_ID_NT;
124		rb->buf102.wki102_ver_major = version.sv_major;
125		rb->buf102.wki102_ver_minor = version.sv_minor;
126		rb->buf102.wki102_computername = (unsigned char *)name;
127		rb->buf102.wki102_langroup = (unsigned char *)domain;
128		rb->buf102.wki102_lanroot = (unsigned char *)"";
129		rb->buf102.wki102_logged_on_users = 1;
130		status = ERROR_SUCCESS;
131		break;
132
133	case 502:
134		bzero(&rb->buf502, sizeof (struct mslm_WKSTA_INFO_502));
135		rb->buf502.keep_connection = 600;
136		rb->buf502.max_commands = 1024;
137		rb->buf502.session_timeout = 5400;
138		rb->buf502.size_char_buf = 1024;
139		rb->buf502.max_threads = 1024;
140		rb->buf502.use_opportunistic_locking = 1;
141		rb->buf502.use_unlock_behind = 1;
142		rb->buf502.use_close_behind = 1;
143		rb->buf502.buf_named_pipes = 1;
144		rb->buf502.use_lock_read_unlock = 1;
145		rb->buf502.utilize_nt_caching = 1;
146		rb->buf502.use_raw_read = 1;
147		rb->buf502.use_raw_write = 1;
148		status = ERROR_SUCCESS;
149		break;
150
151	default:
152		param->result.bufptr.nullptr = 0;
153		status = ERROR_INVALID_LEVEL;
154		break;
155	}
156
157	if (status != ERROR_SUCCESS) {
158		bzero(param, sizeof (struct mslm_NetWkstaGetInfo));
159		param->status = status;
160	}
161
162	return (NDR_DRC_OK);
163}
164
165/*
166 * WKSSVC NetWkstaTransportEnum
167 */
168static int
169wkssvc_s_NetWkstaTransportEnum(void *arg, ndr_xa_t *mxa)
170{
171	struct mslm_NetWkstaTransportEnum *param = arg;
172	struct mslm_NetWkstaTransportCtr0 *info0;
173	struct mslm_NetWkstaTransportInfo0 *ti0;
174
175	switch (param->info.level) {
176	case 0:
177		info0 = NDR_NEW(mxa, struct mslm_NetWkstaTransportCtr0);
178		ti0 = NDR_NEW(mxa, struct mslm_NetWkstaTransportInfo0);
179
180		if (info0 == NULL || ti0 == NULL) {
181			bzero(param, sizeof (struct mslm_NetWkstaGetInfo));
182			param->status = ERROR_NOT_ENOUGH_MEMORY;
183			break;
184		}
185
186		ti0->quality_of_service = 65535;
187		ti0->num_vcs = 0;
188		ti0->transport_name = (unsigned char *)"\\Device\\NetbiosSmb";
189		ti0->transport_address = (unsigned char *)"000000000000";
190		ti0->wan_ish = 1024;
191
192		info0->count = 1;
193		info0->ti0 = ti0;
194		param->info.ru.info0 = info0;
195		param->total_entries = 1;
196
197		if (param->resume_handle)
198			*param->resume_handle = 0;
199
200		param->status = ERROR_SUCCESS;
201		break;
202
203	default:
204		bzero(param, sizeof (struct mslm_NetWkstaGetInfo));
205		param->status = ERROR_INVALID_LEVEL;
206	}
207
208	return (NDR_DRC_OK);
209}
210