1/*
2   Unix SMB/CIFS implementation.
3   Samba utility functions
4   Copyright (C) Andrew Tridgell 1992-1998
5   Copyright (C) Jeremy Allison 2001-2002
6   Copyright (C) Simo Sorce 2001
7   Copyright (C) Jim McDonough (jmcd@us.ibm.com)  2003.
8   Copyright (C) James J Myers 2003
9   Copyright (C) Jelmer Vernooij 2005-2007
10
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 3 of the License, or
14   (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program.  If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "includes.h"
26#include "dynconfig/dynconfig.h"
27#include "system/network.h"
28#include "system/filesys.h"
29#include "system/dir.h"
30#include "param/param.h"
31
32/**
33 * @file
34 * @brief Misc utility functions
35 */
36
37
38bool lp_is_mydomain(struct loadparm_context *lp_ctx,
39			     const char *domain)
40{
41	return strequal(lp_workgroup(lp_ctx), domain);
42}
43
44bool lp_is_my_domain_or_realm(struct loadparm_context *lp_ctx,
45			     const char *domain)
46{
47	return strequal(lp_workgroup(lp_ctx), domain) ||
48		strequal(lp_realm(lp_ctx), domain);
49}
50
51/**
52  see if a string matches either our primary or one of our secondary
53  netbios aliases. do a case insensitive match
54*/
55bool lp_is_myname(struct loadparm_context *lp_ctx, const char *name)
56{
57	const char **aliases;
58	int i;
59
60	if (strcasecmp(name, lp_netbios_name(lp_ctx)) == 0) {
61		return true;
62	}
63
64	aliases = lp_netbios_aliases(lp_ctx);
65	for (i=0; aliases && aliases[i]; i++) {
66		if (strcasecmp(name, aliases[i]) == 0) {
67			return true;
68		}
69	}
70
71	return false;
72}
73
74
75/**
76 A useful function for returning a path in the Samba lock directory.
77**/
78char *lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx,
79			 const char *name)
80{
81	char *fname, *dname;
82	if (name == NULL) {
83		return NULL;
84	}
85	if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
86		return talloc_strdup(mem_ctx, name);
87	}
88
89	dname = talloc_strdup(mem_ctx, lp_lockdir(lp_ctx));
90	trim_string(dname,"","/");
91
92	if (!directory_exist(dname)) {
93		mkdir(dname,0755);
94	}
95
96	fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name);
97
98	talloc_free(dname);
99
100	return fname;
101}
102
103/**
104 * @brief Returns an absolute path to a file in the directory containing the current config file
105 *
106 * @param name File to find, relative to the config file directory.
107 *
108 * @retval Pointer to a talloc'ed string containing the full path.
109 **/
110
111char *config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx,
112			   const char *name)
113{
114	char *fname, *config_dir, *p;
115	config_dir = talloc_strdup(mem_ctx, lp_configfile(lp_ctx));
116	if (config_dir == NULL) {
117		config_dir = talloc_strdup(mem_ctx, lp_default_path());
118	}
119	p = strrchr(config_dir, '/');
120	if (p == NULL) {
121		talloc_free(config_dir);
122		config_dir = talloc_strdup(mem_ctx, ".");
123		if (config_dir == NULL) {
124			return NULL;
125		}
126	} else {
127		p[0] = '\0';
128	}
129	fname = talloc_asprintf(mem_ctx, "%s/%s", config_dir, name);
130	talloc_free(config_dir);
131	return fname;
132}
133
134/**
135 * @brief Returns an absolute path to a file in the Samba private directory.
136 *
137 * @param name File to find, relative to PRIVATEDIR.
138 * if name is not relative, then use it as-is
139 *
140 * @retval Pointer to a talloc'ed string containing the full path.
141 **/
142char *private_path(TALLOC_CTX* mem_ctx,
143			    struct loadparm_context *lp_ctx,
144			    const char *name)
145{
146	char *fname;
147	if (name == NULL) {
148		return NULL;
149	}
150	if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
151		return talloc_strdup(mem_ctx, name);
152	}
153	fname = talloc_asprintf(mem_ctx, "%s/%s", lp_private_dir(lp_ctx), name);
154	return fname;
155}
156
157/**
158  return a path in the smbd.tmp directory, where all temporary file
159  for smbd go. If NULL is passed for name then return the directory
160  path itself
161*/
162char *smbd_tmp_path(TALLOC_CTX *mem_ctx,
163			     struct loadparm_context *lp_ctx,
164			     const char *name)
165{
166	char *fname, *dname;
167
168	dname = private_path(mem_ctx, lp_ctx, "smbd.tmp");
169	if (!directory_exist(dname)) {
170		mkdir(dname,0755);
171	}
172
173	if (name == NULL) {
174		return dname;
175	}
176
177	fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name);
178	talloc_free(dname);
179
180	return fname;
181}
182
183/**
184 * Obtain the init function from a shared library file
185 */
186init_module_fn load_module(TALLOC_CTX *mem_ctx, const char *path)
187{
188	void *handle;
189	void *init_fn;
190
191	handle = dlopen(path, RTLD_NOW);
192	if (handle == NULL) {
193		DEBUG(0, ("Unable to open %s: %s\n", path, dlerror()));
194		return NULL;
195	}
196
197	init_fn = dlsym(handle, SAMBA_INIT_MODULE);
198
199	if (init_fn == NULL) {
200		DEBUG(0, ("Unable to find %s() in %s: %s\n",
201			  SAMBA_INIT_MODULE, path, dlerror()));
202		DEBUG(1, ("Loading module '%s' failed\n", path));
203		dlclose(handle);
204		return NULL;
205	}
206
207	return (init_module_fn)init_fn;
208}
209
210/**
211 * Obtain list of init functions from the modules in the specified
212 * directory
213 */
214init_module_fn *load_modules(TALLOC_CTX *mem_ctx, const char *path)
215{
216	DIR *dir;
217	struct dirent *entry;
218	char *filename;
219	int success = 0;
220	init_module_fn *ret = talloc_array(mem_ctx, init_module_fn, 2);
221
222	ret[0] = NULL;
223
224	dir = opendir(path);
225	if (dir == NULL) {
226		talloc_free(ret);
227		return NULL;
228	}
229
230	while((entry = readdir(dir))) {
231		if (ISDOT(entry->d_name) || ISDOTDOT(entry->d_name))
232			continue;
233
234		filename = talloc_asprintf(mem_ctx, "%s/%s", path, entry->d_name);
235
236		ret[success] = load_module(mem_ctx, filename);
237		if (ret[success]) {
238			ret = talloc_realloc(mem_ctx, ret, init_module_fn, success+2);
239			success++;
240			ret[success] = NULL;
241		}
242
243		talloc_free(filename);
244	}
245
246	closedir(dir);
247
248	return ret;
249}
250
251/**
252 * Run the specified init functions.
253 *
254 * @return true if all functions ran successfully, false otherwise
255 */
256bool run_init_functions(init_module_fn *fns)
257{
258	int i;
259	bool ret = true;
260
261	if (fns == NULL)
262		return true;
263
264	for (i = 0; fns[i]; i++) { ret &= (bool)NT_STATUS_IS_OK(fns[i]()); }
265
266	return ret;
267}
268
269static char *modules_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx,
270			  const char *name)
271{
272	const char *env_moduledir = getenv("LD_SAMBA_MODULE_PATH");
273	return talloc_asprintf(mem_ctx, "%s/%s",
274			       env_moduledir?env_moduledir:lp_modulesdir(lp_ctx),
275			       name);
276}
277
278/**
279 * Load the initialization functions from DSO files for a specific subsystem.
280 *
281 * Will return an array of function pointers to initialization functions
282 */
283
284init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *subsystem)
285{
286	char *path = modules_path(mem_ctx, lp_ctx, subsystem);
287	init_module_fn *ret;
288
289	ret = load_modules(mem_ctx, path);
290
291	talloc_free(path);
292
293	return ret;
294}
295
296const char *lp_messaging_path(TALLOC_CTX *mem_ctx,
297				       struct loadparm_context *lp_ctx)
298{
299	return smbd_tmp_path(mem_ctx, lp_ctx, "messaging");
300}
301
302struct smb_iconv_convenience *smb_iconv_convenience_init_lp(TALLOC_CTX *mem_ctx,
303							 struct loadparm_context *lp_ctx)
304{
305	return smb_iconv_convenience_init(mem_ctx, lp_dos_charset(lp_ctx),
306					  lp_unix_charset(lp_ctx),
307		lp_parm_bool(lp_ctx, NULL, "iconv", "native", true));
308}
309
310
311const char *lp_sam_name(struct loadparm_context *lp_ctx)
312{
313	switch (lp_server_role(lp_ctx)) {
314	case ROLE_DOMAIN_CONTROLLER:
315		return lp_workgroup(lp_ctx);
316	default:
317		return lp_netbios_name(lp_ctx);
318	}
319}
320
321