15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 22*9021Samw@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 265331Samw /* 275331Samw * This module defines generic functions to map Native OS and Native 285331Samw * LanMan names to values. 295331Samw */ 305331Samw 315331Samw #ifdef _KERNEL 325331Samw #include <sys/types.h> 335331Samw #include <sys/sunddi.h> 345331Samw #else 355331Samw #include <string.h> 365331Samw #endif 375331Samw #include <smbsrv/string.h> 385331Samw #include <smbsrv/smbinfo.h> 395331Samw 40*9021Samw@Sun.COM typedef struct smb_native { 41*9021Samw@Sun.COM int sn_value; 42*9021Samw@Sun.COM const char *sn_name; 43*9021Samw@Sun.COM } smb_native_t; 44*9021Samw@Sun.COM 455331Samw /* 465331Samw * smbnative_os_value 475331Samw * 485331Samw * Return the appropriate native OS value for the specified native OS name. 495331Samw * 50*9021Samw@Sun.COM * Example OS values used by Windows: 51*9021Samw@Sun.COM * 52*9021Samw@Sun.COM * Windows 4.0, Windows NT, Windows NT 4.0 53*9021Samw@Sun.COM * Windows 5.0, Windows 5.1 54*9021Samw@Sun.COM * Windows 2000, Windows 2000 5.0, Windows 2000 5.1 55*9021Samw@Sun.COM * Windows 2002 56*9021Samw@Sun.COM * Windows .NET 57*9021Samw@Sun.COM * Windows Server 2003 58*9021Samw@Sun.COM * Windows XP 59*9021Samw@Sun.COM * 605331Samw * Windows 2000 server: "Windows 2000 2195" 615331Samw * Windows XP Professional client: "Windows 2002 2543" 625331Samw * Windows XP PDC server: "Windows 5.1" 635331Samw * Windows .Net: "Windows .NET 3621" 645331Samw * Windows .Net: "Windows .NET 3718" 655331Samw * 665331Samw * DAVE (Thursby Software: CIFS for MacOS) uses "MacOS", sometimes with a 675331Samw * version number appended, i.e. "MacOS 8.5.1". We treat DAVE like NT 4.0 685331Samw * except for the cases that DAVE clients set 'watch tree' flag in notify 695331Samw * change requests. 705331Samw * 715331Samw * Samba reports UNIX as its Native OS, which we can map to NT 4.0. 725331Samw */ 735331Samw int 74*9021Samw@Sun.COM smbnative_os_value(const char *native_os) 755331Samw { 76*9021Samw@Sun.COM static smb_native_t os_table[] = { 775331Samw { NATIVE_OS_WINNT, "Windows NT 4.0" }, 785331Samw { NATIVE_OS_WINNT, "Windows NT" }, 795331Samw { NATIVE_OS_WIN95, "Windows 4.0" }, 805331Samw { NATIVE_OS_WIN2000, "Windows 5.0" }, 815331Samw { NATIVE_OS_WIN2000, "Windows 5.1" }, 825331Samw { NATIVE_OS_WIN2000, "Windows 2000 5.0" }, 835331Samw { NATIVE_OS_NT5_1, "Windows 2000 5.1" }, 845331Samw { NATIVE_OS_WIN2000, "Windows 2000" }, 855331Samw { NATIVE_OS_WIN2000, "Windows 2002" }, 865331Samw { NATIVE_OS_WIN2000, "Windows .NET" }, 87*9021Samw@Sun.COM { NATIVE_OS_WIN2000, "Windows Server" }, 885331Samw { NATIVE_OS_WIN2000, "Windows XP" }, 895331Samw { NATIVE_OS_WINNT, "UNIX" }, 905331Samw { NATIVE_OS_MACOS, "MacOS" } 915331Samw }; 925331Samw 935331Samw int i; 945331Samw int len; 95*9021Samw@Sun.COM const char *name; 96*9021Samw@Sun.COM 97*9021Samw@Sun.COM if (native_os == NULL) 98*9021Samw@Sun.COM return (NATIVE_OS_UNKNOWN); 995331Samw 100*9021Samw@Sun.COM /* 101*9021Samw@Sun.COM * Windows Vista sends an empty native OS string. 102*9021Samw@Sun.COM */ 103*9021Samw@Sun.COM if (*native_os == '\0') 104*9021Samw@Sun.COM return (NATIVE_OS_WIN2000); 105*9021Samw@Sun.COM 106*9021Samw@Sun.COM for (i = 0; i < sizeof (os_table)/sizeof (os_table[0]); ++i) { 107*9021Samw@Sun.COM name = os_table[i].sn_name; 108*9021Samw@Sun.COM len = strlen(name); 109*9021Samw@Sun.COM 110*9021Samw@Sun.COM if (utf8_strncasecmp(name, native_os, len) == 0) 111*9021Samw@Sun.COM return (os_table[i].sn_value); 1125331Samw } 1135331Samw 1145331Samw return (NATIVE_OS_UNKNOWN); 1155331Samw } 1165331Samw 1175331Samw /* 1185331Samw * smbnative_lm_value 1195331Samw * 1205331Samw * Return the appropriate native LanMan value for the specified native 1215331Samw * LanMan name. There's an alignment problem in some packets from some 1225331Samw * clients that means we can miss the first character, so we do an 1235331Samw * additional check starting from the second character. 1245331Samw * 125*9021Samw@Sun.COM * Example LanMan values: 1265331Samw * 127*9021Samw@Sun.COM * NT LAN Manager 4.0 128*9021Samw@Sun.COM * Windows 4.0 129*9021Samw@Sun.COM * Windows NT, Windows NT 4.0 130*9021Samw@Sun.COM * Windows 2000 LAN Manager 131*9021Samw@Sun.COM * Windows 2000, Windows 2000 5.0, Windows 2000 5.1 132*9021Samw@Sun.COM * Windows 2002, Windows 2002 5.1 133*9021Samw@Sun.COM * Windows .NET, Windows .NET 5.2 134*9021Samw@Sun.COM * Windows Server 2003 135*9021Samw@Sun.COM * Windows XP 136*9021Samw@Sun.COM * NETSMB (Solaris CIFS client) 137*9021Samw@Sun.COM * DAVE (Thursby Software: CIFS for MacOS) 138*9021Samw@Sun.COM * Samba 1395331Samw */ 1405331Samw int 141*9021Samw@Sun.COM smbnative_lm_value(const char *native_lm) 1425331Samw { 143*9021Samw@Sun.COM static smb_native_t lm_table[] = { 1445331Samw { NATIVE_LM_NT, "NT LAN Manager 4.0" }, 1455331Samw { NATIVE_LM_NT, "Windows NT" }, 1465331Samw { NATIVE_LM_NT, "Windows 4.0" }, 1475331Samw { NATIVE_LM_NT, "DAVE" } 1485331Samw }; 1495331Samw 1505331Samw int i; 1515331Samw int len; 152*9021Samw@Sun.COM const char *name; 153*9021Samw@Sun.COM 154*9021Samw@Sun.COM /* 155*9021Samw@Sun.COM * Windows Vista sends an empty native LM string. 156*9021Samw@Sun.COM */ 157*9021Samw@Sun.COM if (native_lm == NULL || *native_lm == '\0') 158*9021Samw@Sun.COM return (NATIVE_LM_WIN2000); 1595331Samw 160*9021Samw@Sun.COM for (i = 0; i < sizeof (lm_table)/sizeof (lm_table[0]); ++i) { 161*9021Samw@Sun.COM name = lm_table[i].sn_name; 162*9021Samw@Sun.COM len = strlen(name); 163*9021Samw@Sun.COM 164*9021Samw@Sun.COM if ((utf8_strncasecmp(name, native_lm, len) == 0) || 165*9021Samw@Sun.COM (utf8_strncasecmp(&name[1], native_lm, len - 1) == 0)) { 166*9021Samw@Sun.COM return (lm_table[i].sn_value); 167*9021Samw@Sun.COM } 1685331Samw } 1695331Samw 170*9021Samw@Sun.COM return (NATIVE_LM_WIN2000); 1715331Samw } 1725331Samw 1735331Samw /* 1745331Samw * smbnative_pdc_value 1755331Samw * 176*9021Samw@Sun.COM * This function is called when libsmbrdr connects to a PDC. 177*9021Samw@Sun.COM * The PDC type is derived from the Native LanMan string. 178*9021Samw@Sun.COM * The PDC value will default to PDC_WIN2000. 179*9021Samw@Sun.COM * 180*9021Samw@Sun.COM * Example strings: 1815331Samw * 182*9021Samw@Sun.COM * NT LAN Manager 4.0 183*9021Samw@Sun.COM * Windows 4.0, Windows NT, Windows NT 4.0 184*9021Samw@Sun.COM * Windows 2000 LAN Manager 185*9021Samw@Sun.COM * Windows 2000, Windows 2000 5.0, Windows 2000 5.1 186*9021Samw@Sun.COM * Windows 2002, Windows 2002 5.1 187*9021Samw@Sun.COM * Windows .NET, Windows .NET 5.2 188*9021Samw@Sun.COM * Samba 189*9021Samw@Sun.COM * DAVE 1905331Samw */ 1915331Samw int 192*9021Samw@Sun.COM smbnative_pdc_value(const char *native_lm) 1935331Samw { 194*9021Samw@Sun.COM static smb_native_t pdc_table[] = { 1955331Samw { PDC_WINNT, "NT LAN Manager 4.0" }, 1965331Samw { PDC_WINNT, "Windows NT 4.0" }, 1975331Samw { PDC_WINNT, "Windows NT" }, 1985331Samw { PDC_WINNT, "Windows 4.0" }, 199*9021Samw@Sun.COM { PDC_WINNT, "DAVE" }, 200*9021Samw@Sun.COM { PDC_SAMBA, "Samba" } 2015331Samw }; 2025331Samw 2035331Samw int i; 2045331Samw int len; 205*9021Samw@Sun.COM const char *name; 2065331Samw 207*9021Samw@Sun.COM if (native_lm == NULL || *native_lm == '\0') 208*9021Samw@Sun.COM return (PDC_WIN2000); 2095331Samw 2105331Samw for (i = 0; i < sizeof (pdc_table)/sizeof (pdc_table[0]); ++i) { 211*9021Samw@Sun.COM name = pdc_table[i].sn_name; 212*9021Samw@Sun.COM len = strlen(name); 2135331Samw 214*9021Samw@Sun.COM if ((utf8_strncasecmp(name, native_lm, len) == 0) || 215*9021Samw@Sun.COM (utf8_strncasecmp(&name[1], native_lm, len - 1) == 0)) { 216*9021Samw@Sun.COM return (pdc_table[i].sn_value); 2175331Samw } 2185331Samw } 2195331Samw 220*9021Samw@Sun.COM return (PDC_WIN2000); 2215331Samw } 222