Coverage Report

Created: 2026-07-25 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/lib/param/loadparm.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   Parameter loading functions
4
   Copyright (C) Karl Auer 1993-1998
5
6
   Largely re-written by Andrew Tridgell, September 1994
7
8
   Copyright (C) Simo Sorce 2001
9
   Copyright (C) Alexander Bokovoy 2002
10
   Copyright (C) Stefan (metze) Metzmacher 2002
11
   Copyright (C) Jim McDonough (jmcd@us.ibm.com)  2003.
12
   Copyright (C) James Myers 2003 <myersjj@samba.org>
13
   Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14
   Copyright (C) Andrew Bartlett 2011-2012
15
16
   This program is free software; you can redistribute it and/or modify
17
   it under the terms of the GNU General Public License as published by
18
   the Free Software Foundation; either version 3 of the License, or
19
   (at your option) any later version.
20
21
   This program is distributed in the hope that it will be useful,
22
   but WITHOUT ANY WARRANTY; without even the implied warranty of
23
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
   GNU General Public License for more details.
25
26
   You should have received a copy of the GNU General Public License
27
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
*/
29
30
/*
31
 *  Load parameters.
32
 *
33
 *  This module provides suitable callback functions for the params
34
 *  module. It builds the internal table of service details which is
35
 *  then used by the rest of the server.
36
 *
37
 * To add a parameter:
38
 *
39
 * 1) add it to the global or service structure definition
40
 * 2) add it to the parm_table
41
 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42
 * 4) If it's a global then initialise it in init_globals. If a local
43
 *    (ie. service) parameter then initialise it in the sDefault structure
44
 *
45
 *
46
 * Notes:
47
 *   The configuration file is processed sequentially for speed. It is NOT
48
 *   accessed randomly as happens in 'real' Windows. For this reason, there
49
 *   is a fair bit of sequence-dependent code here - ie., code which assumes
50
 *   that certain things happen before others. In particular, the code which
51
 *   happens at the boundary between sections is delicately poised, so be
52
 *   careful!
53
 *
54
 */
55
56
#include "includes.h"
57
#include "version.h"
58
#include "dynconfig/dynconfig.h"
59
#include "system/time.h"
60
#include "system/locale.h"
61
#include "system/network.h" /* needed for TCP_NODELAY */
62
#include "../lib/util/dlinklist.h"
63
#include "lib/param/param.h"
64
#define LOADPARM_SUBSTITUTION_INTERNALS 1
65
#include "lib/param/loadparm.h"
66
#include "auth/gensec/gensec.h"
67
#include "lib/param/s3_param.h"
68
#include "lib/util/bitmap.h"
69
#include "libcli/smb/smb_constants.h"
70
#include "libcli/smb/smb_util.h"
71
#include "tdb.h"
72
#include "librpc/gen_ndr/nbt.h"
73
#include "librpc/gen_ndr/dns.h"
74
#include "librpc/gen_ndr/security.h"
75
#include "libds/common/roles.h"
76
#include "lib/util/samba_util.h"
77
#include "libcli/auth/ntlm_check.h"
78
#include "lib/crypto/gnutls_helpers.h"
79
#include "lib/util/smb_strtox.h"
80
#include "auth/credentials/credentials.h"
81
82
#ifdef HAVE_HTTPCONNECTENCRYPT
83
#include <cups/http.h>
84
#endif
85
86
0
#define standard_sub_basic talloc_strdup
87
88
#include "lib/param/param_global.h"
89
90
struct loadparm_service *lpcfg_default_service(struct loadparm_context *lp_ctx)
91
0
{
92
0
  return lp_ctx->sDefault;
93
0
}
94
95
int lpcfg_rpc_low_port(struct loadparm_context *lp_ctx)
96
0
{
97
0
  return lp_ctx->globals->rpc_low_port;
98
0
}
99
100
int lpcfg_rpc_high_port(struct loadparm_context *lp_ctx)
101
0
{
102
0
  return lp_ctx->globals->rpc_high_port;
103
0
}
104
105
enum samba_weak_crypto lpcfg_weak_crypto(struct loadparm_context *lp_ctx)
106
0
{
107
0
  if (lp_ctx->globals->weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
108
0
    lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
109
110
0
    if (samba_gnutls_weak_crypto_allowed()) {
111
0
      lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
112
0
    }
113
0
  }
114
115
0
  return lp_ctx->globals->weak_crypto;
116
0
}
117
118
/**
119
 * Convenience routine to grab string parameters into temporary memory
120
 * and run standard_sub_basic on them.
121
 *
122
 * The buffers can be written to by
123
 * callers without affecting the source string.
124
 */
125
126
static const char *lpcfg_string(const char *s)
127
0
{
128
#if 0  /* until REWRITE done to make thread-safe */
129
  size_t len = s ? strlen(s) : 0;
130
  char *ret;
131
#endif
132
133
  /* The follow debug is useful for tracking down memory problems
134
     especially if you have an inner loop that is calling a lp_*()
135
     function that returns a string.  Perhaps this debug should be
136
     present all the time? */
137
138
#if 0
139
  DEBUG(10, ("lpcfg_string(%s)\n", s));
140
#endif
141
142
#if 0  /* until REWRITE done to make thread-safe */
143
  if (!lp_talloc)
144
    lp_talloc = talloc_init("lp_talloc");
145
146
  ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
147
148
  if (!ret)
149
    return NULL;
150
151
  if (!s)
152
    *ret = 0;
153
  else
154
    strlcpy(ret, s, len);
155
156
  if (trim_string(ret, "\"", "\"")) {
157
    if (strchr(ret,'"') != NULL)
158
      strlcpy(ret, s, len);
159
  }
160
161
  standard_sub_basic(ret,len+100);
162
  return (ret);
163
#endif
164
0
  return s;
165
0
}
166
167
/*
168
   In this section all the functions that are used to access the
169
   parameters from the rest of the program are defined
170
*/
171
172
/*
173
 * the creation of separate lpcfg_*() and lp_*() functions is to allow
174
 * for code compatibility between existing Samba4 and Samba3 code.
175
 */
176
177
/* this global context supports the lp_*() function variants */
178
static struct loadparm_context *global_loadparm_context;
179
180
#define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,var_name) \
181
 _PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx, \
182
0
     const struct loadparm_substitution *lp_sub, TALLOC_CTX *mem_ctx) \
183
0
{ \
184
0
   if (lp_ctx == NULL) return NULL;       \
185
0
   return lpcfg_substituted_string(mem_ctx, lp_sub, \
186
0
       lp_ctx->globals->var_name ? lp_ctx->globals->var_name : ""); \
187
0
}
188
189
#define FN_GLOBAL_CONST_STRING(fn_name,var_name)        \
190
0
 _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
191
0
  if (lp_ctx == NULL) return NULL;       \
192
0
  return lp_ctx->globals->var_name ? lpcfg_string(lp_ctx->globals->var_name) : ""; \
193
0
}
194
195
#define FN_GLOBAL_LIST(fn_name,var_name)        \
196
0
 _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
197
0
   if (lp_ctx == NULL) return NULL;       \
198
0
   return lp_ctx->globals->var_name;       \
199
0
 }
200
201
#define FN_GLOBAL_BOOL(fn_name,var_name) \
202
0
 _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\
203
0
   if (lp_ctx == NULL) return false;       \
204
0
   return lp_ctx->globals->var_name;       \
205
0
}
206
207
#define FN_GLOBAL_INTEGER(fn_name,var_name) \
208
0
 _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
209
0
   return lp_ctx->globals->var_name;        \
210
0
 }
Unexecuted instantiation: lpcfg_acl_claims_evaluation
Unexecuted instantiation: lpcfg_ad_dc_functional_level
Unexecuted instantiation: lpcfg_afs_token_lifetime
Unexecuted instantiation: lpcfg_aio_max_threads
Unexecuted instantiation: lpcfg_algorithmic_rid_base
Unexecuted instantiation: lpcfg_allow_dns_updates
Unexecuted instantiation: lpcfg_async_dns_timeout
Unexecuted instantiation: lpcfg__client_ipc_max_protocol
Unexecuted instantiation: lpcfg__client_ipc_min_protocol
Unexecuted instantiation: lpcfg__client_ipc_signing
Unexecuted instantiation: lpcfg_client_ldap_sasl_wrapping
Unexecuted instantiation: lpcfg__client_max_protocol
Unexecuted instantiation: lpcfg_client_min_protocol
Unexecuted instantiation: lpcfg_client_netlogon_ping_protocol
Unexecuted instantiation: lpcfg_client_protection
Unexecuted instantiation: lpcfg_client_schannel
Unexecuted instantiation: lpcfg_client_signing
Unexecuted instantiation: lpcfg_client_smb_encrypt
Unexecuted instantiation: lpcfg__client_use_kerberos
Unexecuted instantiation: lpcfg__client_use_krb5_netlogon
Unexecuted instantiation: lpcfg_config_backend
Unexecuted instantiation: lpcfg_ctdb_locktime_warn_threshold
Unexecuted instantiation: lpcfg_ctdb_timeout
Unexecuted instantiation: lpcfg_cups_connection_timeout
Unexecuted instantiation: lpcfg_cups_encrypt
Unexecuted instantiation: lpcfg_deadtime
Unexecuted instantiation: lpcfg_debug_syslog_format
Unexecuted instantiation: lpcfg_dgram_port
Unexecuted instantiation: lpcfg_dns_port
Unexecuted instantiation: lpcfg__domain_master
Unexecuted instantiation: lpcfg_idmap_cache_time
Unexecuted instantiation: lpcfg_idmap_negative_cache_time
Unexecuted instantiation: lpcfg_init_logon_delay
Unexecuted instantiation: lpcfg_certificate_backdating_compensation
Unexecuted instantiation: lpcfg_strong_certificate_binding_enforcement
Unexecuted instantiation: lpcfg_kdc_default_domain_supported_enctypes
Unexecuted instantiation: lpcfg_kdc_supported_enctypes
Unexecuted instantiation: lpcfg_keepalive
Unexecuted instantiation: lpcfg_kerberos_encryption_types
Unexecuted instantiation: lpcfg_kerberos_method
Unexecuted instantiation: lpcfg_kpasswd_port
Unexecuted instantiation: lpcfg_krb5_port
Unexecuted instantiation: lpcfg_ldap_connection_timeout
Unexecuted instantiation: lpcfg_ldap_debug_level
Unexecuted instantiation: lpcfg_ldap_debug_threshold
Unexecuted instantiation: lpcfg_ldap_deref
Unexecuted instantiation: lpcfg_ldap_follow_referral
Unexecuted instantiation: lpcfg_ldap_max_anonymous_request_size
Unexecuted instantiation: lpcfg_ldap_max_authenticated_request_size
Unexecuted instantiation: lpcfg_ldap_max_search_request_size
Unexecuted instantiation: lpcfg_ldap_page_size
Unexecuted instantiation: lpcfg_ldap_passwd_sync
Unexecuted instantiation: lpcfg_ldap_replication_sleep
Unexecuted instantiation: lpcfg_ldap_server_require_strong_auth
Unexecuted instantiation: lpcfg_ldap_ssl
Unexecuted instantiation: lpcfg_ldap_timeout
Unexecuted instantiation: lpcfg_lm_announce
Unexecuted instantiation: lpcfg_lm_interval
Unexecuted instantiation: lpcfg_lock_spin_time
Unexecuted instantiation: lpcfg_lpq_cache_time
Unexecuted instantiation: lpcfg_machine_password_timeout
Unexecuted instantiation: lpcfg_mangle_prefix
Unexecuted instantiation: lpcfg_map_to_guest
Unexecuted instantiation: lpcfg_max_disk_size
Unexecuted instantiation: lpcfg_max_log_size
Unexecuted instantiation: lpcfg_max_mux
Unexecuted instantiation: lpcfg_max_open_files
Unexecuted instantiation: lpcfg_max_smbd_processes
Unexecuted instantiation: lpcfg_max_stat_cache_size
Unexecuted instantiation: lpcfg_max_ttl
Unexecuted instantiation: lpcfg_max_wins_ttl
Unexecuted instantiation: lpcfg_max_xmit
Unexecuted instantiation: lpcfg_mdns_name
Unexecuted instantiation: lpcfg_min_domain_uid
Unexecuted instantiation: lpcfg_min_receivefile_size
Unexecuted instantiation: lpcfg_min_wins_ttl
Unexecuted instantiation: lpcfg_name_cache_timeout
Unexecuted instantiation: lpcfg_nbt_port
Unexecuted instantiation: lpcfg_nt_hash_store
Unexecuted instantiation: lpcfg_ntlm_auth
Unexecuted instantiation: lpcfg_old_password_allowed_period
Unexecuted instantiation: lpcfg_oplock_break_wait_time
Unexecuted instantiation: lpcfg_os_level
Unexecuted instantiation: lpcfg_passwd_chat_timeout
Unexecuted instantiation: lpcfg__preferred_master
Unexecuted instantiation: lpcfg_prefork_backoff_increment
Unexecuted instantiation: lpcfg_prefork_children
Unexecuted instantiation: lpcfg_prefork_maximum_backoff
Unexecuted instantiation: lpcfg_printcap_cache_time
Unexecuted instantiation: lpcfg_restrict_anonymous
Unexecuted instantiation: lpcfg_rpc_server_port
Unexecuted instantiation: lpcfg__security
Unexecuted instantiation: lpcfg_server_max_protocol
Unexecuted instantiation: lpcfg_server_min_protocol
Unexecuted instantiation: lpcfg__server_role
Unexecuted instantiation: lpcfg_server_schannel
Unexecuted instantiation: lpcfg_server_signing
Unexecuted instantiation: lpcfg_smb2_max_credits
Unexecuted instantiation: lpcfg_smb2_max_read
Unexecuted instantiation: lpcfg_smb2_max_trans
Unexecuted instantiation: lpcfg_smb2_max_write
Unexecuted instantiation: lpcfg__smb3_directory_leases
Unexecuted instantiation: lpcfg_smbd_profiling_level
Unexecuted instantiation: lpcfg_syslog
Unexecuted instantiation: lpcfg_tls_verify_peer
Unexecuted instantiation: lpcfg_username_level
Unexecuted instantiation: lpcfg_username_map_cache_time
Unexecuted instantiation: lpcfg_usershare_max_shares
Unexecuted instantiation: lpcfg_winbind_cache_time
Unexecuted instantiation: lpcfg_winbind_expand_groups
Unexecuted instantiation: lpcfg_winbind_max_clients
Unexecuted instantiation: lpcfg__winbind_max_domain_connections
Unexecuted instantiation: lpcfg_winbind_reconnect_delay
Unexecuted instantiation: lpcfg_winbind_request_timeout
211
212
/* Local parameters don't need the ->s3_fns because the struct
213
 * loadparm_service is shared and lpcfg_service() checks the ->s3_fns
214
 * hook */
215
#define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
216
 _PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_service *service, \
217
0
          struct loadparm_service *sDefault, TALLOC_CTX *ctx) { \
218
0
   return(talloc_strdup(ctx, lpcfg_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)))); \
219
0
 }
220
221
#define FN_LOCAL_CONST_STRING(fn_name,val) \
222
 _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_service *service, \
223
0
          struct loadparm_service *sDefault) { \
224
0
   return((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)); \
225
0
 }
226
227
#define FN_LOCAL_LIST(fn_name,val) \
228
 _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_service *service, \
229
0
           struct loadparm_service *sDefault) {\
230
0
   return(const char **)(service != NULL && service->val != NULL? service->val : sDefault->val); \
231
0
 }
232
233
#define FN_LOCAL_PARM_BOOL(fn_name, val) FN_LOCAL_BOOL(fn_name, val)
234
235
#define FN_LOCAL_BOOL(fn_name,val) \
236
 _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_service *service, \
237
0
         struct loadparm_service *sDefault) { \
238
0
   return((service != NULL)? service->val : sDefault->val); \
239
0
 }
240
241
#define FN_LOCAL_INTEGER(fn_name,val) \
242
 _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_service *service, \
243
0
        struct loadparm_service *sDefault) { \
244
0
   return((service != NULL)? service->val : sDefault->val); \
245
0
 }
246
247
#define FN_LOCAL_PARM_INTEGER(fn_name, val) FN_LOCAL_INTEGER(fn_name, val)
248
249
#define FN_LOCAL_CHAR(fn_name,val) \
250
 _PUBLIC_ char lpcfg_ ## fn_name(struct loadparm_service *service, \
251
0
        struct loadparm_service *sDefault) { \
252
0
   return((service != NULL)? service->val : sDefault->val); \
253
0
 }
254
255
#define FN_LOCAL_PARM_CHAR(fn_name,val) FN_LOCAL_CHAR(fn_name, val)
256
257
#include "lib/param/param_functions.c"
258
259
/* These functions cannot be auto-generated */
260
0
FN_LOCAL_BOOL(autoloaded, autoloaded)
261
0
FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
262
263
/* local prototypes */
264
static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
265
          const char *pszServiceName);
266
static bool do_section(const char *pszSectionName, void *);
267
static bool set_variable_helper(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
268
        const char *pszParmName, const char *pszParmValue);
269
static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
270
               struct loadparm_service *service,
271
               const char *pszParmName,
272
               const char *pszParmValue, int flags);
273
274
/* The following are helper functions for parametrical options support. */
275
/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
276
/* Actual parametrical functions are quite simple */
277
struct parmlist_entry *get_parametric_helper(struct loadparm_service *service,
278
               const char *type, const char *option,
279
               struct parmlist_entry *global_opts)
280
0
{
281
0
  size_t type_len = strlen(type);
282
0
  size_t option_len = strlen(option);
283
0
  char param_key[type_len + option_len + 2];
284
0
  struct parmlist_entry *data = NULL;
285
286
0
  snprintf(param_key, sizeof(param_key), "%s:%s", type, option);
287
288
  /*
289
   * Try to fetch the option from the data.
290
   */
291
0
  if (service != NULL) {
292
0
    data = service->param_opt;
293
0
    while (data != NULL) {
294
0
      if (strwicmp(data->key, param_key) == 0) {
295
0
        return data;
296
0
      }
297
0
      data = data->next;
298
0
    }
299
0
  }
300
301
  /*
302
   * Fall back to fetching from the globals.
303
   */
304
0
  data = global_opts;
305
0
  while (data != NULL) {
306
0
    if (strwicmp(data->key, param_key) == 0) {
307
0
      return data;
308
0
    }
309
0
    data = data->next;
310
0
  }
311
312
0
  return NULL;
313
0
}
314
315
const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
316
            struct loadparm_service *service,
317
            const char *type, const char *option)
318
0
{
319
0
  struct parmlist_entry *data;
320
321
0
  if (lp_ctx == NULL)
322
0
    return NULL;
323
324
0
  data = get_parametric_helper(service,
325
0
             type, option, lp_ctx->globals->param_opt);
326
327
0
  if (data == NULL) {
328
0
    return NULL;
329
0
  } else {
330
0
    return data->value;
331
0
  }
332
0
}
333
334
335
/**
336
 * convenience routine to return int parameters.
337
 */
338
int lp_int(const char *s)
339
0
{
340
341
0
  if (!s || !*s) {
342
0
    DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
343
0
    return -1;
344
0
  }
345
346
0
  return strtol(s, NULL, 0);
347
0
}
348
349
/**
350
 * convenience routine to return unsigned long parameters.
351
 */
352
unsigned long lp_ulong(const char *s)
353
0
{
354
0
  int error = 0;
355
0
  unsigned long int ret;
356
357
0
  if (!s || !*s) {
358
0
    DBG_DEBUG("lp_ulong(%s): is called with NULL!\n",s);
359
0
    return -1;
360
0
  }
361
362
0
  ret = smb_strtoul(s, NULL, 0, &error, SMB_STR_STANDARD);
363
0
  if (error != 0) {
364
0
    DBG_DEBUG("lp_ulong(%s): conversion failed\n",s);
365
0
    return -1;
366
0
  }
367
368
0
  return ret;
369
0
}
370
371
/**
372
 * convenience routine to return unsigned long long parameters.
373
 */
