xref: /titanic_41/usr/src/common/smbsrv/smb_native.c (revision bbf6f00c25b6a2bed23c35eac6d62998ecdb338c)
1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw /*
22fc724630SAlan Wright  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23da6c28aaSamw  * Use is subject to license terms.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw /*
27da6c28aaSamw  * This module defines generic functions to map Native OS and Native
28da6c28aaSamw  * LanMan names to values.
29da6c28aaSamw  */
30da6c28aaSamw 
31da6c28aaSamw #ifdef _KERNEL
32da6c28aaSamw #include <sys/types.h>
33da6c28aaSamw #include <sys/sunddi.h>
34da6c28aaSamw #else
35da6c28aaSamw #include <string.h>
36da6c28aaSamw #endif
37da6c28aaSamw #include <smbsrv/string.h>
38da6c28aaSamw #include <smbsrv/smbinfo.h>
39da6c28aaSamw 
40fc724630SAlan Wright typedef struct smb_native {
41fc724630SAlan Wright 	int sn_value;
42fc724630SAlan Wright 	const char *sn_name;
43fc724630SAlan Wright } smb_native_t;
44fc724630SAlan Wright 
45da6c28aaSamw /*
46da6c28aaSamw  * smbnative_os_value
47da6c28aaSamw  *
48da6c28aaSamw  * Return the appropriate native OS value for the specified native OS name.
49da6c28aaSamw  *
50fc724630SAlan Wright  * Example OS values used by Windows:
51fc724630SAlan Wright  *
52fc724630SAlan Wright  *	Windows 4.0, Windows NT, Windows NT 4.0
53fc724630SAlan Wright  *	Windows 5.0, Windows 5.1
54fc724630SAlan Wright  *	Windows 2000, Windows 2000 5.0, Windows 2000 5.1
55fc724630SAlan Wright  *	Windows 2002
56fc724630SAlan Wright  *	Windows .NET
57fc724630SAlan Wright  *	Windows Server 2003
58fc724630SAlan Wright  *	Windows XP
59fc724630SAlan Wright  *
60da6c28aaSamw  * Windows 2000 server:            "Windows 2000 2195"
61da6c28aaSamw  * Windows XP Professional client: "Windows 2002 2543"
62da6c28aaSamw  * Windows XP PDC server:          "Windows 5.1"
63da6c28aaSamw  * Windows .Net:                   "Windows .NET 3621"
64da6c28aaSamw  * Windows .Net:                   "Windows .NET 3718"
65da6c28aaSamw  *
66da6c28aaSamw  * DAVE (Thursby Software: CIFS for MacOS) uses "MacOS", sometimes with a
67da6c28aaSamw  * version number appended, i.e. "MacOS 8.5.1". We treat DAVE like NT 4.0
68da6c28aaSamw  * except for the cases that DAVE clients set 'watch tree' flag in notify
69da6c28aaSamw  * change requests.
70da6c28aaSamw  *
71da6c28aaSamw  * Samba reports UNIX as its Native OS, which we can map to NT 4.0.
72da6c28aaSamw  */
73da6c28aaSamw int
74fc724630SAlan Wright smbnative_os_value(const char *native_os)
75da6c28aaSamw {
76fc724630SAlan Wright 	static smb_native_t os_table[] = {
77da6c28aaSamw 		{ NATIVE_OS_WINNT,	"Windows NT 4.0"	},
78da6c28aaSamw 		{ NATIVE_OS_WINNT,	"Windows NT"		},
79da6c28aaSamw 		{ NATIVE_OS_WIN95,	"Windows 4.0"		},
80da6c28aaSamw 		{ NATIVE_OS_WIN2000,	"Windows 5.0"		},
81da6c28aaSamw 		{ NATIVE_OS_WIN2000,	"Windows 5.1"		},
82da6c28aaSamw 		{ NATIVE_OS_WIN2000,	"Windows 2000"		},
83da6c28aaSamw 		{ NATIVE_OS_WIN2000,	"Windows 2002"		},
84da6c28aaSamw 		{ NATIVE_OS_WIN2000,	"Windows .NET"		},
85fc724630SAlan Wright 		{ NATIVE_OS_WIN2000,	"Windows Server"	},
86da6c28aaSamw 		{ NATIVE_OS_WIN2000,	"Windows XP"		},
87da6c28aaSamw 		{ NATIVE_OS_WINNT,	"UNIX"			},
88da6c28aaSamw 		{ NATIVE_OS_MACOS,	"MacOS" 		}
89da6c28aaSamw 	};
90da6c28aaSamw 
91da6c28aaSamw 	int i;
92da6c28aaSamw 	int len;
93fc724630SAlan Wright 	const char *name;
94da6c28aaSamw 
95fc724630SAlan Wright 	if (native_os == NULL)
96da6c28aaSamw 		return (NATIVE_OS_UNKNOWN);
97da6c28aaSamw 
9855bf511dSas200622 	/*
9955bf511dSas200622 	 * Windows Vista sends an empty native OS string.
10055bf511dSas200622 	 */
101fc724630SAlan Wright 	if (*native_os == '\0')
10255bf511dSas200622 		return (NATIVE_OS_WIN2000);
10355bf511dSas200622 
104da6c28aaSamw 	for (i = 0; i < sizeof (os_table)/sizeof (os_table[0]); ++i) {
105fc724630SAlan Wright 		name = os_table[i].sn_name;
106fc724630SAlan Wright 		len = strlen(name);
107da6c28aaSamw 
108*bbf6f00cSJordan Brown 		if (smb_strcasecmp(name, native_os, len) == 0)
109fc724630SAlan Wright 			return (os_table[i].sn_value);
110da6c28aaSamw 	}
111fc724630SAlan Wright 
112da6c28aaSamw 	return (NATIVE_OS_UNKNOWN);
113da6c28aaSamw }
114da6c28aaSamw 
115da6c28aaSamw /*
116da6c28aaSamw  * smbnative_lm_value
117da6c28aaSamw  *
118da6c28aaSamw  * Return the appropriate native LanMan value for the specified native
119da6c28aaSamw  * LanMan name. There's an alignment problem in some packets from some
120da6c28aaSamw  * clients that means we can miss the first character, so we do an
121da6c28aaSamw  * additional check starting from the second character.
122da6c28aaSamw  *
123fc724630SAlan Wright  * Example LanMan values:
124da6c28aaSamw  *
125fc724630SAlan Wright  *	NT LAN Manager 4.0
126fc724630SAlan Wright  *	Windows 4.0
127fc724630SAlan Wright  *	Windows NT, Windows NT 4.0
128fc724630SAlan Wright  *	Windows 2000 LAN Manager
129fc724630SAlan Wright  *	Windows 2000, Windows 2000 5.0, Windows 2000 5.1
130fc724630SAlan Wright  *	Windows 2002, Windows 2002 5.1
131fc724630SAlan Wright  *	Windows .NET, Windows .NET 5.2
132fc724630SAlan Wright  *	Windows Server 2003
133fc724630SAlan Wright  *	Windows XP
134fc724630SAlan Wright  *	NETSMB		(Solaris CIFS client)
135fc724630SAlan Wright  *	DAVE		(Thursby Software: CIFS for MacOS)
136fc724630SAlan Wright  *	Samba
137da6c28aaSamw  */
138da6c28aaSamw int
139fc724630SAlan Wright smbnative_lm_value(const char *native_lm)
140da6c28aaSamw {
141fc724630SAlan Wright 	static smb_native_t lm_table[] = {
142da6c28aaSamw 		{ NATIVE_LM_NT,		"NT LAN Manager 4.0"		},
143da6c28aaSamw 		{ NATIVE_LM_NT,		"Windows NT"			},
144da6c28aaSamw 		{ NATIVE_LM_NT,		"Windows 4.0"			},
145da6c28aaSamw 		{ NATIVE_LM_NT,		"DAVE"				}
146da6c28aaSamw 	};
147da6c28aaSamw 
148da6c28aaSamw 	int i;
149da6c28aaSamw 	int len;
150fc724630SAlan Wright 	const char *name;
151da6c28aaSamw 
15255bf511dSas200622 	/*
15355bf511dSas200622 	 * Windows Vista sends an empty native LM string.
15455bf511dSas200622 	 */
155fc724630SAlan Wright 	if (native_lm == NULL || *native_lm == '\0')
15655bf511dSas200622 		return (NATIVE_LM_WIN2000);
15755bf511dSas200622 
158da6c28aaSamw 	for (i = 0; i < sizeof (lm_table)/sizeof (lm_table[0]); ++i) {
159fc724630SAlan Wright 		name = lm_table[i].sn_name;
160fc724630SAlan Wright 		len = strlen(name);
161da6c28aaSamw 
162*bbf6f00cSJordan Brown 		if ((smb_strcasecmp(name, native_lm, len) == 0) ||
163*bbf6f00cSJordan Brown 		    (smb_strcasecmp(&name[1], native_lm, len - 1) == 0)) {
164fc724630SAlan Wright 			return (lm_table[i].sn_value);
165da6c28aaSamw 		}
166da6c28aaSamw 	}
167fc724630SAlan Wright 
168fc724630SAlan Wright 	return (NATIVE_LM_WIN2000);
169da6c28aaSamw }
170da6c28aaSamw 
171da6c28aaSamw /*
172da6c28aaSamw  * smbnative_pdc_value
173da6c28aaSamw  *
174fc724630SAlan Wright  * This function is called when libsmbrdr connects to a PDC.
175fc724630SAlan Wright  * The PDC type is derived from the Native LanMan string.
176fc724630SAlan Wright  * The PDC value will default to PDC_WIN2000.
177da6c28aaSamw  *
178fc724630SAlan Wright  * Example strings:
179fc724630SAlan Wright  *
180fc724630SAlan Wright  *	NT LAN Manager 4.0
181fc724630SAlan Wright  *	Windows 4.0, Windows NT, Windows NT 4.0
182fc724630SAlan Wright  *	Windows 2000 LAN Manager
183fc724630SAlan Wright  *	Windows 2000, Windows 2000 5.0, Windows 2000 5.1
184fc724630SAlan Wright  *	Windows 2002, Windows 2002 5.1
185fc724630SAlan Wright  *	Windows .NET, Windows .NET 5.2
186fc724630SAlan Wright  *	Samba
187fc724630SAlan Wright  *	DAVE
188da6c28aaSamw  */
189da6c28aaSamw int
190fc724630SAlan Wright smbnative_pdc_value(const char *native_lm)
191da6c28aaSamw {
192fc724630SAlan Wright 	static smb_native_t pdc_table[] = {
193da6c28aaSamw 		{ PDC_WINNT,	"NT LAN Manager 4.0"		},
194da6c28aaSamw 		{ PDC_WINNT,	"Windows NT 4.0"		},
195da6c28aaSamw 		{ PDC_WINNT,	"Windows NT"			},
196da6c28aaSamw 		{ PDC_WINNT,	"Windows 4.0"			},
197fc724630SAlan Wright 		{ PDC_WINNT,	"DAVE"				},
198fc724630SAlan Wright 		{ PDC_SAMBA,	"Samba"				}
199da6c28aaSamw 	};
200da6c28aaSamw 
201da6c28aaSamw 	int i;
202da6c28aaSamw 	int len;
203fc724630SAlan Wright 	const char *name;
204da6c28aaSamw 
205fc724630SAlan Wright 	if (native_lm == NULL || *native_lm == '\0')
206fc724630SAlan Wright 		return (PDC_WIN2000);
207da6c28aaSamw 
208da6c28aaSamw 	for (i = 0; i < sizeof (pdc_table)/sizeof (pdc_table[0]); ++i) {
209fc724630SAlan Wright 		name = pdc_table[i].sn_name;
210fc724630SAlan Wright 		len = strlen(name);
211da6c28aaSamw 
212*bbf6f00cSJordan Brown 		if ((smb_strcasecmp(name, native_lm, len) == 0) ||
213*bbf6f00cSJordan Brown 		    (smb_strcasecmp(&name[1], native_lm, len - 1) == 0)) {
214fc724630SAlan Wright 			return (pdc_table[i].sn_value);
215da6c28aaSamw 		}
216da6c28aaSamw 	}
217da6c28aaSamw 
218fc724630SAlan Wright 	return (PDC_WIN2000);
219da6c28aaSamw }
220