Forward port of Richard Sharpe's <realrichardsharpe@gmail.com> fix for bug #8970...
[ddiss/samba.git] / source3 / param / loadparm.c
index 3314ad26ca143bc1afffb94fd638f1e08cc7ef05..dd633399a05f9c0c45db340a489689404f185f9e 100644 (file)
  */
 
 #include "includes.h"
+#include "system/filesys.h"
+#include "util_tdb.h"
 #include "printing.h"
 #include "lib/smbconf/smbconf.h"
 #include "lib/smbconf/smbconf_init.h"
-#include "lib/smbconf/smbconf_reg.h"
 
 #include "ads.h"
 #include "../librpc/gen_ndr/svcctl.h"
@@ -378,6 +379,7 @@ struct global {
        bool bMapUntrustedToDomain;
        bool bAsyncSMBEchoHandler;
        bool bMulticastDnsRegister;
+       bool bAllowInsecureWidelinks;
        int ismb2_max_read;
        int ismb2_max_write;
        int ismb2_max_trans;
@@ -474,6 +476,7 @@ struct service {
        bool bAdministrative_share;
        bool bGuest_ok;
        bool bPrint_ok;
+       bool bPrintNotifyBackchannel;
        bool bMap_system;
        bool bMap_hidden;
        bool bMap_archive;
@@ -618,6 +621,7 @@ static struct service sDefault = {
        False,                  /* bAdministrative_share */
        False,                  /* bGuest_ok */
        False,                  /* bPrint_ok */
+       True,                   /* bPrintNotifyBackchannel */
        False,                  /* bMap_system */
        False,                  /* bMap_hidden */
        True,                   /* bMap_archive */
@@ -634,7 +638,7 @@ static struct service sDefault = {
        false,                  /* bWidelinks */
        True,                   /* bSymlinks */
        False,                  /* bSyncAlways */
-       True,                   /* bStrictAllocate */
+       False,                  /* bStrictAllocate */
        False,                  /* bStrictSync */
        '~',                    /* magic char */
        NULL,                   /* copymap */
@@ -697,6 +701,7 @@ static int default_server_announce;
 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
+static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr);
 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
@@ -704,6 +709,7 @@ static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
+static bool handle_dos_charset( int snum, const char *pszParmValue, char **ptr );
 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
 
@@ -951,7 +957,7 @@ static struct parm_struct parm_table[] = {
                .type           = P_STRING,
                .p_class        = P_GLOBAL,
                .ptr            = &Globals.dos_charset,
-               .special        = handle_charset,
+               .special        = handle_dos_charset,
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED
        },
@@ -1156,7 +1162,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &Globals.bNullPasswords,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
+               .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
        },
        {
                .label          = "obey pam restrictions",
@@ -1255,7 +1261,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &Globals.bEnablePrivileges,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
+               .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
        },
 
        {
@@ -1328,7 +1334,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &Globals.pwordlevel,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
+               .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
        },
        {
                .label          = "username level",
@@ -1427,7 +1433,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &sDefault.szUsername,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
+               .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
        },
        {
                .label          = "user",
@@ -2290,7 +2296,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &Globals.bUseSpnego,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
+               .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
        },
        {
                .label          = "client signing",
@@ -2712,6 +2718,15 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED | FLAG_PRINT,
        },
+       {
+               .label          = "print notify backchannel",
+               .type           = P_BOOL,
+               .p_class        = P_LOCAL,
+               .ptr            = &sDefault.bPrintNotifyBackchannel,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED,
+       },
        {
                .label          = "print ok",
                .type           = P_BOOL,
@@ -4132,7 +4147,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &extra_time_offset,
                .special        = NULL,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
+               .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
        },
        {
                .label          = "NIS homedir",
@@ -4341,6 +4356,15 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED | FLAG_SHARE,
        },
+       {
+               .label          = "allow insecure wide links",
+               .type           = P_BOOL,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.bAllowInsecureWidelinks,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED,
+       },
        {
                .label          = "wide links",
                .type           = P_BOOL,
@@ -4536,18 +4560,9 @@ static struct parm_struct parm_table[] = {
                .type           = P_STRING,
                .p_class        = P_GLOBAL,
                .ptr            = &Globals.szIdmapBackend,
-               .special        = NULL,
+               .special        = handle_idmap_backend,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
-       },
-       {
-               .label          = "idmap read only",
-               .type           = P_BOOL,
-               .p_class        = P_GLOBAL,
-               .ptr            = &Globals.bIdmapReadOnly,
-               .special        = NULL,
-               .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
+               .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
        },
        {
                .label          = "idmap cache time",
@@ -4574,7 +4589,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &Globals.szIdmapUID,
                .special        = handle_idmap_uid,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
+               .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
        },
        {
                .label          = "winbind uid",
@@ -4592,7 +4607,7 @@ static struct parm_struct parm_table[] = {
                .ptr            = &Globals.szIdmapGID,
                .special        = handle_idmap_gid,
                .enum_list      = NULL,
-               .flags          = FLAG_ADVANCED,
+               .flags          = FLAG_ADVANCED | FLAG_DEPRECATED,
        },
        {
                .label          = "winbind gid",
@@ -4860,15 +4875,62 @@ static void init_printer_values(struct service *pService)
 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
 
        case PRINT_TEST:
-       case PRINT_VLP:
-               string_set(&pService->szPrintcommand, "vlp print %p %s");
-               string_set(&pService->szLpqcommand, "vlp lpq %p");
-               string_set(&pService->szLprmcommand, "vlp lprm %p %j");
-               string_set(&pService->szLppausecommand, "vlp lppause %p %j");
-               string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
-               string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
-               string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
+       case PRINT_VLP: {
+               const char *tdbfile;
+               char *tmp;
+
+               tdbfile = talloc_asprintf(
+                       talloc_tos(), "tdbfile=%s",
+                       lp_parm_const_string(-1, "vlp", "tdbfile",
+                                            "/tmp/vlp.tdb"));
+               if (tdbfile == NULL) {
+                       tdbfile="tdbfile=/tmp/vlp.tdb";
+               }
+
+               tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
+                                     tdbfile);
+               string_set(&pService->szPrintcommand,
+                          tmp ? tmp : "vlp print %p %s");
+               TALLOC_FREE(tmp);
+
+               tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
+                                     tdbfile);
+               string_set(&pService->szLpqcommand,
+                          tmp ? tmp : "vlp lpq %p");
+               TALLOC_FREE(tmp);
+
+               tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
+                                     tdbfile);
+               string_set(&pService->szLprmcommand,
+                          tmp ? tmp : "vlp lprm %p %j");
+               TALLOC_FREE(tmp);
+
+               tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
+                                     tdbfile);
+               string_set(&pService->szLppausecommand,
+                          tmp ? tmp : "vlp lppause %p %j");
+               TALLOC_FREE(tmp);
+
+               tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
+                                     tdbfile);
+               string_set(&pService->szLpresumecommand,
+                          tmp ? tmp : "vlp lpresume %p %j");
+               TALLOC_FREE(tmp);
+
+               tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
+                                     tdbfile);
+               string_set(&pService->szQueuepausecommand,
+                          tmp ? tmp : "vlp queuepause %p");
+               TALLOC_FREE(tmp);
+
+               tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
+                                     tdbfile);
+               string_set(&pService->szQueueresumecommand,
+                          tmp ? tmp : "vlp queueresume %p");
+               TALLOC_FREE(tmp);
+
                break;