374
unsigned long long lp_ulonglong(const char *s)
375
0
{
376
0
  int error = 0;
377
0
  unsigned long long int ret;
378
379
0
  if (!s || !*s) {
380
0
    DBG_DEBUG("lp_ulonglong(%s): is called with NULL!\n", s);
381
0
    return -1;
382
0
  }
383
384
0
  ret = smb_strtoull(s, NULL, 0, &error, SMB_STR_STANDARD);
385
0
  if (error != 0) {
386
0
    DBG_DEBUG("lp_ulonglong(%s): conversion failed\n",s);
387
0
    return -1;
388
0
  }
389
390
0
  return ret;
391
0
}
392
393
/**
394
 * convenience routine to return unsigned long parameters.
395
 */
396
static long lp_long(const char *s)
397
0
{
398
399
0
  if (!s) {
400
0
    DEBUG(0,("lp_long(%s): is called with NULL!\n",s));
401
0
    return -1;
402
0
  }
403
404
0
  return strtol(s, NULL, 0);
405
0
}
406
407
/**
408
 * convenience routine to return unsigned long parameters.
409
 */
410
static double lp_double(const char *s)
411
0
{
412
413
0
  if (!s) {
414
0
    DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
415
0
    return -1;
416
0
  }
417
418
0
  return strtod(s, NULL);
419
0
}
420
421
/**
422
 * convenience routine to return boolean parameters.
423
 */
424
bool lp_bool(const char *s)
425
0
{
426
0
  bool ret = false;
427
428
0
  if (!s || !*s) {
429
0
    DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
430
0
    return false;
431
0
  }
432
433
0
  if (!set_boolean(s, &ret)) {
434
0
    DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
435
0
    return false;
436
0
  }
437
438
0
  return ret;
439
0
}
440
441
/**
442
 * Return parametric option from a given service. Type is a part of option before ':'
443
 * Parametric option has following syntax: 'Type: option = value'
444
 * Returned value is allocated in 'lp_talloc' context
445
 */
446
447
const char *lpcfg_parm_string(struct loadparm_context *lp_ctx,
448
            struct loadparm_service *service, const char *type,
449
            const char *option)
450
0
{
451
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
452
453
0
  if (value)
454
0
    return lpcfg_string(value);
455
456
0
  return NULL;
457
0
}
458
459
/**
460
 * Return parametric option from a given service. Type is a part of option before ':'
461
 * Parametric option has following syntax: 'Type: option = value'
462
 * Returned value is allocated in 'lp_talloc' context
463
 */
464
465
const char **lpcfg_parm_string_list(TALLOC_CTX *mem_ctx,
466
            struct loadparm_context *lp_ctx,
467
            struct loadparm_service *service,
468
            const char *type,
469
            const char *option, const char *separator)
470
0
{
471
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
472
473
0
  if (value != NULL) {
474
0
    char **l = str_list_make(mem_ctx, value, separator);
475
0
    return discard_const_p(const char *, l);
476
0
  }
477
478
0
  return NULL;
479
0
}
480
481
/**
482
 * Return parametric option from a given service. Type is a part of option before ':'
483
 * Parametric option has following syntax: 'Type: option = value'
484
 */
485
486
int lpcfg_parm_int(struct loadparm_context *lp_ctx,
487
       struct loadparm_service *service, const char *type,
488
       const char *option, int default_v)
489
0
{
490
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
491
492
0
  if (value)
493
0
    return lp_int(value);
494
495
0
  return default_v;
496
0
}
497
498
/**
499
 * Return parametric option from a given service. Type is a part of
500
 * option before ':'.
501
 * Parametric option has following syntax: 'Type: option = value'.
502
 */
503
504
int lpcfg_parm_bytes(struct loadparm_context *lp_ctx,
505
      struct loadparm_service *service, const char *type,
506
      const char *option, int default_v)
507
0
{
508
0
  uint64_t bval;
509
510
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
511
512
0
  if (value && conv_str_size_error(value, &bval)) {
513
0
    if (bval <= INT_MAX) {
514
0
      return (int)bval;
515
0
    }
516
0
  }
517
518
0
  return default_v;
519
0
}
520
521
/**
522
 * Return parametric option from a given service.
523
 * Type is a part of option before ':'
524
 * Parametric option has following syntax: 'Type: option = value'
525
 */
526
unsigned long lpcfg_parm_ulong(struct loadparm_context *lp_ctx,
527
          struct loadparm_service *service, const char *type,
528
          const char *option, unsigned long default_v)
529
0
{
530
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
531
532
0
  if (value)
533
0
    return lp_ulong(value);
534
535
0
  return default_v;
536
0
}
537
538
/**
539
 * Return parametric option from a given service.
540
 * Type is a part of option before ':'
541
 * Parametric option has following syntax: 'Type: option = value'
542
 */
543
unsigned long long lpcfg_parm_ulonglong(struct loadparm_context *lp_ctx,
544
          struct loadparm_service *service,
545
          const char *type, const char *option,
546
          unsigned long long default_v)
547
0
{
548
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
549
550
0
  if (value) {
551
0
    return lp_ulonglong(value);
552
0
  }
553
554
0
  return default_v;
555
0
}
556
557
long lpcfg_parm_long(struct loadparm_context *lp_ctx,
558
         struct loadparm_service *service, const char *type,
559
         const char *option, long default_v)
560
0
{
561
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
562
563
0
  if (value)
564
0
    return lp_long(value);
565
566
0
  return default_v;
567
0
}
568
569
double lpcfg_parm_double(struct loadparm_context *lp_ctx,
570
          struct loadparm_service *service, const char *type,
571
          const char *option, double default_v)
572
0
{
573
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
574
575
0
  if (value != NULL)
576
0
    return lp_double(value);
577
578
0
  return default_v;
579
0
}
580
581
/**
582
 * Return parametric option from a given service. Type is a part of option before ':'
583
 * Parametric option has following syntax: 'Type: option = value'
584
 */
585
586
bool lpcfg_parm_bool(struct loadparm_context *lp_ctx,
587
         struct loadparm_service *service, const char *type,
588
         const char *option, bool default_v)
589
0
{
590
0
  const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
591
592
0
  if (value != NULL)
593
0
    return lp_bool(value);
594
595
0
  return default_v;
596
0
}
597
598
599
/* this is used to prevent lots of mallocs of size 1 */
600
static const char lpcfg_string_empty[] = "";
601
602
/**
603
 Free a string value.
604
**/
605
void lpcfg_string_free(char **s)
606
0
{
607
0
  if (s == NULL) {
608
0
    return;
609
0
  }
610
0
  if (*s == lpcfg_string_empty) {
611
0
    *s = NULL;
612
0
    return;
613
0
  }
614
0
  TALLOC_FREE(*s);
615
0
}
616
617
/**
618
 * Set a string value, deallocating any existing space, and allocing the space
619
 * for the string
620
 */
621
bool lpcfg_string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
622
0
{
623
0
  lpcfg_string_free(dest);
624
625
0
  if ((src == NULL) || (*src == '\0')) {
626
0
    *dest = discard_const_p(char, lpcfg_string_empty);
627
0
    return true;
628
0
  }
629
630
0
  *dest = talloc_strdup(mem_ctx, src);
631
0
  if ((*dest) == NULL) {
632
0
    DEBUG(0,("Out of memory in string_set\n"));
633
0
    return false;
634
0
  }
635
636
0
  return true;
637
0
}
638
639
/**
640
 * Set a string value, deallocating any existing space, and allocing the space
641
 * for the string
642
 */
643
bool lpcfg_string_set_upper(TALLOC_CTX *mem_ctx, char **dest, const char *src)
644
0
{
645
0
  lpcfg_string_free(dest);
646
647
0
  if ((src == NULL) || (*src == '\0')) {
648
0
    *dest = discard_const_p(char, lpcfg_string_empty);
649
0
    return true;
650
0
  }
651
652
0
  *dest = strupper_talloc(mem_ctx, src);
653
0
  if ((*dest) == NULL) {
654
0
    DEBUG(0,("Out of memory in string_set_upper\n"));
655
0
    return false;
656
0
  }
657
658
0
  return true;
659
0
}
660
661
662
663
/**
664
 * Add a new service to the services array initialising it with the given
665
 * service.
666
 */
667
668
struct loadparm_service *lpcfg_add_service(struct loadparm_context *lp_ctx,
669
             const struct loadparm_service *pservice,
670
             const char *name)
671
0
{
672
0
  int i;
673
0
  int num_to_alloc = lp_ctx->iNumServices + 1;
674
0
  struct parmlist_entry *data, *pdata;
675
676
0
  if (lp_ctx->s3_fns != NULL) {
677
0
    smb_panic("Add a service should not be called on an s3 loadparm ctx");
678
0
  }
679
680
0
  if (pservice == NULL) {
681
0
    pservice = lp_ctx->sDefault;
682
0
  }
683
684
  /* it might already exist */
685
0
  if (name) {
686
0
    struct loadparm_service *service = lpcfg_getservicebyname(lp_ctx,
687
0
                    name);
688
0
    if (service != NULL) {
689
      /* Clean all parametric options for service */
690
      /* They will be added during parsing again */
691
0
      data = service->param_opt;
692
0
      while (data) {
693
0
        pdata = data->next;
694
0
        talloc_free(data);
695
0
        data = pdata;
696
0
      }
697
0
      service->param_opt = NULL;
698
0
      return service;
699
0
    }
700
0
  }
701
702
  /* find an invalid one */
703
0
  for (i = 0; i < lp_ctx->iNumServices; i++)
704
0
    if (lp_ctx->services[i] == NULL)
705
0
      break;
706
707
  /* if not, then create one */
708
0
  if (i == lp_ctx->iNumServices) {
709
0
    struct loadparm_service **tsp;
710
711
0
    tsp = talloc_realloc(lp_ctx, lp_ctx->services, struct loadparm_service *, num_to_alloc);
712
713
0
    if (!tsp) {
714
0
      DEBUG(0,("lpcfg_add_service: failed to enlarge services!\n"));
715
0
      return NULL;
716
0
    } else {
717
0
      lp_ctx->services = tsp;
718
0
      lp_ctx->services[lp_ctx->iNumServices] = NULL;
719
0
    }
720
721
0
    lp_ctx->iNumServices++;
722
0
  }
723
724
0
  lp_ctx->services[i] = talloc_zero(lp_ctx->services, struct loadparm_service);
725
0
  if (lp_ctx->services[i] == NULL) {
726
0
    DEBUG(0,("lpcfg_add_service: out of memory!\n"));
727
0
    return NULL;
728
0
  }
729
0
  copy_service(lp_ctx->services[i], pservice, NULL);
730
0
  if (name != NULL)
731
0
    lpcfg_string_set(lp_ctx->services[i], &lp_ctx->services[i]->szService, name);
732
0
  return lp_ctx->services[i];
733
0
}
734
735
/**
736
 * Map a parameter's string representation to something we can use.
737
 * Returns False if the parameter string is not recognised, else TRUE.
738
 */
739
740
int lpcfg_map_parameter(const char *pszParmName)
741
0
{
742
0
  int iIndex;
743
744
0
  for (iIndex = 0; parm_table[iIndex].label; iIndex++)
745
0
    if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
746
0
      return iIndex;
747
748
  /* Warn only if it isn't parametric option */
749
0
  if (strchr(pszParmName, ':') == NULL)
750
0
    DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
751
  /* We do return 'fail' for parametric options as well because they are
752
     stored in different storage
753
   */
754
0
  return -1;
755
0
}
756
757
758
/**
759
  return the parameter structure for a parameter
760
*/
761
struct parm_struct *lpcfg_parm_struct(struct loadparm_context *lp_ctx, const char *name)
762
0
{
763
0
  int num = lpcfg_map_parameter(name);
764
765
0
  if (num < 0) {
766
0
    return NULL;
767
0
  }
768
769
0
  return &parm_table[num];
770
0
}
771
772
/**
773
  return the parameter pointer for a parameter
774
*/
775
void *lpcfg_parm_ptr(struct loadparm_context *lp_ctx,
776
      struct loadparm_service *service, struct parm_struct *parm)
777
0
{
778
0
  if (lp_ctx->s3_fns) {
779
0
    return lp_ctx->s3_fns->get_parm_ptr(service, parm);
780
0
  }
781
782
0
  if (service == NULL) {
783
0
    if (parm->p_class == P_LOCAL)
784
0
      return ((char *)lp_ctx->sDefault)+parm->offset;
785
0
    else if (parm->p_class == P_GLOBAL)
786
0
      return ((char *)lp_ctx->globals)+parm->offset;
787
0
    else return NULL;
788
0
  } else {
789
0
    return ((char *)service) + parm->offset;
790
0
  }
791
0
}
792
793
/**
794
  return the parameter pointer for a parameter
795
*/
796
bool lpcfg_parm_is_cmdline(struct loadparm_context *lp_ctx, const char *name)
797
0
{
798
0
  int parmnum;
799
800
0
  parmnum = lpcfg_map_parameter(name);
801
0
  if (parmnum == -1) return false;
802
803
0
  return lp_ctx->flags[parmnum] & FLAG_CMDLINE;
804
0
}
805
806
bool lpcfg_parm_is_unspecified(struct loadparm_context *lp_ctx, const char *name)
807
0
{
808
0
  int parmnum;
809
810
0
  parmnum = lpcfg_map_parameter(name);
811
0
  if (parmnum == -1) return false;
812
813
0
  return lp_ctx->flags[parmnum] & FLAG_DEFAULT;
814
0
}
815
816
/**
817
 * Find a service by name. Otherwise works like get_service.
818
 */
819
820
static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
821
          const char *pszServiceName)
822
0
{
823
0
  int iService;
824
825
0
  if (lp_ctx->s3_fns) {
826
0
    return lp_ctx->s3_fns->get_service(pszServiceName);
827
0
  }
828
829
0
  for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
830
0
    if (lp_ctx->services[iService] != NULL &&
831
0
        strwicmp(lp_ctx->services[iService]->szService, pszServiceName) == 0) {
832
0
      return lp_ctx->services[iService];
833
0
    }
834
835
0
  return NULL;
836
0
}
837
838
/**
839
 * Add a parametric option to a parmlist_entry,
840
 * replacing old value, if already present.
841
 */
842
void set_param_opt(TALLOC_CTX *mem_ctx,
843
       struct parmlist_entry **opt_list,
844
       const char *opt_name,
845
       const char *opt_value,
846
       unsigned priority)
847
0
{
848
0
  struct parmlist_entry *new_opt, *opt;
849
850
0
  opt = *opt_list;
851
852
  /* Traverse destination */
853
0
  while (opt) {
854
    /* If we already have same option, override it */
855
0
    if (strwicmp(opt->key, opt_name) == 0) {
856
0
      if ((opt->priority & FLAG_CMDLINE) &&
857
0
          !(priority & FLAG_CMDLINE)) {
858
        /* it's been marked as not to be
859
           overridden */
860
0
        return;
861
0
      }
862
0
      TALLOC_FREE(opt->list);
863
0
      lpcfg_string_set(opt, &opt->value, opt_value);
864
0
      opt->priority = priority;
865
0
      return;
866
0
    }
867
0
    opt = opt->next;
868
0
  }
869
870
0
  new_opt = talloc_pooled_object(
871
0
    mem_ctx, struct parmlist_entry,
872
0
    2, strlen(opt_name) + 1 + strlen(opt_value) + 1);
873
0
  if (new_opt == NULL) {
874
0
    smb_panic("OOM");
875
0
  }
876
0
  new_opt->key = NULL;
877
0
  lpcfg_string_set(new_opt, &new_opt->key, opt_name);
878
0
  new_opt->value = NULL;
879
0
  lpcfg_string_set(new_opt, &new_opt->value, opt_value);
880
881
0
  new_opt->list = NULL;
882
0
  new_opt->priority = priority;
883
0
  DLIST_ADD(*opt_list, new_opt);
884
0
}
885
886
/**
887
 * Copy a service structure to another.
888
 * If pcopymapDest is NULL then copy all fields
889
 */
890
891
void copy_service(struct loadparm_service *pserviceDest,
892
      const struct loadparm_service *pserviceSource,
893
      struct bitmap *pcopymapDest)
894
0
{
895
0
  int i;
896
0
  bool bcopyall = (pcopymapDest == NULL);
897
0
  struct parmlist_entry *data;
898
899
0
  for (i = 0; parm_table[i].label; i++)
900
0
    if (parm_table[i].p_class == P_LOCAL &&
901
0
        (bcopyall || bitmap_query(pcopymapDest, i))) {
902
0
      const void *src_ptr =
903
0
        ((const char *)pserviceSource) + parm_table[i].offset;
904
0
      void *dest_ptr =
905
0
        ((char *)pserviceDest) + parm_table[i].offset;
906
907
0
      switch (parm_table[i].type) {
908
0
        case P_BOOL:
909
0
        case P_BOOLREV:
910
0
          *(bool *)dest_ptr = *(const bool *)src_ptr;
911
0
          break;
912
913
0
        case P_INTEGER:
914
0
        case P_BYTES:
915
0
        case P_OCTAL:
916
0
        case P_ENUM:
917
0
          *(int *)dest_ptr = *(const int *)src_ptr;
918
0
          break;
919
920
0
        case P_CHAR:
921
0
          *(char *)dest_ptr = *(const char *)src_ptr;
922
0
          break;
923
924
0
        case P_STRING:
925
0
          lpcfg_string_set(pserviceDest,
926
0
               (char **)dest_ptr,
927
0
               *(const char * const *)src_ptr);
928
0
          break;
929
930
0
        case P_USTRING:
931
0
          lpcfg_string_set_upper(pserviceDest,
932
0
               (char **)dest_ptr,
933
0
               *(const char * const *)src_ptr);
934
0
          break;
935
0
        case P_CMDLIST:
936
0
        case P_LIST:
937
0
          TALLOC_FREE(*((char ***)dest_ptr));
938
0
          *(char ***)dest_ptr = str_list_copy(pserviceDest,
939
0
                      *discard_const_p(const char **, src_ptr));
940
0
          break;
941
0
        default:
942
0
          break;
943
0
      }
944
0
    }
945
946
0
  if (bcopyall) {
947
0
    init_copymap(pserviceDest);
948
0
    if (pserviceSource->copymap)
949
0
      bitmap_copy(pserviceDest->copymap,
950
0
            pserviceSource->copymap);
951
0
  }
952
953
0
  for (data = pserviceSource->param_opt; data != NULL; data = data->next) {
954
0
    set_param_opt(pserviceDest, &pserviceDest->param_opt,
955
0
            data->key, data->value, data->priority);
956
0
  }
957
0
}
958
959
/**
960
 * Check a service for consistency. Return False if the service is in any way
961
 * incomplete or faulty, else True.
962
 */
963
bool lpcfg_service_ok(struct loadparm_service *service)
964
0
{
965
0
  bool bRetval;
966
967
0
  bRetval = true;
968
0
  if (service->szService[0] == '\0') {
969
0
    DEBUG(0, ("The following message indicates an internal error:\n"));
970
0
    DEBUG(0, ("No service name in service entry.\n"));
971
0
    bRetval = false;
972
0
  }
973
974
  /* The [printers] entry MUST be printable. I'm all for flexibility, but */
975
  /* I can't see why you'd want a non-printable printer service...        */
976
0
  if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
977
0
    if (!service->printable) {
978
0
      DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
979
0
             service->szService));
980
0
      service->printable = true;
981
0
    }
982
    /* [printers] service must also be non-browsable. */
983
0
    if (service->browseable)
984
0
      service->browseable = false;
985
0
  }
986
987
0
  if (service->path[0] == '\0' &&
988
0
      strwicmp(service->szService, HOMES_NAME) != 0 &&
989
0
      service->msdfs_proxy[0] == '\0')
990
0
  {
991
0
    DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
992
0
      service->szService));
993
0
    service->available = false;
994
0
  }
995
996
0
  if (!service->available)
997
0
    DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
998
0
        service->szService));
999
1000
0
  return bRetval;
