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*11963SAfshin.Ardakani@Sun.COM * Copyright 2010 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
409021Samw@Sun.COM typedef struct smb_native {
419021Samw@Sun.COM int sn_value;
429021Samw@Sun.COM const char *sn_name;
439021Samw@Sun.COM } smb_native_t;
449021Samw@Sun.COM
455331Samw /*
465331Samw * smbnative_os_value
475331Samw *
485331Samw * Return the appropriate native OS value for the specified native OS name.
495331Samw *
509021Samw@Sun.COM * Example OS values used by Windows:
519021Samw@Sun.COM *
529021Samw@Sun.COM * Windows 4.0, Windows NT, Windows NT 4.0
539021Samw@Sun.COM * Windows 5.0, Windows 5.1
549021Samw@Sun.COM * Windows 2000, Windows 2000 5.0, Windows 2000 5.1
559021Samw@Sun.COM * Windows 2002
569021Samw@Sun.COM * Windows .NET
579021Samw@Sun.COM * Windows Server 2003
589021Samw@Sun.COM * Windows XP
599021Samw@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
smbnative_os_value(const char * native_os)749021Samw@Sun.COM smbnative_os_value(const char *native_os)
755331Samw {
769021Samw@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" },
835331Samw { NATIVE_OS_WIN2000, "Windows 2002" },
845331Samw { NATIVE_OS_WIN2000, "Windows .NET" },
859021Samw@Sun.COM { NATIVE_OS_WIN2000, "Windows Server" },
865331Samw { NATIVE_OS_WIN2000, "Windows XP" },
875331Samw { NATIVE_OS_WINNT, "UNIX" },
885331Samw { NATIVE_OS_MACOS, "MacOS" }
895331Samw };
905331Samw
915331Samw int i;
925331Samw int len;
939021Samw@Sun.COM const char *name;
949021Samw@Sun.COM
959021Samw@Sun.COM if (native_os == NULL)
969021Samw@Sun.COM return (NATIVE_OS_UNKNOWN);
975331Samw
989021Samw@Sun.COM /*
999021Samw@Sun.COM * Windows Vista sends an empty native OS string.
1009021Samw@Sun.COM */
1019021Samw@Sun.COM if (*native_os == '\0')
1029021Samw@Sun.COM return (NATIVE_OS_WIN2000);
1039021Samw@Sun.COM
1049021Samw@Sun.COM for (i = 0; i < sizeof (os_table)/sizeof (os_table[0]); ++i) {
1059021Samw@Sun.COM name = os_table[i].sn_name;
1069021Samw@Sun.COM len = strlen(name);
1079021Samw@Sun.COM
10810966SJordan.Brown@Sun.COM if (smb_strcasecmp(name, native_os, len) == 0)
1099021Samw@Sun.COM return (os_table[i].sn_value);
1105331Samw }
1115331Samw
1125331Samw return (NATIVE_OS_UNKNOWN);
1135331Samw }
1145331Samw
1155331Samw /*
1165331Samw * smbnative_lm_value
1175331Samw *
1185331Samw * Return the appropriate native LanMan value for the specified native
1195331Samw * LanMan name. There's an alignment problem in some packets from some
1205331Samw * clients that means we can miss the first character, so we do an
1215331Samw * additional check starting from the second character.
1225331Samw *
1239021Samw@Sun.COM * Example LanMan values:
1245331Samw *
1259021Samw@Sun.COM * NT LAN Manager 4.0
1269021Samw@Sun.COM * Windows 4.0
1279021Samw@Sun.COM * Windows NT, Windows NT 4.0
1289021Samw@Sun.COM * Windows 2000 LAN Manager
1299021Samw@Sun.COM * Windows 2000, Windows 2000 5.0, Windows 2000 5.1
1309021Samw@Sun.COM * Windows 2002, Windows 2002 5.1
1319021Samw@Sun.COM * Windows .NET, Windows .NET 5.2
1329021Samw@Sun.COM * Windows Server 2003
1339021Samw@Sun.COM * Windows XP
1349021Samw@Sun.COM * NETSMB (Solaris CIFS client)
1359021Samw@Sun.COM * DAVE (Thursby Software: CIFS for MacOS)
1369021Samw@Sun.COM * Samba
1375331Samw */
1385331Samw int
smbnative_lm_value(const char * native_lm)1399021Samw@Sun.COM smbnative_lm_value(const char *native_lm)
1405331Samw {
1419021Samw@Sun.COM static smb_native_t lm_table[] = {
1425331Samw { NATIVE_LM_NT, "NT LAN Manager 4.0" },
1435331Samw { NATIVE_LM_NT, "Windows NT" },
1445331Samw { NATIVE_LM_NT, "Windows 4.0" },
1455331Samw { NATIVE_LM_NT, "DAVE" }
1465331Samw };
1475331Samw
1485331Samw int i;
1495331Samw int len;
1509021Samw@Sun.COM const char *name;
1519021Samw@Sun.COM
1529021Samw@Sun.COM /*
1539021Samw@Sun.COM * Windows Vista sends an empty native LM string.
1549021Samw@Sun.COM */
1559021Samw@Sun.COM if (native_lm == NULL || *native_lm == '\0')
1569021Samw@Sun.COM return (NATIVE_LM_WIN2000);
1575331Samw
1589021Samw@Sun.COM for (i = 0; i < sizeof (lm_table)/sizeof (lm_table[0]); ++i) {
1599021Samw@Sun.COM name = lm_table[i].sn_name;
1609021Samw@Sun.COM len = strlen(name);
1619021Samw@Sun.COM
16210966SJordan.Brown@Sun.COM if ((smb_strcasecmp(name, native_lm, len) == 0) ||
16310966SJordan.Brown@Sun.COM (smb_strcasecmp(&name[1], native_lm, len - 1) == 0)) {
1649021Samw@Sun.COM return (lm_table[i].sn_value);
1659021Samw@Sun.COM }
1665331Samw }
1675331Samw
1689021Samw@Sun.COM return (NATIVE_LM_WIN2000);
1695331Samw }
1705331Samw
1715331Samw /*
1725331Samw * smbnative_pdc_value
1735331Samw *
1749021Samw@Sun.COM * This function is called when libsmbrdr connects to a PDC.
1759021Samw@Sun.COM * The PDC type is derived from the Native LanMan string.
1769021Samw@Sun.COM * The PDC value will default to PDC_WIN2000.
1779021Samw@Sun.COM *
1789021Samw@Sun.COM * Example strings:
1795331Samw *
1809021Samw@Sun.COM * NT LAN Manager 4.0
1819021Samw@Sun.COM * Windows 4.0, Windows NT, Windows NT 4.0
1829021Samw@Sun.COM * Windows 2000 LAN Manager
1839021Samw@Sun.COM * Windows 2000, Windows 2000 5.0, Windows 2000 5.1
1849021Samw@Sun.COM * Windows 2002, Windows 2002 5.1
1859021Samw@Sun.COM * Windows .NET, Windows .NET 5.2
1869021Samw@Sun.COM * Samba
1879021Samw@Sun.COM * DAVE
1885331Samw */
1895331Samw int
smbnative_pdc_value(const char * native_lm)1909021Samw@Sun.COM smbnative_pdc_value(const char *native_lm)
1915331Samw {
1929021Samw@Sun.COM static smb_native_t pdc_table[] = {
1935331Samw { PDC_WINNT, "NT LAN Manager 4.0" },
1945331Samw { PDC_WINNT, "Windows NT 4.0" },
1955331Samw { PDC_WINNT, "Windows NT" },
1965331Samw { PDC_WINNT, "Windows 4.0" },
1979021Samw@Sun.COM { PDC_WINNT, "DAVE" },
1989021Samw@Sun.COM { PDC_SAMBA, "Samba" }
1995331Samw };
2005331Samw
2015331Samw int i;
2025331Samw int len;
2039021Samw@Sun.COM const char *name;
2045331Samw
2059021Samw@Sun.COM if (native_lm == NULL || *native_lm == '\0')
2069021Samw@Sun.COM return (PDC_WIN2000);
2075331Samw
2085331Samw for (i = 0; i < sizeof (pdc_table)/sizeof (pdc_table[0]); ++i) {
2099021Samw@Sun.COM name = pdc_table[i].sn_name;
2109021Samw@Sun.COM len = strlen(name);
2115331Samw
21210966SJordan.Brown@Sun.COM if ((smb_strcasecmp(name, native_lm, len) == 0) ||
21310966SJordan.Brown@Sun.COM (smb_strcasecmp(&name[1], native_lm, len - 1) == 0)) {
2149021Samw@Sun.COM return (pdc_table[i].sn_value);
2155331Samw }
2165331Samw }
2175331Samw
2189021Samw@Sun.COM return (PDC_WIN2000);
2195331Samw }
220*11963SAfshin.Ardakani@Sun.COM
221*11963SAfshin.Ardakani@Sun.COM /*
222*11963SAfshin.Ardakani@Sun.COM * Returns the native OS string for the given OS version.
223*11963SAfshin.Ardakani@Sun.COM * If no match is found the string for Windows 2000 is returned.
224*11963SAfshin.Ardakani@Sun.COM */
225*11963SAfshin.Ardakani@Sun.COM const char *
smbnative_os_str(smb_version_t * version)226*11963SAfshin.Ardakani@Sun.COM smbnative_os_str(smb_version_t *version)
227*11963SAfshin.Ardakani@Sun.COM {
228*11963SAfshin.Ardakani@Sun.COM int i;
229*11963SAfshin.Ardakani@Sun.COM
230*11963SAfshin.Ardakani@Sun.COM static smb_native_t osstr_table[] = {
231*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_NT, "Windows NT" },
232*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_2000, "Windows 2000" },
233*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_XP, "Windows XP" },
234*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_2003, "Windows Server 2003" },
235*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_VISTA, "" },
236*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_2008, "" },
237*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_2008R2, "" }
238*11963SAfshin.Ardakani@Sun.COM };
239*11963SAfshin.Ardakani@Sun.COM
240*11963SAfshin.Ardakani@Sun.COM for (i = 0; i < sizeof (osstr_table)/sizeof (osstr_table[0]); ++i) {
241*11963SAfshin.Ardakani@Sun.COM if (version->sv_major == osstr_table[i].sn_value)
242*11963SAfshin.Ardakani@Sun.COM return (osstr_table[i].sn_name);
243*11963SAfshin.Ardakani@Sun.COM }
244*11963SAfshin.Ardakani@Sun.COM
245*11963SAfshin.Ardakani@Sun.COM return (osstr_table[1].sn_name);
246*11963SAfshin.Ardakani@Sun.COM }
247*11963SAfshin.Ardakani@Sun.COM
248*11963SAfshin.Ardakani@Sun.COM /*
249*11963SAfshin.Ardakani@Sun.COM * Returns the native Lanman string for the given OS version.
250*11963SAfshin.Ardakani@Sun.COM * If no match is found the string for Windows 2000 is returned.
251*11963SAfshin.Ardakani@Sun.COM */
252*11963SAfshin.Ardakani@Sun.COM const char *
smbnative_lm_str(smb_version_t * version)253*11963SAfshin.Ardakani@Sun.COM smbnative_lm_str(smb_version_t *version)
254*11963SAfshin.Ardakani@Sun.COM {
255*11963SAfshin.Ardakani@Sun.COM int i;
256*11963SAfshin.Ardakani@Sun.COM
257*11963SAfshin.Ardakani@Sun.COM static smb_native_t lmstr_table[] = {
258*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_NT, "NT LAN Manager 4.0" },
259*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_2000, "Windows 2000 LAN Manager" },
260*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_XP, "Windows 2002 5.1" },
261*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_2003, "Windows Server 2003 5.2" },
262*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_VISTA, "" },
263*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_2008, "" },
264*11963SAfshin.Ardakani@Sun.COM { SMB_MAJOR_2008R2, "" }
265*11963SAfshin.Ardakani@Sun.COM };
266*11963SAfshin.Ardakani@Sun.COM
267*11963SAfshin.Ardakani@Sun.COM for (i = 0; i < sizeof (lmstr_table)/sizeof (lmstr_table[0]); ++i) {
268*11963SAfshin.Ardakani@Sun.COM if (version->sv_major == lmstr_table[i].sn_value)
269*11963SAfshin.Ardakani@Sun.COM return (lmstr_table[i].sn_name);
270*11963SAfshin.Ardakani@Sun.COM }
271*11963SAfshin.Ardakani@Sun.COM
272*11963SAfshin.Ardakani@Sun.COM return (lmstr_table[1].sn_name);
273*11963SAfshin.Ardakani@Sun.COM }
274