From 9dd8940e5f4d89da67b66fb1932a95cc6fda63a5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 03:14:08 +0100 Subject: Add header for NetGetJoinableOUs to libnetapi. Guenther (This used to be commit f297ea259d58f7a12924b7111ab79818188cff46) --- source3/lib/netapi/netapi.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 67bb8a8fca..c2f1b488db 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -95,6 +95,17 @@ NET_API_STATUS NetGetJoinInformation(const char *server_name, const char **name_buffer, uint16_t *name_type); +/**************************************************************** + NetGetJoinableOUs +****************************************************************/ + +NET_API_STATUS NetGetJoinableOUs(const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous); + /**************************************************************** NetServerGetInfo ****************************************************************/ -- cgit From db40120c73f4d4cbb132f94cd3c5859fbdad0f5a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 08:48:44 +0100 Subject: Fix the build w/o ADS. Guenther (This used to be commit 645f2376d40fabdc787902ac7506ad7234616619) --- source3/lib/netapi/joindomain.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index cbfc6c01e3..133aff3dd8 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -558,6 +558,7 @@ static WERROR NetGetJoinableOUsLocal(struct libnetapi_ctx *ctx, uint32_t *ou_count, const char ***ous) { +#ifdef WITH_ADS NTSTATUS status; ADS_STATUS ads_status; ADS_STRUCT *ads = NULL; @@ -608,6 +609,9 @@ static WERROR NetGetJoinableOUsLocal(struct libnetapi_ctx *ctx, ads_destroy(&ads); return WERR_OK; +#else + return WERR_NOT_SUPPORTED; +#endif } /**************************************************************** -- cgit From 1ea809383ef310f442bae7b5d4591f9aa655ad60 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 08:15:27 +0100 Subject: Fix typo in debug message. Michael (This used to be commit d7a8d7ffbd724a59aa3fc4bdeca6be5d5a0e7258) --- source3/registry/reg_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 18435ff033..788af28d5d 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -183,7 +183,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx, /* Look up the table of registry I/O operations */ if ( !(key->hook = reghook_cache_find( key->name )) ) { - DEBUG(0,("reg_open_onelevel: Failed to assigned a " + DEBUG(0,("reg_open_onelevel: Failed to assign a " "REGISTRY_HOOK to [%s]\n", key->name )); result = WERR_BADFILE; goto done; -- cgit From 60fbc7e4f03bff29ad548c1e8640e6fde23ace2a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 09:40:42 +0100 Subject: Add a registry backend netlogon_params that replaces the former dynamic overlay. This is the first step in replacing the dynamic overlays by proper backends implementing REGISTRY_OPS. Michael (This used to be commit e8a0524961d81fa83e0316905dc9d215e4aa7656) --- source3/Makefile.in | 1 + source3/include/reg_objects.h | 1 + source3/registry/reg_backend_netlogon_params.c | 58 ++++++++++++++++++++++++++ source3/registry/reg_dynamic.c | 4 ++ source3/registry/reg_frontend.c | 2 + 5 files changed, 66 insertions(+) create mode 100644 source3/registry/reg_backend_netlogon_params.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 227650027a..45aa4cbc37 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -417,6 +417,7 @@ REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_pri registry/reg_util.o registry/reg_dynamic.o registry/reg_perfcount.o \ registry/reg_smbconf.o registry/reg_api.o \ registry/reg_frontend_hilvl.o \ + registry/reg_backend_netlogon_params.o \ $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ) RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index 23a14e6757..3b846db681 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -100,6 +100,7 @@ typedef struct { #define KEY_EVENTLOG "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Eventlog" #define KEY_SHARES "HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares" #define KEY_SMBCONF "HKLM\\SOFTWARE\\Samba\\smbconf" +#define KEY_NETLOGON_PARAMS "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters" #define KEY_TREE_ROOT "" /* diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c new file mode 100644 index 0000000000..b70e1bdf50 --- /dev/null +++ b/source3/registry/reg_backend_netlogon_params.c @@ -0,0 +1,58 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 2002-2005 + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Netlogon parameters registry backend. + * + * This replaces the former dynamic netlogon parameters overlay. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + + +static int netlogon_params_fetch_reg_values(const char *key, + REGVAL_CTR *regvals) +{ + uint32 dwValue; + + if ( !pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue) ) + dwValue = 0; + + regval_ctr_addvalue( regvals, "RefusePasswordChange", REG_DWORD, + (char*)&dwValue, sizeof(dwValue) ); + + return regval_ctr_numvals( regvals ); +} + + +REGISTRY_OPS netlogon_params_reg_ops = { + NULL, + netlogon_params_fetch_reg_values, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index e70bd178f9..07c9673c28 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -29,6 +29,7 @@ struct reg_dyn_values { int (*fetch_values) ( REGVAL_CTR *val ); }; +#if 0 /*********************************************************************** ***********************************************************************/ @@ -44,6 +45,7 @@ static int netlogon_params( REGVAL_CTR *regvals ) return regval_ctr_numvals( regvals ); } +#endif /*********************************************************************** ***********************************************************************/ @@ -200,7 +202,9 @@ static int current_version( REGVAL_CTR *values ) ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { +#if 0 { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/NETLOGON/PARAMETERS", &netlogon_params }, +#endif { "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRODUCTOPTIONS", &prod_options }, { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 9e84d3a8c4..6674b0ba20 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -28,6 +28,7 @@ extern REGISTRY_OPS printing_ops; extern REGISTRY_OPS eventlog_ops; extern REGISTRY_OPS shares_reg_ops; extern REGISTRY_OPS smbconf_reg_ops; +extern REGISTRY_OPS netlogon_params_reg_ops; extern REGISTRY_OPS regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -40,6 +41,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_PRINTING_PORTS, &printing_ops }, { KEY_SHARES, &shares_reg_ops }, { KEY_SMBCONF, &smbconf_reg_ops }, + { KEY_NETLOGON_PARAMS, &netlogon_params_reg_ops }, #endif { NULL, NULL } }; -- cgit From 3d3d6e7020749c63455e16ba110bc46862d3c146 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 18 Jan 2008 11:08:17 +0100 Subject: Add the "allinfo" command to smbclient Modeled after the Samba4 allinfo command (This used to be commit 3fa0cf3fe5f819f6e76df6f7cef3bb4e1c307a52) --- source3/client/client.c | 88 ++++++++++++++++++++++++++++++++ source3/include/smb.h | 10 ++++ source3/libsmb/clirap.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+) diff --git a/source3/client/client.c b/source3/client/client.c index 267c13048e..59ca2e0adc 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1527,6 +1527,92 @@ static int cmd_altname(void) return 0; } +/**************************************************************************** + Show all info we can get +****************************************************************************/ + +static int do_allinfo(const char *name) +{ + fstring altname; + struct timespec b_time, a_time, m_time, c_time; + SMB_OFF_T size; + uint16_t mode; + SMB_INO_T ino; + NTTIME tmp; + unsigned int num_streams; + struct stream_struct *streams; + unsigned int i; + + if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli, name, altname))) { + d_printf("%s getting alt name for %s\n", + cli_errstr(cli),name); + return false; + } + d_printf("altname: %s\n", altname); + + if (!cli_qpathinfo2(cli, name, &b_time, &a_time, &m_time, &c_time, + &size, &mode, &ino)) { + d_printf("%s getting pathinfo for %s\n", + cli_errstr(cli),name); + return false; + } + + unix_timespec_to_nt_time(&tmp, b_time); + d_printf("create_time: %s\n", nt_time_string(talloc_tos(), tmp)); + + unix_timespec_to_nt_time(&tmp, a_time); + d_printf("access_time: %s\n", nt_time_string(talloc_tos(), tmp)); + + unix_timespec_to_nt_time(&tmp, m_time); + d_printf("write_time: %s\n", nt_time_string(talloc_tos(), tmp)); + + unix_timespec_to_nt_time(&tmp, c_time); + d_printf("change_time: %s\n", nt_time_string(talloc_tos(), tmp)); + + if (!cli_qpathinfo_streams(cli, name, talloc_tos(), &num_streams, + &streams)) { + d_printf("%s getting streams for %s\n", + cli_errstr(cli),name); + return false; + } + + for (i=0; i\n"); + return 1; + } + name = talloc_asprintf_append(name, buf); + if (!name) { + return 1; + } + + do_allinfo(name); + + return 0; +} + /**************************************************************************** Put a single file. ****************************************************************************/ @@ -3839,6 +3925,8 @@ static struct { char compl_args[2]; /* Completion argument info */ } commands[] = { {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}}, + {"allinfo",cmd_allinfo," show all available info", + {COMPL_NONE,COMPL_NONE}}, {"altname",cmd_altname," show alt name",{COMPL_NONE,COMPL_NONE}}, {"archive",cmd_archive,"\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}}, {"blocksize",cmd_block,"blocksize (default 20)",{COMPL_NONE,COMPL_NONE}}, diff --git a/source3/include/smb.h b/source3/include/smb.h index d64b8ba80c..15e51dbdd7 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -574,6 +574,16 @@ struct trans_state { char *data; }; +/* + * Info about an alternate data stream + */ + +struct stream_struct { + SMB_OFF_T size; + SMB_OFF_T alloc_size; + char *name; +}; + /* Include VFS stuff */ #include "smb_acls.h" diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index aab77a3d54..4c5e338606 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -805,6 +805,137 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, return True; } +/**************************************************************************** + Get the stream info +****************************************************************************/ + +bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname, + TALLOC_CTX *mem_ctx, + unsigned int *pnum_streams, + struct stream_struct **pstreams) +{ + unsigned int data_len = 0; + unsigned int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + char *param; + char *rparam=NULL, *rdata=NULL; + char *p; + unsigned int num_streams; + struct stream_struct *streams; + unsigned int ofs; + size_t namelen = 2*(strlen(fname)+1); + + param = SMB_MALLOC_ARRAY(char, 6+namelen+2); + if (param == NULL) { + return false; + } + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_FILE_STREAM_INFORMATION); + p += 6; + p += clistr_push(cli, p, fname, namelen, STR_TERMINATE); + + param_len = PTR_DIFF(p, param); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, len, max */ + param, param_len, 10, /* param, len, max */ + NULL, data_len, cli->max_xmit /* data, len, max */ + )) { + return false; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return false; + } + + if (!rdata) { + SAFE_FREE(rparam); + return false; + } + + num_streams = 0; + streams = NULL; + ofs = 0; + + while ((data_len > ofs) && (data_len - ofs >= 24)) { + uint32_t nlen, len; + ssize_t size; + void *vstr; + struct stream_struct *tmp; + uint8_t *tmp_buf; + + tmp = TALLOC_REALLOC_ARRAY(mem_ctx, streams, + struct stream_struct, + num_streams+1); + + if (tmp == NULL) { + goto fail; + } + streams = tmp; + + nlen = IVAL(rdata, ofs + 0x04); + + streams[num_streams].size = IVAL_TO_SMB_OFF_T( + rdata, ofs + 0x08); + streams[num_streams].alloc_size = IVAL_TO_SMB_OFF_T( + rdata, ofs + 0x10); + + if (nlen > data_len - (ofs + 24)) { + goto fail; + } + + /* + * We need to null-terminate src, how do I do this with + * convert_string_talloc?? + */ + + tmp_buf = TALLOC_ARRAY(streams, uint8_t, nlen+2); + if (tmp_buf == NULL) { + goto fail; + } + + memcpy(tmp_buf, rdata+ofs+24, nlen); + tmp_buf[nlen] = 0; + tmp_buf[nlen+1] = 0; + + size = convert_string_talloc(streams, CH_UTF16, CH_UNIX, + tmp_buf, nlen+2, &vstr, + false); + TALLOC_FREE(tmp_buf); + + if (size == -1) { + goto fail; + } + streams[num_streams].name = (char *)vstr; + num_streams++; + + len = IVAL(rdata, ofs); + if (len > data_len - ofs) { + goto fail; + } + if (len == 0) break; + ofs += len; + } + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + *pnum_streams = num_streams; + *pstreams = streams; + return true; + + fail: + TALLOC_FREE(streams); + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return false; +} + /**************************************************************************** Send a qfileinfo QUERY_FILE_NAME_INFO call. ****************************************************************************/ -- cgit From 27d9ac321961891b0580a9f67366ef6b603de418 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 12:07:02 +0100 Subject: Use C99 structure initializers for netlogon_params_reg_ops. Michael (This used to be commit f3901f179b770ffadb3e5a82ac5a2da00d83f40a) --- source3/registry/reg_backend_netlogon_params.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index b70e1bdf50..507d2c5df8 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -46,13 +46,5 @@ static int netlogon_params_fetch_reg_values(const char *key, REGISTRY_OPS netlogon_params_reg_ops = { - NULL, - netlogon_params_fetch_reg_values, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + .fetch_values = netlogon_params_fetch_reg_values, }; -- cgit From 928f899948d25a133c9622a2ac8208e4499ba260 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Nov 2007 14:46:47 +0100 Subject: r25970: libreplace: fix AC_N_DEFINE() so that some appears in config.h metze (cherry picked from commit a07c983fde52607806745914bb41039afb5618cc) (This used to be commit 3db37038b3e5a59a9baa85f6bcd32ac6e5ec2da1) --- source3/lib/replace/libreplace_macros.m4 | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/source3/lib/replace/libreplace_macros.m4 b/source3/lib/replace/libreplace_macros.m4 index 92fecd3db8..54e6b7ac75 100644 --- a/source3/lib/replace/libreplace_macros.m4 +++ b/source3/lib/replace/libreplace_macros.m4 @@ -248,11 +248,18 @@ m4_define([AH_CHECK_FUNC_EXT], dnl Define an AC_DEFINE with ifndef guard. dnl AC_N_DEFINE(VARIABLE [, VALUE]) -define(AC_N_DEFINE, -[cat >> confdefs.h <<\EOF -[#ifndef] $1 -[#define] $1 ifelse($#, 2, [$2], $#, 3, [$2], 1) -[#endif] +AC_DEFUN([AC_N_DEFINE], +[ +AH_VERBATIM([$1], [ +#ifndef $1 +# undef $1 +#endif +]) + + cat >>confdefs.h <<\EOF +#ifndef $1 +[#define] $1 m4_if($#, 1, 1, [$2]) +#endif EOF ]) -- cgit From 2e0dc77bdad8e6c88920cfb8624a8dac981dd4c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Nov 2007 14:55:48 +0100 Subject: r25971: libreplace: remove AC_EXTENSION_FLAG as it's the same as AC_N_DEFINE metze (cherry picked from commit 05b4619c5beff474488d1abe5e647acd94a3e20c) (This used to be commit 58932ca791024bd9a543ff5e21bc26970ceed477) --- source3/lib/replace/libreplace_cc.m4 | 4 ++-- source3/lib/replace/libreplace_macros.m4 | 13 ------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/source3/lib/replace/libreplace_cc.m4 b/source3/lib/replace/libreplace_cc.m4 index a01bf1b290..a0722b2fcf 100644 --- a/source3/lib/replace/libreplace_cc.m4 +++ b/source3/lib/replace/libreplace_cc.m4 @@ -48,8 +48,8 @@ LIBREPLACE_C99_STRUCT_INIT([],[AC_MSG_WARN([c99 structure initializer are not su AC_PROG_INSTALL AC_ISC_POSIX -AC_EXTENSION_FLAG(_XOPEN_SOURCE_EXTENDED) -AC_EXTENSION_FLAG(_OSF_SOURCE) +AC_N_DEFINE(_XOPEN_SOURCE_EXTENDED) +AC_N_DEFINE(_OSF_SOURCE) AC_SYS_LARGEFILE diff --git a/source3/lib/replace/libreplace_macros.m4 b/source3/lib/replace/libreplace_macros.m4 index 54e6b7ac75..1856eacf66 100644 --- a/source3/lib/replace/libreplace_macros.m4 +++ b/source3/lib/replace/libreplace_macros.m4 @@ -87,19 +87,6 @@ fi rm -f conftest* ])]) -AC_DEFUN([AC_EXTENSION_FLAG], -[ - cat >>confdefs.h <<\EOF -#ifndef $1 -# define $1 1 -#endif -EOF -AH_VERBATIM([$1], [#ifndef $1 -# define $1 1 -#endif]) -]) - - dnl see if a declaration exists for a function or variable dnl defines HAVE_function_DECL if it exists dnl AC_HAVE_DECL(var, includes) -- cgit From f75898d5b5712bcd8cb45cd54893932c1d0e5b36 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Nov 2007 15:43:14 +0100 Subject: r25974: libreplace: see what the build-farm says if we use _XOPEN_SOURCE=600 On Tru64 this brings in socklen_t and some other socket stuff metze (cherry picked from commit d42f2e5759332f1f0c6c1269bd29ac62ddb11016) (This used to be commit af3772e22f5e6e0158783086e9791ffc95ee5368) --- source3/lib/replace/libreplace_cc.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/lib/replace/libreplace_cc.m4 b/source3/lib/replace/libreplace_cc.m4 index a0722b2fcf..3f0a337083 100644 --- a/source3/lib/replace/libreplace_cc.m4 +++ b/source3/lib/replace/libreplace_cc.m4 @@ -49,6 +49,7 @@ AC_PROG_INSTALL AC_ISC_POSIX AC_N_DEFINE(_XOPEN_SOURCE_EXTENDED) +AC_N_DEFINE(_XOPEN_SOURCE,600) AC_N_DEFINE(_OSF_SOURCE) AC_SYS_LARGEFILE -- cgit From 0e1348869e50715f889a97a375abc7ae1af13d69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Nov 2007 16:40:32 +0100 Subject: r25976: libreplace: not all platforms like _XOPEN_SOURCE=600 - Only use _XOPEN_SOURCE=600 on Tru64 - _OSF_SOURCE is also Tru64 specific metze (cherry picked from commit d19ab62081ce4ee4273ff752ad0443782a994826) (This used to be commit dbff70b2ebe7cc09f7fbe5a0319f978dfcfa1da9) --- source3/lib/replace/libreplace_cc.m4 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/lib/replace/libreplace_cc.m4 b/source3/lib/replace/libreplace_cc.m4 index 3f0a337083..bf5056838d 100644 --- a/source3/lib/replace/libreplace_cc.m4 +++ b/source3/lib/replace/libreplace_cc.m4 @@ -49,8 +49,6 @@ AC_PROG_INSTALL AC_ISC_POSIX AC_N_DEFINE(_XOPEN_SOURCE_EXTENDED) -AC_N_DEFINE(_XOPEN_SOURCE,600) -AC_N_DEFINE(_OSF_SOURCE) AC_SYS_LARGEFILE @@ -78,6 +76,11 @@ case "$host_os" in CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" fi ;; + *osf*) + # this brings in socklen_t + AC_N_DEFINE(_XOPEN_SOURCE,600) + AC_N_DEFINE(_OSF_SOURCE) + ;; # # VOS may need to have POSIX support and System V compatibility enabled. # -- cgit From a2bfb1749ca7bc0c713d3508c1324799245c7d1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Nov 2007 14:42:14 +0100 Subject: r26102: libreplace: remove system/printing.h as it only contains samba3 stuff metze (cherry picked from commit 1ecb4ec01b0506c95a5f90a62040329e7a39ee93) (This used to be commit ff8a001f0d3f2655efafed41f2f0b14552a5c7e7) --- source3/lib/replace/system/printing.h | 50 ----------------------------------- source3/lib/replace/test/testsuite.c | 1 - 2 files changed, 51 deletions(-) delete mode 100644 source3/lib/replace/system/printing.h diff --git a/source3/lib/replace/system/printing.h b/source3/lib/replace/system/printing.h deleted file mode 100644 index 7eb02d004a..0000000000 --- a/source3/lib/replace/system/printing.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _system_printing_h -#define _system_printing_h - -/* - Unix SMB/CIFS implementation. - - printing system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef AIX -#define DEFAULT_PRINTING PRINT_AIX -#define PRINTCAP_NAME "/etc/qconfig" -#endif - -#ifdef HPUX -#define DEFAULT_PRINTING PRINT_HPUX -#endif - -#ifdef QNX -#define DEFAULT_PRINTING PRINT_QNX -#endif - -#ifndef DEFAULT_PRINTING -#define DEFAULT_PRINTING PRINT_BSD -#endif -#ifndef PRINTCAP_NAME -#define PRINTCAP_NAME "/etc/printcap" -#endif - -#endif diff --git a/source3/lib/replace/test/testsuite.c b/source3/lib/replace/test/testsuite.c index 269a2ff5d6..5b95ae395c 100644 --- a/source3/lib/replace/test/testsuite.c +++ b/source3/lib/replace/test/testsuite.c @@ -37,7 +37,6 @@ #include "system/locale.h" #include "system/network.h" #include "system/passwd.h" -#include "system/printing.h" #include "system/readline.h" #include "system/select.h" #include "system/shmem.h" -- cgit From 1e5418edbc370e87293c324eae54372a495bb932 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 20 Dec 2007 15:59:39 +0100 Subject: r26550: libreplace: fallback to __ss_family of struct sockaddr_storage metze (cherry picked from commit 11bdc9bed80b9842ac1ab8f22509a5d191cddc91) (This used to be commit c11122afda52ce787dd1d3357bd85b6ce36b8ca4) --- source3/lib/replace/libreplace.m4 | 20 ++++++++++++++++++++ source3/lib/replace/system/network.h | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/source3/lib/replace/libreplace.m4 b/source3/lib/replace/libreplace.m4 index 7a5283a4d6..f866b3648f 100644 --- a/source3/lib/replace/libreplace.m4 +++ b/source3/lib/replace/libreplace.m4 @@ -153,6 +153,26 @@ AC_HAVE_TYPE([struct sockaddr_in6], [ #include ]) +if test x"$ac_cv_type_struct_sockaddr_storage" = x"yes"; then +AC_CHECK_MEMBER(struct sockaddr_storage.ss_family, + AC_DEFINE(HAVE_SS_FAMILY, 1, [Defined if struct sockaddr_storage has ss_family field]),, + [ +#include +#include +#include + ]) + +if test x"$ac_cv_member_struct_sockaddr_storage_ss_family" != x"yes"; then +AC_CHECK_MEMBER(struct sockaddr_storage.__ss_family, + AC_DEFINE(HAVE___SS_FAMILY, 1, [Defined if struct sockaddr_storage has __ss_family field]),, + [ +#include +#include +#include + ]) +fi +fi + AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror) AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename) AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup) diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index b6ae3c7c6f..2f387de5cf 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -227,9 +227,18 @@ typedef unsigned short int sa_family_t; #ifdef HAVE_STRUCT_SOCKADDR_IN6 #define sockaddr_storage sockaddr_in6 #define ss_family sin6_family +#define HAVE_SS_FAMILY 1 #else #define sockaddr_storage sockaddr_in #define ss_family sin_family +#define HAVE_SS_FAMILY 1 +#endif +#endif + +#ifndef HAVE_SS_FAMILY +#ifdef HAVE___SS_FAMILY +#define ss_family __ss_family +#define HAVE_SS_FAMILY 1 #endif #endif -- cgit From f8ad02305fca3357e924c9c0e462b05b1452ae16 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 04:46:11 +0100 Subject: Try to fix the build on Tru64; avoid single quotes because they get expanded by perl in the build system. (cherry picked from commit bba8914af56cb161c275fbbdea2479d6f8bd703c) (This used to be commit a0e663ff2c6548e48c9710e3fb314f3bbabb59d0) --- source3/lib/replace/libreplace_ld.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/replace/libreplace_ld.m4 b/source3/lib/replace/libreplace_ld.m4 index cb8e21434e..0ca6f7a34d 100644 --- a/source3/lib/replace/libreplace_ld.m4 +++ b/source3/lib/replace/libreplace_ld.m4 @@ -265,7 +265,7 @@ AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG], LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,--allow-shlib-undefined" ;; *osf*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-expect_unresolved '*'" + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,*" ;; *darwin*) LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup" -- cgit From a0e04a94170ffb54e8a809ed869a08af898fb723 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 22:24:07 +0100 Subject: libreplace: Escape asterisk. (cherry picked from commit df36c78549b40ee5e47d5cc79de2eb79f58c567a) (This used to be commit 174a45ec18fff064d89f6a12b044973ab3c10c54) --- source3/lib/replace/libreplace_ld.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/replace/libreplace_ld.m4 b/source3/lib/replace/libreplace_ld.m4 index 0ca6f7a34d..2aec698967 100644 --- a/source3/lib/replace/libreplace_ld.m4 +++ b/source3/lib/replace/libreplace_ld.m4 @@ -265,7 +265,7 @@ AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG], LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,--allow-shlib-undefined" ;; *osf*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,*" + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,\"*\"" ;; *darwin*) LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup" -- cgit From db449a4c5f807b11ec723b11a2db32d09162e163 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Jan 2008 16:34:06 +0100 Subject: Revert "Host SerNet-AIX has __ss_family instead of ss_family in sockaddr_storage" This reverts commit e33286f4a68352e55df081d06307f64f190773b3. 393bab185e0e9f02aac5740becc2aba2762133c8 is the v4-0-test fix for the same problem. metze (This used to be commit b8a57a24c390355c4950ca499c1d96aff80abad7) --- source3/configure.in | 9 --------- source3/lib/replace/system/network.h | 4 ---- 2 files changed, 13 deletions(-) diff --git a/source3/configure.in b/source3/configure.in index f65eb3c204..a34d42c478 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -3051,15 +3051,6 @@ if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then fi fi -dnl AIX 5.3.0.0 -AC_TRY_COMPILE([#include ],[ -struct sockaddr_storage s; s.__ss_family = 0], -samba_cv_have_aix_sockaddr_storage=yes,samba_cv_have_aix_sockaddr_storage=no) - -if test x"$samba_cv_have_aix_sockaddr_storage" = x"yes"; then - AC_DEFINE(HAVE_AIX_SOCKADDR_STORAGE, 1, [Whether struct sockaddr_storage has __sa_family]) -fi - if test $iface = no; then AC_CACHE_CHECK([for iface AIX],samba_cv_HAVE_IFACE_AIX,[ SAVE_CPPFLAGS="$CPPFLAGS" diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index 2f387de5cf..fe6e46817f 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -242,10 +242,6 @@ typedef unsigned short int sa_family_t; #endif #endif -#ifdef HAVE_AIX_SOCKADDR_STORAGE -#define ss_family __ss_family -#endif - #ifndef HAVE_STRUCT_ADDRINFO #define HAVE_STRUCT_ADDRINFO struct addrinfo { -- cgit From bb707b1db6add166a7887284281fa4b65776be08 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 18 Jan 2008 14:22:49 -0500 Subject: Fix typo that disabled setting group id. Thanks, Henrik. (This used to be commit 843e1694cfe4a999ed14a9c215b8e77723d0fe79) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2fd8294d04..fbcb7f64e2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5931,7 +5931,7 @@ smbc_setxattr_ctx(SMBCCTX *context, } else { ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, - namevalue, SMBC_XATTR_MODE_CHOWN, 0); + namevalue, SMBC_XATTR_MODE_CHGRP, 0); } TALLOC_FREE(frame); return ret; -- cgit From b97fbf58886427fbb7f3181694bf6f9648f5d0f4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jan 2008 13:47:10 -0800 Subject: Fix error message for new allinfo command. Jeremy. (This used to be commit 3a1bcbfa7ca2b55265eb486e2b7c740e04775698) --- source3/client/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/client/client.c b/source3/client/client.c index 59ca2e0adc..28b4a2b24b 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1600,7 +1600,7 @@ static int cmd_allinfo(void) } if (!next_token_talloc(ctx, &cmd_ptr, &buf, NULL)) { - d_printf("altname \n"); + d_printf("allinfo \n"); return 1; } name = talloc_asprintf_append(name, buf); -- cgit From 805caafd44cbc5fff49711b1a15fb64cc99f3ad3 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 19 Jan 2008 02:12:35 +0100 Subject: util_str: Don't return memory from talloc_tos(), use mem_ctx instead. (This used to be commit ab0ee6e9a6a9eee317228f0c2bde254ad9a59b85) --- source3/lib/afs.c | 23 +++++++++++++---------- source3/lib/util_str.c | 6 +++--- source3/rpc_server/srv_samr_util.c | 12 ++++++------ source3/utils/net_rpc_samsync.c | 6 +++--- source3/utils/ntlm_auth.c | 25 +++++++++++++++---------- 5 files changed, 40 insertions(+), 32 deletions(-) diff --git a/source3/lib/afs.c b/source3/lib/afs.c index a7d6f6c9f7..b3d590bf24 100644 --- a/source3/lib/afs.c +++ b/source3/lib/afs.c @@ -42,20 +42,23 @@ static char *afs_encode_token(const char *cell, const DATA_BLOB ticket, const struct ClearToken *ct) { char *base64_ticket; - char *result; + char *result = NULL; DATA_BLOB key = data_blob(ct->HandShakeKey, 8); char *base64_key; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("afs_encode_token"); + if (mem_ctx == NULL) + goto done; - base64_ticket = base64_encode_data_blob(ticket); + base64_ticket = base64_encode_data_blob(mem_ctx, ticket); if (base64_ticket == NULL) - return NULL; + goto done; - base64_key = base64_encode_data_blob(key); - if (base64_key == NULL) { - TALLOC_FREE(base64_ticket); - return NULL; - } + base64_key = base64_encode_data_blob(mem_ctx, key); + if (base64_key == NULL) + goto done; asprintf(&result, "%s\n%u\n%s\n%u\n%u\n%u\n%s\n", cell, ct->AuthHandle, base64_key, ct->ViceId, ct->BeginTimestamp, @@ -63,8 +66,8 @@ static char *afs_encode_token(const char *cell, const DATA_BLOB ticket, DEBUG(10, ("Got ticket string:\n%s\n", result)); - TALLOC_FREE(base64_ticket); - TALLOC_FREE(base64_key); +done: + TALLOC_FREE(mem_ctx); return result; } diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 3e3268104c..bcb9197141 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -2415,13 +2415,13 @@ void base64_decode_inplace(char *s) } /** - * Encode a base64 string into a malloc()ed string caller to free. + * Encode a base64 string into a talloc()ed string caller to free. * * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c * with adjustments **/ -char *base64_encode_data_blob(DATA_BLOB data) +char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data) { int bits = 0; int char_count = 0; @@ -2434,7 +2434,7 @@ char *base64_encode_data_blob(DATA_BLOB data) out_cnt = 0; len = data.length; output_len = data.length * 2; - result = TALLOC_ARRAY(talloc_tos(), char, output_len); /* get us plenty of space */ + result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */ SMB_ASSERT(result != NULL); while (len-- && out_cnt < (data.length * 2) - 5) { diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index bde7936343..c8f732153c 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -44,16 +44,16 @@ void copy_id20_to_sam_passwd(struct samu *to, SAM_USER_INFO_20 *from) char *new_string; DATA_BLOB mung; - if (from == NULL || to == NULL) + if (from == NULL || to == NULL) return; - + if (from->hdr_munged_dial.buffer) { old_string = pdb_get_munged_dial(to); mung.length = from->hdr_munged_dial.uni_str_len; mung.data = (uint8 *) from->uni_munged_dial.buffer; mung.free = NULL; new_string = (mung.length == 0) ? - NULL : base64_encode_data_blob(mung); + NULL : base64_encode_data_blob(talloc_tos(), mung); DEBUG(10,("INFO_20 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string)); if (STRING_CHANGED_NC(old_string,new_string)) pdb_set_munged_dial(to , new_string, PDB_CHANGED); @@ -196,7 +196,7 @@ void copy_id21_to_sam_passwd(struct samu *to, SAM_USER_INFO_21 *from) mung.data = (uint8 *) from->uni_munged_dial.buffer; mung.free = NULL; newstr = (mung.length == 0) ? - NULL : base64_encode_data_blob(mung); + NULL : base64_encode_data_blob(talloc_tos(), mung); DEBUG(10,("INFO_21 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr)); if (STRING_CHANGED_NC(old_string,newstr)) pdb_set_munged_dial(to , newstr, PDB_CHANGED); @@ -421,7 +421,7 @@ void copy_id23_to_sam_passwd(struct samu *to, SAM_USER_INFO_23 *from) mung.data = (uint8 *) from->uni_munged_dial.buffer; mung.free = NULL; newstr = (mung.length == 0) ? - NULL : base64_encode_data_blob(mung); + NULL : base64_encode_data_blob(talloc_tos(), mung); DEBUG(10,("INFO_23 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr)); if (STRING_CHANGED_NC(old_string, newstr)) pdb_set_munged_dial(to , newstr, PDB_CHANGED); @@ -633,7 +633,7 @@ void copy_id25_to_sam_passwd(struct samu *to, SAM_USER_INFO_25 *from) mung.data = (uint8 *) from->uni_munged_dial.buffer; mung.free = NULL; newstr = (mung.length == 0) ? - NULL : base64_encode_data_blob(mung); + NULL : base64_encode_data_blob(talloc_tos(), mung); DEBUG(10,("INFO_25 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr)); if (STRING_CHANGED_NC(old_string,newstr)) pdb_set_munged_dial(to , newstr, PDB_CHANGED); diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 779006884d..d0fcfe3aeb 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -365,7 +365,8 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d old_string = pdb_get_munged_dial(account); mung.length = delta->hdr_parameters.uni_str_len; mung.data = (uint8 *) delta->uni_parameters.buffer; - newstr = (mung.length == 0) ? NULL : base64_encode_data_blob(mung); + newstr = (mung.length == 0) ? NULL : + base64_encode_data_blob(talloc_tos(), mung); if (STRING_CHANGED_NC(old_string, newstr)) pdb_set_munged_dial(account, newstr, PDB_CHANGED); @@ -1422,12 +1423,11 @@ static int fprintf_attr(FILE *add_fd, const char *attr_name, base64_blob.data = (unsigned char *)value; base64_blob.length = strlen(value); - base64 = base64_encode_data_blob(base64_blob); + base64 = base64_encode_data_blob(value, base64_blob); SMB_ASSERT(base64 != NULL); res = fprintf(add_fd, "%s:: %s\n", attr_name, base64); TALLOC_FREE(value); - TALLOC_FREE(base64); return res; } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 6a702fc0cf..68bf24fec7 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -739,7 +739,8 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod } else if (strncmp(buf, "GK", 2) == 0) { DEBUG(10, ("Requested NTLMSSP session key\n")); if(have_session_key) { - char *key64 = base64_encode_data_blob(session_key); + char *key64 = base64_encode_data_blob(talloc_tos(), + session_key); x_fprintf(x_stdout, "GK %s\n", key64?key64:""); TALLOC_FREE(key64); } else { @@ -768,7 +769,8 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod nt_status = ntlmssp_update(ntlmssp_state, request, &reply); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - char *reply_base64 = base64_encode_data_blob(reply); + char *reply_base64 = base64_encode_data_blob(talloc_tos(), + reply); x_fprintf(x_stdout, "TT %s\n", reply_base64); TALLOC_FREE(reply_base64); data_blob_free(&reply); @@ -889,7 +891,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo DEBUG(10, ("Requested session key\n")); if(have_session_key) { - char *key64 = base64_encode_data_blob(session_key); + char *key64 = base64_encode_data_blob(talloc_tos(), + session_key); x_fprintf(x_stdout, "GK %s\n", key64?key64:""); TALLOC_FREE(key64); } @@ -925,7 +928,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo } if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - char *reply_base64 = base64_encode_data_blob(reply); + char *reply_base64 = base64_encode_data_blob(talloc_tos(), + reply); if (first) { x_fprintf(x_stdout, "YR %s\n", reply_base64); } else { @@ -939,7 +943,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo } DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_IS_OK(nt_status)) { - char *reply_base64 = base64_encode_data_blob(reply); + char *reply_base64 = base64_encode_data_blob(talloc_tos(), + reply); x_fprintf(x_stdout, "AF %s\n", reply_base64); TALLOC_FREE(reply_base64); @@ -1039,7 +1044,7 @@ static void offer_gss_spnego_mechs(void) { return; } - reply_base64 = base64_encode_data_blob(token); + reply_base64 = base64_encode_data_blob(talloc_tos(), token); x_fprintf(x_stdout, "TT %s *\n", reply_base64); TALLOC_FREE(reply_base64); @@ -1276,7 +1281,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, return; } - reply_base64 = base64_encode_data_blob(token); + reply_base64 = base64_encode_data_blob(talloc_tos(), token); x_fprintf(x_stdout, "%s %s %s\n", reply_code, reply_base64, reply_argument); @@ -1343,7 +1348,7 @@ static bool manage_client_ntlmssp_init(SPNEGO_DATA spnego) write_spnego_data(&to_server, &spnego); data_blob_free(&spnego.negTokenInit.mechToken); - to_server_base64 = base64_encode_data_blob(to_server); + to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); data_blob_free(&to_server); x_fprintf(x_stdout, "KK %s\n", to_server_base64); TALLOC_FREE(to_server_base64); @@ -1401,7 +1406,7 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) write_spnego_data(&to_server, &spnego); data_blob_free(&request); - to_server_base64 = base64_encode_data_blob(to_server); + to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); data_blob_free(&to_server); x_fprintf(x_stdout, "KK %s\n", to_server_base64); TALLOC_FREE(to_server_base64); @@ -1490,7 +1495,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego) return False; } - reply_base64 = base64_encode_data_blob(to_server); + reply_base64 = base64_encode_data_blob(talloc_tos(), to_server); x_fprintf(x_stdout, "KK %s *\n", reply_base64); TALLOC_FREE(reply_base64); -- cgit From 145ab107b2670b3d645c6757d0a3930eaff6c4d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 17 Jan 2008 17:48:33 +0100 Subject: Always return nlink=1 for directories I did not test it, but it should not affect cifsfs, there are special posix calls that also return the stat information unfiltered. (This used to be commit e96cf1309e45628f4c27d03f77a4eef5e00602df) --- source3/smbd/trans2.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 23d6f12996..763b6480e3 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3745,11 +3745,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn, nlink = sbuf.st_nlink; - if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) { - /* NTFS does not seem to count ".." */ - nlink -= 1; - } - if ((nlink > 0) && delete_pending) { nlink -= 1; } @@ -4018,7 +4013,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd data_size = 24; SOFF_T(pdata,0,allocation_size); SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,nlink); + SIVAL(pdata,16,(mode&aDIR)?1:nlink); SCVAL(pdata,20,delete_pending?1:0); SCVAL(pdata,21,(mode&aDIR)?1:0); SSVAL(pdata,22,0); /* Padding. */ @@ -4096,7 +4091,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd pdata += 40; SOFF_T(pdata,0,allocation_size); SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,nlink); + SIVAL(pdata,16,(mode&aDIR)?1:nlink); SCVAL(pdata,20,delete_pending); SCVAL(pdata,21,(mode&aDIR)?1:0); SSVAL(pdata,22,0); -- cgit From ca6cf1fe94f096aac846d0111b39006bdd40b7e3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jan 2008 18:39:27 -0800 Subject: Actually test vl's new code and make it work to fix the build farm :-). Jeremy. (This used to be commit 63defd3e9d4ba3f02f36ec5ad7b73463f31962a1) --- source3/smbd/trans2.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 763b6480e3..935a881607 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3743,12 +3743,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } } - nlink = sbuf.st_nlink; - - if ((nlink > 0) && delete_pending) { - nlink -= 1; - } - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; @@ -3767,6 +3761,16 @@ static void call_trans2qfilepathinfo(connection_struct *conn, if (!mode) mode = FILE_ATTRIBUTE_NORMAL; + nlink = sbuf.st_nlink; + + if (nlink && (mode&aDIR)) { + nlink = 1; + } + + if ((nlink > 0) && delete_pending) { + nlink -= 1; + } + fullpathname = fname; if (!(mode & aDIR)) file_size = get_file_size(sbuf); @@ -4013,7 +4017,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd data_size = 24; SOFF_T(pdata,0,allocation_size); SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,(mode&aDIR)?1:nlink); + SIVAL(pdata,16,nlink); SCVAL(pdata,20,delete_pending?1:0); SCVAL(pdata,21,(mode&aDIR)?1:0); SSVAL(pdata,22,0); /* Padding. */ @@ -4091,7 +4095,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd pdata += 40; SOFF_T(pdata,0,allocation_size); SOFF_T(pdata,8,file_size); - SIVAL(pdata,16,(mode&aDIR)?1:nlink); + SIVAL(pdata,16,nlink); SCVAL(pdata,20,delete_pending); SCVAL(pdata,21,(mode&aDIR)?1:0); SSVAL(pdata,22,0); -- cgit From 7b73ad2755290c5345b506dcc9c8afa04432bd5e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 12:54:46 +0100 Subject: Link ndr_xattr.o with LIBNDR_GEN_OBJ It will be used elsewhere (net xattr for example) (This used to be commit 924c4ede2acbd4e1d327ccdefc92bbbb3d67d7d8) --- source3/Makefile.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 45aa4cbc37..d3e37826d7 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -276,6 +276,7 @@ LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \ librpc/gen_ndr/ndr_netlogon.o \ librpc/gen_ndr/ndr_samr.o \ librpc/gen_ndr/ndr_notify.o \ + librpc/gen_ndr/ndr_xattr.o \ librpc/gen_ndr/ndr_libnet_join.o RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o @@ -515,7 +516,7 @@ VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o VFS_SHADOW_COPY2_OBJ = modules/vfs_shadow_copy2.o VFS_AFSACL_OBJ = modules/vfs_afsacl.o -VFS_XATTR_TDB_OBJ = modules/vfs_xattr_tdb.o librpc/gen_ndr/ndr_xattr.o +VFS_XATTR_TDB_OBJ = modules/vfs_xattr_tdb.o VFS_POSIXACL_OBJ = modules/vfs_posixacl.o VFS_AIXACL_OBJ = modules/vfs_aixacl.o modules/vfs_aixacl_util.o VFS_AIXACL2_OBJ = modules/vfs_aixacl2.o modules/vfs_aixacl_util.o modules/nfs4_acls.o -- cgit From f22a29e1bd0c59710b1f6ab56e903fa6e1e51a46 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 16 Jan 2008 09:52:26 +0100 Subject: ntlm_auth: Dynamically allocate the read buffer. This ports over my changes from Samba4 (This used to be commit 4a475baf26ba9f99bc05f13dd2745494174a00c1) --- source3/utils/ntlm_auth.c | 71 ++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 68bf24fec7..b0c79571d2 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -28,7 +28,8 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -#define SQUID_BUFFER_SIZE 2010 +#define INITIAL_BUFFER_SIZE 300 +#define MAX_BUFFER_SIZE 630000 enum stdio_helper_mode { SQUID_2_4_BASIC, @@ -2070,46 +2071,60 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_ static void manage_squid_request(enum stdio_helper_mode helper_mode, stdio_helper_function fn) { - char buf[SQUID_BUFFER_SIZE+1]; - int length; + char *buf; + char tmp[INITIAL_BUFFER_SIZE+1]; + int length, buf_size = 0; char *c; - static bool err; - /* this is not a typo - x_fgets doesn't work too well under squid */ - if (fgets(buf, sizeof(buf)-1, stdin) == NULL) { - if (ferror(stdin)) { - DEBUG(1, ("fgets() failed! dying..... errno=%d (%s)\n", ferror(stdin), - strerror(ferror(stdin)))); - - exit(1); /* BIIG buffer */ - } - exit(0); - } - - c=(char *)memchr(buf,'\n',sizeof(buf)-1); - if (c) { - *c = '\0'; - length = c-buf; - } else { - err = 1; - return; - } - if (err) { - DEBUG(2, ("Oversized message\n")); + buf = talloc_strdup(NULL, ""); + if (!buf) { + DEBUG(0, ("Failed to allocate input buffer.\n")); x_fprintf(x_stderr, "ERR\n"); - err = 0; - return; + exit(1); } + do { + + /* this is not a typo - x_fgets doesn't work too well under + * squid */ + if (fgets(tmp, sizeof(tmp)-1, stdin) == NULL) { + if (ferror(stdin)) { + DEBUG(1, ("fgets() failed! dying..... errno=%d " + "(%s)\n", ferror(stdin), + strerror(ferror(stdin)))); + + exit(1); + } + exit(0); + } + + buf = talloc_strdup_append_buffer(buf, tmp); + buf_size += INITIAL_BUFFER_SIZE; + + if (buf_size > MAX_BUFFER_SIZE) { + DEBUG(2, ("Oversized message\n")); + x_fprintf(x_stderr, "ERR\n"); + talloc_free(buf); + return; + } + + c = strchr(buf, '\n'); + } while (c == NULL); + + *c = '\0'; + length = c-buf; + DEBUG(10, ("Got '%s' from squid (length: %d).\n",buf,length)); if (buf[0] == '\0') { DEBUG(2, ("Invalid Request\n")); x_fprintf(x_stderr, "ERR\n"); + talloc_free(buf); return; } - + fn(helper_mode, buf, length); + talloc_free(buf); } -- cgit From 83f30d72e02829fc0304fbeb9751e71e6aaf6c84 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 16 Jan 2008 14:45:22 +0100 Subject: ntlm_auth: Prepare for a deeper rewrite of the helper functions (This used to be commit f8243d1913cd19401ce6a13f53c6b84a36fc9dd6) --- source3/utils/ntlm_auth.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index b0c79571d2..24a49afadd 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -43,6 +43,23 @@ enum stdio_helper_mode { NUM_HELPER_MODES }; +enum ntlm_auth_con_state { + CLIENT_INITIAL, + CLIENT_RESPONSE, + CLIENT_FINISHED, + CLIENT_ERROR, + SERVER_INITIAL, + SERVER_CHALLENGE, + SERVER_FINISHED, + SERVER_ERROR +}; + +struct ntlm_auth_state { + TALLOC_CTX *mem_ctx; + enum stdio_helper_mode helper_mode; + enum ntlm_auth_con_state con_state; +}; + typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, char *buf, int length); @@ -2069,14 +2086,15 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_ } } -static void manage_squid_request(enum stdio_helper_mode helper_mode, stdio_helper_function fn) +static void manage_squid_request(struct ntlm_auth_state *state, + stdio_helper_function fn) { char *buf; char tmp[INITIAL_BUFFER_SIZE+1]; int length, buf_size = 0; char *c; - buf = talloc_strdup(NULL, ""); + buf = talloc_strdup(state->mem_ctx, ""); if (!buf) { DEBUG(0, ("Failed to allocate input buffer.\n")); x_fprintf(x_stderr, "ERR\n"); @@ -2123,17 +2141,38 @@ static void manage_squid_request(enum stdio_helper_mode helper_mode, stdio_helpe return; } - fn(helper_mode, buf, length); + fn(state->helper_mode, buf, length); talloc_free(buf); } static void squid_stream(enum stdio_helper_mode stdio_mode, stdio_helper_function fn) { + TALLOC_CTX *mem_ctx; + struct ntlm_auth_state *state; + /* initialize FDescs */ x_setbuf(x_stdout, NULL); x_setbuf(x_stderr, NULL); + + mem_ctx = talloc_init("ntlm_auth"); + if (!mem_ctx) { + DEBUG(0, ("squid_stream: Failed to create talloc context\n")); + x_fprintf(x_stderr, "ERR\n"); + exit(1); + } + + state = talloc(mem_ctx, struct ntlm_auth_state); + if (!state) { + DEBUG(0, ("squid_stream: Failed to talloc ntlm_auth_state\n")); + x_fprintf(x_stderr, "ERR\n"); + exit(1); + } + + state->mem_ctx = mem_ctx; + state->helper_mode = stdio_mode; + while(1) { - manage_squid_request(stdio_mode, fn); + manage_squid_request(state, fn); } } -- cgit From 40db1a1625da0e63e5f21ec7a7d275e5fbaf71e8 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 18 Jan 2008 10:37:16 +0100 Subject: nltm_auth: Use struct ntlm_auth_state in helper functions. Now rewriting the helpers one after the other can start. (This used to be commit 2479a0c3adf46b2d0a9b109ce689c93296f16a62) --- source3/utils/ntlm_auth.c | 74 +++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 24a49afadd..8387833540 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -43,12 +43,15 @@ enum stdio_helper_mode { NUM_HELPER_MODES }; -enum ntlm_auth_con_state { - CLIENT_INITIAL, +enum ntlm_auth_cli_state { + CLIENT_INITIAL = 0, CLIENT_RESPONSE, CLIENT_FINISHED, - CLIENT_ERROR, - SERVER_INITIAL, + CLIENT_ERROR +}; + +enum ntlm_auth_svr_state { + SERVER_INITIAL = 0, SERVER_CHALLENGE, SERVER_FINISHED, SERVER_ERROR @@ -57,31 +60,33 @@ enum ntlm_auth_con_state { struct ntlm_auth_state { TALLOC_CTX *mem_ctx; enum stdio_helper_mode helper_mode; - enum ntlm_auth_con_state con_state; + enum ntlm_auth_cli_state cli_state; + enum ntlm_auth_svr_state svr_state; }; -typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +typedef void (*stdio_helper_function)(struct ntlm_auth_state *state, char *buf, + int length); -static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode, +static void manage_squid_basic_request (struct ntlm_auth_state *state, char *buf, int length); -static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_squid_ntlmssp_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_client_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_client_ntlmssp_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_gss_spnego_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_gss_spnego_client_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_ntlm_server_1_request (enum stdio_helper_mode stdio_helper_mode, - char *buf, int length); +static void manage_ntlm_server_1_request (struct ntlm_auth_state *state, + char *buf, int length); -static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_mode, char *buf, int length); +static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state, + char *buf, int length); static const struct { enum stdio_helper_mode mode; @@ -697,8 +702,8 @@ static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_m return NT_STATUS_MORE_PROCESSING_REQUIRED; } -static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, + char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; static char* want_feature_list = NULL; @@ -816,8 +821,8 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod data_blob_free(&request); } -static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, + char *buf, int length) { /* The statics here are *HORRIBLE* and this entire concept needs to be rewritten. Essentially it's using these statics @@ -987,8 +992,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo data_blob_free(&request); } -static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_squid_basic_request(struct ntlm_auth_state *state, + char *buf, int length) { char *user, *pass; user=buf; @@ -1002,7 +1007,7 @@ static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, *pass='\0'; pass++; - if (stdio_helper_mode == SQUID_2_5_BASIC) { + if (state->helper_mode == SQUID_2_5_BASIC) { rfc1738_unescape(user); rfc1738_unescape(pass); } @@ -1071,8 +1076,8 @@ static void offer_gss_spnego_mechs(void) { return; } -static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_gss_spnego_request(struct ntlm_auth_state *state, + char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; SPNEGO_DATA request, response; @@ -1545,8 +1550,8 @@ static void manage_client_krb5_targ(SPNEGO_DATA spnego) #endif -static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_gss_spnego_client_request(struct ntlm_auth_state *state, + char *buf, int length) { DATA_BLOB request; SPNEGO_DATA spnego; @@ -1683,8 +1688,8 @@ static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper return; } -static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mode, - char *buf, int length) +static void manage_ntlm_server_1_request(struct ntlm_auth_state *state, + char *buf, int length) { char *request, *parameter; static DATA_BLOB challenge; @@ -1876,7 +1881,8 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod } } -static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_mode, char *buf, int length) +static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state, + char *buf, int length) { char *request, *parameter; static DATA_BLOB new_nt_pswd; @@ -2141,7 +2147,7 @@ static void manage_squid_request(struct ntlm_auth_state *state, return; } - fn(state->helper_mode, buf, length); + fn(state, buf, length); talloc_free(buf); } -- cgit From 4b05fd29e6f19a63194d4af6d4c499591235cfb1 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 18 Jan 2008 14:40:47 +0100 Subject: ntlm_auth: Rewrite manage_client_ntlmssp_request without statics. (This used to be commit af438426222f4990f3e4103babbbb5de03ade93d) --- source3/utils/ntlm_auth.c | 121 +++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 55 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 8387833540..751dd2001d 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -62,6 +62,12 @@ struct ntlm_auth_state { enum stdio_helper_mode helper_mode; enum ntlm_auth_cli_state cli_state; enum ntlm_auth_svr_state svr_state; + struct ntlmssp_state *ntlmssp_state; + uint32_t neg_flags; + char *want_feature_list; + bool have_session_key; + DATA_BLOB session_key; + DATA_BLOB initial_message; }; typedef void (*stdio_helper_function)(struct ntlm_auth_state *state, char *buf, @@ -824,20 +830,9 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, char *buf, int length) { - /* The statics here are *HORRIBLE* and this entire concept - needs to be rewritten. Essentially it's using these statics - as the state in a state machine. BLEEEGH ! JRA. */ - - static NTLMSSP_STATE *ntlmssp_state = NULL; - static DATA_BLOB initial_message; - static char* want_feature_list = NULL; - static uint32 neg_flags = 0; - static bool have_session_key = False; - static DATA_BLOB session_key; DATA_BLOB request, reply; NTSTATUS nt_status; - bool first = False; - + if (!opt_username || !*opt_username) { x_fprintf(x_stderr, "username must be specified!\n\n"); exit(1); @@ -852,8 +847,9 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, if (strlen(buf) > 3) { if(strncmp(buf, "SF ", 3) == 0) { DEBUG(10, ("Looking for flags to negotiate\n")); - SAFE_FREE(want_feature_list); - want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3); + talloc_free(state->want_feature_list); + state->want_feature_list = talloc_strdup(state->mem_ctx, + buf+3); x_fprintf(x_stdout, "OK\n"); return; } @@ -865,7 +861,8 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, if (strncmp(buf, "PW ", 3) == 0) { /* We asked for a password and obviously got it :-) */ - opt_password = SMB_STRNDUP((const char *)request.data, request.length); + opt_password = SMB_STRNDUP((const char *)request.data, + request.length); if (opt_password == NULL) { DEBUG(1, ("Out of memory\n")); @@ -879,8 +876,8 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, return; } - if (!ntlmssp_state && use_cached_creds) { - /* check whether credentials are usable. */ + if (!state->ntlmssp_state && use_cached_creds) { + /* check whether cached credentials are usable. */ DATA_BLOB empty_blob = data_blob_null; nt_status = do_ccache_ntlm_auth(empty_blob, empty_blob, NULL); @@ -891,31 +888,39 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, } if (opt_password == NULL && !use_cached_creds) { - /* Request a password from the calling process. After - sending it, the calling process should retry asking for the negotiate. */ - + sending it, the calling process should retry asking for the + negotiate. */ + DEBUG(10, ("Requesting password\n")); x_fprintf(x_stdout, "PW\n"); return; } if (strncmp(buf, "YR", 2) == 0) { - if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + if (state->ntlmssp_state) + ntlmssp_end(&state->ntlmssp_state); + state->cli_state = CLIENT_INITIAL; } else if (strncmp(buf, "TT", 2) == 0) { - + /* No special preprocessing required */ } else if (strncmp(buf, "GF", 2) == 0) { DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); - x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l); + + if(state->cli_state == CLIENT_FINISHED) { + x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); + } + else { + x_fprintf(x_stdout, "BH\n"); + } + data_blob_free(&request); return; } else if (strncmp(buf, "GK", 2) == 0 ) { DEBUG(10, ("Requested session key\n")); - if(have_session_key) { - char *key64 = base64_encode_data_blob(talloc_tos(), - session_key); + if(state->cli_state == CLIENT_FINISHED) { + char *key64 = base64_encode_data_blob(state->mem_ctx, + state->session_key); x_fprintf(x_stdout, "GK %s\n", key64?key64:""); TALLOC_FREE(key64); } @@ -931,39 +936,42 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, return; } - if (!ntlmssp_state) { - if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_client(&ntlmssp_state))) { + if (!state->ntlmssp_state) { + nt_status = ntlm_auth_start_ntlmssp_client( + &state->ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); return; } - ntlmssp_want_feature_list(ntlmssp_state, want_feature_list); - first = True; - initial_message = data_blob_null; + ntlmssp_want_feature_list(state->ntlmssp_state, + state->want_feature_list); + state->initial_message = data_blob_null; } DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, request.data, request.length); - if (use_cached_creds && !opt_password && !first) { - nt_status = do_ccache_ntlm_auth(initial_message, request, &reply); + if (use_cached_creds && !opt_password && + (state->cli_state == CLIENT_RESPONSE)) { + nt_status = do_ccache_ntlm_auth(state->initial_message, request, + &reply); } else { - nt_status = ntlmssp_update(ntlmssp_state, request, &reply); + nt_status = ntlmssp_update(state->ntlmssp_state, request, + &reply); } - + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - char *reply_base64 = base64_encode_data_blob(talloc_tos(), + char *reply_base64 = base64_encode_data_blob(state->mem_ctx, reply); - if (first) { + if (state->cli_state == CLIENT_INITIAL) { x_fprintf(x_stdout, "YR %s\n", reply_base64); - } else { - x_fprintf(x_stdout, "KK %s\n", reply_base64); - } - TALLOC_FREE(reply_base64); - if (first) { - initial_message = reply; + state->initial_message = reply; + state->cli_state = CLIENT_RESPONSE; } else { + x_fprintf(x_stdout, "KK %s\n", reply_base64); data_blob_free(&reply); } + TALLOC_FREE(reply_base64); DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_IS_OK(nt_status)) { char *reply_base64 = base64_encode_data_blob(talloc_tos(), @@ -971,22 +979,25 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, x_fprintf(x_stdout, "AF %s\n", reply_base64); TALLOC_FREE(reply_base64); - if(have_session_key) - data_blob_free(&session_key); + if(state->have_session_key) + data_blob_free(&state->session_key); - session_key = data_blob(ntlmssp_state->session_key.data, - ntlmssp_state->session_key.length); - neg_flags = ntlmssp_state->neg_flags; - have_session_key = True; + state->session_key = data_blob( + state->ntlmssp_state->session_key.data, + state->ntlmssp_state->session_key.length); + state->neg_flags = state->ntlmssp_state->neg_flags; + state->have_session_key = true; DEBUG(10, ("NTLMSSP OK!\n")); - if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + state->cli_state = CLIENT_FINISHED; + if (state->ntlmssp_state) + ntlmssp_end(&state->ntlmssp_state); } else { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); - if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + state->cli_state = CLIENT_ERROR; + if (state->ntlmssp_state) + ntlmssp_end(&state->ntlmssp_state); } data_blob_free(&request); @@ -2167,7 +2178,7 @@ static void squid_stream(enum stdio_helper_mode stdio_mode, stdio_helper_functio exit(1); } - state = talloc(mem_ctx, struct ntlm_auth_state); + state = talloc_zero(mem_ctx, struct ntlm_auth_state); if (!state) { DEBUG(0, ("squid_stream: Failed to talloc ntlm_auth_state\n")); x_fprintf(x_stderr, "ERR\n"); -- cgit From b133f5ac0abaa7afb7ddf67d1916a0247cf91a5c Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 19 Jan 2008 12:29:03 +0100 Subject: ntlm_auth: Get rid of statics in manage_squid_ntlmssp_request (This used to be commit 97768628f5ec533818b7f5165e92c156d668b79b) --- source3/utils/ntlm_auth.c | 87 +++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 751dd2001d..3e2093a194 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1,23 +1,24 @@ -/* +/* Unix SMB/CIFS implementation. Winbind status program. Copyright (C) Tim Potter 2000-2003 Copyright (C) Andrew Bartlett 2003-2004 - Copyright (C) Francesco Chemolli 2000 + Copyright (C) Francesco Chemolli 2000 Copyright (C) Robert O'Callahan 2006 (added cached credential code). + Copyright (C) Kai Blin 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -152,7 +153,7 @@ static char winbind_separator(void) d_printf("winbind separator was NULL!\n"); return *lp_winbind_separator(); } - + return sep; } @@ -711,11 +712,6 @@ static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_m static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, char *buf, int length) { - static NTLMSSP_STATE *ntlmssp_state = NULL; - static char* want_feature_list = NULL; - static uint32 neg_flags = 0; - static bool have_session_key = False; - static DATA_BLOB session_key; DATA_BLOB request, reply; NTSTATUS nt_status; @@ -728,8 +724,9 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, if (strlen(buf) > 3) { if(strncmp(buf, "SF ", 3) == 0){ DEBUG(10, ("Setting flags to negotioate\n")); - SAFE_FREE(want_feature_list); - want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3); + TALLOC_FREE(state->want_feature_list); + state->want_feature_list = talloc_strdup(state->mem_ctx, + buf+3); x_fprintf(x_stdout, "OK\n"); return; } @@ -739,9 +736,11 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, } if ((strncmp(buf, "PW ", 3) == 0)) { - /* The calling application wants us to use a local password (rather than winbindd) */ + /* The calling application wants us to use a local password + * (rather than winbindd) */ - opt_password = SMB_STRNDUP((const char *)request.data, request.length); + opt_password = SMB_STRNDUP((const char *)request.data, + request.length); if (opt_password == NULL) { DEBUG(1, ("Out of memory\n")); @@ -756,26 +755,33 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, } if (strncmp(buf, "YR", 2) == 0) { - if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + if (state->ntlmssp_state) + ntlmssp_end(&state->ntlmssp_state); + state->svr_state = SERVER_INITIAL; } else if (strncmp(buf, "KK", 2) == 0) { - + /* No special preprocessing required */ } else if (strncmp(buf, "GF", 2) == 0) { DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); - x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l); + + if (state->svr_state == SERVER_FINISHED) { + x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); + } + else { + x_fprintf(x_stdout, "BH\n"); + } data_blob_free(&request); return; } else if (strncmp(buf, "GK", 2) == 0) { DEBUG(10, ("Requested NTLMSSP session key\n")); - if(have_session_key) { - char *key64 = base64_encode_data_blob(talloc_tos(), - session_key); + if(state->have_session_key) { + char *key64 = base64_encode_data_blob(state->mem_ctx, + state->session_key); x_fprintf(x_stdout, "GK %s\n", key64?key64:""); TALLOC_FREE(key64); } else { x_fprintf(x_stdout, "BH\n"); } - + data_blob_free(&request); return; } else { @@ -784,44 +790,51 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, return; } - if (!ntlmssp_state) { - if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) { + if (!state->ntlmssp_state) { + nt_status = ntlm_auth_start_ntlmssp_server( + &state->ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); return; } - ntlmssp_want_feature_list(ntlmssp_state, want_feature_list); + ntlmssp_want_feature_list(state->ntlmssp_state, + state->want_feature_list); } DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, request.data, request.length); - nt_status = ntlmssp_update(ntlmssp_state, request, &reply); - + nt_status = ntlmssp_update(state->ntlmssp_state, request, &reply); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - char *reply_base64 = base64_encode_data_blob(talloc_tos(), + char *reply_base64 = base64_encode_data_blob(state->mem_ctx, reply); x_fprintf(x_stdout, "TT %s\n", reply_base64); TALLOC_FREE(reply_base64); data_blob_free(&reply); + state->svr_state = SERVER_CHALLENGE; DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); - ntlmssp_end(&ntlmssp_state); + ntlmssp_end(&state->ntlmssp_state); } else if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); } else { - x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context); + x_fprintf(x_stdout, "AF %s\n", + (char *)state->ntlmssp_state->auth_context); DEBUG(10, ("NTLMSSP OK!\n")); - - if(have_session_key) - data_blob_free(&session_key); - session_key = data_blob(ntlmssp_state->session_key.data, - ntlmssp_state->session_key.length); - neg_flags = ntlmssp_state->neg_flags; - have_session_key = True; + + if(state->have_session_key) + data_blob_free(&state->session_key); + state->session_key = data_blob( + state->ntlmssp_state->session_key.data, + state->ntlmssp_state->session_key.length); + state->neg_flags = state->ntlmssp_state->neg_flags; + state->have_session_key = true; + state->svr_state = SERVER_FINISHED; } data_blob_free(&request); -- cgit From 398c323f7544e815cfeb2b750f9ff28061c294f3 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 19 Jan 2008 12:27:31 +0100 Subject: afs: Use talloc_stackframe() instead of talloc_init() Thanks to vl for pointing this out. (This used to be commit 76cf5a979bf3014b1de660520e538546b3676b23) --- source3/lib/afs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/afs.c b/source3/lib/afs.c index b3d590bf24..9f5d81f442 100644 --- a/source3/lib/afs.c +++ b/source3/lib/afs.c @@ -48,7 +48,7 @@ static char *afs_encode_token(const char *cell, const DATA_BLOB ticket, char *base64_key; TALLOC_CTX *mem_ctx; - mem_ctx = talloc_init("afs_encode_token"); + mem_ctx = talloc_stackframe(); if (mem_ctx == NULL) goto done; -- cgit From 5a48ee89b8527534064439678f98365057912d77 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 13:37:40 +0100 Subject: Fix the build ... forgot to "git add" it (This used to be commit 6d0a727f26dd0945634486f18a55aa8dd5813983) --- source3/include/includes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/include/includes.h b/source3/include/includes.h index e9477d8ba1..7eca8d3ddf 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -702,6 +702,7 @@ typedef char fstring[FSTRING_LEN]; #include "rpc_perfcount.h" #include "rpc_perfcount_defs.h" #include "librpc/gen_ndr/notify.h" +#include "librpc/gen_ndr/xattr.h" #include "nt_printing.h" #include "idmap.h" #include "client.h" -- cgit From 6d7eb2e6ecec5920fe347c5d75d8596bd289eecf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Jan 2008 13:22:39 +0100 Subject: Make get_ea_value public (This used to be commit 0aa406bbba8699063ea3758b19dca24cf42ff15a) --- source3/smbd/trans2.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 935a881607..12b0f20879 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -114,8 +114,9 @@ static bool samba_private_attr_name(const char *unix_ea_name) Get one EA value. Fill in a struct ea_struct. ****************************************************************************/ -static bool get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, - const char *fname, char *ea_name, struct ea_struct *pea) +NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, + files_struct *fsp, const char *fname, + const char *ea_name, struct ea_struct *pea) { /* Get the value of this xattr. Max size is 64k. */ size_t attr_size = 256; @@ -126,7 +127,7 @@ static bool get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size); if (!val) { - return False; + return NT_STATUS_NO_MEMORY; } if (fsp && fsp->fh->fd != -1) { @@ -141,7 +142,7 @@ static bool get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str } if (sizeret == -1) { - return False; + return map_nt_error_from_unix(errno); } DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret)); @@ -149,13 +150,17 @@ static bool get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str pea->flags = 0; if (strnequal(ea_name, "user.", 5)) { - pea->name = &ea_name[5]; + pea->name = talloc_strdup(mem_ctx, &ea_name[5]); } else { - pea->name = ea_name; + pea->name = talloc_strdup(mem_ctx, ea_name); + } + if (pea->name == NULL) { + TALLOC_FREE(val); + return NT_STATUS_NO_MEMORY; } pea->value.data = (unsigned char *)val; pea->value.length = (size_t)sizeret; - return True; + return NT_STATUS_OK; } /**************************************************************************** @@ -215,7 +220,9 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str if (!listp) return NULL; - if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) { + if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx, conn, fsp, + fname, p, + &listp->ea))) { return NULL; } -- cgit From 84518f1fc74437c61b79080671f3adfd809b2c32 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 16:07:56 +0100 Subject: Add get_ea_names_from_file to sanely list posix xattrs Refactor get_ea_list_from_file to use that. (This used to be commit aec357a456798050abe565d2a744ed5f17ad5901) --- source3/smbd/trans2.c | 191 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 142 insertions(+), 49 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 12b0f20879..53eff65b54 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -163,86 +163,179 @@ NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, return NT_STATUS_OK; } -/**************************************************************************** - Return a linked list of the total EA's. Plus the total size -****************************************************************************/ - -static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, - const char *fname, size_t *pea_total_len) +NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, + files_struct *fsp, const char *fname, + char ***pnames, size_t *pnum_names) { /* Get a list of all xattrs. Max namesize is 64k. */ size_t ea_namelist_size = 1024; - char *ea_namelist; + char *ea_namelist = NULL; + char *p; + char **names, **tmp; + size_t num_names; ssize_t sizeret; - int i; - struct ea_list *ea_list_head = NULL; - - *pea_total_len = 0; if (!lp_ea_support(SNUM(conn))) { - return NULL; + *pnames = NULL; + *pnum_names = 0; + return NT_STATUS_OK; } - for (i = 0, ea_namelist = TALLOC_ARRAY(mem_ctx, char, ea_namelist_size); i < 6; - ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) { + /* + * TALLOC the result early to get the talloc hierarchy right. + */ - if (!ea_namelist) { - return NULL; + names = TALLOC_ARRAY(mem_ctx, char *, 1); + if (names == NULL) { + DEBUG(0, ("talloc failed\n")); + return NT_STATUS_NO_MEMORY; + } + + while (ea_namelist_size <= 65536) { + + ea_namelist = TALLOC_REALLOC_ARRAY( + names, ea_namelist, char, ea_namelist_size); + if (ea_namelist == NULL) { + DEBUG(0, ("talloc failed\n")); + TALLOC_FREE(names); + return NT_STATUS_NO_MEMORY; } if (fsp && fsp->fh->fd != -1) { - sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist, ea_namelist_size); + sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist, + ea_namelist_size); } else { - sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size); + sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, + ea_namelist_size); } - if (sizeret == -1 && errno == ERANGE) { + if ((sizeret == -1) && (errno = ERANGE)) { ea_namelist_size *= 2; - } else { + } + else { break; } } - if (sizeret == -1) - return NULL; + if (sizeret == -1) { + TALLOC_FREE(names); + return map_nt_error_from_unix(errno); + } - DEBUG(10,("get_ea_list_from_file: ea_namelist size = %u\n", (unsigned int)sizeret )); + DEBUG(10, ("get_ea_list_from_file: ea_namelist size = %u\n", + (unsigned int)sizeret)); - if (sizeret) { - for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) { - struct ea_list *listp; + if (sizeret == 0) { + TALLOC_FREE(names); + *pnames = NULL; + *pnum_names = 0; + return NT_STATUS_OK; + } - if (strnequal(p, "system.", 7) || samba_private_attr_name(p)) - continue; + /* + * Ensure the result is 0-terminated + */ - listp = TALLOC_P(mem_ctx, struct ea_list); - if (!listp) - return NULL; + if (ea_namelist[sizeret-1] != '\0') { + TALLOC_FREE(names); + return NT_STATUS_INTERNAL_ERROR; + } - if (!NT_STATUS_IS_OK(get_ea_value(mem_ctx, conn, fsp, - fname, p, - &listp->ea))) { - return NULL; - } + /* + * count the names + */ + num_names = 0; - { - fstring dos_ea_name; - push_ascii_fstring(dos_ea_name, listp->ea.name); - *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length; - DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n", - (unsigned int)*pea_total_len, dos_ea_name, - (unsigned int)listp->ea.value.length )); - } - DLIST_ADD_END(ea_list_head, listp, struct ea_list *); + for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) { + num_names += 1; + } + + tmp = TALLOC_REALLOC_ARRAY(mem_ctx, names, char *, num_names); + if (tmp == NULL) { + DEBUG(0, ("talloc failed\n")); + TALLOC_FREE(names); + return NT_STATUS_NO_MEMORY; + } + + names = tmp; + num_names = 0; + + for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) { + names[num_names++] = p; + } + + *pnames = names; + *pnum_names = num_names; + return NT_STATUS_OK; +} + +/**************************************************************************** + Return a linked list of the total EA's. Plus the total size +****************************************************************************/ + +static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, + const char *fname, size_t *pea_total_len) +{ + /* Get a list of all xattrs. Max namesize is 64k. */ + size_t i, num_names; + char **names; + struct ea_list *ea_list_head = NULL; + NTSTATUS status; + + *pea_total_len = 0; + + if (!lp_ea_support(SNUM(conn))) { + return NULL; + } + + status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname, + &names, &num_names); + + if (!NT_STATUS_IS_OK(status) || (num_names == 0)) { + return NULL; + } + + for (i=0; iea))) { + return NULL; } + + push_ascii_fstring(dos_ea_name, listp->ea.name); + + *pea_total_len += + 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length; + + DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len " + "= %u\n", (unsigned int)*pea_total_len, dos_ea_name, + (unsigned int)listp->ea.value.length)); + + DLIST_ADD_END(ea_list_head, listp, struct ea_list *); + } - DEBUG(10,("get_ea_list_from_file: total_len = %u\n", (unsigned int)*pea_total_len)); + /* Add on 4 for total length. */ + if (*pea_total_len) { + *pea_total_len += 4; + } + + DEBUG(10, ("get_ea_list_from_file: total_len = %u\n", + (unsigned int)*pea_total_len)); + return ea_list_head; } -- cgit From 3b889a256b6e2414d92c948d2e741773294e7ac9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 16:19:08 +0100 Subject: The remote storage op is gone Alexander, I think this ok... (This used to be commit 197b08ad789c4968155f1c711ef43a5383a89289) --- source3/include/vfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index d03cf3477d..3109a5c3e4 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -103,7 +103,7 @@ /* Leave at 22 - not yet released. Remove parameter fd from write. - obnox */ /* Leave at 22 - not yet released. Remove parameter fromfd from sendfile. - obnox */ /* Leave at 22 - not yet released. Remove parameter fromfd from recvfile. - obnox */ -/* Leave at 22 - not yet released. Additional change: add operations for offline files and remote storage volume abstraction -- ab*/ +/* Leave at 22 - not yet released. Additional change: add operations for offline files -- ab */ #define SMB_VFS_INTERFACE_VERSION 22 -- cgit From 70f88005c77cee0848a495da139144206b53eb3f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 15:44:48 +0100 Subject: Fix error return in xattr_tdb_load_attrs (This used to be commit 64e54ea8f76fe57193955aabc1459fe635233aca) --- source3/modules/vfs_xattr_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 29864a8f94..597dd38eaf 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -110,7 +110,7 @@ static NTSTATUS xattr_tdb_load_attrs(TALLOC_CTX *mem_ctx, status = xattr_tdb_pull_attrs(mem_ctx, &data, presult); TALLOC_FREE(data.dptr); - return NT_STATUS_OK; + return status; } /* -- cgit From a0bd9d97a3a701fdb1f9a48ce925f63b786a8070 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 19 Jan 2008 15:14:45 +0100 Subject: Tiny memory leak in lib/version.c Hi, while implementing the extra_info version stuff, it occured to me that samba_version_string() potentially allocates memory which is unused but never free'd. If SAMBA_VERSION_VENDOR_PATCH is defined, a second call to asprintf takes place. The result is stored in tmp_version. Afterwards, samba_version is set to tmp_version without free'ing samba_version first. Looks like a simple free(samba_version) is missing. Patch against 3.2-test below. Ok, this only happens once over the lifetime of the application, so it's no big deal, but I though it doesn't hurt to mention it. Corinna * lib/version.c (samba_version_string): Free samba_version before setting to tmp_version. (This used to be commit 373a23d48f2dd24e65dbf814ea58b4add2322128) --- source3/lib/version.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/lib/version.c b/source3/lib/version.c index 204c2044a8..cbb70ae8a6 100644 --- a/source3/lib/version.c +++ b/source3/lib/version.c @@ -51,6 +51,7 @@ const char *samba_version_string(void) */ assert(res != -1); + free(samba_version); samba_version = tmp_version; #endif -- cgit From 07e07f696ad10f3a5d7a0d9de656ff13600ac97d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 19:31:02 +0100 Subject: Use SAFE_FREE instead of free (This used to be commit 999647329028147d7c29a3348202641b3e03430e) --- source3/lib/version.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/lib/version.c b/source3/lib/version.c index cbb70ae8a6..3cae02ad2e 100644 --- a/source3/lib/version.c +++ b/source3/lib/version.c @@ -51,7 +51,8 @@ const char *samba_version_string(void) */ assert(res != -1); - free(samba_version); + SAFE_FREE(samba_version); + samba_version = tmp_version; #endif -- cgit From 1b976d51928dd6fa923272d277e13e5267188869 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 20:41:15 +0100 Subject: Add the STREAMINFO vfs call Based on jpeach's work, modified the streaminfo prototype Make use of it in trans2.c together with marshall_stream_info() (This used to be commit c34d729c7c0600a8f11bf7e489a634a4e37fe88e) --- source3/include/vfs.h | 10 ++++ source3/include/vfs_macros.h | 3 ++ source3/modules/vfs_default.c | 59 ++++++++++++++++++++++ source3/smbd/trans2.c | 112 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 171 insertions(+), 13 deletions(-) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 3109a5c3e4..cda28a1680 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -104,6 +104,7 @@ /* Leave at 22 - not yet released. Remove parameter fromfd from sendfile. - obnox */ /* Leave at 22 - not yet released. Remove parameter fromfd from recvfile. - obnox */ /* Leave at 22 - not yet released. Additional change: add operations for offline files -- ab */ +/* Leave at 22 - not yet released. Add the streaminfo call. -- jpeach, vl */ #define SMB_VFS_INTERFACE_VERSION 22 @@ -198,6 +199,7 @@ typedef enum _vfs_op_type { SMB_VFS_OP_NOTIFY_WATCH, SMB_VFS_OP_CHFLAGS, SMB_VFS_OP_FILE_ID_CREATE, + SMB_VFS_OP_STREAMINFO, /* NT ACL operations. */ @@ -339,6 +341,13 @@ struct vfs_ops { int (*chflags)(struct vfs_handle_struct *handle, const char *path, unsigned int flags); struct file_id (*file_id_create)(struct vfs_handle_struct *handle, SMB_DEV_T dev, SMB_INO_T inode); + NTSTATUS (*streaminfo)(struct vfs_handle_struct *handle, + struct files_struct *fsp, + const char *fname, + TALLOC_CTX *mem_ctx, + unsigned int *num_streams, + struct stream_struct **streams); + /* NT ACL operations. */ NTSTATUS (*fget_nt_acl)(struct vfs_handle_struct *handle, @@ -476,6 +485,7 @@ struct vfs_ops { struct vfs_handle_struct *notify_watch; struct vfs_handle_struct *chflags; struct vfs_handle_struct *file_id_create; + struct vfs_handle_struct *streaminfo; /* NT ACL operations. */ diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index dd30f977dc..1674f26326 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -82,6 +82,7 @@ #define SMB_VFS_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs.ops.notify_watch((conn)->vfs.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p))) #define SMB_VFS_CHFLAGS(conn, path, flags) ((conn)->vfs.ops.chflags((conn)->vfs.handles.chflags, (path), (flags))) #define SMB_VFS_FILE_ID_CREATE(conn, dev, inode) ((conn)->vfs.ops.file_id_create((conn)->vfs.handles.file_id_create, (dev), (inode))) +#define SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams) ((conn)->vfs.ops.streaminfo((conn)->vfs.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams))) /* NT ACL operations. */ #define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs.ops.fget_nt_acl((fsp)->conn->vfs.handles.fget_nt_acl, (fsp), (security_info), (ppdesc))) @@ -206,6 +207,7 @@ #define SMB_VFS_OPAQUE_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs_opaque.ops.notify_watch((conn)->vfs_opaque.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p))) #define SMB_VFS_OPAQUE_CHFLAGS(conn, path, flags) ((conn)->vfs_opaque.ops.chflags((conn)->vfs_opaque.handles.chflags, (path), (flags))) #define SMB_VFS_OPAQUE_FILE_ID_CREATE(conn, dev, inode) ((conn)->vfs.ops_opaque.file_id_create((conn)->vfs_opaque.handles.file_id_create, (dev), (inode))) +#define SMB_VFS_OPAQUE_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams) ((conn)->vfs_opaque.ops.streaminfo((conn)->vfs_opaque.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams))) /* NT ACL operations. */ #define SMB_VFS_OPAQUE_FGET_NT_ACL(fsp, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.fget_nt_acl((fsp)->conn->vfs_opaque.handles.fget_nt_acl, (fsp), (security_info), (ppdesc))) @@ -331,6 +333,7 @@ #define SMB_VFS_NEXT_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs_next.ops.notify_watch((conn)->vfs_next.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p))) #define SMB_VFS_NEXT_CHFLAGS(handle, path, flags) ((handle)->vfs_next.ops.chflags((handle)->vfs_next.handles.chflags, (path), (flags))) #define SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode) ((handle)->vfs_next.ops.file_id_create((handle)->vfs_next.handles.file_id_create, (dev), (inode))) +#define SMB_VFS_NEXT_STREAMINFO(handle, fsp, fname, mem_ctx, num_streams, streams) ((handle)->vfs.ops.streaminfo((handle)->vfs.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams))) /* NT ACL operations. */ #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (security_info), (ppdesc))) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 31234f23ec..2e620d04cc 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -942,6 +942,63 @@ static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, S return file_id_create_dev(dev, inode); } +static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle, + struct files_struct *fsp, + const char *fname, + TALLOC_CTX *mem_ctx, + unsigned int *pnum_streams, + struct stream_struct **pstreams) +{ + SMB_STRUCT_STAT sbuf; + NTSTATUS status; + unsigned int num_streams = 0; + struct stream_struct *streams = NULL; + int ret; + + if ((fsp != NULL) && (fsp->is_directory)) { + /* + * No default streams on directories + */ + goto done; + } + + if ((fsp != NULL) && (fsp->fh->fd != -1)) { + ret = SMB_VFS_FSTAT(fsp, &sbuf); + } + else { + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + if (S_ISDIR(sbuf.st_mode)) { + goto done; + } + + streams = talloc(mem_ctx, struct stream_struct); + + if (streams == NULL) { + return NT_STATUS_NO_MEMORY; + } + + streams->size = sbuf.st_size; + streams->alloc_size = get_allocation_size(handle->conn, fsp, &sbuf); + + streams->name = talloc_strdup(streams, "::$DATA"); + if (streams->name == NULL) { + TALLOC_FREE(streams); + return NT_STATUS_NO_MEMORY; + } + + num_streams = 1; + done: + *pnum_streams = num_streams; + *pstreams = streams; + return NT_STATUS_OK; +} + static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) @@ -1367,6 +1424,8 @@ static vfs_op_tuple vfs_default_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_file_id_create), SMB_VFS_OP_FILE_ID_CREATE, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_streaminfo), SMB_VFS_OP_STREAMINFO, + SMB_VFS_LAYER_OPAQUE}, /* NT ACL operations. */ diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 53eff65b54..d56a0dab09 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5,7 +5,7 @@ Copyright (C) Stefan (metze) Metzmacher 2003 Copyright (C) Volker Lendecke 2005-2007 Copyright (C) Steve French 2005 - Copyright (C) James Peach 2007 + Copyright (C) James Peach 2006-2007 Extensively modified by Andrew Tridgell, 1995 @@ -3568,6 +3568,72 @@ static char *store_file_unix_basic_info2(connection_struct *conn, return pdata; } +static NTSTATUS marshall_stream_info(unsigned int num_streams, + const struct stream_struct *streams, + char *data, + unsigned int max_data_bytes, + unsigned int *data_size) +{ + unsigned int i; + unsigned int ofs = 0; + + for (i=0; i max_data_bytes) { + TALLOC_FREE(namebuf); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + SIVAL(data, ofs+4, namelen); + SOFF_T(data, ofs+8, streams[i].size); + SOFF_T(data, ofs+16, streams[i].alloc_size); + memcpy(data+ofs+24, namebuf, namelen); + TALLOC_FREE(namebuf); + + next_offset = ofs + 24 + namelen; + + if (i == num_streams-1) { + SIVAL(data, ofs, 0); + } + else { + unsigned int align = ndr_align_size(next_offset, 8); + + if (next_offset + align > max_data_bytes) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + memset(data+next_offset, 0, align); + next_offset += align; + + SIVAL(data, ofs, next_offset - ofs); + ofs = next_offset; + } + + ofs = next_offset; + } + + *data_size = ofs; + + return NT_STATUS_OK; +} + /**************************************************************************** Reply to a TRANSACT2_QFILEINFO on a PIPE ! ****************************************************************************/ @@ -4273,20 +4339,40 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd */ case SMB_QUERY_FILE_STREAM_INFO: #endif - case SMB_FILE_STREAM_INFORMATION: - DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n")); - if (mode & aDIR) { - data_size = 0; - } else { - size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", (size_t)0xE, False); - SIVAL(pdata,0,0); /* ??? */ - SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */ - SOFF_T(pdata,8,file_size); - SOFF_T(pdata,16,allocation_size); - data_size = 24 + byte_len; + case SMB_FILE_STREAM_INFORMATION: { + unsigned int num_streams; + struct stream_struct *streams; + NTSTATUS status; + + DEBUG(10,("call_trans2qfilepathinfo: " + "SMB_FILE_STREAM_INFORMATION\n")); + + status = SMB_VFS_STREAMINFO( + conn, fsp, fname, talloc_tos(), + &num_streams, &streams); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("could not get stream info: %s\n", + nt_errstr(status))); + reply_nterror(req, status); + return; } - break; + status = marshall_stream_info(num_streams, streams, + pdata, max_data_bytes, + &data_size); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("marshall_stream_info failed: %s\n", + nt_errstr(status))); + reply_nterror(req, status); + return; + } + + TALLOC_FREE(streams); + + break; + } case SMB_QUERY_COMPRESSION_INFO: case SMB_FILE_COMPRESSION_INFORMATION: DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n")); -- cgit From 14e7c292bc76b0edb8cafcaa728a612fa806fa6d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 22:44:55 +0100 Subject: Add an error mapping for ENOATTR (This used to be commit 9f0d778490415b05224f36287df999672ee16928) --- source3/lib/errmap_unix.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c index 885a1c55b2..8194cf80cc 100644 --- a/source3/lib/errmap_unix.c +++ b/source3/lib/errmap_unix.c @@ -92,6 +92,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = { #ifdef EWOULDBLOCK { EWOULDBLOCK, ERRDOS, 111, NT_STATUS_NETWORK_BUSY }, #endif +#ifdef ENOATTR + { ENOATTR, ERRDOS, ERRbadfile, NT_STATUS_NOT_FOUND }, +#endif { 0, 0, 0, NT_STATUS_OK } }; -- cgit From 2411c6cb90e485bd289b8b654db1c632556bfb2d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 23:10:09 +0100 Subject: Add "split_ntfs_stream_name()" together with a torture test (This used to be commit d813bd9e02d9baf916eb96c478be89f0c435e07c) --- source3/lib/util.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++ source3/smbd/nttrans.c | 3 ++ source3/torture/torture.c | 69 ++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+) diff --git a/source3/lib/util.c b/source3/lib/util.c index bc3eaa8d5e..11f3660df8 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -3273,3 +3273,93 @@ void *talloc_zeronull(const void *context, size_t size, const char *name) return talloc_named_const(context, size, name); } #endif + +/* Split a path name into filename and stream name components. Canonicalise + * such that an implicit $DATA token is always explicit. + * + * The "specification" of this function can be found in the + * run_local_stream_name() function in torture.c, I've tried those + * combinations against a W2k3 server. + */ + +NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, + char **pbase, char **pstream) +{ + char *base = NULL; + char *stream = NULL; + char *sname; /* stream name */ + const char *stype; /* stream type */ + + DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname)); + + sname = strchr_m(fname, ':'); + + if (lp_posix_pathnames() || (sname == NULL)) { + if (pbase != NULL) { + base = talloc_strdup(mem_ctx, fname); + NT_STATUS_HAVE_NO_MEMORY(base); + } + goto done; + } + + if (pbase != NULL) { + base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname)); + NT_STATUS_HAVE_NO_MEMORY(base); + } + + sname += 1; + + stype = strchr_m(sname, ':'); + + if (stype == NULL) { + sname = talloc_strdup(mem_ctx, sname); + stype = "$DATA"; + } + else { + if (StrCaseCmp(stype, ":$DATA") != 0) { + /* + * If there is an explicit stream type, so far we only + * allow $DATA. Is there anything else allowed? -- vl + */ + DEBUG(10, ("[%s] is an invalid stream type\n", stype)); + TALLOC_FREE(base); + return NT_STATUS_OBJECT_NAME_INVALID; + } + sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname)); + stype += 1; + } + + if (sname == NULL) { + TALLOC_FREE(base); + return NT_STATUS_NO_MEMORY; + } + + if (sname[0] == '\0') { + /* + * no stream name, so no stream + */ + goto done; + } + + if (pstream != NULL) { + stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype); + if (stream == NULL) { + TALLOC_FREE(sname); + TALLOC_FREE(base); + return NT_STATUS_NO_MEMORY; + } + /* + * upper-case the type field + */ + strupper_m(strchr_m(stream, ':')+1); + } + + done: + if (pbase != NULL) { + *pbase = base; + } + if (pstream != NULL) { + *pstream = stream; + } + return NT_STATUS_OK; +} diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index e8df732ea2..9381174af0 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -271,6 +271,9 @@ void send_nt_replies(connection_struct *conn, /**************************************************************************** Is it an NTFS stream name ? + An NTFS file name is .:: + $DATA can be used as both a stream name and a stream type. A missing stream + name or type implies $DATA. ****************************************************************************/ bool is_ntfs_stream_name(const char *fname) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 05b41413b4..070474cf6f 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5098,6 +5098,74 @@ static bool run_local_rbtree(int dummy) return ret; } +static bool test_stream_name(const char *fname, const char *expected_base, + const char *expected_stream, + NTSTATUS expected_status) +{ + NTSTATUS status; + char *base = NULL; + char *stream = NULL; + + status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream); + if (!NT_STATUS_EQUAL(status, expected_status)) { + goto error; + } + + if (!NT_STATUS_IS_OK(status)) { + return true; + } + + if (base == NULL) goto error; + + if (strcmp(expected_base, base) != 0) goto error; + + if ((expected_stream != NULL) && (stream == NULL)) goto error; + if ((expected_stream == NULL) && (stream != NULL)) goto error; + + if ((stream != NULL) && (strcmp(expected_stream, stream) != 0)) + goto error; + + TALLOC_FREE(base); + TALLOC_FREE(stream); + return true; + + error: + d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n", + fname, expected_base ? expected_base : "", + expected_stream ? expected_stream : "", + nt_errstr(expected_status)); + d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n", + base ? base : "", stream ? stream : "", + nt_errstr(status)); + TALLOC_FREE(base); + TALLOC_FREE(stream); + return false; +} + +static bool run_local_stream_name(int dummy) +{ + bool ret = true; + + ret &= test_stream_name( + "bla", "bla", NULL, NT_STATUS_OK); + ret &= test_stream_name( + "bla::$DATA", "bla", NULL, NT_STATUS_OK); + ret &= test_stream_name( + "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID); + ret &= test_stream_name( + "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID); + ret &= test_stream_name( + "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID); + ret &= test_stream_name( + "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK); + ret &= test_stream_name( + "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK); + ret &= test_stream_name( + "bla:x", "bla", "x:$DATA", NT_STATUS_OK); + + return ret; +} + static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b) { if (a.length != b.length) { @@ -5328,6 +5396,7 @@ static struct { { "LOCAL-GENCACHE", run_local_gencache, 0}, { "LOCAL-RBTREE", run_local_rbtree, 0}, { "LOCAL-MEMCACHE", run_local_memcache, 0}, + { "LOCAL-STREAM-NAME", run_local_stream_name, 0}, {NULL, NULL, 0}}; -- cgit From 1069cfe4ade88a032164c1242c9480a544584655 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 23:25:36 +0100 Subject: Add streams support This is the core of the streams support. The main change is that in files_struct there is now a base_fsp pointer that holds the main file open while a stream is open. This is necessary to get the rather strange delete semantics right: You can't delete the main file while a stream is open without FILE_SHARE_DELETE, and while a stream is open a successful unlink of the main file leads to DELETE_PENDING for all further access on the main file or any stream. (This used to be commit 6022873cc155bdbbd3fb620689715f07a24d6ed1) --- source3/include/smb.h | 5 ++ source3/smbd/close.c | 115 +++++++++++++++++++++++++- source3/smbd/filename.c | 121 +++++++++++++++++++++++++++ source3/smbd/open.c | 214 +++++++++++++++++++++++++++++++++++++++++++++--- source3/smbd/reply.c | 28 +++++-- 5 files changed, 459 insertions(+), 24 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index 15e51dbdd7..25421115c8 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -513,6 +513,8 @@ typedef struct files_struct { FAKE_FILE_HANDLE *fake_file_handle; struct notify_change_buf *notify; + + struct files_struct *base_fsp; /* placeholder for delete on close */ } files_struct; #include "ntquotas.h" @@ -1369,6 +1371,9 @@ struct bitmap { #define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 #define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 +/* Private options for streams support */ +#define NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE 0x04000000 + /* Responses when opening a file. */ #define FILE_WAS_SUPERSEDED 0 #define FILE_WAS_OPENED 1 diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 4c385d7611..4bd23a35fc 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -155,6 +155,75 @@ static void notify_deferred_opens(struct share_mode_lock *lck) } } +/**************************************************************************** + Delete all streams +****************************************************************************/ + +static NTSTATUS delete_all_streams(connection_struct *conn, const char *fname) +{ + struct stream_struct *stream_info; + int i; + unsigned int num_streams; + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; + + status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(), + &num_streams, &stream_info); + + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { + DEBUG(10, ("no streams around\n")); + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n", + nt_errstr(status))); + goto fail; + } + + DEBUG(10, ("delete_all_streams found %d streams\n", + num_streams)); + + if (num_streams == 0) { + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + + for (i=0; ifs_capabilities & FILE_NAMED_STREAMS) + && !is_ntfs_stream_name(fsp->fsp_name)) { + + status = delete_all_streams(conn, fsp->fsp_name); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5, ("delete_all_streams failed: %s\n", + nt_errstr(status))); + goto done; + } + } + + if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) { /* * This call can potentially fail as another smbd may @@ -570,12 +652,37 @@ static NTSTATUS close_stat(files_struct *fsp) NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type) { + NTSTATUS status; + struct files_struct *base_fsp = fsp->base_fsp; + if(fsp->is_directory) { - return close_directory(fsp, close_type); + status = close_directory(fsp, close_type); } else if (fsp->is_stat) { - return close_stat(fsp); + status = close_stat(fsp); } else if (fsp->fake_file_handle != NULL) { - return close_fake_file(fsp); + status = close_fake_file(fsp); + } else { + status = close_normal_file(fsp, close_type); + } + + if (!NT_STATUS_IS_OK(status)) { + return status; } - return close_normal_file(fsp, close_type); + + if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) { + + /* + * fsp was a stream, the base fsp can't be a stream as well + * + * For SHUTDOWN_CLOSE this is not possible here, because + * SHUTDOWN_CLOSE only happens from files.c which walks the + * complete list of files. If we mess with more than one fsp + * those loops will become confused. + */ + + SMB_ASSERT(base_fsp->base_fsp == NULL); + close_file(base_fsp, close_type); + } + + return status; } diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index be4960cab8..1d44c7498e 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -28,6 +28,13 @@ static bool scan_directory(connection_struct *conn, const char *path, char *name, char **found_name); +static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, + connection_struct *conn, + const char *orig_path, + const char *basepath, + const char *streamname, + SMB_STRUCT_STAT *pst, + char **path); /**************************************************************************** Mangle the 2nd name and check if it is then equal to the first name. @@ -119,6 +126,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, char *start, *end; char *dirpath = NULL; char *name = NULL; + char *stream = NULL; bool component_was_mangled = False; bool name_has_wildcard = False; NTSTATUS result; @@ -206,6 +214,18 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, return NT_STATUS_NO_MEMORY; } + stream = strchr_m(name, ':'); + + if (stream != NULL) { + char *tmp = talloc_strdup(ctx, stream); + if (tmp == NULL) { + TALLOC_FREE(name); + return NT_STATUS_NO_MEMORY; + } + *stream = '\0'; + stream = tmp; + } + /* * Large directory fix normalization. If we're case sensitive, and * the case preserving parameters are set to "no", normalize the case of @@ -653,6 +673,20 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, DEBUG(5,("conversion finished %s -> %s\n",orig_path, name)); done: + if (stream != NULL) { + char *tmp = NULL; + + result = build_stream_path(ctx, conn, orig_path, name, stream, + pst, &tmp); + if (!NT_STATUS_IS_OK(result)) { + goto fail; + } + + DEBUG(10, ("build_stream_path returned %s\n", tmp)); + + TALLOC_FREE(name); + name = tmp; + } *pp_conv_path = name; TALLOC_FREE(dirpath); return NT_STATUS_OK; @@ -823,3 +857,90 @@ static bool scan_directory(connection_struct *conn, const char *path, errno = ENOENT; return False; } + +static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, + connection_struct *conn, + const char *orig_path, + const char *basepath, + const char *streamname, + SMB_STRUCT_STAT *pst, + char **path) +{ + SMB_STRUCT_STAT st; + char *result = NULL; + NTSTATUS status; + unsigned int i, num_streams; + struct stream_struct *streams = NULL; + + result = talloc_asprintf(mem_ctx, "%s%s", basepath, streamname); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (SMB_VFS_STAT(conn, result, &st) == 0) { + *pst = st; + *path = result; + return NT_STATUS_OK; + } + + if (errno != ENOENT) { + status = map_nt_error_from_unix(errno); + DEBUG(10, ("vfs_stat failed: %s\n", nt_errstr(status))); + goto fail; + } + + status = SMB_VFS_STREAMINFO(conn, NULL, basepath, mem_ctx, + &num_streams, &streams); + + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + SET_STAT_INVALID(*pst); + *path = result; + return NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("vfs_streaminfo failed: %s\n", nt_errstr(status))); + goto fail; + } + + for (i=0; icase_sensitive)) { + DEBUGADD(10, ("equal\n")); + break; + } + DEBUGADD(10, ("not equal\n")); + } + + if (i == num_streams) { + SET_STAT_INVALID(*pst); + *path = result; + TALLOC_FREE(streams); + return NT_STATUS_OK; + } + + TALLOC_FREE(result); + + result = talloc_asprintf(mem_ctx, "%s%s", basepath, streams[i].name); + if (result == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + SET_STAT_INVALID(*pst); + + if (SMB_VFS_STAT(conn, result, pst) == 0) { + stat_cache_add(orig_path, result, conn->case_sensitive); + } + + *path = result; + TALLOC_FREE(streams); + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + TALLOC_FREE(streams); + return status; +} diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 9d48bcc98b..0d6e07a032 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1842,7 +1842,9 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, set_share_mode(lck, fsp, current_user.ut.uid, 0, fsp->oplock_type, new_file_created); /* Handle strange delete on close create semantics. */ - if ((create_options & FILE_DELETE_ON_CLOSE) && can_set_initial_delete_on_close(lck)) { + if ((create_options & FILE_DELETE_ON_CLOSE) + && (is_ntfs_stream_name(fname) + || can_set_initial_delete_on_close(lck))) { status = can_set_delete_on_close(fsp, True, new_dos_attributes); if (!NT_STATUS_IS_OK(status)) { @@ -2443,6 +2445,115 @@ static struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx return result; } +/* + * If a main file is opened for delete, all streams need to be checked for + * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS. + * If that works, delete them all by setting the delete on close and close. + */ + +static NTSTATUS open_streams_for_delete(connection_struct *conn, + const char *fname) +{ + struct stream_struct *stream_info; + files_struct **streams; + int i; + unsigned int num_streams; + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; + + status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(), + &num_streams, &stream_info); + + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { + DEBUG(10, ("no streams around\n")); + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n", + nt_errstr(status))); + goto fail; + } + + DEBUG(10, ("open_streams_for_delete found %d streams\n", + num_streams)); + + if (num_streams == 0) { + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + + streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams); + if (streams == NULL) { + DEBUG(0, ("talloc failed\n")); + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + for (i=0; i= 0; i--) { + if (streams[i] == NULL) { + continue; + } + + DEBUG(10, ("Closing stream # %d, %s\n", i, + streams[i]->fsp_name)); + close_file(streams[i], NORMAL_CLOSE); + } + + fail: + TALLOC_FREE(frame); + return status; +} + /* * Wrapper around open_file_ntcreate and open_directory */ @@ -2466,6 +2577,7 @@ NTSTATUS create_file_unixpath(connection_struct *conn, { SMB_STRUCT_STAT sbuf; int info = FILE_WAS_OPENED; + files_struct *base_fsp = NULL; files_struct *fsp = NULL; NTSTATUS status; @@ -2495,7 +2607,23 @@ NTSTATUS create_file_unixpath(connection_struct *conn, sbuf = *psbuf; } else { - SET_STAT_INVALID(sbuf); + if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) { + SET_STAT_INVALID(sbuf); + } + } + + if ((conn->fs_capabilities & FILE_NAMED_STREAMS) + && (access_mask & DELETE_ACCESS) + && !is_ntfs_stream_name(fname)) { + /* + * We can't open a file with DELETE access if any of the + * streams is open without FILE_SHARE_DELETE + */ + status = open_streams_for_delete(conn, fname); + + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } } /* This is the correct thing to do (check every time) but can_delete @@ -2528,12 +2656,61 @@ NTSTATUS create_file_unixpath(connection_struct *conn, } #endif + if ((conn->fs_capabilities & FILE_NAMED_STREAMS) + && is_ntfs_stream_name(fname) + && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) { + char *base; + uint32 base_create_disposition; + + if (create_options & FILE_DIRECTORY_FILE) { + status = NT_STATUS_NOT_A_DIRECTORY; + goto fail; + } + + status = split_ntfs_stream_name(talloc_tos(), fname, + &base, NULL); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("split_ntfs_stream_name failed: %s\n", + nt_errstr(status))); + goto fail; + } + + SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */ + + switch (create_disposition) { + case FILE_OPEN: + base_create_disposition = FILE_OPEN; + break; + default: + base_create_disposition = FILE_OPEN_IF; + break; + } + + status = create_file_unixpath(conn, NULL, base, 0, + FILE_SHARE_READ + | FILE_SHARE_WRITE + | FILE_SHARE_DELETE, + base_create_disposition, + 0, 0, 0, 0, NULL, NULL, + &base_fsp, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("create_file_unixpath for base %s failed: " + "%s\n", base, nt_errstr(status))); + goto fail; + } + } + /* * If it's a request for a directory open, deal with it separately. */ if (create_options & FILE_DIRECTORY_FILE) { + if (create_options & FILE_NON_DIRECTORY_FILE) { + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + /* Can't open a temp directory. IFS kit test. */ if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) { status = NT_STATUS_INVALID_PARAMETER; @@ -2664,6 +2841,16 @@ NTSTATUS create_file_unixpath(connection_struct *conn, DEBUG(10, ("create_file: info=%d\n", info)); + /* + * Set fsp->base_fsp late enough that we can't "goto fail" anymore. In + * the fail: branch we call close_file(fsp, ERROR_CLOSE) which would + * also close fsp->base_fsp which we have to also do explicitly in + * this routine here, as not in all "goto fail:" we have the fsp set + * up already to be initialized with the base_fsp. + */ + + fsp->base_fsp = base_fsp; + *result = fsp; if (pinfo != NULL) { *pinfo = info; @@ -2685,6 +2872,10 @@ NTSTATUS create_file_unixpath(connection_struct *conn, close_file(fsp, ERROR_CLOSE); fsp = NULL; } + if (base_fsp != NULL) { + close_file(base_fsp, ERROR_CLOSE); + base_fsp = NULL; + } return status; } @@ -2812,19 +3003,18 @@ NTSTATUS create_file(connection_struct *conn, status = NT_STATUS_NO_MEMORY; goto fail; } - } else { - /* - * Check to see if this is a mac fork of some kind. - */ + } + + /* + * Check to see if this is a mac fork of some kind. + */ - if (is_ntfs_stream_name(fname)) { - enum FAKE_FILE_TYPE fake_file_type; + if (is_ntfs_stream_name(fname)) { + enum FAKE_FILE_TYPE fake_file_type; - fake_file_type = is_fake_file(fname); + fake_file_type = is_fake_file(fname); - if (fake_file_type == FAKE_FILE_TYPE_NONE) { - return NT_STATUS_OBJECT_PATH_NOT_FOUND; - } + if (fake_file_type != FAKE_FILE_TYPE_NONE) { /* * Here we go! support for changing the disk quotas diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 381ddfe151..61ec611b6b 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -167,6 +167,10 @@ static NTSTATUS check_path_syntax_internal(char *path, } *d = '\0'; + + if (NT_STATUS_IS_OK(ret) && !posix_path) { + ret = split_ntfs_stream_name(NULL, path, NULL, NULL); + } return ret; } @@ -2289,14 +2293,22 @@ static NTSTATUS do_unlink(connection_struct *conn, /* On open checks the open itself will check the share mode, so don't do it here as we'll get it wrong. */ - status = open_file_ntcreate(conn, req, fname, &sbuf, - DELETE_ACCESS, - FILE_SHARE_NONE, - FILE_OPEN, - 0, - FILE_ATTRIBUTE_NORMAL, - req != NULL ? 0 : INTERNAL_OPEN_ONLY, - NULL, &fsp); + status = create_file_unixpath + (conn, /* conn */ + req, /* req */ + fname, /* fname */ + DELETE_ACCESS, /* access_mask */ + FILE_SHARE_NONE, /* share_access */ + FILE_OPEN, /* create_disposition*/ + FILE_NON_DIRECTORY_FILE, /* create_options */ + FILE_ATTRIBUTE_NORMAL, /* file_attributes */ + 0, /* oplock_request */ + 0, /* allocation_size */ + NULL, /* sd */ + NULL, /* ea_list */ + &fsp, /* result */ + NULL, /* pinfo */ + &sbuf); /* psbuf */ if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("open_file_ntcreate failed: %s\n", -- cgit From 4ba64fce494b064590a932d53cdbdb5f7bc4a837 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 23:33:11 +0100 Subject: vfs_streams_xattr module Store streams in posix xattrs. A kludge, as xattrs are limited in many ways, but it might be a help for some situations. (This used to be commit 83a805220e52742119546c76a054d50582e33a24) --- source3/Makefile.in | 5 + source3/configure.in | 3 +- source3/modules/vfs_streams_xattr.c | 672 ++++++++++++++++++++++++++++++++++++ 3 files changed, 679 insertions(+), 1 deletion(-) create mode 100644 source3/modules/vfs_streams_xattr.c diff --git a/source3/Makefile.in b/source3/Makefile.in index d3e37826d7..ec06bc971d 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -526,6 +526,7 @@ VFS_HPUXACL_OBJ = modules/vfs_hpuxacl.o VFS_IRIXACL_OBJ = modules/vfs_irixacl.o VFS_TRU64ACL_OBJ = modules/vfs_tru64acl.o VFS_CATIA_OBJ = modules/vfs_catia.o +VFS_STREAMS_XATTR_OBJ = modules/vfs_streams_xattr.o VFS_CACHEPRIME_OBJ = modules/vfs_cacheprime.o VFS_PREALLOC_OBJ = modules/vfs_prealloc.o VFS_COMMIT_OBJ = modules/vfs_commit.o @@ -1747,6 +1748,10 @@ bin/catia.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_CATIA_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_CATIA_OBJ) +bin/streams_xattr.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_STREAMS_XATTR_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_STREAMS_XATTR_OBJ) + bin/cacheprime.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_CACHEPRIME_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_CACHEPRIME_OBJ) diff --git a/source3/configure.in b/source3/configure.in index a34d42c478..38788eda39 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -707,7 +707,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_winreg rpc_initshutdown rpc_lsa_ds rpc_wkssvc rpc_svcctl2 rpc_ntsvcs rpc_net rpc_netdfs rpc_srvsvc2 rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops vfs_xattr_tdb" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops vfs_xattr_tdb vfs_streams_xattr" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_rpcecho" @@ -6497,6 +6497,7 @@ SMB_MODULE(vfs_irixacl, \$(VFS_IRIXACL_OBJ), "bin/irixacl.$SHLIBEXT", VFS) SMB_MODULE(vfs_hpuxacl, \$(VFS_HPUXACL_OBJ), "bin/hpuxacl.$SHLIBEXT", VFS) SMB_MODULE(vfs_tru64acl, \$(VFS_TRU64ACL_OBJ), "bin/tru64acl.$SHLIBEXT", VFS) SMB_MODULE(vfs_catia, \$(VFS_CATIA_OBJ), "bin/catia.$SHLIBEXT", VFS) +SMB_MODULE(vfs_streams_xattr, \$(VFS_STREAMS_XATTR_OBJ), "bin/streams_xattr.$SHLIBEXT", VFS) SMB_MODULE(vfs_cacheprime, \$(VFS_CACHEPRIME_OBJ), "bin/cacheprime.$SHLIBEXT", VFS) SMB_MODULE(vfs_prealloc, \$(VFS_PREALLOC_OBJ), "bin/prealloc.$SHLIBEXT", VFS) SMB_MODULE(vfs_commit, \$(VFS_COMMIT_OBJ), "bin/commit.$SHLIBEXT", VFS) diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c new file mode 100644 index 0000000000..3701cddfb5 --- /dev/null +++ b/source3/modules/vfs_streams_xattr.c @@ -0,0 +1,672 @@ +/* + * Store streams in xattrs + * + * Copyright (C) Volker Lendecke, 2008 + * + * Partly based on James Peach's Darwin module, which is + * + * Copyright (C) James Peach 2006-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + +#define XATTR_DOSSTREAM_PREFIX "user.DosStream." + +struct stream_io { + char *base; + char *xattr_name; +}; + +static SMB_INO_T stream_inode(const SMB_STRUCT_STAT *sbuf, const char *sname) +{ + struct MD5Context ctx; + unsigned char hash[16]; + SMB_INO_T result; + char *upper_sname; + + DEBUG(10, ("stream_inode called for %lu/%lu [%s]\n", + (unsigned long)sbuf->st_dev, + (unsigned long)sbuf->st_ino, sname)); + + upper_sname = talloc_strdup_upper(talloc_tos(), sname); + SMB_ASSERT(upper_sname != NULL); + + MD5Init(&ctx); + MD5Update(&ctx, (unsigned char *)&(sbuf->st_dev), + sizeof(sbuf->st_dev)); + MD5Update(&ctx, (unsigned char *)&(sbuf->st_ino), + sizeof(sbuf->st_ino)); + MD5Update(&ctx, (unsigned char *)upper_sname, + talloc_get_size(upper_sname)-1); + MD5Final(hash, &ctx); + + TALLOC_FREE(upper_sname); + + /* Hopefully all the variation is in the lower 4 (or 8) bytes! */ + memcpy(&result, hash, sizeof(result)); + + DEBUG(10, ("stream_inode returns %lu\n", (unsigned long)result)); + + return result; +} + +static ssize_t get_xattr_size(connection_struct *conn, const char *fname, + const char *xattr_name) +{ + NTSTATUS status; + struct ea_struct ea; + ssize_t result; + + status = get_ea_value(talloc_tos(), conn, NULL, fname, + xattr_name, &ea); + + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + + result = ea.value.length-1; + TALLOC_FREE(ea.value.data); + return result; +} + + +static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, + SMB_STRUCT_STAT *sbuf) +{ + struct stream_io *io = (struct stream_io *) + VFS_FETCH_FSP_EXTENSION(handle, fsp); + + if (io == NULL) { + return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); + } + + if (SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf) == -1) { + return -1; + } + + sbuf->st_size = get_xattr_size(handle->conn, io->base, io->xattr_name); + if (sbuf->st_size == -1) { + return -1; + } + + sbuf->st_ino = stream_inode(sbuf, io->xattr_name); + sbuf->st_mode &= ~S_IFMT; + sbuf->st_mode |= S_IFREG; + sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1; + + return 0; +} + +static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname, + SMB_STRUCT_STAT *sbuf) +{ + NTSTATUS status; + char *base, *sname; + int result = -1; + char *xattr_name; + + if (!is_ntfs_stream_name(fname)) { + return SMB_VFS_NEXT_STAT(handle, fname, sbuf); + } + + status = split_ntfs_stream_name(talloc_tos(), fname, &base, &sname); + if (!NT_STATUS_IS_OK(status)) { + errno = EINVAL; + goto fail; + } + + if (SMB_VFS_NEXT_STAT(handle, base, sbuf) == -1) { + goto fail; + } + + xattr_name = talloc_asprintf(talloc_tos(), "%s%s", + XATTR_DOSSTREAM_PREFIX, sname); + if (xattr_name == NULL) { + errno = ENOMEM; + goto fail; + } + + sbuf->st_size = get_xattr_size(handle->conn, base, xattr_name); + if (sbuf->st_size == -1) { + errno = ENOENT; + goto fail; + } + + sbuf->st_ino = stream_inode(sbuf, xattr_name); + sbuf->st_mode &= ~S_IFMT; + sbuf->st_mode |= S_IFREG; + sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1; + + result = 0; + fail: + TALLOC_FREE(base); + TALLOC_FREE(sname); + return result; +} + +static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname, + SMB_STRUCT_STAT *sbuf) +{ + NTSTATUS status; + char *base, *sname; + int result = -1; + char *xattr_name; + + if (!is_ntfs_stream_name(fname)) { + return SMB_VFS_NEXT_LSTAT(handle, fname, sbuf); + } + + status = split_ntfs_stream_name(talloc_tos(), fname, &base, &sname); + if (!NT_STATUS_IS_OK(status)) { + errno = EINVAL; + goto fail; + } + + if (SMB_VFS_NEXT_LSTAT(handle, base, sbuf) == -1) { + goto fail; + } + + xattr_name = talloc_asprintf(talloc_tos(), "%s%s", + XATTR_DOSSTREAM_PREFIX, sname); + if (xattr_name == NULL) { + errno = ENOMEM; + goto fail; + } + + sbuf->st_size = get_xattr_size(handle->conn, base, xattr_name); + if (sbuf->st_size == -1) { + errno = ENOENT; + goto fail; + } + + sbuf->st_ino = stream_inode(sbuf, xattr_name); + sbuf->st_mode &= ~S_IFMT; + sbuf->st_mode |= S_IFREG; + sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1; + + result = 0; + fail: + TALLOC_FREE(base); + TALLOC_FREE(sname); + return result; +} + +static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, + files_struct *fsp, int flags, mode_t mode) +{ + TALLOC_CTX *frame; + NTSTATUS status; + struct stream_io *sio; + char *base, *sname; + struct ea_struct ea; + char *xattr_name; + int baseflags; + int hostfd = -1; + + if (!is_ntfs_stream_name(fname)) { + return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); + } + + frame = talloc_stackframe(); + + status = split_ntfs_stream_name(talloc_tos(), fname, + &base, &sname); + if (!NT_STATUS_IS_OK(status)) { + errno = EINVAL; + goto fail; + } + + xattr_name = talloc_asprintf(talloc_tos(), "%s%s", + XATTR_DOSSTREAM_PREFIX, sname); + if (xattr_name == NULL) { + errno = ENOMEM; + goto fail; + } + + /* + * We use baseflags to turn off nasty side-effects when opening the + * underlying file. + */ + baseflags = flags; + baseflags &= ~O_TRUNC; + baseflags &= ~O_EXCL; + baseflags &= ~O_CREAT; + + hostfd = SMB_VFS_NEXT_OPEN(handle, base, fsp, baseflags, mode); + + /* It is legit to open a stream on a directory, but the base + * fd has to be read-only. + */ + if ((hostfd == -1) && (errno == EISDIR)) { + baseflags &= ~O_ACCMODE; + baseflags |= O_RDONLY; + hostfd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, baseflags, + mode); + } + + if (hostfd == -1) { + goto fail; + } + + status = get_ea_value(talloc_tos(), handle->conn, fsp, base, + xattr_name, &ea); + + if (!NT_STATUS_IS_OK(status) + && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + /* + * The base file is not there. This is an error even if we got + * O_CREAT, the higher levels should have created the base + * file for us. + */ + errno = ENOENT; + goto fail; + } + + if (!NT_STATUS_IS_OK(status)) { + /* + * The attribute does not exist + */ + + if (flags & O_CREAT) { + /* + * Darn, xattrs need at least 1 byte + */ + char null = '\0'; + + if (SMB_VFS_NEXT_SETXATTR( + handle, base, xattr_name, &null, sizeof(null), + flags & O_EXCL ? XATTR_CREATE : 0) == -1) { + goto fail; + } + } + } + + if (flags & O_TRUNC) { + char null = '\0'; + if (SMB_VFS_NEXT_SETXATTR( + handle, base, xattr_name, &null, sizeof(null), + flags & O_EXCL ? XATTR_CREATE : 0) == -1) { + goto fail; + } + } + + sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, + struct stream_io); + if (sio == NULL) { + errno = ENOMEM; + goto fail; + } + + sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), + xattr_name); + sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), + base); + + if ((sio->xattr_name == NULL) || (sio->base == NULL)) { + errno = ENOMEM; + goto fail; + } + + TALLOC_FREE(frame); + return hostfd; + + fail: + if (hostfd >= 0) { + /* + * BUGBUGBUG -- we would need to call fd_close_posix here, but + * we don't have a full fsp yet + */ + SMB_VFS_NEXT_CLOSE(handle, fsp, hostfd); + } + + TALLOC_FREE(frame); + return -1; +} + +static int streams_xattr_unlink(vfs_handle_struct *handle, const char *fname) +{ + NTSTATUS status; + char *base = NULL; + char *sname = NULL; + int ret = -1; + char *xattr_name; + + if (!is_ntfs_stream_name(fname)) { + return SMB_VFS_NEXT_UNLINK(handle, fname); + } + + status = split_ntfs_stream_name(talloc_tos(), fname, &base, &sname); + if (!NT_STATUS_IS_OK(status)) { + errno = EINVAL; + goto fail; + } + + xattr_name = talloc_asprintf(talloc_tos(), "%s%s", + XATTR_DOSSTREAM_PREFIX, sname); + if (xattr_name == NULL) { + errno = ENOMEM; + goto fail; + } + + ret = SMB_VFS_NEXT_REMOVEXATTR(handle, base, xattr_name); + + if ((ret == -1) && (errno == ENOATTR)) { + errno = ENOENT; + goto fail; + } + + ret = 0; + + fail: + TALLOC_FREE(base); + TALLOC_FREE(sname); + return ret; +} + +static NTSTATUS walk_xattr_streams(connection_struct *conn, files_struct *fsp, + const char *fname, + bool (*fn)(struct ea_struct *ea, + void *private_data), + void *private_data) +{ + NTSTATUS status; + char **names; + size_t i, num_names; + size_t prefix_len = strlen(XATTR_DOSSTREAM_PREFIX); + + status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname, + &names, &num_names); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + for (i=0; imem_ctx, + &state->num_streams, &state->streams, + ea->name, ea->value.length-1, + smb_roundup(state->handle->conn, + ea->value.length-1))) { + state->status = NT_STATUS_NO_MEMORY; + return false; + } + + return true; +} + +static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle, + struct files_struct *fsp, + const char *fname, + TALLOC_CTX *mem_ctx, + unsigned int *pnum_streams, + struct stream_struct **pstreams) +{ + SMB_STRUCT_STAT sbuf; + int ret; + NTSTATUS status; + struct streaminfo_state state; + + if ((fsp != NULL) && (fsp->fh->fd != -1)) { + if (is_ntfs_stream_name(fsp->fsp_name)) { + return NT_STATUS_INVALID_PARAMETER; + } + ret = SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf); + } + else { + if (is_ntfs_stream_name(fname)) { + return NT_STATUS_INVALID_PARAMETER; + } + ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + state.streams = NULL; + state.num_streams = 0; + + if (!S_ISDIR(sbuf.st_mode)) { + if (!add_one_stream(mem_ctx, + &state.num_streams, &state.streams, + "::$DATA", sbuf.st_size, + get_allocation_size(handle->conn, fsp, + &sbuf))) { + return NT_STATUS_NO_MEMORY; + } + } + + state.mem_ctx = mem_ctx; + state.handle = handle; + state.status = NT_STATUS_OK; + + status = walk_xattr_streams(handle->conn, fsp, fname, + collect_one_stream, &state); + + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(state.streams); + return status; + } + + if (!NT_STATUS_IS_OK(state.status)) { + TALLOC_FREE(state.streams); + return state.status; + } + + *pnum_streams = state.num_streams; + *pstreams = state.streams; + return NT_STATUS_OK; +} + +static int streams_xattr_statvfs(struct vfs_handle_struct *handle, + const char *path, + struct vfs_statvfs_struct *statbuf) +{ + int ret; + + ret = SMB_VFS_NEXT_STATVFS(handle, path, statbuf); + statbuf->FsCapabilities |= FILE_NAMED_STREAMS; + return ret; + +} + +static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, + files_struct *fsp, const void *data, + size_t n, SMB_OFF_T offset) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + struct ea_struct ea; + NTSTATUS status; + int ret; + + if (sio == NULL) { + return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); + } + + status = get_ea_value(talloc_tos(), handle->conn, fsp, sio->base, + sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + + if ((offset + n) > ea.value.length-1) { + uint8 *tmp; + + tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), ea.value.data, uint8, + offset + n + 1); + + if (tmp == NULL) { + TALLOC_FREE(ea.value.data); + errno = ENOMEM; + return -1; + } + ea.value.data = tmp; + ea.value.length = offset + n + 1; + ea.value.data[offset+n] = 0; + } + + memcpy(ea.value.data + offset, data, n); + + ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, sio->xattr_name, + ea.value.data, ea.value.length, 0); + + TALLOC_FREE(ea.value.data); + + return n; +} + +static ssize_t streams_xattr_pread(vfs_handle_struct *handle, + files_struct *fsp, void *data, + size_t n, SMB_OFF_T offset) +{ + struct stream_io *sio = + (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp); + struct ea_struct ea; + NTSTATUS status; + size_t length, overlap; + + if (sio == NULL) { + return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); + } + + status = get_ea_value(talloc_tos(), handle->conn, fsp, sio->base, + sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; + } + + length = ea.value.length-1; + + /* Attempt to read past EOF. */ + if (length <= offset) { + errno = EINVAL; + return -1; + } + + overlap = (offset + n) > length ? (length - offset) : n; + memcpy(data, ea.value.data + offset, overlap); + + TALLOC_FREE(ea.value.data); + return overlap; +} + +/* VFS operations structure */ + +static vfs_op_tuple streams_xattr_ops[] = { + {SMB_VFS_OP(streams_xattr_statvfs), SMB_VFS_OP_STATVFS, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_open), SMB_VFS_OP_OPEN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_stat), SMB_VFS_OP_STAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_fstat), SMB_VFS_OP_FSTAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_lstat), SMB_VFS_OP_LSTAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_pread), SMB_VFS_OP_PREAD, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_pwrite), SMB_VFS_OP_PWRITE, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_lstat), SMB_VFS_OP_LSTAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_unlink), SMB_VFS_OP_UNLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_xattr_streaminfo), SMB_VFS_OP_STREAMINFO, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_streams_xattr_init(void); +NTSTATUS vfs_streams_xattr_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "streams_xattr", + streams_xattr_ops); +} -- cgit From dfd05b9b65c5ad12dbb64b626d3180fb9e21ccb0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 23:36:34 +0100 Subject: vfs_streams_depot Store streams in a file each. Not 100% finished, and not built by default. (This used to be commit 5f5fc72b01c8e8fc096375c7cb4a97186c387259) --- source3/Makefile.in | 5 + source3/configure.in | 1 + source3/modules/vfs_streams_depot.c | 648 ++++++++++++++++++++++++++++++++++++ 3 files changed, 654 insertions(+) create mode 100644 source3/modules/vfs_streams_depot.c diff --git a/source3/Makefile.in b/source3/Makefile.in index ec06bc971d..ea5e5a82a7 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -527,6 +527,7 @@ VFS_IRIXACL_OBJ = modules/vfs_irixacl.o VFS_TRU64ACL_OBJ = modules/vfs_tru64acl.o VFS_CATIA_OBJ = modules/vfs_catia.o VFS_STREAMS_XATTR_OBJ = modules/vfs_streams_xattr.o +VFS_STREAMS_DEPOT_OBJ = modules/vfs_streams_depot.o VFS_CACHEPRIME_OBJ = modules/vfs_cacheprime.o VFS_PREALLOC_OBJ = modules/vfs_prealloc.o VFS_COMMIT_OBJ = modules/vfs_commit.o @@ -1752,6 +1753,10 @@ bin/streams_xattr.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_STREAMS_XATTR_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_STREAMS_XATTR_OBJ) +bin/streams_depot.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_STREAMS_DEPOT_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_STREAMS_DEPOT_OBJ) + bin/cacheprime.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_CACHEPRIME_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_CACHEPRIME_OBJ) diff --git a/source3/configure.in b/source3/configure.in index 38788eda39..25e3b3600b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -6498,6 +6498,7 @@ SMB_MODULE(vfs_hpuxacl, \$(VFS_HPUXACL_OBJ), "bin/hpuxacl.$SHLIBEXT", VFS) SMB_MODULE(vfs_tru64acl, \$(VFS_TRU64ACL_OBJ), "bin/tru64acl.$SHLIBEXT", VFS) SMB_MODULE(vfs_catia, \$(VFS_CATIA_OBJ), "bin/catia.$SHLIBEXT", VFS) SMB_MODULE(vfs_streams_xattr, \$(VFS_STREAMS_XATTR_OBJ), "bin/streams_xattr.$SHLIBEXT", VFS) +SMB_MODULE(vfs_streams_depot, \$(VFS_STREAMS_DEPOT_OBJ), "bin/streams_depot.$SHLIBEXT", VFS) SMB_MODULE(vfs_cacheprime, \$(VFS_CACHEPRIME_OBJ), "bin/cacheprime.$SHLIBEXT", VFS) SMB_MODULE(vfs_prealloc, \$(VFS_PREALLOC_OBJ), "bin/prealloc.$SHLIBEXT", VFS) SMB_MODULE(vfs_commit, \$(VFS_COMMIT_OBJ), "bin/commit.$SHLIBEXT", VFS) diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c new file mode 100644 index 0000000000..68e7a75947 --- /dev/null +++ b/source3/modules/vfs_streams_depot.c @@ -0,0 +1,648 @@ +/* + * Store streams in a separate subdirectory + * + * Copyright (C) Volker Lendecke, 2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + +/* + * Excerpt from a mail from tridge: + * + * Volker, what I'm thinking of is this: + * /mount-point/.streams/XX/YY/aaaa.bbbb/namedstream1 + * /mount-point/.streams/XX/YY/aaaa.bbbb/namedstream2 + * + * where XX/YY is a 2 level hash based on the fsid/inode. "aaaa.bbbb" + * is the fsid/inode. "namedstreamX" is a file named after the stream + * name. + */ + +static uint32_t hash_fn(DATA_BLOB key) +{ + uint32_t value; /* Used to compute the hash value. */ + uint32_t i; /* Used to cycle through random values. */ + + /* Set the initial value from the key size. */ + for (value = 0x238F13AF * key.length, i=0; i < key.length; i++) + value = (value + (key.data[i] << (i*5 % 24))); + + return (1103515243 * value + 12345); +} + +/* + * With the hashing scheme based on the inode we need to protect against + * streams showing up on files with re-used inodes. This can happen if we + * create a stream directory from within Samba, and a local process or NFS + * client deletes the file without deleting the streams directory. When the + * inode is re-used and the stream directory is still around, the streams in + * there would be show up as belonging to the new file. + * + * There are several workarounds for this, probably the easiest one is on + * systems which have a true birthtime stat element: When the file has a later + * birthtime than the streams directory, then we have to recreate the + * directory. + * + * The other workaround is to somehow mark the file as generated by Samba with + * something that a NFS client would not do. The closest one is a special + * xattr value being set. On systems which do not support xattrs, it might be + * an option to put in a special ACL entry for a non-existing group. + */ + +#define SAMBA_XATTR_MARKER "user.SAMBA_STREAMS" + +static bool file_is_valid(vfs_handle_struct *handle, const char *path) +{ + char buf; + + DEBUG(10, ("file_is_valid (%s) called\n", path)); + + if (SMB_VFS_NEXT_GETXATTR(handle, path, SAMBA_XATTR_MARKER, + &buf, sizeof(buf)) != sizeof(buf)) { + DEBUG(10, ("GETXATTR failed: %s\n", strerror(errno))); + return false; + } + + if (buf != '1') { + DEBUG(10, ("got wrong buffer content: '%c'\n", buf)); + return false; + } + + return true; +} + +static bool mark_file_valid(vfs_handle_struct *handle, const char *path) +{ + char buf = '1'; + int ret; + + DEBUG(10, ("marking file %s as valid\n", path)); + + ret = SMB_VFS_NEXT_SETXATTR(handle, path, SAMBA_XATTR_MARKER, + &buf, sizeof(buf), 0); + + if (ret == -1) { + DEBUG(10, ("SETXATTR failed: %s\n", strerror(errno))); + return false; + } + + return true; +} + +static char *stream_dir(vfs_handle_struct *handle, const char *base_path, + const SMB_STRUCT_STAT *base_sbuf, bool create_it) +{ + uint32_t hash; + char *result = NULL; + SMB_STRUCT_STAT sbuf; + uint8_t first, second; + char *tmp; + char *id_hex; + struct file_id id; + uint8 id_buf[16]; + + const char *rootdir = lp_parm_const_string( + SNUM(handle->conn), "streams", "directory", + handle->conn->connectpath); + + if (base_sbuf == NULL) { + if (SMB_VFS_NEXT_STAT(handle, base_path, &sbuf) == -1) { + /* + * base file is not there + */ + goto fail; + } + base_sbuf = &sbuf; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, base_sbuf->st_dev, + base_sbuf->st_ino); + + push_file_id_16((char *)id_buf, &id); + + hash = hash_fn(data_blob_const(id_buf, sizeof(id_buf))); + + first = hash & 0xff; + second = (hash >> 8) & 0xff; + + id_hex = hex_encode(talloc_tos(), id_buf, sizeof(id_buf)); + + if (id_hex == NULL) { + errno = ENOMEM; + goto fail; + } + + result = talloc_asprintf(talloc_tos(), "%s/%2.2X/%2.2X/%s", rootdir, + first, second, id_hex); + + TALLOC_FREE(id_hex); + + if (result == NULL) { + errno = ENOMEM; + return NULL; + } + + if (SMB_VFS_NEXT_STAT(handle, result, &sbuf) == 0) { + char *newname; + + if (!S_ISDIR(sbuf.st_mode)) { + errno = EINVAL; + goto fail; + } + + if (file_is_valid(handle, base_path)) { + return result; + } + + /* + * Someone has recreated a file under an existing inode + * without deleting the streams directory. For now, just move + * it away. + */ + + again: + newname = talloc_asprintf(talloc_tos(), "lost-%lu", random()); + if (newname == NULL) { + errno = ENOMEM; + goto fail; + } + + if (SMB_VFS_NEXT_RENAME(handle, result, newname) == -1) { + if ((errno == EEXIST) || (errno == ENOTEMPTY)) { + TALLOC_FREE(newname); + goto again; + } + goto fail; + } + + TALLOC_FREE(newname); + } + + if (!create_it) { + errno = ENOENT; + goto fail; + } + + if ((SMB_VFS_NEXT_MKDIR(handle, rootdir, 0755) != 0) + && (errno != EEXIST)) { + goto fail; + } + + tmp = talloc_asprintf(result, "%s/%2.2X", rootdir, first); + if (tmp == NULL) { + errno = ENOMEM; + goto fail; + } + + if ((SMB_VFS_NEXT_MKDIR(handle, tmp, 0755) != 0) + && (errno != EEXIST)) { + goto fail; + } + + TALLOC_FREE(tmp); + + tmp = talloc_asprintf(result, "%s/%2.2X/%2.2X", rootdir, first, + second); + if (tmp == NULL) { + errno = ENOMEM; + goto fail; + } + + if ((SMB_VFS_NEXT_MKDIR(handle, tmp, 0755) != 0) + && (errno != EEXIST)) { + goto fail; + } + + TALLOC_FREE(tmp); + + if ((SMB_VFS_NEXT_MKDIR(handle, result, 0755) != 0) + && (errno != EEXIST)) { + goto fail; + } + + if (!mark_file_valid(handle, base_path)) { + goto fail; + } + + return result; + + fail: + TALLOC_FREE(result); + return NULL; +} + +static char *stream_name(vfs_handle_struct *handle, const char *fname, + bool create_dir) +{ + char *base = NULL; + char *sname = NULL; + char *id_hex = NULL; + char *dirname, *stream_fname; + + if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), fname, + &base, &sname))) { + DEBUG(10, ("split_ntfs_stream_name failed\n")); + errno = ENOMEM; + goto fail; + } + + dirname = stream_dir(handle, base, NULL, create_dir); + + if (dirname == NULL) { + goto fail; + } + + stream_fname = talloc_asprintf(talloc_tos(), "%s/:%s", dirname, sname); + + if (stream_fname == NULL) { + errno = ENOMEM; + goto fail; + } + + DEBUG(10, ("stream filename = %s\n", stream_fname)); + + TALLOC_FREE(base); + TALLOC_FREE(sname); + TALLOC_FREE(id_hex); + + return stream_fname; + + fail: + DEBUG(5, ("stream_name failed: %s\n", strerror(errno))); + TALLOC_FREE(base); + TALLOC_FREE(sname); + TALLOC_FREE(id_hex); + return NULL; +} + +static NTSTATUS walk_streams(vfs_handle_struct *handle, + const char *fname, + const SMB_STRUCT_STAT *sbuf, + char **pdirname, + bool (*fn)(const char *dirname, + const char *dirent, + void *private_data), + void *private_data) +{ + char *dirname; + SMB_STRUCT_DIR *dirhandle = NULL; + char *dirent; + + dirname = stream_dir(handle, fname, sbuf, false); + + if (dirname == NULL) { + if (errno == ENOENT) { + /* + * no stream around + */ + return NT_STATUS_OK; + } + return map_nt_error_from_unix(errno); + } + + DEBUG(10, ("walk_streams: dirname=%s\n", dirname)); + + dirhandle = SMB_VFS_NEXT_OPENDIR(handle, dirname, NULL, 0); + + if (dirhandle == NULL) { + TALLOC_FREE(dirname); + return map_nt_error_from_unix(errno); + } + + while ((dirent = vfs_readdirname(handle->conn, dirhandle)) != NULL) { + + if (ISDOT(dirent) || ISDOTDOT(dirent)) { + continue; + } + + DEBUG(10, ("walk_streams: dirent=%s\n", dirent)); + + if (!fn(dirname, dirent, private_data)) { + break; + } + } + + SMB_VFS_NEXT_CLOSEDIR(handle, dirhandle); + + if (pdirname != NULL) { + *pdirname = dirname; + } + else { + TALLOC_FREE(dirname); + } + + return NT_STATUS_OK; +} + +static int streams_depot_stat(vfs_handle_struct *handle, const char *fname, + SMB_STRUCT_STAT *sbuf) +{ + char *stream_fname; + int ret = -1; + + DEBUG(10, ("streams_depot_stat called for [%s]\n", fname)); + + if (!is_ntfs_stream_name(fname)) { + return SMB_VFS_NEXT_STAT(handle, fname, sbuf); + } + + stream_fname = stream_name(handle, fname, false); + if (stream_fname == NULL) { + goto done; + } + + ret = SMB_VFS_NEXT_STAT(handle, stream_fname, sbuf); + + done: + TALLOC_FREE(stream_fname); + return ret; +} + +static int streams_depot_lstat(vfs_handle_struct *handle, const char *fname, + SMB_STRUCT_STAT *sbuf) +{ + char *stream_fname; + int ret = -1; + + if (!is_ntfs_stream_name(fname)) { + return SMB_VFS_NEXT_LSTAT(handle, fname, sbuf); + } + + stream_fname = stream_name(handle, fname, false); + if (stream_fname == NULL) { + goto done; + } + + ret = SMB_VFS_NEXT_LSTAT(handle, stream_fname, sbuf); + + done: + TALLOC_FREE(stream_fname); + return ret; +} + +static int streams_depot_open(vfs_handle_struct *handle, const char *fname, + files_struct *fsp, int flags, mode_t mode) +{ + TALLOC_CTX *frame; + char *base = NULL; + SMB_STRUCT_STAT base_sbuf; + char *stream_fname; + int ret = -1; + + if (!is_ntfs_stream_name(fname)) { + return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); + } + + frame = talloc_stackframe(); + + if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), fname, + &base, NULL))) { + errno = ENOMEM; + goto done; + } + + ret = SMB_VFS_NEXT_STAT(handle, base, &base_sbuf); + + if (ret == -1) { + goto done; + } + + TALLOC_FREE(base); + + stream_fname = stream_name(handle, fname, true); + if (stream_fname == NULL) { + goto done; + } + + ret = SMB_VFS_NEXT_OPEN(handle, stream_fname, fsp, flags, mode); + + done: + TALLOC_FREE(frame); + return ret; +} + +static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) +{ + int ret = -1; + SMB_STRUCT_STAT sbuf; + + DEBUG(10, ("streams_depot_unlink called for %s\n", fname)); + + if (is_ntfs_stream_name(fname)) { + char *stream_fname; + + stream_fname = stream_name(handle, fname, false); + if (stream_fname == NULL) { + return -1; + } + + ret = SMB_VFS_NEXT_UNLINK(handle, stream_fname); + + TALLOC_FREE(stream_fname); + return ret; + } + + /* + * We potentially need to delete the per-inode streams directory + */ + + if (SMB_VFS_NEXT_STAT(handle, fname, &sbuf) == -1) { + return -1; + } + + if (sbuf.st_nlink == 1) { + char *dirname = stream_dir(handle, fname, &sbuf, false); + + if (dirname != NULL) { + SMB_VFS_NEXT_RMDIR(handle, dirname); + } + TALLOC_FREE(dirname); + } + + return SMB_VFS_NEXT_UNLINK(handle, fname); +} + +static bool add_one_stream(TALLOC_CTX *mem_ctx, unsigned int *num_streams, + struct stream_struct **streams, + const char *name, SMB_OFF_T size, + SMB_OFF_T alloc_size) +{ + struct stream_struct *tmp; + + tmp = TALLOC_REALLOC_ARRAY(mem_ctx, *streams, struct stream_struct, + (*num_streams)+1); + if (tmp == NULL) { + return false; + } + + tmp[*num_streams].name = talloc_strdup(tmp, name); + if (tmp[*num_streams].name == NULL) { + return false; + } + + tmp[*num_streams].size = size; + tmp[*num_streams].alloc_size = alloc_size; + + *streams = tmp; + *num_streams += 1; + return true; +} + +struct streaminfo_state { + TALLOC_CTX *mem_ctx; + vfs_handle_struct *handle; + unsigned int num_streams; + struct stream_struct *streams; + NTSTATUS status; +}; + +static bool collect_one_stream(const char *dirname, + const char *dirent, + void *private_data) +{ + struct streaminfo_state *state = + (struct streaminfo_state *)private_data; + char *full_sname; + SMB_STRUCT_STAT sbuf; + + if (asprintf(&full_sname, "%s/%s", dirname, dirent) == -1) { + state->status = NT_STATUS_NO_MEMORY; + return false; + } + if (SMB_VFS_NEXT_STAT(state->handle, full_sname, &sbuf) == -1) { + DEBUG(10, ("Could not stat %s: %s\n", full_sname, + strerror(errno))); + SAFE_FREE(full_sname); + return true; + } + + SAFE_FREE(full_sname); + + if (!add_one_stream(state->mem_ctx, + &state->num_streams, &state->streams, + dirent, sbuf.st_size, + get_allocation_size( + state->handle->conn, NULL, &sbuf))) { + state->status = NT_STATUS_NO_MEMORY; + return false; + } + + return true; +} + +static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle, + struct files_struct *fsp, + const char *fname, + TALLOC_CTX *mem_ctx, + unsigned int *pnum_streams, + struct stream_struct **pstreams) +{ + SMB_STRUCT_STAT sbuf; + int ret; + NTSTATUS status; + struct streaminfo_state state; + + if ((fsp != NULL) && (fsp->fh->fd != -1)) { + if (is_ntfs_stream_name(fsp->fsp_name)) { + return NT_STATUS_INVALID_PARAMETER; + } + ret = SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf); + } + else { + if (is_ntfs_stream_name(fname)) { + return NT_STATUS_INVALID_PARAMETER; + } + ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + state.streams = NULL; + state.num_streams = 0; + + if (!S_ISDIR(sbuf.st_mode)) { + if (!add_one_stream(mem_ctx, + &state.num_streams, &state.streams, + "::$DATA", sbuf.st_size, + get_allocation_size(handle->conn, fsp, + &sbuf))) { + return NT_STATUS_NO_MEMORY; + } + } + + state.mem_ctx = mem_ctx; + state.handle = handle; + state.status = NT_STATUS_OK; + + status = walk_streams(handle, fname, &sbuf, NULL, collect_one_stream, + &state); + + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(state.streams); + return status; + } + + if (!NT_STATUS_IS_OK(state.status)) { + TALLOC_FREE(state.streams); + return state.status; + } + + *pnum_streams = state.num_streams; + *pstreams = state.streams; + return NT_STATUS_OK; +} + +static int streams_depot_statvfs(struct vfs_handle_struct *handle, + const char *path, + struct vfs_statvfs_struct *statbuf) +{ + int ret; + + ret = SMB_VFS_NEXT_STATVFS(handle, path, statbuf); + statbuf->FsCapabilities |= FILE_NAMED_STREAMS; + return ret; + +} + +/* VFS operations structure */ + +static vfs_op_tuple streams_depot_ops[] = { + {SMB_VFS_OP(streams_depot_statvfs), SMB_VFS_OP_STATVFS, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_depot_open), SMB_VFS_OP_OPEN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_depot_stat), SMB_VFS_OP_STAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_depot_lstat), SMB_VFS_OP_LSTAT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_depot_unlink), SMB_VFS_OP_UNLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(streams_depot_streaminfo), SMB_VFS_OP_STREAMINFO, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_streams_depot_init(void); +NTSTATUS vfs_streams_depot_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "streams_depot", + streams_depot_ops); +} -- cgit From 014bfd35f8c57370b27a1d07c335e2d9813a1333 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 00:44:14 +0100 Subject: Some systems do not have XATTR_ defined (This used to be commit 2cac1d3919a96c480f34c93d8b9b07782d46ed23) --- source3/include/includes.h | 8 ++++++++ source3/lib/system.c | 5 ----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index 7eca8d3ddf..c6d0885ad9 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -1108,6 +1108,14 @@ char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...) PRINTF_ATT #define VXFS_QUOTA #endif +#ifndef XATTR_CREATE +#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ +#endif + +#ifndef XATTR_REPLACE +#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ +#endif + #if defined(HAVE_KRB5) krb5_error_code smb_krb5_parse_name(krb5_context context, diff --git a/source3/lib/system.c b/source3/lib/system.c index eb6dcae6fb..fa50955ef6 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -1917,11 +1917,6 @@ int sys_fremovexattr (int filedes, const char *name) #endif } -#if !defined(HAVE_SETXATTR) -#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ -#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ -#endif - int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags) { #if defined(HAVE_SETXATTR) -- cgit From 29af710d6acc4fe7e02313b7c878dc7301feeaea Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 23:01:58 +0100 Subject: Use c99 struct initializers for REGISTRY_OPS in reg_smbconf.c. Michael (This used to be commit 96d116b003c1187869cbdbc21274a0b5cb1bf7d6) --- source3/registry/reg_smbconf.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/source3/registry/reg_smbconf.c b/source3/registry/reg_smbconf.c index 8dfb745a7e..a6e478200f 100644 --- a/source3/registry/reg_smbconf.c +++ b/source3/registry/reg_smbconf.c @@ -265,13 +265,11 @@ static WERROR smbconf_set_secdesc(const char *key, */ REGISTRY_OPS smbconf_reg_ops = { - smbconf_fetch_keys, - smbconf_fetch_values, - smbconf_store_keys, - smbconf_store_values, - smbconf_reg_access_check, - smbconf_get_secdesc, - smbconf_set_secdesc, - NULL, - NULL + .fetch_subkeys = smbconf_fetch_keys, + .fetch_values = smbconf_fetch_values, + .store_subkeys = smbconf_store_keys, + .store_values = smbconf_store_values, + .reg_access_check = smbconf_reg_access_check, + .get_secdesc = smbconf_get_secdesc, + .set_secdesc = smbconf_set_secdesc, }; -- cgit From 15015b74906fd4ce6bab5c500946ca0aa7da0fa8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 23:06:12 +0100 Subject: Use c99 struct initializers for REGISTRY_OPS in reg_printing.c Michael (This used to be commit a89bee4139666ba163385c9e7d15fbc5d623ed6f) --- source3/registry/reg_printing.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c index 5be0796002..a4da103d40 100644 --- a/source3/registry/reg_printing.c +++ b/source3/registry/reg_printing.c @@ -1262,9 +1262,8 @@ static bool regprint_store_reg_values( const char *key, REGVAL_CTR *values ) */ REGISTRY_OPS printing_ops = { - regprint_fetch_reg_keys, - regprint_fetch_reg_values, - regprint_store_reg_keys, - regprint_store_reg_values, - NULL, NULL, NULL, NULL, NULL + .fetch_subkeys = regprint_fetch_reg_keys, + .fetch_values = regprint_fetch_reg_values, + .store_subkeys = regprint_store_reg_keys, + .store_values = regprint_store_reg_values, }; -- cgit From cb1e0de56f180fa6da82908a73610daecd19b9d7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 23:09:38 +0100 Subject: Use c99 struct initializers for REGISTRY_OPS in reg_shares.c Michael (This used to be commit 2c4dfd7aaa3c3b384b547451f914a86f59157928) --- source3/registry/reg_shares.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source3/registry/reg_shares.c b/source3/registry/reg_shares.c index 4ac6e1d151..ee9e5dc5a1 100644 --- a/source3/registry/reg_shares.c +++ b/source3/registry/reg_shares.c @@ -155,11 +155,10 @@ static bool shares_store_value( const char *key, REGVAL_CTR *val ) */ REGISTRY_OPS shares_reg_ops = { - shares_subkey_info, - shares_value_info, - shares_store_subkey, - shares_store_value, - NULL, NULL, NULL, NULL, NULL + .fetch_subkeys = shares_subkey_info, + .fetch_values = shares_value_info, + .store_subkeys = shares_store_subkey, + .store_values = shares_store_value, }; -- cgit From 139340f570f006032aba2d5d98e13731e373bdfe Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 12:13:37 +0100 Subject: Volker is right: why keep commented out migrated dynamic reg overlays around?... Michael (This used to be commit a73b8d16aa0f7a3bb7417e9839e04380e6a68629) --- source3/registry/reg_dynamic.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index 07c9673c28..037bdab0cc 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -29,24 +29,6 @@ struct reg_dyn_values { int (*fetch_values) ( REGVAL_CTR *val ); }; -#if 0 -/*********************************************************************** -***********************************************************************/ - -static int netlogon_params( REGVAL_CTR *regvals ) -{ - uint32 dwValue; - - if ( !pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue) ) - dwValue = 0; - - regval_ctr_addvalue( regvals, "RefusePasswordChange", REG_DWORD, - (char*)&dwValue, sizeof(dwValue) ); - - return regval_ctr_numvals( regvals ); -} -#endif - /*********************************************************************** ***********************************************************************/ @@ -202,9 +184,6 @@ static int current_version( REGVAL_CTR *values ) ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { -#if 0 - { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/NETLOGON/PARAMETERS", &netlogon_params }, -#endif { "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRODUCTOPTIONS", &prod_options }, { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, -- cgit From 563c4ef74082b0d06d0511fef700980d92f04d08 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 16:13:01 +0100 Subject: Use constant KEY_NETLOGON_PARAMS instead of literal key. Michael (This used to be commit daf37c954572bbf652506daae9ff0c9c365b2a9e) --- source3/registry/reg_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index c4bfc2b6c9..1b95c2558c 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -50,7 +50,7 @@ static const char *builtin_registry_paths[] = { "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions", "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters", - "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters", + KEY_NETLOGON_PARAMS, "HKU", "HKCR", "HKPD", -- cgit From 1b2dd2dcc8a78c3b6d4ba9fe229dd6f286947b32 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 17:51:57 +0100 Subject: Fix registering Registry backends in reghook_cache_add(). This was broken in 331c0d6216e1a1607a49ed7eb4078e10138ec16a (pstring removal). Michael (This used to be commit 7d1e986f3a5ab316a8501ddaca1ba1f0867b4531) --- source3/registry/reg_cachehook.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/registry/reg_cachehook.c b/source3/registry/reg_cachehook.c index 74670aac30..22352c6112 100644 --- a/source3/registry/reg_cachehook.c +++ b/source3/registry/reg_cachehook.c @@ -56,7 +56,7 @@ bool reghook_cache_add( REGISTRY_HOOK *hook ) return false; } - key = talloc_asprintf(ctx, "//%s", hook->keyname); + key = talloc_asprintf(ctx, "\\%s", hook->keyname); if (!key) { return false; } -- cgit From c8a0b2a3a2c82312076341fb2fe53e0abed0a6fb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 22:39:33 +0100 Subject: In reg_backend_netlogon_params, delegate fetch_subkeys() to regdb. In order to be able to open the netlogon_params key (the new backend replacing the former dynamic overlay), certain methods need to be provided. Delegate these to the regdb backend (like e.g. the smbconf backend does). Michael (This used to be commit 9261b2c4bf48e133eecda9ec0095bd8edf20326c) --- source3/registry/reg_backend_netlogon_params.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index 507d2c5df8..ff5a33e6e4 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -29,6 +29,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY +extern REGISTRY_OPS regdb_ops; static int netlogon_params_fetch_reg_values(const char *key, REGVAL_CTR *regvals) @@ -44,7 +45,13 @@ static int netlogon_params_fetch_reg_values(const char *key, return regval_ctr_numvals( regvals ); } +static int netlogon_params_fetch_subkeys(const char *key, + REGSUBKEY_CTR *subkey_ctr) +{ + return regdb_ops.fetch_subkeys(key, subkey_ctr); +} REGISTRY_OPS netlogon_params_reg_ops = { .fetch_values = netlogon_params_fetch_reg_values, + .fetch_subkeys = netlogon_params_fetch_subkeys, }; -- cgit From 2e47997e6e433f915bcba6cd891857c15ea95a12 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 22:42:30 +0100 Subject: Rename netlogon_params_fetch_reg_values() to netlogon_params_fetch_values(). Michael (This used to be commit 54e7c8098565495a833500d4b2a8d5240ed55c82) --- source3/registry/reg_backend_netlogon_params.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index ff5a33e6e4..d63cd6b31b 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -31,8 +31,7 @@ extern REGISTRY_OPS regdb_ops; -static int netlogon_params_fetch_reg_values(const char *key, - REGVAL_CTR *regvals) +static int netlogon_params_fetch_values(const char *key, REGVAL_CTR *regvals) { uint32 dwValue; @@ -52,6 +51,6 @@ static int netlogon_params_fetch_subkeys(const char *key, } REGISTRY_OPS netlogon_params_reg_ops = { - .fetch_values = netlogon_params_fetch_reg_values, + .fetch_values = netlogon_params_fetch_values, .fetch_subkeys = netlogon_params_fetch_subkeys, }; -- cgit From d48c5f15993c90635f4bb46f87245d9c244d7ddf Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:30:38 +0100 Subject: Some reformatting in netlogon_params_fetch_values(). Michael (This used to be commit 24f13fb72e4cbaba48235fa840b2a93bf1c5d9c3) --- source3/registry/reg_backend_netlogon_params.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index d63cd6b31b..71f88144c8 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -34,14 +34,15 @@ extern REGISTRY_OPS regdb_ops; static int netlogon_params_fetch_values(const char *key, REGVAL_CTR *regvals) { uint32 dwValue; - - if ( !pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue) ) + + if (!pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) { dwValue = 0; - - regval_ctr_addvalue( regvals, "RefusePasswordChange", REG_DWORD, - (char*)&dwValue, sizeof(dwValue) ); + } + + regval_ctr_addvalue(regvals, "RefusePasswordChange", REG_DWORD, + (char*)&dwValue, sizeof(dwValue)); - return regval_ctr_numvals( regvals ); + return regval_ctr_numvals(regvals); } static int netlogon_params_fetch_subkeys(const char *key, -- cgit From 663815ec2bbb4b2566a6d72f6680b39953640bb1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 16:15:43 +0100 Subject: Add a registry backend prod_options that replaces the former dynamic overlay. Michael (This used to be commit d9b89e9d30702f64805b3a3a3612066b19c051d1) --- source3/Makefile.in | 1 + source3/include/reg_objects.h | 1 + source3/registry/reg_backend_prod_options.c | 70 +++++++++++++++++++++++++++++ source3/registry/reg_db.c | 2 +- source3/registry/reg_dynamic.c | 31 ------------- source3/registry/reg_frontend.c | 2 + 6 files changed, 75 insertions(+), 32 deletions(-) create mode 100644 source3/registry/reg_backend_prod_options.c diff --git a/source3/Makefile.in b/source3/Makefile.in index ea5e5a82a7..57605d1018 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -419,6 +419,7 @@ REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_pri registry/reg_smbconf.o registry/reg_api.o \ registry/reg_frontend_hilvl.o \ registry/reg_backend_netlogon_params.o \ + registry/reg_backend_prod_options.o \ $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ) RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index 3b846db681..021ed0e0fd 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -101,6 +101,7 @@ typedef struct { #define KEY_SHARES "HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares" #define KEY_SMBCONF "HKLM\\SOFTWARE\\Samba\\smbconf" #define KEY_NETLOGON_PARAMS "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters" +#define KEY_PROD_OPTIONS "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions" #define KEY_TREE_ROOT "" /* diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c new file mode 100644 index 0000000000..7be97bee06 --- /dev/null +++ b/source3/registry/reg_backend_prod_options.c @@ -0,0 +1,70 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 2002-2005 + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * Product options registry backend. + * + * This replaces the former dynamic product options overlay. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +extern REGISTRY_OPS regdb_ops; + +static int prod_options_fetch_values(const char *key, REGVAL_CTR *regvals) +{ + const char *value_ascii = ""; + fstring value; + int value_length; + + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + value_ascii = "LanmanNT"; + break; + case ROLE_STANDALONE: + value_ascii = "ServerNT"; + break; + case ROLE_DOMAIN_MEMBER: + value_ascii = "WinNT"; + break; + } + + value_length = push_ucs2( value, value, value_ascii, sizeof(value), + STR_TERMINATE|STR_NOALIGN ); + regval_ctr_addvalue( regvals, "ProductType", REG_SZ, value, + value_length ); + + return regval_ctr_numvals( regvals ); +} + +static int prod_options_fetch_subkeys(const char *key, + REGSUBKEY_CTR *subkey_ctr) +{ + return regdb_ops.fetch_subkeys(key, subkey_ctr); +} + +REGISTRY_OPS prod_options_reg_ops = { + .fetch_values = prod_options_fetch_values, + .fetch_subkeys = prod_options_fetch_subkeys, +}; diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index 1b95c2558c..f70e44fd51 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -47,7 +47,7 @@ static const char *builtin_registry_paths[] = { "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib", "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009", "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", - "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions", + KEY_PROD_OPTIONS, "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters", KEY_NETLOGON_PARAMS, diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index 037bdab0cc..2735e2a27a 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -32,36 +32,6 @@ struct reg_dyn_values { /*********************************************************************** ***********************************************************************/ -static int prod_options( REGVAL_CTR *regvals ) -{ - const char *value_ascii = ""; - fstring value; - int value_length; - - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - value_ascii = "LanmanNT"; - break; - case ROLE_STANDALONE: - value_ascii = "ServerNT"; - break; - case ROLE_DOMAIN_MEMBER: - value_ascii = "WinNT"; - break; - } - - value_length = push_ucs2( value, value, value_ascii, sizeof(value), - STR_TERMINATE|STR_NOALIGN ); - regval_ctr_addvalue( regvals, "ProductType", REG_SZ, value, - value_length ); - - return regval_ctr_numvals( regvals ); -} - -/*********************************************************************** -***********************************************************************/ - static int tcpip_params( REGVAL_CTR *regvals ) { fstring value; @@ -184,7 +154,6 @@ static int current_version( REGVAL_CTR *values ) ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { - { "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRODUCTOPTIONS", &prod_options }, { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009", &perflib_009_params }, diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 6674b0ba20..32ec7f9a87 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -29,6 +29,7 @@ extern REGISTRY_OPS eventlog_ops; extern REGISTRY_OPS shares_reg_ops; extern REGISTRY_OPS smbconf_reg_ops; extern REGISTRY_OPS netlogon_params_reg_ops; +extern REGISTRY_OPS prod_options_reg_ops; extern REGISTRY_OPS regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -42,6 +43,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_SHARES, &shares_reg_ops }, { KEY_SMBCONF, &smbconf_reg_ops }, { KEY_NETLOGON_PARAMS, &netlogon_params_reg_ops }, + { KEY_PROD_OPTIONS, &prod_options_reg_ops }, #endif { NULL, NULL } }; -- cgit From f383b853f58d54352332a60e6f0842dfd41f5ff0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:25:08 +0100 Subject: Some reformatting in prod_options_fetch_values(). Michael (This used to be commit 347b9886547516bc2a43190ae7faaf349d2c9d04) --- source3/registry/reg_backend_prod_options.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c index 7be97bee06..7ac5c5b4b9 100644 --- a/source3/registry/reg_backend_prod_options.c +++ b/source3/registry/reg_backend_prod_options.c @@ -33,10 +33,10 @@ extern REGISTRY_OPS regdb_ops; static int prod_options_fetch_values(const char *key, REGVAL_CTR *regvals) { - const char *value_ascii = ""; - fstring value; - int value_length; - + const char *value_ascii = ""; + fstring value; + int value_length; + switch (lp_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: @@ -49,12 +49,12 @@ static int prod_options_fetch_values(const char *key, REGVAL_CTR *regvals) value_ascii = "WinNT"; break; } - - value_length = push_ucs2( value, value, value_ascii, sizeof(value), - STR_TERMINATE|STR_NOALIGN ); - regval_ctr_addvalue( regvals, "ProductType", REG_SZ, value, - value_length ); - + + value_length = push_ucs2(value, value, value_ascii, sizeof(value), + STR_TERMINATE|STR_NOALIGN ); + regval_ctr_addvalue(regvals, "ProductType", REG_SZ, value, + value_length); + return regval_ctr_numvals( regvals ); } -- cgit From c5a5b404b43817525590aa924f1762824f49d156 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 23:46:13 +0100 Subject: Add a registry backend tcpip_params that replaces the former dynamic overlay. Michael (This used to be commit a8a743b693a162954948ca2438ce4b842c5cba30) --- source3/Makefile.in | 1 + source3/include/reg_objects.h | 1 + source3/registry/reg_backend_tcpip_params.c | 65 +++++++++++++++++++++++++++++ source3/registry/reg_db.c | 2 +- source3/registry/reg_dynamic.c | 26 ------------ source3/registry/reg_frontend.c | 2 + 6 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 source3/registry/reg_backend_tcpip_params.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 57605d1018..7416ee2b3c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -420,6 +420,7 @@ REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_pri registry/reg_frontend_hilvl.o \ registry/reg_backend_netlogon_params.o \ registry/reg_backend_prod_options.o \ + registry/reg_backend_tcpip_params.o \ $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ) RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index 021ed0e0fd..d33d469de3 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -102,6 +102,7 @@ typedef struct { #define KEY_SMBCONF "HKLM\\SOFTWARE\\Samba\\smbconf" #define KEY_NETLOGON_PARAMS "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters" #define KEY_PROD_OPTIONS "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions" +#define KEY_TCPIP_PARAMS "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" #define KEY_TREE_ROOT "" /* diff --git a/source3/registry/reg_backend_tcpip_params.c b/source3/registry/reg_backend_tcpip_params.c new file mode 100644 index 0000000000..1714bdb439 --- /dev/null +++ b/source3/registry/reg_backend_tcpip_params.c @@ -0,0 +1,65 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 2002-2005 + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * TCP/IP parameters registry backend. + * + * This replaces the former dynamic tcpip parameters overlay. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +extern REGISTRY_OPS regdb_ops; + +static int tcpip_params_fetch_values(const char *key, REGVAL_CTR *regvals) +{ + fstring value; + int value_length; + char *hname; + char *mydomainname = NULL; + + hname = myhostname(); + value_length = push_ucs2( value, value, hname, sizeof(value), STR_TERMINATE|STR_NOALIGN); + regval_ctr_addvalue( regvals, "Hostname",REG_SZ, value, value_length ); + + mydomainname = get_mydnsdomname(talloc_tos()); + if (!mydomainname) { + return -1; + } + + value_length = push_ucs2( value, value, mydomainname, sizeof(value), STR_TERMINATE|STR_NOALIGN); + regval_ctr_addvalue( regvals, "Domain", REG_SZ, value, value_length ); + + return regval_ctr_numvals( regvals ); +} + +static int tcpip_params_fetch_subkeys(const char *key, + REGSUBKEY_CTR *subkey_ctr) +{ + return regdb_ops.fetch_subkeys(key, subkey_ctr); +} + +REGISTRY_OPS tcpip_params_reg_ops = { + .fetch_values = tcpip_params_fetch_values, + .fetch_subkeys = tcpip_params_fetch_subkeys, +}; diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index f70e44fd51..ce88c56c61 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -49,7 +49,7 @@ static const char *builtin_registry_paths[] = { "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", KEY_PROD_OPTIONS, "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", - "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters", + KEY_TCPIP_PARAMS, KEY_NETLOGON_PARAMS, "HKU", "HKCR", diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index 2735e2a27a..9d20b8935c 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -32,31 +32,6 @@ struct reg_dyn_values { /*********************************************************************** ***********************************************************************/ -static int tcpip_params( REGVAL_CTR *regvals ) -{ - fstring value; - int value_length; - char *hname; - char *mydomainname = NULL; - - hname = myhostname(); - value_length = push_ucs2( value, value, hname, sizeof(value), STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue( regvals, "Hostname",REG_SZ, value, value_length ); - - mydomainname = get_mydnsdomname(talloc_tos()); - if (!mydomainname) { - return -1; - } - - value_length = push_ucs2( value, value, mydomainname, sizeof(value), STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue( regvals, "Domain", REG_SZ, value, value_length ); - - return regval_ctr_numvals( regvals ); -} - -/*********************************************************************** -***********************************************************************/ - static int perflib_params( REGVAL_CTR *regvals ) { int base_index = -1; @@ -154,7 +129,6 @@ static int current_version( REGVAL_CTR *values ) ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { - { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009", &perflib_009_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION", ¤t_version }, diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 32ec7f9a87..6ecc8011e4 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -30,6 +30,7 @@ extern REGISTRY_OPS shares_reg_ops; extern REGISTRY_OPS smbconf_reg_ops; extern REGISTRY_OPS netlogon_params_reg_ops; extern REGISTRY_OPS prod_options_reg_ops; +extern REGISTRY_OPS tcpip_params_reg_ops; extern REGISTRY_OPS regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -44,6 +45,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_SMBCONF, &smbconf_reg_ops }, { KEY_NETLOGON_PARAMS, &netlogon_params_reg_ops }, { KEY_PROD_OPTIONS, &prod_options_reg_ops }, + { KEY_TCPIP_PARAMS, &tcpip_params_reg_ops }, #endif { NULL, NULL } }; -- cgit From b4e3c752722f6e7d143caa810ce0f8eb9c8d12c9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:21:45 +0100 Subject: Some reformatting in tcpip_params_fetch_values(). Michael (This used to be commit 5b3813b233dc2a60e6d5a9942b4044219d800415) --- source3/registry/reg_backend_tcpip_params.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/source3/registry/reg_backend_tcpip_params.c b/source3/registry/reg_backend_tcpip_params.c index 1714bdb439..db7df5dd8f 100644 --- a/source3/registry/reg_backend_tcpip_params.c +++ b/source3/registry/reg_backend_tcpip_params.c @@ -33,24 +33,26 @@ extern REGISTRY_OPS regdb_ops; static int tcpip_params_fetch_values(const char *key, REGVAL_CTR *regvals) { - fstring value; - int value_length; - char *hname; + fstring value; + int value_length; + char *hname; char *mydomainname = NULL; hname = myhostname(); - value_length = push_ucs2( value, value, hname, sizeof(value), STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue( regvals, "Hostname",REG_SZ, value, value_length ); + value_length = push_ucs2(value, value, hname, sizeof(value), + STR_TERMINATE|STR_NOALIGN); + regval_ctr_addvalue(regvals, "Hostname",REG_SZ, value, value_length); mydomainname = get_mydnsdomname(talloc_tos()); if (!mydomainname) { return -1; } - value_length = push_ucs2( value, value, mydomainname, sizeof(value), STR_TERMINATE|STR_NOALIGN); - regval_ctr_addvalue( regvals, "Domain", REG_SZ, value, value_length ); + value_length = push_ucs2(value, value, mydomainname, sizeof(value), + STR_TERMINATE|STR_NOALIGN); + regval_ctr_addvalue(regvals, "Domain", REG_SZ, value, value_length); - return regval_ctr_numvals( regvals ); + return regval_ctr_numvals(regvals); } static int tcpip_params_fetch_subkeys(const char *key, -- cgit From 949a88ee2f1163605a73a28920190c11c25e4609 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:00:14 +0100 Subject: Add a registry backend hkpt_params that replaces the former dynamic overlay. Michael (This used to be commit 8e8bb6ba120adf9942f612b7fd89bdbced6c1285) --- source3/Makefile.in | 1 + source3/registry/reg_backend_hkpt_params.c | 67 ++++++++++++++++++++++++++++++ source3/registry/reg_dynamic.c | 29 ------------- source3/registry/reg_frontend.c | 2 + 4 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 source3/registry/reg_backend_hkpt_params.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 7416ee2b3c..0def36dd64 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -421,6 +421,7 @@ REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_pri registry/reg_backend_netlogon_params.o \ registry/reg_backend_prod_options.o \ registry/reg_backend_tcpip_params.o \ + registry/reg_backend_hkpt_params.o \ $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ) RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o diff --git a/source3/registry/reg_backend_hkpt_params.c b/source3/registry/reg_backend_hkpt_params.c new file mode 100644 index 0000000000..0b962e10bd --- /dev/null +++ b/source3/registry/reg_backend_hkpt_params.c @@ -0,0 +1,67 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 2002-2005 + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * HKPT parameters registry backend. + * + * This replaces the former dynamic hkpt parameters overlay. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +extern REGISTRY_OPS regdb_ops; + +static int hkpt_params_fetch_values(const char *key, REGVAL_CTR *regvals) +{ + uint32 base_index; + uint32 buffer_size; + char *buffer = NULL; + + /* This is ALMOST the same as perflib_009_params, but HKPT has + a "Counters" entry instead of a "Counter" key. */ + + base_index = reg_perfcount_get_base_index(); + buffer_size = reg_perfcount_get_counter_names(base_index, &buffer); + regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, buffer, buffer_size); + + if(buffer_size > 0) + SAFE_FREE(buffer); + + buffer_size = reg_perfcount_get_counter_help(base_index, &buffer); + regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size); + if(buffer_size > 0) + SAFE_FREE(buffer); + + return regval_ctr_numvals( regvals ); +} + +static int hkpt_params_fetch_subkeys(const char *key, + REGSUBKEY_CTR *subkey_ctr) +{ + return regdb_ops.fetch_subkeys(key, subkey_ctr); +} + +REGISTRY_OPS hkpt_params_reg_ops = { + .fetch_values = hkpt_params_fetch_values, + .fetch_subkeys = hkpt_params_fetch_subkeys, +}; diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index 9d20b8935c..c342cd07e4 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -75,33 +75,6 @@ static int perflib_009_params( REGVAL_CTR *regvals ) /*********************************************************************** ***********************************************************************/ -static int hkpt_params( REGVAL_CTR *regvals ) -{ - uint32 base_index; - uint32 buffer_size; - char *buffer = NULL; - - /* This is ALMOST the same as perflib_009_params, but HKPT has - a "Counters" entry instead of a "Counter" key. */ - - base_index = reg_perfcount_get_base_index(); - buffer_size = reg_perfcount_get_counter_names(base_index, &buffer); - regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, buffer, buffer_size); - - if(buffer_size > 0) - SAFE_FREE(buffer); - - buffer_size = reg_perfcount_get_counter_help(base_index, &buffer); - regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size); - if(buffer_size > 0) - SAFE_FREE(buffer); - - return regval_ctr_numvals( regvals ); -} - -/*********************************************************************** -***********************************************************************/ - static int current_version( REGVAL_CTR *values ) { const char *sysroot_string = "c:\\Windows"; @@ -122,7 +95,6 @@ static int current_version( REGVAL_CTR *values ) return regval_ctr_numvals( values ); } - /*********************************************************************** Structure holding the registry paths and pointers to the value enumeration functions @@ -132,7 +104,6 @@ static struct reg_dyn_values dynamic_values[] = { { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009", &perflib_009_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION", ¤t_version }, - { "HKPT", &hkpt_params }, { NULL, NULL } }; diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 6ecc8011e4..9539c2ba2f 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -31,6 +31,7 @@ extern REGISTRY_OPS smbconf_reg_ops; extern REGISTRY_OPS netlogon_params_reg_ops; extern REGISTRY_OPS prod_options_reg_ops; extern REGISTRY_OPS tcpip_params_reg_ops; +extern REGISTRY_OPS hkpt_params_reg_ops; extern REGISTRY_OPS regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -46,6 +47,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_NETLOGON_PARAMS, &netlogon_params_reg_ops }, { KEY_PROD_OPTIONS, &prod_options_reg_ops }, { KEY_TCPIP_PARAMS, &tcpip_params_reg_ops }, + { KEY_HKPT, &hkpt_params_reg_ops }, #endif { NULL, NULL } }; -- cgit From 8eed06fb8cc6db37d15ddc0f64744a536588ba29 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:15:31 +0100 Subject: Some reformatting in hkpt_params_fetch_values(). Michael (This used to be commit f245c4e094ad56080847e286c76976f29c95a221) --- source3/registry/reg_backend_hkpt_params.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/source3/registry/reg_backend_hkpt_params.c b/source3/registry/reg_backend_hkpt_params.c index 0b962e10bd..2ed5e78e1c 100644 --- a/source3/registry/reg_backend_hkpt_params.c +++ b/source3/registry/reg_backend_hkpt_params.c @@ -39,19 +39,22 @@ static int hkpt_params_fetch_values(const char *key, REGVAL_CTR *regvals) /* This is ALMOST the same as perflib_009_params, but HKPT has a "Counters" entry instead of a "Counter" key. */ - + base_index = reg_perfcount_get_base_index(); buffer_size = reg_perfcount_get_counter_names(base_index, &buffer); - regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, buffer, buffer_size); - - if(buffer_size > 0) + regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, buffer, + buffer_size); + + if(buffer_size > 0) { SAFE_FREE(buffer); - + } + buffer_size = reg_perfcount_get_counter_help(base_index, &buffer); regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size); - if(buffer_size > 0) + if(buffer_size > 0) { SAFE_FREE(buffer); - + } + return regval_ctr_numvals( regvals ); } -- cgit From 25c21fb562c6bb9c61a9e2e58d585619f18d3c84 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:09:52 +0100 Subject: Use some consts instead of literal strings for registry keys. Michael (This used to be commit 80024f4e1c6594c3038e86a765f763d24fd96b59) --- source3/registry/reg_db.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index ce88c56c61..fad6c8acd1 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -51,10 +51,10 @@ static const char *builtin_registry_paths[] = { "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", KEY_TCPIP_PARAMS, KEY_NETLOGON_PARAMS, - "HKU", - "HKCR", - "HKPD", - "HKPT", + KEY_HKU, + KEY_HKCR, + KEY_HKPD, + KEY_HKPT, NULL }; struct builtin_regkey_value { -- cgit From a1af15d29f1e009a80bf205397a6a0b122d67e26 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 02:23:00 +0100 Subject: Reorder the registry key name constants in a more systematic way. Michael (This used to be commit faf406a4a1baf2946ea754a0760204748be99541) --- source3/include/reg_objects.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index d33d469de3..e6fbcbdd6d 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -94,15 +94,15 @@ typedef struct { #define KEY_HKCU "HKCU" #define KEY_HKDD "HKDD" #define KEY_SERVICES "HKLM\\SYSTEM\\CurrentControlSet\\Services" -#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print" -#define KEY_PRINTING_2K "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers" -#define KEY_PRINTING_PORTS "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports" #define KEY_EVENTLOG "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Eventlog" #define KEY_SHARES "HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares" -#define KEY_SMBCONF "HKLM\\SOFTWARE\\Samba\\smbconf" #define KEY_NETLOGON_PARAMS "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters" -#define KEY_PROD_OPTIONS "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions" #define KEY_TCPIP_PARAMS "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" +#define KEY_PROD_OPTIONS "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions" +#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print" +#define KEY_PRINTING_2K "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers" +#define KEY_PRINTING_PORTS "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports" +#define KEY_SMBCONF "HKLM\\SOFTWARE\\Samba\\smbconf" #define KEY_TREE_ROOT "" /* -- cgit From 2925d8357319c9872d570fe045c883a25891b59e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 03:24:13 +0100 Subject: Add a registry backend current_version that replaces the former dynamic overlay. Make sure to only respond to the exact current version key since subkeys are registered by other backends (printing and - soon - perflib). Michael (This used to be commit 2c650bf63ccd9dc5dddbf4700831489544ded055) --- source3/Makefile.in | 1 + source3/include/reg_objects.h | 1 + source3/registry/reg_backend_current_version.c | 80 ++++++++++++++++++++++++++ source3/registry/reg_dynamic.c | 24 -------- source3/registry/reg_frontend.c | 2 + 5 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 source3/registry/reg_backend_current_version.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 0def36dd64..fa40d92948 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -422,6 +422,7 @@ REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_pri registry/reg_backend_prod_options.o \ registry/reg_backend_tcpip_params.o \ registry/reg_backend_hkpt_params.o \ + registry/reg_backend_current_version.o \ $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ) RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index e6fbcbdd6d..24db16261d 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -102,6 +102,7 @@ typedef struct { #define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print" #define KEY_PRINTING_2K "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers" #define KEY_PRINTING_PORTS "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports" +#define KEY_CURRENT_VERSION "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" #define KEY_SMBCONF "HKLM\\SOFTWARE\\Samba\\smbconf" #define KEY_TREE_ROOT "" diff --git a/source3/registry/reg_backend_current_version.c b/source3/registry/reg_backend_current_version.c new file mode 100644 index 0000000000..51b081721c --- /dev/null +++ b/source3/registry/reg_backend_current_version.c @@ -0,0 +1,80 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 2002-2005 + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * CurrentVersion registry backend. + * + * This is a virtual overlay, dynamically presenting version information. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +extern REGISTRY_OPS regdb_ops; + +#define KEY_CURRENT_VERSION_NORM "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION" + +static int current_version_fetch_values(const char *key, REGVAL_CTR *values) +{ + const char *sysroot_string = "c:\\Windows"; + fstring sysversion; + fstring value; + uint32 value_length; + char *path = NULL; + TALLOC_CTX *ctx = talloc_tos(); + + path = talloc_strdup(ctx, key); + if (path == NULL) { + return -1; + } + path = normalize_reg_path(ctx, path); + if (path == NULL) { + return -1; + } + + if (strncmp(path, KEY_CURRENT_VERSION_NORM, strlen(path)) != 0) { + return 0; + } + + value_length = push_ucs2( value, value, sysroot_string, sizeof(value), + STR_TERMINATE|STR_NOALIGN ); + regval_ctr_addvalue( values, "SystemRoot", REG_SZ, value, value_length ); + + fstr_sprintf( sysversion, "%d.%d", lp_major_announce_version(), lp_minor_announce_version() ); + value_length = push_ucs2( value, value, sysversion, sizeof(value), + STR_TERMINATE|STR_NOALIGN ); + regval_ctr_addvalue( values, "CurrentVersion", REG_SZ, value, value_length ); + + + return regval_ctr_numvals( values ); +} + +static int current_version_fetch_subkeys(const char *key, + REGSUBKEY_CTR *subkey_ctr) +{ + return regdb_ops.fetch_subkeys(key, subkey_ctr); +} + +REGISTRY_OPS current_version_reg_ops = { + .fetch_values = current_version_fetch_values, + .fetch_subkeys = current_version_fetch_subkeys, +}; diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index c342cd07e4..ca87cc60f5 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -72,29 +72,6 @@ static int perflib_009_params( REGVAL_CTR *regvals ) return regval_ctr_numvals( regvals ); } -/*********************************************************************** -***********************************************************************/ - -static int current_version( REGVAL_CTR *values ) -{ - const char *sysroot_string = "c:\\Windows"; - fstring sysversion; - fstring value; - uint32 value_length; - - value_length = push_ucs2( value, value, sysroot_string, sizeof(value), - STR_TERMINATE|STR_NOALIGN ); - regval_ctr_addvalue( values, "SystemRoot", REG_SZ, value, value_length ); - - fstr_sprintf( sysversion, "%d.%d", lp_major_announce_version(), lp_minor_announce_version() ); - value_length = push_ucs2( value, value, sysversion, sizeof(value), - STR_TERMINATE|STR_NOALIGN ); - regval_ctr_addvalue( values, "CurrentVersion", REG_SZ, value, value_length ); - - - return regval_ctr_numvals( values ); -} - /*********************************************************************** Structure holding the registry paths and pointers to the value enumeration functions @@ -103,7 +80,6 @@ static int current_version( REGVAL_CTR *values ) static struct reg_dyn_values dynamic_values[] = { { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009", &perflib_009_params }, - { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION", ¤t_version }, { NULL, NULL } }; diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 9539c2ba2f..d489050904 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -32,6 +32,7 @@ extern REGISTRY_OPS netlogon_params_reg_ops; extern REGISTRY_OPS prod_options_reg_ops; extern REGISTRY_OPS tcpip_params_reg_ops; extern REGISTRY_OPS hkpt_params_reg_ops; +extern REGISTRY_OPS current_version_reg_ops; extern REGISTRY_OPS regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -48,6 +49,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_PROD_OPTIONS, &prod_options_reg_ops }, { KEY_TCPIP_PARAMS, &tcpip_params_reg_ops }, { KEY_HKPT, &hkpt_params_reg_ops }, + { KEY_CURRENT_VERSION, ¤t_version_reg_ops }, #endif { NULL, NULL } }; -- cgit From c4b65647ca551eeb87ec31579eda9ebf79fdceed Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 03:25:54 +0100 Subject: Some reformatting of current_version_fetch_values(). Michael (This used to be commit d2e3814db8a4a5f0fc097e9f56753888470ef213) --- source3/registry/reg_backend_current_version.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/source3/registry/reg_backend_current_version.c b/source3/registry/reg_backend_current_version.c index 51b081721c..a9d281c522 100644 --- a/source3/registry/reg_backend_current_version.c +++ b/source3/registry/reg_backend_current_version.c @@ -55,17 +55,18 @@ static int current_version_fetch_values(const char *key, REGVAL_CTR *values) return 0; } - value_length = push_ucs2( value, value, sysroot_string, sizeof(value), - STR_TERMINATE|STR_NOALIGN ); - regval_ctr_addvalue( values, "SystemRoot", REG_SZ, value, value_length ); - - fstr_sprintf( sysversion, "%d.%d", lp_major_announce_version(), lp_minor_announce_version() ); - value_length = push_ucs2( value, value, sysversion, sizeof(value), - STR_TERMINATE|STR_NOALIGN ); - regval_ctr_addvalue( values, "CurrentVersion", REG_SZ, value, value_length ); - - - return regval_ctr_numvals( values ); + value_length = push_ucs2(value, value, sysroot_string, sizeof(value), + STR_TERMINATE|STR_NOALIGN ); + regval_ctr_addvalue(values, "SystemRoot", REG_SZ, value, value_length); + + fstr_sprintf(sysversion, "%d.%d", lp_major_announce_version(), + lp_minor_announce_version()); + value_length = push_ucs2(value, value, sysversion, sizeof(value), + STR_TERMINATE|STR_NOALIGN); + regval_ctr_addvalue(values, "CurrentVersion", REG_SZ, value, + value_length); + + return regval_ctr_numvals(values); } static int current_version_fetch_subkeys(const char *key, -- cgit From c16b74cc861c031fda34ea131dadc9d4e175a8ed Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 03:39:27 +0100 Subject: Add a registry backend perflib that replaces the former dynamic overlay. Michael (This used to be commit c3fba415951329ee90c7250b4e8d539f91b227f6) --- source3/Makefile.in | 1 + source3/include/reg_objects.h | 2 + source3/registry/reg_backend_perflib.c | 106 +++++++++++++++++++++++++++++++++ source3/registry/reg_db.c | 4 +- source3/registry/reg_dynamic.c | 45 -------------- source3/registry/reg_frontend.c | 2 + 6 files changed, 113 insertions(+), 47 deletions(-) create mode 100644 source3/registry/reg_backend_perflib.c diff --git a/source3/Makefile.in b/source3/Makefile.in index fa40d92948..1dcf75847f 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -423,6 +423,7 @@ REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_pri registry/reg_backend_tcpip_params.o \ registry/reg_backend_hkpt_params.o \ registry/reg_backend_current_version.o \ + registry/reg_backend_perflib.o \ $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ) RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index 24db16261d..3df701f61c 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -103,6 +103,8 @@ typedef struct { #define KEY_PRINTING_2K "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers" #define KEY_PRINTING_PORTS "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports" #define KEY_CURRENT_VERSION "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" +#define KEY_PERFLIB "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib" +#define KEY_PERFLIB_009 "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009" #define KEY_SMBCONF "HKLM\\SOFTWARE\\Samba\\smbconf" #define KEY_TREE_ROOT "" diff --git a/source3/registry/reg_backend_perflib.c b/source3/registry/reg_backend_perflib.c new file mode 100644 index 0000000000..999bca2682 --- /dev/null +++ b/source3/registry/reg_backend_perflib.c @@ -0,0 +1,106 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 2002-2005 + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * perflib registry backend. + * + * This is a virtual overlay, dynamically presenting perflib values. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +extern REGISTRY_OPS regdb_ops; + +#define KEY_PERFLIB_NORM "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB" +#define KEY_PERFLIB_009_NORM "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009" + +static int perflib_params( REGVAL_CTR *regvals ) +{ + int base_index = -1; + int last_counter = -1; + int last_help = -1; + int version = 0x00010001; + + base_index = reg_perfcount_get_base_index(); + regval_ctr_addvalue(regvals, "Base Index", REG_DWORD, (char *)&base_index, sizeof(base_index)); + last_counter = reg_perfcount_get_last_counter(base_index); + regval_ctr_addvalue(regvals, "Last Counter", REG_DWORD, (char *)&last_counter, sizeof(last_counter)); + last_help = reg_perfcount_get_last_help(last_counter); + regval_ctr_addvalue(regvals, "Last Help", REG_DWORD, (char *)&last_help, sizeof(last_help)); + regval_ctr_addvalue(regvals, "Version", REG_DWORD, (char *)&version, sizeof(version)); + + return regval_ctr_numvals( regvals ); +} + +static int perflib_009_params( REGVAL_CTR *regvals ) +{ + int base_index; + int buffer_size; + char *buffer = NULL; + + base_index = reg_perfcount_get_base_index(); + buffer_size = reg_perfcount_get_counter_names(base_index, &buffer); + regval_ctr_addvalue(regvals, "Counter", REG_MULTI_SZ, buffer, buffer_size); + if(buffer_size > 0) + SAFE_FREE(buffer); + buffer_size = reg_perfcount_get_counter_help(base_index, &buffer); + regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size); + if(buffer_size > 0) + SAFE_FREE(buffer); + + return regval_ctr_numvals( regvals ); +} + +static int perflib_fetch_values(const char *key, REGVAL_CTR *regvals) +{ + char *path = NULL; + TALLOC_CTX *ctx = talloc_tos(); + + path = talloc_strdup(ctx, key); + if (path == NULL) { + return -1; + } + path = normalize_reg_path(ctx, path); + if (path == NULL) { + return -1; + } + + if (strncmp(path, KEY_PERFLIB_NORM, strlen(path)) == 0) { + return perflib_params(regvals); + } else if (strncmp(path, KEY_PERFLIB_009_NORM, strlen(path)) == 0) { + return perflib_009_params(regvals); + } else { + return 0; + } +} + +static int perflib_fetch_subkeys(const char *key, + REGSUBKEY_CTR *subkey_ctr) +{ + return regdb_ops.fetch_subkeys(key, subkey_ctr); +} + +REGISTRY_OPS perflib_reg_ops = { + .fetch_values = perflib_fetch_values, + .fetch_subkeys = perflib_fetch_subkeys, +}; diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index fad6c8acd1..e162fb587f 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -44,8 +44,8 @@ static const char *builtin_registry_paths[] = { KEY_SHARES, KEY_EVENTLOG, KEY_SMBCONF, - "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib", - "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009", + KEY_PERFLIB, + KEY_PERFLIB_009, "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", KEY_PROD_OPTIONS, "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index ca87cc60f5..97cb462615 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -29,57 +29,12 @@ struct reg_dyn_values { int (*fetch_values) ( REGVAL_CTR *val ); }; -/*********************************************************************** -***********************************************************************/ - -static int perflib_params( REGVAL_CTR *regvals ) -{ - int base_index = -1; - int last_counter = -1; - int last_help = -1; - int version = 0x00010001; - - base_index = reg_perfcount_get_base_index(); - regval_ctr_addvalue(regvals, "Base Index", REG_DWORD, (char *)&base_index, sizeof(base_index)); - last_counter = reg_perfcount_get_last_counter(base_index); - regval_ctr_addvalue(regvals, "Last Counter", REG_DWORD, (char *)&last_counter, sizeof(last_counter)); - last_help = reg_perfcount_get_last_help(last_counter); - regval_ctr_addvalue(regvals, "Last Help", REG_DWORD, (char *)&last_help, sizeof(last_help)); - regval_ctr_addvalue(regvals, "Version", REG_DWORD, (char *)&version, sizeof(version)); - - return regval_ctr_numvals( regvals ); -} - -/*********************************************************************** -***********************************************************************/ - -static int perflib_009_params( REGVAL_CTR *regvals ) -{ - int base_index; - int buffer_size; - char *buffer = NULL; - - base_index = reg_perfcount_get_base_index(); - buffer_size = reg_perfcount_get_counter_names(base_index, &buffer); - regval_ctr_addvalue(regvals, "Counter", REG_MULTI_SZ, buffer, buffer_size); - if(buffer_size > 0) - SAFE_FREE(buffer); - buffer_size = reg_perfcount_get_counter_help(base_index, &buffer); - regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size); - if(buffer_size > 0) - SAFE_FREE(buffer); - - return regval_ctr_numvals( regvals ); -} - /*********************************************************************** Structure holding the registry paths and pointers to the value enumeration functions ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { - { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, - { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009", &perflib_009_params }, { NULL, NULL } }; diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index d489050904..9a35eb2263 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -33,6 +33,7 @@ extern REGISTRY_OPS prod_options_reg_ops; extern REGISTRY_OPS tcpip_params_reg_ops; extern REGISTRY_OPS hkpt_params_reg_ops; extern REGISTRY_OPS current_version_reg_ops; +extern REGISTRY_OPS perflib_reg_ops; extern REGISTRY_OPS regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -50,6 +51,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_TCPIP_PARAMS, &tcpip_params_reg_ops }, { KEY_HKPT, &hkpt_params_reg_ops }, { KEY_CURRENT_VERSION, ¤t_version_reg_ops }, + { KEY_PERFLIB, &perflib_reg_ops }, #endif { NULL, NULL } }; -- cgit From e45dacce898021bbce0ba5b2c18dc8e103931e51 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 03:45:40 +0100 Subject: Remove the dynamic registry overlay. It is unnecessary now the dynamic functions have been made registry backends of their own. Michael (This used to be commit e327953bd6b11aeb6f2ae48b49550a942eae8e88) --- source3/Makefile.in | 3 +- source3/registry/reg_dynamic.c | 92 ----------------------------------- source3/registry/reg_frontend_hilvl.c | 11 ----- 3 files changed, 1 insertion(+), 105 deletions(-) delete mode 100644 source3/registry/reg_dynamic.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 1dcf75847f..b32fc2fe77 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -415,7 +415,7 @@ REGOBJS_OBJ = registry/reg_objects.o REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \ registry/reg_db.o registry/reg_eventlog.o registry/reg_shares.o \ - registry/reg_util.o registry/reg_dynamic.o registry/reg_perfcount.o \ + registry/reg_util.o registry/reg_perfcount.o \ registry/reg_smbconf.o registry/reg_api.o \ registry/reg_frontend_hilvl.o \ registry/reg_backend_netlogon_params.o \ @@ -741,7 +741,6 @@ REG_API_OBJ = registry/reg_api.o \ registry/reg_cachehook.o \ registry/reg_eventlog.o \ registry/reg_perfcount.o \ - registry/reg_dynamic.o \ \ lib/util_nttoken.o \ $(UTIL_REG_API_OBJ) \ diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c deleted file mode 100644 index 97cb462615..0000000000 --- a/source3/registry/reg_dynamic.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Virtual Windows Registry Layer - * Copyright (C) Gerald Carter 2002-2005 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -/* Implementation of registry frontend view functions. */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - -struct reg_dyn_values { - const char *path; - int (*fetch_values) ( REGVAL_CTR *val ); -}; - -/*********************************************************************** - Structure holding the registry paths and pointers to the value - enumeration functions -***********************************************************************/ - -static struct reg_dyn_values dynamic_values[] = { - { NULL, NULL } -}; - -/*********************************************************************** -***********************************************************************/ - -int fetch_dynamic_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) -{ - int i; - char *path = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - path = talloc_strdup(ctx, key->name); - if (!path) { - return -1; - } - path = normalize_reg_path(ctx, path); - if (!path) { - return -1; - } - - for ( i=0; dynamic_values[i].path; i++ ) { - if ( strcmp( path, dynamic_values[i].path ) == 0 ) - return dynamic_values[i].fetch_values( val ); - } - - return -1; -} - -/*********************************************************************** -***********************************************************************/ - -bool check_dynamic_reg_values( REGISTRY_KEY *key ) -{ - int i; - char *path = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - path = talloc_strdup(ctx, key->name); - if (!path) { - return false; - } - path = normalize_reg_path(ctx, path); - if (!path) { - return false; - } - - for ( i=0; dynamic_values[i].path; i++ ) { - /* can't write to dynamic keys */ - if ( strcmp( path, dynamic_values[i].path ) == 0 ) - return true; - } - - return false; -} diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c index cd02eeef74..6819d06704 100644 --- a/source3/registry/reg_frontend_hilvl.c +++ b/source3/registry/reg_frontend_hilvl.c @@ -87,9 +87,6 @@ bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) { - if ( check_dynamic_reg_values( key ) ) - return false; - if ( key->hook && key->hook->ops && key->hook->ops->store_values ) return key->hook->ops->store_values( key->name, val ); @@ -122,14 +119,6 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) if ( key->hook && key->hook->ops && key->hook->ops->fetch_values ) result = key->hook->ops->fetch_values( key->name, val ); - /* if the backend lookup returned no data, try the dynamic overlay */ - - if ( result == 0 ) { - result = fetch_dynamic_reg_values( key, val ); - - return ( result != -1 ) ? result : 0; - } - return result; } -- cgit From 7745674f0cbf5be272ad20fdd1e5edd45165e849 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 16:08:52 +0100 Subject: Add some debugging output to reg_cachehook.c Michael (This used to be commit 2a278928805f4497e8afa28bdca433cbedc4a8d7) --- source3/registry/reg_cachehook.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/source3/registry/reg_cachehook.c b/source3/registry/reg_cachehook.c index 22352c6112..f9851c7810 100644 --- a/source3/registry/reg_cachehook.c +++ b/source3/registry/reg_cachehook.c @@ -37,6 +37,11 @@ bool reghook_cache_init( void ) { if (cache_tree == NULL) { cache_tree = pathtree_init(&default_hook, NULL); + if (cache_tree !=0) { + DEBUG(10, ("reghook_cache_init: new tree with default " + "ops %p for key [%s]\n", (void *)®db_ops, + KEY_TREE_ROOT)); + } } return (cache_tree != NULL); @@ -65,7 +70,8 @@ bool reghook_cache_add( REGISTRY_HOOK *hook ) return false; } - DEBUG(10,("reghook_cache_add: Adding key [%s]\n", key)); + DEBUG(10, ("reghook_cache_add: Adding ops %p for key [%s]\n", + (void *)hook->ops, key)); return pathtree_add( cache_tree, key, hook ); } @@ -102,6 +108,9 @@ REGISTRY_HOOK* reghook_cache_find( const char *keyname ) DEBUG(10,("reghook_cache_find: Searching for keyname [%s]\n", key)); hook = (REGISTRY_HOOK *)pathtree_find( cache_tree, key ) ; + + DEBUG(10, ("reghook_cache_find: found ops %p for key [%s]\n", + hook ? (void *)hook->ops : 0, key)); SAFE_FREE( key ); -- cgit From 6c5a831e96982ce0954c09de126205e334ff3a31 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 17:57:32 +0100 Subject: Add a debug message to fetch_reg_values(). Michael (This used to be commit 239aa59cc1b78f7fb82aa66418cdf92517ebc123) --- source3/registry/reg_frontend_hilvl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c index 6819d06704..e6e7613457 100644 --- a/source3/registry/reg_frontend_hilvl.c +++ b/source3/registry/reg_frontend_hilvl.c @@ -116,6 +116,9 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) { int result = -1; + DEBUG(10, ("fetch_reg_values called for key '%s' (ops %p)\n", key->name, + (key->hook && key->hook->ops) ? (void *)key->hook->ops : NULL)); + if ( key->hook && key->hook->ops && key->hook->ops->fetch_values ) result = key->hook->ops->fetch_values( key->name, val ); -- cgit From 536bff422969f79e92e90ca959716624fbb96ed1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 16:06:37 +0100 Subject: Do an explicit init_globals() when restarting for "config backend = registry". Michael (This used to be commit 487c43f9284598a3c60b06fc60e5c50844e11b87) --- source3/param/loadparm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 0d3fbbf77c..0796a78dd3 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -5725,6 +5725,7 @@ bool lp_load(const char *pszFname, */ config_backend = CONFIG_BACKEND_REGISTRY; /* start over */ + init_globals(false); return lp_load(pszFname, global_only, save_defaults, add_ipc, initialize_globals); } -- cgit From 0bb6fb7b6f8ea1c039e710f55bba779363716f2d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 19 Jan 2008 21:53:49 -0800 Subject: Couple of minor fixes for POSIX pathname processing in the new stream code. (1) In smbd/filename, don't split the name at ':' if we know it's a posix path (this should be parameterized....). (2). When calling posix_mkdir, we get the flag FILE_FLAG_POSIX_SEMANTICS passed to open_directory(). I know for a posix client lp_posix_pathnames should be true (which is checked for in is_ntfs_stream_name() but we have an explicit flag here, so let's use it. Jeremy. (This used to be commit 7bb7a0def6518784befa75e5303289d2b4d36dd4) --- source3/smbd/filename.c | 18 ++++++++++-------- source3/smbd/open.c | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 1d44c7498e..10e9583049 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -214,16 +214,18 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, return NT_STATUS_NO_MEMORY; } - stream = strchr_m(name, ':'); + if (!lp_posix_pathnames()) { + stream = strchr_m(name, ':'); - if (stream != NULL) { - char *tmp = talloc_strdup(ctx, stream); - if (tmp == NULL) { - TALLOC_FREE(name); - return NT_STATUS_NO_MEMORY; + if (stream != NULL) { + char *tmp = talloc_strdup(ctx, stream); + if (tmp == NULL) { + TALLOC_FREE(name); + return NT_STATUS_NO_MEMORY; + } + *stream = '\0'; + stream = tmp; } - *stream = '\0'; - stream = tmp; } /* diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 0d6e07a032..ad221c3227 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2106,7 +2106,7 @@ NTSTATUS open_directory(connection_struct *conn, (unsigned int)create_disposition, (unsigned int)file_attributes)); - if (is_ntfs_stream_name(fname)) { + if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) && is_ntfs_stream_name(fname)) { DEBUG(2, ("open_directory: %s is a stream name!\n", fname)); return NT_STATUS_NOT_A_DIRECTORY; } -- cgit From 611609ee2584cc0703c0524ae712ee385ae006f4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 09:03:32 +0100 Subject: Fix a segfault MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pointed out by Steven Danneman on irc, thanks! Jerry, Günther, please check! (This used to be commit 9e71c89ac648040739ef2161a2e6c4299be1e35b) --- source3/winbindd/winbindd_cm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 908228717e..ef159f0670 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -613,7 +613,13 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain, DS_RETURN_DNS_NAME, &domain_info); if (W_ERROR_IS_OK(werr)) { - fstrcpy(tmp, domain_info->domain_controller_name); + tmp = talloc_strdup( + mem_ctx, domain_info->domain_controller_name); + if (tmp == NULL) { + DEBUG(0, ("talloc_strdup failed\n")); + talloc_destroy(mem_ctx); + return false; + } if (strlen(domain->alt_name) == 0) { fstrcpy(domain->alt_name, domain_info->domain_name); @@ -635,11 +641,10 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain, /* And restore our original timeout. */ cli_set_timeout(netlogon_pipe->cli, orig_timeout); - talloc_destroy(mem_ctx); - if (!W_ERROR_IS_OK(werr)) { DEBUG(10, ("rpccli_netlogon_getanydcname failed: %s\n", dos_errstr(werr))); + talloc_destroy(mem_ctx); return False; } @@ -654,6 +659,8 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain, fstrcpy(dcname, p); + talloc_destroy(mem_ctx); + DEBUG(10, ("rpccli_netlogon_getanydcname returned %s\n", dcname)); if (!resolve_name(dcname, dc_ss, 0x20)) { -- cgit From e1d01878f5e7c4a0f7d90ae0463bd6c11774d910 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 11:10:06 +0100 Subject: Complete the ea->xattr rename in vfs_xattr_tdb (This used to be commit dac468216e7e103b6897f33ec3608412f77265cf) --- source3/modules/vfs_xattr_tdb.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 597dd38eaf..0acca51c5d 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -558,7 +558,8 @@ static bool xattr_tdb_init(int snum, struct db_context **p_db) struct db_context *db; const char *dbname; - dbname = lp_parm_const_string(snum, "ea", "tdb", lock_path("eas.tdb")); + dbname = lp_parm_const_string(snum, "xattr", "tdb", + lock_path("xattr.tdb")); if (dbname == NULL) { errno = ENOTSUP; @@ -660,7 +661,7 @@ static int xattr_tdb_rmdir(vfs_handle_struct *handle, const char *path) * Destructor for the VFS private data */ -static void close_ea_db(void **data) +static void close_xattr_db(void **data) { struct db_context **p_db = (struct db_context **)data; TALLOC_FREE(*p_db); @@ -688,14 +689,14 @@ static int xattr_tdb_connect(vfs_handle_struct *handle, const char *service, } if (!xattr_tdb_init(snum, &db)) { - DEBUG(5, ("Could not init ea tdb\n")); + DEBUG(5, ("Could not init xattr tdb\n")); lp_do_parameter(snum, "ea support", "False"); return 0; } lp_do_parameter(snum, "ea support", "True"); - SMB_VFS_HANDLE_SET_DATA(handle, db, close_ea_db, + SMB_VFS_HANDLE_SET_DATA(handle, db, close_xattr_db, struct db_context, return -1); return 0; -- cgit From 0b9314db5ace99096d7f8afa7f449f8e734a6b64 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 11:20:58 +0100 Subject: Support XATTR_CREATE and XATTR_REPLACE in vfs_xattr_tdb (This used to be commit 3509ee597f0977aadd4c70cfe8830a6aa95cd71f) --- source3/modules/vfs_xattr_tdb.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 0acca51c5d..7416fa785a 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -269,6 +269,11 @@ static int xattr_tdb_setattr(struct db_context *db_ctx, for (i=0; inum_xattrs; i++) { if (strcmp(attribs->xattrs[i].name, name) == 0) { + if (flags & XATTR_CREATE) { + TALLOC_FREE(rec); + errno = EEXIST; + return -1; + } break; } } @@ -276,6 +281,12 @@ static int xattr_tdb_setattr(struct db_context *db_ctx, if (i == attribs->num_xattrs) { struct tdb_xattr *tmp; + if (flags & XATTR_REPLACE) { + TALLOC_FREE(rec); + errno = ENOATTR; + return -1; + } + tmp = TALLOC_REALLOC_ARRAY( attribs, attribs->xattrs, struct tdb_xattr, attribs->num_xattrs + 1); -- cgit From a6fcaf73d7ae238283cd107260ae215d31b05ac4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 13:49:38 +0100 Subject: Really remove the _NEXT_ from vfs_xattr_tdb.c This must have been lost somewhere in my patch-mangling (This used to be commit c1794375d1fa27d72ec32946bb4bd7b9f96e59fc) --- source3/modules/vfs_streams_xattr.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 3701cddfb5..104ed638db 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -131,7 +131,7 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname, goto fail; } - if (SMB_VFS_NEXT_STAT(handle, base, sbuf) == -1) { + if (SMB_VFS_STAT(handle->conn, base, sbuf) == -1) { goto fail; } @@ -178,7 +178,7 @@ static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname, goto fail; } - if (SMB_VFS_NEXT_LSTAT(handle, base, sbuf) == -1) { + if (SMB_VFS_LSTAT(handle->conn, base, sbuf) == -1) { goto fail; } @@ -248,7 +248,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, baseflags &= ~O_EXCL; baseflags &= ~O_CREAT; - hostfd = SMB_VFS_NEXT_OPEN(handle, base, fsp, baseflags, mode); + hostfd = SMB_VFS_OPEN(handle->conn, base, fsp, baseflags, mode); /* It is legit to open a stream on a directory, but the base * fd has to be read-only. @@ -256,8 +256,8 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, if ((hostfd == -1) && (errno == EISDIR)) { baseflags &= ~O_ACCMODE; baseflags |= O_RDONLY; - hostfd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, baseflags, - mode); + hostfd = SMB_VFS_OPEN(handle->conn, fname, fsp, baseflags, + mode); } if (hostfd == -1) { @@ -289,8 +289,12 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, */ char null = '\0'; - if (SMB_VFS_NEXT_SETXATTR( - handle, base, xattr_name, &null, sizeof(null), + DEBUG(10, ("creating attribute %s on file %s\n", + xattr_name, base)); + + if (SMB_VFS_SETXATTR( + handle->conn, base, xattr_name, + &null, sizeof(null), flags & O_EXCL ? XATTR_CREATE : 0) == -1) { goto fail; } @@ -299,8 +303,9 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, if (flags & O_TRUNC) { char null = '\0'; - if (SMB_VFS_NEXT_SETXATTR( - handle, base, xattr_name, &null, sizeof(null), + if (SMB_VFS_SETXATTR( + handle->conn, base, xattr_name, + &null, sizeof(null), flags & O_EXCL ? XATTR_CREATE : 0) == -1) { goto fail; } @@ -332,7 +337,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, * BUGBUGBUG -- we would need to call fd_close_posix here, but * we don't have a full fsp yet */ - SMB_VFS_NEXT_CLOSE(handle, fsp, hostfd); + SMB_VFS_CLOSE(fsp, hostfd); } TALLOC_FREE(frame); @@ -364,7 +369,7 @@ static int streams_xattr_unlink(vfs_handle_struct *handle, const char *fname) goto fail; } - ret = SMB_VFS_NEXT_REMOVEXATTR(handle, base, xattr_name); + ret = SMB_VFS_REMOVEXATTR(handle->conn, base, xattr_name); if ((ret == -1) && (errno == ENOATTR)) { errno = ENOENT; @@ -497,13 +502,13 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle, if (is_ntfs_stream_name(fsp->fsp_name)) { return NT_STATUS_INVALID_PARAMETER; } - ret = SMB_VFS_NEXT_FSTAT(handle, fsp, &sbuf); + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { if (is_ntfs_stream_name(fname)) { return NT_STATUS_INVALID_PARAMETER; } - ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); } if (ret == -1) { @@ -595,8 +600,8 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, memcpy(ea.value.data + offset, data, n); - ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, sio->xattr_name, - ea.value.data, ea.value.length, 0); + ret = SMB_VFS_FSETXATTR(fsp->base_fsp, sio->xattr_name, + ea.value.data, ea.value.length, 0); TALLOC_FREE(ea.value.data); -- cgit From a39771d3d20280b289478da758089a1035415d65 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 13:51:52 +0100 Subject: For pread/pwrite we need to do the setxattr on base_fsp (This used to be commit d481dddc81699aba79e48bca79bfb10e586b5cbb) --- source3/modules/vfs_streams_xattr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 104ed638db..7d7ec02fe7 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -576,8 +576,8 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); } - status = get_ea_value(talloc_tos(), handle->conn, fsp, sio->base, - sio->xattr_name, &ea); + status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, + sio->base, sio->xattr_name, &ea); if (!NT_STATUS_IS_OK(status)) { return -1; } @@ -622,8 +622,8 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle, return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); } - status = get_ea_value(talloc_tos(), handle->conn, fsp, sio->base, - sio->xattr_name, &ea); + status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, + sio->base, sio->xattr_name, &ea); if (!NT_STATUS_IS_OK(status)) { return -1; } -- cgit From 4222fa62e927500f21f386ac57dd599234f7d8b1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 13:55:27 +0100 Subject: Add some DEBUG (This used to be commit 8db25aba63b1dffb0dfbc74012c7ebd0ce4d5682) --- source3/modules/vfs_streams_xattr.c | 12 ++++++++++++ source3/modules/vfs_xattr_tdb.c | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 7d7ec02fe7..e304810a02 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -92,6 +92,8 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, struct stream_io *io = (struct stream_io *) VFS_FETCH_FSP_EXTENSION(handle, fsp); + DEBUG(10, ("streams_xattr_fstat called for %d\n", fsp->fh->fd)); + if (io == NULL) { return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); } @@ -105,6 +107,8 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, return -1; } + DEBUG(10, ("sbuf->st_size = %d\n", (int)sbuf->st_size)); + sbuf->st_ino = stream_inode(sbuf, io->xattr_name); sbuf->st_mode &= ~S_IFMT; sbuf->st_mode |= S_IFREG; @@ -219,6 +223,8 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, int baseflags; int hostfd = -1; + DEBUG(10, ("streams_xattr_open called for %s\n", fname)); + if (!is_ntfs_stream_name(fname)) { return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); } @@ -267,6 +273,8 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, status = get_ea_value(talloc_tos(), handle->conn, fsp, base, xattr_name, &ea); + DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); + if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { /* @@ -274,6 +282,8 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, * O_CREAT, the higher levels should have created the base * file for us. */ + DEBUG(10, ("streams_xattr_open: base file %s not around, " + "returning ENOENT\n", base)); errno = ENOENT; goto fail; } @@ -572,6 +582,8 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, NTSTATUS status; int ret; + DEBUG(10, ("streams_xattr_pwrite called for %d bytes\n", (int)n)); + if (sio == NULL) { return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); } diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 7416fa785a..208066bedc 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -165,6 +165,9 @@ static ssize_t xattr_tdb_getattr(struct db_context *db_ctx, ssize_t result = -1; NTSTATUS status; + DEBUG(10, ("xattr_tdb_getattr called for file %s, name %s\n", + file_id_string_tos(id), name)); + status = xattr_tdb_load_attrs(talloc_tos(), db_ctx, id, &attribs); if (!NT_STATUS_IS_OK(status)) { @@ -250,6 +253,9 @@ static int xattr_tdb_setattr(struct db_context *db_ctx, struct tdb_xattrs *attribs; uint32_t i; + DEBUG(10, ("xattr_tdb_setattr called for file %s, name %s\n", + file_id_string_tos(id), name)); + rec = xattr_tdb_lock_attrs(talloc_tos(), db_ctx, id); if (rec == NULL) { -- cgit From 6fcbb1111d06cd158cc6f1178418fe7299830197 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 14:05:36 +0100 Subject: In streams_xattr_pwrite, base_fsp does not have an fd These bugs haven't shown up when I did my tests with real xattrs, not with the xattr_tdb backend. It worked because the stream fsp does has the base file as fd. (This used to be commit b7022f8f7bf83c9c5e73e98d1477b7da766e8c5f) --- source3/modules/vfs_streams_xattr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index e304810a02..4fc25f0e83 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -612,7 +612,8 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, memcpy(ea.value.data + offset, data, n); - ret = SMB_VFS_FSETXATTR(fsp->base_fsp, sio->xattr_name, + ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name, + sio->xattr_name, ea.value.data, ea.value.length, 0); TALLOC_FREE(ea.value.data); -- cgit From fe57c149f0916e895055e2a9faf5eac8724912fb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 14:09:08 +0100 Subject: Do not use an unfinished fsp in streams_xattr_open (This used to be commit 023b313d0d4ed3beb8d77177bc8141cadeb86658) --- source3/modules/vfs_streams_xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 4fc25f0e83..d0112a5d74 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -270,7 +270,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname, goto fail; } - status = get_ea_value(talloc_tos(), handle->conn, fsp, base, + status = get_ea_value(talloc_tos(), handle->conn, NULL, base, xattr_name, &ea); DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); -- cgit From f87d08f6222f3e86b771c9c8ef669c1872118f6b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 14:43:30 +0100 Subject: Don't test split_ntfs_stream_name This is a hot code path, and if it has a :, the name will be split later on anyway. (This used to be commit 9f7f6b812d89decea1456ccdc37978e645d11a63) --- source3/smbd/reply.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 61ec611b6b..5a5eb1e190 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -168,9 +168,6 @@ static NTSTATUS check_path_syntax_internal(char *path, *d = '\0'; - if (NT_STATUS_IS_OK(ret) && !posix_path) { - ret = split_ntfs_stream_name(NULL, path, NULL, NULL); - } return ret; } -- cgit From 896ec681816b38d85e3dfbb45e9df8993de42899 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 14:44:07 +0100 Subject: NT_STATUS_OBJECT_NAME_NOT_FOUND also means "no streams around :-)" (This used to be commit 96b9a7b3eb92c9f133a3f43ffc4d57d0212e4ebd) --- source3/smbd/open.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index ad221c3227..f55728665f 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2464,7 +2464,8 @@ static NTSTATUS open_streams_for_delete(connection_struct *conn, status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(), &num_streams, &stream_info); - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED) + || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { DEBUG(10, ("no streams around\n")); TALLOC_FREE(frame); return NT_STATUS_OK; -- cgit From bf7f13c9a7aebd228d9ba4d45a69809b7a1a8d99 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 15:09:53 +0100 Subject: Fix valgrind errors (This used to be commit d7e6ec2258350c564053371361c8f1d7d0f775b1) --- source3/modules/vfs_streams_xattr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index d0112a5d74..87bcf22fb3 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -121,7 +121,7 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) { NTSTATUS status; - char *base, *sname; + char *base = NULL, *sname = NULL; int result = -1; char *xattr_name; @@ -132,7 +132,7 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname, status = split_ntfs_stream_name(talloc_tos(), fname, &base, &sname); if (!NT_STATUS_IS_OK(status)) { errno = EINVAL; - goto fail; + return -1; } if (SMB_VFS_STAT(handle->conn, base, sbuf) == -1) { -- cgit From 152c720ddbff3566d64d7e09561354820ff840c9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 14:10:51 +0100 Subject: Active RAW-STREAMS in make test (This used to be commit 63ee2ef775b48fcaecccf4dc7ef3601ceb8053c5) --- source3/script/tests/selftest.sh | 2 +- source3/script/tests/test_posix_s3.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh index 5a170b2117..c6232cf301 100755 --- a/source3/script/tests/selftest.sh +++ b/source3/script/tests/selftest.sh @@ -186,7 +186,7 @@ cat >$SERVERCONFFILE<