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 /* 22*3a6c5f83SAlan Wright * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23da6c28aaSamw * Use is subject to license terms. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw #ifndef _KERNEL 27da6c28aaSamw #include <stdlib.h> 28da6c28aaSamw #include <string.h> 29da6c28aaSamw #else 30da6c28aaSamw #include <sys/types.h> 31da6c28aaSamw #include <sys/sunddi.h> 32da6c28aaSamw #endif 33da6c28aaSamw #include <smbsrv/ctype.h> 34da6c28aaSamw 35*3a6c5f83SAlan Wright /* 36*3a6c5f83SAlan Wright * Maximum recursion depth for the wildcard match functions. 37*3a6c5f83SAlan Wright * These functions may recurse when processing a '*'. 38*3a6c5f83SAlan Wright */ 39*3a6c5f83SAlan Wright #define SMB_MATCH_DEPTH_MAX 32 40*3a6c5f83SAlan Wright 4194fff790SAlan Wright #define SMB_CRC_POLYNOMIAL 0xD8B5D8B5 42da6c28aaSamw 43*3a6c5f83SAlan Wright static int smb_match_private(const char *, const char *, int *); 44*3a6c5f83SAlan Wright static int smb_match_ci_private(const char *, const char *, int *); 45*3a6c5f83SAlan Wright 46da6c28aaSamw /* 47*3a6c5f83SAlan Wright * Returns: 48*3a6c5f83SAlan Wright * 1 match 49*3a6c5f83SAlan Wright * 0 no-match 50da6c28aaSamw */ 51da6c28aaSamw int 52da6c28aaSamw smb_match(char *patn, char *str) 53da6c28aaSamw { 54*3a6c5f83SAlan Wright int depth = 0; 55*3a6c5f83SAlan Wright int rc; 56*3a6c5f83SAlan Wright 57*3a6c5f83SAlan Wright if ((rc = smb_match_private(patn, str, &depth)) == -1) 58*3a6c5f83SAlan Wright rc = 0; 59*3a6c5f83SAlan Wright 60*3a6c5f83SAlan Wright return (rc); 61*3a6c5f83SAlan Wright } 62*3a6c5f83SAlan Wright 63*3a6c5f83SAlan Wright /* 64*3a6c5f83SAlan Wright * The '*' character matches multiple characters. 65*3a6c5f83SAlan Wright * The '?' character matches a single character. 66*3a6c5f83SAlan Wright * 67*3a6c5f83SAlan Wright * If the pattern has trailing '?'s then it matches the specified number 68*3a6c5f83SAlan Wright * of characters or less. For example, "x??" matches "xab", "xa" and "x", 69*3a6c5f83SAlan Wright * but not "xabc". 70*3a6c5f83SAlan Wright * 71*3a6c5f83SAlan Wright * Returns: 72*3a6c5f83SAlan Wright * 1 match 73*3a6c5f83SAlan Wright * 0 no-match 74*3a6c5f83SAlan Wright * -1 no-match, too many wildcards in pattern 75*3a6c5f83SAlan Wright */ 76*3a6c5f83SAlan Wright static int 77*3a6c5f83SAlan Wright smb_match_private(const char *patn, const char *str, int *depth) 78*3a6c5f83SAlan Wright { 79*3a6c5f83SAlan Wright int rc; 80*3a6c5f83SAlan Wright 81da6c28aaSamw for (;;) { 82da6c28aaSamw switch (*patn) { 83da6c28aaSamw case 0: 84da6c28aaSamw return (*str == 0); 85da6c28aaSamw 86da6c28aaSamw case '?': 87da6c28aaSamw if (*str != 0) { 88da6c28aaSamw str++; 89da6c28aaSamw patn++; 90da6c28aaSamw continue; 91da6c28aaSamw } else { 92da6c28aaSamw return (0); 93da6c28aaSamw } 94da6c28aaSamw /*NOTREACHED*/ 95da6c28aaSamw 96da6c28aaSamw case '*': 97*3a6c5f83SAlan Wright patn += strspn(patn, "*"); 98da6c28aaSamw if (*patn == 0) 99da6c28aaSamw return (1); 100da6c28aaSamw 101*3a6c5f83SAlan Wright if ((*depth)++ >= SMB_MATCH_DEPTH_MAX) 102*3a6c5f83SAlan Wright return (-1); 103da6c28aaSamw 104da6c28aaSamw while (*str) { 105*3a6c5f83SAlan Wright rc = smb_match_private(patn, str, depth); 106*3a6c5f83SAlan Wright if (rc != 0) 107*3a6c5f83SAlan Wright return (rc); 108da6c28aaSamw str++; 109da6c28aaSamw } 110da6c28aaSamw return (0); 111da6c28aaSamw 112da6c28aaSamw default: 113da6c28aaSamw if (*str != *patn) 114da6c28aaSamw return (0); 115da6c28aaSamw str++; 116da6c28aaSamw patn++; 117da6c28aaSamw continue; 118da6c28aaSamw } 119da6c28aaSamw } 120*3a6c5f83SAlan Wright /*NOTREACHED*/ 121da6c28aaSamw } 122da6c28aaSamw 123da6c28aaSamw int 124da6c28aaSamw smb_match83(char *patn, char *str83) 125da6c28aaSamw { 126da6c28aaSamw int avail; 127da6c28aaSamw char *ptr; 128da6c28aaSamw char name83[14]; 129da6c28aaSamw 130da6c28aaSamw ptr = name83; 131da6c28aaSamw for (avail = 8; (avail > 0) && (*patn != '.') && (*patn != 0); 132da6c28aaSamw avail--) { 133da6c28aaSamw *(ptr++) = *(patn++); 134da6c28aaSamw } 135da6c28aaSamw while (avail--) 136da6c28aaSamw *(ptr++) = ' '; 137da6c28aaSamw *(ptr++) = '.'; 138da6c28aaSamw 139da6c28aaSamw if (*patn == '.') 140da6c28aaSamw patn++; 141da6c28aaSamw else if (*patn != 0) 142da6c28aaSamw return (0); 143da6c28aaSamw 144da6c28aaSamw for (avail = 3; (avail > 0) && (*patn != 0); avail--) { 145da6c28aaSamw *(ptr++) = *(patn++); 146da6c28aaSamw } 147da6c28aaSamw if (*patn != 0) 148da6c28aaSamw return (0); 149da6c28aaSamw 150da6c28aaSamw while (avail--) 151da6c28aaSamw *(ptr++) = ' '; 152da6c28aaSamw *ptr = 0; 153da6c28aaSamw 154da6c28aaSamw return (smb_match_ci(name83, str83)); 155da6c28aaSamw } 156da6c28aaSamw 157*3a6c5f83SAlan Wright /* 158*3a6c5f83SAlan Wright * Returns: 159*3a6c5f83SAlan Wright * 1 match 160*3a6c5f83SAlan Wright * 0 no-match 161*3a6c5f83SAlan Wright */ 162da6c28aaSamw int 163da6c28aaSamw smb_match_ci(char *patn, char *str) 164da6c28aaSamw { 165*3a6c5f83SAlan Wright int depth = 0; 166*3a6c5f83SAlan Wright int rc; 167*3a6c5f83SAlan Wright 168*3a6c5f83SAlan Wright if ((rc = smb_match_ci_private(patn, str, &depth)) == -1) 169*3a6c5f83SAlan Wright rc = 0; 170*3a6c5f83SAlan Wright 171*3a6c5f83SAlan Wright return (rc); 172*3a6c5f83SAlan Wright } 173*3a6c5f83SAlan Wright 174*3a6c5f83SAlan Wright /* 175*3a6c5f83SAlan Wright * The '*' character matches multiple characters. 176*3a6c5f83SAlan Wright * The '?' character matches a single character. 177*3a6c5f83SAlan Wright * 178*3a6c5f83SAlan Wright * If the pattern has trailing '?'s then it matches the specified number 179*3a6c5f83SAlan Wright * of characters or less. For example, "x??" matches "xab", "xa" and "x", 180*3a6c5f83SAlan Wright * but not "xabc". 181*3a6c5f83SAlan Wright * 182*3a6c5f83SAlan Wright * Returns: 183*3a6c5f83SAlan Wright * 1 match 184*3a6c5f83SAlan Wright * 0 no-match 185*3a6c5f83SAlan Wright * -1 no-match, too many wildcards in pattern 186*3a6c5f83SAlan Wright */ 187*3a6c5f83SAlan Wright static int 188*3a6c5f83SAlan Wright smb_match_ci_private(const char *patn, const char *str, int *depth) 189*3a6c5f83SAlan Wright { 190*3a6c5f83SAlan Wright const char *p; 191*3a6c5f83SAlan Wright int rc; 192*3a6c5f83SAlan Wright 193da6c28aaSamw /* 194da6c28aaSamw * "<" is a special pattern that matches only those names that do 195da6c28aaSamw * NOT have an extension. "." and ".." are ok. 196da6c28aaSamw */ 197da6c28aaSamw if (strcmp(patn, "<") == 0) { 198da6c28aaSamw if ((strcmp(str, ".") == 0) || (strcmp(str, "..") == 0)) 199da6c28aaSamw return (1); 200da6c28aaSamw if (strchr(str, '.') == 0) 201da6c28aaSamw return (1); 202da6c28aaSamw return (0); 203da6c28aaSamw } 204*3a6c5f83SAlan Wright 205da6c28aaSamw for (;;) { 206da6c28aaSamw switch (*patn) { 207da6c28aaSamw case 0: 208da6c28aaSamw return (*str == 0); 209da6c28aaSamw 210da6c28aaSamw case '?': 211da6c28aaSamw if (*str != 0) { 212da6c28aaSamw str++; 213da6c28aaSamw patn++; 214da6c28aaSamw continue; 215da6c28aaSamw } else { 216*3a6c5f83SAlan Wright p = patn; 217*3a6c5f83SAlan Wright p += strspn(p, "?"); 218*3a6c5f83SAlan Wright return ((*p == '\0') ? 1 : 0); 219da6c28aaSamw } 220da6c28aaSamw /*NOTREACHED*/ 221da6c28aaSamw 222da6c28aaSamw case '*': 223*3a6c5f83SAlan Wright patn += strspn(patn, "*"); 224da6c28aaSamw if (*patn == 0) 225da6c28aaSamw return (1); 226da6c28aaSamw 227*3a6c5f83SAlan Wright if ((*depth)++ >= SMB_MATCH_DEPTH_MAX) 228*3a6c5f83SAlan Wright return (-1); 229*3a6c5f83SAlan Wright 230da6c28aaSamw while (*str) { 231*3a6c5f83SAlan Wright rc = smb_match_ci_private(patn, str, depth); 232*3a6c5f83SAlan Wright if (rc != 0) 233*3a6c5f83SAlan Wright return (rc); 234da6c28aaSamw str++; 235da6c28aaSamw } 236da6c28aaSamw return (0); 237da6c28aaSamw 238da6c28aaSamw default: 239da6c28aaSamw if (*str != *patn) { 240da6c28aaSamw int c1 = *str; 241da6c28aaSamw int c2 = *patn; 242da6c28aaSamw 243da6c28aaSamw c1 = mts_tolower(c1); 244da6c28aaSamw c2 = mts_tolower(c2); 245da6c28aaSamw if (c1 != c2) 246da6c28aaSamw return (0); 247da6c28aaSamw } 248da6c28aaSamw str++; 249da6c28aaSamw patn++; 250da6c28aaSamw continue; 251da6c28aaSamw } 252da6c28aaSamw } 253*3a6c5f83SAlan Wright /*NOTREACHED*/ 254da6c28aaSamw } 25594fff790SAlan Wright 25694fff790SAlan Wright uint32_t 25794fff790SAlan Wright smb_crc_gen(uint8_t *buf, size_t len) 25894fff790SAlan Wright { 25994fff790SAlan Wright uint32_t crc = SMB_CRC_POLYNOMIAL; 26094fff790SAlan Wright uint8_t *p; 26194fff790SAlan Wright int i; 26294fff790SAlan Wright 26394fff790SAlan Wright for (p = buf, i = 0; i < len; ++i, ++p) { 26494fff790SAlan Wright crc = (crc ^ (uint32_t)*p) + (crc << 12); 26594fff790SAlan Wright 26694fff790SAlan Wright if (crc == 0 || crc == 0xFFFFFFFF) 26794fff790SAlan Wright crc = SMB_CRC_POLYNOMIAL; 26894fff790SAlan Wright } 26994fff790SAlan Wright 27094fff790SAlan Wright return (crc); 27194fff790SAlan Wright } 272