Пример #1
0
int strcmp_wa(const smb_ucs2_t *a, const char *b)
{
	smb_ucs2_t cp = 0;

	while (*b && *(COPY_UCS2_CHAR(&cp,a)) == UCS2_CHAR(*b)) {
		a++;
		b++;
	}
	return (*(COPY_UCS2_CHAR(&cp,a)) - UCS2_CHAR(*b));
}
Пример #2
0
static int null_match(const smb_ucs2_t *p)
{
	for (;*p;p++) {
		if (*p != UCS2_CHAR('*') &&
		    *p != UCS2_CHAR('<') &&
		    *p != UCS2_CHAR('"') &&
		    *p != UCS2_CHAR('>')) return -1;
	}
	return 0;
}
Пример #3
0
int strncmp_wa(const smb_ucs2_t *a, const char *b, size_t len)
{
	smb_ucs2_t cp = 0;
	size_t n = 0;

	while ((n < len) && *b && *(COPY_UCS2_CHAR(&cp,a)) == UCS2_CHAR(*b)) {
		a++;
		b++;
		n++;
	}
	return (len - n)?(*(COPY_UCS2_CHAR(&cp,a)) - UCS2_CHAR(*b)):0;
}
Пример #4
0
static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **prefix,
		smb_ucs2_t **extension, bool allow_wildcards)
{
	size_t ext_len;
	smb_ucs2_t *p;

	*extension = 0;
	*prefix = strdup_w(ucs2_string);
	if (!*prefix) {
		return NT_STATUS_NO_MEMORY;
	}
	if ((p = strrchr_w(*prefix, UCS2_CHAR('.')))) {
		ext_len = strlen_w(p+1);
		if ((ext_len > 0) && (ext_len < 4) && (p != *prefix) &&
		    (NT_STATUS_IS_OK(has_valid_83_chars(p+1,allow_wildcards)))) /* check extension */ {
			*p = 0;
			*extension = strdup_w(p+1);
			if (!*extension) {
				SAFE_FREE(*prefix);
				return NT_STATUS_NO_MEMORY;
			}
		}
	}
	return NT_STATUS_OK;
}
Пример #5
0
void pstrcpy_wa(smb_ucs2_t *dest, const char *src)
{
	int i;
	for (i=0;i<PSTRING_LEN;i++) {
		dest[i] = UCS2_CHAR(src[i]);
		if (src[i] == 0) return;
	}
}
Пример #6
0
/**
 * Load or generate the case handling tables.
 *
 * The case tables are defined in UCS2 and don't depend on any
 * configured parameters, so they never need to be reloaded.
 **/
