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 36 static int wkssvc_s_NetWkstaGetInfo(void *, ndr_xa_t *); 37 static int wkssvc_s_NetWkstaTransportEnum(void *, ndr_xa_t *); 38 39 static 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 45 static 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 60 void 61 wkssvc_initialize(void) 62 { 63 (void) ndr_svc_register(&wkssvc_service); 64 } 65 66 /* 67 * WKSSVC NetWkstaGetInfo 68 */ 69 static int 70 wkssvc_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 */ 168 static int 169 wkssvc_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