+       }
 #endif /* DEVELOPER */
 
        }
@@ -5513,9 +5575,9 @@ static char *lp_string(const char *s)
  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
 
 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
-FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
-FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
-FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
+FN_GLOBAL_CONST_STRING(lp_dos_charset, &Globals.dos_charset)
+FN_GLOBAL_CONST_STRING(lp_unix_charset, &Globals.unix_charset)
+FN_GLOBAL_CONST_STRING(lp_display_charset, &Globals.display_charset)
 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
@@ -5678,7 +5740,6 @@ int lp_winbind_max_domain_connections(void)
 }
 
 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
-FN_GLOBAL_BOOL(lp_idmap_read_only, &Globals.bIdmapReadOnly)
 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
@@ -5918,6 +5979,7 @@ FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
+FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
@@ -5944,6 +6006,7 @@ FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
 FN_GLOBAL_BOOL(lp_multicast_dns_register, &Globals.bMulticastDnsRegister)
+FN_GLOBAL_BOOL(lp_allow_insecure_widelinks, &Globals.bAllowInsecureWidelinks)
 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
@@ -7157,14 +7220,14 @@ bool service_ok(int iService)
 
 static struct smbconf_ctx *lp_smbconf_ctx(void)
 {
-       WERROR werr;
+       sbcErr err;
        static struct smbconf_ctx *conf_ctx = NULL;
 
        if (conf_ctx == NULL) {
-               werr = smbconf_init(NULL, &conf_ctx, "registry:");
-               if (!W_ERROR_IS_OK(werr)) {
+               err = smbconf_init(NULL, &conf_ctx, "registry:");
+               if (!SBC_ERROR_IS_OK(err)) {
                        DEBUG(1, ("error initializing registry configuration: "
-                                 "%s\n", win_errstr(werr)));
+                                 "%s\n", sbcErrorString(err)));
                        conf_ctx = NULL;
                }
        }
