xref: /titanic_51/usr/src/common/smbsrv/smb_native.c (revision a7746f662862b6ac0a85751d8adbc897743a83e1)
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * This module defines generic functions to map Native OS and Native
30  * LanMan names to values.
31  */
32 
33 #ifdef _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 /*
43  * smbnative_os_value
44  *
45  * Return the appropriate native OS value for the specified native OS name.
46  *
47  * Windows 2000 server:            "Windows 2000 2195"
48  * Windows XP Professional client: "Windows 2002 2543"
49  * Windows XP PDC server:          "Windows 5.1"
50  * Windows .Net:                   "Windows .NET 3621"
51  * Windows .Net:                   "Windows .NET 3718"
52  *
53  * DAVE (Thursby Software: CIFS for MacOS) uses "MacOS", sometimes with a
54  * version number appended, i.e. "MacOS 8.5.1". We treat DAVE like NT 4.0
55  * except for the cases that DAVE clients set 'watch tree' flag in notify
56  * change requests.
57  *
58  * Samba reports UNIX as its Native OS, which we can map to NT 4.0.
59  */
60 int
61 smbnative_os_value(char *native_os)
62 {
63 	typedef struct native_os_table {
64 		int os_value;
65 		char *os_name;
66 	} native_os_table_t;
67 
68 	static native_os_table_t os_table[] = {
69 		{ NATIVE_OS_WINNT,	"Windows NT 4.0"	},
70 		{ NATIVE_OS_WINNT,	"Windows NT"		},
71 		{ NATIVE_OS_WIN95,	"Windows 4.0"		},
72 		{ NATIVE_OS_WIN2000,	"Windows 5.0"		},
73 		{ NATIVE_OS_WIN2000,	"Windows 5.1"		},
74 		{ NATIVE_OS_WIN2000,	"Windows 2000 5.0"	},
75 		{ NATIVE_OS_NT5_1,	"Windows 2000 5.1"	},
76 		{ NATIVE_OS_WIN2000,	"Windows 2000"		},
77 		{ NATIVE_OS_WIN2000,	"Windows 2002"		},
78 		{ NATIVE_OS_WIN2000,	"Windows .NET"		},
79 		{ NATIVE_OS_WIN2000,	"Windows Server 2003"	},
80 		{ NATIVE_OS_WIN2000,	"Windows XP"		},
81 		{ NATIVE_OS_WINNT,	"UNIX"			},
82 		{ NATIVE_OS_MACOS,	"MacOS" 		}
83 	};
84 
85 	int i;
86 	int len;
87 	char *os_name;
88 
89 	if (native_os == NULL) {
90 		return (NATIVE_OS_UNKNOWN);
91 	}
92 
93 	for (i = 0; i < sizeof (os_table)/sizeof (os_table[0]); ++i) {
94 		os_name = os_table[i].os_name;
95 		len = strlen(os_name);
96 
97 		if (utf8_strncasecmp(os_name, native_os, len) == 0) {
98 			return (os_table[i].os_value);
99 		}
100 	}
101 	return (NATIVE_OS_UNKNOWN);
102 }
103 
104 
105 /*
106  * smbnative_lm_value
107  *
108  * Return the appropriate native LanMan value for the specified native
109  * LanMan name. There's an alignment problem in some packets from some
110  * clients that means we can miss the first character, so we do an
111  * additional check starting from the second character.
112  *
113  * DAVE (Thursby Software: CIFS for MacOS) sometimes uses a Unicode
114  * character in the LanMan name. Variations seen so far are:
115  *
116  *	44 00 41 00 56 00 45 00 00 00        D.A.V.E...
117  *
118  *	44 00 41 00 56 00 45 00 22 21 20 00 56 00 32 00
119  *	2E 00 35 00 2E 00 31 00 00 00        D.A.V.E."!..V.2...5...1...
120  *
121  * Samba reports its own name (Samba) as its Native LM, which we can
122  * map to NT LM 4.0.
123  */
124 int
125 smbnative_lm_value(char *native_lm)
126 {
127 	typedef struct native_lm_table {
128 		int lm_value;
129 		char *lm_name;
130 	} native_lm_table_t;
131 
132 	static native_lm_table_t lm_table[] = {
133 		{ NATIVE_LM_NT,		"NT LAN Manager 4.0"		},
134 		{ NATIVE_LM_NT,		"Windows NT 4.0"		},
135 		{ NATIVE_LM_NT,		"Windows NT"			},
136 		{ NATIVE_LM_NT,		"Windows 4.0"			},
137 		{ NATIVE_LM_WIN2000,	"Windows 2000 LAN Manager"	},
138 		{ NATIVE_LM_WIN2000,	"Windows 2000 5.0"		},
139 		{ NATIVE_LM_WIN2000,	"Windows 2000 5.1"		},
140 		{ NATIVE_LM_WIN2000,	"Windows 2000",			},
141 		{ NATIVE_LM_WIN2000,	"Windows 2002 5.1"		},
142 		{ NATIVE_LM_WIN2000,	"Windows 2002"			},
143 		{ NATIVE_LM_WIN2000,	"Windows .NET 5.2"		},
144 		{ NATIVE_LM_WIN2000,	"Windows .NET"			},
145 		{ NATIVE_LM_WIN2000,	"Windows Server 2003"		},
146 		{ NATIVE_LM_WIN2000,	"Windows XP"			},
147 		{ NATIVE_LM_NT,		"Samba"				},
148 		{ NATIVE_LM_NT,		"DAVE"				}
149 	};
150 
151 	int i;
152 	int len;
153 	char *lm_name;
154 
155 	if (native_lm == NULL) {
156 		return (NATIVE_LM_NONE);
157 	}
158 
159 	for (i = 0; i < sizeof (lm_table)/sizeof (lm_table[0]); ++i) {
160 		lm_name = lm_table[i].lm_name;
161 		len = strlen(lm_name);
162 
163 		if ((utf8_strncasecmp(lm_name, native_lm, len) == 0) ||
164 		    (utf8_strncasecmp(&lm_name[1], native_lm, len - 1) == 0)) {
165 			return (lm_table[i].lm_value);
166 		}
167 	}
168 	return (NATIVE_LM_NONE);
169 }
170 
171 /*
172  * smbnative_pdc_value
173  *
174  * This function is used when NetFORCE contacting a PDC
175  * to authenticate a connected user to determine and keep
176  * the PDC type.
177  *
178  * The reason for adding this functionality is that NetFORCE
179  * doesn't support Samba PDC but code didn't check the PDC type
180  * and do authentication agains any PDC. This behaviour could
181  * cause problem in some circumstances.
182  * Now that we determine the PDC type the authentication code
183  * can be configured (by smb.samba.pdc env var) to return access
184  * denied to authentication attempts when PDC is Samba.
185  */
186 int
187 smbnative_pdc_value(char *native_lm)
188 {
189 	typedef struct pdc_table {
190 		int pdc_value;
191 		char *pdc_lmname;
192 	} pdc_table_t;
193 
194 	static pdc_table_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_WIN2000,	"Windows 2000 LAN Manager"	},
200 		{ PDC_WIN2000,	"Windows 2000 5.0"		},
201 		{ PDC_WIN2000,	"Windows 2000 5.1"		},
202 		{ PDC_WIN2000,	"Windows 2000",			},
203 		{ PDC_WIN2000,	"Windows 2002 5.1"		},
204 		{ PDC_WIN2000,	"Windows 2002"			},
205 		{ PDC_WIN2000,	"Windows .NET 5.2"		},
206 		{ PDC_WIN2000,	"Windows .NET"			},
207 		{ PDC_SAMBA,	"Samba"				},
208 		{ PDC_WINNT,	"DAVE"				}
209 	};
210 
211 	int i;
212 	int len;
213 	char *pdc_lmname;
214 
215 	if (native_lm == 0) {
216 		return (PDC_UNKNOWN);
217 	}
218 
219 	for (i = 0; i < sizeof (pdc_table)/sizeof (pdc_table[0]); ++i) {
220 		pdc_lmname = pdc_table[i].pdc_lmname;
221 		len = strlen(pdc_lmname);
222 
223 		if ((utf8_strncasecmp(pdc_lmname, native_lm, len) == 0) ||
224 		    (utf8_strncasecmp(&pdc_lmname[1], native_lm, len - 1)
225 		    == 0)) {
226 			return (pdc_table[i].pdc_value);
227 		}
228 	}
229 
230 	return (PDC_UNKNOWN);
231 }
232