void load_case_tables(void)
{
	static int initialised;
	int i;

	if (initialised) return;
	initialised = 1;

	upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
	lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);

	/* we would like Samba to limp along even if these tables are
	   not available */
	if (!upcase_table) {
		DEBUG(1,("creating lame upcase table\n"));
		upcase_table = malloc(0x20000);
		for (i=0;i<0x10000;i++) {
			smb_ucs2_t v;
			SSVAL(&v, 0, i);
			upcase_table[v] = i;
		}
		for (i=0;i<256;i++) {
			smb_ucs2_t v;
			SSVAL(&v, 0, UCS2_CHAR(i));
			upcase_table[v] = UCS2_CHAR(islower(i)?toupper(i):i);
		}
	}

	if (!lowcase_table) {
		DEBUG(1,("creating lame lowcase table\n"));
		lowcase_table = malloc(0x20000);
		for (i=0;i<0x10000;i++) {
			smb_ucs2_t v;
			SSVAL(&v, 0, i);
			lowcase_table[v] = i;
		}
		for (i=0;i<256;i++) {
			smb_ucs2_t v;
			SSVAL(&v, 0, UCS2_CHAR(i));
			lowcase_table[v] = UCS2_CHAR(isupper(i)?tolower(i):i);
		}
	}
}
Пример #7
0
smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p)
{
	while (*s != 0) {
		int i;
		for (i=0; p[i] && *s != UCS2_CHAR(p[i]); i++) 
			;
		if (p[i]) return (smb_ucs2_t *)s;
		s++;
	}
	return NULL;
}
Пример #8
0
static NTSTATUS has_illegal_chars(const smb_ucs2_t *s, bool allow_wildcards)
{
	if (!allow_wildcards && ms_has_wild_w(s)) {
		return NT_STATUS_UNSUCCESSFUL;
	}

	while (*s) {
		if (*s <= 0x1f) {
			/* Control characters. */
			return NT_STATUS_UNSUCCESSFUL;
		}
		switch(*s) {
			case UCS2_CHAR('\\'):
			case UCS2_CHAR('/'):
			case UCS2_CHAR('|'):
			case UCS2_CHAR(':'):
				return NT_STATUS_UNSUCCESSFUL;
		}
		s++;
	}

	return NT_STATUS_OK;
}
Пример #9
0
smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins)
{
	smb_ucs2_t *r;
	size_t slen, inslen;

	if (!s || !*s || !ins || !*ins) return NULL;
	slen = strlen_w(s);
	inslen = strlen(ins);
	r = (smb_ucs2_t *)s;
	while ((r = strchr_w(r, UCS2_CHAR(*ins)))) {
		if (strncmp_wa(r, ins, inslen) == 0) return r;
		r++;
	}
	return NULL;
}
Пример #10
0
smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p)
{
	smb_ucs2_t cp;

	while (*(COPY_UCS2_CHAR(&cp,s))) {
		int i;
		for (i=0; p[i] && cp != UCS2_CHAR(p[i]); i++) 
			;
		if (p[i]) {
			return (smb_ucs2_t *)s;
		}
		s++;
	}
	return NULL;
}
Пример #11
0
static NTSTATUS is_8_3_w(const smb_ucs2_t *fname, bool allow_wildcards)
{
	smb_ucs2_t *pref = 0, *ext = 0;
	size_t plen;
	NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;

	if (!fname || !*fname)
		return NT_STATUS_INVALID_PARAMETER;

	if (strlen_w(fname) > 12)
		return NT_STATUS_UNSUCCESSFUL;

	if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
		return NT_STATUS_OK;

	/* Name cannot start with '.' */
	if (*fname == UCS2_CHAR('.'))
		return NT_STATUS_UNSUCCESSFUL;

	if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards, True)))
		goto done;

	if (!NT_STATUS_IS_OK(mangle_get_prefix(fname, &pref, &ext, allow_wildcards)))
		goto done;
	plen = strlen_w(pref);

	if (strchr_wa(pref, '.'))
		goto done;
	if (plen < 1 || plen > 8)
		goto done;
	if (ext && (strlen_w(ext) > 3))
		goto done;

	ret = NT_STATUS_OK;

