Home | History | Annotate | Download | only in smbsrv
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 /*
     27  * This module defines generic functions to map Native OS and Native
     28  * LanMan names to values.
     29  */
     30 
     31 #ifdef _KERNEL
     32 #include <sys/types.h>
     33 #include <sys/sunddi.h>
     34 #else
     35 #include <string.h>
     36 #endif
     37 #include <smbsrv/string.h>
     38 #include <smbsrv/smbinfo.h>
     39 
     40 typedef struct smb_native {
     41 	int sn_value;
     42 	const char *sn_name;
     43 } smb_native_t;
     44 
     45 /*
     46  * smbnative_os_value
     47  *
     48  * Return the appropriate native OS value for the specified native OS name.
     49  *
     50  * Example OS values used by Windows:
     51  *
     52  *	Windows 4.0, Windows NT, Windows NT 4.0
     53  *	Windows 5.0, Windows 5.1
     54  *	Windows 2000, Windows 2000 5.0, Windows 2000 5.1
     55  *	Windows 2002
     56  *	Windows .NET
     57  *	Windows Server 2003
     58  *	Windows XP
     59  *
     60  * Windows 2000 server:            "Windows 2000 2195"
     61  * Windows XP Professional client: "Windows 2002 2543"
     62  * Windows XP PDC server:          "Windows 5.1"
     63  * Windows .Net:                   "Windows .NET 3621"
     64  * Windows .Net:                   "Windows .NET 3718"
     65  *
     66  * DAVE (Thursby Software: CIFS for MacOS) uses "MacOS", sometimes with a
     67  * version number appended, i.e. "MacOS 8.5.1". We treat DAVE like NT 4.0
     68  * except for the cases that DAVE clients set 'watch tree' flag in notify
     69  * change requests.
     70  *
     71  * Samba reports UNIX as its Native OS, which we can map to NT 4.0.
     72  */
     73 int
     74 smbnative_os_value(const char *native_os)
     75 {
     76 	static smb_native_t os_table[] = {
     77 		{ NATIVE_OS_WINNT,	"Windows NT 4.0"	},
     78 		{ NATIVE_OS_WINNT,	"Windows NT"		},
     79 		{ NATIVE_OS_WIN95,	"Windows 4.0"		},
     80 		{ NATIVE_OS_WIN2000,	"Windows 5.0"		},
     81 		{ NATIVE_OS_WIN2000,	"Windows 5.1"		},
     82 		{ NATIVE_OS_WIN2000,	"Windows 2000"		},
     83 		{ NATIVE_OS_WIN2000,	"Windows 2002"		},
     84 		{ NATIVE_OS_WIN2000,	"Windows .NET"		},
     85 		{ NATIVE_OS_WIN2000,	"Windows Server"	},
     86 		{ NATIVE_OS_WIN2000,	"Windows XP"		},
     87 		{ NATIVE_OS_WINNT,	"UNIX"			},
     88 		{ NATIVE_OS_MACOS,	"MacOS" 		}
     89 	};
     90 
     91 	int i;
     92 	int len;
     93 	const char *name;
     94 
     95 	if (native_os == NULL)
     96 		return (NATIVE_OS_UNKNOWN);
     97 
     98 	/*
     99 	 * Windows Vista sends an empty native OS string.
    100 	 */
    101 	if (*native_os == '\0')
    102 		return (NATIVE_OS_WIN2000);
    103 
    104 	for (i = 0; i < sizeof (os_table)/sizeof (os_table[0]); ++i) {
    105 		name = os_table[i].sn_name;
    106 		len = strlen(name);
    107 
    108 		if (smb_strcasecmp(name, native_os, len) == 0)
    109 			return (os_table[i].sn_value);
    110 	}
    111 
    112 	return (NATIVE_OS_UNKNOWN);
    113 }
    114 
    115 /*
    116  * smbnative_lm_value
    117  *
    118  * Return the appropriate native LanMan value for the specified native
    119  * LanMan name. There's an alignment problem in some packets from some
    120  * clients that means we can miss the first character, so we do an
    121  * additional check starting from the second character.
    122  *
    123  * Example LanMan values:
    124  *
    125  *	NT LAN Manager 4.0
    126  *	Windows 4.0
    127  *	Windows NT, Windows NT 4.0
    128  *	Windows 2000 LAN Manager
    129  *	Windows 2000, Windows 2000 5.0, Windows 2000 5.1
    130  *	Windows 2002, Windows 2002 5.1
    131  *	Windows .NET, Windows .NET 5.2
    132  *	Windows Server 2003
    133  *	Windows XP
    134  *	NETSMB		(Solaris CIFS client)
    135  *	DAVE		(Thursby Software: CIFS for MacOS)
    136  *	Samba
    137  */
    138 int
    139 smbnative_lm_value(const char *native_lm)
    140 {
    141 	static smb_native_t lm_table[] = {
    142 		{ NATIVE_LM_NT,		"NT LAN Manager 4.0"		},
    143 		{ NATIVE_LM_NT,		"Windows NT"			},
    144 		{ NATIVE_LM_NT,		"Windows 4.0"			},
    145 		{ NATIVE_LM_NT,		"DAVE"				}
    146 	};
    147 
    148 	int i;
    149 	int len;
    150 	const char *name;
    151 
    152 	/*
    153 	 * Windows Vista sends an empty native LM string.
    154 	 */
    155 	if (native_lm == NULL || *native_lm == '\0')
    156 		return (NATIVE_LM_WIN2000);
    157 
    158 	for (i = 0; i < sizeof (lm_table)/sizeof (lm_table[0]); ++i) {
    159 		name = lm_table[i].sn_name;
    160 		len = strlen(name);
    161 
    162 		if ((smb_strcasecmp(name, native_lm, len) == 0) ||
    163 		    (smb_strcasecmp(&name[1], native_lm, len - 1) == 0)) {
    164 			return (lm_table[i].sn_value);
    165 		}
    166 	}
    167 
    168 	return (NATIVE_LM_WIN2000);
    169 }
    170 
    171 /*
    172  * smbnative_pdc_value
    173  *
    174  * This function is called when libsmbrdr connects to a PDC.
    175  * The PDC type is derived from the Native LanMan string.
    176  * The PDC value will default to PDC_WIN2000.
    177  *
    178  * Example strings:
    179  *
    180  *	NT LAN Manager 4.0
    181  *	Windows 4.0, Windows NT, Windows NT 4.0
    182  *	Windows 2000 LAN Manager
    183  *	Windows 2000, Windows 2000 5.0, Windows 2000 5.1
    184  *	Windows 2002, Windows 2002 5.1
    185  *	Windows .NET, Windows .NET 5.2
    186  *	Samba
    187  *	DAVE
    188  */
    189 int
    190 smbnative_pdc_value(const char *native_lm)
    191 {
    192 	static smb_native_t pdc_table[] = {
    193 		{ PDC_WINNT,	"NT LAN Manager 4.0"		},
    194 		{ PDC_WINNT,	"Windows NT 4.0"		},
    195 		{ PDC_WINNT,	"Windows NT"			},
    196 		{ PDC_WINNT,	"Windows 4.0"			},
    197 		{ PDC_WINNT,	"DAVE"				},
    198 		{ PDC_SAMBA,	"Samba"				}
    199 	};
    200 
    201 	int i;
    202 	int len;
    203 	const char *name;
    204 
    205 	if (native_lm == NULL || *native_lm == '\0')
    206 		return (PDC_WIN2000);
    207 
    208 	for (i = 0; i < sizeof (pdc_table)/sizeof (pdc_table[0]); ++i) {
    209 		name = pdc_table[i].sn_name;
    210 		len = strlen(name);
    211 
    212 		if ((smb_strcasecmp(name, native_lm, len) == 0) ||
    213 		    (smb_strcasecmp(&name[1], native_lm, len - 1) == 0)) {
    214 			return (pdc_table[i].sn_value);
    215 		}
    216 	}
    217 
    218 	return (PDC_WIN2000);
    219 }
    220