X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source3%2Fparam%2Floadparm.c;h=14c3c5e0515b8d3cb00f37eca286209a30c21d27;hp=f36262a7a8b6f4fa68c1b9d22e5595f2abc3ad8a;hb=0cd2acef79ec0da2a2181554a0d2e4886b83b084;hpb=8489543e6661152437b52bbcebdc7088e2bfedf1 diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index f36262a7a8b..14c3c5e0515 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -75,10 +75,6 @@ #include #endif -#ifdef HAVE_HTTPCONNECTENCRYPT -#include -#endif - bool bLoaded = false; extern userdom_struct current_user_info; @@ -97,8 +93,11 @@ static struct smbconf_csn conf_last_csn; static int config_backend = CONFIG_BACKEND_FILE; /* some helpful bits */ -#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid) -#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid) +#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \ + (ServicePtrs != NULL) && \ + (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid) +#define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \ + ServicePtrs[i]->valid) #define USERSHARE_VALID 1 #define USERSHARE_PENDING_DELETE 2 @@ -122,8 +121,8 @@ static struct loadparm_service sDefault = .invalid_users = NULL, .valid_users = NULL, .admin_users = NULL, - .szCopy = NULL, - .szInclude = NULL, + .copy = NULL, + .include = NULL, .preexec = NULL, .postexec = NULL, .root_preexec = NULL, @@ -158,7 +157,7 @@ static struct loadparm_service sDefault = .aio_write_behind = NULL, .dfree_command = NULL, .min_print_space = 0, - .iMaxPrintJobs = 1000, + .max_print_jobs = 1000, .max_reported_print_jobs = 0, .write_cache_size = 0, .create_mask = 0744, @@ -183,8 +182,9 @@ static struct loadparm_service sDefault = .hide_unwriteable_files = false, .browseable = true, .access_based_share_enum = false, - .bAvailable = true, + .available = true, .read_only = true, + .spotlight = false, .guest_only = false, .administrative_share = false, .guest_ok = false, @@ -203,7 +203,7 @@ static struct loadparm_service sDefault = .level2_oplocks = true, .only_user = false, .mangled_names = true, - .bWidelinks = false, + .wide_links = false, .follow_symlinks = true, .sync_always = false, .strict_allocate = false, @@ -238,8 +238,6 @@ static struct loadparm_service sDefault = .acl_map_full_control = true, .acl_group_control = false, .acl_allow_execute_always = false, - .change_notify = true, - .kernel_change_notify = true, .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE, .aio_read_size = 0, .aio_write_size = 0, @@ -267,44 +265,6 @@ static void set_allowed_client_auth(void); static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue); static void free_param_opts(struct parmlist_entry **popts); -/* this is used to prevent lots of mallocs of size 1 */ -static const char null_string[] = ""; - -/** - Free a string value. -**/ - -static void string_free(char **s) -{ - if (!s || !(*s)) - return; - if (*s == null_string) - *s = NULL; - TALLOC_FREE(*s); -} - -/** - Set a string value, deallocating any existing space, and allocing the space - for the string -**/ - -static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src) -{ - string_free(dest); - - if (!src) { - src = ""; - } - - (*dest) = talloc_strdup(mem_ctx, src); - if ((*dest) == NULL) { - DEBUG(0,("Out of memory in string_init\n")); - return false; - } - - return true; -} - /** * Function to return the default value for the maximum number of open * file descriptors permitted. This function tries to consult the @@ -368,7 +328,7 @@ static void free_one_parameter_common(void *parm_ptr, if ((parm.type == P_STRING) || (parm.type == P_USTRING)) { - string_free((char**)parm_ptr); + lpcfg_string_free((char**)parm_ptr); } else if (parm.type == P_LIST || parm.type == P_CMDLIST) { TALLOC_FREE(*((char***)parm_ptr)); } @@ -442,8 +402,25 @@ static void free_parameters_by_snum(int snum) */ static void free_global_parameters(void) { + uint32_t i; + struct parm_struct *parm; + free_param_opts(&Globals.param_opt); free_parameters_by_snum(GLOBAL_SECTION_SNUM); + + /* Reset references in the defaults because the context is going to be freed */ + for (i=0; parm_table[i].label; i++) { + parm = &parm_table[i]; + if ((parm->type == P_STRING) || + (parm->type == P_USTRING)) { + if ((parm->def.svalue != NULL) && + (*(parm->def.svalue) != '\0')) { + if (talloc_parent(parm->def.svalue) == Globals.ctx) { + parm->def.svalue = NULL; + } + } + } + } TALLOC_FREE(Globals.ctx); } @@ -489,7 +466,7 @@ bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue) return false; } - DLIST_ADD_END(stored_options, entry, struct lp_stored_option); + DLIST_ADD_END(stored_options, entry); return true; } @@ -525,10 +502,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) if (!done_init) { /* The logfile can be set before this is invoked. Free it if so. */ - if (Globals.logfile != NULL) { - string_free(&Globals.logfile); - Globals.logfile = NULL; - } + lpcfg_string_free(&Globals.logfile); done_init = true; } else { free_global_parameters(); @@ -551,13 +525,16 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) if ((parm_table[i].type == P_STRING || parm_table[i].type == P_USTRING)) { - string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), ""); + lpcfg_string_set( + Globals.ctx, + (char **)lp_parm_ptr(NULL, &parm_table[i]), + ""); } } - string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING); - string_set(Globals.ctx, &sDefault.printjob_username, "%U"); + lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING); + lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U"); init_printer_values(lp_ctx, Globals.ctx, &sDefault); @@ -566,36 +543,47 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) DEBUG(3, ("Initialising global parameters\n")); /* Must manually force to upper case here, as this does not go via the handler */ - string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper()); + lpcfg_string_set(Globals.ctx, &Globals.netbios_name, + myhostname_upper()); - string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE()); - string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR()); + lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file, + get_dyn_SMB_PASSWD_FILE()); + lpcfg_string_set(Globals.ctx, &Globals.private_dir, + get_dyn_PRIVATE_DIR()); /* use the new 'hash2' method by default, with a prefix of 1 */ - string_set(Globals.ctx, &Globals.mangling_method, "hash2"); + lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2"); Globals.mangle_prefix = 1; - string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT); + lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT); /* using UTF8 by default allows us to support all chars */ - string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET); + lpcfg_string_set(Globals.ctx, &Globals.unix_charset, + DEFAULT_UNIX_CHARSET); /* Use codepage 850 as a default for the dos character set */ - string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET); + lpcfg_string_set(Globals.ctx, &Globals.dos_charset, + DEFAULT_DOS_CHARSET); /* * Allow the default PASSWD_CHAT to be overridden in local.h. */ - string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT); - - string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP); - - string_set(Globals.ctx, &Globals.passwd_program, ""); - string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR()); - string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR()); - string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR()); - string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR()); - string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0"); + lpcfg_string_set(Globals.ctx, &Globals.passwd_chat, + DEFAULT_PASSWD_CHAT); + + lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP); + + lpcfg_string_set(Globals.ctx, &Globals.passwd_program, ""); + lpcfg_string_set(Globals.ctx, &Globals.lock_directory, + get_dyn_LOCKDIR()); + lpcfg_string_set(Globals.ctx, &Globals.state_directory, + get_dyn_STATEDIR()); + lpcfg_string_set(Globals.ctx, &Globals.cache_directory, + get_dyn_CACHEDIR()); + lpcfg_string_set(Globals.ctx, &Globals.pid_directory, + get_dyn_PIDDIR()); + lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address, + "0.0.0.0"); /* * By default support explicit binding to broadcast * addresses. @@ -606,21 +594,24 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) if (s == NULL) { smb_panic("init_globals: ENOMEM"); } - string_set(Globals.ctx, &Globals.server_string, s); + lpcfg_string_set(Globals.ctx, &Globals.server_string, s); TALLOC_FREE(s); #ifdef DEVELOPER - string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999"); + lpcfg_string_set(Globals.ctx, &Globals.panic_action, + "/bin/sleep 999999999"); #endif - string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS); + lpcfg_string_set(Globals.ctx, &Globals.socket_options, + DEFAULT_SOCKET_OPTIONS); - string_set(Globals.ctx, &Globals.logon_drive, ""); + lpcfg_string_set(Globals.ctx, &Globals.logon_drive, ""); /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */ - string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U"); - string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile"); + lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U"); + lpcfg_string_set(Globals.ctx, &Globals.logon_path, + "\\\\%N\\%U\\profile"); Globals.name_resolve_order = str_list_make_v3_const(NULL, "lmhosts wins host bcast", NULL); - string_set(Globals.ctx, &Globals.password_server, "*"); + lpcfg_string_set(Globals.ctx, &Globals.password_server, "*"); Globals.algorithmic_rid_base = BASE_RID; @@ -643,7 +634,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.large_readwrite = true; Globals.max_log_size = 5000; Globals.max_open_files = max_open_files(); - Globals.server_max_protocol = PROTOCOL_SMB3_00; + Globals.server_max_protocol = PROTOCOL_SMB3_11; Globals.server_min_protocol = PROTOCOL_LANMAN1; Globals._client_max_protocol = PROTOCOL_DEFAULT; Globals.client_min_protocol = PROTOCOL_CORE; @@ -661,7 +652,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.syslog = 1; Globals.syslog_only = false; Globals.timestamp_logs = true; - string_set(Globals.ctx, &Globals.log_level, "0"); + lpcfg_string_set(Globals.ctx, &Globals.log_level, "0"); Globals.debug_prefix_timestamp = false; Globals.debug_hires_timestamp = true; Globals.debug_pid = false; @@ -677,9 +668,10 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) Globals.nis_homedir = false; #ifdef WITH_NISPLUS_HOME - string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir"); + lpcfg_string_set(Globals.ctx, &Globals.homedir_map, + "auto_home.org_dir"); #else - string_set(Globals.ctx, &Globals.homedir_map, "auto.home"); + lpcfg_string_set(Globals.ctx, &Globals.homedir_map, "auto.home"); #endif #endif Globals.time_server = false; @@ -698,6 +690,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */ Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */ Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */ + Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */ Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */ /* Note, that we will also use NTLM2 session security (which is different), if it is available */ @@ -715,20 +708,23 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.reset_on_zero_vc = false; Globals.log_writeable_files_on_exit = false; Globals.create_krb5_conf = true; - Globals.winbindMaxDomainConnections = 1; + Globals._winbind_max_domain_connections = 1; /* hostname lookups can be very expensive and are broken on a large number of sites (tridge) */ Globals.hostname_lookups = false; - string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam"); - string_set(Globals.ctx, &Globals.ldap_suffix, ""); - string_set(Globals.ctx, &Globals.szLdapMachineSuffix, ""); - string_set(Globals.ctx, &Globals.szLdapUserSuffix, ""); - string_set(Globals.ctx, &Globals.szLdapGroupSuffix, ""); - string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, ""); + Globals.change_notify = true, + Globals.kernel_change_notify = true, - string_set(Globals.ctx, &Globals.ldap_admin_dn, ""); + lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam"); + lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, ""); + lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, ""); + lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, ""); + lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, ""); + lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, ""); + + lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, ""); Globals.ldap_ssl = LDAP_SSL_START_TLS; Globals.ldap_ssl_ads = false; Globals.ldap_deref = -1; @@ -745,6 +741,9 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN; + Globals.ldap_server_require_strong_auth = + LDAP_SERVER_REQUIRE_STRONG_AUTH_NO; + /* This is what we tell the afs client. in reality we set the token * to never expire, though, when this runs out the afs client will * forget the token. Set to 0 to get NEVERDATE.*/ @@ -778,17 +777,19 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.wins_dns_proxy = true; Globals.allow_trusted_domains = true; - string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb"); + lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb"); - string_set(Globals.ctx, &Globals.template_shell, "/bin/false"); - string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U"); - string_set(Globals.ctx, &Globals.winbind_separator, "\\"); - string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR); + lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false"); + lpcfg_string_set(Globals.ctx, &Globals.template_homedir, + "/home/%D/%U"); + lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\"); + lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory, + dyn_WINBINDD_SOCKET_DIR); - string_set(Globals.ctx, &Globals.cups_server, ""); - string_set(Globals.ctx, &Globals.iprint_server, ""); + lpcfg_string_set(Globals.ctx, &Globals.cups_server, ""); + lpcfg_string_set(Globals.ctx, &Globals.iprint_server, ""); - string_set(Globals.ctx, &Globals._ctdbd_socket, ""); + lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, ""); Globals.cluster_addresses = NULL; Globals.clustering = false; @@ -834,9 +835,9 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) if (s == NULL) { smb_panic("init_globals: ENOMEM"); } - string_set(Globals.ctx, &Globals.usershare_path, s); + lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s); TALLOC_FREE(s); - string_set(Globals.ctx, &Globals.usershare_template_share, ""); + lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, ""); Globals.usershare_max_shares = 0; /* By default disallow sharing of directories not owned by the sharer. */ Globals.usershare_owner_only = true; @@ -848,7 +849,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) /* By default no shares out of the registry */ Globals.registry_shares = false; - Globals.iminreceivefile = 0; + Globals.min_receivefile_size = 0; Globals.map_untrusted_to_domain = false; Globals.multicast_dns_register = true; @@ -856,10 +857,11 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ; Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE; Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT; - Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS; + Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS; Globals.smb2_leases = false; - string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR()); + lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir, + get_dyn_NCALRPCDIR()); Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL); @@ -867,19 +869,24 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.tls_enabled = true; - string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem"); - string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem"); - string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem"); + lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem"); + lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem"); + lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem"); + lpcfg_string_set(Globals.ctx, &Globals.tls_priority, + "NORMAL:-VERS-SSL3.0"); - string_set(Globals.ctx, &Globals.share_backend, "classic"); + lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic"); - Globals.iPreferredMaster = Auto; + Globals._preferred_master = Auto; Globals.allow_dns_updates = DNS_UPDATE_SIGNED; - string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR()); + lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, + get_dyn_NTP_SIGND_SOCKET_DIR()); - string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR()); + lpcfg_string_set(Globals.ctx, + &Globals.winbindd_privileged_socket_directory, + get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR()); s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR()); if (s == NULL) { @@ -918,6 +925,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.web_port = 901; + Globals.aio_max_threads = 100; + /* Now put back the settings that were set with lp_set_cmdline() */ apply_lp_set_cmdline(); } @@ -1016,44 +1025,15 @@ char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK #define FN_LOCAL_PARM_CHAR(fn_name,val) \ char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);} -static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int, - winbindMaxDomainConnections) - int lp_winbind_max_domain_connections(void) { if (lp_winbind_offline_logon() && - lp_winbind_max_domain_connections_int() > 1) { + lp__winbind_max_domain_connections() > 1) { DEBUG(1, ("offline logons active, restricting max domain " "connections to 1\n")); return 1; } - return MAX(1, lp_winbind_max_domain_connections_int()); -} - -int lp_smb2_max_credits(void) -{ - if (Globals.ismb2_max_credits == 0) { - Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS; - } - return Globals.ismb2_max_credits; -} -int lp_cups_encrypt(void) -{ - int result = 0; -#ifdef HAVE_HTTPCONNECTENCRYPT - switch (Globals.CupsEncrypt) { - case Auto: - result = HTTP_ENCRYPT_REQUIRED; - break; - case true: - result = HTTP_ENCRYPT_ALWAYS; - break; - case false: - result = HTTP_ENCRYPT_NEVER; - break; - } -#endif - return result; + return MAX(1, lp__winbind_max_domain_connections()); } /* These functions remain in source3/param for now */ @@ -1096,6 +1076,79 @@ static struct parmlist_entry *get_parametrics(int snum, const char *type, } } +static void discard_whitespace(char *str) +{ + size_t len = strlen(str); + size_t i = 0; + + while (i < len) { + if (isspace(str[i])) { + memmove(&str[i], &str[i+1], len-i); + len -= 1; + continue; + } + i += 1; + } +} + +/** + * @brief Go through all global parametric parameters + * + * @param regex_str A regular expression to scan param for + * @param max_matches Max number of submatches the regexp expects + * @param cb Function to call on match. Should return true + * when it wants wi_scan_global_parametrics to stop + * scanning + * @param private_data Anonymous pointer passed to cb + * + * @return 0: success, regcomp/regexec return value on error. + * See "man regexec" for possible errors + */ + +int lp_wi_scan_global_parametrics( + const char *regex_str, size_t max_matches, + bool (*cb)(const char *string, regmatch_t matches[], + void *private_data), + void *private_data) +{ + struct parmlist_entry *data; + regex_t regex; + int ret; + + ret = regcomp(®ex, regex_str, REG_ICASE); + if (ret != 0) { + return ret; + } + + for (data = Globals.param_opt; data != NULL; data = data->next) { + size_t keylen = strlen(data->key); + char key[keylen+1]; + regmatch_t matches[max_matches]; + bool stop; + + memcpy(key, data->key, sizeof(key)); + discard_whitespace(key); + + ret = regexec(®ex, key, max_matches, matches, 0); + if (ret == REG_NOMATCH) { + continue; + } + if (ret != 0) { + goto fail; + } + + stop = cb(key, matches, private_data); + if (stop) { + break; + } + } + + ret = 0; +fail: + regfree(®ex); + return ret; +} + #define MISSING_PARAMETER(name) \ DEBUG(0, ("%s(): value is NULL or empty!\n", #name)) @@ -1199,6 +1252,22 @@ unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsi /* Return parametric option from a given service. Type is a part of option before ':' */ /* Parametric option has following syntax: 'Type: option = value' */ +unsigned long long lp_parm_ulonglong(int snum, const char *type, + const char *option, unsigned long long def) +{ + struct parmlist_entry *data = get_parametrics(snum, type, option); + + if (data && data->value && *data->value) { + return lp_ulonglong(data->value); + } + + return def; +} + +/* Return parametric option from a given service. Type is a part of option + * before ':' */ +/* Parametric option has following syntax: 'Type: option = value' */ + bool lp_parm_bool(int snum, const char *type, const char *option, bool def) { struct parmlist_entry *data = get_parametrics(snum, type, option); @@ -1238,8 +1307,8 @@ static void free_param_opts(struct parmlist_entry **popts) } opt = *popts; while (opt != NULL) { - string_free(&opt->key); - string_free(&opt->value); + lpcfg_string_free(&opt->key); + lpcfg_string_free(&opt->value); TALLOC_FREE(opt->list); next_opt = opt->next; TALLOC_FREE(opt); @@ -1263,7 +1332,7 @@ static void free_service(struct loadparm_service *pservice) free_parameters(pservice); - string_free(&pservice->szService); + lpcfg_string_free(&pservice->szService); TALLOC_FREE(pservice->copymap); free_param_opts(&pservice->param_opt); @@ -1296,7 +1365,7 @@ static void free_service_byindex(int idx) } free_service(ServicePtrs[idx]); - talloc_free_children(ServicePtrs[idx]); + TALLOC_FREE(ServicePtrs[idx]); } /*************************************************************************** @@ -1307,7 +1376,6 @@ static void free_service_byindex(int idx) static int add_a_service(const struct loadparm_service *pservice, const char *name) { int i; - int num_to_alloc = iNumServices + 1; struct loadparm_service **tsp = NULL; /* it might already exist */ @@ -1318,26 +1386,37 @@ static int add_a_service(const struct loadparm_service *pservice, const char *na } } - /* if not, then create one */ - i = iNumServices; - tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc); - if (tsp == NULL) { - DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n")); - return (-1); + /* Re use empty slots if any before allocating new one.*/ + for (i=0; i < iNumServices; i++) { + if (ServicePtrs[i] == NULL) { + break; + } + } + if (i == iNumServices) { + /* if not, then create one */ + tsp = talloc_realloc(NULL, ServicePtrs, + struct loadparm_service *, + iNumServices + 1); + if (tsp == NULL) { + DEBUG(0, ("add_a_service: failed to enlarge " + "ServicePtrs!\n")); + return (-1); + } + ServicePtrs = tsp; + iNumServices++; } - ServicePtrs = tsp; - ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service); - if (!ServicePtrs[iNumServices]) { + ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service); + if (!ServicePtrs[i]) { DEBUG(0,("add_a_service: out of memory!\n")); return (-1); } - iNumServices++; ServicePtrs[i]->valid = true; copy_service(ServicePtrs[i], pservice, NULL); if (name) - string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService, + name); DEBUG(8,("add_a_service: Creating snum = %d for %s\n", i, ServicePtrs[i]->szService)); @@ -1426,7 +1505,8 @@ bool lp_add_home(const char *pszHomename, int iDefaultService, if (!(*(ServicePtrs[iDefaultService]->path)) || strequal(ServicePtrs[iDefaultService]->path, lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) { - string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, + pszHomedir); } if (!(*(ServicePtrs[i]->comment))) { @@ -1434,7 +1514,8 @@ bool lp_add_home(const char *pszHomename, int iDefaultService, if (comment == NULL) { return false; } - string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, + comment); TALLOC_FREE(comment); } @@ -1482,18 +1563,19 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok) return false; } - string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir()); - string_set(ServicePtrs[i], &ServicePtrs[i]->username, ""); - string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment); - string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC"); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir()); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->username, ""); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC"); ServicePtrs[i]->max_connections = 0; - ServicePtrs[i]->bAvailable = true; + ServicePtrs[i]->available = true; ServicePtrs[i]->read_only = true; ServicePtrs[i]->guest_only = false; ServicePtrs[i]->administrative_share = true; ServicePtrs[i]->guest_ok = guest_ok; ServicePtrs[i]->printable = false; ServicePtrs[i]->browseable = sDefault.browseable; + ServicePtrs[i]->autoloaded = true; DEBUG(3, ("adding IPC service\n")); @@ -1519,8 +1601,9 @@ bool lp_add_printer(const char *pszPrintername, int iDefaultService) /* entry (if/when the 'available' keyword is implemented!). */ /* the printer name is set to the service name. */ - string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername); - string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, + pszPrintername); + lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment); /* set the browseable flag from the gloabl default */ ServicePtrs[i]->browseable = sDefault.browseable; @@ -1652,7 +1735,7 @@ static int map_parameter_canonical(const char *pszParmName, bool *inverse) bool loc_inverse = false; parm_num = lpcfg_map_parameter(pszParmName); - if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) { + if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) { /* invalid, parametric or no canidate for synonyms ... */ goto done; } @@ -1682,8 +1765,8 @@ static bool is_synonym_of(int parm1, int parm2, bool *inverse) { if ((parm_table[parm1].offset == parm_table[parm2].offset) && (parm_table[parm1].p_class == parm_table[parm2].p_class) && - (parm_table[parm1].flags & FLAG_HIDE) && - !(parm_table[parm2].flags & FLAG_HIDE)) + (parm_table[parm1].flags & FLAG_SYNONYM) && + !(parm_table[parm2].flags & FLAG_SYNONYM)) { if (inverse != NULL) { if ((parm_table[parm1].type == P_BOOLREV) && @@ -1713,13 +1796,9 @@ static void show_parameter(int parmIndex) bool inverse; const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER", "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", - "P_ENUM" }; - unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL, - FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED, - FLAG_HIDE}; - const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT", - "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER", - "FLAG_DEPRECATED", "FLAG_HIDE", NULL}; + "P_ENUM", "P_BYTES", "P_CMDLIST" }; + unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM }; + const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL}; printf("%s=%s", parm_table[parmIndex].label, type[parm_table[parmIndex].type]); @@ -2246,9 +2325,9 @@ bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *servic add_to_file_list(NULL, &file_lists, pszParmValue, fname); if (service == NULL) { - string_set(Globals.ctx, ptr, fname); + lpcfg_string_set(Globals.ctx, ptr, fname); } else { - string_set(service, ptr, fname); + lpcfg_string_set(service, ptr, fname); } if (file_exist(fname)) { @@ -2362,32 +2441,32 @@ static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str ) const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx) { - if (Globals.szLdapMachineSuffix[0]) - return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix); + if (Globals._ldap_machine_suffix[0]) + return append_ldap_suffix(ctx, Globals._ldap_machine_suffix); return lp_string(ctx, Globals.ldap_suffix); } const char *lp_ldap_user_suffix(TALLOC_CTX *ctx) { - if (Globals.szLdapUserSuffix[0]) - return append_ldap_suffix(ctx, Globals.szLdapUserSuffix); + if (Globals._ldap_user_suffix[0]) + return append_ldap_suffix(ctx, Globals._ldap_user_suffix); return lp_string(ctx, Globals.ldap_suffix); } const char *lp_ldap_group_suffix(TALLOC_CTX *ctx) { - if (Globals.szLdapGroupSuffix[0]) - return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix); + if (Globals._ldap_group_suffix[0]) + return append_ldap_suffix(ctx, Globals._ldap_group_suffix); return lp_string(ctx, Globals.ldap_suffix); } const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx) { - if (Globals.szLdapIdmapSuffix[0]) - return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix); + if (Globals._ldap_idmap_suffix[0]) + return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix); return lp_string(ctx, Globals.ldap_suffix); } @@ -2664,7 +2743,7 @@ static void dump_copy_map(bool *pcopymap) bool lp_snum_ok(int iService) { - return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable); + return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available); } /*************************************************************************** @@ -2719,7 +2798,8 @@ void lp_add_one_printer(const char *name, const char *comment, if (lp_servicenumber(name) < 0) { lp_add_printer(name, printers); if ((i = lp_servicenumber(name)) >= 0) { - string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment); + lpcfg_string_set(ServicePtrs[i], + &ServicePtrs[i]->comment, comment); ServicePtrs[i]->autoloaded = true; } } @@ -2803,9 +2883,13 @@ static void lp_save_defaults(void) break; case P_STRING: case P_USTRING: - parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i])); + lpcfg_string_set( + Globals.ctx, + &parm_table[i].def.svalue, + *(char **)lp_parm_ptr( + NULL, &parm_table[i])); if (parm_table[i].def.svalue == NULL) { - smb_panic("talloc_strdup failed"); + smb_panic("lpcfg_string_set() failed"); } break; case P_BOOL: @@ -3281,8 +3365,10 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i /* And note when it was loaded. */ ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime; - string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath); - string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment); + lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, + sharepath); + lpcfg_string_set(ServicePtrs[iService], + &ServicePtrs[iService]->comment, comment); ret = iService; @@ -3667,7 +3753,7 @@ static bool lp_load_ex(const char *pszFname, apply_lp_set_cmdline(); } - lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend); + lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend); /* We get sections first, so have to start 'behind' to make up */ iServiceIndex = -1; @@ -4102,10 +4188,12 @@ static bool lp_domain_master_true_or_auto(void) bool lp_preferred_master(void) { - if (Globals.iPreferredMaster == Auto) + int preferred_master = lp__preferred_master(); + + if (preferred_master == Auto) return (lp_local_master() && lp_domain_master()); - return (bool)Globals.iPreferredMaster; + return (bool)preferred_master; } /******************************************************************* @@ -4134,7 +4222,7 @@ const char *lp_printername(TALLOC_CTX *ctx, int snum) void lp_set_logfile(const char *name) { - string_set(Globals.ctx, &Globals.logfile, name); + lpcfg_string_set(Globals.ctx, &Globals.logfile, name); debug_set_logfile(name); } @@ -4144,7 +4232,8 @@ void lp_set_logfile(const char *name) int lp_maxprintjobs(int snum) { - int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs; + int maxjobs = lp_max_print_jobs(snum); + if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID) maxjobs = PRINT_MAX_JOBID - 1; @@ -4153,9 +4242,11 @@ int lp_maxprintjobs(int snum) const char *lp_printcapname(void) { - if ((Globals.szPrintcapname != NULL) && - (Globals.szPrintcapname[0] != '\0')) - return Globals.szPrintcapname; + const char *printcap_name = lp_printcap_name(); + + if ((printcap_name != NULL) && + (printcap_name[0] != '\0')) + return printcap_name; if (sDefault.printing == PRINT_CUPS) { return "cups"; @@ -4221,20 +4312,9 @@ void set_use_sendfile(int snum, bool val) sDefault._use_sendfile = val; } -/******************************************************************* - Turn off storing DOS attributes if this share doesn't support it. -********************************************************************/ - -void set_store_dos_attributes(int snum, bool val) -{ - if (!LP_SNUM_OK(snum)) - return; - ServicePtrs[(snum)]->store_dos_attributes = val; -} - void lp_set_mangling_method(const char *new_method) { - string_set(Globals.ctx, &Globals.mangling_method, new_method); + lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method); } /******************************************************************* @@ -4270,7 +4350,8 @@ enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp) if (posix_default_lock_was_set) { return posix_cifsx_locktype; } else { - return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK; + return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ? + POSIX_LOCK : WINDOWS_LOCK; } } @@ -4285,10 +4366,12 @@ void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val) int lp_min_receive_file_size(void) { - if (Globals.iminreceivefile < 0) { + int min_receivefile_size = lp_min_receivefile_size(); + + if (min_receivefile_size < 0) { return 0; } - return Globals.iminreceivefile; + return min_receivefile_size; } /******************************************************************* @@ -4297,19 +4380,13 @@ int lp_min_receive_file_size(void) even after a configuration file reload. ********************************************************************/ -static bool lp_widelinks_internal(int snum) -{ - return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks : - sDefault.bWidelinks); -} - void widelinks_warning(int snum) { if (lp_allow_insecure_wide_links()) { return; } - if (lp_unix_extensions() && lp_widelinks_internal(snum)) { + if (lp_unix_extensions() && lp_wide_links(snum)) { DEBUG(0,("Share '%s' has wide links and unix extensions enabled. " "These parameters are incompatible. " "Wide links will be disabled for this share.\n", @@ -4330,7 +4407,7 @@ bool lp_widelinks(int snum) } } - return lp_widelinks_internal(snum); + return lp_wide_links(snum); } int lp_server_role(void)