done:
	SAFE_FREE(pref);
	SAFE_FREE(ext);
	return ret;
}
Пример #12
0
/*
  p and n are the pattern and string being matched. The max_n array is
  an optimisation only. The ldot pointer is NULL if the string does
  not contain a '.', otherwise it points at the last dot in 'n'.
*/
static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n,
			   struct max_n *max_n, const smb_ucs2_t *ldot,
			   bool is_case_sensitive)
{
	smb_ucs2_t c;
	int i;

	while ((c = *p++)) {
		switch (c) {
			/* a '*' matches zero or more characters of any type */
		case UCS2_CHAR('*'):
			if (max_n->predot && max_n->predot <= n) {
				return null_match(p);
			}
			for (i=0; n[i]; i++) {
				if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) {
					return 0;
				}
			}
			if (!max_n->predot || max_n->predot > n) max_n->predot = n;
			return null_match(p);

			/* a '<' matches zero or more characters of
			   any type, but stops matching at the last
			   '.' in the string. */
		case UCS2_CHAR('<'):
			if (max_n->predot && max_n->predot <= n) {
				return null_match(p);
			}
			if (max_n->postdot && max_n->postdot <= n && n <= ldot) {
				return -1;
			}
			for (i=0; n[i]; i++) {
				if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) return 0;
				if (n+i == ldot) {
					if (ms_fnmatch_core(p, n+i+1, max_n+1, ldot, is_case_sensitive) == 0) return 0;
					if (!max_n->postdot || max_n->postdot > n) max_n->postdot = n;
					return -1;
				}
			}
			if (!max_n->predot || max_n->predot > n) max_n->predot = n;
			return null_match(p);

			/* a '?' matches any single character */
		case UCS2_CHAR('?'):
			if (! *n) {
				return -1;
			}
			n++;
			break;

			/* a '?' matches any single character */
		case UCS2_CHAR('>'):
			if (n[0] == UCS2_CHAR('.')) {
				if (! n[1] && null_match(p) == 0) {
					return 0;
				}
				break;
			}
			if (! *n) return null_match(p);
			n++;
			break;

		case UCS2_CHAR('"'):
			if (*n == 0 && null_match(p) == 0) {
				return 0;
			}
			if (*n != UCS2_CHAR('.')) return -1;
			n++;
			break;

		default:
			if (c != *n) {
				if (is_case_sensitive) {
					return -1;
				}
				if (toupper_w(c) != toupper_w(*n)) {
					return -1;
				}
			}
			n++;
			break;
		}
	}

	if (! *n) {
		return 0;
	}

	return -1;
}
Пример #13
0
int tolower_ascii(int c)
{
	smb_ucs2_t uc = tolower_w(UCS2_CHAR(c));
	return UCS2_TO_CHAR(uc);
}
Пример #14
0
int strcmp_wa(const smb_ucs2_t *a, const char *b)
{
	while (*b && *a == UCS2_CHAR(*b)) { a++; b++; }
	return (*a - UCS2_CHAR(*b));
}
Пример #15
0
int strncmp_wa(const smb_ucs2_t *a, const char *b, size_t len)
{
	size_t n = 0;
	while ((n < len) && *b && *a == UCS2_CHAR(*b)) { a++; b++; n++;}
	return (len - n)?(*a - UCS2_CHAR(*b)):0;
}
Пример #16
0
static NTSTATUS is_valid_name(const smb_ucs2_t *fname, bool allow_wildcards, bool only_8_3)
{
	smb_ucs2_t *str, *p;
	size_t num_ucs2_chars;
	NTSTATUS ret = NT_STATUS_OK;

	if (!fname || !*fname)
		return NT_STATUS_INVALID_PARAMETER;

	/* . and .. are valid names. */
	if (strcmp_wa(fname, ".")==0 || strcmp_wa(fname, "..")==0)
		return NT_STATUS_OK;

	if (only_8_3) {
		ret = has_valid_83_chars(fname, allow_wildcards);
		if (!NT_STATUS_IS_OK(ret))
			return ret;
	}

	ret = has_illegal_chars(fname, allow_wildcards);
	if (!NT_STATUS_IS_OK(ret))
		return ret;

	/* Name can't end in '.' or ' ' */
	num_ucs2_chars = strlen_w(fname);
	if (fname[num_ucs2_chars-1] == UCS2_CHAR('.') || fname[num_ucs2_chars-1] == UCS2_CHAR(' ')) {
		return NT_STATUS_UNSUCCESSFUL;
	}

	str = strdup_w(fname);

	/* Truncate copy after the first dot. */
	p = strchr_w(str, UCS2_CHAR('.'));
	if (p) {
		*p = 0;
	}

	strupper_w(str);
	p = &str[1];

	switch(str[0])
	{
	case UCS2_CHAR('A'):
		if(strcmp_wa(p, "UX") == 0)
			ret = NT_STATUS_UNSUCCESSFUL;
		break;
	case UCS2_CHAR('C'):
		if((strcmp_wa(p, "LOCK$") == 0)
		|| (strcmp_wa(p, "ON") == 0)
		|| (strcmp_wa(p, "OM1") == 0)
		|| (strcmp_wa(p, "OM2") == 0)
		|| (strcmp_wa(p, "OM3") == 0)
		|| (strcmp_wa(p, "OM4") == 0)
		)
			ret = NT_STATUS_UNSUCCESSFUL;
		break;
	case UCS2_CHAR('L'):
		if((strcmp_wa(p, "PT1") == 0)
		|| (strcmp_wa(p, "PT2") == 0)
		|| (strcmp_wa(p, "PT3") == 0)
		)
			ret = NT_STATUS_UNSUCCESSFUL;
		break;
	case UCS2_CHAR('N'):
		if(strcmp_wa(p, "UL") == 0)
			ret = NT_STATUS_UNSUCCESSFUL;
		break;
	case UCS2_CHAR('P'):
		if(strcmp_wa(p, "RN") == 0)
			ret = NT_STATUS_UNSUCCESSFUL;
		break;
	default:
		break;
	}

	SAFE_FREE(str);
	return ret;
}
Пример #17
0
void load_case_tables(void)
{
	static int initialised;
	char *old_locale = NULL, *saved_locale = NULL;
	int i;

	if (initialised) {
		return;
	}
	initialised = 1;

	upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
	upcase_table_use_unmap = ( upcase_table != NULL );

	lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);
	lowcase_table_use_unmap = ( lowcase_table != NULL );

#ifdef HAVE_SETLOCALE
	/* Get the name of the current locale.  */
	old_locale = setlocale(LC_ALL, NULL);

	if (old_locale) {
		/* Save it as it is in static storage. */
		saved_locale = SMB_STRDUP(old_locale);
	}

	/* We set back the locale to C to get ASCII-compatible toupper/lower functions. */
	setlocale(LC_ALL, "C");
