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