summaryrefslogtreecommitdiff
path: root/source3/smbd/mangle.c
blob: 16f99636eb539b0a4b61c3c99d2823667930b5f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* 
   Unix SMB/CIFS implementation.
   Name mangling interface
   Copyright (C) Andrew Tridgell 2002
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "includes.h"

static struct mangle_fns *mangle_fns;

/* this allows us to add more mangling backends */
static const struct {
	const char *name;
	struct mangle_fns *(*init_fn)(void);
} mangle_backends[] = {
	{ "hash", mangle_hash_init },
	{ "hash2", mangle_hash2_init },
	{ "posix", posix_mangle_init },
	/*{ "tdb", mangle_tdb_init }, */
	{ NULL, NULL }
};

/*
  initialise the mangling subsystem
*/
static void mangle_init(void)
{
	int i;
	const char *method;

	if (mangle_fns)
		return;

	method = lp_mangling_method();

	/* find the first mangling method that manages to initialise and
	   matches the "mangling method" parameter */
	for (i=0; mangle_backends[i].name && !mangle_fns; i++) {
		if (!method || !*method || strcmp(method, mangle_backends[i].name) == 0) {
			mangle_fns = mangle_backends[i].init_fn();
		}
	}

	if (!mangle_fns) {
		DEBUG(0,("Failed to initialise mangling system '%s'\n", method));
		exit_server("mangling init failed");
	}
}


/*
  reset the cache. This is called when smb.conf has been reloaded
*/
void mangle_reset_cache(void)
{
	mangle_init();
	mangle_fns->reset();
}

void mangle_change_to_posix(void)
{
	mangle_fns = NULL;
	lp_set_mangling_method("posix");
	mangle_reset_cache();
}

/*
  see if a filename has come out of our mangling code
*/
BOOL mangle_is_mangled(const char *s, const struct share_params *p)
{
	return mangle_fns->is_mangled(s, p);
}

/*
  see if a filename matches the rules of a 8.3 filename
*/
BOOL mangle_is_8_3(const char *fname, BOOL check_case,
		   const struct share_params *p)
{
	return mangle_fns->is_8_3(fname, check_case, False, p);
}

BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case,
			     const struct share_params *p)
{
	return mangle_fns->is_8_3(fname, check_case, True, p);
}

/*
  try to reverse map a 8.3 name to the original filename. This doesn't have to 
  always succeed, as the directory handling code in smbd will scan the directory
  looking for a matching name if it doesn't. It should succeed most of the time
  or there will be a huge performance penalty
*/
BOOL mangle_check_cache(char *s, size_t maxlen,
			const struct share_params *p)
{
	return mangle_fns->check_cache(s, maxlen, p);
}

/* 
   map a long filename to a 8.3 name. 
 */

void mangle_map(pstring OutName, BOOL need83, BOOL cache83,
		const struct share_params *p)
{
	/* name mangling can be disabled for speed, in which case
	   we just truncate the string */
	if (!lp_manglednames(p)) {
		if (need83) {
			string_truncate(OutName, 12);
		}
		return;
	}

	/* invoke the inane "mangled map" code */
	mangle_map_filename(OutName, p);
	mangle_fns->name_map(OutName, need83, cache83, lp_defaultcase(p->service), p);
}