@@ -7204,7 +7267,7 @@ static bool process_smbconf_service(struct smbconf_service *service)
  */
 bool process_registry_service(const char *service_name)
 {
-       WERROR werr;
+       sbcErr err;
        struct smbconf_service *service = NULL;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
        struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
@@ -7225,8 +7288,8 @@ bool process_registry_service(const char *service_name)
                goto done;
        }
 
-       werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
-       if (!W_ERROR_IS_OK(werr)) {
+       err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
+       if (!SBC_ERROR_IS_OK(err)) {
                goto done;
        }
 
@@ -7262,7 +7325,7 @@ static bool process_registry_globals(void)
 
 bool process_registry_shares(void)
 {
-       WERROR werr;
+       sbcErr err;
        uint32_t count;
        struct smbconf_service **service = NULL;
        uint32_t num_shares = 0;
@@ -7274,8 +7337,8 @@ bool process_registry_shares(void)
                goto done;
        }
 
-       werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
-       if (!W_ERROR_IS_OK(werr)) {
+       err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
+       if (!SBC_ERROR_IS_OK(err)) {
                goto done;
        }
 
@@ -7299,6 +7362,35 @@ done:
        return ret;
 }
 
+/**
+ * reload those shares from registry that are already
+ * activated in the services array.
+ */
+static bool reload_registry_shares(void)
+{
+       int i;
+       bool ret = true;
+
+       for (i = 0; i < iNumServices; i++) {
+               if (!VALID(i)) {
+                       continue;
+               }
+
+               if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
+                       continue;
+               }
+
+               ret = process_registry_service(ServicePtrs[i]->szService);
+               if (!ret) {
+                       goto done;
+               }
+       }
+
+done:
+       return ret;
+}
+
+
 #define MAX_INCLUDE_DEPTH 100
 
 static uint8_t include_depth;
@@ -7480,6 +7572,43 @@ static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
        return True;
 }
 
+static bool handle_dos_charset(int snum, const char *pszParmValue, char **ptr)
+{
+       bool is_utf8 = false;
+       size_t len = strlen(pszParmValue);
+
+       if (len == 4 || len == 5) {
+               /* Don't use StrCaseCmp here as we don't want to
+                  initialize iconv. */
+               if ((toupper_m(pszParmValue[0]) == 'U') &&
+                   (toupper_m(pszParmValue[1]) == 'T') &&
+                   (toupper_m(pszParmValue[2]) == 'F')) {
+                       if (len == 4) {
+                               if (pszParmValue[3] == '8') {
+                                       is_utf8 = true;
+                               }
+                       } else {
+                               if (pszParmValue[3] == '-' &&
+                                   pszParmValue[4] == '8') {
+                                       is_utf8 = true;
+                               }
+                       }
+               }
+       }
+
+       if (strcmp(*ptr, pszParmValue) != 0) {
+               if (is_utf8) {
+                       DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
+                               "be UTF8, using (default value) %s instead.\n",
+                               DEFAULT_DOS_CHARSET));
+                       pszParmValue = DEFAULT_DOS_CHARSET;
+               }
+               string_set(ptr, pszParmValue);
+               init_iconv();
+       }
+       return True;
+}
+
 
 
 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