1001
0
}
1002
1003
1004
/*******************************************************************
1005
 Keep a linked list of all config files so we know when one has changed
1006
 it's date and needs to be reloaded.
1007
********************************************************************/
1008
1009
void add_to_file_list(TALLOC_CTX *mem_ctx, struct file_lists **list,
1010
           const char *fname, const char *subfname)
1011
0
{
1012
0
  struct file_lists *f = *list;
1013
1014
0
  while (f) {
1015
0
    if (f->name && !strcmp(f->name, fname))
1016
0
      break;
1017
0
    f = f->next;
1018
0
  }
1019
1020
0
  if (!f) {
1021
0
    f = talloc_zero(mem_ctx, struct file_lists);
1022
0
    if (!f)
1023
0
      goto fail;
1024
0
    f->next = *list;
1025
0
    f->name = talloc_strdup(f, fname);
1026
0
    if (!f->name) {
1027
0
      TALLOC_FREE(f);
1028
0
      goto fail;
1029
0
    }
1030
0
    f->subfname = talloc_strdup(f, subfname);
1031
0
    if (!f->subfname) {
1032
0
      TALLOC_FREE(f);
1033
0
      goto fail;
1034
0
    }
1035
0
    *list = f;
1036
0
  }
1037
1038
  /* If file_modtime() fails it leaves f->modtime as zero. */
1039
0
  (void)file_modtime(subfname, &f->modtime);
1040
0
  return;
1041
1042
0
fail:
1043
0
  DEBUG(0, ("Unable to add file to file list: %s\n", fname));
1044
1045
0
}
1046
1047
/*
1048
 * set the value for a P_ENUM
1049
 */
1050
bool lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
1051
                              int *ptr )
1052
0
{
1053
0
  int i;
1054
1055
0
  for (i = 0; parm->enum_list[i].name; i++) {
1056
0
    if (strwicmp(pszParmValue, parm->enum_list[i].name) == 0) {
1057
0
      *ptr = parm->enum_list[i].value;
1058
0
      return true;
1059
0
    }
1060
0
  }
1061
0
  DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
1062
0
      pszParmValue, parm->label));
1063
0
  return false;
1064
0
}
1065
1066
1067
/***************************************************************************
1068
 Handle the "realm" parameter
1069
***************************************************************************/
1070
1071
bool handle_realm(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1072
      const char *pszParmValue, char **ptr)
1073
0
{
1074
0
  char *upper;
1075
0
  char *lower;
1076
1077
0
  upper = strupper_talloc(lp_ctx, pszParmValue);
1078
0
  if (upper == NULL) {
1079
0
    return false;
1080
0
  }
1081
1082
0
  lower = strlower_talloc(lp_ctx, pszParmValue);
1083
0
  if (lower == NULL) {
1084
0
    TALLOC_FREE(upper);
1085
0
    return false;
1086
0
  }
1087
1088
0
  lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->realm, upper);
1089
0
  lpcfg_string_set(lp_ctx->globals->ctx, &lp_ctx->globals->dnsdomain, lower);
1090
1091
0
  return true;
1092
0
}
1093
1094
/***************************************************************************
1095
 Handle the include operation.
1096
***************************************************************************/
1097
1098
bool handle_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1099
         const char *pszParmValue, char **ptr)
1100
0
{
1101
0
  char *fname;
1102
0
  const char *substitution_variable_substring;
1103
0
  char next_char;
1104
1105
0
  if (lp_ctx->s3_fns) {
1106
0
    return lp_ctx->s3_fns->lp_include(lp_ctx, service, pszParmValue, ptr);
1107
0
  }
1108
1109
0
  fname = standard_sub_basic(lp_ctx, pszParmValue);
1110
1111
0
  add_to_file_list(lp_ctx, &lp_ctx->file_lists, pszParmValue, fname);
1112
1113
0
  lpcfg_string_set(lp_ctx, ptr, fname);
1114
1115
0
  if (file_exist(fname))
1116
0
    return pm_process(fname, do_section, lpcfg_do_parameter, lp_ctx);
1117
1118
       /*
1119
        * If the file doesn't exist, we check that it isn't due to variable
1120
        * substitution
1121
        */
1122
0
  substitution_variable_substring = strchr(fname, '%');
1123
1124
0
  if (substitution_variable_substring != NULL) {
1125
0
    next_char = substitution_variable_substring[1];
1126
0
    if ((next_char >= 'a' && next_char <= 'z')
1127
0
        || (next_char >= 'A' && next_char <= 'Z')) {
1128
0
      DEBUG(2, ("Tried to load %s but variable substitution in "
1129
0
         "filename, ignoring file.\n", fname));
1130
0
      return true;
1131
0
    }
1132
0
  }
1133
1134
0
  DEBUG(2, ("Can't find include file %s\n", fname));
1135
1136
0
  return true;
1137
0
}
1138
1139
/***************************************************************************
1140
 Handle the interpretation of the copy parameter.
1141
***************************************************************************/
1142
1143
bool handle_copy(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1144
      const char *pszParmValue, char **ptr)
1145
0
{
1146
0
  bool bRetval;
1147
0
  struct loadparm_service *serviceTemp = NULL;
1148
1149
0
  bRetval = false;
1150
1151
0
  DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1152
1153
0
  serviceTemp = lpcfg_getservicebyname(lp_ctx, pszParmValue);
1154
1155
0
  if (service == NULL) {
1156
0
    DEBUG(0, ("Unable to copy service - invalid service destination.\n"));
1157
0
    return false;
1158
0
  }
1159
1160
0
  if (serviceTemp != NULL) {
1161
0
    if (serviceTemp == service) {
1162
0
      DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1163
0
    } else {
1164
0
      copy_service(service,
1165
0
             serviceTemp,
1166
0
             service->copymap);
1167
0
      lpcfg_string_set(service, ptr, pszParmValue);
1168
1169
0
      bRetval = true;
1170
0
    }
1171
0
  } else {
1172
0
    DEBUG(0, ("Unable to copy service - source not found: %s\n",
1173
0
        pszParmValue));
1174
0
    bRetval = false;
1175
0
  }
1176
1177
0
  return bRetval;
1178
0
}
1179
1180
bool handle_debug_list(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1181
      const char *pszParmValue, char **ptr)
1182
0
{
1183
0
  lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
1184
1185
0
  return debug_parse_levels(pszParmValue);
1186
0
}
1187
1188
bool handle_logfile(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1189
        const char *pszParmValue, char **ptr)
1190
0
{
1191
0
  if (lp_ctx->s3_fns == NULL) {
1192
0
    debug_set_logfile(pszParmValue);
1193
0
  }
1194
1195
0
  lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
1196
1197
0
  return true;
1198
0
}
1199
1200
/*
1201
 * These special charset handling methods only run in the source3 code.
1202
 */
1203
1204
bool handle_charset(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1205
      const char *pszParmValue, char **ptr)
1206
0
{
1207
0
  if (lp_ctx->s3_fns) {
1208
0
    if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
1209
0
      struct smb_iconv_handle *ret = NULL;
1210
1211
0
      ret = reinit_iconv_handle(NULL,
1212
0
              lpcfg_dos_charset(lp_ctx),
1213
0
              lpcfg_unix_charset(lp_ctx));
1214
0
      if (ret == NULL) {
1215
0
        smb_panic("reinit_iconv_handle failed");
1216
0
      }
1217
0
    }
1218
1219
0
  }
1220
0
  return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
1221
1222
0
}
1223
1224
bool handle_dos_charset(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1225
      const char *pszParmValue, char **ptr)
1226
0
{
1227
0
  bool is_utf8 = false;
1228
0
  size_t len = strlen(pszParmValue);
1229
1230
0
  if (lp_ctx->s3_fns) {
1231
0
    if (len == 4 || len == 5) {
1232
      /* Don't use StrCaseCmp here as we don't want to
1233
         initialize iconv. */
1234
0
      if ((toupper_m(pszParmValue[0]) == 'U') &&
1235
0
          (toupper_m(pszParmValue[1]) == 'T') &&
1236
0
          (toupper_m(pszParmValue[2]) == 'F')) {
1237
0
        if (len == 4) {
1238
0
          if (pszParmValue[3] == '8') {
1239
0
            is_utf8 = true;
1240
0
          }
1241
0
        } else {
1242
0
          if (pszParmValue[3] == '-' &&
1243
0
              pszParmValue[4] == '8') {
1244
0
            is_utf8 = true;
1245
0
          }
1246
0
        }
1247
0
      }
1248
0
    }
1249
1250
0
    if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
1251
0
      struct smb_iconv_handle *ret = NULL;
1252
0
      if (is_utf8) {
1253
0
        DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
1254
0
          "be UTF8, using (default value) %s instead.\n",
1255
0
          DEFAULT_DOS_CHARSET));
1256
0
        pszParmValue = DEFAULT_DOS_CHARSET;
1257
0
      }
1258
0
      ret = reinit_iconv_handle(NULL,
1259
0
            lpcfg_dos_charset(lp_ctx),
1260
0
            lpcfg_unix_charset(lp_ctx));
1261
0
      if (ret == NULL) {
1262
0
        smb_panic("reinit_iconv_handle failed");
1263
0
      }
1264
0
    }
1265
0
  }
1266
1267
0
  return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
1268
0
}
1269
1270
bool handle_printing(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1271
          const char *pszParmValue, char **ptr)
1272
0
{
1273
0
  static int parm_num = -1;
1274
1275
0
  if (parm_num == -1) {
1276
0
    parm_num = lpcfg_map_parameter("printing");
1277
0
    if (parm_num == -1) {
1278
0
      return false;
1279
0
    }
1280
0
  }
1281
1282
0
  if (!lp_set_enum_parm(&parm_table[parm_num], pszParmValue, (int*)ptr)) {
1283
0
    return false;
1284
0
  }
1285
1286
0
  if (lp_ctx->s3_fns) {
1287
0
    if (service == NULL) {
1288
0
      init_printer_values(lp_ctx, lp_ctx->globals->ctx, lp_ctx->sDefault);
1289
0
    } else {
1290
0
      init_printer_values(lp_ctx, service, service);
1291
0
    }
1292
0
  }
1293
1294
0
  return true;
1295
0
}
1296
1297
bool handle_ldap_debug_level(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1298
           const char *pszParmValue, char **ptr)
1299
0
{
1300
0
  lp_ctx->globals->ldap_debug_level = lp_int(pszParmValue);
1301
1302
0
  if (lp_ctx->s3_fns) {
1303
0
    lp_ctx->s3_fns->init_ldap_debugging();
1304
0
  }
1305
0
  return true;
1306
0
}
1307
1308
/*
1309
 * idmap related parameters
1310
 */
1311
1312
bool handle_idmap_backend(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1313
        const char *pszParmValue, char **ptr)
1314
0
{
1315
0
  if (lp_ctx->s3_fns) {
1316
0
    lp_do_parameter_parametric(lp_ctx, service, "idmap config * : backend",
1317
0
             pszParmValue, 0);
1318
0
  }
1319
1320
0
  return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
1321
0
}
1322
1323
bool handle_idmap_uid(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1324
          const char *pszParmValue, char **ptr)
1325
0
{
1326
0
  if (lp_ctx->s3_fns) {
1327
0
    lp_do_parameter_parametric(lp_ctx, service, "idmap config * : range",
1328
0
             pszParmValue, 0);
1329
0
  }
1330
1331
0
  return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
1332
0
}
1333
1334
bool handle_idmap_gid(struct loadparm_context *lp_ctx, struct loadparm_service *service,
1335
          const char *pszParmValue, char **ptr)
1336
0
{
1337
0
  if (lp_ctx->s3_fns) {
1338
0
    lp_do_parameter_parametric(lp_ctx, service, "idmap config * : range",
1339
0
             pszParmValue, 0);
1340
0
  }
1341
1342
0
  return lpcfg_string_set(lp_ctx->globals->ctx, ptr, pszParmValue);
1343
0
}
1344
1345
bool smb_transport_parse(const char *_value, struct smb_transport *_t)
1346
0
{
1347
0
  size_t _value_len = strlen(_value);
1348
0
  char value[_value_len+1];
1349
0
  const char *vparam = NULL;
1350
0
  const char *portstr = NULL;
1351
0
  char *p = NULL;
1352
0
  struct smb_transport t = {
1353
0
    .type = SMB_TRANSPORT_TYPE_UNKNOWN,
1354
0
  };
1355
0
  bool invalid = false;
1356
1357
0
  memcpy(value, _value, sizeof(value));
1358
1359
0
  p = strchr(value, ':');
1360
0
  if (p != NULL) {
1361
0
    vparam = p + 1;
1362
0
    p[0] = '\0';
1363
0
  }
1364
1365
0
  if (strcmp("tcp", value) == 0) {
1366
0
    t.type = SMB_TRANSPORT_TYPE_TCP;
1367
0
    t.port = 445;
1368
0
  } else if (strcmp("nbt", value) == 0) {
1369
0
    t.type = SMB_TRANSPORT_TYPE_NBT;
1370
0
    t.port = 139;
1371
0
  } else if (strcmp("quic", value) == 0) {
1372
0
    t.type = SMB_TRANSPORT_TYPE_QUIC;
1373
0
    t.port = 443;
1374
0
  } else if (vparam != NULL) {
1375
    /*
1376
     * a port number should not have
1377
     * extra parameter!
1378
     */
1379
0
    invalid = true;
1380
0
  } else {
1381
    /*
1382
     * Could a port number only
1383
     */
1384
0
    portstr = value;
1385
0
  }
1386
1387
0
  if (!invalid && portstr == NULL) {
1388
0
    portstr = vparam;
1389
0
  }
1390
1391
0
  if (portstr != NULL) {
1392
0
    char *_end = NULL;
1393
0
    int _port = 0;
1394
0
    _port = strtol(portstr, &_end, 10);
1395
0
    if (*_end != '\0' || _port <= 0 || _port > 65535) {
1396
0
      invalid = true;
1397
0
    } else {
1398
0
      t.port = _port;
1399
0
    }
1400
0
  }
1401
1402
0
  if (invalid) {
1403
0
    t = (struct smb_transport) {
1404
0
      .type = SMB_TRANSPORT_TYPE_UNKNOWN,
1405
0
    };
1406
1407
0
    *_t = t;
1408
0
    return false;
1409
0
  }
1410
1411
0
  if (t.type == SMB_TRANSPORT_TYPE_UNKNOWN) {
1412
0
    if (t.port == 139) {
1413
0
      t.type = SMB_TRANSPORT_TYPE_NBT;
1414
0
    } else {
1415
0
      t.type = SMB_TRANSPORT_TYPE_TCP;
1416
0
    }
1417
0
  }
1418
1419
0
  *_t = t;
1420
0
  return true;
1421
0
}
1422
1423
static bool handle_smb_transports(struct loadparm_context *lp_ctx,
1424
          struct loadparm_service *service,
1425
          const char *pszParmValue,
1426
          char **ptr,
1427
          const char *optname)
1428
0
{
1429
0
  const char **list = NULL;
1430
0
  static int parm_num = -1;
1431
0
  size_t i;
1432
0
  bool ok;
1433
1434
0
  if (!pszParmValue || !*pszParmValue) {
1435
0
    return false;
1436
0
  }
1437
1438
0
  if (parm_num == -1) {
1439
0
    parm_num = lpcfg_map_parameter(optname);
1440
0
    if (parm_num == -1) {
1441
0
      return false;
1442
0
    }
1443
0
  }
1444
1445
0
  ok = set_variable_helper(lp_ctx->globals->ctx,
1446
0
         parm_num,
1447
0
         ptr,
1448
0
         optname,
1449
0
         pszParmValue);
1450
0
  if (!ok) {
1451
0
    return false;
1452
0
  }
1453
1454
0
  list = *(const char ***)ptr;
1455
1456
0
  if (list == NULL) {
1457
0
    return false;
1458
0
  }
1459
1460
  /* Check that each transport is a valid */
1461
0
  for (i = 0; list[i] != NULL; i++) {
1462
0
    struct smb_transport t = {
1463
0
      .type = SMB_TRANSPORT_TYPE_UNKNOWN,
1464
0
    };
1465
1466
0
    ok = smb_transport_parse(list[i], &t);
1467
0
    if (!ok) {
1468
0
      return false;
1469
0
    }
1470
0
  }
1471
1472
0
  return true;
1473
0
}
1474
1475
bool handle_client_smb_transports(struct loadparm_context *lp_ctx,
1476
          struct loadparm_service *service,
1477
          const char *pszParmValue,
1478
          char **ptr)
1479
0
{
1480
0
  return handle_smb_transports(lp_ctx, service, pszParmValue, ptr,
1481
0
             "client smb transports");
1482
0
}
1483
1484
bool handle_server_smb_transports(struct loadparm_context *lp_ctx,
1485
          struct loadparm_service *service,
1486
          const char *pszParmValue,
1487
          char **ptr)
1488
0
{
1489
0
  return handle_smb_transports(lp_ctx, service, pszParmValue, ptr,
1490
0
             "server smb transports");
1491
0
}
1492
1493
bool handle_rpc_server_dynamic_port_range(struct loadparm_context *lp_ctx,
1494
            struct loadparm_service *service,
1495
            const char *pszParmValue,
1496
            char **ptr)
1497
0
{
1498
0
  static int parm_num = -1;
1499
0
  int low_port = -1, high_port = -1;
1500
0
  int rc;
1501
1502
0
  if (parm_num == -1) {
1503
0
    parm_num = lpcfg_map_parameter("rpc server dynamic port range");
1504
0
    if (parm_num == -1) {
1505
0
      return false;
1506
0
    }
1507
0
  }
1508
1509
0
  if (pszParmValue == NULL || pszParmValue[0] == '\0') {
1510
0
    return false;
1511
0
  }
1512
1513
0
  rc = sscanf(pszParmValue, "%d - %d", &low_port, &high_port);
1514
0
  if (rc != 2) {
1515
0
    return false;
1516
0
  }
1517
1518
0
  if (low_port > high_port) {
1519
0
    return false;
1520
0
  }
1521
1522
0
  if (low_port < SERVER_TCP_PORT_MIN|| high_port > SERVER_TCP_PORT_MAX) {
1523
0
    return false;
1524
0
  }
1525
1526
0
  if (!set_variable_helper(lp_ctx->globals->ctx, parm_num, ptr,
1527
0
         "rpc server dynamic port range",
1528
0
         pszParmValue)) {
1529
0
    return false;
1530
0
  }
1531
1532
0
  lp_ctx->globals->rpc_low_port = low_port;
1533
0
  lp_ctx->globals->rpc_high_port = high_port;
1534
1535
0
  return true;
1536
0
}
1537
1538
bool handle_smb2_max_credits(struct loadparm_context *lp_ctx,
1539
           struct loadparm_service *service,
1540
           const char *pszParmValue, char **ptr)
1541
0
{
1542
0
  int value = lp_int(pszParmValue);
1543
1544
0
  if (value <= 0) {
1545
0
    value = DEFAULT_SMB2_MAX_CREDITS;
1546
0
  }
1547
1548
0
  *(int *)ptr = value;
1549
1550
0
  return true;
1551
0
}
1552
1553
bool handle_cups_encrypt(struct loadparm_context *lp_ctx,
1554
       struct loadparm_service *service,
1555
       const char *pszParmValue, char **ptr)
1556
0
{
1557
0
  int result = 0;
1558
0
#ifdef HAVE_HTTPCONNECTENCRYPT
1559
0
  int value = lp_int(pszParmValue);
1560
1561
0
  switch (value) {
1562
0
    case Auto:
1563
0
      result = HTTP_ENCRYPT_REQUIRED;
1564
0
      break;
1565
0
    case true:
1566
0
      result = HTTP_ENCRYPT_ALWAYS;
1567
0
      break;
1568
0
    case false:
1569
0
      result = HTTP_ENCRYPT_NEVER;
1570
0
      break;
1571
0
    default:
1572
0
      result = 0;
1573
0
      break;
1574
0
  }
1575
0
#endif
1576
0
  *(int *)ptr = result;
1577
1578
0
  return true;
1579
0
}
1580
1581
/***************************************************************************
1582
 Initialise a copymap.
1583
***************************************************************************/
1584
1585
/**
1586
 * Initializes service copymap
1587
 * Note: pservice *must* be valid TALLOC_CTX
1588
 */
