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