@@ -7653,38 +7782,25 @@ bool lp_idmap_gid(gid_t *low, gid_t *high)
         return True;
 }
 
-/* Do some simple checks on "idmap [ug]id" parameter values */
-
-static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
+static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr)
 {
-       uint32 low, high;
-
-       if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
-               return False;
+       lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
 
-       /* Parse OK */
+       return true;
+}
 
-       string_set(ptr, pszParmValue);
+/* Do some simple checks on "idmap [ug]id" parameter values */
 
-        idmap_uid_low = low;
-        idmap_uid_high = high;
+static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
+{
+       lp_do_parameter(snum, "idmap config * : range", pszParmValue);
 
        return True;
 }
 
 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
 {
-       uint32 low, high;
-
-       if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
-               return False;
-
-       /* Parse OK */
-
-       string_set(ptr, pszParmValue);
-
-        idmap_gid_low = low;
-        idmap_gid_high = high;
+       lp_do_parameter(snum, "idmap config * : range", pszParmValue);
 
        return True;
 }
@@ -8572,7 +8688,8 @@ static void lp_add_auto_services(char *str)
  Auto-load one printer.
 ***************************************************************************/
 
-void lp_add_one_printer(const char *name, const char *comment, void *pdata)
+void lp_add_one_printer(const char *name, const char *comment,
+                       const char *location, void *pdata)
 {
        int printers = lp_servicenumber(PRINTERS_NAME);
        int i;
@@ -9469,6 +9586,8 @@ static bool lp_load_ex(const char *pszFname,
 
        free_param_opts(&Globals.param_opt);
 
+       lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
+
        /* We get sections first, so have to start 'behind' to make up */
        iServiceIndex = -1;
 
@@ -9520,11 +9639,19 @@ static bool lp_load_ex(const char *pszFname,
                bRetval = false;
        }
 
-       if (bRetval && lp_registry_shares() && allow_registry_shares) {
-               bRetval = process_registry_shares();
+       if (bRetval && lp_registry_shares()) {
+               if (allow_registry_shares) {
+                       bRetval = process_registry_shares();
+               } else {
+                       bRetval = reload_registry_shares();
+               }
        }
 
-       lp_add_auto_services(lp_auto_services());
+       {
+               char *serv = lp_auto_services();
+               lp_add_auto_services(serv);
+               TALLOC_FREE(serv);
+       }
 
        if (add_ipc) {
                /* When 'restrict anonymous = 2' guest connections to ipc$
@@ -9539,6 +9666,17 @@ static bool lp_load_ex(const char *pszFname,
        set_default_server_announce_type();
        set_allowed_client_auth();
 
+       if (lp_security() == SEC_SHARE) {
+               DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
+       } else if (lp_security() == SEC_SERVER) {
+               DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
+       }
+
+       if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
+               DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
+                         lp_passwordserver()));
+       }
+
        bLoaded = True;
 
        /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
@@ -10199,6 +10337,10 @@ static bool lp_widelinks_internal(int snum)
 
 void widelinks_warning(int snum)
 {
+       if (lp_allow_insecure_widelinks()) {
+               return;
+       }
+
        if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
                DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
                        "These parameters are incompatible. "
@@ -10211,7 +10353,13 @@ bool lp_widelinks(int snum)
 {
        /* wide links is always incompatible with unix extensions */
        if (lp_unix_extensions()) {
-               return false;
+               /*
+                * Unless we have "allow insecure widelinks"
+                * turned on.
+                */
+               if (!lp_allow_insecure_widelinks()) {
+                       return false;
+               }
        }
 
        return lp_widelinks_internal(snum);