1589
void init_copymap(struct loadparm_service *pservice)
1590
0
{
1591
0
  int i;
1592
1593
0
  TALLOC_FREE(pservice->copymap);
1594
1595
0
  pservice->copymap = bitmap_talloc(pservice, num_parameters());
1596
0
  if (!pservice->copymap) {
1597
0
    DEBUG(0,
1598
0
          ("Couldn't allocate copymap!! (size %d)\n",
1599
0
           (int)num_parameters()));
1600
0
  } else {
1601
0
    for (i = 0; i < num_parameters(); i++) {
1602
0
      bitmap_set(pservice->copymap, i);
1603
0
    }
1604
0
  }
1605
0
}
1606
1607
/**
1608
 * Process a parametric option
1609
 */
1610
static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
1611
               struct loadparm_service *service,
1612
               const char *pszParmName,
1613
               const char *pszParmValue, int flags)
1614
0
{
1615
0
  struct parmlist_entry **data;
1616
0
  char *name;
1617
0
  TALLOC_CTX *mem_ctx;
1618
1619
0
  while (isspace((unsigned char)*pszParmName)) {
1620
0
    pszParmName++;
1621
0
  }
1622
1623
0
  name = strlower_talloc(lp_ctx, pszParmName);
1624
0
  if (!name) return false;
1625
1626
0
  if (service == NULL) {
1627
0
    data = &lp_ctx->globals->param_opt;
1628
    /**
1629
     * s3 code cannot deal with parametric options stored on the globals ctx.
1630
     */
1631
0
    if (lp_ctx->s3_fns != NULL) {
1632
0
      mem_ctx = NULL;
1633
0
    } else {
1634
0
      mem_ctx = lp_ctx->globals->ctx;
1635
0
    }
1636
0
  } else {
1637
0
    data = &service->param_opt;
1638
0
    mem_ctx = service;
1639
0
  }
1640
1641
0
  set_param_opt(mem_ctx, data, name, pszParmValue, flags);
1642
1643
0
  talloc_free(name);
1644
1645
0
  return true;
1646
0
}
1647
1648
static bool set_variable_helper(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
1649
       const char *pszParmName, const char *pszParmValue)
1650
0
{
1651
0
  size_t i;
1652
1653
  /* switch on the type of variable it is */
1654
0
  switch (parm_table[parmnum].type)
1655
0
  {
1656
0
    case P_BOOL: {
1657
0
      bool b;
1658
0
      if (!set_boolean(pszParmValue, &b)) {
1659
0
        DEBUG(0, ("set_variable_helper(%s): value is not "
1660
0
            "boolean!\n", pszParmValue));
1661
0
        return false;
1662
0
      }
1663
0
      *(bool *)parm_ptr = b;
1664
0
      }
1665
0
      break;
1666
1667
0
    case P_BOOLREV: {
1668
0
      bool b;
1669
0
      if (!set_boolean(pszParmValue, &b)) {
1670
0
        DEBUG(0, ("set_variable_helper(%s): value is not "
1671
0
            "boolean!\n", pszParmValue));
1672
0
        return false;
1673
0
      }
1674
0
      *(bool *)parm_ptr = !b;
1675
0
      }
1676
0
      break;
1677
1678
0
    case P_INTEGER:
1679
0
      *(int *)parm_ptr = lp_int(pszParmValue);
1680
0
      break;
1681
1682
0
    case P_CHAR:
1683
0
      *(char *)parm_ptr = *pszParmValue;
1684
0
      break;
1685
1686
0
    case P_OCTAL:
1687
0
      i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
1688
0
      if ( i != 1 ) {
1689
0
        DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
1690
0
        return false;
1691
0
      }
1692
0
      break;
1693
1694
0
    case P_BYTES:
1695
0
    {
1696
0
      uint64_t val;
1697
0
      if (conv_str_size_error(pszParmValue, &val)) {
1698
0
        if (val <= INT_MAX) {
1699
0
          *(int *)parm_ptr = (int)val;
1700
0
          break;
1701
0
        }
1702
0
      }
1703
1704
0
      DEBUG(0, ("set_variable_helper(%s): value is not "
1705
0
                "a valid size specifier!\n", pszParmValue));
1706
0
      return false;
1707
0
    }
1708
1709
0
    case P_CMDLIST:
1710
0
      TALLOC_FREE(*(char ***)parm_ptr);
1711
0
      *(char ***)parm_ptr = str_list_make_v3(mem_ctx,
1712
0
              pszParmValue, NULL);
1713
0
      break;
1714
1715
0
    case P_LIST:
1716
0
    {
1717
0
      char **new_list = str_list_make_v3(mem_ctx,
1718
0
              pszParmValue, NULL);
1719
0
      if (new_list == NULL) {
1720
0
        break;
1721
0
      }
1722
1723
0
      for (i=0; new_list[i]; i++) {
1724
0
        if (*(const char ***)parm_ptr != NULL &&
1725
0
            new_list[i][0] == '+' &&
1726
0
            new_list[i][1])
1727
0
        {
1728
0
          if (!str_list_check(*(const char ***)parm_ptr,
1729
0
                  &new_list[i][1])) {
1730
0
            *(const char ***)parm_ptr = str_list_add(*(const char ***)parm_ptr,
1731
0
                       &new_list[i][1]);
1732
0
          }
1733
0
        } else if (*(const char ***)parm_ptr != NULL &&
1734
0
             new_list[i][0] == '-' &&
1735
0
             new_list[i][1])
1736
0
        {
1737
0
          str_list_remove(*(const char ***)parm_ptr,
1738
0
              &new_list[i][1]);
1739
0
        } else {
1740
0
          if (i != 0) {
1741
0
            DEBUG(0, ("Unsupported list syntax for: %s = %s\n",
1742
0
                pszParmName, pszParmValue));
1743
0
            return false;
1744
0
          }
1745
0
          *(char ***)parm_ptr = new_list;
1746
0
          break;
1747
0
        }
1748
0
      }
1749
0
      break;
1750
0
    }
1751
1752
0
    case P_STRING:
1753
0
      lpcfg_string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1754
0
      break;
1755
1756
0
    case P_USTRING:
1757
0
      lpcfg_string_set_upper(mem_ctx, (char **)parm_ptr, pszParmValue);
1758
0
      break;
1759
1760
0
    case P_ENUM:
1761
0
      if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
1762
0
        return false;
1763
0
      }
1764
0
      break;
1765
1766
0
  }
1767
1768
0
  return true;
1769
1770
0
}
1771
1772
bool handle_name_resolve_order(struct loadparm_context *lp_ctx,
1773
             struct loadparm_service *service,
1774
             const char *pszParmValue, char **ptr)
1775
0
{
1776
0
  const char **valid_values = NULL;
1777
0
  const char **values_to_set = NULL;
1778
0
  int i;
1779
0
  bool value_is_valid = false;
1780
0
  valid_values = str_list_make_v3_const(NULL,
1781
0
                DEFAULT_NAME_RESOLVE_ORDER,
1782
0
                NULL);
1783
0
  if (valid_values == NULL) {
1784
0
    DBG_ERR("OOM: failed to make string list from %s\n",
1785
0
      DEFAULT_NAME_RESOLVE_ORDER);
1786
0
    goto out;
1787
0
  }
1788
0
  values_to_set = str_list_make_v3_const(lp_ctx->globals->ctx,
1789
0
                 pszParmValue,
1790
0
                 NULL);
1791
0
  if (values_to_set == NULL) {
1792
0
    DBG_ERR("OOM: failed to make string list from %s\n",
1793
0
      pszParmValue);
1794
0
    goto out;
1795
0
  }
1796
0
  TALLOC_FREE(lp_ctx->globals->name_resolve_order);
1797
0
  for (i = 0; values_to_set[i] != NULL; i++) {
1798
0
    value_is_valid = str_list_check(valid_values, values_to_set[i]);
1799
0
    if (!value_is_valid) {
1800
0
      DBG_ERR("WARNING: Ignoring invalid list value '%s' "
1801
0
        "for parameter 'name resolve order'\n",
1802
0
        values_to_set[i]);
1803
0
      break;
1804
0
    }
1805
0
  }
1806
0
out:
1807
0
  if (value_is_valid) {
1808
0
    lp_ctx->globals->name_resolve_order = values_to_set;
1809
0
  } else {
1810
0
    TALLOC_FREE(values_to_set);
1811
0
  }
1812
0
  TALLOC_FREE(valid_values);
1813
0
  return value_is_valid;
1814
0
}
1815
1816
bool handle_kdc_default_domain_supported_enctypes(struct loadparm_context *lp_ctx,
1817
              struct loadparm_service *service,
1818
              const char *pszParmValue, char **ptr)
1819
0
{
1820
0
  char **enctype_list = NULL;
1821
0
  char **enctype = NULL;
1822
0
  uint32_t result = 0;
1823
0
  bool ok = true;
1824
1825
0
  enctype_list = str_list_make(NULL, pszParmValue, NULL);
1826
0
  if (enctype_list == NULL) {
1827
0
    DBG_ERR("OOM: failed to make string list from %s\n",
1828
0
      pszParmValue);
1829
0
    ok = false;
1830
0
    goto out;
1831
0
  }
1832
1833
0
  for (enctype = enctype_list; *enctype != NULL; ++enctype) {
1834
0
    if (strwicmp(*enctype, "arcfour-hmac-md5") == 0 ||
1835
0
        strwicmp(*enctype, "rc4-hmac") == 0)
1836
0
    {
1837
0
      result |= KERB_ENCTYPE_RC4_HMAC_MD5;
1838
0
    }
1839
0
    else if (strwicmp(*enctype, "aes128-cts-hmac-sha1-96") == 0 ||
1840
0
       strwicmp(*enctype, "aes128-cts") == 0)
1841
0
    {
1842
0
      result |= KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1843
0
    }
1844
0
    else if (strwicmp(*enctype, "aes256-cts-hmac-sha1-96") == 0 ||
1845
0
       strwicmp(*enctype, "aes256-cts") == 0)
1846
0
    {
1847
0
      result |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1848
0
    }
1849
0
    else if (strwicmp(*enctype, "aes256-cts-hmac-sha1-96-sk") == 0 ||
1850
0
       strwicmp(*enctype, "aes256-cts-sk") == 0)
1851
0
    {
1852
0
      result |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96_SK;
1853
0
    }
1854
0
    else {
1855
0
      const char *bitstr = *enctype;
1856
0
      int base;
1857
0
      int error;
1858
0
      unsigned long bit;
1859
1860
      /* See if the bit's specified in hexadecimal. */
1861
0
      if (bitstr[0] == '0' &&
1862
0
          (bitstr[1] == 'x' || bitstr[2] == 'X'))
1863
0
      {
1864
0
        base = 16;
1865
0
        bitstr += 2;
1866
0
      }
1867
0
      else {
1868
0
        base = 10;
1869
0
      }
1870
1871
0
      bit = smb_strtoul(bitstr, NULL, base, &error, SMB_STR_FULL_STR_CONV);
1872
0
      if (error) {
1873
0
        DBG_ERR("WARNING: Ignoring invalid value '%s' "
1874
0
          "for parameter 'kdc default domain supported enctypes'\n",
1875
0
          *enctype);
1876
0
        ok = false;
1877
0
      } else {
1878
0
        result |= bit;
1879
0
      }
1880
0
    }
1881
0
  }
1882
1883
0
  *(int *)ptr = result;
1884
0
out:
1885
0
  TALLOC_FREE(enctype_list);
1886
1887
0
  return ok;
1888
0
}
1889
1890
bool handle_kdc_supported_enctypes(struct loadparm_context *lp_ctx,
1891
           struct loadparm_service *service,
1892
           const char *pszParmValue, char **ptr)
1893
0
{
1894
0
  char **enctype_list = NULL;
1895
0
  char **enctype = NULL;
1896
0
  uint32_t result = 0;
1897
0
  bool ok = true;
1898
1899
0
  enctype_list = str_list_make(NULL, pszParmValue, NULL);
1900
0
  if (enctype_list == NULL) {
1901
0
    DBG_ERR("OOM: failed to make string list from %s\n",
1902
0
      pszParmValue);
1903
0
    ok = false;
1904
0
    goto out;
1905
0
  }
1906
1907
0
  for (enctype = enctype_list; *enctype != NULL; ++enctype) {
1908
0
    if (strwicmp(*enctype, "arcfour-hmac-md5") == 0 ||
1909
0
        strwicmp(*enctype, "rc4-hmac") == 0)
1910
0
    {
1911
0
      result |= KERB_ENCTYPE_RC4_HMAC_MD5;
1912
0
    }
1913
0
    else if (strwicmp(*enctype, "aes128-cts-hmac-sha1-96") == 0 ||
1914
0
       strwicmp(*enctype, "aes128-cts") == 0)
1915
0
    {
1916
0
      result |= KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1917
0
    }
1918
0
    else if (strwicmp(*enctype, "aes256-cts-hmac-sha1-96") == 0 ||
1919
0
       strwicmp(*enctype, "aes256-cts") == 0)
1920
0
    {
1921
0
      result |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1922
0
    }
1923
0
    else {
1924
0
      const char *bitstr = *enctype;
1925
0
      int base;
1926
0
      int error;
1927
0
      unsigned long bit;
1928
1929
      /* See if the bit's specified in hexadecimal. */
1930
0
      if (bitstr[0] == '0' &&
1931
0
          (bitstr[1] == 'x' || bitstr[2] == 'X'))
1932
0
      {
1933
0
        base = 16;
1934
0
        bitstr += 2;
1935
0
      }
1936
0
      else {
1937
0
        base = 10;
1938
0
      }
1939
1940
0
      bit = smb_strtoul(bitstr, NULL, base, &error, SMB_STR_FULL_STR_CONV);
1941
0
      if (error) {
1942
0
        DBG_ERR("WARNING: Ignoring invalid value '%s' "
1943
0
          "for parameter 'kdc default domain supported enctypes'\n",
1944
0
          *enctype);
1945
0
        ok = false;
1946
0
      } else {
1947
0
        result |= bit;
1948
0
      }
1949
0
    }
1950
0
  }
1951
1952
0
  *(int *)ptr = result;
1953
0
out:
1954
0
  TALLOC_FREE(enctype_list);
1955
1956
0
  return ok;
1957
0
}
1958
1959
static bool set_variable(TALLOC_CTX *mem_ctx, struct loadparm_service *service,
1960
       int parmnum, void *parm_ptr,
1961
       const char *pszParmName, const char *pszParmValue,
1962
       struct loadparm_context *lp_ctx, bool on_globals)
1963
0
{
1964
0
  int i;
1965
0
  bool ok;
1966
1967
  /* if it is a special case then go ahead */
1968
0
  if (parm_table[parmnum].special) {
1969
0
    ok = parm_table[parmnum].special(lp_ctx, service, pszParmValue,
1970
0
              (char **)parm_ptr);
1971
0
  } else {
1972
0
    ok = set_variable_helper(mem_ctx, parmnum, parm_ptr,
1973
0
           pszParmName, pszParmValue);
1974
0
  }
1975
1976
0
  if (!ok) {
1977
0
    return false;
1978
0
  }
1979
1980
0
  if (on_globals && (lp_ctx->flags[parmnum] & FLAG_DEFAULT)) {
1981
0
    lp_ctx->flags[parmnum] &= ~FLAG_DEFAULT;
1982
    /* we have to also unset FLAG_DEFAULT on aliases */
1983
0
    for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
1984
0
      lp_ctx->flags[i] &= ~FLAG_DEFAULT;
1985
0
    }
1986
0
    for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset;i++) {
1987
0
      lp_ctx->flags[i] &= ~FLAG_DEFAULT;
1988
0
    }
1989
0
  }
1990
0
  return true;
1991
0
}
1992
1993
1994
bool lpcfg_do_global_parameter(struct loadparm_context *lp_ctx,
1995
             const char *pszParmName, const char *pszParmValue)
1996
0
{
1997
0
  int parmnum = lpcfg_map_parameter(pszParmName);
1998
0
  void *parm_ptr;
1999
2000
0
  if (parmnum < 0) {
2001
0
    if (strchr(pszParmName, ':')) {
2002
0
      return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, 0);
2003
0
    }
2004
0
    DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2005
0
    return true;
2006
0
  }
2007
2008
  /* if the flag has been set on the command line, then don't allow override,
2009
     but don't report an error */
2010
0
  if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
2011
0
    return true;
2012
0
  }
2013
2014
0
  if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2015
0
    char *suppress_env = getenv("SAMBA_DEPRECATED_SUPPRESS");
2016
0
    bool print_warning = (suppress_env == NULL
2017
0
              || suppress_env[0] == '\0');
2018
0
    if (print_warning) {
2019
0
      DBG_WARNING("WARNING: The \"%s\" option "
2020
0
            "is deprecated\n",
2021
0
            pszParmName);
2022
2023
0
    }
2024
0
  }
2025
2026
0
  parm_ptr = lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]);
2027
2028
0
  return set_variable(lp_ctx->globals->ctx, NULL, parmnum, parm_ptr,
2029
0
          pszParmName, pszParmValue, lp_ctx, true);
2030
0
}
2031
2032
bool lpcfg_do_service_parameter(struct loadparm_context *lp_ctx,
2033
        struct loadparm_service *service,
2034
        const char *pszParmName, const char *pszParmValue)
2035
0
{
2036
0
  void *parm_ptr;
2037
0
  int i;
2038
0
  int parmnum = lpcfg_map_parameter(pszParmName);
2039
2040
0
  if (parmnum < 0) {
2041
0
    if (strchr(pszParmName, ':')) {
2042
0
      return lp_do_parameter_parametric(lp_ctx, service, pszParmName, pszParmValue, 0);
2043
0
    }
2044
0
    DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2045
0
    return true;
2046
0
  }
2047
2048
  /* if the flag has been set on the command line, then don't allow override,
2049
     but don't report an error */
2050
0
  if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
2051
0
    return true;
2052
0
  }
2053
2054
0
  if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2055
0
    char *suppress_env = getenv("SAMBA_DEPRECATED_SUPPRESS");
2056
0
    bool print_warning = (suppress_env == NULL
2057
0
              || suppress_env[0] == '\0');
2058
0
    if (print_warning) {
2059
0
      DBG_WARNING("WARNING: The \"%s\" option "
2060
0
            "is deprecated\n",
2061
0
            pszParmName);
2062
2063
0
    }
2064
0
  }
2065
2066
0
  if (parm_table[parmnum].p_class == P_GLOBAL) {
2067
0
    DEBUG(0,
2068
0
          ("Global parameter %s found in service section!\n",
2069
0
           pszParmName));
2070
0
    return true;
2071
0
  }
2072
0
  parm_ptr = ((char *)service) + parm_table[parmnum].offset;
2073
2074
0
  if (!service->copymap)
2075
0
    init_copymap(service);
2076
2077
  /* this handles the aliases - set the copymap for other
2078
   * entries with the same data pointer */
2079
0
  for (i = 0; parm_table[i].label; i++)
2080
0
    if (parm_table[i].offset == parm_table[parmnum].offset &&
2081
0
        parm_table[i].p_class == parm_table[parmnum].p_class)
2082
0
      bitmap_clear(service->copymap, i);
2083
2084
0
  return set_variable(service, service, parmnum, parm_ptr, pszParmName,
2085
0
          pszParmValue, lp_ctx, false);
2086
0
}
2087
2088
/**
2089
 * Process a parameter.
2090
 */
2091
2092
bool lpcfg_do_parameter(const char *pszParmName, const char *pszParmValue,
2093
       void *userdata)
2094
0
{
2095
0
  struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2096
2097
0
  if (lp_ctx->bInGlobalSection)
2098
0
    return lpcfg_do_global_parameter(lp_ctx, pszParmName,
2099
0
                pszParmValue);
2100
0
  else
2101
0
    return lpcfg_do_service_parameter(lp_ctx, lp_ctx->currentService,
2102
0
              pszParmName, pszParmValue);
2103
0
}
2104
2105
/*
2106
  variable argument do parameter
2107
*/
2108
bool lpcfg_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
2109
bool lpcfg_do_global_parameter_var(struct loadparm_context *lp_ctx,
2110
        const char *pszParmName, const char *fmt, ...)
