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 if (*native_os == '\0') { 94 /* 95 * Windows Vista sends an empty native OS string. 96 */ 97 return (NATIVE_OS_WIN2000); 98 } 99 100 for (i = 0; i < sizeof (os_table)/sizeof (os_table[0]); ++i) { 101 os_name = os_table[i].os_name; 102 len = strlen(os_name); 103 104 if (utf8_strncasecmp(os_name, native_os, len) == 0) { 105 return (os_table[i].os_value); 106 } 107 } 108 return (NATIVE_OS_UNKNOWN); 109 } 110 111 112 /* 113 * smbnative_lm_value 114 * 115 * Return the appropriate native LanMan value for the specified native 116 * LanMan name. There's an alignment problem in some packets from some 117 * clients that means we can miss the first character, so we do an 118 * additional check starting from the second character. 119 * 120 * DAVE (Thursby Software: CIFS for MacOS) sometimes uses a Unicode 121 * character in the LanMan name. Variations seen so far are: 122 * 123 * 44 00 41 00 56 00 45 00 00 00 D.A.V.E... 124 * 125 * 44 00 41 00 56 00 45 00 22 21 20 00 56 00 32 00 126 * 2E 00 35 00 2E 00 31 00 00 00 D.A.V.E."!..V.2...5...1... 127 * 128 * Samba reports its own name (Samba) as its Native LM, which we can 129 * map to NT LM 4.0. 130 */ 131 int 132 smbnative_lm_value(char *native_lm) 133 { 134 typedef struct native_lm_table { 135 int lm_value; 136 char *lm_name; 137 } native_lm_table_t; 138 139 static native_lm_table_t lm_table[] = { 140 { NATIVE_LM_NT, "NT LAN Manager 4.0" }, 141 { NATIVE_LM_NT, "Windows NT 4.0" }, 142 { NATIVE_LM_NT, "Windows NT" }, 143 { NATIVE_LM_NT, "Windows 4.0" }, 144 { NATIVE_LM_WIN2000, "Windows 2000 LAN Manager" }, 145 { NATIVE_LM_WIN2000, "Windows 2000 5.0" }, 146 { NATIVE_LM_WIN2000, "Windows 2000 5.1" }, 147 { NATIVE_LM_WIN2000, "Windows 2000", }, 148 { NATIVE_LM_WIN2000, "Windows 2002 5.1" }, 149 { NATIVE_LM_WIN2000, "Windows 2002" }, 150 { NATIVE_LM_WIN2000, "Windows .NET 5.2" }, 151 { NATIVE_LM_WIN2000, "Windows .NET" }, 152 { NATIVE_LM_WIN2000, "Windows Server 2003" }, 153 { NATIVE_LM_WIN2000, "Windows XP" }, 154 { NATIVE_LM_NT, "Samba" }, 155 { NATIVE_LM_NT, "DAVE" } 156 }; 157 158 int i; 159 int len; 160 char *lm_name; 161 162 if (native_lm == NULL) { 163 return (NATIVE_LM_NONE); 164 } 165 166 if (*native_lm == '\0') { 167 /* 168 * Windows Vista sends an empty native LM string. 169 */ 170 return (NATIVE_LM_WIN2000); 171 } 172 173 for (i = 0; i < sizeof (lm_table)/sizeof (lm_table[0]); ++i) { 174 lm_name = lm_table[i].lm_name; 175 len = strlen(lm_name); 176 177 if ((utf8_strncasecmp(lm_name, native_lm, len) == 0) || 178 (utf8_strncasecmp(&lm_name[1], native_lm, len - 1) == 0)) { 179 return (lm_table[i].lm_value); 180 } 181 } 182 return (NATIVE_LM_NONE); 183 } 184 185 /* 186 * smbnative_pdc_value 187 * 188 * This function is used when NetFORCE contacting a PDC 189 * to authenticate a connected user to determine and keep 190 * the PDC type. 191 * 192 * The reason for adding this functionality is that NetFORCE 193 * doesn't support Samba PDC but code didn't check the PDC type 194 * and do authentication agains any PDC. This behaviour could 195 * cause problem in some circumstances. 196 * Now that we determine the PDC type the authentication code 197 * can be configured (by smb.samba.pdc env var) to return access 198 * denied to authentication attempts when PDC is Samba. 199 */ 200 int 201 smbnative_pdc_value(char *native_lm) 202 { 203 typedef struct pdc_table { 204 int pdc_value; 205 char *pdc_lmname; 206 } pdc_table_t; 207 208 static pdc_table_t pdc_table[] = { 209 { PDC_WINNT, "NT LAN Manager 4.0" }, 210 { PDC_WINNT, "Windows NT 4.0" }, 211 { PDC_WINNT, "Windows NT" }, 212 { PDC_WINNT, "Windows 4.0" }, 213 { PDC_WIN2000, "Windows 2000 LAN Manager" }, 214 { PDC_WIN2000, "Windows 2000 5.0" }, 215 { PDC_WIN2000, "Windows 2000 5.1" }, 216 { PDC_WIN2000, "Windows 2000", }, 217 { PDC_WIN2000, "Windows 2002 5.1" }, 218 { PDC_WIN2000, "Windows 2002" }, 219 { PDC_WIN2000, "Windows .NET 5.2" }, 220 { PDC_WIN2000, "Windows .NET" }, 221 { PDC_SAMBA, "Samba" }, 222 { PDC_WINNT, "DAVE" } 223 }; 224 225 int i; 226 int len; 227 char *pdc_lmname; 228 229 if (native_lm == 0) { 230 return (PDC_UNKNOWN); 231 } 232 233 for (i = 0; i < sizeof (pdc_table)/sizeof (pdc_table[0]); ++i) { 234 pdc_lmname = pdc_table[i].pdc_lmname; 235 len = strlen(pdc_lmname); 236 237 if ((utf8_strncasecmp(pdc_lmname, native_lm, len) == 0) || 238 (utf8_strncasecmp(&pdc_lmname[1], native_lm, len - 1) 239 == 0)) { 240 return (pdc_table[i].pdc_value); 241 } 242 } 243 244 return (PDC_UNKNOWN); 245 } 246