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