2111
0
{
2112
0
  char *s;
2113
0
  bool ret;
2114
0
  va_list ap;
2115
2116
0
  va_start(ap, fmt);
2117
0
  s = talloc_vasprintf(NULL, fmt, ap);
2118
0
  va_end(ap);
2119
0
  ret = lpcfg_do_global_parameter(lp_ctx, pszParmName, s);
2120
0
  talloc_free(s);
2121
0
  return ret;
2122
0
}
2123
2124
2125
/*
2126
  set a parameter from the commandline - this is called from command line parameter
2127
  parsing code. It sets the parameter then marks the parameter as unable to be modified
2128
  by smb.conf processing
2129
*/
2130
bool lpcfg_set_cmdline(struct loadparm_context *lp_ctx, const char *pszParmName,
2131
           const char *pszParmValue)
2132
0
{
2133
0
  int parmnum;
2134
0
  int i;
2135
2136
0
  while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
2137
2138
0
  parmnum = lpcfg_map_parameter(pszParmName);
2139
2140
0
  if (parmnum < 0 && strchr(pszParmName, ':')) {
2141
    /* set a parametric option */
2142
0
    bool ok;
2143
0
    ok = lp_do_parameter_parametric(lp_ctx, NULL, pszParmName,
2144
0
            pszParmValue, FLAG_CMDLINE);
2145
0
    if (lp_ctx->s3_fns != NULL) {
2146
0
      if (ok) {
2147
0
        lp_ctx->s3_fns->store_cmdline(pszParmName, pszParmValue);
2148
0
      }
2149
0
    }
2150
0
    return ok;
2151
0
  }
2152
2153
0
  if (parmnum < 0) {
2154
0
    DEBUG(0,("Unknown option '%s'\n", pszParmName));
2155
0
    return false;
2156
0
  }
2157
2158
  /* reset the CMDLINE flag in case this has been called before */
2159
0
  lp_ctx->flags[parmnum] &= ~FLAG_CMDLINE;
2160
2161
0
  if (!lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
2162
0
    return false;
2163
0
  }
2164
2165
0
  lp_ctx->flags[parmnum] |= FLAG_CMDLINE;
2166
2167
  /* we have to also set FLAG_CMDLINE on aliases */
2168
0
  for (i=parmnum-1;
2169
0
       i>=0 && parm_table[i].p_class == parm_table[parmnum].p_class &&
2170
0
       parm_table[i].offset == parm_table[parmnum].offset;
2171
0
       i--) {
2172
0
    lp_ctx->flags[i] |= FLAG_CMDLINE;
2173
0
  }
2174
0
  for (i=parmnum+1;
2175
0
       i<num_parameters() &&
2176
0
       parm_table[i].p_class == parm_table[parmnum].p_class &&
2177
0
       parm_table[i].offset == parm_table[parmnum].offset;
2178
0
       i++) {
2179
0
    lp_ctx->flags[i] |= FLAG_CMDLINE;
2180
0
  }
2181
2182
0
  if (lp_ctx->s3_fns != NULL) {
2183
0
    lp_ctx->s3_fns->store_cmdline(pszParmName, pszParmValue);
2184
0
  }
2185
2186
0
  return true;
2187
0
}
2188
2189
/*
2190
  set a option from the commandline in 'a=b' format. Use to support --option
2191
*/
2192
bool lpcfg_set_option(struct loadparm_context *lp_ctx, const char *option)
2193
0
{
2194
0
  char *p, *s;
2195
0
  bool ret;
2196
2197
0
  s = talloc_strdup(NULL, option);
2198
0
  if (!s) {
2199
0
    return false;
2200
0
  }
2201
2202
0
  p = strchr(s, '=');
2203
0
  if (!p) {
2204
0
    talloc_free(s);
2205
0
    return false;
2206
0
  }
2207
2208
0
  *p = 0;
2209
2210
0
  ret = lpcfg_set_cmdline(lp_ctx, s, p+1);
2211
0
  talloc_free(s);
2212
0
  return ret;
2213
0
}
2214
2215
2216
#define BOOLSTR(b) ((b) ? "Yes" : "No")
2217
2218
/**
2219
 * Print a parameter of the specified type.
2220
 */
2221
2222
void lpcfg_print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2223
0
{
2224
  /* For the separation of lists values that we print below */
2225
0
  const char *list_sep = ", ";
2226
0
  int i;
2227
0
  switch (p->type)
2228
0
  {
2229
0
    case P_ENUM:
2230
0
      for (i = 0; p->enum_list[i].name; i++) {
2231
0
        if (*(int *)ptr == p->enum_list[i].value) {
2232
0
          fprintf(f, "%s",
2233
0
            p->enum_list[i].name);
2234
0
          break;
2235
0
        }
2236
0
      }
2237
0
      break;
2238
2239
0
    case P_BOOL:
2240
0
      fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
2241
0
      break;
2242
2243
0
    case P_BOOLREV:
2244
0
      fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
2245
0
      break;
2246
2247
0
    case P_INTEGER:
2248
0
    case P_BYTES:
2249
0
      fprintf(f, "%d", *(int *)ptr);
2250
0
      break;
2251
2252
0
    case P_CHAR:
2253
0
      fprintf(f, "%c", *(char *)ptr);
2254
0
      break;
2255
2256
0
    case P_OCTAL: {
2257
0
      int val = *(int *)ptr;
2258
0
      if (val == -1) {
2259
0
        fprintf(f, "-1");
2260
0
      } else {
2261
0
        fprintf(f, "0%03o", val);
2262
0
      }
2263
0
      break;
2264
0
    }
2265
2266
0
    case P_CMDLIST:
2267
0
      list_sep = " ";
2268
2269
0
      FALL_THROUGH;
2270
0
    case P_LIST:
2271
0
      if ((char ***)ptr && *(char ***)ptr) {
2272
0
        char **list = *(char ***)ptr;
2273
0
        for (; *list; list++) {
2274
          /* surround strings with whitespace in double quotes */
2275
0
          if (*(list+1) == NULL) {
2276
            /* last item, no extra separator */
2277
0
            list_sep = "";
2278
0
          }
2279
0
          if ( strchr_m( *list, ' ' ) ) {
2280
0
            fprintf(f, "\"%s\"%s", *list, list_sep);
2281
0
          } else {
2282
0
            fprintf(f, "%s%s", *list, list_sep);
2283
0
          }
2284
0
        }
2285
0
      }
2286
0
      break;
2287
2288
0
    case P_STRING:
2289
0
    case P_USTRING:
2290
0
      if (*(char **)ptr) {
2291
0
        fprintf(f, "%s", *(char **)ptr);
2292
0
      }
2293
0
      break;
2294
0
  }
2295
0
}
2296
2297
/**
2298
 * Check if two parameters are equal.
2299
 */
2300
2301
static bool lpcfg_equal_parameter(parm_type type, void *ptr1, void *ptr2)
2302
0
{
2303
0
  switch (type) {
2304
0
    case P_BOOL:
2305
0
    case P_BOOLREV:
2306
0
      return (*((bool *)ptr1) == *((bool *)ptr2));
2307
2308
0
    case P_INTEGER:
2309
0
    case P_ENUM:
2310
0
    case P_OCTAL:
2311
0
    case P_BYTES:
2312
0
      return (*((int *)ptr1) == *((int *)ptr2));
2313
2314
0
    case P_CHAR:
2315
0
      return (*((char *)ptr1) == *((char *)ptr2));
2316
2317
0
    case P_LIST:
2318
0
    case P_CMDLIST:
2319
0
      return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
2320
2321
0
    case P_STRING:
2322
0
    case P_USTRING:
2323
0
    {
2324
0
      char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2325
0
      if (p1 && !*p1)
2326
0
        p1 = NULL;
2327
0
      if (p2 && !*p2)
2328
0
        p2 = NULL;
2329
0
      return (p1 == p2 || strequal(p1, p2));
2330
0
    }
2331
0
  }
2332
0
  return false;
2333
0
}
2334
2335
/**
2336
 * Process a new section (service).
2337
 *
2338
 * At this stage all sections are services.
2339
 * Later we'll have special sections that permit server parameters to be set.
2340
 * Returns True on success, False on failure.
2341
 */
2342
2343
static bool do_section(const char *pszSectionName, void *userdata)
2344
0
{
2345
0
  struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2346
0
  bool bRetval;
2347
0
  bool isglobal;
2348
2349
0
  if (lp_ctx->s3_fns != NULL) {
2350
0
    return lp_ctx->s3_fns->do_section(pszSectionName, lp_ctx);
2351
0
  }
2352
2353
0
  isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2354
0
       (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2355
2356
  /* if we've just struck a global section, note the fact. */
2357
0
  lp_ctx->bInGlobalSection = isglobal;
2358
2359
  /* check for multiple global sections */
2360
0
  if (lp_ctx->bInGlobalSection) {
2361
0
    DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
2362
0
    bRetval = true;
2363
0
    goto out;
2364
0
  }
2365
2366
  /* if we have a current service, tidy it up before moving on */
2367
0
  bRetval = true;
2368
2369
0
  if (lp_ctx->currentService != NULL)
2370
0
    bRetval = lpcfg_service_ok(lp_ctx->currentService);
2371
2372
  /* if all is still well, move to the next record in the services array */
2373
0
  if (bRetval) {
2374
    /* We put this here to avoid an odd message order if messages are */
2375
    /* issued by the post-processing of a previous section. */
2376
0
    DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
2377
2378
0
    if ((lp_ctx->currentService = lpcfg_add_service(lp_ctx, lp_ctx->sDefault,
2379
0
                   pszSectionName))
2380
0
        == NULL) {
2381
0
      DEBUG(0, ("Failed to add a new service\n"));
2382
0
      bRetval = false;
2383
0
      goto out;
2384
0
    }
2385
0
  }
2386
0
out:
2387
0
  return bRetval;
2388
0
}
2389
2390
2391
/**
2392
 * Determine if a particular base parameter is currently set to the default value.
2393
 */
2394
2395
static bool is_default(void *base_structure, int i)
2396
0
{
2397
0
  void *def_ptr = ((char *)base_structure) + parm_table[i].offset;
2398
0
  switch (parm_table[i].type) {
2399
0
    case P_CMDLIST:
2400
0
    case P_LIST:
2401
0
      return str_list_equal((const char * const *)parm_table[i].def.lvalue,
2402
0
                *(const char * const **)def_ptr);
2403
0
    case P_STRING:
2404
0
    case P_USTRING:
2405
0
      return strequal(parm_table[i].def.svalue,
2406
0
          *(char **)def_ptr);
2407
0
    case P_BOOL:
2408
0
    case P_BOOLREV:
2409
0
      return parm_table[i].def.bvalue ==
2410
0
        *(bool *)def_ptr;
2411
0
    case P_INTEGER:
2412
0
    case P_CHAR:
2413
0
    case P_OCTAL:
2414
0
    case P_BYTES:
2415
0
    case P_ENUM:
2416
0
      return parm_table[i].def.ivalue ==
2417
0
        *(int *)def_ptr;
2418
0
  }
2419
0
  return false;
2420
0
}
2421
2422
/**
2423
 *Display the contents of the global structure.
2424
 */
2425
2426
void lpcfg_dump_globals(struct loadparm_context *lp_ctx, FILE *f,
2427
       bool show_defaults)
2428
0
{
2429
0
  int i;
2430
0
  struct parmlist_entry *data;
2431
2432
0
  fprintf(f, "# Global parameters\n[global]\n");
2433
2434
0
  for (i = 0; parm_table[i].label; i++) {
2435
0
    if (parm_table[i].p_class != P_GLOBAL) {
2436
0
      continue;
2437
0
    }
2438
2439
0
    if (parm_table[i].flags & FLAG_SYNONYM) {
2440
0
      continue;
2441
0
    }
2442
2443
0
    if (!show_defaults) {
2444
0
      if (lp_ctx->flags && (lp_ctx->flags[i] & FLAG_DEFAULT)) {
2445
0
        continue;
2446
0
      }
2447
2448
0
      if (is_default(lp_ctx->globals, i)) {
2449
0
        continue;
2450
0
      }
2451
0
    }
2452
2453
0
    fprintf(f, "\t%s = ", parm_table[i].label);
2454
0
    lpcfg_print_parameter(&parm_table[i], lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
2455
0
    fprintf(f, "\n");
2456
0
  }
2457
0
  if (lp_ctx->globals->param_opt != NULL) {
2458
0
    for (data = lp_ctx->globals->param_opt; data;
2459
0
         data = data->next) {
2460
0
      if (!show_defaults && (data->priority & FLAG_DEFAULT)) {
2461
0
        continue;
2462
0
      }
2463
0
      fprintf(f, "\t%s = %s\n", data->key, data->value);
2464
0
    }
2465
0
        }
2466
2467
0
}
2468
2469
/**
2470
 * Display the contents of a single services record.
2471
 */
2472
2473
void lpcfg_dump_a_service(struct loadparm_service * pService, struct loadparm_service *sDefault, FILE * f,
2474
        unsigned int *flags, bool show_defaults)
2475
0
{
2476
0
  int i;
2477
0
  struct parmlist_entry *data;
2478
2479
0
  if (pService != sDefault)
2480
0
    fprintf(f, "\n[%s]\n", pService->szService);
2481
2482
0
  for (i = 0; parm_table[i].label; i++) {
2483
0
    if (parm_table[i].p_class != P_LOCAL) {
2484
0
      continue;
2485
0
    }
2486
2487
0
    if (parm_table[i].flags & FLAG_SYNONYM) {
2488
0
      continue;
2489
0
    }
2490
2491
0
    if (*parm_table[i].label == '-') {
2492
0
      continue;
2493
0
    }
2494
2495
0
    if (pService == sDefault) {
2496
0
      if (!show_defaults) {
2497
0
        if (flags && (flags[i] & FLAG_DEFAULT)) {
2498
0
          continue;
2499
0
        }
2500
2501
0
        if (is_default(sDefault, i)) {
2502
0
          continue;
2503
0
        }
2504
0
      }
2505
0
    } else {
2506
0
      bool equal;
2507
2508
0
      equal = lpcfg_equal_parameter(parm_table[i].type,
2509
0
                  ((char *)pService) +
2510
0
                  parm_table[i].offset,
2511
0
                  ((char *)sDefault) +
2512
0
                  parm_table[i].offset);
2513
0
      if (equal) {
2514
0
        continue;
2515
0
      }
2516
0
    }
2517
2518
0
    fprintf(f, "\t%s = ", parm_table[i].label);
2519
0
    lpcfg_print_parameter(&parm_table[i],
2520
0
        ((char *)pService) + parm_table[i].offset, f);
2521
0
    fprintf(f, "\n");
2522
0
  }
2523
0
  if (pService->param_opt != NULL) {
2524
0
    for (data = pService->param_opt; data; data = data->next) {
2525
0
      if (!show_defaults && (data->priority & FLAG_DEFAULT)) {
2526
0
        continue;
2527
0
      }
2528
0
      fprintf(f, "\t%s = %s\n", data->key, data->value);
2529
0
    }
2530
0
        }
2531
0
}
2532
2533
bool lpcfg_dump_a_parameter(struct loadparm_context *lp_ctx,
2534
          struct loadparm_service *service,
2535
          const char *parm_name, FILE * f)
2536
0
{
2537
0
  struct parm_struct *parm;
2538
0
  void *ptr;
2539
0
  char *local_parm_name;
2540
0
  char *parm_opt;
2541
0
  const char *parm_opt_value;
2542
2543
  /* check for parametrical option */
2544
0
  local_parm_name = talloc_strdup(lp_ctx, parm_name);
2545
0
  if (local_parm_name == NULL) {
2546
0
    return false;
2547
0
  }
2548
2549
0
  parm_opt = strchr( local_parm_name, ':');
2550
2551
0
  if (parm_opt) {
2552
0
    *parm_opt = '\0';
2553
0
    parm_opt++;
2554
0
    if (strlen(parm_opt)) {
2555
0
      parm_opt_value = lpcfg_parm_string(lp_ctx, service,
2556
0
        local_parm_name, parm_opt);
2557
0
      if (parm_opt_value) {
2558
0
        fprintf(f, "%s\n", parm_opt_value);
2559
0
        TALLOC_FREE(local_parm_name);
2560
0
        return true;
2561
0
      }
2562
0
    }
2563
0
    TALLOC_FREE(local_parm_name);
2564
0
    return false;
2565
0
  }
2566
0
  TALLOC_FREE(local_parm_name);
2567
2568
  /* parameter is not parametric, search the table */
2569
0
  parm = lpcfg_parm_struct(lp_ctx, parm_name);
2570
0
  if (!parm) {
2571
0
    return false;
2572
0
  }
2573
2574
0
  if (service != NULL && parm->p_class == P_GLOBAL) {
2575
0
    return false;
2576
0
  }
2577
2578
0
  ptr = lpcfg_parm_ptr(lp_ctx, service,parm);
2579
2580
0
  lpcfg_print_parameter(parm, ptr, f);
2581
0
  fprintf(f, "\n");
2582
0
  return true;
2583
0
}
2584
2585
/**
2586
 * Auto-load some home services.
2587
 */
2588
static void lpcfg_add_auto_services(struct loadparm_context *lp_ctx,
2589
            const char *str)
2590
0
{
2591
0
  return;
2592
0
}
2593
2594
/***************************************************************************
2595
 Initialise the sDefault parameter structure for the printer values.
2596
***************************************************************************/
2597
2598
void init_printer_values(struct loadparm_context *lp_ctx, TALLOC_CTX *ctx,
2599
       struct loadparm_service *pService)
2600
0
{
2601
  /* choose defaults depending on the type of printing */
2602
0
  switch (pService->printing) {
2603
0
    case PRINT_BSD:
2604
0
    case PRINT_AIX:
2605
0
    case PRINT_LPRNT:
2606
0
    case PRINT_LPROS2:
2607
0
      lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
2608
0
      lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
2609
0
      lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
2610
0
      break;
2611
2612
0
    case PRINT_LPRNG:
2613
0
    case PRINT_PLP:
2614
0
      lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
2615
0
      lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
2616
0
      lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
2617
0
      lpcfg_string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
2618
0
      lpcfg_string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
2619
0
      lpcfg_string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
2620
0
      lpcfg_string_set(ctx, &pService->lpresume_command, "lpc release '%p' %j");
2621
0
      break;
2622
2623
0
    case PRINT_CUPS:
2624
0
    case PRINT_IPRINT:
2625
      /* set the lpq command to contain the destination printer
2626
         name only.  This is used by cups_queue_get() */
2627
0
      lpcfg_string_set(ctx, &pService->lpq_command, "%p");
2628
0
      lpcfg_string_set(ctx, &pService->lprm_command, "");
2629
0
      lpcfg_string_set(ctx, &pService->print_command, "");
2630
0
      lpcfg_string_set(ctx, &pService->lppause_command, "");
2631
0
      lpcfg_string_set(ctx, &pService->lpresume_command, "");
2632
0
      lpcfg_string_set(ctx, &pService->queuepause_command, "");
2633
0
      lpcfg_string_set(ctx, &pService->queueresume_command, "");
2634
0
      break;
2635
2636
0
    case PRINT_SYSV:
2637
0
    case PRINT_HPUX:
2638
0
      lpcfg_string_set(ctx, &pService->lpq_command, "lpstat -o%p");
2639
0
      lpcfg_string_set(ctx, &pService->lprm_command, "cancel %p-%j");
2640
0
      lpcfg_string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
2641
0
      lpcfg_string_set(ctx, &pService->queuepause_command, "disable %p");
2642
0
      lpcfg_string_set(ctx, &pService->queueresume_command, "enable %p");
2643
0
#ifndef HPUX
2644
0
      lpcfg_string_set(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
2645
0
      lpcfg_string_set(ctx, &pService->lpresume_command, "lp -i %p-%j -H resume");
2646
0
#endif /* HPUX */
2647
0
      break;
2648
2649
0
    case PRINT_QNX:
2650
0
      lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P%p");
2651
0
      lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
2652
0
      lpcfg_string_set(ctx, &pService->print_command, "lp -r -P%p %s");
2653
0
      break;
2654
2655
0
#if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
2656
2657
0
  case PRINT_TEST:
2658
0
  case PRINT_VLP: {
2659
0
    const char *tdbfile;
2660
0
    TALLOC_CTX *tmp_ctx = talloc_new(ctx);
2661
0
    const char *tmp;
2662
2663
0
    tmp = lpcfg_parm_string(lp_ctx, NULL, "vlp", "tdbfile");
2664
0
    if (tmp == NULL) {
2665
0
      tmp = "/tmp/vlp.tdb";
2666
0
    }
2667
2668
0
    tdbfile = talloc_asprintf(tmp_ctx, "tdbfile=%s", tmp);
2669
0
    if (tdbfile == NULL) {
2670
0
      tdbfile="tdbfile=/tmp/vlp.tdb";
2671
0
    }
2672
2673
0
    tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
2674
0
              tdbfile);
2675
0
    lpcfg_string_set(ctx, &pService->print_command,
2676
0
         tmp ? tmp : "vlp print %p %s");
2677
2678
0
    tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
2679
0
              tdbfile);
2680
0
    lpcfg_string_set(ctx, &pService->lpq_command,
2681
0
         tmp ? tmp : "vlp lpq %p");
2682
2683
0
    tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
2684
0
              tdbfile);
2685
0
    lpcfg_string_set(ctx, &pService->lprm_command,
2686
0
         tmp ? tmp : "vlp lprm %p %j");
2687
2688
0
    tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
2689
0
              tdbfile);
2690
0
    lpcfg_string_set(ctx, &pService->lppause_command,
2691
0
         tmp ? tmp : "vlp lppause %p %j");
2692
2693
0
    tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
2694
0
              tdbfile);
2695
0
    lpcfg_string_set(ctx, &pService->lpresume_command,
2696
0
         tmp ? tmp : "vlp lpresume %p %j");
2697
2698
0
    tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
2699
0
              tdbfile);
