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 * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 26 */ 27 28 /* 29 * This module defines generic functions to map Native OS and Native 30 * LanMan names to values. 31 */ 32 33 #if defined(_KERNEL) || defined(_FAKE_KERNEL) 34 #include <sys/types.h> 35 #include <sys/sunddi.h> 36 #else 37 #include <string.h> 38 #endif 39 #include <smbsrv/string.h> 40 #include <smbsrv/smbinfo.h> 41 42 typedef struct smb_native { 43 int sn_value; 44 const char *sn_name; 45 } smb_native_t; 46 47 /* 48 * smbnative_os_value 49 * 50 * Return the appropriate native OS value for the specified native OS name. 51 * 52 * Example OS values used by Windows: 53 * 54 * Windows 4.0, Windows NT, Windows NT 4.0 55 * Windows 5.0, Windows 5.1 56 * Windows 2000, Windows 2000 5.0, Windows 2000 5.1 57 * Windows 2002 58 * Windows .NET 59 * Windows Server 2003 60 * Windows XP 61 * 62 * Windows 2000 server: "Windows 2000 2195" 63 * Windows XP Professional client: "Windows 2002 2543" 64 * Windows XP PDC server: "Windows 5.1" 65 * Windows .Net: "Windows .NET 3621" 66 * Windows .Net: "Windows .NET 3718" 67 * 68 * DAVE (Thursby Software: CIFS for MacOS) uses "MacOS", sometimes with a 69 * version number appended, i.e. "MacOS 8.5.1". We treat DAVE like NT 4.0 70 * except for the cases that DAVE clients set 'watch tree' flag in notify 71 * change requests. 72 * 73 * Samba reports UNIX as its Native OS, which we can map to NT 4.0. 74 */ 75 int 76 smbnative_os_value(const char *native_os) 77 { 78 static smb_native_t os_table[] = { 79 { NATIVE_OS_WINNT, "Windows NT 4.0" }, 80 { NATIVE_OS_WINNT, "Windows NT" }, 81 { NATIVE_OS_WIN95, "Windows 4.0" }, 82 { NATIVE_OS_WIN2000, "Windows 5.0" }, 83 { NATIVE_OS_WIN2000, "Windows 5.1" }, 84 { NATIVE_OS_WIN2000, "Windows 2000" }, 85 { NATIVE_OS_WIN2000, "Windows 2002" }, 86 { NATIVE_OS_WIN2000, "Windows .NET" }, 87 { NATIVE_OS_WIN2000, "Windows Server" }, 88 { NATIVE_OS_WIN2000, "Windows XP" }, 89 { NATIVE_OS_WINNT, "UNIX" }, 90 { NATIVE_OS_MACOS, "MacOS" } 91 }; 92 93 int i; 94 int len; 95 const char *name; 96 97 if (native_os == NULL) 98 return (NATIVE_OS_UNKNOWN); 99 100 /* 101 * Windows Vista sends an empty native OS string. 102 */ 103 if (*native_os == '\0') 104 return (NATIVE_OS_WIN2000); 105 106 for (i = 0; i < sizeof (os_table)/sizeof (os_table[0]); ++i) { 107 name = os_table[i].sn_name; 108 len = strlen(name); 109 110 if (smb_strcasecmp(name, native_os, len) == 0) 111 return (os_table[i].sn_value); 112 } 113 114 return (NATIVE_OS_UNKNOWN); 115 } 116 117 /* 118 * smbnative_lm_value 119 * 120 * Return the appropriate native LanMan value for the specified native 121 * LanMan name. There's an alignment problem in some packets from some 122 * clients that means we can miss the first character, so we do an 123 * additional check starting from the second character. 124 * 125 * Example LanMan values: 126 * 127 * NT LAN Manager 4.0 128 * Windows 4.0 129 * Windows NT, Windows NT 4.0 130 * Windows 2000 LAN Manager 131 * Windows 2000, Windows 2000 5.0, Windows 2000 5.1 132 * Windows 2002, Windows 2002 5.1 133 * Windows .NET, Windows .NET 5.2 134 * Windows Server 2003 135 * Windows XP 136 * NETSMB (Solaris CIFS client) 137 * DAVE (Thursby Software: CIFS for MacOS) 138 * Samba 139 */ 140 int 141 smbnative_lm_value(const char *native_lm) 142 { 143 static smb_native_t lm_table[] = { 144 { NATIVE_LM_NT, "NT LAN Manager 4.0" }, 145 { NATIVE_LM_NT, "Windows NT" }, 146 { NATIVE_LM_NT, "Windows 4.0" }, 147 { NATIVE_LM_NT, "DAVE" } 148 }; 149 150 int i; 151 int len; 152 const char *name; 153 154 /* 155 * Windows Vista sends an empty native LM string. 156 */ 157 if (native_lm == NULL || *native_lm == '\0') 158 return (NATIVE_LM_WIN2000); 159 160 for (i = 0; i < sizeof (lm_table)/sizeof (lm_table[0]); ++i) { 161 name = lm_table[i].sn_name; 162 len = strlen(name); 163 164 if ((smb_strcasecmp(name, native_lm, len) == 0) || 165 (smb_strcasecmp(&name[1], native_lm, len - 1) == 0)) { 166 return (lm_table[i].sn_value); 167 } 168 } 169 170 return (NATIVE_LM_WIN2000); 171 } 172 173 /* 174 * smbnative_pdc_value 175 * 176 * This function is called when libsmbrdr connects to a PDC. 177 * The PDC type is derived from the Native LanMan string. 178 * The PDC value will default to PDC_WIN2000. 179 * 180 * Example strings: 181 * 182 * NT LAN Manager 4.0 183 * Windows 4.0, Windows NT, Windows NT 4.0 184 * Windows 2000 LAN Manager 185 * Windows 2000, Windows 2000 5.0, Windows 2000 5.1 186 * Windows 2002, Windows 2002 5.1 187 * Windows .NET, Windows .NET 5.2 188 * Samba 189 * DAVE 190 */ 191 int 192 smbnative_pdc_value(const char *native_lm) 193 { 194 static smb_native_t pdc_table[] = { 195 { PDC_WINNT, "NT LAN Manager 4.0" }, 196 { PDC_WINNT, "Windows NT 4.0" }, 197 { PDC_WINNT, "Windows NT" }, 198 { PDC_WINNT, "Windows 4.0" }, 199 { PDC_WINNT, "DAVE" }, 200 { PDC_SAMBA, "Samba" } 201 }; 202 203 int i; 204 int len; 205 const char *name; 206 207 if (native_lm == NULL || *native_lm == '\0') 208 return (PDC_WIN2000); 209 210 for (i = 0; i < sizeof (pdc_table)/sizeof (pdc_table[0]); ++i) { 211 name = pdc_table[i].sn_name; 212 len = strlen(name); 213 214 if ((smb_strcasecmp(name, native_lm, len) == 0) || 215 (smb_strcasecmp(&name[1], native_lm, len - 1) == 0)) { 216 return (pdc_table[i].sn_value); 217 } 218 } 219 220 return (PDC_WIN2000); 221 } 222 223 /* 224 * Returns the native OS string for the given OS version. 225 * If no match is found the string for Windows 2000 is returned. 226 */ 227 const char * 228 smbnative_os_str(smb_version_t *version) 229 { 230 int i; 231 232 static smb_native_t osstr_table[] = { 233 { SMB_MAJOR_NT, "Windows NT" }, 234 { SMB_MAJOR_2000, "Windows 2000" }, 235 { SMB_MAJOR_XP, "Windows XP" }, 236 { SMB_MAJOR_2003, "Windows Server 2003" }, 237 { SMB_MAJOR_VISTA, "" }, 238 { SMB_MAJOR_2008, "" }, 239 { SMB_MAJOR_2008R2, "" } 240 }; 241 242 for (i = 0; i < sizeof (osstr_table)/sizeof (osstr_table[0]); ++i) { 243 if (version->sv_major == osstr_table[i].sn_value) 244 return (osstr_table[i].sn_name); 245 } 246 247 return (osstr_table[1].sn_name); 248 } 249 250 /* 251 * Returns the native Lanman string for the given OS version. 252 * If no match is found the string for Windows 2000 is returned. 253 */ 254 const char * 255 smbnative_lm_str(smb_version_t *version) 256 { 257 int i; 258 259 static smb_native_t lmstr_table[] = { 260 { SMB_MAJOR_NT, "NT LAN Manager 4.0" }, 261 { SMB_MAJOR_2000, "Windows 2000 LAN Manager" }, 262 { SMB_MAJOR_XP, "Windows 2002 5.1" }, 263 { SMB_MAJOR_2003, "Windows Server 2003 5.2" }, 264 { SMB_MAJOR_VISTA, "" }, 265 { SMB_MAJOR_2008, "" }, 266 { SMB_MAJOR_2008R2, "" } 267 }; 268 269 for (i = 0; i < sizeof (lmstr_table)/sizeof (lmstr_table[0]); ++i) { 270 if (version->sv_major == lmstr_table[i].sn_value) 271 return (lmstr_table[i].sn_name); 272 } 273 274 return (lmstr_table[1].sn_name); 275 } 276