param: Add non-global smb.cfg option (support 2 different smb.confs)
[samba.git] / lib / param / util.c
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 #include "libds/common/roles.h"
32 #include "tdb.h"
33
34 /**
35  * @file
36  * @brief Misc utility functions
37  */
38
39
40 bool lpcfg_is_mydomain(struct loadparm_context *lp_ctx,
41                              const char *domain)
42 {
43         return strequal(lpcfg_workgroup(lp_ctx), domain);
44 }
45
46 bool lpcfg_is_my_domain_or_realm(struct loadparm_context *lp_ctx,
47                              const char *domain)
48 {
49         return strequal(lpcfg_workgroup(lp_ctx), domain) ||
50                 strequal(lpcfg_realm(lp_ctx), domain);
51 }
52
53 /**
54   see if a string matches either our primary or one of our secondary 
55   netbios aliases. do a case insensitive match
56 */
57 bool lpcfg_is_myname(struct loadparm_context *lp_ctx, const char *name)
58 {
59         const char **aliases;
60         int i;
61
62         if (strcasecmp_m(name, lpcfg_netbios_name(lp_ctx)) == 0) {
63                 return true;
64         }
65
66         aliases = lpcfg_netbios_aliases(lp_ctx);
67         for (i=0; aliases && aliases[i]; i++) {
68                 if (strcasecmp_m(name, aliases[i]) == 0) {
69                         return true;
70                 }
71         }
72
73         return false;
74 }
75
76 static char *lpcfg_common_path(TALLOC_CTX* mem_ctx,
77                                const char *parent,
78                                const char *name)
79 {
80         char *fname, *dname;
81         bool ok;
82
83         if (name == NULL) {
84                 return NULL;
85         }
86         if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
87                 return talloc_strdup(mem_ctx, name);
88         }
89
90         dname = talloc_strdup(mem_ctx, parent);
91         if (dname == NULL) {
92                 return NULL;
93         }
94         trim_string(dname,"","/");
95
96         ok = directory_create_or_exist(dname, 0755);
97         if (!ok) {
98                 DEBUG(1, ("Unable to create directory %s for file %s. "
99                           "Error was %s\n", dname, name, strerror(errno)));
100                 return NULL;
101         }
102
103         fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name);
104         if (fname == NULL) {
105                 return dname;
106         }
107         talloc_free(dname);
108
109         return fname;
110 }
111
112
113 /**
114  A useful function for returning a path in the Samba lock directory.
115 **/
116 char *lpcfg_lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx,
117                          const char *name)
118 {
119         return lpcfg_common_path(mem_ctx, lpcfg_lock_directory(lp_ctx), name);
120 }
121
122 /**
123  A useful function for returning a path in the Samba state directory.
124 **/
125 char *lpcfg_state_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx,
126                        const char *name)
127 {
128         return lpcfg_common_path(mem_ctx, lpcfg_state_directory(lp_ctx), name);
129 }
130
131 /**
132  A useful function for returning a path in the Samba cache directory.
133 **/
134 char *lpcfg_cache_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx,
135                        const char *name)
136 {
137         return lpcfg_common_path(mem_ctx, lpcfg_cache_directory(lp_ctx), name);
138 }
139
140 /**
141  * @brief Returns an absolute path to a file in the directory containing the current config file
142  *
143  * @param name File to find, relative to the config file directory.
144  *
145  * @retval Pointer to a talloc'ed string containing the full path.
146  **/
147
148 char *lpcfg_config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx,
149                            const char *name)
150 {
151         char *fname, *config_dir, *p;
152         config_dir = talloc_strdup(mem_ctx, lpcfg_configfile(lp_ctx));
153         if (config_dir == NULL) {
154                 config_dir = talloc_strdup(mem_ctx, lp_default_path());
155         }
156         p = strrchr(config_dir, '/');
157         if (p == NULL) {
158                 talloc_free(config_dir);
159                 config_dir = talloc_strdup(mem_ctx, ".");
160                 if (config_dir == NULL) {
161                         return NULL;
162                 }
163         } else {
164                 p[0] = '\0';
165         }
166         fname = talloc_asprintf(mem_ctx, "%s/%s", config_dir, name);
167         talloc_free(config_dir);
168         return fname;
169 }
170
171 /**
172  * @brief Returns an absolute path to a file in the Samba private directory.
173  *
174  * @param name File to find, relative to PRIVATEDIR.
175  * if name is not relative, then use it as-is
176  *
177  * @retval Pointer to a talloc'ed string containing the full path.
178  **/
179 char *lpcfg_private_path(TALLOC_CTX* mem_ctx,
180                             struct loadparm_context *lp_ctx,
181                             const char *name)
182 {
183         char *fname;
184         if (name == NULL) {
185                 return NULL;
186         }
187         if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
188                 return talloc_strdup(mem_ctx, name);
189         }
190         fname = talloc_asprintf(mem_ctx, "%s/%s", lpcfg_private_dir(lp_ctx), name);
191         return fname;
192 }
193
194 /**
195  * @brief Returns an absolute path to a NTDB or TDB file in the Samba
196  * private directory.
197  *
198  * @param name File to find, relative to PRIVATEDIR, without .tdb extension.
199  *
200  * @retval Pointer to a talloc'ed string containing the full path, for
201  * use with dbwrap_local_open().
202  **/
203 char *lpcfg_private_db_path(TALLOC_CTX *mem_ctx,
204                             struct loadparm_context *lp_ctx,
205                             const char *name)
206 {
207         return talloc_asprintf(mem_ctx, "%s/%s.tdb",
208                                lpcfg_private_dir(lp_ctx), name);
209 }
210
211 /**
212   return a path in the smbd.tmp directory, where all temporary file
213   for smbd go. If NULL is passed for name then return the directory 
214   path itself
215 */
216 char *smbd_tmp_path(TALLOC_CTX *mem_ctx, 
217                              struct loadparm_context *lp_ctx,
218                              const char *name)
219 {
220         char *fname, *dname;
221         bool ok;
222
223         dname = lpcfg_private_path(mem_ctx, lp_ctx, "smbd.tmp");
224         if (dname == NULL) {
225                 return NULL;
226         }
227
228         ok = directory_create_or_exist(dname, 0755);
229         if (!ok) {
230                 return NULL;
231         }
232
233         if (name == NULL) {
234                 return dname;
235         }
236
237         fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name);
238         if (fname == NULL) {
239                 return dname;
240         }
241         talloc_free(dname);
242
243         return fname;
244 }
245
246 const char *lpcfg_imessaging_path(TALLOC_CTX *mem_ctx,
247                                        struct loadparm_context *lp_ctx)
248 {
249         return smbd_tmp_path(mem_ctx, lp_ctx, "msg");
250 }
251
252 const char *lpcfg_sam_name(struct loadparm_context *lp_ctx)
253 {
254         switch (lpcfg_server_role(lp_ctx)) {
255         case ROLE_DOMAIN_BDC:
256         case ROLE_DOMAIN_PDC:
257         case ROLE_ACTIVE_DIRECTORY_DC:
258                 return lpcfg_workgroup(lp_ctx);
259         default:
260                 return lpcfg_netbios_name(lp_ctx);
261         }
262 }
263
264 const char *lpcfg_sam_dnsname(struct loadparm_context *lp_ctx)
265 {
266         switch (lpcfg_server_role(lp_ctx)) {
267         case ROLE_ACTIVE_DIRECTORY_DC:
268                 return lpcfg_dnsdomain(lp_ctx);
269         default:
270                 return NULL;
271         }
272 }
273
274 static long tdb_fetch_lifetime(TALLOC_CTX *mem_ctx, struct tdb_context *tdb, const char *keystr)
275 {
276         TDB_DATA key;
277         TDB_DATA ret;
278         char *tmp = NULL;
279         long result;
280
281         key.dptr = discard_const_p(unsigned char, keystr);
282         key.dsize = strlen(keystr);
283
284         if (!key.dptr)
285                 return -1;
286
287         ret = tdb_fetch(tdb, key);
288         if (ret.dsize == 0)
289                 return -1;
290
291         tmp = talloc_realloc(mem_ctx, tmp, char, ret.dsize+1);
292         memset(tmp, 0, ret.dsize+1);
293         memcpy(tmp, ret.dptr, ret.dsize);
294         free(ret.dptr);
295
296         result = atol(tmp);
297         talloc_free(tmp);
298         return result;
299 }
300
301 void lpcfg_default_kdc_policy(TALLOC_CTX *mem_ctx,
302                                 struct loadparm_context *lp_ctx,
303                                 time_t *svc_tkt_lifetime,
304                                 time_t *usr_tkt_lifetime,
305                                 time_t *renewal_lifetime)
306 {
307         long val;
308         TDB_CONTEXT *ctx = NULL;
309         const char *kdc_tdb = NULL;
310
311         kdc_tdb = lpcfg_cache_path(mem_ctx, lp_ctx, "gpo.tdb");
312         if (kdc_tdb)
313                 ctx = tdb_open(kdc_tdb, 0, TDB_DEFAULT, O_RDWR, 0600);
314
315         if (!ctx || ( val = tdb_fetch_lifetime(mem_ctx, ctx, "kdc:service_ticket_lifetime") ) == -1 )
316                 val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "service ticket lifetime", 10);
317         *svc_tkt_lifetime = val * 60 * 60;
318
319         if (!ctx || ( val = tdb_fetch_lifetime(mem_ctx, ctx, "kdc:user_ticket_lifetime") ) == -1 )
320                 val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "user ticket lifetime", 10);
321         *usr_tkt_lifetime = val * 60 * 60;
322
323         if (!ctx || ( val = tdb_fetch_lifetime(mem_ctx, ctx, "kdc:renewal_lifetime") ) == -1 )
324                 val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "renewal lifetime", 24 * 7);
325         *renewal_lifetime = val * 60 * 60;
326 }