2700
0
    lpcfg_string_set(ctx, &pService->queuepause_command,
2701
0
         tmp ? tmp : "vlp queuepause %p");
2702
2703
0
    tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
2704
0
              tdbfile);
2705
0
    lpcfg_string_set(ctx, &pService->queueresume_command,
2706
0
         tmp ? tmp : "vlp queueresume %p");
2707
0
    TALLOC_FREE(tmp_ctx);
2708
2709
0
    break;
2710
0
  }
2711
0
#endif /* DEVELOPER */
2712
2713
0
  }
2714
0
}
2715
2716
2717
static int lpcfg_destructor(struct loadparm_context *lp_ctx)
2718
0
{
2719
0
  struct parmlist_entry *data;
2720
2721
0
  if (lp_ctx->refuse_free) {
2722
    /* someone is trying to free the
2723
       global_loadparm_context.
2724
       We can't allow that. */
2725
0
    return -1;
2726
0
  }
2727
2728
0
  if (lp_ctx->globals->param_opt != NULL) {
2729
0
    struct parmlist_entry *next;
2730
0
    for (data = lp_ctx->globals->param_opt; data; data=next) {
2731
0
      next = data->next;
2732
0
      if (data->priority & FLAG_CMDLINE) continue;
2733
0
      DLIST_REMOVE(lp_ctx->globals->param_opt, data);
2734
0
      talloc_free(data);
2735
0
    }
2736
0
  }
2737
2738
0
  return 0;
2739
0
}
2740
2741
/**
2742
 * Initialise the global parameter structure.
2743
 *
2744
 * Note that most callers should use loadparm_init_global() instead
2745
 */
2746
struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
2747
0
{
2748
0
  int i;
2749
0
  char *myname;
2750
0
  struct loadparm_context *lp_ctx;
2751
0
  struct parmlist_entry *parm;
2752
0
  char *logfile;
2753
2754
0
  lp_ctx = talloc_zero(mem_ctx, struct loadparm_context);
2755
0
  if (lp_ctx == NULL)
2756
0
    return NULL;
2757
2758
0
  talloc_set_destructor(lp_ctx, lpcfg_destructor);
2759
0
  lp_ctx->bInGlobalSection = true;
2760
0
  lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global);
2761
  /* This appears odd, but globals in s3 isn't a pointer */
2762
0
  lp_ctx->globals->ctx = lp_ctx->globals;
2763
0
  lp_ctx->globals->rpc_low_port = SERVER_TCP_LOW_PORT;
2764
0
  lp_ctx->globals->rpc_high_port = SERVER_TCP_HIGH_PORT;
2765
0
  lp_ctx->globals->weak_crypto = SAMBA_WEAK_CRYPTO_UNKNOWN;
2766
0
  lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
2767
0
  lp_ctx->flags = talloc_zero_array(lp_ctx, unsigned int, num_parameters());
2768
2769
0
  lp_ctx->sDefault->max_print_jobs = 1000;
2770
0
  lp_ctx->sDefault->available = true;
2771
0
  lp_ctx->sDefault->browseable = true;
2772
0
  lp_ctx->sDefault->read_only = true;
2773
0
  lp_ctx->sDefault->map_archive = true;
2774
0
  lp_ctx->sDefault->strict_locking = true;
2775
0
  lp_ctx->sDefault->oplocks = true;
2776
0
  lp_ctx->sDefault->create_mask = 0744;
2777
0
  lp_ctx->sDefault->force_create_mode = 0000;
2778
0
  lp_ctx->sDefault->directory_mask = 0755;
2779
0
  lp_ctx->sDefault->force_directory_mode = 0000;
2780
0
  lp_ctx->sDefault->aio_read_size = 1;
2781
0
  lp_ctx->sDefault->aio_write_size = 1;
2782
0
  lp_ctx->sDefault->smbd_search_ask_sharemode = true;
2783
0
  lp_ctx->sDefault->smbd_getinfo_ask_sharemode = true;
2784
0
  lp_ctx->sDefault->volume_serial_number = -1;
2785
2786
0
  DEBUG(3, ("Initialising global parameters\n"));
2787
2788
0
  for (i = 0; parm_table[i].label; i++) {
2789
0
    if ((parm_table[i].type == P_STRING ||
2790
0
         parm_table[i].type == P_USTRING) &&
2791
0
        !(lp_ctx->flags[i] & FLAG_CMDLINE)) {
2792
0
      TALLOC_CTX *parent_mem;
2793
0
      char **r;
2794
0
      if (parm_table[i].p_class == P_LOCAL) {
2795
0
        parent_mem = lp_ctx->sDefault;
2796
0
        r = (char **)(((char *)lp_ctx->sDefault) + parm_table[i].offset);
2797
0
      } else {
2798
0
        parent_mem = lp_ctx->globals;
2799
0
        r = (char **)(((char *)lp_ctx->globals) + parm_table[i].offset);
2800
0
      }
2801
0
      lpcfg_string_set(parent_mem, r, "");
2802
0
    }
2803
0
  }
2804
2805
0
  logfile = talloc_asprintf(lp_ctx, "%s/log.samba", dyn_LOGFILEBASE);
2806
0
  lpcfg_do_global_parameter(lp_ctx, "log file", logfile);
2807
0
  talloc_free(logfile);
2808
2809
0
  lpcfg_do_global_parameter(lp_ctx, "log level", "0");
2810
2811
0
  lpcfg_do_global_parameter(lp_ctx, "syslog", "1");
2812
0
  lpcfg_do_global_parameter(lp_ctx, "syslog only", "No");
2813
0
  lpcfg_do_global_parameter(lp_ctx, "debug timestamp", "Yes");
2814
0
  lpcfg_do_global_parameter(lp_ctx, "debug prefix timestamp", "No");
2815
0
  lpcfg_do_global_parameter(lp_ctx, "debug hires timestamp", "Yes");
2816
0
  lpcfg_do_global_parameter(lp_ctx, "debug syslog format", "No");
2817
0
  lpcfg_do_global_parameter(lp_ctx, "debug pid", "No");
2818
0
  lpcfg_do_global_parameter(lp_ctx, "debug uid", "No");
2819
0
  lpcfg_do_global_parameter(lp_ctx, "debug class", "No");
2820
0
  lpcfg_do_global_parameter(lp_ctx, "winbind debug traceid", "Yes");
2821
2822
0
  lpcfg_do_global_parameter(lp_ctx, "server role", "auto");
2823
0
  lpcfg_do_global_parameter(lp_ctx, "domain logons", "No");
2824
0
  lpcfg_do_global_parameter(lp_ctx, "domain master", "Auto");
2825
2826
  /* options that can be set on the command line must be initialised via
2827
     the slower lpcfg_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
2828
0
#ifdef TCP_NODELAY
2829
0
  lpcfg_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
2830
0
#endif
2831
0
  lpcfg_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
2832
0
  myname = get_myname(lp_ctx);
2833
0
  lpcfg_do_global_parameter(lp_ctx, "netbios name", myname);
2834
0
  talloc_free(myname);
2835
0
  lpcfg_do_global_parameter(lp_ctx,
2836
0
          "name resolve order",
2837
0
          DEFAULT_NAME_RESOLVE_ORDER);
2838
2839
0
  lpcfg_do_global_parameter(lp_ctx, "fstype", "NTFS");
2840
2841
0
  lpcfg_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
2842
0
  lpcfg_do_global_parameter(lp_ctx, "max connections", "0");
2843
2844
0
  lpcfg_do_global_parameter(
2845
0
    lp_ctx,
2846
0
    "dcerpc endpoint servers",
2847
0
    "epmapper samr netlogon lsarpc drsuapi dssetup unixinfo "
2848
0
    "browser eventlog6 backupkey dnsserver");
2849
0
  lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl ft_scanner winbindd ntp_signd kcc dnsupdate dns");
2850
0
  lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true");
2851
  /* the winbind method for domain controllers is for both RODC
2852
     auth forwarding and for trusted domains */
2853
0
  lpcfg_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
2854
0
  lpcfg_do_global_parameter(lp_ctx, "binddns dir", dyn_BINDDNS_DIR);
2855
0
  lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
2856
2857
  /* This hive should be dynamically generated by Samba using
2858
     data from the sam, but for the moment leave it in a tdb to
2859
     keep regedt32 from popping up an annoying dialog. */
2860
0
  lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
2861
2862
  /* using UTF8 by default allows us to support all chars */
2863
0
  lpcfg_do_global_parameter(lp_ctx, "unix charset", "UTF-8");
2864
2865
  /* Use codepage 850 as a default for the dos character set */
2866
0
  lpcfg_do_global_parameter(lp_ctx, "dos charset", "CP850");
2867
2868
  /*
2869
   * Allow the default PASSWD_CHAT to be overridden in local.h.
2870
   */
2871
0
  lpcfg_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
2872
2873
0
  lpcfg_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
2874
0
  lpcfg_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
2875
0
  lpcfg_do_global_parameter(lp_ctx, "state directory", dyn_STATEDIR);
2876
0
  lpcfg_do_global_parameter(lp_ctx, "cache directory", dyn_CACHEDIR);
2877
0
  lpcfg_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
2878
2879
0
  lpcfg_do_global_parameter(lp_ctx, "nbt client socket address", "0.0.0.0");
2880
0
  lpcfg_do_global_parameter_var(lp_ctx, "server string",
2881
0
           "Samba %s", SAMBA_VERSION_STRING);
2882
2883
0
  lpcfg_do_global_parameter(lp_ctx, "password server", "*");
2884
2885
0
  lpcfg_do_global_parameter(lp_ctx, "max mux", "50");
2886
0
  lpcfg_do_global_parameter(lp_ctx, "max xmit", "16644");
2887
0
  lpcfg_do_global_parameter(lp_ctx, "host msdfs", "true");
2888
2889
0
  lpcfg_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
2890
0
  lpcfg_do_global_parameter(lp_ctx, "server min protocol", "SMB2_02");
2891
0
  lpcfg_do_global_parameter(lp_ctx, "server max protocol", "SMB3");
2892
0
  lpcfg_do_global_parameter(lp_ctx, "client min protocol", "SMB2_02");
2893
0
  lpcfg_do_global_parameter(lp_ctx, "client max protocol", "default");
2894
0
  lpcfg_do_global_parameter(lp_ctx, "client ipc min protocol", "default");
2895
0
  lpcfg_do_global_parameter(lp_ctx, "client ipc max protocol", "default");
2896
0
  lpcfg_do_global_parameter(lp_ctx, "security", "AUTO");
2897
0
  lpcfg_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
2898
0
  lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True");
2899
0
  lpcfg_do_global_parameter(lp_ctx, "WriteRaw", "True");
2900
0
  lpcfg_do_global_parameter(lp_ctx, "NullPasswords", "False");
2901
0
  lpcfg_do_global_parameter(lp_ctx, "old password allowed period", "60");
2902
0
  lpcfg_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
2903
2904
0
  lpcfg_do_global_parameter(lp_ctx, "TimeServer", "False");
2905
0
  lpcfg_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
2906
0
  lpcfg_do_global_parameter(lp_ctx, "Unicode", "True");
2907
0
  lpcfg_do_global_parameter(lp_ctx, "ClientLanManAuth", "False");
2908
0
  lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True");
2909
0
  lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False");
2910
0
  lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "ntlmv2-only");
2911
0
  lpcfg_do_global_parameter(lp_ctx, "NT hash store", "always");
2912
0
  lpcfg_do_global_parameter(lp_ctx, "RawNTLMv2Auth", "False");
2913
2914
0
  lpcfg_do_global_parameter(lp_ctx, "allow dcerpc auth level connect", "False");
2915
2916
0
  lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True");
2917
2918
0
  lpcfg_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
2919
0
  lpcfg_do_global_parameter(lp_ctx, "LocalMaster", "True");
2920
2921
0
  lpcfg_do_global_parameter(lp_ctx, "wins support", "False");
2922
0
  lpcfg_do_global_parameter(lp_ctx, "dns proxy", "True");
2923
2924
0
  lpcfg_do_global_parameter(lp_ctx, "winbind separator", "\\");
2925
0
  lpcfg_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
2926
0
  lpcfg_do_global_parameter(lp_ctx, "winbind scan trusted domains", "False");
2927
0
  lpcfg_do_global_parameter(lp_ctx, "require strong key", "True");
2928
0
  lpcfg_do_global_parameter(lp_ctx, "reject md5 servers", "True");
2929
0
  lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
2930
0
  lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
2931
0
  lpcfg_do_global_parameter_var(lp_ctx, "gpo update command", "%s/samba-gpupdate", dyn_SCRIPTSBINDIR);
2932
0
  lpcfg_do_global_parameter_var(lp_ctx, "apply group policies", "False");
2933
0
  lpcfg_do_global_parameter_var(lp_ctx, "dns update command", "%s/samba_dnsupdate", dyn_SCRIPTSBINDIR);
2934
0
  lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
2935
0
  lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
2936
0
          "%s/samba_kcc", dyn_SCRIPTSBINDIR);
2937
#ifdef MIT_KDC_PATH
2938
  lpcfg_do_global_parameter_var(lp_ctx,
2939
              "mit kdc command",
2940
              MIT_KDC_PATH);
2941
#endif
2942
0
  lpcfg_do_global_parameter(lp_ctx, "template shell", "/bin/false");
2943
0
  lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%D/%U");
2944
2945
0
  lpcfg_do_global_parameter(lp_ctx, "client signing", "default");
2946
0
  lpcfg_do_global_parameter(lp_ctx, "client ipc signing", "default");
2947
0
  lpcfg_do_global_parameter(lp_ctx, "server signing", "default");
2948
2949
0
  lpcfg_do_global_parameter(lp_ctx, "use mmap", "True");
2950
2951
0
  lpcfg_do_global_parameter(lp_ctx, "server smb transports", "tcp, nbt");
2952
0
  lpcfg_do_global_parameter(lp_ctx, "client smb transports", "tcp, nbt");
2953
0
  lpcfg_do_global_parameter_var(lp_ctx, "nbt port", "%d", NBT_NAME_SERVICE_PORT);
2954
0
  lpcfg_do_global_parameter_var(lp_ctx, "dgram port", "%d", NBT_DGRAM_SERVICE_PORT);
2955
0
  lpcfg_do_global_parameter(lp_ctx, "krb5 port", "88");
2956
0
  lpcfg_do_global_parameter(lp_ctx, "kpasswd port", "464");
2957
0
  lpcfg_do_global_parameter_var(lp_ctx, "dns port", "%d", DNS_SERVICE_PORT);
2958
2959
0
  lpcfg_do_global_parameter(lp_ctx, "kdc enable fast", "True");
2960
0
  lpcfg_do_global_parameter(lp_ctx, "strong certificate binding enforcement", "full");
2961
0
  lpcfg_do_global_parameter(lp_ctx, "certificate backdating compensation", "0");
2962
0
  lpcfg_do_global_parameter(lp_ctx, "kdc always include pac", "True");
2963
0
  lpcfg_do_global_parameter(lp_ctx, "kdc name match implicit dollar without canonicalization",
2964
0
          "yes");
2965
0
  lpcfg_do_global_parameter(lp_ctx, "kdc require canonicalization", "no");
2966
0
  lpcfg_do_global_parameter(lp_ctx, "krb5 acceptor report canonical client name", "yes");
2967
2968
0
  lpcfg_do_global_parameter(lp_ctx, "nt status support", "True");
2969
2970
0
  lpcfg_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
2971
0
  lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600");
2972
2973
0
  lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True");
2974
0
  lpcfg_do_global_parameter(lp_ctx, "tls verify peer", "as_strict_as_possible");
2975
0
  lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
2976
0
  lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
2977
0
  lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
2978
0
  lpcfg_do_global_parameter(lp_ctx,
2979
0
          "tls priority",
2980
0
          "NORMAL:-VERS-SSL3.0");
2981
2982
0
  lpcfg_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate -g");
2983
2984
0
        lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "secure only");
2985
0
  lpcfg_do_global_parameter(lp_ctx, "dns zone scavenging", "False");
2986
0
        lpcfg_do_global_parameter(lp_ctx, "dns forwarder", "");
2987
2988
0
  lpcfg_do_global_parameter(lp_ctx, "algorithmic rid base", "1000");
2989
2990
0
  lpcfg_do_global_parameter(lp_ctx, "enhanced browsing", "True");
2991
2992
0
  lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
2993
2994
0
  lpcfg_do_global_parameter(lp_ctx, "server schannel", "True");
2995
0
  lpcfg_do_global_parameter(lp_ctx, "server schannel require seal", "True");
2996
0
  lpcfg_do_global_parameter(lp_ctx, "reject md5 clients", "True");
2997
2998
0
  lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
2999
3000
0
  lpcfg_do_global_parameter(lp_ctx, "max open files", "16384");
3001
3002
0
  lpcfg_do_global_parameter(lp_ctx, "cups connection timeout", "30");
3003
3004
0
  lpcfg_do_global_parameter(lp_ctx, "locking", "True");
3005
3006
0
  lpcfg_do_global_parameter(lp_ctx, "block size", "1024");
3007
3008
0
  lpcfg_do_global_parameter(lp_ctx, "client use spnego", "True");
3009
3010
0
  lpcfg_do_global_parameter(lp_ctx, "change notify", "True");
3011
3012
0
  lpcfg_do_global_parameter(lp_ctx, "name cache timeout", "660");
3013
3014
0
  lpcfg_do_global_parameter(lp_ctx, "defer sharing violations", "True");
3015
3016
0
  lpcfg_do_global_parameter(lp_ctx, "ldap replication sleep", "1000");
3017
3018
0
  lpcfg_do_global_parameter(lp_ctx, "idmap backend", "tdb");
3019
3020
0
  lpcfg_do_global_parameter(lp_ctx, "enable privileges", "True");
3021
3022
0
  lpcfg_do_global_parameter_var(lp_ctx, "smb2 max write", "%u", DEFAULT_SMB2_MAX_WRITE);
