xref: /onnv-gate/usr/src/common/smbsrv/smb_native.c (revision 11963:061945695ce1)
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