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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _KERNEL 27 #include <stdlib.h> 28 #include <string.h> 29 #else 30 #include <sys/types.h> 31 #include <sys/sunddi.h> 32 #endif 33 #include <smbsrv/ctype.h> 34 35 #define SMB_CRC_POLYNOMIAL 0xD8B5D8B5 36 37 /* 38 * c Any non-special character matches itslef 39 * ? Match any character 40 * ab character 'a' followed by character 'b' 41 * S Any string of non-special characters 42 * AB String 'A' followed by string 'B' 43 * * Any String, including the empty string 44 */ 45 int 46 smb_match(char *patn, char *str) 47 { 48 for (;;) { 49 switch (*patn) { 50 case 0: 51 return (*str == 0); 52 53 case '?': 54 if (*str != 0) { 55 str++; 56 patn++; 57 continue; 58 } else { 59 return (0); 60 } 61 /*NOTREACHED*/ 62 63 #if 0 64 case '[': 65 int invert = 0, clower, cupper; 66 67 patn++; 68 if (*patn == '!') { 69 invert = 1; 70 patn++; 71 } 72 for (;;) { 73 clower = *patn; 74 if (clower == 0) 75 break; 76 if (clower == ']') { 77 patn++; 78 break; 79 } 80 patn++; 81 if (*patn == '-') { 82 /* range */ 83 patn++; 84 cupper = *patn; 85 if (cupper == 0) 86 break; 87 patn++; 88 } else { 89 cupper = clower; 90 } 91 if (*str < clower || cupper < *str) 92 continue; 93 94 /* match */ 95 if (invert) 96 return (0); 97 98 while (*patn && *patn++ != ']') 99 ; 100 str++; 101 continue; /* THIS WON`T WORK */ 102 } 103 if (invert) { 104 str++; 105 continue; 106 } 107 return (0); 108 109 #endif 110 111 case '*': 112 patn++; 113 if (*patn == 0) 114 return (1); 115 116 #if 0 117 if (*patn != '?' && *patn != '*' && *patn != '[') { 118 /* accelerate */ 119 while (*str) { 120 if (*str == *patn && 121 match(patn+1, str+1)) 122 return (1); 123 str++; 124 } 125 return (0); 126 } 127 #endif 128 129 while (*str) { 130 if (smb_match(patn, str)) 131 return (1); 132 str++; 133 } 134 return (0); 135 136 default: 137 if (*str != *patn) 138 return (0); 139 str++; 140 patn++; 141 continue; 142 } 143 } 144 } 145 146 int 147 smb_match83(char *patn, char *str83) 148 { 149 int avail; 150 char *ptr; 151 char name83[14]; 152 153 ptr = name83; 154 for (avail = 8; (avail > 0) && (*patn != '.') && (*patn != 0); 155 avail--) { 156 *(ptr++) = *(patn++); 157 } 158 while (avail--) 159 *(ptr++) = ' '; 160 *(ptr++) = '.'; 161 162 if (*patn == '.') 163 patn++; 164 else if (*patn != 0) 165 return (0); 166 167 for (avail = 3; (avail > 0) && (*patn != 0); avail--) { 168 *(ptr++) = *(patn++); 169 } 170 if (*patn != 0) 171 return (0); 172 173 while (avail--) 174 *(ptr++) = ' '; 175 *ptr = 0; 176 177 return (smb_match_ci(name83, str83)); 178 } 179 180 181 182 int 183 smb_match_ci(char *patn, char *str) 184 { 185 /* 186 * "<" is a special pattern that matches only those names that do 187 * NOT have an extension. "." and ".." are ok. 188 */ 189 if (strcmp(patn, "<") == 0) { 190 if ((strcmp(str, ".") == 0) || (strcmp(str, "..") == 0)) 191 return (1); 192 if (strchr(str, '.') == 0) 193 return (1); 194 return (0); 195 } 196 for (;;) { 197 switch (*patn) { 198 case 0: 199 return (*str == 0); 200 201 case '?': 202 if (*str != 0) { 203 str++; 204 patn++; 205 continue; 206 } else { 207 return (0); 208 } 209 /*NOTREACHED*/ 210 211 212 case '*': 213 patn++; 214 if (*patn == 0) 215 return (1); 216 217 while (*str) { 218 if (smb_match_ci(patn, str)) 219 return (1); 220 str++; 221 } 222 return (0); 223 224 default: 225 if (*str != *patn) { 226 int c1 = *str; 227 int c2 = *patn; 228 229 c1 = mts_tolower(c1); 230 c2 = mts_tolower(c2); 231 if (c1 != c2) 232 return (0); 233 } 234 str++; 235 patn++; 236 continue; 237 } 238 } 239 /* NOT REACHED */ 240 } 241 242 uint32_t 243 smb_crc_gen(uint8_t *buf, size_t len) 244 { 245 uint32_t crc = SMB_CRC_POLYNOMIAL; 246 uint8_t *p; 247 int i; 248 249 for (p = buf, i = 0; i < len; ++i, ++p) { 250 crc = (crc ^ (uint32_t)*p) + (crc << 12); 251 252 if (crc == 0 || crc == 0xFFFFFFFF) 253 crc = SMB_CRC_POLYNOMIAL; 254 } 255 256 return (crc); 257 } 258