3023
3024
0
  lpcfg_do_global_parameter(lp_ctx, "passdb backend", "tdbsam");
3025
3026
0
  lpcfg_do_global_parameter(lp_ctx, "deadtime", "10080");
3027
3028
0
  lpcfg_do_global_parameter(lp_ctx, "winbind nested groups", "True");
3029
3030
0
  lpcfg_do_global_parameter(lp_ctx, "mangled names", "illegal");
3031
3032
0
  lpcfg_do_global_parameter_var(lp_ctx, "smb2 max credits", "%u", DEFAULT_SMB2_MAX_CREDITS);
3033
3034
0
  lpcfg_do_global_parameter(lp_ctx, "ldap ssl", "start tls");
3035
3036
0
  lpcfg_do_global_parameter(lp_ctx, "ldap deref", "auto");
3037
3038
0
  lpcfg_do_global_parameter(lp_ctx, "lm interval", "60");
3039
3040
0
  lpcfg_do_global_parameter(lp_ctx, "mangling method", "hash2");
3041
3042
0
  lpcfg_do_global_parameter(lp_ctx, "hide dot files", "True");
3043
3044
0
  lpcfg_do_global_parameter(lp_ctx, "browse list", "True");
3045
3046
0
  lpcfg_do_global_parameter(lp_ctx, "passwd chat timeout", "2");
3047
3048
0
  lpcfg_do_global_parameter(lp_ctx, "guest account", GUEST_ACCOUNT);
3049
3050
0
  lpcfg_do_global_parameter(lp_ctx, "client schannel", "True");
3051
3052
0
  lpcfg_do_global_parameter(lp_ctx, "client use krb5 netlogon", "default");
3053
3054
0
  lpcfg_do_global_parameter(lp_ctx, "smb encrypt", "default");
3055
3056
0
  lpcfg_do_global_parameter(lp_ctx, "max log size", "5000");
3057
3058
0
  lpcfg_do_global_parameter(lp_ctx, "idmap negative cache time", "120");
3059
3060
0
  lpcfg_do_global_parameter(lp_ctx, "ldap follow referral", "auto");
3061
3062
0
  lpcfg_do_global_parameter(lp_ctx, "multicast dns register", "yes");
3063
3064
0
  lpcfg_do_global_parameter(lp_ctx, "winbind reconnect delay", "30");
3065
3066
0
  lpcfg_do_global_parameter(lp_ctx, "winbind request timeout", "60");
3067
3068
0
  lpcfg_do_global_parameter(lp_ctx, "nt acl support", "yes");
3069
3070
0
  lpcfg_do_global_parameter(lp_ctx, "acl check permissions", "yes");
3071
3072
0
  lpcfg_do_global_parameter(lp_ctx, "keepalive", "300");
3073
3074
0
  lpcfg_do_global_parameter(lp_ctx, "smbd profiling level", "off");
3075
3076
0
  lpcfg_do_global_parameter(lp_ctx, "winbind cache time", "300");
3077
3078
0
  lpcfg_do_global_parameter(lp_ctx, "level2 oplocks", "yes");
3079
3080
0
  lpcfg_do_global_parameter(lp_ctx, "show add printer wizard", "yes");
3081
3082
0
  lpcfg_do_global_parameter(lp_ctx, "ldap page size", "1000");
3083
3084
0
  lpcfg_do_global_parameter(lp_ctx, "kernel share modes", "no");
3085
3086
0
  lpcfg_do_global_parameter(lp_ctx, "strict locking", "Auto");
3087
3088
0
  lpcfg_do_global_parameter(lp_ctx, "strict sync", "yes");
3089
3090
0
  lpcfg_do_global_parameter(lp_ctx, "map readonly", "no");
3091
3092
0
  lpcfg_do_global_parameter(lp_ctx, "allow trusted domains", "yes");
3093
3094
0
  lpcfg_do_global_parameter(lp_ctx, "default devmode", "yes");
3095
3096
0
  lpcfg_do_global_parameter(lp_ctx, "os level", "20");
3097
3098
0
  lpcfg_do_global_parameter(lp_ctx, "dos filetimes", "yes");
3099
3100
0
  lpcfg_do_global_parameter(lp_ctx, "mangling char", "~");
3101
3102
0
  lpcfg_do_global_parameter(lp_ctx, "printcap cache time", "750");
3103
3104
0
  lpcfg_do_global_parameter(lp_ctx, "create krb5 conf", "yes");
3105
3106
0
  lpcfg_do_global_parameter(lp_ctx, "winbind max clients", "200");
3107
3108
0
  lpcfg_do_global_parameter(lp_ctx, "acl map full control", "yes");
3109
3110
0
  lpcfg_do_global_parameter(lp_ctx, "nt pipe support", "yes");
3111
3112
0
  lpcfg_do_global_parameter(lp_ctx, "ldap debug threshold", "10");
3113
3114
0
  lpcfg_do_global_parameter(lp_ctx, "client ldap sasl wrapping", "seal");
3115
3116
0
  lpcfg_do_global_parameter(lp_ctx, "mdns name", "netbios");
3117
3118
0
  lpcfg_do_global_parameter(lp_ctx, "ldap server require strong auth", "yes");
3119
3120
0
  lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes");
3121
3122
0
  lpcfg_do_global_parameter(lp_ctx, "machine password timeout", "604800");
3123
3124
0
  lpcfg_do_global_parameter(lp_ctx, "ldap connection timeout", "2");
3125
3126
0
  lpcfg_do_global_parameter(lp_ctx, "winbind expand groups", "0");
3127
3128
0
  lpcfg_do_global_parameter(lp_ctx, "stat cache", "yes");
3129
3130
0
  lpcfg_do_global_parameter(lp_ctx, "lpq cache time", "30");
3131
3132
0
  lpcfg_do_global_parameter_var(lp_ctx, "smb2 max trans", "%u", DEFAULT_SMB2_MAX_TRANSACT);
3133
3134
0
  lpcfg_do_global_parameter_var(lp_ctx, "smb2 max read", "%u", DEFAULT_SMB2_MAX_READ);
3135
3136
0
  lpcfg_do_global_parameter(lp_ctx, "durable handles", "yes");
3137
3138
0
  lpcfg_do_global_parameter(lp_ctx, "max stat cache size", "512");
3139
3140
0
  lpcfg_do_global_parameter(lp_ctx, "ldap passwd sync", "no");
3141
3142
0
  lpcfg_do_global_parameter(lp_ctx, "kernel change notify", "yes");
3143
3144
0
  lpcfg_do_global_parameter(lp_ctx, "max ttl", "259200");
3145
3146
0
  lpcfg_do_global_parameter(lp_ctx, "blocking locks", "yes");
3147
3148
0
  lpcfg_do_global_parameter(lp_ctx, "load printers", "yes");
3149
3150
0
  lpcfg_do_global_parameter(lp_ctx, "idmap cache time", "604800");
3151
3152
0
  lpcfg_do_global_parameter(lp_ctx, "preserve case", "yes");
3153
3154
0
  lpcfg_do_global_parameter(lp_ctx, "lm announce", "auto");
3155
3156
0
  lpcfg_do_global_parameter(lp_ctx, "afs token lifetime", "604800");
3157
3158
0
  lpcfg_do_global_parameter(lp_ctx, "enable core files", "yes");
3159
3160
0
  lpcfg_do_global_parameter(lp_ctx, "winbind max domain connections", "1");
3161
3162
0
  lpcfg_do_global_parameter(lp_ctx, "case sensitive", "auto");
3163
3164
0
  lpcfg_do_global_parameter(lp_ctx, "ldap timeout", "15");
3165
3166
0
  lpcfg_do_global_parameter(lp_ctx, "mangle prefix", "1");
3167
3168
0
  lpcfg_do_global_parameter(lp_ctx, "posix locking", "yes");
3169
3170
0
  lpcfg_do_global_parameter(lp_ctx, "lock spin time", "200");
3171
3172
0
  lpcfg_do_global_parameter(lp_ctx, "nmbd bind explicit broadcast", "yes");
3173
3174
0
  lpcfg_do_global_parameter(lp_ctx, "init logon delay", "100");
3175
3176
0
  lpcfg_do_global_parameter(lp_ctx, "usershare owner only", "yes");
3177
3178
0
  lpcfg_do_global_parameter(lp_ctx, "-valid", "yes");
3179
3180
0
  lpcfg_do_global_parameter_var(lp_ctx, "usershare path", "%s/usershares", get_dyn_STATEDIR());
3181
3182
0
#ifdef DEVELOPER
3183
0
  lpcfg_do_global_parameter_var(lp_ctx, "panic action", "/bin/sleep 999999999");
3184
0
#endif
3185
3186
0
  lpcfg_do_global_parameter(lp_ctx, "smb passwd file", get_dyn_SMB_PASSWD_FILE());
3187
3188
0
  lpcfg_do_global_parameter(lp_ctx, "logon home", "\\\\%N\\%U");
3189
3190
0
  lpcfg_do_global_parameter(lp_ctx, "logon path", "\\\\%N\\%U\\profile");
3191
3192
0
  lpcfg_do_global_parameter(lp_ctx, "printjob username", "%U");
3193
3194
0
  lpcfg_do_global_parameter(lp_ctx, "aio max threads", "100");
3195
3196
0
  lpcfg_do_global_parameter(lp_ctx, "smb2 leases", "yes");
3197
3198
0
  lpcfg_do_global_parameter(lp_ctx, "smb3 directory leases", "Auto");
3199
3200
0
  lpcfg_do_global_parameter(lp_ctx, "smb3 unix extensions", "yes");
3201
3202
0
  lpcfg_do_global_parameter(lp_ctx, "server multi channel support", "yes");
3203
3204
0
  lpcfg_do_global_parameter(lp_ctx, "kerberos encryption types", "all");
3205
3206
0
  lpcfg_do_global_parameter(lp_ctx,
3207
0
          "rpc server dynamic port range",
3208
0
          "49152-65535");
3209
3210
0
  lpcfg_do_global_parameter(lp_ctx, "prefork children", "4");
3211
0
  lpcfg_do_global_parameter(lp_ctx, "prefork backoff increment", "10");
3212
0
  lpcfg_do_global_parameter(lp_ctx, "prefork maximum backoff", "120");
3213
3214
0
  lpcfg_do_global_parameter(lp_ctx, "check parent directory delete on close", "no");
3215
3216
0
  lpcfg_do_global_parameter(lp_ctx, "ea support", "yes");
3217
3218
0
  lpcfg_do_global_parameter(lp_ctx, "store dos attributes", "yes");
3219
3220
0
  lpcfg_do_global_parameter(lp_ctx, "vfs mkdir use tmp name", "Auto");
3221
3222
0
  lpcfg_do_global_parameter(lp_ctx, "debug encryption", "no");
3223
3224
0
  lpcfg_do_global_parameter(lp_ctx, "spotlight backend", "noindex");
3225
3226
0
  lpcfg_do_global_parameter(
3227
0
    lp_ctx, "ldap max anonymous request size", "256000");
3228
0
  lpcfg_do_global_parameter(
3229
0
    lp_ctx, "ldap max authenticated request size", "16777216");
3230
0
  lpcfg_do_global_parameter(
3231
0
    lp_ctx, "ldap max search request size", "256000");
3232
3233
  /* Async DNS query timeout in seconds. */
3234
0
  lpcfg_do_global_parameter(lp_ctx, "async dns timeout", "10");
3235
3236
0
  lpcfg_do_global_parameter(lp_ctx,
3237
0
          "client smb encrypt",
3238
0
          "default");
3239
3240
0
  lpcfg_do_global_parameter(lp_ctx,
3241
0
          "client use kerberos",
3242
0
          "desired");
3243
3244
0
  lpcfg_do_global_parameter(lp_ctx,
3245
0
          "client protection",
3246
0
          "default");
3247
3248
0
  lpcfg_do_global_parameter(lp_ctx,
3249
0
          "smbd max xattr size",
3250
0
          "65536");
3251
3252
0
  lpcfg_do_global_parameter(lp_ctx,
3253
0
          "acl flag inherited canonicalization",
3254
0
          "yes");
3255
3256
0
  lpcfg_do_global_parameter(lp_ctx,
3257
0
          "winbind use krb5 enterprise principals",
3258
0
          "yes");
3259
3260
0
  lpcfg_do_global_parameter(lp_ctx,
3261
0
          "client smb3 signing algorithms",
3262
0
          DEFAULT_SMB3_SIGNING_ALGORITHMS);
3263
0
  lpcfg_do_global_parameter(lp_ctx,
3264
0
          "server smb3 signing algorithms",
3265
0
          DEFAULT_SMB3_SIGNING_ALGORITHMS);
3266
3267
0
  lpcfg_do_global_parameter(lp_ctx,
3268
0
          "client smb3 encryption algorithms",
3269
0
          DEFAULT_SMB3_ENCRYPTION_ALGORITHMS);
3270
0
  lpcfg_do_global_parameter(lp_ctx,
3271
0
          "server smb3 encryption algorithms",
3272
0
          DEFAULT_SMB3_ENCRYPTION_ALGORITHMS);
3273
3274
0
  lpcfg_do_global_parameter(lp_ctx,
3275
0
          "min domain uid",
3276
0
          "1000");
3277
3278
0
  lpcfg_do_global_parameter(lp_ctx,
3279
0
          "rpc start on demand helpers",
3280
0
          "yes");
3281
3282
0
  lpcfg_do_global_parameter(lp_ctx,
3283
0
          "ad dc functional level",
3284
0
          "2008_R2");
3285
3286
0
  lpcfg_do_global_parameter(lp_ctx,
3287
0
          "acl claims evaluation",
3288
0
          "AD DC only");
3289
3290
0
  lpcfg_do_global_parameter(lp_ctx,
3291
0
          "server smb encryption over quic",
3292
0
          "yes");
3293
3294
0
  lpcfg_do_global_parameter(lp_ctx,
3295
0
          "client smb encryption over quic",
3296
0
          "yes");
3297
3298
0
  for (i = 0; parm_table[i].label; i++) {
3299
0
    if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
3300
0
      lp_ctx->flags[i] |= FLAG_DEFAULT;
3301
0
    }
3302
0
  }
3303
3304
0
  for (parm=lp_ctx->globals->param_opt; parm; parm=parm->next) {
3305
0
    if (!(parm->priority & FLAG_CMDLINE)) {
3306
0
      parm->priority |= FLAG_DEFAULT;
3307
0
    }
3308
0
  }
3309
3310
0
  for (parm=lp_ctx->sDefault->param_opt; parm; parm=parm->next) {
3311
0
    if (!(parm->priority & FLAG_CMDLINE)) {
3312
0
      parm->priority |= FLAG_DEFAULT;
3313
0
    }
3314
0
  }
3315
3316
0
  return lp_ctx;
3317
0
}
3318
3319
/**
3320
 * Initialise the global parameter structure.
3321
 */
3322
struct loadparm_context *loadparm_init_global(bool load_default)
3323
0
{
3324
0
  if (global_loadparm_context == NULL) {
3325
0
    global_loadparm_context = loadparm_init(NULL);
3326
0
  }
3327
0
  if (global_loadparm_context == NULL) {
3328
0
    return NULL;
3329
0
  }
3330
0
  global_loadparm_context->global = true;
3331
0
  if (load_default && !global_loadparm_context->loaded) {
3332
0
    lpcfg_load_default(global_loadparm_context);
3333
0
  }
3334
0
  global_loadparm_context->refuse_free = true;
3335
0
  return global_loadparm_context;
3336
0
}
3337
3338
/**
3339
 * @brief Initialise the global parameter structure.
3340
 *
3341
 * This function initialized the globals if needed. Make sure that
3342
 * gfree_loadparm() is called before the application exits.
3343
 *
3344
 * @param mem_ctx   The talloc memory context to allocate lp_ctx on.
3345
 *
3346
 * @param s3_fns    The loadparm helper functions to use
3347
 *
3348
 * @return An initialized lp_ctx pointer or NULL on error.
3349
 */
3350
struct loadparm_context *loadparm_init_s3(TALLOC_CTX *mem_ctx,
3351
            const struct loadparm_s3_helpers *s3_fns)
3352
0
{
3353
0
  struct loadparm_context *loadparm_context = talloc_zero(mem_ctx, struct loadparm_context);
3354
0
  if (!loadparm_context) {
3355
0
    return NULL;
3356
0
  }
3357
0
  loadparm_context->s3_fns = s3_fns;
3358
0
  loadparm_context->globals = s3_fns->globals;
3359
0
  loadparm_context->flags = s3_fns->flags;
3360
3361
  /* Make sure globals are correctly initialized */
3362
0
  loadparm_context->s3_fns->init_globals(loadparm_context, false);
3363
3364
0
  return loadparm_context;
3365
0
}
3366
3367
const char *lpcfg_configfile(struct loadparm_context *lp_ctx)
3368
0
{
3369
0
  return lp_ctx->szConfigFile;
3370
0
}
3371
3372
const char *lp_default_path(void)
3373
0
{
3374
0
    if (getenv("SMB_CONF_PATH"))
3375
0
        return getenv("SMB_CONF_PATH");
3376
0
    else
3377
0
        return dyn_CONFIGFILE;
3378
0
}
3379
3380
/**
3381
 * Update the internal state of a loadparm context after settings
3382
 * have changed.
3383
 */
3384
static bool lpcfg_update(struct loadparm_context *lp_ctx)
3385
0
{
3386
0
  struct debug_settings settings;
3387
0
  int max_protocol, min_protocol;
3388
0
  TALLOC_CTX *tmp_ctx;
3389
0
  const struct loadparm_substitution *lp_sub =
3390
0
    lpcfg_noop_substitution();
3391
3392
0
  tmp_ctx = talloc_new(lp_ctx);
3393
0
  if (tmp_ctx == NULL) {
3394
0
    return false;
3395
0
  }
3396
3397
0
  lpcfg_add_auto_services(lp_ctx, lpcfg_auto_services(lp_ctx, lp_sub, tmp_ctx));
3398
3399
0
  if (!lp_ctx->globals->wins_server_list && lp_ctx->globals->we_are_a_wins_server) {
3400
0
    lpcfg_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
3401
0
  }
3402
3403
0
  if (!lp_ctx->global) {
3404
0
    TALLOC_FREE(tmp_ctx);
3405
0
    return true;
3406
0
  }
3407
3408
0
  panic_action = lp_ctx->globals->panic_action;
3409
3410
0
  reload_charcnv(lp_ctx);
3411
3412
0
  ZERO_STRUCT(settings);
3413
  /* Add any more debug-related smb.conf parameters created in
3414
   * future here */
3415
0
  settings.timestamp_logs = lp_ctx->globals->timestamp_logs;
3416
0
  settings.debug_prefix_timestamp = lp_ctx->globals->debug_prefix_timestamp;
3417
0
  settings.debug_hires_timestamp = lp_ctx->globals->debug_hires_timestamp;
3418
0
  settings.debug_syslog_format = lp_ctx->globals->debug_syslog_format;
3419
0
  settings.debug_pid = lp_ctx->globals->debug_pid;
3420
0
  settings.debug_uid = lp_ctx->globals->debug_uid;
3421
0
  settings.debug_class = lp_ctx->globals->debug_class;
3422
0
  settings.max_log_size = lp_ctx->globals->max_log_size;
3423
0
  debug_set_settings(&settings, lp_ctx->globals->logging,
3424
0
         lp_ctx->globals->syslog,
3425
0
         lp_ctx->globals->syslog_only);
3426
3427
  /* FIXME: This is a bit of a hack, but we can't use a global, since
3428
   * not everything that uses lp also uses the socket library */
3429
0
  if (lpcfg_parm_bool(lp_ctx, NULL, "socket", "testnonblock", false)) {
3430
0
    setenv("SOCKET_TESTNONBLOCK", "1", 1);
3431
0
  } else {
3432
0
    unsetenv("SOCKET_TESTNONBLOCK");
3433
0
  }
3434
3435
  /* Check if command line max protocol < min protocol, if so
3436
   * report a warning to the user.
3437
   */
3438
0
  max_protocol = lpcfg_client_max_protocol(lp_ctx);
3439
0
  min_protocol = lpcfg_client_min_protocol(lp_ctx);
3440
0
  if (lpcfg_client_max_protocol(lp_ctx) < lpcfg_client_min_protocol(lp_ctx)) {
3441
0
    const char *max_protocolp, *min_protocolp;
3442
0
    max_protocolp = lpcfg_get_smb_protocol(max_protocol);
3443
0
    min_protocolp = lpcfg_get_smb_protocol(min_protocol);
3444
0
    DBG_ERR("Max protocol %s is less than min protocol %s.\n",
3445
0
      max_protocolp, min_protocolp);
3446
0
  }
3447
3448
0
  TALLOC_FREE(tmp_ctx);
3449
0
  return true;
3450
0
}
3451
3452
bool lpcfg_load_default(struct loadparm_context *lp_ctx)
3453
0
{
3454
0
    const char *path;
3455
3456
0
    path = lp_default_path();
3457
3458
0
    if (!file_exist(path)) {
3459
      /* We allow the default smb.conf file to not exist,
3460
       * basically the equivalent of an empty file. */
3461
0
      return lpcfg_update(lp_ctx);
3462
0
    }
3463
3464
0
    return lpcfg_load(lp_ctx, path);
3465
0
}
3466
3467
/**
3468
 * Load the services array from the services file.
3469
 *
3470
 * Return True on success, False on failure.
3471
 */