#endif

	/* we would like Samba to limp along even if these tables are
	   not available */
	if (!upcase_table) {
		DEBUG(1,("creating lame upcase table\n"));
		upcase_table = SMB_MALLOC(0x20000);
		for (i=0;i<0x10000;i++) {
			smb_ucs2_t v;
			SSVAL(&v, 0, i);
			upcase_table[v] = i;
		}
		for (i=0;i<256;i++) {
			smb_ucs2_t v;
			SSVAL(&v, 0, UCS2_CHAR(i));
			upcase_table[v] = UCS2_CHAR(islower(i)?toupper(i):i);
		}
	}

	if (!lowcase_table) {
		DEBUG(1,("creating lame lowcase table\n"));
		lowcase_table = SMB_MALLOC(0x20000);
		for (i=0;i<0x10000;i++) {
			smb_ucs2_t v;
			SSVAL(&v, 0, i);
			lowcase_table[v] = i;
		}
		for (i=0;i<256;i++) {
			smb_ucs2_t v;
			SSVAL(&v, 0, UCS2_CHAR(i));
			lowcase_table[v] = UCS2_CHAR(isupper(i)?tolower(i):i);
		}
	}

#ifdef HAVE_SETLOCALE
	/* Restore the old locale. */
	if (saved_locale) {
		setlocale (LC_ALL, saved_locale);
		SAFE_FREE(saved_locale);
	}
#endif
}
Пример #18
0
smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c)
{
	return strchr_w(s, UCS2_CHAR(c));
}
Пример #19
0
int islower_ascii(int c)
{
	return islower_w(UCS2_CHAR(c));
}
Пример #20
0
int ms_fnmatch(const char *pattern, const char *string, bool translate_pattern,
	       bool is_case_sensitive)
{
	smb_ucs2_t *p = NULL;
	smb_ucs2_t *s = NULL;
	int ret, count, i;
	struct max_n *max_n = NULL;
	struct max_n *max_n_free = NULL;
	struct max_n one_max_n;
	size_t converted_size;

	if (ISDOTDOT(string)) {
		string = ".";
	}

	if (strpbrk(pattern, "<>*?\"") == NULL) {
		/* this is not just an optmisation - it is essential
		   for LANMAN1 correctness */
		if (is_case_sensitive) {
			return strcmp(pattern, string);
		} else {
			return StrCaseCmp(pattern, string);
		}
	}

	if (!push_ucs2_talloc(talloc_tos(), &p, pattern, &converted_size)) {
		return -1;
	}

	if (!push_ucs2_talloc(talloc_tos(), &s, string, &converted_size)) {
		TALLOC_FREE(p);
		return -1;
	}

	if (translate_pattern) {
		/*
		  for older negotiated protocols it is possible to
		  translate the pattern to produce a "new style"
		  pattern that exactly matches w2k behaviour
		*/
		for (i=0;p[i];i++) {
			if (p[i] == UCS2_CHAR('?')) {
				p[i] = UCS2_CHAR('>');
			} else if (p[i] == UCS2_CHAR('.') &&
				   (p[i+1] == UCS2_CHAR('?') ||
				    p[i+1] == UCS2_CHAR('*') ||
				    p[i+1] == 0)) {
				p[i] = UCS2_CHAR('"');
			} else if (p[i] == UCS2_CHAR('*') && p[i+1] == UCS2_CHAR('.')) {
				p[i] = UCS2_CHAR('<');
			}
		}
	}

	for (count=i=0;p[i];i++) {
		if (p[i] == UCS2_CHAR('*') || p[i] == UCS2_CHAR('<')) count++;
	}

	if (count != 0) {
		if (count == 1) {
			/*
			 * We're doing this a LOT, so save the effort to allocate
			 */
			ZERO_STRUCT(one_max_n);
			max_n = &one_max_n;
		}
		else {
			max_n = SMB_CALLOC_ARRAY(struct max_n, count);
			if (!max_n) {
				TALLOC_FREE(p);
				TALLOC_FREE(s);
				return -1;
			}
			max_n_free = max_n;
		}
	}

	ret = ms_fnmatch_core(p, s, max_n, strrchr_w(s, UCS2_CHAR('.')), is_case_sensitive);

	SAFE_FREE(max_n_free);
	TALLOC_FREE(p);
	TALLOC_FREE(s);
	return ret;
}