3472
static bool lpcfg_load_internal(struct loadparm_context *lp_ctx,
3473
        const char *filename, bool set_global)
3474
0
{
3475
0
  char *n2;
3476
0
  bool bRetval;
3477
3478
0
  if (lp_ctx->szConfigFile != NULL) {
3479
0
    talloc_free(discard_const_p(char, lp_ctx->szConfigFile));
3480
0
    lp_ctx->szConfigFile = NULL;
3481
0
  }
3482
3483
0
  lp_ctx->szConfigFile = talloc_strdup(lp_ctx, filename);
3484
3485
0
  if (lp_ctx->s3_fns) {
3486
0
    return lp_ctx->s3_fns->load(filename);
3487
0
  }
3488
3489
0
  lp_ctx->bInGlobalSection = true;
3490
0
  n2 = standard_sub_basic(lp_ctx, lp_ctx->szConfigFile);
3491
0
  DEBUG(2, ("lpcfg_load: refreshing parameters from %s\n", n2));
3492
3493
0
  add_to_file_list(lp_ctx, &lp_ctx->file_lists, lp_ctx->szConfigFile, n2);
3494
3495
  /* We get sections first, so have to start 'behind' to make up */
3496
0
  lp_ctx->currentService = NULL;
3497
0
  bRetval = pm_process(n2, do_section, lpcfg_do_parameter, lp_ctx);
3498
3499
  /* finish up the last section */
3500
0
  DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3501
0
  if (bRetval)
3502
0
    if (lp_ctx->currentService != NULL)
3503
0
      bRetval = lpcfg_service_ok(lp_ctx->currentService);
3504
3505
0
  bRetval = bRetval && lpcfg_update(lp_ctx);
3506
3507
  /* we do this unconditionally, so that it happens even
3508
     for a missing smb.conf */
3509
0
  reload_charcnv(lp_ctx);
3510
3511
0
  if (bRetval == true && set_global) {
3512
    /* set this up so that any child python tasks will
3513
       find the right smb.conf */
3514
0
    setenv("SMB_CONF_PATH", filename, 1);
3515
3516
    /* set the context used by the lp_*() function
3517
       variants */
3518
0
    global_loadparm_context = lp_ctx;
3519
0
    lp_ctx->loaded = true;
3520
0
  }
3521
3522
0
  return bRetval;
3523
0
}
3524
3525
bool lpcfg_load_no_global(struct loadparm_context *lp_ctx, const char *filename)
3526
0
{
3527
0
    return lpcfg_load_internal(lp_ctx, filename, false);
3528
0
}
3529
3530
bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename)
3531
0
{
3532
0
    return lpcfg_load_internal(lp_ctx, filename, true);
3533
0
}
3534
3535
/**
3536
 * Return the max number of services.
3537
 */
3538
3539
int lpcfg_numservices(struct loadparm_context *lp_ctx)
3540
0
{
3541
0
  if (lp_ctx->s3_fns) {
3542
0
    return lp_ctx->s3_fns->get_numservices();
3543
0
  }
3544
3545
0
  return lp_ctx->iNumServices;
3546
0
}
3547
3548
/**
3549
 * Display the contents of the services array in human-readable form.
3550
 */
3551
3552
void lpcfg_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults,
3553
       int maxtoprint)
3554
0
{
3555
0
  int iService;
3556
3557
0
  if (lp_ctx->s3_fns) {
3558
0
    lp_ctx->s3_fns->dump(f, show_defaults, maxtoprint);
3559
0
    return;
3560
0
  }
3561
3562
0
  lpcfg_dump_globals(lp_ctx, f, show_defaults);
3563
3564
0
  lpcfg_dump_a_service(lp_ctx->sDefault, lp_ctx->sDefault, f, lp_ctx->flags, show_defaults);
3565
3566
0
  for (iService = 0; iService < maxtoprint; iService++)
3567
0
    lpcfg_dump_one(f, show_defaults, lp_ctx->services[iService], lp_ctx->sDefault);
3568
0
}
3569
3570
/**
3571
 * Display the contents of one service in human-readable form.
3572
 */
3573
void lpcfg_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service, struct loadparm_service *sDefault)
3574
0
{
3575
0
  if (service != NULL) {
3576
0
    if (service->szService[0] == '\0')
3577
0
      return;
3578
0
    lpcfg_dump_a_service(service, sDefault, f, NULL, show_defaults);
3579
0
  }
3580
0
}
3581
3582
struct loadparm_service *lpcfg_servicebynum(struct loadparm_context *lp_ctx,
3583
              int snum)
3584
0
{
3585
0
  if (lp_ctx->s3_fns) {
3586
0
    return lp_ctx->s3_fns->get_servicebynum(snum);
3587
0
  }
3588
3589
0
  return lp_ctx->services[snum];
3590
0
}
3591
3592
struct loadparm_service *lpcfg_service(struct loadparm_context *lp_ctx,
3593
            const char *service_name)
3594
0
{
3595
0
  int iService;
3596
0
        char *serviceName;
3597
3598
0
  if (lp_ctx->s3_fns) {
3599
0
    return lp_ctx->s3_fns->get_service(service_name);
3600
0
  }
3601
3602
0
  for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) {
3603
0
    if (lp_ctx->services[iService] &&
3604
0
        lp_ctx->services[iService]->szService) {
3605
      /*
3606
       * The substitution here is used to support %U is
3607
       * service names
3608
       */
3609
0
      serviceName = standard_sub_basic(
3610
0
          lp_ctx->services[iService],
3611
0
          lp_ctx->services[iService]->szService);
3612
0
      if (strequal(serviceName, service_name)) {
3613
0
        talloc_free(serviceName);
3614
0
        return lp_ctx->services[iService];
3615
0
      }
3616
0
      talloc_free(serviceName);
3617
0
    }
3618
0
  }
3619
3620
0
  DEBUG(7,("lpcfg_servicenumber: couldn't find %s\n", service_name));
3621
0
  return NULL;
3622
0
}
3623
3624
const char *lpcfg_servicename(const struct loadparm_service *service)
3625
0
{
3626
0
  return service ? lpcfg_string((const char *)service->szService) : NULL;
3627
0
}
3628
3629
struct smb_iconv_handle *lpcfg_iconv_handle(struct loadparm_context *lp_ctx)
3630
0
{
3631
0
  if (lp_ctx == NULL) {
3632
0
    return get_iconv_handle();
3633
0
  }
3634
0
  return lp_ctx->iconv_handle;
3635
0
}
3636
3637
_PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx)
3638
0
{
3639
0
  if (!lp_ctx->global) {
3640
0
    return;
3641
0
  }
3642
3643
0
  lp_ctx->iconv_handle =
3644
0
    reinit_iconv_handle(lp_ctx,
3645
0
            lpcfg_dos_charset(lp_ctx),
3646
0
            lpcfg_unix_charset(lp_ctx));
3647
0
  if (lp_ctx->iconv_handle == NULL) {
3648
0
    smb_panic("reinit_iconv_handle failed");
3649
0
  }
3650
0
}
3651
3652
_PUBLIC_ char *lpcfg_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
3653
0
{
3654
0
  return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_keyfile(lp_ctx));
3655
0
}
3656
3657
_PUBLIC_ char *lpcfg_tls_certfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
3658
0
{
3659
0
  return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_certfile(lp_ctx));
3660
0
}
3661
3662
_PUBLIC_ char *lpcfg_tls_cafile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
3663
0
{
3664
0
  return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_cafile(lp_ctx));
3665
0
}
3666
3667
_PUBLIC_ char *lpcfg_tls_crlfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
3668
0
{
3669
0
  return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_crlfile(lp_ctx));
3670
0
}
3671
3672
_PUBLIC_ char *lpcfg_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
3673
0
{
3674
0
  return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_dhpfile(lp_ctx));
3675
0
}
3676
3677
struct gensec_settings *lpcfg_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
3678
0
{
3679
0
  struct gensec_settings *settings = talloc_zero(mem_ctx, struct gensec_settings);
3680
0
  if (settings == NULL)
3681
0
    return NULL;
3682
0
  SMB_ASSERT(lp_ctx != NULL);
3683
0
  settings->lp_ctx = talloc_reference(settings, lp_ctx);
3684
0
  settings->target_hostname = lpcfg_parm_string(lp_ctx, NULL, "gensec", "target_hostname");
3685
0
  return settings;
3686
0
}
3687
3688
int lpcfg_server_role(struct loadparm_context *lp_ctx)
3689
0
{
3690
0
  int domain_master = lpcfg__domain_master(lp_ctx);
3691
3692
0
  return lp_find_server_role(lpcfg__server_role(lp_ctx),
3693
0
           lpcfg__security(lp_ctx),
3694
0
           lpcfg__domain_logons(lp_ctx),
3695
0
           (domain_master == true) ||
3696
0
           (domain_master == Auto));
3697
0
}
3698
3699
int lpcfg_security(struct loadparm_context *lp_ctx)
3700
0
{
3701
0
  return lp_find_security(lpcfg__server_role(lp_ctx),
3702
0
        lpcfg__security(lp_ctx));
3703
0
}
3704
3705
int lpcfg_client_max_protocol(struct loadparm_context *lp_ctx)
3706
0
{
3707
0
  int client_max_protocol = lpcfg__client_max_protocol(lp_ctx);
3708
0
  if (client_max_protocol == PROTOCOL_DEFAULT) {
3709
0
    return PROTOCOL_LATEST;
3710
0
  }
3711
0
  return client_max_protocol;
3712
0
}
3713
3714
int lpcfg_client_ipc_min_protocol(struct loadparm_context *lp_ctx)
3715
0
{
3716
0
  int client_ipc_min_protocol = lpcfg__client_ipc_min_protocol(lp_ctx);
3717
0
  if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
3718
0
    client_ipc_min_protocol = lpcfg_client_min_protocol(lp_ctx);
3719
0
  }
3720
0
  if (client_ipc_min_protocol < PROTOCOL_NT1) {
3721
0
    return PROTOCOL_NT1;
3722
0
  }
3723
0
  return client_ipc_min_protocol;
3724
0
}
3725
3726
int lpcfg_client_ipc_max_protocol(struct loadparm_context *lp_ctx)
3727
0
{
3728
0
  int client_ipc_max_protocol = lpcfg__client_ipc_max_protocol(lp_ctx);
3729
0
  if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
3730
0
    return PROTOCOL_LATEST;
3731
0
  }
3732
0
  if (client_ipc_max_protocol < PROTOCOL_NT1) {
3733
0
    return PROTOCOL_NT1;
3734
0
  }
3735
0
  return client_ipc_max_protocol;
3736
0
}
3737
3738
int lpcfg_client_ipc_signing(struct loadparm_context *lp_ctx)
3739
0
{
3740
0
  int client_ipc_signing = lpcfg__client_ipc_signing(lp_ctx);
3741
0
  if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
3742
0
    return SMB_SIGNING_REQUIRED;
3743
0
  }
3744
0
  return client_ipc_signing;
3745
0
}
3746
3747
enum credentials_use_kerberos lpcfg_client_use_kerberos(struct loadparm_context *lp_ctx)
3748
0
{
3749
0
  if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED) {
3750
0
    return CRED_USE_KERBEROS_REQUIRED;
3751
0
  }
3752
3753
0
  return lpcfg__client_use_kerberos(lp_ctx);
3754
0
}
3755
3756
bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory)
3757
0
{
3758
0
  bool allowed = true;
3759
0
  enum smb_signing_setting signing_setting = lpcfg_server_signing(lp_ctx);
3760
3761
0
  *mandatory = false;
3762
3763
0
  if (signing_setting == SMB_SIGNING_DEFAULT) {
3764
    /*
3765
     * If we are a domain controller, SMB signing is
3766
     * really important, as it can prevent a number of
3767
     * attacks on communications between us and the
3768
     * clients
3769
     *
3770
     * However, it really sucks (no sendfile, CPU
3771
     * overhead) performance-wise when used on a
3772
     * file server, so disable it by default
3773
     * on non-DCs
3774
     */
3775
3776
0
    if (lpcfg_server_role(lp_ctx) >= ROLE_ACTIVE_DIRECTORY_DC) {
3777
0
      signing_setting = SMB_SIGNING_REQUIRED;
3778
0
    } else {
3779
0
      signing_setting = SMB_SIGNING_OFF;
3780
0
    }
3781
0
  }
3782
3783
0
  switch (signing_setting) {
3784
0
  case SMB_SIGNING_REQUIRED:
3785
0
    *mandatory = true;
3786
0
    break;
3787
0
  case SMB_SIGNING_DESIRED:
3788
0
  case SMB_SIGNING_IF_REQUIRED:
3789
0
    break;
3790
0
  case SMB_SIGNING_OFF:
3791
0
    allowed = false;
3792
0
    break;
3793
0
  case SMB_SIGNING_DEFAULT:
3794
0
  case SMB_SIGNING_IPC_DEFAULT:
3795
0
    smb_panic(__location__);
3796
0
    break;
3797
0
  }
3798
3799
0
  return allowed;
3800
0
}
3801
3802
int lpcfg_client_use_krb5_netlogon(struct loadparm_context *lp_ctx)
3803
0
{
3804
0
  int val = lpcfg__client_use_krb5_netlogon(lp_ctx);
3805
3806
0
  if (val == LP_ENUM_Default) {
3807
0
    val = false;
3808
0
  }
3809
3810
0
  return val;
3811
0
}
3812
3813
int lpcfg_tdb_hash_size(struct loadparm_context *lp_ctx, const char *name)
3814
0
{
3815
0
  const char *base;
3816
3817
0
  if (name == NULL) {
3818
0
    return 0;
3819
0
  }
3820
3821
0
  base = strrchr_m(name, '/');
3822
0
  if (base != NULL) {
3823
0
    base += 1;
3824
0
  } else {
3825
0
    base = name;
3826
0
  }
3827
0
  return lpcfg_parm_int(lp_ctx, NULL, "tdb_hashsize", base, 0);
3828
3829
0
}
3830
3831
int lpcfg_tdb_flags(struct loadparm_context *lp_ctx, int tdb_flags)
3832
0
{
3833
0
  if (!lpcfg_use_mmap(lp_ctx)) {
3834
0
    tdb_flags |= TDB_NOMMAP;
3835
0
  }
3836
0
  return tdb_flags;
3837
0
}
3838
3839
/*
3840
 * Do not allow LanMan auth if unless NTLMv1 is also allowed
3841
 *
3842
 * This also ensures it is disabled if NTLM is totally disabled
3843
 */
3844
bool lpcfg_lanman_auth(struct loadparm_context *lp_ctx)
3845
0
{
3846
0
  enum ntlm_auth_level ntlm_auth_level = lpcfg_ntlm_auth(lp_ctx);
3847
3848
0
  if (ntlm_auth_level == NTLM_AUTH_ON) {
3849
0
    return lpcfg__lanman_auth(lp_ctx);
3850
0
  } else {
3851
0
    return false;
3852
0
  }
3853
0
}
3854
3855
static char *lpcfg_noop_substitution_fn(
3856
      TALLOC_CTX *mem_ctx,
3857
      const struct loadparm_substitution *lp_sub,
3858
      const char *raw_value,
3859
      void *private_data)
3860
0
{
3861
0
  return talloc_strdup(mem_ctx, raw_value);
3862
0
}
3863
3864
static const struct loadparm_substitution global_noop_substitution = {
3865
  .substituted_string_fn = lpcfg_noop_substitution_fn,
3866
};
3867
3868
const struct loadparm_substitution *lpcfg_noop_substitution(void)
3869
0
{
3870
0
  return &global_noop_substitution;
3871
0
}
3872
3873
char *lpcfg_substituted_string(TALLOC_CTX *mem_ctx,
3874
             const struct loadparm_substitution *lp_sub,
3875
             const char *raw_value)
3876
0
{
3877
0
  return lp_sub->substituted_string_fn(mem_ctx,
3878
0
               lp_sub,
3879
0
               raw_value,
3880
0
               lp_sub->private_data);
3881
0
}
3882
3883
/**
3884
 * @brief Parse a string value of a given parameter to its integer enum value.
3885
 *
3886
 * @param[in]  param_name    The parameter name (e.g. 'client smb encrypt')
3887
 *
3888
 * @param[in]  param_value   The parameter value (e.g. 'required').
3889
 *
3890
 * @return The integer value of the enum the param_value matches or INT32_MIN
3891
 * on error.
3892
 */
3893
int32_t lpcfg_parse_enum_vals(const char *param_name,
3894
            const char *param_value)
3895
0
{
3896
0
  struct parm_struct *parm = NULL;
3897
0
  int32_t ret = INT32_MIN;
3898
0
  bool ok;
3899
3900
0
  parm = lpcfg_parm_struct(NULL, param_name);
3901
0
  if (parm == NULL) {
3902
0
    return INT32_MIN;
3903
0
  }
3904
3905
0
  ok = lp_set_enum_parm(parm, param_value, &ret);
3906
0
  if (!ok) {
3907
0
    return INT32_MIN;
3908
0
  }
3909
3910
0
  return ret;
3911
0
}
3912
3913
const char *lpcfg_dns_hostname(struct loadparm_context *lp_ctx)
3914
0
{
3915
0
  const char *dns_hostname = lpcfg__dns_hostname(lp_ctx);
3916
0
  const char *dns_domain = lpcfg_dnsdomain(lp_ctx);
3917
0
  char *netbios_name = NULL;
3918
0
  char *hostname = NULL;
3919
3920
0
  if (dns_hostname != NULL && dns_hostname[0] != '\0') {
3921
0
    return dns_hostname;
3922
0
  }
3923
3924
0
  netbios_name = strlower_talloc(lp_ctx, lpcfg_netbios_name(lp_ctx));
3925
0
  if (netbios_name == NULL) {
3926
0
    return NULL;
3927
0
  }
3928
3929
  /* If it isn't set, try to initialize with [netbios name].[realm] */
3930
0
  if (dns_domain != NULL && dns_domain[0] != '\0') {
3931
0
    hostname = talloc_asprintf(lp_ctx,
3932
0
             "%s.%s",
3933
0
             netbios_name,
3934
0
             dns_domain);
3935
0
  } else {
3936
0
    hostname = talloc_strdup(lp_ctx, netbios_name);
3937
0
  }
3938
0
  TALLOC_FREE(netbios_name);
3939
0
  if (hostname == NULL) {
3940
0
    return NULL;
3941
0
  }
3942
3943
0
  lpcfg_string_set(lp_ctx->globals->ctx,
3944
0
       &lp_ctx->globals->_dns_hostname,
3945
0
       hostname);
3946
3947
0
  return hostname;
3948
0
}