summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-01-04 19:06:37 -0800
committerJeremy Allison <jra@samba.org>2008-01-04 19:06:37 -0800
commit01afb07321a5af0fdd46fb30bda9419b553c1d5c (patch)
treed685c6a6dfd5674e9394f850ccad999330c7e97c
parent06f80cf8becc84672aad9d8703e1a2fbc80af20c (diff)
parent3d40b197b0312967c8d22af73f18414a9fe053bb (diff)
downloadsamba-01afb07321a5af0fdd46fb30bda9419b553c1d5c.tar.gz
samba-01afb07321a5af0fdd46fb30bda9419b553c1d5c.tar.bz2
samba-01afb07321a5af0fdd46fb30bda9419b553c1d5c.zip
Merge branch 'v3-2-test' of ssh://jra@git.samba.org/data/git/samba into v3-2-test
(This used to be commit 3a45f62310faf63cd6864d2cb10f941492eda818)
-rw-r--r--.gitignore1
-rw-r--r--source3/Makefile.in14
-rw-r--r--source3/client/client.c10
-rw-r--r--source3/configure.in4
-rw-r--r--source3/include/ads_protos.h4
-rw-r--r--source3/include/doserr.h2
-rw-r--r--source3/include/memcache.h55
-rw-r--r--source3/include/smb.h6
-rw-r--r--source3/include/smb_macros.h11
-rw-r--r--source3/lib/dummysmbd.c21
-rw-r--r--source3/lib/netapi/examples/netdomjoin-gui/logo-small.pngbin0 -> 4485 bytes
-rw-r--r--source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c98
-rw-r--r--source3/lib/netapi/examples/netdomjoin/netdomjoin.c12
-rw-r--r--source3/lib/netapi/joindomain.c43
-rw-r--r--source3/lib/netapi/serverinfo.c4
-rw-r--r--source3/lib/util_reg_smbconf.c4
-rw-r--r--source3/lib/util_sock.c238
-rw-r--r--source3/lib/winbind_util.c49
-rw-r--r--source3/libads/ldap.c77
-rw-r--r--source3/libnet/libnet_conf.c385
-rw-r--r--source3/libnet/libnet_join.c139
-rw-r--r--source3/libnet/libnet_join.h12
-rw-r--r--source3/libsmb/doserr.c4
-rw-r--r--source3/libsmb/smb_seal.c25
-rw-r--r--source3/libsmb/smb_signing.c8
-rw-r--r--source3/libsmb/smbencrypt.c20
-rw-r--r--source3/locking/locking.c5
-rw-r--r--source3/nmbd/nmbd_packets.c5
-rw-r--r--source3/nmbd/nmbd_responserecordsdb.c24
-rw-r--r--source3/nsswitch/libwbclient/wbc_pam.c4
-rw-r--r--source3/nsswitch/libwbclient/wbc_pwd.c8
-rw-r--r--source3/nsswitch/libwbclient/wbc_sid.c35
-rw-r--r--source3/nsswitch/libwbclient/wbc_util.c16
-rw-r--r--source3/nsswitch/libwbclient/wbclient.h2
-rw-r--r--source3/param/loadparm.c5
-rw-r--r--source3/passdb/pdb_ldap.c4
-rw-r--r--source3/printing/nt_printing.c2
-rw-r--r--source3/registry/reg_api.c2
-rw-r--r--source3/registry/reg_cachehook.c10
-rw-r--r--source3/registry/reg_db.c24
-rwxr-xr-xsource3/script/tests/test_smbclient_s3.sh8
-rwxr-xr-xsource3/script/tests/test_smbtorture_s3.sh2
-rwxr-xr-xsource3/script/tests/tests_all.sh4
-rw-r--r--source3/smbd/aio.c27
-rw-r--r--source3/smbd/blocking.c54
-rw-r--r--source3/smbd/error.c4
-rw-r--r--source3/smbd/ipc.c59
-rw-r--r--source3/smbd/lanman.c2
-rw-r--r--source3/smbd/message.c8
-rw-r--r--source3/smbd/negprot.c2
-rw-r--r--source3/smbd/notify.c46
-rw-r--r--source3/smbd/nttrans.c53
-rw-r--r--source3/smbd/open.c12
-rw-r--r--source3/smbd/oplock.c26
-rw-r--r--source3/smbd/pipes.c3
-rw-r--r--source3/smbd/process.c177
-rw-r--r--source3/smbd/reply.c376
-rw-r--r--source3/smbd/seal.c44
-rw-r--r--source3/smbd/sesssetup.c42
-rw-r--r--source3/smbd/trans2.c154
-rw-r--r--source3/torture/torture.c61
-rw-r--r--source3/utils/net_conf.c153
-rw-r--r--source3/utils/smbcacls.c2
-rw-r--r--source3/utils/smbfilter.c28
-rw-r--r--source3/winbindd/winbindd_ads.c12
-rw-r--r--source3/winbindd/winbindd_cm.c38
-rw-r--r--source3/winbindd/winbindd_group.c11
-rw-r--r--source3/winbindd/winbindd_rpc.c6
-rw-r--r--source3/winbindd/winbindd_util.c10
69 files changed, 1655 insertions, 1161 deletions
diff --git a/.gitignore b/.gitignore
index d3266edbbe..00ad9c82c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,4 @@ source/proto_exists
source/winbindd/winbindd_proto.h
source/cscope.out
source/torture.tdb
+source/pkgconfig/*.pc
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 01f2988b88..2267be4680 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -676,7 +676,7 @@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(RPC_PARSE_OBJ) \
$(SECRETS_OBJ) $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(LDB_OBJ)
-LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o $(TDB_BASE_OBJ)
+LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o $(TDBBASE_OBJ)
# This shared library is intended for linking with unit test programs
# to test Samba internals. It's called libbigballofmud.so to
@@ -1414,7 +1414,7 @@ bin/libaddns.a: $(BINARY_PREREQS) $(LIBADDNS_OBJ)
bin/libnetapi.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBNETAPI_OBJ)
@echo Linking shared library $@
- @$(SHLD_DSO) $(LIBNETAPI_OBJ) $(LIBS) \
+ @$(SHLD_DSO) $(LIBNETAPI_OBJ) @LIBWBCLIENT_SHARED@ $(LIBS) \
$(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS) \
@SONAMEFLAG@`basename $@`.$(SONAME_VER)
@@ -1424,7 +1424,7 @@ bin/libnetapi.a: $(BINARY_PREREQS) $(LIBNETAPI_OBJ)
bin/libsmbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ)
@echo Linking shared library $@
- @$(SHLD_DSO) $(LIBSMBCLIENT_OBJ) $(LIBS) \
+ @$(SHLD_DSO) $(LIBSMBCLIENT_OBJ) @LIBWBCLIENT_SHARED@ $(LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
@SONAMEFLAG@`basename $@`.$(SONAME_VER)
@@ -2129,6 +2129,14 @@ Makefile: $(srcdir)/Makefile.in config.status
######################################################################
# Samba Testing Framework
+# Check shared libs for unresolved symbols
+test_shlibs: $(SHLIBS)
+ @echo "Testing $(SHLIBS) "
+ @for module in $(SHLIBS); do \
+ ./script/tests/dlopen.sh bin/$${module}.@SHLIBEXT@ \
+ || exit 1; \
+ done
+
# Check for NSS module problems.
test_nss_modules: nss_modules
@echo "Testing $(NSS_MODULES) "
diff --git a/source3/client/client.c b/source3/client/client.c
index 6c00638eb9..a5e4a3863a 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -4328,16 +4328,22 @@ static void readline_callback(void)
timeout.tv_usec = 0;
sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout);
- /* We deliberately use receive_smb instead of
+ /* We deliberately use receive_smb_raw instead of
client_receive_smb as we want to receive
session keepalives and then drop them here.
*/
if (FD_ISSET(cli->fd,&fds)) {
- if (!receive_smb(cli->fd,cli->inbuf,0,&cli->smb_rw_error)) {
+ if (receive_smb_raw(cli->fd,cli->inbuf,0,0,&cli->smb_rw_error) == -1) {
DEBUG(0, ("Read from server failed, maybe it closed the "
"connection\n"));
return;
}
+ if(CVAL(cli->inbuf,0) != SMBkeepalive) {
+ DEBUG(0, ("Read from server "
+ "returned unexpected packet!\n"));
+ return;
+ }
+
goto again;
}
diff --git a/source3/configure.in b/source3/configure.in
index d7fde01619..934a99462b 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -455,7 +455,7 @@ AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnin
# DEVELOPER_CFLAGS, so that you can turn them on and off with a simple
# Makefile edit, avoiding the need to re-run configure.
if test x"$ac_cv_prog_gcc" = x"yes" ; then
- DEVELOPER_CFLAGS="-gstabs -Wall -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+ DEVELOPER_CFLAGS="-g -Wall -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
# Add -Wdeclaration-after-statement if compiler supports it
AC_CACHE_CHECK(
[that the C compiler understands -Wdeclaration-after-statement],
@@ -5102,7 +5102,7 @@ LIBNETAPI_SHARED=
LIBNETAPI=
AC_MSG_CHECKING(whether to build the libnetapi shared library)
AC_ARG_WITH(libnetapi,
-[ --with-libnetapi Build the libnetapi shared library (default=no undefined API)],
+[ --with-libnetapi Build the libnetapi shared library (default=yes if shared libs supported)],
[ case "$withval" in
*)
AC_MSG_RESULT(no)
diff --git a/source3/include/ads_protos.h b/source3/include/ads_protos.h
index 0292d91f4f..738df3ed40 100644
--- a/source3/include/ads_protos.h
+++ b/source3/include/ads_protos.h
@@ -114,3 +114,7 @@ ADS_STATUS ads_get_tokensids(ADS_STRUCT *ads,
DOM_SID *primary_group_sid,
DOM_SID **sids,
size_t *num_sids);
+ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads,
+ TALLOC_CTX *mem_ctx,
+ char ***ous,
+ size_t *num_ous);
diff --git a/source3/include/doserr.h b/source3/include/doserr.h
index 079a5664dd..08f5b3e39d 100644
--- a/source3/include/doserr.h
+++ b/source3/include/doserr.h
@@ -216,12 +216,14 @@
#define WERR_BUF_TOO_SMALL W_ERROR(2123)
#define WERR_JOB_NOT_FOUND W_ERROR(2151)
#define WERR_DEST_NOT_FOUND W_ERROR(2152)
+#define WERR_USER_EXISTS W_ERROR(2224)
#define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320)
#define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453)
#define WERR_SETUP_ALREADY_JOINED W_ERROR(2691)
#define WERR_SETUP_NOT_JOINED W_ERROR(2692)
#define WERR_SETUP_DOMAIN_CONTROLLER W_ERROR(2693)
+#define WERR_DEFAULT_JOIN_REQUIRED W_ERROR(2694)
#define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319)
#define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105)
diff --git a/source3/include/memcache.h b/source3/include/memcache.h
index 5a0ce63cb7..0a596b91a5 100644
--- a/source3/include/memcache.h
+++ b/source3/include/memcache.h
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
In-memory cache
- Copyright (C) Volker Lendecke 2005-2007
+ Copyright (C) Volker Lendecke 2007-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
@@ -24,6 +24,15 @@
struct memcache;
+/*
+ * A memcache can store different subkeys with overlapping keys, the
+ * memcache_number becomes part of the key. Feel free to add caches of your
+ * own here.
+ *
+ * If you add talloc type caches, also note this in the switch statement in
+ * memcache_is_talloc().
+ */
+
enum memcache_number {
STAT_CACHE,
UID_SID_CACHE,
@@ -38,25 +47,69 @@ enum memcache_number {
SINGLETON_CACHE
};
+/*
+ * Create a memcache structure. max_size is in bytes, if you set it 0 it will
+ * not forget anything.
+ */
+
struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size);
+/*
+ * If you set this global memcache, use it as the default cache when NULL is
+ * passed to the memcache functions below. This is a workaround for many
+ * situations where passing the cache everywhere would be a big hassle.
+ */
+
void memcache_set_global(struct memcache *cache);
+/*
+ * Add a data blob to the cache
+ */
+
void memcache_add(struct memcache *cache, enum memcache_number n,
DATA_BLOB key, DATA_BLOB value);
+/*
+ * Add a talloc object to the cache. The difference to memcache_add() is that
+ * when the objects is to be discared, talloc_free is called for it. Also
+ * talloc_move() ownership of the object to the cache.
+ *
+ * Please note that the current implementation has a fixed relationship
+ * between what cache subtypes store talloc objects and which ones store plain
+ * blobs. We can fix this, but for now we don't have a mixed use of blobs vs
+ * talloc objects in the cache types.
+ */
+
void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
DATA_BLOB key, void *ptr);
+/*
+ * Delete an object from the cache
+ */
+
void memcache_delete(struct memcache *cache, enum memcache_number n,
DATA_BLOB key);
+/*
+ * Look up an object from the cache. Memory still belongs to the cache, so
+ * make a copy of it if needed.
+ */
+
bool memcache_lookup(struct memcache *cache, enum memcache_number n,
DATA_BLOB key, DATA_BLOB *value);
+/*
+ * Look up an object from the cache. Memory still belongs to the cache, so
+ * make a copy of it if needed.
+ */
+
void *memcache_lookup_talloc(struct memcache *cache, enum memcache_number n,
DATA_BLOB key);
+/*
+ * Flush a complete cache subset.
+ */
+
void memcache_flush(struct memcache *cache, enum memcache_number n);
#endif
diff --git a/source3/include/smb.h b/source3/include/smb.h
index aca0009688..49245eaa83 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -27,7 +27,7 @@
#define _SMB_H
/* logged when starting the various Samba daemons */
-#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2007"
+#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2008"
#if defined(LARGE_SMB_OFF_T)
@@ -659,6 +659,7 @@ typedef struct connection_struct {
int num_files_open;
unsigned int num_smb_operations; /* Count of smb operations on this tree. */
int encrypt_level;
+ bool encrypted_tid;
/* Semantics requested by the client or forced by the server config. */
bool case_sensitive;
@@ -694,6 +695,8 @@ struct smb_request {
const uint8 *inbuf;
uint8 *outbuf;
size_t unread_bytes;
+ bool encrypted;
+ connection_struct *conn;
};
/* Defines for the sent_oplock_break field above. */
@@ -757,6 +760,7 @@ struct pending_message_list {
struct pending_message_list *next, *prev;
struct timeval request_time; /* When was this first issued? */
struct timeval end_time; /* When does this time out? */
+ bool encrypted;
DATA_BLOB buf;
DATA_BLOB private_data;
};
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 9bacdce1db..3324f3fc02 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -158,10 +158,10 @@
#define SMB_LARGE_LKLEN_OFFSET_HIGH(indx) (12 + (20 * (indx)))
#define SMB_LARGE_LKLEN_OFFSET_LOW(indx) (16 + (20 * (indx)))
-#define ERROR_DOS(class,code) error_packet(inbuf,outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
-#define ERROR_NT(status) error_packet(inbuf,outbuf,0,0,status,__LINE__,__FILE__)
-#define ERROR_FORCE_NT(status) error_packet(inbuf,outbuf,-1,-1,status,__LINE__,__FILE__)
-#define ERROR_BOTH(status,class,code) error_packet(inbuf,outbuf,class,code,status,__LINE__,__FILE__)
+#define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
+#define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__)
+#define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__)
+#define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__)
#define reply_nterror(req,status) reply_nt_error(req,status,__LINE__,__FILE__)
#define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__)
@@ -192,6 +192,9 @@
#define _smb_setlen_large(buf,len) do { buf[0] = 0; buf[1] = ((len)&0xFF0000)>>16; \
buf[2] = ((len)&0xFF00)>>8; buf[3] = (len)&0xFF; } while (0)
+#define ENCRYPTION_REQUIRED(conn) ((conn) ? ((conn)->encrypt_level == Required) : false)
+#define IS_CONN_ENCRYPTED(conn) ((conn) ? (conn)->encrypted_tid : false)
+
/*******************************************************************
find the difference in milliseconds between two struct timeval
values
diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c
index 464ba92306..dbe886e3d1 100644
--- a/source3/lib/dummysmbd.c
+++ b/source3/lib/dummysmbd.c
@@ -51,24 +51,3 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
{
return NT_STATUS_OK;
}
-
-NTSTATUS srv_decrypt_buffer(char *buf)
-{
- return NT_STATUS_OK;
-}
-
-NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out)
-{
- *buf_out = buffer;
- return NT_STATUS_OK;
-}
-
-void srv_free_enc_buffer(char *buf)
-{
- ;
-}
-
-bool srv_encryption_on(void)
-{
- return false;
-}
diff --git a/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png b/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png
new file mode 100644
index 0000000000..f041198002
--- /dev/null
+++ b/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png
Binary files differ
diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
index beb12be8b1..d12e66bb26 100644
--- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
+++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
@@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* Join Support (gtk + netapi)
- * Copyright (C) Guenther Deschner 2007
+ * Copyright (C) Guenther Deschner 2007-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
@@ -35,6 +35,7 @@
#define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico"
#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png"
+#define SAMBA_IMAGE_PATH_SMALL "/usr/share/pixmaps/samba/logo-small.png"
#define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 )
#define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 )
@@ -124,7 +125,6 @@ static void free_join_state(struct join_state *s)
SAFE_FREE(s->my_fqdn);
SAFE_FREE(s->my_dnsdomain);
SAFE_FREE(s->my_hostname);
-
}
static void do_cleanup(struct join_state *state)
@@ -225,7 +225,8 @@ static void callback_do_reboot(GtkWidget *widget,
gtk_widget_destroy(dialog);
#endif
- gtk_label_set_text(GTK_LABEL(state->label_reboot), "Changes will take effect after you restart this computer");
+ gtk_label_set_text(GTK_LABEL(state->label_reboot),
+ "Changes will take effect after you restart this computer");
debug("destroying do_change window\n");
gtk_widget_destroy(GTK_WIDGET(state->window_do_change));
@@ -248,11 +249,14 @@ static void callback_do_reboot(GtkWidget *widget,
SAFE_FREE(buffer);
state->name_type_new = type;
#endif
- gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new);
- if (state->name_type_new == 3) {
- gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Domain:");
+ gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer),
+ state->name_buffer_new);
+ if (state->name_type_new == NetSetupDomainName) {
+ gtk_label_set_text(GTK_LABEL(state->label_current_name_type),
+ "Domain:");
} else {
- gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Workgroup:");
+ gtk_label_set_text(GTK_LABEL(state->label_current_name_type),
+ "Workgroup:");
}
}
}
@@ -365,7 +369,8 @@ static void callback_do_join(GtkWidget *widget,
uint32_t unjoin_flags = 0;
gboolean domain_join = FALSE;
gboolean try_unjoin = FALSE;
- const char *domain_or_workgroup = NULL;
+ const char *new_workgroup_type = NULL;
+ const char *initial_workgroup_type = NULL;
struct join_state *state = (struct join_state *)data;
@@ -376,14 +381,33 @@ static void callback_do_join(GtkWidget *widget,
gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt));
}
+ switch (state->name_type_initial) {
+ case NetSetupWorkgroupName:
+ initial_workgroup_type = "workgroup";
+ break;
+ case NetSetupDomainName:
+ initial_workgroup_type = "domain";
+ break;
+ default:
+ break;
+ }
+
+ switch (state->name_type_new) {
+ case NetSetupWorkgroupName:
+ new_workgroup_type = "workgroup";
+ break;
+ case NetSetupDomainName:
+ new_workgroup_type = "domain";
+ break;
+ default:
+ break;
+ }
+
if (state->name_type_new == NetSetupDomainName) {
domain_join = TRUE;
join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */
- domain_or_workgroup = "domain";
- } else {
- domain_or_workgroup = "workgroup";
}
if ((state->name_type_initial == NetSetupDomainName) &&
@@ -394,7 +418,7 @@ static void callback_do_join(GtkWidget *widget,
}
debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ",
- domain_or_workgroup,
+ new_workgroup_type,
state->name_buffer_new,
join_flags);
if (domain_join) {
@@ -422,8 +446,8 @@ static void callback_do_join(GtkWidget *widget,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"The following error occured attempting to unjoin the %s: \"%s\": %s",
- domain_or_workgroup,
- state->name_buffer_new,
+ initial_workgroup_type,
+ state->name_buffer_initial,
err_str);
g_signal_connect_swapped(dialog, "response",
@@ -451,7 +475,7 @@ static void callback_do_join(GtkWidget *widget,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"The following error occured attempting to join the %s: \"%s\": %s",
- domain_or_workgroup,
+ new_workgroup_type,
state->name_buffer_new,
err_str);
@@ -465,7 +489,7 @@ static void callback_do_join(GtkWidget *widget,
}
debug("callback_do_join: Successfully joined %s\n",
- domain_or_workgroup);
+ new_workgroup_type);
dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -473,7 +497,7 @@ static void callback_do_join(GtkWidget *widget,
GTK_BUTTONS_OK,
"Welcome to the %s %s.",
state->name_buffer_new,
- domain_or_workgroup);
+ new_workgroup_type);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
@@ -760,6 +784,8 @@ static void callback_do_change(GtkWidget *widget,
debug("callback_do_change called\n");
+#if 0
+ /* FIXME: add proper warnings for Samba as a DC */
if (state->server_role == 3) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main),
@@ -774,13 +800,14 @@ static void callback_do_change(GtkWidget *widget,
gtk_widget_show(dialog);
return;
}
+#endif
state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes");
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
- gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); /* breite * höhe */
+ gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500);
gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
g_signal_connect(G_OBJECT(window), "delete_event",
@@ -830,14 +857,17 @@ static void callback_do_change(GtkWidget *widget,
char *str = NULL;
entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
if (state->name_type_initial == NetSetupDomainName) {
- asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain);
+ asprintf(&str, "%s.%s", entry_text,
+ state->my_dnsdomain);
} else {
asprintf(&str, "%s.", entry_text);
}
- gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str);
+ gtk_label_set_text(GTK_LABEL(state->label_full_computer_name),
+ str);
free(str);
gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0);
- gtk_box_pack_start(GTK_BOX(box1), state->label_full_computer_name, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(box1),
+ state->label_full_computer_name, TRUE, TRUE, 0);
gtk_widget_show(state->label_full_computer_name);
}
@@ -872,7 +902,8 @@ static void callback_do_change(GtkWidget *widget,
G_CALLBACK(callback_continue),
(gpointer)state);
if (state->name_type_initial == NetSetupDomainName) {
- gtk_entry_set_text(GTK_ENTRY(state->entry_domain), state->name_buffer_initial);
+ gtk_entry_set_text(GTK_ENTRY(state->entry_domain),
+ state->name_buffer_initial);
gtk_widget_set_sensitive(state->entry_workgroup, FALSE);
gtk_widget_set_sensitive(state->entry_domain, TRUE);
}
@@ -893,7 +924,8 @@ static void callback_do_change(GtkWidget *widget,
G_CALLBACK(callback_do_join_workgroup),
(gpointer)state);
{
- gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), MAX_NETBIOS_NAME_LEN);
+ gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup),
+ MAX_NETBIOS_NAME_LEN);
g_signal_connect(G_OBJECT(state->entry_workgroup), "changed",
G_CALLBACK(callback_enter_workgroup_and_unlock),
(gpointer)state);
@@ -902,7 +934,8 @@ static void callback_do_change(GtkWidget *widget,
(gpointer)state);
if (state->name_type_initial == NetSetupWorkgroupName) {
- gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), state->name_buffer_initial);
+ gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup),
+ state->name_buffer_initial);
gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE);
gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE);
}
@@ -979,21 +1012,25 @@ static int draw_main_window(struct join_state *state)
icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH,
&error);
if (icon == NULL) {
- g_print("failed to load logo from %s : %s\n",
+ g_print("failed to load icon from %s : %s\n",
SAMBA_ICON_PATH, error->message);
}
#if 1
- image = gtk_image_new_from_file(SAMBA_IMAGE_PATH);
+ image = gtk_image_new_from_file(SAMBA_IMAGE_PATH_SMALL);
#else
image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png");
#endif
+ if (image == NULL) {
+ g_print("failed to load logo from %s : %s\n",
+ SAMBA_IMAGE_PATH_SMALL, error->message);
+ }
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
state->window_main = window;
gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue");
- gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); /* breite * höhe */
+ gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
@@ -1015,14 +1052,15 @@ static int draw_main_window(struct join_state *state)
{
/* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */
- gtk_misc_set_alignment(GTK_MISC(image), 0, 0);
+/* gtk_misc_set_alignment(GTK_MISC(image), 0, 0); */
+ gtk_widget_set_size_request(GTK_WIDGET(image), 150, 40);
gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10);
gtk_widget_show(image);
/* Label */
label = gtk_label_new("Samba uses the following information to identify your computer on the network.");
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
- gtk_widget_set_size_request(GTK_WIDGET(label), 500, 40);
+/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */
+ gtk_widget_set_size_request(GTK_WIDGET(label), 400, 40);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
gtk_widget_show(label);
diff --git a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c
index e8b529927f..634d265597 100644
--- a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c
+++ b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c
@@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* Join Support (cmdline + netapi)
- * Copyright (C) Guenther Deschner 2007
+ * Copyright (C) Guenther Deschner 2007-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
@@ -56,7 +56,10 @@ int main(int argc, char **argv)
if (argc < 2) {
printf("usage: netdomjoin\n");
- printf("\t[hostname=HOSTNAME] [domain=DOMAIN] <ou=OU> <usero=USERO> <passwordo=PASSWORDO> <userd=USERD> <passwordd=PASSWORDD>\n");
+ printf("\t[hostname] [domain=DOMAIN] <ou=OU> "
+ "<usero=USERO> <passwordo=PASSWORDO> "
+ "<userd=USERD> <passwordd=PASSWORDD> "
+ "<debug=DEBUGLEVEL>\n");
return 0;
}
@@ -87,6 +90,11 @@ int main(int argc, char **argv)
str = get_string_param(argv[i]);
libnetapi_set_password(ctx, str);
}
+ if (strncasecmp(argv[i], "debug", strlen("debug"))== 0) {
+ const char *str = NULL;
+ str = get_string_param(argv[i]);
+ libnetapi_set_debuglevel(ctx, str);
+ }
}
status = NetJoinDomain(server_name,
diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c
index e3d5eada02..c7849c952f 100644
--- a/source3/lib/netapi/joindomain.c
+++ b/source3/lib/netapi/joindomain.c
@@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* NetApi Join Support
- * Copyright (C) Guenther Deschner 2007
+ * Copyright (C) Guenther Deschner 2007-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
@@ -54,8 +54,9 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx,
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
- r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name);
- W_ERROR_HAVE_NO_MEMORY(r->in.server_name);
+ r->in.dc_name = talloc_strdup(mem_ctx,
+ info->domain_controller_name);
+ W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
}
if (account_ou) {
@@ -69,8 +70,8 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx,
}
if (password) {
- r->in.password = talloc_strdup(mem_ctx, password);
- W_ERROR_HAVE_NO_MEMORY(r->in.password);
+ r->in.admin_password = talloc_strdup(mem_ctx, password);
+ W_ERROR_HAVE_NO_MEMORY(r->in.admin_password);
}
r->in.join_flags = join_flags;
@@ -89,13 +90,11 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx,
{
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_cli = NULL;
- struct wkssvc_PasswordBuffer encrypted_password;
+ struct wkssvc_PasswordBuffer *encrypted_password = NULL;
NTSTATUS status;
WERROR werr;
unsigned int old_timeout = 0;
- ZERO_STRUCT(encrypted_password);
-
status = cli_full_connection(&cli, NULL, server_name,
NULL, 0,
"IPC$", "IPC",
@@ -114,7 +113,7 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx,
if (!pipe_cli) {
werr = ntstatus_to_werror(status);
goto done;
- };
+ }
if (password) {
encode_wkssvc_join_password_buffer(ctx,
@@ -128,7 +127,7 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx,
status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx,
server_name, domain_name,
account_ou, Account,
- &encrypted_password,
+ encrypted_password,
join_flags, &werr);
if (!NT_STATUS_IS_OK(status)) {
werr = ntstatus_to_werror(status);
@@ -224,8 +223,8 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
W_ERROR_NOT_OK_RETURN(werr);
if (server_name) {
- r->in.server_name = talloc_strdup(mem_ctx, server_name);
- W_ERROR_HAVE_NO_MEMORY(r->in.server_name);
+ r->in.dc_name = talloc_strdup(mem_ctx, server_name);
+ W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
} else {
NTSTATUS status;
@@ -233,7 +232,6 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
DS_WRITABLE_REQUIRED |
- DS_IS_FLAT_NAME |
DS_RETURN_DNS_NAME;
if (lp_realm()) {
domain = lp_realm();
@@ -245,8 +243,9 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
- r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name);
- W_ERROR_HAVE_NO_MEMORY(r->in.server_name);
+ r->in.dc_name = talloc_strdup(mem_ctx,
+ info->domain_controller_name);
+ W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
}
if (account) {
@@ -255,8 +254,8 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
}
if (password) {
- r->in.password = talloc_strdup(mem_ctx, password);
- W_ERROR_HAVE_NO_MEMORY(r->in.password);
+ r->in.admin_password = talloc_strdup(mem_ctx, password);
+ W_ERROR_HAVE_NO_MEMORY(r->in.admin_password);
}
r->in.unjoin_flags = unjoin_flags;
@@ -276,13 +275,11 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx,
{
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_cli = NULL;
- struct wkssvc_PasswordBuffer encrypted_password;
+ struct wkssvc_PasswordBuffer *encrypted_password = NULL;
NTSTATUS status;
WERROR werr;
unsigned int old_timeout = 0;
- ZERO_STRUCT(encrypted_password);
-
status = cli_full_connection(&cli, NULL, server_name,
NULL, 0,
"IPC$", "IPC",
@@ -301,7 +298,7 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx,
if (!pipe_cli) {
werr = ntstatus_to_werror(status);
goto done;
- };
+ }
if (password) {
encode_wkssvc_join_password_buffer(ctx,
@@ -315,7 +312,7 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx,
status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx,
server_name,
account,
- &encrypted_password,
+ encrypted_password,
unjoin_flags,
&werr);
if (!NT_STATUS_IS_OK(status)) {
@@ -408,7 +405,7 @@ static WERROR NetGetJoinInformationRemote(struct libnetapi_ctx *ctx,
if (!pipe_cli) {
werr = ntstatus_to_werror(status);
goto done;
- };
+ }
status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, ctx,
server_name,
diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c
index 27c7c4b2fc..0e356e0ee7 100644
--- a/source3/lib/netapi/serverinfo.c
+++ b/source3/lib/netapi/serverinfo.c
@@ -167,8 +167,8 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx,
return WERR_NOT_SUPPORTED;
}
- return libnet_smbconf_set_global_param("server string",
- info1005->comment);
+ return libnet_conf_set_global_parameter("server string",
+ info1005->comment);
}
static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx,
diff --git a/source3/lib/util_reg_smbconf.c b/source3/lib/util_reg_smbconf.c
index 154c67ab8f..fa58f28d03 100644
--- a/source3/lib/util_reg_smbconf.c
+++ b/source3/lib/util_reg_smbconf.c
@@ -57,7 +57,7 @@ done:
*/
bool registry_init_regdb(void)
{
- bool ret = False;
+ bool ret = false;
int saved_errno = 0;
static REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops};
@@ -78,7 +78,7 @@ bool registry_init_regdb(void)
goto done;
}
- ret = True;
+ ret = true;
done:
return ret;
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index d16a8f079a..945506ea77 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -1277,80 +1277,6 @@ ssize_t receive_smb_raw(int fd,
}
/****************************************************************************
- Wrapper for receive_smb_raw().
- Checks the MAC on signed packets.
-****************************************************************************/
-
-bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_errors *pre)
-{
- if (receive_smb_raw(fd, buffer, timeout, 0, pre) < 0) {
- return false;
- }
-
- if (srv_encryption_on()) {
- NTSTATUS status = srv_decrypt_buffer(buffer);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("receive_smb: SMB decryption failed "
- "on incoming packet! Error %s\n",
- nt_errstr(status) ));
- cond_set_smb_read_error(pre, SMB_READ_BAD_DECRYPT);
- return false;
- }
- }
-
- /* Check the incoming SMB signature. */
- if (!srv_check_sign_mac(buffer, true)) {
- DEBUG(0, ("receive_smb: SMB Signature verification "
- "failed on incoming packet!\n"));
- cond_set_smb_read_error(pre,SMB_READ_BAD_SIG);
- return false;
- }
-
- return true;
-}
-
-/****************************************************************************
- Send an smb to a fd.
-****************************************************************************/
-
-bool send_smb(int fd, char *buffer)
-{
- size_t len;
- size_t nwritten=0;
- ssize_t ret;
- char *buf_out = buffer;
-
- /* Sign the outgoing packet if required. */
- srv_calculate_sign_mac(buf_out);
-
- if (srv_encryption_on()) {
- NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("send_smb: SMB encryption failed "
- "on outgoing packet! Error %s\n",
- nt_errstr(status) ));
- return false;
- }
- }
-
- len = smb_len(buf_out) + 4;
-
- while (nwritten < len) {
- ret = write_data(fd,buf_out+nwritten,len - nwritten);
- if (ret <= 0) {
- DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
- (int)len,(int)ret, strerror(errno) ));
- srv_free_enc_buffer(buf_out);
- return false;
- }
- nwritten += ret;
- }
-
- srv_free_enc_buffer(buf_out);
- return true;
-}
-
-/****************************************************************************
Open a socket of the specified type, port, and address for incoming data.
****************************************************************************/
@@ -1824,18 +1750,66 @@ static bool matchname(const char *remotehost,
return false;
}
-static struct {
- struct sockaddr_storage ss;
- char *name;
-} nc;
+/*******************************************************************
+ Deal with the singleton cache.
+******************************************************************/
+
+struct name_addr_pair {
+ struct sockaddr_storage ss;
+ const char *name;
+};
+
+/*******************************************************************
+ Lookup a name/addr pair. Returns memory allocated from memcache.
+******************************************************************/
+
+static bool lookup_nc(struct name_addr_pair *nc)
+{
+ DATA_BLOB tmp;
+
+ ZERO_STRUCTP(nc);
+
+ if (!memcache_lookup(
+ NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_peer_name"),
+ &tmp)) {
+ return false;
+ }
+
+ memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
+ nc->name = (const char *)tmp.data + sizeof(nc->ss);
+ return true;
+}
+
+/*******************************************************************
+ Save a name/addr pair.
+******************************************************************/
+
+static void store_nc(const struct name_addr_pair *nc)
+{
+ DATA_BLOB tmp;
+ size_t namelen = strlen(nc->name);
+
+ tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
+ if (!tmp.data) {
+ return;
+ }
+ memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
+ memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
+
+ memcache_add(NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_peer_name"),
+ tmp);
+ data_blob_free(&tmp);
+}
/*******************************************************************
Return the DNS name of the remote end of a socket.
******************************************************************/
-const char *get_peer_name(int fd,
- bool force_lookup)
+const char *get_peer_name(int fd, bool force_lookup)
{
+ struct name_addr_pair nc;
char addr_buf[INET6_ADDRSTRLEN];
struct sockaddr_storage ss;
socklen_t length = sizeof(ss);
@@ -1850,13 +1824,15 @@ const char *get_peer_name(int fd,
possible */
if (!lp_hostname_lookups() && (force_lookup == false)) {
length = sizeof(nc.ss);
- p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
+ nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
&nc.ss, &length);
- SAFE_FREE(nc.name);
- nc.name = SMB_STRDUP(p);
+ store_nc(&nc);
+ lookup_nc(&nc);
return nc.name ? nc.name : "UNKNOWN";
}
+ lookup_nc(&nc);
+
memset(&ss, '\0', sizeof(ss));
p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &ss, &length);
@@ -1865,9 +1841,7 @@ const char *get_peer_name(int fd,
return nc.name ? nc.name : "UNKNOWN";
}
- /* Not the same. Reset the cache. */
- zero_addr(&nc.ss);
- SAFE_FREE(nc.name);
+ /* Not the same. We need to lookup. */
if (fd == -1) {
return "UNKNOWN";
}
@@ -1904,7 +1878,11 @@ const char *get_peer_name(int fd,
strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
}
- nc.name = SMB_STRDUP(name_buf);
+ nc.name = name_buf;
+ nc.ss = ss;
+
+ store_nc(&nc);
+ lookup_nc(&nc);
return nc.name ? nc.name : "UNKNOWN";
}
@@ -2026,50 +2004,68 @@ out_umask:
const char *get_mydnsfullname(void)
{
- static char *dnshostname_cache;
-
- if (dnshostname_cache == NULL || !*dnshostname_cache) {
- struct addrinfo *res = NULL;
- char my_hostname[HOST_NAME_MAX];
- bool ret;
+ struct addrinfo *res = NULL;
+ char my_hostname[HOST_NAME_MAX];
+ bool ret;
+ DATA_BLOB tmp;
- /* get my host name */
- if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
- DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
- return NULL;
- }
+ if (memcache_lookup(NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_mydnsfullname"),
+ &tmp)) {
+ SMB_ASSERT(tmp.length > 0);
+ return (const char *)tmp.data;
+ }
- /* Ensure null termination. */
- my_hostname[sizeof(my_hostname)-1] = '\0';
+ /* get my host name */
+ if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
+ DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
+ return NULL;
+ }
- ret = interpret_string_addr_internal(&res,
- my_hostname,
- AI_ADDRCONFIG|AI_CANONNAME);
+ /* Ensure null termination. */
+ my_hostname[sizeof(my_hostname)-1] = '\0';
- if (!ret || res == NULL) {
- DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
- "name %s [%s]\n",
+ ret = interpret_string_addr_internal(&res,
my_hostname,
- gai_strerror(ret) ));
- return NULL;
- }
+ AI_ADDRCONFIG|AI_CANONNAME);
- /*
- * Make sure that getaddrinfo() returns the "correct" host name.
- */
+ if (!ret || res == NULL) {
+ DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
+ "name %s [%s]\n",
+ my_hostname,
+ gai_strerror(ret) ));
+ return NULL;
+ }
- if (res->ai_canonname == NULL) {
- DEBUG(3,("get_mydnsfullname: failed to get "
- "canonical name for %s\n",
- my_hostname));
- freeaddrinfo(res);
- return NULL;
- }
+ /*
+ * Make sure that getaddrinfo() returns the "correct" host name.
+ */
- dnshostname_cache = SMB_STRDUP(res->ai_canonname);
+ if (res->ai_canonname == NULL) {
+ DEBUG(3,("get_mydnsfullname: failed to get "
+ "canonical name for %s\n",
+ my_hostname));
freeaddrinfo(res);
+ return NULL;
}
- return dnshostname_cache;
+
+ /* This copies the data, so we must do a lookup
+ * afterwards to find the value to return.
+ */
+
+ memcache_add(NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_mydnsfullname"),
+ data_blob_string_const(res->ai_canonname));
+
+ freeaddrinfo(res);
+
+ if (!memcache_lookup(NULL, SINGLETON_CACHE,
+ data_blob_string_const("get_mydnsfullname"),
+ &tmp)) {
+ return NULL;
+ }
+
+ return (const char *)tmp.data;
}
/************************************************************
diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c
index f51a0171a2..3cf068a6e0 100644
--- a/source3/lib/winbind_util.c
+++ b/source3/lib/winbind_util.c
@@ -35,12 +35,12 @@ bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
result = wbcLookupName(dom_name, name, &dom_sid, &type);
if (result != WBC_ERR_SUCCESS)
- return False;
+ return false;
memcpy(sid, &dom_sid, sizeof(DOM_SID));
*name_type = (enum lsa_SidType)type;
- return True;
+ return true;
}
/* Call winbindd to convert sid to name */
@@ -59,7 +59,7 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
result = wbcLookupSid(&dom_sid, &domain_name, &account_name, &type);
if (result != WBC_ERR_SUCCESS)
- return False;
+ return false;
/* Copy out result */
@@ -74,16 +74,16 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
sid_string_dbg(sid), domain_name, account_name));
- SAFE_FREE(domain_name);
- SAFE_FREE(account_name);
+ wbcFreeMemory(domain_name);
+ wbcFreeMemory(account_name);
if ((domain && !*domain) || (name && !*name)) {
DEBUG(0,("winbind_lookup_sid: talloc() failed!\n"));
- return False;
+ return false;
}
- return True;
+ return true;
}
/* Ping winbindd to see it is alive */
@@ -192,8 +192,9 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
ret = wbcLookupRids(&dom_sid, num_rids, rids,
&dom_name, &namelist, &name_types);
- if (ret != WBC_ERR_SUCCESS)
- return False;
+ if (ret != WBC_ERR_SUCCESS) {
+ return false;
+ }
*domain_name = talloc_strdup(mem_ctx, dom_name);
*names = TALLOC_ARRAY(mem_ctx, const char*, num_rids);
@@ -202,13 +203,13 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
for(i=0; i<num_rids; i++) {
(*names)[i] = talloc_strdup(names, namelist[i]);
(*types)[i] = (enum lsa_SidType)name_types[i];
-
- free(CONST_DISCARD(char*, namelist[i]));
}
- free(namelist);
- free(name_types);
+
+ wbcFreeMemory(CONST_DISCARD(char*, dom_name));
+ wbcFreeMemory(namelist);
+ wbcFreeMemory(name_types);
- return True;
+ return true;
}
/* Ask Winbind to allocate a new uid for us */
@@ -238,7 +239,7 @@ bool winbind_allocate_gid(gid_t *gid)
bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
enum lsa_SidType *name_type)
{
- return False;
+ return false;
}
/* Call winbindd to convert sid to name */
@@ -247,42 +248,42 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
const char **domain, const char **name,
enum lsa_SidType *name_type)
{
- return False;
+ return false;
}
/* Ping winbindd to see it is alive */
bool winbind_ping(void)
{
- return False;
+ return false;
}
/* Call winbindd to convert SID to uid */
bool winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
{
- return False;
+ return false;
}
/* Call winbindd to convert uid to sid */
bool winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
{
- return False;
+ return false;
}
/* Call winbindd to convert SID to gid */
bool winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
{
- return False;
+ return false;
}
/* Call winbindd to convert gid to sid */
bool winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
{
- return False;
+ return false;
}
/* Check for a trusted domain */
@@ -300,21 +301,21 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
const char **domain_name,
const char ***names, enum lsa_SidType **types)
{
- return False;
+ return false;
}
/* Ask Winbind to allocate a new uid for us */
bool winbind_allocate_uid(uid_t *uid)
{
- return False;
+ return false;
}
/* Ask Winbind to allocate a new gid for us */
bool winbind_allocate_gid(gid_t *gid)
{
- return False;
+ return false;
}
#endif /* WITH_WINBIND */
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 953693ce48..975e926864 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -56,6 +56,10 @@ static void gotalarm_sig(void)
{
LDAP *ldp = NULL;
+
+ DEBUG(10, ("Opening connection to LDAP server '%s:%d', timeout "
+ "%u seconds\n", server, port, to));
+
/* Setup timeout */
gotalarm = 0;
CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
@@ -65,8 +69,10 @@ static void gotalarm_sig(void)
ldp = ldap_open(server, port);
if (ldp == NULL) {
- DEBUG(2,("Could not open LDAP connection to %s:%d: %s\n",
+ DEBUG(2,("Could not open connection to LDAP server %s:%d: %s\n",
server, port, strerror(errno)));
+ } else {
+ DEBUG(10, ("Connected to LDAP server '%s:%d'\n", server, port));
}
/* Teardown timeout. */
@@ -400,7 +406,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
got_connection:
print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
- DEBUG(3,("Connected to LDAP server %s\n", addr));
+ DEBUG(3,("Successfully contacted LDAP server %s\n", addr));
if (!ads->auth.user_name) {
/* Must use the userPrincipalName value here or sAMAccountName
@@ -442,11 +448,12 @@ got_connection:
/* Otherwise setup the TCP LDAP session */
- if ( (ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name,
- LDAP_PORT, lp_ldap_timeout())) == NULL )
- {
+ ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name,
+ LDAP_PORT, lp_ldap_timeout());
+ if (ads->ldap.ld == NULL) {
return ADS_ERROR(LDAP_OPERATIONS_ERROR);
}
+ DEBUG(3,("Connected to LDAP server %s\n", ads->config.ldap_server_name));
/* cache the successful connection for workgroup and realm */
if (ads_closest_dc(ads)) {
@@ -2791,6 +2798,66 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix
}
/**
+ * get the joinable ous for a domain
+ * @param ads connection to ads server
+ * @param mem_ctx Pointer to talloc context
+ * @param ous Pointer to an array of ous
+ * @param num_ous Pointer to the number of ous
+ * @return status of search
+ **/
+ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads,
+ TALLOC_CTX *mem_ctx,
+ char ***ous,
+ size_t *num_ous)
+{
+ ADS_STATUS status;
+ LDAPMessage *res = NULL;
+ LDAPMessage *msg = NULL;
+ const char *attrs[] = { "dn", NULL };
+ int count = 0;
+
+ status = ads_search(ads, &res,
+ "(|(objectClass=domain)(objectclass=organizationalUnit))",
+ attrs);
+ if (!ADS_ERR_OK(status)) {
+ return status;
+ }
+
+ count = ads_count_replies(ads, res);
+ if (count < 1) {
+ ads_msgfree(ads, res);
+ return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
+ }
+
+ for (msg = ads_first_entry(ads, res); msg;
+ msg = ads_next_entry(ads, msg)) {
+
+ char *dn = NULL;
+
+ dn = ads_get_dn(ads, msg);
+ if (!dn) {
+ ads_msgfree(ads, res);
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
+
+ if (!add_string_to_array(mem_ctx, dn,
+ (const char ***)ous,
+ (int *)num_ous)) {
+ ads_memfree(ads, dn);
+ ads_msgfree(ads, res);
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
+
+ ads_memfree(ads, dn);
+ }
+
+ ads_msgfree(ads, res);
+
+ return status;
+}
+
+
+/**
* pull a DOM_SID from an extended dn string
* @param mem_ctx TALLOC_CTX
* @param extended_dn string
diff --git a/source3/libnet/libnet_conf.c b/source3/libnet/libnet_conf.c
index 1069abcfbd..c8e55a70b2 100644
--- a/source3/libnet/libnet_conf.c
+++ b/source3/libnet/libnet_conf.c
@@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* libnet smbconf registry Support
- * Copyright (C) Michael Adam 2007
+ * Copyright (C) Michael Adam 2007-2008
* Copyright (C) Guenther Deschner 2007
*
* This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,11 @@
#include "includes.h"
#include "libnet/libnet.h"
+/*
+ * yuck - static variable to keep track of the registry initialization.
+ */
+static bool registry_initialized = false;
+
/**********************************************************************
*
* Helper functions (mostly registry related)
@@ -31,12 +36,11 @@
/**
* add a string to a talloced array of strings.
*/
-static WERROR libnet_smbconf_add_string_to_array(TALLOC_CTX *mem_ctx,
- char ***array,
- uint32_t count,
- const char *string)
+static WERROR libnet_conf_add_string_to_array(TALLOC_CTX *mem_ctx,
+ char ***array,
+ uint32_t count,
+ const char *string)
{
- WERROR werr = WERR_OK;
char **new_array = NULL;
if ((array == NULL) || (string == NULL)) {
@@ -55,31 +59,65 @@ static WERROR libnet_smbconf_add_string_to_array(TALLOC_CTX *mem_ctx,
return WERR_OK;
}
-/*
- * Open a subkey of KEY_SMBCONF (i.e a service)
+static WERROR libnet_conf_reg_initialize(void)
+{
+ WERROR werr = WERR_OK;
+
+ if (registry_initialized) {
+ goto done;
+ }
+
+ if (!registry_init_regdb()) {
+ werr = WERR_REG_IO_FAILURE;
+ goto done;
+ }
+
+ registry_initialized = true;
+
+done:
+ return werr;
+}
+
+/**
+ * Open a registry key specified by "path"
*/
-static WERROR libnet_smbconf_reg_open_path(TALLOC_CTX *ctx,
- const char *subkeyname,
- uint32 desired_access,
- struct registry_key **key)
+static WERROR libnet_conf_reg_open_path(TALLOC_CTX *mem_ctx,
+ const char *path,
+ uint32 desired_access,
+ struct registry_key **key)
{
WERROR werr = WERR_OK;
- char *path = NULL;
NT_USER_TOKEN *token;
+ TALLOC_CTX *tmp_ctx = NULL;
- if (!(token = registry_create_admin_token(ctx))) {
- DEBUG(1, ("Error creating admin token\n"));
+ if (path == NULL) {
+ DEBUG(1, ("Error: NULL path string given\n"));
+ werr = WERR_INVALID_PARAM;
goto done;
}
- if (subkeyname == NULL) {
- path = talloc_strdup(ctx, KEY_SMBCONF);
- } else {
- path = talloc_asprintf(ctx, "%s\\%s", KEY_SMBCONF, subkeyname);
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ werr = WERR_NOMEM;
+ goto done;
}
- werr = reg_open_path(ctx, path, desired_access,
- token, key);
+ werr = libnet_conf_reg_initialize();
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("Error initializing registry: %s\n",
+ dos_errstr(werr)));
+ goto done;
+ }
+
+ token = registry_create_admin_token(tmp_ctx);
+ if (token == NULL) {
+ DEBUG(1, ("Error creating admin token\n"));
+ /* what is the appropriate error code here? */
+ werr = WERR_CAN_NOT_COMPLETE;
+ goto done;
+ }
+
+ werr = reg_open_path(mem_ctx, path, desired_access, token, key);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("Error opening registry path '%s': %s\n",
@@ -87,42 +125,51 @@ static WERROR libnet_smbconf_reg_open_path(TALLOC_CTX *ctx,
}
done:
- TALLOC_FREE(path);
+ TALLOC_FREE(tmp_ctx);
return werr;
}
-/*
- * open the base key KEY_SMBCONF
+/**
+ * Open a subkey of KEY_SMBCONF (i.e a service)
*/
-static WERROR libnet_smbconf_reg_open_basepath(TALLOC_CTX *ctx,
+static WERROR libnet_conf_reg_open_service_key(TALLOC_CTX *ctx,
+ const char *servicename,
uint32 desired_access,
struct registry_key **key)
{
- return libnet_smbconf_reg_open_path(ctx, NULL, desired_access, key);
-}
-
-/*
- * check if a subkey of KEY_SMBCONF of a given name exists
- */
-bool libnet_smbconf_key_exists(const char *subkeyname)
-{
- bool ret = false;
WERROR werr = WERR_OK;
- TALLOC_CTX *mem_ctx = talloc_stackframe();
- struct registry_key *key = NULL;
+ char *path = NULL;
- werr = libnet_smbconf_reg_open_path(mem_ctx, subkeyname, REG_KEY_READ,
- &key);
- if (W_ERROR_IS_OK(werr)) {
- ret = true;
+ if (servicename == NULL) {
+ DEBUG(3, ("Error: NULL servicename given.\n"));
+ werr = WERR_INVALID_PARAM;
+ goto done;
}
- TALLOC_FREE(mem_ctx);
- return ret;
+ path = talloc_asprintf(ctx, "%s\\%s", KEY_SMBCONF, servicename);
+
+ werr = libnet_conf_reg_open_path(ctx, path, desired_access, key);
+
+done:
+ TALLOC_FREE(path);
+ return werr;
+}
+
+/**
+ * open the base key KEY_SMBCONF
+ */
+static WERROR libnet_conf_reg_open_base_key(TALLOC_CTX *ctx,
+ uint32 desired_access,
+ struct registry_key **key)
+{
+ return libnet_conf_reg_open_path(ctx, KEY_SMBCONF, desired_access, key);
}
-static bool libnet_smbconf_value_exists(struct registry_key *key,
- const char *param)
+/**
+ * check if a value exists in a given registry key
+ */
+static bool libnet_conf_value_exists(struct registry_key *key,
+ const char *param)
{
bool ret = false;
WERROR werr = WERR_OK;
@@ -138,12 +185,12 @@ static bool libnet_smbconf_value_exists(struct registry_key *key,
return ret;
}
-/*
+/**
* create a subkey of KEY_SMBCONF
*/
-WERROR libnet_smbconf_reg_createkey_internal(TALLOC_CTX *ctx,
- const char * subkeyname,
- struct registry_key **newkey)
+static WERROR libnet_conf_reg_create_service_key(TALLOC_CTX *ctx,
+ const char * subkeyname,
+ struct registry_key **newkey)
{
WERROR werr = WERR_OK;
struct registry_key *create_parent = NULL;
@@ -158,8 +205,8 @@ WERROR libnet_smbconf_reg_createkey_internal(TALLOC_CTX *ctx,
goto done;
}
- werr = libnet_smbconf_reg_open_basepath(create_ctx, REG_KEY_WRITE,
- &create_parent);
+ werr = libnet_conf_reg_open_base_key(create_ctx, REG_KEY_WRITE,
+ &create_parent);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -167,12 +214,12 @@ WERROR libnet_smbconf_reg_createkey_internal(TALLOC_CTX *ctx,
werr = reg_createkey(ctx, create_parent, subkeyname,
REG_KEY_WRITE, newkey, &action);
if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
- d_fprintf(stderr, "Key '%s' already exists.\n", subkeyname);
+ DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
werr = WERR_ALREADY_EXISTS;
}
if (!W_ERROR_IS_OK(werr)) {
- d_fprintf(stderr, "Error creating key %s: %s\n",
- subkeyname, dos_errstr(werr));
+ DEBUG(5, ("Error creating key %s: %s\n",
+ subkeyname, dos_errstr(werr)));
}
done:
@@ -180,12 +227,12 @@ done:
return werr;
}
-/*
+/**
* add a value to a key.
*/
-WERROR libnet_smbconf_reg_setvalue_internal(struct registry_key *key,
- const char *valname,
- const char *valstr)
+static WERROR libnet_conf_reg_set_value(struct registry_key *key,
+ const char *valname,
+ const char *valstr)
{
struct registry_value val;
WERROR werr = WERR_OK;
@@ -198,11 +245,11 @@ WERROR libnet_smbconf_reg_setvalue_internal(struct registry_key *key,
&canon_valstr))
{
if (canon_valname == NULL) {
- d_fprintf(stderr, "invalid parameter '%s' given\n",
- valname);
+ DEBUG(5, ("invalid parameter '%s' given\n",
+ valname));
} else {
- d_fprintf(stderr, "invalid value '%s' given for "
- "parameter '%s'\n", valstr, valname);
+ DEBUG(5, ("invalid value '%s' given for "
+ "parameter '%s'\n", valstr, valname));
}
werr = WERR_INVALID_PARAM;
goto done;
@@ -215,16 +262,16 @@ WERROR libnet_smbconf_reg_setvalue_internal(struct registry_key *key,
val.v.sz.len = strlen(canon_valstr) + 1;
if (registry_smbconf_valname_forbidden(canon_valname)) {
- d_fprintf(stderr, "Parameter '%s' not allowed in registry.\n",
- canon_valname);
+ DEBUG(5, ("Parameter '%s' not allowed in registry.\n",
+ canon_valname));
werr = WERR_INVALID_PARAM;
goto done;
}
subkeyname = strrchr_m(key->key->name, '\\');
if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) {
- d_fprintf(stderr, "Invalid registry key '%s' given as "
- "smbconf section.\n", key->key->name);
+ DEBUG(5, ("Invalid registry key '%s' given as "
+ "smbconf section.\n", key->key->name));
werr = WERR_INVALID_PARAM;
goto done;
}
@@ -232,19 +279,18 @@ WERROR libnet_smbconf_reg_setvalue_internal(struct registry_key *key,
if (!strequal(subkeyname, GLOBAL_NAME) &&
lp_parameter_is_global(valname))
{
- d_fprintf(stderr, "Global paramter '%s' not allowed in "
+ DEBUG(5, ("Global paramter '%s' not allowed in "
"service definition ('%s').\n", canon_valname,
- subkeyname);
+ subkeyname));
werr = WERR_INVALID_PARAM;
goto done;
}
werr = reg_setvalue(key, canon_valname, &val);
if (!W_ERROR_IS_OK(werr)) {
- d_fprintf(stderr,
- "Error adding value '%s' to "
+ DEBUG(5, ("Error adding value '%s' to "
"key '%s': %s\n",
- canon_valname, key->key->name, dos_errstr(werr));
+ canon_valname, key->key->name, dos_errstr(werr)));
}
done:
@@ -258,8 +304,8 @@ done:
* which are ar stored as REG_SZ values, so the incomplete
* handling should be ok.
*/
-static char *libnet_smbconf_format_registry_value(TALLOC_CTX *mem_ctx,
- struct registry_value *value)
+static char *libnet_conf_format_registry_value(TALLOC_CTX *mem_ctx,
+ struct registry_value *value)
{
char *result = NULL;
@@ -299,11 +345,11 @@ static char *libnet_smbconf_format_registry_value(TALLOC_CTX *mem_ctx,
* Get the values of a key as a list of value names
* and a list of value strings (ordered)
*/
-static WERROR libnet_smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
- struct registry_key *key,
- uint32_t *num_values,
- char ***value_names,
- char ***value_strings)
+static WERROR libnet_conf_reg_get_values(TALLOC_CTX *mem_ctx,
+ struct registry_key *key,
+ uint32_t *num_values,
+ char ***value_names,
+ char ***value_strings)
{
TALLOC_CTX *tmp_ctx = NULL;
WERROR werr = WERR_OK;
@@ -333,19 +379,19 @@ static WERROR libnet_smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
{
char *valstring;
- werr = libnet_smbconf_add_string_to_array(tmp_ctx,
- &tmp_valnames,
- count, valname);
+ werr = libnet_conf_add_string_to_array(tmp_ctx,
+ &tmp_valnames,
+ count, valname);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
- valstring = libnet_smbconf_format_registry_value(tmp_ctx,
- valvalue);
- werr = libnet_smbconf_add_string_to_array(tmp_ctx,
- &tmp_valstrings,
- count,
- valstring);
+ valstring = libnet_conf_format_registry_value(tmp_ctx,
+ valvalue);
+ werr = libnet_conf_add_string_to_array(tmp_ctx,
+ &tmp_valstrings,
+ count,
+ valstring);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -379,22 +425,15 @@ done:
/**
* Drop the whole configuration (restarting empty).
*/
-WERROR libnet_smbconf_drop(void)
+WERROR libnet_conf_drop(void)
{
char *path, *p;
WERROR werr = WERR_OK;
- NT_USER_TOKEN *token;
struct registry_key *parent_key = NULL;
struct registry_key *new_key = NULL;
TALLOC_CTX* mem_ctx = talloc_stackframe();
enum winreg_CreateAction action;
- if (!(token = registry_create_admin_token(mem_ctx))) {
- /* what is the appropriate error code here? */
- werr = WERR_CAN_NOT_COMPLETE;
- goto done;
- }
-
path = talloc_strdup(mem_ctx, KEY_SMBCONF);
if (path == NULL) {
werr = WERR_NOMEM;
@@ -402,7 +441,8 @@ WERROR libnet_smbconf_drop(void)
}
p = strrchr(path, '\\');
*p = '\0';
- werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token, &parent_key);
+ werr = libnet_conf_reg_open_path(mem_ctx, path, REG_KEY_WRITE,
+ &parent_key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
@@ -431,9 +471,9 @@ done:
* param_names : list of lists of parameter names for each share
* param_values : list of lists of parameter values for each share
*/
-WERROR libnet_smbconf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
- char ***share_names, uint32_t **num_params,
- char ****param_names, char ****param_values)
+WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
+ char ***share_names, uint32_t **num_params,
+ char ****param_names, char ****param_values)
{
WERROR werr = WERR_OK;
TALLOC_CTX *tmp_ctx = NULL;
@@ -458,8 +498,8 @@ WERROR libnet_smbconf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
goto done;
}
- werr = libnet_smbconf_get_share_names(tmp_ctx, &tmp_num_shares,
- &tmp_share_names);
+ werr = libnet_conf_get_share_names(tmp_ctx, &tmp_num_shares,
+ &tmp_share_names);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -476,10 +516,10 @@ WERROR libnet_smbconf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
}
for (count = 0; count < tmp_num_shares; count++) {
- werr = libnet_smbconf_getshare(mem_ctx, tmp_share_names[count],
- &tmp_num_params[count],
- &tmp_param_names[count],
- &tmp_param_values[count]);
+ werr = libnet_conf_get_share(mem_ctx, tmp_share_names[count],
+ &tmp_num_params[count],
+ &tmp_param_names[count],
+ &tmp_param_values[count]);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -509,8 +549,8 @@ done:
/**
* get the list of share names defined in the configuration.
*/
-WERROR libnet_smbconf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
- char ***share_names)
+WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
+ char ***share_names)
{
uint32_t count;
uint32_t added_count = 0;
@@ -532,19 +572,18 @@ WERROR libnet_smbconf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
}
/* make sure "global" is always listed first */
- if (libnet_smbconf_key_exists(GLOBAL_NAME)) {
- werr = libnet_smbconf_add_string_to_array(tmp_ctx,
- &tmp_share_names,
- 0, GLOBAL_NAME);
+ if (libnet_conf_share_exists(GLOBAL_NAME)) {
+ werr = libnet_conf_add_string_to_array(tmp_ctx,
+ &tmp_share_names,
+ 0, GLOBAL_NAME);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
added_count++;
}
- werr = libnet_smbconf_reg_open_basepath(tmp_ctx,
- SEC_RIGHTS_ENUM_SUBKEYS,
- &key);
+ werr = libnet_conf_reg_open_base_key(tmp_ctx, SEC_RIGHTS_ENUM_SUBKEYS,
+ &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -558,10 +597,10 @@ WERROR libnet_smbconf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
continue;
}
- werr = libnet_smbconf_add_string_to_array(tmp_ctx,
- &tmp_share_names,
- added_count,
- subkey_name);
+ werr = libnet_conf_add_string_to_array(tmp_ctx,
+ &tmp_share_names,
+ added_count,
+ subkey_name);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -585,23 +624,64 @@ done:
}
/**
+ * check if a share/service of a given name exists
+ */
+bool libnet_conf_share_exists(const char *servicename)
+{
+ bool ret = false;
+ WERROR werr = WERR_OK;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+ struct registry_key *key = NULL;
+
+ werr = libnet_conf_reg_open_service_key(mem_ctx, servicename,
+ REG_KEY_READ, &key);
+ if (W_ERROR_IS_OK(werr)) {
+ ret = true;
+ }
+
+ TALLOC_FREE(mem_ctx);
+ return ret;
+}
+
+/**
+ * Add a service if it does not already exist.
+ */
+WERROR libnet_conf_create_share(const char *servicename)
+{
+ WERROR werr;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+ struct registry_key *key = NULL;
+
+ if (libnet_conf_share_exists(servicename)) {
+ werr = WERR_ALREADY_EXISTS;
+ goto done;
+ }
+
+ werr = libnet_conf_reg_create_service_key(mem_ctx, servicename, &key);
+
+done:
+ TALLOC_FREE(mem_ctx);
+ return werr;
+}
+
+/**
* get a definition of a share (service) from configuration.
*/
-WERROR libnet_smbconf_getshare(TALLOC_CTX *mem_ctx, const char *servicename,
- uint32_t *num_params, char ***param_names,
- char ***param_values)
+WERROR libnet_conf_get_share(TALLOC_CTX *mem_ctx, const char *servicename,
+ uint32_t *num_params, char ***param_names,
+ char ***param_values)
{
WERROR werr = WERR_OK;
struct registry_key *key = NULL;
- werr = libnet_smbconf_reg_open_path(mem_ctx, servicename, REG_KEY_READ,
- &key);
+ werr = libnet_conf_reg_open_service_key(mem_ctx, servicename,
+ REG_KEY_READ, &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
- werr = libnet_smbconf_reg_get_values(mem_ctx, key, num_params,
- param_names, param_values);
+ werr = libnet_conf_reg_get_values(mem_ctx, key, num_params,
+ param_names, param_values);
done:
TALLOC_FREE(key);
@@ -611,13 +691,13 @@ done:
/**
* delete a service from configuration
*/
-WERROR libnet_smbconf_delshare(const char *servicename)
+WERROR libnet_conf_delete_share(const char *servicename)
{
WERROR werr = WERR_OK;
struct registry_key *key = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
- werr = libnet_smbconf_reg_open_basepath(ctx, REG_KEY_WRITE, &key);
+ werr = libnet_conf_reg_open_base_key(ctx, REG_KEY_WRITE, &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -632,26 +712,26 @@ done:
/**
* set a configuration parameter to the value provided.
*/
-WERROR libnet_smbconf_setparm(const char *service,
- const char *param,
- const char *valstr)
+WERROR libnet_conf_set_parameter(const char *service,
+ const char *param,
+ const char *valstr)
{
WERROR werr;
struct registry_key *key = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (!libnet_smbconf_key_exists(service)) {
- werr = libnet_smbconf_reg_createkey_internal(mem_ctx, service,
- &key);
- } else {
- werr = libnet_smbconf_reg_open_path(mem_ctx, service,
- REG_KEY_WRITE, &key);
+ if (!libnet_conf_share_exists(service)) {
+ werr = WERR_NO_SUCH_SERVICE;
+ goto done;
}
+
+ werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_WRITE,
+ &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
- werr = libnet_smbconf_reg_setvalue_internal(key, param, valstr);
+ werr = libnet_conf_reg_set_value(key, param, valstr);
done:
TALLOC_FREE(mem_ctx);
@@ -661,10 +741,10 @@ done:
/**
* get the value of a configuration parameter as a string
*/
-WERROR libnet_smbconf_getparm(TALLOC_CTX *mem_ctx,
- const char *service,
- const char *param,
- char **valstr)
+WERROR libnet_conf_get_parameter(TALLOC_CTX *mem_ctx,
+ const char *service,
+ const char *param,
+ char **valstr)
{
WERROR werr = WERR_OK;
struct registry_key *key = NULL;
@@ -675,18 +755,18 @@ WERROR libnet_smbconf_getparm(TALLOC_CTX *mem_ctx,
goto done;
}
- if (!libnet_smbconf_key_exists(service)) {
+ if (!libnet_conf_share_exists(service)) {
werr = WERR_NO_SUCH_SERVICE;
goto done;
}
- werr = libnet_smbconf_reg_open_path(mem_ctx, service, REG_KEY_READ,
- &key);
+ werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_READ,
+ &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
- if (!libnet_smbconf_value_exists(key, param)) {
+ if (!libnet_conf_value_exists(key, param)) {
werr = WERR_INVALID_PARAM;
goto done;
}
@@ -696,7 +776,7 @@ WERROR libnet_smbconf_getparm(TALLOC_CTX *mem_ctx,
goto done;
}
- *valstr = libnet_smbconf_format_registry_value(mem_ctx, value);
+ *valstr = libnet_conf_format_registry_value(mem_ctx, value);
if (*valstr == NULL) {
werr = WERR_NOMEM;
@@ -711,23 +791,23 @@ done:
/**
* delete a parameter from configuration
*/
-WERROR libnet_smbconf_delparm(const char *service,
- const char *param)
+WERROR libnet_conf_delete_parameter(const char *service, const char *param)
{
struct registry_key *key = NULL;
WERROR werr = WERR_OK;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (!libnet_smbconf_key_exists(service)) {
+ if (!libnet_conf_share_exists(service)) {
return WERR_NO_SUCH_SERVICE;
}
- werr = libnet_smbconf_reg_open_path(mem_ctx, service, REG_KEY_ALL, &key);
+ werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_ALL,
+ &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
- if (!libnet_smbconf_value_exists(key, param)) {
+ if (!libnet_conf_value_exists(key, param)) {
werr = WERR_INVALID_PARAM;
goto done;
}
@@ -746,9 +826,8 @@ done:
*
**********************************************************************/
-WERROR libnet_smbconf_set_global_param(const char *param,
- const char *val)
+WERROR libnet_conf_set_global_parameter(const char *param, const char *val)
{
- return libnet_smbconf_setparm(GLOBAL_NAME, param, val);
+ return libnet_conf_set_parameter(GLOBAL_NAME, param, val);
}
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 6edcdb8945..95b643ffa6 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -2,7 +2,7 @@
* Unix SMB/CIFS implementation.
* libnet Join Support
* Copyright (C) Gerald (Jerry) Carter 2006
- * Copyright (C) Guenther Deschner 2007
+ * Copyright (C) Guenther Deschner 2007-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
@@ -22,12 +22,30 @@
#include "libnet/libnet_join.h"
#include "libnet/libnet_proto.h"
-static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
- struct libnet_JoinCtx *r)
+static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r)
+{
+ if (!secrets_store_domain_sid(r->out.netbios_domain_name,
+ r->out.domain_sid))
+ {
+ return false;
+ }
+
+ if (!secrets_store_machine_password(r->in.machine_password,
+ r->out.netbios_domain_name,
+ SEC_CHAN_WKSTA))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r)
{
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_hnd = NULL;
- const char *password = NULL;
POLICY_HND sam_pol, domain_pol, user_pol, lsa_pol;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
char *acct_name;
@@ -46,17 +64,20 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
DATA_BLOB digested_session_key;
uchar md4_trust_password[16];
- password = talloc_strdup(mem_ctx,
- generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH));
- NT_STATUS_HAVE_NO_MEMORY(password);
+ if (!r->in.machine_password) {
+ r->in.machine_password = talloc_strdup(mem_ctx, generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH));
+ NT_STATUS_HAVE_NO_MEMORY(r->in.machine_password);
+ }
- status = cli_full_connection(&cli, NULL, r->in.server_name,
+ status = cli_full_connection(&cli, NULL,
+ r->in.dc_name,
NULL, 0,
"IPC$", "IPC",
r->in.admin_account,
- NULL, //r->in.domain_name,
- r->in.password,
- 0, Undefined, NULL);
+ NULL,
+ r->in.admin_password,
+ 0,
+ Undefined, NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
@@ -152,15 +173,16 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
goto done;
}
- E_md4hash(r->in.password, md4_trust_password);
- encode_pw_buffer(pwbuf, r->in.password, STR_UNICODE);
+ E_md4hash(r->in.machine_password, md4_trust_password);
+ encode_pw_buffer(pwbuf, r->in.machine_password, STR_UNICODE);
generate_random_buffer((uint8*)md5buffer, sizeof(md5buffer));
digested_session_key = data_blob_talloc(mem_ctx, 0, 16);
MD5Init(&md5ctx);
MD5Update(&md5ctx, md5buffer, sizeof(md5buffer));
- MD5Update(&md5ctx, cli->user_session_key.data, cli->user_session_key.length);
+ MD5Update(&md5ctx, cli->user_session_key.data,
+ cli->user_session_key.length);
MD5Final(digested_session_key.data, &md5ctx);
SamOEMhashBlob(pwbuf, sizeof(pwbuf), &digested_session_key);
@@ -194,21 +216,6 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
cli_rpc_pipe_close(pipe_hnd);
- if (!secrets_store_domain_sid(r->out.netbios_domain_name,
- r->out.domain_sid))
- {
- status = NT_STATUS_INTERNAL_DB_ERROR;
- goto done;
- }
-
- if (!secrets_store_machine_password(password,
- r->out.netbios_domain_name,
- SEC_CHAN_WKSTA))
- {
- status = NT_STATUS_INTERNAL_DB_ERROR;
- goto done;
- }
-
status = NT_STATUS_OK;
done:
if (cli) {
@@ -218,8 +225,22 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
return status;
}
-static NTSTATUS do_DomainUnjoin(TALLOC_CTX *mem_ctx,
- struct libnet_UnjoinCtx *r)
+static bool libnet_join_unjoindomain_remove_secrets(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx *r)
+{
+ if (!secrets_delete_machine_password_ex(lp_workgroup())) {
+ return false;
+ }
+
+ if (!secrets_delete_domain_sid(lp_workgroup())) {
+ return false;
+ }
+
+ return true;
+}
+
+static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx *r)
{
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_hnd = NULL;
@@ -233,12 +254,13 @@ static NTSTATUS do_DomainUnjoin(TALLOC_CTX *mem_ctx,
SAM_USERINFO_CTR ctr, *qctr = NULL;
SAM_USER_INFO_16 p16;
- status = cli_full_connection(&cli, NULL, r->in.server_name,
+ status = cli_full_connection(&cli, NULL,
+ r->in.dc_name,
NULL, 0,
"IPC$", "IPC",
r->in.admin_account,
- NULL, //r->in.domain_name,
- r->in.password,
+ NULL,
+ r->in.admin_password,
0, Undefined, NULL);
if (!NT_STATUS_IS_OK(status)) {
@@ -308,21 +330,12 @@ static NTSTATUS do_DomainUnjoin(TALLOC_CTX *mem_ctx,
rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
- if (!secrets_delete_machine_password_ex(lp_workgroup())) {
- status = NT_STATUS_INTERNAL_DB_ERROR;
- goto done;
- }
-
- if (!secrets_delete_domain_sid(lp_workgroup())) {
- status = NT_STATUS_INTERNAL_DB_ERROR;
- goto done;
- }
-
done:
- rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
- rpccli_samr_close(pipe_hnd, mem_ctx, &sam_pol);
-
- cli_rpc_pipe_close(pipe_hnd);
+ if (pipe_hnd) {
+ rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &sam_pol);
+ cli_rpc_pipe_close(pipe_hnd);
+ }
if (cli) {
cli_shutdown(cli);
@@ -338,11 +351,11 @@ static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r)
if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE)) {
- werr = libnet_smbconf_set_global_param("security", "user");
+ werr = libnet_conf_set_global_parameter("security", "user");
W_ERROR_NOT_OK_RETURN(werr);
- werr = libnet_smbconf_set_global_param("workgroup",
- r->in.domain_name);
+ werr = libnet_conf_set_global_parameter("workgroup",
+ r->in.domain_name);
return werr;
}
@@ -350,18 +363,18 @@ static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r)
is_ad = true;
}
- werr = libnet_smbconf_set_global_param("security", "domain");
+ werr = libnet_conf_set_global_parameter("security", "domain");
W_ERROR_NOT_OK_RETURN(werr);
- werr = libnet_smbconf_set_global_param("workgroup",
- r->out.netbios_domain_name);
+ werr = libnet_conf_set_global_parameter("workgroup",
+ r->out.netbios_domain_name);
W_ERROR_NOT_OK_RETURN(werr);
if (is_ad) {
- werr = libnet_smbconf_set_global_param("security", "ads");
+ werr = libnet_conf_set_global_parameter("security", "ads");
W_ERROR_NOT_OK_RETURN(werr);
- werr = libnet_smbconf_set_global_param("realm",
+ werr = libnet_conf_set_global_parameter("realm",
r->out.dns_domain_name);
W_ERROR_NOT_OK_RETURN(werr);
}
@@ -375,11 +388,11 @@ static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r)
if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
- werr = libnet_smbconf_set_global_param("security", "user");
+ werr = libnet_conf_set_global_parameter("security", "user");
W_ERROR_NOT_OK_RETURN(werr);
}
- werr = libnet_smbconf_delparm("GLOBAL", "realm");
+ werr = libnet_conf_delete_parameter(GLOBAL_NAME, "realm");
return werr;
}
@@ -481,13 +494,17 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
- status = do_DomainJoin(mem_ctx, r);
+ status = libnet_join_joindomain_rpc(mem_ctx, r);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
return WERR_SETUP_ALREADY_JOINED;
}
return ntstatus_to_werror(status);
}
+
+ if (!libnet_join_joindomain_store_secrets(mem_ctx, r)) {
+ return WERR_SETUP_NOT_JOINED;
+ }
}
werr = do_JoinConfig(r);
@@ -510,13 +527,15 @@ WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx,
if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
- status = do_DomainUnjoin(mem_ctx, r);
+ status = libnet_join_unjoindomain_rpc(mem_ctx, r);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
return WERR_SETUP_NOT_JOINED;
}
return ntstatus_to_werror(status);
}
+
+ libnet_join_unjoindomain_remove_secrets(mem_ctx, r);
}
werr = do_UnjoinConfig(r);
diff --git a/source3/libnet/libnet_join.h b/source3/libnet/libnet_join.h
index 46ab27e8b0..9e7b8a9813 100644
--- a/source3/libnet/libnet_join.h
+++ b/source3/libnet/libnet_join.h
@@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* libnet Join Support
- * Copyright (C) Guenther Deschner 2007
+ * Copyright (C) Guenther Deschner 2007-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
@@ -22,11 +22,13 @@
struct libnet_JoinCtx {
struct {
- const char *server_name;
+ const char *dc_name;
+ const char *machine_name;
const char *domain_name;
const char *account_ou;
const char *admin_account;
- const char *password;
+ const char *admin_password;
+ const char *machine_password;
uint32_t join_flags;
const char *os_version;
const char *os_string;
@@ -47,10 +49,10 @@ struct libnet_JoinCtx {
struct libnet_UnjoinCtx {
struct {
- const char *server_name;
+ const char *dc_name;
const char *domain_name;
const char *admin_account;
- const char *password;
+ const char *admin_password;
uint32_t unjoin_flags;
bool modify_config;
struct dom_sid *domain_sid;
diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c
index dd556bba5a..79445a2410 100644
--- a/source3/libsmb/doserr.c
+++ b/source3/libsmb/doserr.c
@@ -63,6 +63,7 @@ werror_code_struct dos_errs[] =
{ "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND },
{ "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND },
{ "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN },
+ { "WERR_USER_EXISTS", WERR_USER_EXISTS },
{ "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS },
{ "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION },
{ "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE },
@@ -77,6 +78,7 @@ werror_code_struct dos_errs[] =
{ "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED },
{ "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED },
{ "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER },
+ { "WERR_DEFAULT_JOIN_REQUIRED", WERR_DEFAULT_JOIN_REQUIRED },
{ "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE },
{ "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE },
{ "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN },
@@ -90,6 +92,7 @@ werror_code_struct dos_errs[] =
{ "WERR_REG_CORRUPT", WERR_REG_CORRUPT },
{ "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE },
{ "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID },
+ { "WERR_NO_SUCH_SERVICE", WERR_NO_SUCH_SERVICE },
{ "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED },
{ "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE},
{ "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS},
@@ -110,6 +113,7 @@ werror_str_struct dos_err_strs[] = {
{ WERR_SETUP_ALREADY_JOINED, "Machine is already joined" },
{ WERR_SETUP_DOMAIN_CONTROLLER, "Machine is a Domain Controller" },
{ WERR_LOGON_FAILURE, "Invalid logon credentials" },
+ { WERR_USER_EXISTS, "User account already exists" },
};
/*****************************************************************************
diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c
index 055a27d05a..b5befbf7cd 100644
--- a/source3/libsmb/smb_seal.c
+++ b/source3/libsmb/smb_seal.c
@@ -23,13 +23,13 @@
Pull out the encryption context for this packet. 0 means global context.
******************************************************************************/
-NTSTATUS get_enc_ctx_num(const char *buf, uint16 *p_enc_ctx_num)
+NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16 *p_enc_ctx_num)
{
if (smb_len(buf) < 8) {
return NT_STATUS_INVALID_BUFFER_SIZE;
}
- if (buf[4] == (char)0xFF) {
+ if (buf[4] == 0xFF) {
if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') {
/* Not an encrypted buffer. */
return NT_STATUS_NOT_FOUND;
@@ -93,8 +93,8 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len);
- /* Reset the length. */
- _smb_setlen(buf,data_len + 4);
+ /* Reset the length and overwrite the header. */
+ smb_setlen(buf,data_len + 4);
SAFE_FREE(inbuf);
return NT_STATUS_OK;
@@ -203,7 +203,8 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta
}
memcpy(buf + 8, out_buf.value, out_buf.length);
- _smb_setlen(buf, out_buf.length + 4);
+ /* Reset the length and overwrite the header. */
+ smb_setlen(buf, out_buf.length + 4);
gss_release_buffer(&minor, &out_buf);
return NT_STATUS_OK;
@@ -440,9 +441,9 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf)
{
/* We know this is an smb buffer, and we
* didn't malloc, only copy, for a keepalive,
- * so ignore session keepalives. */
+ * so ignore non-session messages. */
- if(CVAL(buf,0) == SMBkeepalive) {
+ if(CVAL(buf,0)) {
return;
}
@@ -461,12 +462,12 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli)
NTSTATUS status;
uint16 enc_ctx_num;
- /* Ignore session keepalives. */
- if(CVAL(cli->inbuf,0) == SMBkeepalive) {
+ /* Ignore non-session messages. */
+ if(CVAL(cli->inbuf,0)) {
return NT_STATUS_OK;
}
- status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num);
+ status = get_enc_ctx_num((const uint8_t *)cli->inbuf, &enc_ctx_num);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -484,8 +485,8 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli)
NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out)
{
- /* Ignore session keepalives. */
- if(CVAL(cli->outbuf,0) == SMBkeepalive) {
+ /* Ignore non-session messages. */
+ if(CVAL(cli->outbuf,0)) {
return NT_STATUS_OK;
}
diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c
index d5cbe3b125..f03c21bd0e 100644
--- a/source3/libsmb/smb_signing.c
+++ b/source3/libsmb/smb_signing.c
@@ -745,8 +745,8 @@ bool srv_oplock_set_signing(bool onoff)
bool srv_check_sign_mac(const char *inbuf, bool must_be_ok)
{
- /* Check if it's a session keepalive. */
- if(CVAL(inbuf,0) == SMBkeepalive) {
+ /* Check if it's a non-session message. */
+ if(CVAL(inbuf,0)) {
return True;
}
@@ -759,8 +759,8 @@ bool srv_check_sign_mac(const char *inbuf, bool must_be_ok)
void srv_calculate_sign_mac(char *outbuf)
{
- /* Check if it's a session keepalive. */
- if(CVAL(outbuf,0) == SMBkeepalive) {
+ /* Check if it's a non-session message. */
+ if(CVAL(outbuf,0)) {
return;
}
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 9e37d1d6cf..d7f6f604f7 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -704,16 +704,22 @@ char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in)
void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
const char *pwd,
DATA_BLOB *session_key,
- struct wkssvc_PasswordBuffer *pwd_buf)
+ struct wkssvc_PasswordBuffer **pwd_buf)
{
uint8_t buffer[516];
struct MD5Context ctx;
-
- DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
-
+ struct wkssvc_PasswordBuffer *my_pwd_buf = NULL;
+ DATA_BLOB confounded_session_key;
int confounder_len = 8;
uint8_t confounder[8];
+ my_pwd_buf = talloc_zero(mem_ctx, struct wkssvc_PasswordBuffer);
+ if (!my_pwd_buf) {
+ return;
+ }
+
+ confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
+
encode_pw_buffer(buffer, pwd, STR_UNICODE);
generate_random_buffer((uint8_t *)confounder, confounder_len);
@@ -725,10 +731,12 @@ void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
SamOEMhashBlob(buffer, 516, &confounded_session_key);
- memcpy(&pwd_buf->data[0], confounder, confounder_len);
- memcpy(&pwd_buf->data[8], buffer, 516);
+ memcpy(&my_pwd_buf->data[0], confounder, confounder_len);
+ memcpy(&my_pwd_buf->data[8], buffer, 516);
data_blob_free(&confounded_session_key);
+
+ *pwd_buf = my_pwd_buf;
}
WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index dab21e53b3..270c6d2261 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -608,7 +608,10 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
for (i = 0; i < lck->num_share_modes; i++) {
struct share_mode_entry *entry_p = &lck->share_modes[i];
- char *str = share_mode_str(NULL, i, entry_p);
+ char *str = NULL;
+ if (DEBUGLEVEL >= 10) {
+ str = share_mode_str(NULL, i, entry_p);
+ }
DEBUG(10,("parse_share_modes: %s\n",
str ? str : ""));
if (!process_exists(entry_p->pid)) {
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index 3bb1514203..c1d373aa18 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -1613,6 +1613,8 @@ void retransmit_or_expire_response_records(time_t t)
for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
struct response_record *rrec, *nextrrec;
+ restart:
+
for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
nextrrec = rrec->next;
@@ -1651,6 +1653,9 @@ on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_
no timeout function. */
remove_response_record(subrec, rrec);
}
+ /* We have changed subrec->responselist,
+ * restart from the beginning of this list. */
+ goto restart;
} /* !rrec->in_expitation_processing */
} /* rrec->repeat_count > 0 */
} /* rrec->repeat_time <= t */
diff --git a/source3/nmbd/nmbd_responserecordsdb.c b/source3/nmbd/nmbd_responserecordsdb.c
index 22a038ef2e..6498ce04cf 100644
--- a/source3/nmbd/nmbd_responserecordsdb.c
+++ b/source3/nmbd/nmbd_responserecordsdb.c
@@ -31,26 +31,12 @@ int num_response_packets = 0;
static void add_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct response_record *rrec2;
-
num_response_packets++; /* count of total number of packets still around */
DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
rrec->response_id, subrec->subnet_name, num_response_packets));
- if (!subrec->responselist) {
- subrec->responselist = rrec;
- rrec->prev = NULL;
- rrec->next = NULL;
- return;
- }
-
- for (rrec2 = subrec->responselist; rrec2->next; rrec2 = rrec2->next)
- ;
-
- rrec2->next = rrec;
- rrec->next = NULL;
- rrec->prev = rrec2;
+ DLIST_ADD_END(subrec->responselist, rrec, struct response_record *);
}
/***************************************************************************
@@ -60,13 +46,7 @@ static void add_response_record(struct subnet_record *subrec,
void remove_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
- if (rrec->prev)
- rrec->prev->next = rrec->next;
- if (rrec->next)
- rrec->next->prev = rrec->prev;
-
- if (subrec->responselist == rrec)
- subrec->responselist = rrec->next;
+ DLIST_REMOVE(subrec->responselist, rrec);
if(rrec->userdata) {
if(rrec->userdata->free_fn) {
diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c
index 1548c3344a..7f7c7b8140 100644
--- a/source3/nsswitch/libwbclient/wbc_pam.c
+++ b/source3/nsswitch/libwbclient/wbc_pam.c
@@ -31,7 +31,7 @@
* @return #wbcErr
**/
-wbcErr wbcAuthenticateUser(const char *username,
+wbcErr wbcAuthenticateUser(const char *username,
const char *password)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
@@ -61,5 +61,5 @@ wbcErr wbcAuthenticateUser(const char *username,
BAIL_ON_WBC_ERROR(wbc_status);
done:
- return wbc_status;
+ return wbc_status;
}
diff --git a/source3/nsswitch/libwbclient/wbc_pwd.c b/source3/nsswitch/libwbclient/wbc_pwd.c
index 4e3b0d3967..b24e198bc5 100644
--- a/source3/nsswitch/libwbclient/wbc_pwd.c
+++ b/source3/nsswitch/libwbclient/wbc_pwd.c
@@ -228,13 +228,14 @@ wbcErr wbcGetgrnam(const char *name, struct group **grp)
&response);
BAIL_ON_WBC_ERROR(wbc_status);
- *grp = copy_group_entry(&response.data.gr, response.extra_data.data);
+ *grp = copy_group_entry(&response.data.gr,
+ (char*)response.extra_data.data);
BAIL_ON_PTR_ERROR(*grp, wbc_status);
done:
if (response.extra_data.data)
free(response.extra_data.data);
-
+
return wbc_status;
}
@@ -270,7 +271,8 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
&response);
BAIL_ON_WBC_ERROR(wbc_status);
- *grp = copy_group_entry(&response.data.gr, response.extra_data.data);
+ *grp = copy_group_entry(&response.data.gr,
+ (char*)response.extra_data.data);
BAIL_ON_PTR_ERROR(*grp, wbc_status);
done:
diff --git a/source3/nsswitch/libwbclient/wbc_sid.c b/source3/nsswitch/libwbclient/wbc_sid.c
index c877e1d9d4..abe1457cc1 100644
--- a/source3/nsswitch/libwbclient/wbc_sid.c
+++ b/source3/nsswitch/libwbclient/wbc_sid.c
@@ -265,12 +265,12 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
/* Copy out result */
if (domain != NULL) {
- *domain = strdup(response.data.name.dom_name);
+ *domain = talloc_strdup(NULL, response.data.name.dom_name);
BAIL_ON_PTR_ERROR((*domain), wbc_status);
}
if (name != NULL) {
- *name = strdup(response.data.name.name);
+ *name = talloc_strdup(NULL, response.data.name.name);
BAIL_ON_PTR_ERROR((*name), wbc_status);
}
@@ -283,9 +283,9 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
done:
if (!WBC_ERROR_IS_OK(wbc_status)) {
if (*domain)
- free(*domain);
+ talloc_free(*domain);
if (*name)
- free(*name);
+ talloc_free(*name);
}
return wbc_status;
@@ -334,11 +334,9 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
ridbuf_size = (sizeof(char)*11) * num_rids + 1;
- ridlist = malloc(ridbuf_size);
+ ridlist = talloc_zero_array(NULL, char, ridbuf_size);
BAIL_ON_PTR_ERROR(ridlist, wbc_status);
- memset(ridlist, 0x0, ridbuf_size);
-
len = 0;
for (i=0; i<num_rids && (len-1)>0; i++) {
char ridstr[12];
@@ -356,15 +354,15 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
wbc_status = wbcRequestResponse(WINBINDD_LOOKUPRIDS,
&request,
&response);
- free(ridlist);
+ talloc_free(ridlist);
- domain_name = strdup(response.data.domain_name);
+ domain_name = talloc_strdup(NULL, response.data.domain_name);
BAIL_ON_PTR_ERROR(domain_name, wbc_status);
- *names = (const char**)malloc(sizeof(char*) * num_rids);
+ *names = talloc_array(NULL, const char*, num_rids);
BAIL_ON_PTR_ERROR((*names), wbc_status);
- *types = (enum wbcSidType*)malloc(sizeof(enum wbcSidType) * num_rids);
+ *types = talloc_array(NULL, enum wbcSidType, num_rids);
BAIL_ON_PTR_ERROR((*types), wbc_status);
p = (char *)response.extra_data.data;
@@ -393,7 +391,8 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
*q = '\0';
- (*names)[i] = strdup(p);
+ (*names)[i] = talloc_strdup((*names), p);
+ BAIL_ON_PTR_ERROR(((*names)[i]), wbc_status);
p = q+1;
}
@@ -403,18 +402,20 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
BAIL_ON_WBC_ERROR(wbc_status);
}
- free(response.extra_data.data);
-
wbc_status = WBC_ERR_SUCCESS;
done:
+ if (response.extra_data.data) {
+ free(response.extra_data.data);
+ }
+
if (!WBC_ERROR_IS_OK(wbc_status)) {
if (domain_name)
- free(domain_name);
+ talloc_free(domain_name);
if (*names)
- free(*names);
+ talloc_free(*names);
if (*types)
- free(*types);
+ talloc_free(*types);
} else {
*pp_domain_name = domain_name;
}
diff --git a/source3/nsswitch/libwbclient/wbc_util.c b/source3/nsswitch/libwbclient/wbc_util.c
index c6acb27e55..ff3cec8689 100644
--- a/source3/nsswitch/libwbclient/wbc_util.c
+++ b/source3/nsswitch/libwbclient/wbc_util.c
@@ -51,10 +51,6 @@ wbcErr wbcPing(void)
*
* @return #wbcErr
*
- * The char* members of the struct wbcDomainInfo* are malloc()'d
- * and it the the responsibility of the caller to free the members
- * before discarding the struct.
- *
**/
@@ -64,7 +60,7 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
struct winbindd_response response;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainInfo *info = NULL;
-
+
if (!domain || !dinfo) {
wbc_status = WBC_ERR_INVALID_PARAM;
BAIL_ON_WBC_ERROR(wbc_status);
@@ -75,7 +71,7 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- strncpy(request.domain_name, domain,
+ strncpy(request.domain_name, domain,
sizeof(request.domain_name)-1);
wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO,
@@ -86,15 +82,15 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
info = talloc(NULL, struct wbcDomainInfo);
BAIL_ON_PTR_ERROR(info, wbc_status);
- info->short_name = talloc_strdup(info,
+ info->short_name = talloc_strdup(info,
response.data.domain_info.name);
BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
- info->dns_name = talloc_strdup(info,
+ info->dns_name = talloc_strdup(info,
response.data.domain_info.alt_name);
BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
- wbc_status = wbcStringToSid(response.data.domain_info.sid,
+ wbc_status = wbcStringToSid(response.data.domain_info.sid,
&info->sid);
BAIL_ON_WBC_ERROR(wbc_status);
@@ -106,7 +102,7 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
info->flags |= WBC_DOMINFO_PRIMARY;
*dinfo = info;
-
+
wbc_status = WBC_ERR_SUCCESS;
done:
diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h
index 2867aad69e..6b85d7e8b3 100644
--- a/source3/nsswitch/libwbclient/wbclient.h
+++ b/source3/nsswitch/libwbclient/wbclient.h
@@ -177,7 +177,7 @@ wbcErr wbcDomainSequenceNumbers(void);
* Athenticate functions
*/
-wbcErr wbcAuthenticateUser(const char *username,
+wbcErr wbcAuthenticateUser(const char *username,
const char *password);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 16e9372009..29166cf02e 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -6213,7 +6213,7 @@ uint32 lp_get_spoolss_state( void )
}
/*******************************************************************
- Ensure we don't use sendfile if server smb signing or selaing is active.
+ Ensure we don't use sendfile if server smb signing is active.
********************************************************************/
bool lp_use_sendfile(int snum)
@@ -6224,8 +6224,7 @@ bool lp_use_sendfile(int snum)
}
return (_lp_use_sendfile(snum) &&
(get_remote_arch() != RA_WIN95) &&
- !srv_is_signing_active() &&
- !srv_encryption_on());
+ !srv_is_signing_active());
}
/*******************************************************************
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index b638219466..205b178a93 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -1768,6 +1768,10 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
SAFE_FREE(ld_error);
ber_bvfree(bv);
+#if defined(LDAP_CONSTRAINT_VIOLATION)
+ if (rc == LDAP_CONSTRAINT_VIOLATION)
+ return NT_STATUS_PASSWORD_RESTRICTION;
+#endif
return NT_STATUS_UNSUCCESSFUL;
} else {
DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index f115fba91f..bae32e89f7 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1867,7 +1867,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
goto err_exit;
}
- create_directory(conn, new_dir);
+ create_directory(conn, NULL, new_dir);
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
* listed for this driver which has already been moved, skip it (note:
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index bc4508ff94..bb410e646b 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -729,7 +729,7 @@ WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
}
/* recurse through subkeys first */
- werr = reg_openkey(mem_ctx, parent, path, REG_KEY_WRITE, &key);
+ werr = reg_openkey(mem_ctx, parent, path, REG_KEY_ALL, &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
diff --git a/source3/registry/reg_cachehook.c b/source3/registry/reg_cachehook.c
index 289d4e50ce..74670aac30 100644
--- a/source3/registry/reg_cachehook.c
+++ b/source3/registry/reg_cachehook.c
@@ -25,19 +25,21 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
-static SORTED_TREE *cache_tree;
+static SORTED_TREE *cache_tree = NULL;
extern REGISTRY_OPS regdb_ops; /* these are the default */
static REGISTRY_HOOK default_hook = { KEY_TREE_ROOT, &regdb_ops };
/**********************************************************************
- Initialize the cache tree
+ Initialize the cache tree if it has not been initialized yet.
*********************************************************************/
bool reghook_cache_init( void )
{
- cache_tree = pathtree_init( &default_hook, NULL );
+ if (cache_tree == NULL) {
+ cache_tree = pathtree_init(&default_hook, NULL);
+ }
- return ( cache_tree == NULL );
+ return (cache_tree != NULL);
}
/**********************************************************************
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c
index 25c6557c87..f50a41816c 100644
--- a/source3/registry/reg_db.c
+++ b/source3/registry/reg_db.c
@@ -259,7 +259,7 @@ bool regdb_init( void )
uint32 vers_id;
if ( tdb_reg )
- return True;
+ return true;
if ( !(tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600)) )
{
@@ -267,7 +267,7 @@ bool regdb_init( void )
if ( !tdb_reg ) {
DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n",
state_path("registry.tdb"), strerror(errno) ));
- return False;
+ return false;
}
DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
@@ -286,11 +286,11 @@ bool regdb_init( void )
/* always setup the necessary keys and values */
if ( !init_registry_data() ) {
- DEBUG(0,("init_registry: Failed to initialize data in registry!\n"));
- return False;
+ DEBUG(0,("regdb_init: Failed to initialize data in registry!\n"));
+ return false;
}
- return True;
+ return true;
}
/***********************************************************************
@@ -329,6 +329,10 @@ WERROR regdb_open( void )
int regdb_close( void )
{
+ if (tdb_refcount == 0) {
+ return 0;
+ }
+
tdb_refcount--;
DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount));
@@ -364,7 +368,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
uint8 *buffer = NULL;
int i = 0;
uint32 len, buflen;
- bool ret = True;
+ bool ret = true;
uint32 num_subkeys = regsubkey_ctr_numkeys(ctr);
char *keyname = NULL;
TALLOC_CTX *ctx = talloc_tos();
@@ -382,7 +386,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
/* allocate some initial memory */
if (!(buffer = (uint8 *)SMB_MALLOC(1024))) {
- return False;
+ return false;
}
buflen = 1024;
len = 0;
@@ -399,7 +403,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
/* allocate some extra space */
if ((buffer = (uint8 *)SMB_REALLOC( buffer, len*2 )) == NULL) {
DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2));
- ret = False;
+ ret = false;
goto done;
}
buflen = len*2;
@@ -413,7 +417,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
dbuf.dptr = buffer;
dbuf.dsize = len;
if ( tdb_store_bystring( tdb_reg->tdb, keyname, dbuf, TDB_REPLACE ) == -1) {
- ret = False;
+ ret = false;
goto done;
}
@@ -801,7 +805,7 @@ bool regdb_store_values( const char *key, REGVAL_CTR *values )
&& (memcmp(old_data.dptr, data.dptr, data.dsize) == 0)) {
SAFE_FREE(old_data.dptr);
SAFE_FREE(data.dptr);
- return True;
+ return true;
}
ret = tdb_trans_store_bystring(tdb_reg->tdb, keystr, data, TDB_REPLACE);
diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh
index fdade5a617..8bf9cd1ec4 100755
--- a/source3/script/tests/test_smbclient_s3.sh
+++ b/source3/script/tests/test_smbclient_s3.sh
@@ -2,7 +2,7 @@
# this runs the file serving tests that are expected to pass with samba3
-if [ $# != 2 ]; then
+if [ $# -lt 2 ]; then
cat <<EOF
Usage: test_smbclient_s3.sh SERVER SERVER_IP
EOF
@@ -12,6 +12,8 @@ fi
SERVER="$1"
SERVER_IP="$2"
SMBCLIENT="$VALGRIND ${SMBCLIENT:-$BINDIR/smbclient} $CONFIGURATION"
+shift 3
+ADDARGS="$*"
incdir=`dirname $0`
. $incdir/test_functions.sh
@@ -24,7 +26,7 @@ test_noninteractive_no_prompt()
prompt="smb"
echo du | \
- $SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I SERVER_IP 2>&1 | \
+ $SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I SERVER_IP $ADDARGS 2>&1 | \
grep $prompt
if [ $? = 0 ] ; then
@@ -49,7 +51,7 @@ EOF
CLI_FORCE_INTERACTIVE=yes \
$SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I $SERVER_IP \
- < $tmpfile 2>/dev/null | \
+ $ADDARGS < $tmpfile 2>/dev/null | \
grep $prompt
if [ $? = 0 ] ; then
diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh
index f662eacd3e..acb641b9fb 100755
--- a/source3/script/tests/test_smbtorture_s3.sh
+++ b/source3/script/tests/test_smbtorture_s3.sh
@@ -42,7 +42,7 @@ for t in $tests; do
fi
start=""
name="$t"
- testit "$name" $VALGRIND $BINDIR/smbtorture $ADDARGS $unc -U"$username"%"$password" $t || failed=`expr $failed + 1`
+ testit "$name" $VALGRIND $BINDIR/smbtorture $unc -U"$username"%"$password" $ADDARGS $t || failed=`expr $failed + 1`
done
testok $0 $failed
diff --git a/source3/script/tests/tests_all.sh b/source3/script/tests/tests_all.sh
index 109e9c2920..c9fd748296 100755
--- a/source3/script/tests/tests_all.sh
+++ b/source3/script/tests/tests_all.sh
@@ -1,7 +1,11 @@
$SCRIPTDIR/test_local_s3.sh || failed=`expr $failed + $?`
$SCRIPTDIR/test_smbtorture_s3.sh //$SERVER_IP/tmp $USERNAME $PASSWORD "" || failed=`expr $failed + $?`
+echo testing encrypted
+$SCRIPTDIR/test_smbtorture_s3.sh //$SERVER_IP/tmp $USERNAME $PASSWORD "" -e || failed=`expr $failed + $?`
$SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP || failed=`expr $failed + $?`
+echo testing encrypted
+$SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP -e || failed=`expr $failed + $?`
$SCRIPTDIR/test_wbinfo_s3.sh $WORKGROUP $SERVER $USERNAME $PASSWORD || failed=`expr $failed + $?`
LD_LIBRARY_PATH="$SAMBA4SHAREDDIR:$LD_LIBRARY_PATH"
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index a439c3a4f0..bc1761b0fd 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -236,7 +236,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
}
construct_reply_common((char *)req->inbuf, aio_ex->outbuf);
- srv_set_message((const char *)req->inbuf, aio_ex->outbuf, 12, 0, True);
+ srv_set_message(aio_ex->outbuf, 12, 0, True);
SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */
a = &aio_ex->acb;
@@ -356,8 +356,9 @@ bool schedule_aio_write_and_X(connection_struct *conn,
SSVAL(aio_ex->outbuf,smb_vwv2,numtowrite);
SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1);
show_msg(aio_ex->outbuf);
- if (!send_smb(smbd_server_fd(),aio_ex->outbuf)) {
- exit_server_cleanly("handle_aio_write: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),aio_ex->outbuf,
+ IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("handle_aio_write: srv_send_smb "
"failed.");
}
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
@@ -387,7 +388,6 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
int ret = 0;
int outsize;
char *outbuf = aio_ex->outbuf;
- const char *inbuf = aio_ex->inbuf;
char *data = smb_buf(outbuf);
ssize_t nread = SMB_VFS_AIO_RETURN(aio_ex->fsp,&aio_ex->acb);
@@ -410,9 +410,9 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
ret = errno;
ERROR_NT(map_nt_error_from_unix(ret));
- outsize = srv_set_message(inbuf,outbuf,0,0,true);
+ outsize = srv_set_message(outbuf,0,0,true);
} else {
- outsize = srv_set_message(inbuf, outbuf,12,nread,False);
+ outsize = srv_set_message(outbuf,12,nread,False);
SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be * -1. */
SSVAL(outbuf,smb_vwv5,nread);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
@@ -425,10 +425,11 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
(int)aio_ex->acb.aio_nbytes, (int)nread ) );
}
- _smb_setlen(outbuf,outsize - 4);
+ smb_setlen(outbuf,outsize - 4);
show_msg(outbuf);
- if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server_cleanly("handle_aio_read_complete: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),outbuf,
+ IS_CONN_ENCRYPTED(aio_ex->fsp->conn))) {
+ exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
"failed.");
}
@@ -497,7 +498,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
ret = errno;
ERROR_BOTH(map_nt_error_from_unix(ret), ERRHRD, ERRdiskfull);
- srv_set_message(inbuf,outbuf,0,0,true);
+ srv_set_message(outbuf,0,0,true);
} else {
bool write_through = BITSETW(aio_ex->inbuf+smb_vwv7,0);
NTSTATUS status;
@@ -516,15 +517,15 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
ret = errno;
ERROR_BOTH(map_nt_error_from_unix(ret),
ERRHRD, ERRdiskfull);
- srv_set_message(inbuf,outbuf,0,0,true);
+ srv_set_message(outbuf,0,0,true);
DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
fsp->fsp_name, nt_errstr(status) ));
}
}
show_msg(outbuf);
- if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server_cleanly("handle_aio_write: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("handle_aio_write: srv_send_smb failed.");
}
DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed "
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 0078bb7d13..41963166f7 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -41,6 +41,7 @@ typedef struct _blocking_lock_record {
enum brl_type lock_type;
char *inbuf;
int length;
+ bool encrypted;
} blocking_lock_record;
/* dlink list we store pending lock records on. */
@@ -149,7 +150,7 @@ static bool recalc_brl_timeout(void)
****************************************************************************/
bool push_blocking_lock_request( struct byte_range_lock *br_lck,
- const char *inbuf, int length,
+ const struct smb_request *req,
files_struct *fsp,
int lock_timeout,
int lock_num,
@@ -161,6 +162,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
uint32 blocking_pid)
{
static bool set_lock_msg;
+ size_t length = smb_len(req->inbuf)+4;
blocking_lock_record *blr;
NTSTATUS status;
@@ -188,7 +190,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
return False;
}
- blr->com_type = CVAL(inbuf,smb_com);
+ blr->com_type = CVAL(req->inbuf,smb_com);
blr->fsp = fsp;
if (lock_timeout == -1) {
blr->expire_time.tv_sec = 0;
@@ -204,8 +206,9 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blr->lock_type = lock_type;
blr->offset = offset;
blr->count = count;
- memcpy(blr->inbuf, inbuf, length);
+ memcpy(blr->inbuf, req->inbuf, length);
blr->length = length;
+ blr->encrypted = req->encrypted;
/* Add a pending lock record for this. */
status = brl_lock(smbd_messaging_context(), br_lck,
@@ -242,7 +245,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blr->fsp->fnum, blr->fsp->fsp_name ));
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(inbuf,smb_mid));
+ srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
return True;
}
@@ -259,7 +262,7 @@ static void reply_lockingX_success(blocking_lock_record *blr)
smb_panic("Could not allocate smb_request");
}
- init_smb_request(req, (uint8 *)blr->inbuf, 0);
+ init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
reply_outbuf(req, 2, 0);
/*
@@ -272,8 +275,10 @@ static void reply_lockingX_success(blocking_lock_record *blr)
chain_reply(req);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) {
- exit_server_cleanly("send_blocking_reply: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(blr->fsp->conn))) {
+ exit_server_cleanly("send_blocking_reply: srv_send_smb failed.");
}
}
@@ -298,19 +303,21 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat
/* Store the last lock error. */
files_struct *fsp = blr->fsp;
- fsp->last_lock_failure.context.smbpid = blr->lock_pid;
- fsp->last_lock_failure.context.tid = fsp->conn->cnum;
- fsp->last_lock_failure.context.pid = procid_self();
- fsp->last_lock_failure.start = blr->offset;
- fsp->last_lock_failure.size = blr->count;
- fsp->last_lock_failure.fnum = fsp->fnum;
- fsp->last_lock_failure.lock_type = READ_LOCK; /* Don't care. */
- fsp->last_lock_failure.lock_flav = blr->lock_flav;
+ if (fsp) {
+ fsp->last_lock_failure.context.smbpid = blr->lock_pid;
+ fsp->last_lock_failure.context.tid = fsp->conn->cnum;
+ fsp->last_lock_failure.context.pid = procid_self();
+ fsp->last_lock_failure.start = blr->offset;
+ fsp->last_lock_failure.size = blr->count;
+ fsp->last_lock_failure.fnum = fsp->fnum;
+ fsp->last_lock_failure.lock_type = READ_LOCK; /* Don't care. */
+ fsp->last_lock_failure.lock_flav = blr->lock_flav;
+ }
}
ERROR_NT(status);
- if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server_cleanly("generic_blocking_lock_error: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),outbuf, blr->encrypted)) {
+ exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
}
}
@@ -388,8 +395,10 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status
*/
SCVAL(outbuf,smb_com,SMBtrans2);
ERROR_NT(status);
- if (!send_smb(smbd_server_fd(),outbuf)) {
- exit_server_cleanly("blocking_lock_reply_error: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ outbuf,
+ IS_CONN_ENCRYPTED(blr->fsp->conn))) {
+ exit_server_cleanly("blocking_lock_reply_error: srv_send_smb failed.");
}
break;
}
@@ -531,12 +540,12 @@ static bool process_trans2(blocking_lock_record *blr)
return True;
}
- init_smb_request(req, (uint8 *)blr->inbuf, 0);
+ init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
SCVAL(req->inbuf, smb_com, SMBtrans2);
SSVAL(params,0,0);
/* Fake up max_data_bytes here - we know it fits. */
- send_trans2_replies(req, params, 2, NULL, 0, 0xffff);
+ send_trans2_replies(blr->fsp->conn, req, params, 2, NULL, 0, 0xffff);
return True;
}
@@ -597,6 +606,9 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
locktype,
NT_STATUS_RANGE_NOT_LOCKED);
}
+ /* We're closing the file fsp here, so ensure
+ * we don't have a dangling pointer. */
+ blr->fsp = NULL;
}
}
}
diff --git a/source3/smbd/error.c b/source3/smbd/error.c
index c669e74146..de2de088ec 100644
--- a/source3/smbd/error.c
+++ b/source3/smbd/error.c
@@ -81,9 +81,9 @@ void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatu
}
}
-int error_packet(const char *inbuf, char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
+int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
{
- int outsize = srv_set_message(inbuf, outbuf,0,0,True);
+ int outsize = srv_set_message(outbuf,0,0,True);
error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
return outsize;
}
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index f28016ccb3..68a13d692f 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -30,7 +30,7 @@ extern int max_send;
#define NERR_notsupported 50
-static void api_no_reply(struct smb_request *req);
+static void api_no_reply(connection_struct *conn, struct smb_request *req);
/*******************************************************************
copies parameters and data, as needed, into the smb buffer
@@ -81,7 +81,8 @@ static void copy_trans_params_and_data(char *outbuf, int align,
Send a trans reply.
****************************************************************************/
-void send_trans_reply(struct smb_request *req,
+void send_trans_reply(connection_struct *conn,
+ struct smb_request *req,
char *rparam, int rparam_len,
char *rdata, int rdata_len,
bool buffer_too_large)
@@ -129,8 +130,10 @@ void send_trans_reply(struct smb_request *req,
}
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
- exit_server_cleanly("send_trans_reply: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
TALLOC_FREE(req->outbuf);
@@ -175,8 +178,10 @@ void send_trans_reply(struct smb_request *req,
}
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(), (char *)req->outbuf))
- exit_server_cleanly("send_trans_reply: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
tot_data_sent += this_ldata;
tot_param_sent += this_lparam;
@@ -188,7 +193,7 @@ void send_trans_reply(struct smb_request *req,
Start the first part of an RPC reply which began with an SMBtrans request.
****************************************************************************/
-static void api_rpc_trans_reply(struct smb_request *req, smb_np_struct *p)
+static void api_rpc_trans_reply(connection_struct *conn, struct smb_request *req, smb_np_struct *p)
{
bool is_data_outstanding;
char *rdata = (char *)SMB_MALLOC(p->max_trans_reply);
@@ -203,11 +208,11 @@ static void api_rpc_trans_reply(struct smb_request *req, smb_np_struct *p)
if((data_len = read_from_pipe( p, rdata, p->max_trans_reply,
&is_data_outstanding)) < 0) {
SAFE_FREE(rdata);
- api_no_reply(req);
+ api_no_reply(conn,req);
return;
}
- send_trans_reply(req, NULL, 0, rdata, data_len, is_data_outstanding);
+ send_trans_reply(conn, req, NULL, 0, rdata, data_len, is_data_outstanding);
SAFE_FREE(rdata);
return;
}
@@ -216,7 +221,7 @@ static void api_rpc_trans_reply(struct smb_request *req, smb_np_struct *p)
WaitNamedPipeHandleState
****************************************************************************/
-static void api_WNPHS(struct smb_request *req, smb_np_struct *p,
+static void api_WNPHS(connection_struct *conn, struct smb_request *req, smb_np_struct *p,
char *param, int param_len)
{
uint16 priority;
@@ -231,10 +236,10 @@ static void api_WNPHS(struct smb_request *req, smb_np_struct *p,
if (wait_rpc_pipe_hnd_state(p, priority)) {
/* now send the reply */
- send_trans_reply(req, NULL, 0, NULL, 0, False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
return;
}
- api_no_reply(req);
+ api_no_reply(conn,req);
}
@@ -242,7 +247,7 @@ static void api_WNPHS(struct smb_request *req, smb_np_struct *p,
SetNamedPipeHandleState
****************************************************************************/
-static void api_SNPHS(struct smb_request *req, smb_np_struct *p,
+static void api_SNPHS(connection_struct *conn, struct smb_request *req, smb_np_struct *p,
char *param, int param_len)
{
uint16 id;
@@ -257,10 +262,10 @@ static void api_SNPHS(struct smb_request *req, smb_np_struct *p,
if (set_rpc_pipe_hnd_state(p, id)) {
/* now send the reply */
- send_trans_reply(req, NULL, 0, NULL, 0, False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
return;
}
- api_no_reply(req);
+ api_no_reply(conn,req);
}
@@ -268,7 +273,7 @@ static void api_SNPHS(struct smb_request *req, smb_np_struct *p,
When no reply is generated, indicate unsupported.
****************************************************************************/
-static void api_no_reply(struct smb_request *req)
+static void api_no_reply(connection_struct *conn, struct smb_request *req)
{
char rparam[4];
@@ -279,7 +284,7 @@ static void api_no_reply(struct smb_request *req)
DEBUG(3,("Unsupported API fd command\n"));
/* now send the reply */
- send_trans_reply(req, rparam, 4, NULL, 0, False);
+ send_trans_reply(conn, req, rparam, 4, NULL, 0, False);
return;
}
@@ -321,7 +326,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
/* Win9x does this call with a unicode pipe name, not a pnum. */
/* Just return success for now... */
DEBUG(3,("Got TRANSACT_WAITNAMEDPIPEHANDLESTATE on text pipe name\n"));
- send_trans_reply(req, NULL, 0, NULL, 0, False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
return;
}
@@ -349,18 +354,18 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
/* dce/rpc command */
reply = write_to_pipe(p, data, tdscnt);
if (!reply) {
- api_no_reply(req);
+ api_no_reply(conn, req);
return;
}
- api_rpc_trans_reply(req, p);
+ api_rpc_trans_reply(conn, req, p);
break;
case TRANSACT_WAITNAMEDPIPEHANDLESTATE:
/* Wait Named Pipe Handle state */
- api_WNPHS(req, p, params, tpscnt);
+ api_WNPHS(conn, req, p, params, tpscnt);
break;
case TRANSACT_SETNAMEDPIPEHANDLESTATE:
/* Set Named Pipe Handle state */
- api_SNPHS(req, p, params, tpscnt);
+ api_SNPHS(conn, req, p, params, tpscnt);
break;
default:
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -472,8 +477,10 @@ static void handle_trans(connection_struct *conn, struct smb_request *req,
state->max_data_return,
state->max_param_return);
- if (state->close_on_completion)
+ if (state->close_on_completion) {
close_cnum(conn,state->vuid);
+ req->conn = NULL;
+ }
return;
}
@@ -482,8 +489,9 @@ static void handle_trans(connection_struct *conn, struct smb_request *req,
Reply to a SMBtrans.
****************************************************************************/
-void reply_trans(connection_struct *conn, struct smb_request *req)
+void reply_trans(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
unsigned int dsoff;
unsigned int dscnt;
unsigned int psoff;
@@ -662,8 +670,9 @@ void reply_trans(connection_struct *conn, struct smb_request *req)
Reply to a secondary SMBtrans.
****************************************************************************/
-void reply_transs(connection_struct *conn, struct smb_request *req)
+void reply_transs(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
int size;
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 3ab216c062..5a6df1f139 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -4605,7 +4605,7 @@ void api_reply(connection_struct *conn, uint16 vuid,
/* If api_Unsupported returns false we can't return anything. */
if (reply) {
- send_trans_reply(req, rparam, rparam_len,
+ send_trans_reply(conn, req, rparam, rparam_len,
rdata, rdata_len, False);
}
diff --git a/source3/smbd/message.c b/source3/smbd/message.c
index d0b524da0e..a870f03df9 100644
--- a/source3/smbd/message.c
+++ b/source3/smbd/message.c
@@ -137,7 +137,7 @@ static void msg_deliver(struct msg_state *state)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_sends(connection_struct *conn, struct smb_request *req)
+void reply_sends(struct smb_request *req)
{
struct msg_state *state;
int len;
@@ -190,7 +190,7 @@ void reply_sends(connection_struct *conn, struct smb_request *req)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_sendstrt(connection_struct *conn, struct smb_request *req)
+void reply_sendstrt(struct smb_request *req)
{
char *p;
@@ -234,7 +234,7 @@ void reply_sendstrt(connection_struct *conn, struct smb_request *req)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_sendtxt(connection_struct *conn, struct smb_request *req)
+void reply_sendtxt(struct smb_request *req)
{
int len;
char *msg;
@@ -287,7 +287,7 @@ void reply_sendtxt(connection_struct *conn, struct smb_request *req)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_sendend(connection_struct *conn, struct smb_request *req)
+void reply_sendend(struct smb_request *req)
{
START_PROFILE(SMBsendend);
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 02f752fd67..9f56949eeb 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -505,7 +505,7 @@ static const struct {
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_negprot(connection_struct *conn, struct smb_request *req)
+void reply_negprot(struct smb_request *req)
{
size_t size = smb_len(req->inbuf) + 4;
int choice= -1;
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index baab48f77e..7287210802 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -128,10 +128,10 @@ static bool notify_marshall_changes(int num_changes,
Setup the common parts of the return packet and send it.
*****************************************************************************/
-static void change_notify_reply_packet(const uint8 *request_buf,
+static void change_notify_reply_packet(connection_struct *conn,
+ const uint8 *request_buf,
NTSTATUS error_code)
{
- const char *inbuf = (const char *)request_buf;
char outbuf[smb_size+38];
memset(outbuf, '\0', sizeof(outbuf));
@@ -143,15 +143,18 @@ static void change_notify_reply_packet(const uint8 *request_buf,
* Seems NT needs a transact command with an error code
* in it. This is a longer packet than a simple error.
*/
- srv_set_message((const char *)request_buf, outbuf,18,0,False);
+ srv_set_message(outbuf,18,0,False);
show_msg(outbuf);
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server_cleanly("change_notify_reply_packet: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),
+ outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("change_notify_reply_packet: srv_send_smb "
"failed.");
}
-void change_notify_reply(const uint8 *request_buf, uint32 max_param,
+void change_notify_reply(connection_struct *conn,
+ const uint8 *request_buf, uint32 max_param,
struct notify_change_buf *notify_buf)
{
prs_struct ps;
@@ -159,7 +162,7 @@ void change_notify_reply(const uint8 *request_buf, uint32 max_param,
uint8 tmp_request[smb_size];
if (notify_buf->num_changes == -1) {
- change_notify_reply_packet(request_buf, NT_STATUS_OK);
+ change_notify_reply_packet(conn, request_buf, NT_STATUS_OK);
notify_buf->num_changes = 0;
return;
}
@@ -172,12 +175,12 @@ void change_notify_reply(const uint8 *request_buf, uint32 max_param,
* We exceed what the client is willing to accept. Send
* nothing.
*/
- change_notify_reply_packet(request_buf, NT_STATUS_OK);
+ change_notify_reply_packet(conn, request_buf, NT_STATUS_OK);
goto done;
}
if (!(req = talloc(talloc_tos(), struct smb_request))) {
- change_notify_reply_packet(request_buf, NT_STATUS_NO_MEMORY);
+ change_notify_reply_packet(conn, request_buf, NT_STATUS_NO_MEMORY);
goto done;
}
@@ -190,9 +193,9 @@ void change_notify_reply(const uint8 *request_buf, uint32 max_param,
smb_setlen((char *)tmp_request, smb_size);
SCVAL(tmp_request, smb_wct, 0);
- init_smb_request(req, tmp_request,0);
+ init_smb_request(req, tmp_request,0, conn->encrypted_tid);
- send_nt_replies(req, NT_STATUS_OK, prs_data_p(&ps),
+ send_nt_replies(conn, req, NT_STATUS_OK, prs_data_p(&ps),
prs_offset(&ps), NULL, 0);
done:
@@ -243,9 +246,10 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
return status;
}
-NTSTATUS change_notify_add_request(const uint8 *inbuf, uint32 max_param,
- uint32 filter, bool recursive,
- struct files_struct *fsp)
+NTSTATUS change_notify_add_request(const struct smb_request *req,
+ uint32 max_param,
+ uint32 filter, bool recursive,
+ struct files_struct *fsp)
{
struct notify_change_request *request = NULL;
struct notify_mid_map *map = NULL;
@@ -259,7 +263,7 @@ NTSTATUS change_notify_add_request(const uint8 *inbuf, uint32 max_param,
request->mid_map = map;
map->req = request;
- memcpy(request->request_buf, inbuf, sizeof(request->request_buf));
+ memcpy(request->request_buf, req->inbuf, sizeof(request->request_buf));
request->max_param = max_param;
request->filter = filter;
request->fsp = fsp;
@@ -268,11 +272,11 @@ NTSTATUS change_notify_add_request(const uint8 *inbuf, uint32 max_param,
DLIST_ADD_END(fsp->notify->requests, request,
struct notify_change_request *);
- map->mid = SVAL(inbuf, smb_mid);
+ map->mid = SVAL(req->inbuf, smb_mid);
DLIST_ADD(notify_changes_by_mid, map);
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(inbuf,smb_mid));
+ srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
return NT_STATUS_OK;
}
@@ -325,7 +329,8 @@ void remove_pending_change_notify_requests_by_mid(uint16 mid)
return;
}
- change_notify_reply_packet(map->req->request_buf, NT_STATUS_CANCELLED);
+ change_notify_reply_packet(map->req->fsp->conn,
+ map->req->request_buf, NT_STATUS_CANCELLED);
change_notify_remove_request(map->req);
}
@@ -341,7 +346,7 @@ void remove_pending_change_notify_requests_by_fid(files_struct *fsp,
}
while (fsp->notify->requests != NULL) {
- change_notify_reply_packet(
+ change_notify_reply_packet(fsp->conn,
fsp->notify->requests->request_buf, status);
change_notify_remove_request(fsp->notify->requests);
}
@@ -435,7 +440,8 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name)
* TODO: do we have to walk the lists of requests pending?
*/
- change_notify_reply(fsp->notify->requests->request_buf,
+ change_notify_reply(fsp->conn,
+ fsp->notify->requests->request_buf,
fsp->notify->requests->max_param,
fsp->notify);
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 69772b6bec..a51f3afd82 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -66,7 +66,8 @@ static char *nttrans_realloc(char **ptr, size_t size)
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
+void send_nt_replies(connection_struct *conn,
+ struct smb_request *req, NTSTATUS nt_error,
char *params, int paramsize,
char *pdata, int datasize)
{
@@ -242,8 +243,10 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
/* Send the packet */
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) {
- exit_server_cleanly("send_nt_replies: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn))) {
+ exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
}
TALLOC_FREE(req->outbuf);
@@ -410,8 +413,9 @@ static void do_ntcreate_pipe_open(connection_struct *conn,
Reply to an NT create and X call.
****************************************************************************/
-void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req)
+void reply_ntcreate_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
uint32 flags;
uint32 access_mask;
@@ -726,7 +730,7 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
return;
}
@@ -1080,7 +1084,7 @@ static void call_nt_transact_create(connection_struct *conn,
DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
return;
}
@@ -1090,7 +1094,7 @@ static void call_nt_transact_create(connection_struct *conn,
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_ntcancel(connection_struct *conn, struct smb_request *req)
+void reply_ntcancel(struct smb_request *req)
{
/*
* Go through and cancel any pending change notifies.
@@ -1252,8 +1256,9 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
Reply to a NT rename request.
****************************************************************************/
-void reply_ntrename(connection_struct *conn, struct smb_request *req)
+void reply_ntrename(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *oldname = NULL;
char *newname = NULL;
char *p;
@@ -1474,7 +1479,7 @@ static void call_nt_transact_notify_change(connection_struct *conn,
* here.
*/
- change_notify_reply(req->inbuf, max_param_count, fsp->notify);
+ change_notify_reply(fsp->conn, req->inbuf, max_param_count, fsp->notify);
/*
* change_notify_reply() above has independently sent its
@@ -1487,7 +1492,9 @@ static void call_nt_transact_notify_change(connection_struct *conn,
* No changes pending, queue the request
*/
- status = change_notify_add_request(req->inbuf, max_param_count, filter,
+ status = change_notify_add_request(req,
+ max_param_count,
+ filter,
recursive, fsp);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -1554,7 +1561,7 @@ static void call_nt_transact_rename(connection_struct *conn,
/*
* Rename was successful.
*/
- send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
fsp->fsp_name, new_name));
@@ -1657,7 +1664,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
SIVAL(params,0,(uint32)sd_size);
if (max_data_count < sd_size) {
- send_nt_replies(req, NT_STATUS_BUFFER_TOO_SMALL,
+ send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
params, 4, *ppdata, 0);
TALLOC_FREE(frame);
return;
@@ -1686,7 +1693,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
SMB_ASSERT(sd_size == blob.length);
memcpy(data, blob.data, sd_size);
- send_nt_replies(req, NT_STATUS_OK, params, 4, data, (int)sd_size);
+ send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
TALLOC_FREE(frame);
return;
@@ -1744,7 +1751,7 @@ static void call_nt_transact_set_security_desc(connection_struct *conn,
}
done:
- send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
}
@@ -1793,7 +1800,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
so we can know if we need to pre-allocate or not */
DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
- send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
case FSCTL_CREATE_OR_GET_OBJECT_ID:
@@ -1819,7 +1826,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
push_file_id_16(pdata, &fsp->file_id);
memcpy(pdata+16,create_volume_objectid(conn,objid),16);
push_file_id_16(pdata+32, &fsp->file_id);
- send_nt_replies(req, NT_STATUS_OK, NULL, 0,
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
pdata, data_count);
return;
}
@@ -1964,7 +1971,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
talloc_destroy(shadow_data->mem_ctx);
- send_nt_replies(req, NT_STATUS_OK, NULL, 0,
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
pdata, data_count);
return;
@@ -2020,7 +2027,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
*/
/* this works for now... */
- send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+ send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
}
default:
@@ -2306,7 +2313,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
break;
}
- send_nt_replies(req, nt_status, params, param_len,
+ send_nt_replies(conn, req, nt_status, params, param_len,
pdata, data_len);
}
@@ -2436,7 +2443,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn,
return;
}
- send_nt_replies(req, NT_STATUS_OK, params, param_len,
+ send_nt_replies(conn, req, NT_STATUS_OK, params, param_len,
pdata, data_len);
}
#endif /* HAVE_SYS_QUOTAS */
@@ -2573,8 +2580,9 @@ static void handle_nttrans(connection_struct *conn,
Reply to a SMBNTtrans.
****************************************************************************/
-void reply_nttrans(connection_struct *conn, struct smb_request *req)
+void reply_nttrans(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
uint32 pscnt;
uint32 psoff;
uint32 dscnt;
@@ -2764,8 +2772,9 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req)
Reply to a SMBnttranss
****************************************************************************/
-void reply_nttranss(connection_struct *conn, struct smb_request *req)
+void reply_nttranss(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index d3ba9e076c..e3fae02b83 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2267,7 +2267,7 @@ NTSTATUS open_directory(connection_struct *conn,
return NT_STATUS_OK;
}
-NTSTATUS create_directory(connection_struct *conn, const char *directory)
+NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, const char *directory)
{
NTSTATUS status;
SMB_STRUCT_STAT sbuf;
@@ -2275,7 +2275,7 @@ NTSTATUS create_directory(connection_struct *conn, const char *directory)
SET_STAT_INVALID(sbuf);
- status = open_directory(conn, NULL, directory, &sbuf,
+ status = open_directory(conn, req, directory, &sbuf,
FILE_READ_ATTRIBUTES, /* Just a stat open */
FILE_SHARE_NONE, /* Ignored for stat opens */
FILE_CREATE,
@@ -2606,16 +2606,16 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
uint32_t sec_info_sent = ALL_SECURITY_INFORMATION;
uint32_t saved_access_mask = fsp->access_mask;
- if (sd->owner_sid==0) {
+ if (sd->owner_sid == NULL) {
sec_info_sent &= ~OWNER_SECURITY_INFORMATION;
}
- if (sd->group_sid==0) {
+ if (sd->group_sid == NULL) {
sec_info_sent &= ~GROUP_SECURITY_INFORMATION;
}
- if (sd->sacl==0) {
+ if (sd->sacl == NULL) {
sec_info_sent &= ~SACL_SECURITY_INFORMATION;
}
- if (sd->dacl==0) {
+ if (sd->dacl == NULL) {
sec_info_sent &= ~DACL_SECURITY_INFORMATION;
}
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 8a5b1f4ecd..277e07c178 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -252,13 +252,7 @@ static char *new_break_smb_message(TALLOC_CTX *mem_ctx,
}
memset(result,'\0',smb_size);
- if (!srv_encryption_on()) {
- cli_set_message(result,8,0,true);
- } else {
- char inbuf[8];
- smb_set_enclen(inbuf,4,srv_enc_ctx());
- srv_set_message(inbuf,result,8,0,true);
- }
+ srv_set_message(result,8,0,true);
SCVAL(result,smb_com,SMBlockingX);
SSVAL(result,smb_tid,fsp->conn->cnum);
SSVAL(result,smb_pid,0xFFFF);
@@ -455,8 +449,10 @@ static void process_oplock_async_level2_break_message(struct messaging_context *
sign_state = srv_oplock_set_signing(False);
show_msg(break_msg);
- if (!send_smb(smbd_server_fd(), break_msg)) {
- exit_server_cleanly("oplock_break: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ break_msg,
+ IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
/* Restore the sign state to what it was. */
@@ -560,8 +556,10 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
sign_state = srv_oplock_set_signing(False);
show_msg(break_msg);
- if (!send_smb(smbd_server_fd(), break_msg)) {
- exit_server_cleanly("oplock_break: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ break_msg,
+ IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
/* Restore the sign state to what it was. */
@@ -637,8 +635,10 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
sign_state = srv_oplock_set_signing(False);
show_msg(break_msg);
- if (!send_smb(smbd_server_fd(), break_msg)) {
- exit_server_cleanly("oplock_break: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ break_msg,
+ IS_CONN_ENCRYPTED(fsp->conn))) {
+ exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
/* Restore the sign state to what it was. */
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 88b67c03e5..6b4b83d97d 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -291,8 +291,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
return;
}
- srv_set_message((const char *)req->inbuf,
- (char *)req->outbuf, 12, nread, False);
+ srv_set_message((char *)req->outbuf, 12, nread, False);
SSVAL(req->outbuf,smb_vwv5,nread);
SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf));
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 48a6d18bc9..fe32d57ff7 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -50,14 +50,52 @@ enum smb_read_errors *get_srv_read_error(void)
return &smb_read_error;
}
+/****************************************************************************
+ Send an smb to a fd.
+****************************************************************************/
+
+bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
+{
+ size_t len;
+ size_t nwritten=0;
+ ssize_t ret;
+ char *buf_out = buffer;
+
+ /* Sign the outgoing packet if required. */
+ srv_calculate_sign_mac(buf_out);
+
+ if (do_encrypt) {
+ NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("send_smb: SMB encryption failed "
+ "on outgoing packet! Error %s\n",
+ nt_errstr(status) ));
+ return false;
+ }
+ }
+
+ len = smb_len(buf_out) + 4;
+
+ while (nwritten < len) {
+ ret = write_data(fd,buf_out+nwritten,len - nwritten);
+ if (ret <= 0) {
+ DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
+ (int)len,(int)ret, strerror(errno) ));
+ srv_free_enc_buffer(buf_out);
+ return false;
+ }
+ nwritten += ret;
+ }
+
+ srv_free_enc_buffer(buf_out);
+ return true;
+}
+
/*******************************************************************
Setup the word count and byte count for a smb message.
- copying the '0xFF X X X' bytes from incoming
- buffer (so we copy any encryption context).
********************************************************************/
-int srv_set_message(const char *frombuf,
- char *buf,
+int srv_set_message(char *buf,
int num_words,
int num_bytes,
bool zero)
@@ -67,22 +105,14 @@ int srv_set_message(const char *frombuf,
}
SCVAL(buf,smb_wct,num_words);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
- _smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
- if (buf != frombuf) {
- memcpy(buf+4, frombuf+4, 4);
- }
+ smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
return (smb_size + num_words*2 + num_bytes);
}
-static bool valid_smb_header(const char *inbuf)
+static bool valid_smb_header(const uint8_t *inbuf)
{
- if (srv_encryption_on()) {
- uint16_t enc_num;
- NTSTATUS status = get_enc_ctx_num(inbuf, &enc_num);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
- return (enc_num == 0);
+ if (is_encrypted_packet(inbuf)) {
+ return true;
}
return (strncmp(smb_base(inbuf),"\377SMB",4) == 0);
}
@@ -162,7 +192,7 @@ static ssize_t read_packet_remainder(int fd,
(2*14) + /* word count (including bcc) */ \
1 /* pad byte */)
-ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
+static ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
const char lenbuf[4],
int fd,
char **buffer,
@@ -202,7 +232,7 @@ ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
* valid writeX call.
*/
- if (is_valid_writeX_buffer(writeX_header)) {
+ if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
/*
* If the data offset is beyond what
* we've read, drain the extra bytes.
@@ -310,7 +340,7 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
return -1;
}
- if (CVAL(lenbuf,0) != SMBkeepalive &&
+ if (CVAL(lenbuf,0) == 0 &&
min_recv_size &&
smb_len_large(lenbuf) > min_recv_size && /* Could be a UNIX large writeX. */
!srv_is_signing_active()) {
@@ -350,18 +380,24 @@ static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
return len + 4;
}
-ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
- unsigned int timeout, size_t *p_unread)
+static ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx,
+ int fd,
+ char **buffer,
+ unsigned int timeout,
+ size_t *p_unread,
+ bool *p_encrypted)
{
ssize_t len;
+ *p_encrypted = false;
+
len = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout, p_unread);
if (len < 0) {
return -1;
}
- if (srv_encryption_on()) {
+ if (is_encrypted_packet((uint8_t *)*buffer)) {
NTSTATUS status = srv_decrypt_buffer(*buffer);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
@@ -371,6 +407,7 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
SMB_READ_BAD_DECRYPT);
return -1;
}
+ *p_encrypted = true;
}
/* Check the incoming SMB signature. */
@@ -390,7 +427,8 @@ ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
void init_smb_request(struct smb_request *req,
const uint8 *inbuf,
- size_t unread_bytes)
+ size_t unread_bytes,
+ bool encrypted)
{
size_t req_size = smb_len(inbuf) + 4;
/* Ensure we have at least smb_size bytes. */
@@ -406,6 +444,8 @@ void init_smb_request(struct smb_request *req,
req->tid = SVAL(inbuf, smb_tid);
req->wct = CVAL(inbuf, smb_wct);
req->unread_bytes = unread_bytes;
+ req->encrypted = encrypted;
+ req->conn = conn_find(req->tid);
/* Ensure we have at least wct words and 2 bytes of bcc. */
if (smb_size + req->wct*2 > req_size) {
@@ -463,6 +503,7 @@ static bool push_queued_message(struct smb_request *req,
msg->request_time = request_time;
msg->end_time = end_time;
+ msg->encrypted = req->encrypted;
if (private_data) {
msg->private_data = data_blob_talloc(msg, private_data,
@@ -738,7 +779,8 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx,
char **buffer,
size_t *buffer_len,
int timeout,
- size_t *p_unread)
+ size_t *p_unread,
+ bool *p_encrypted)
{
fd_set r_fds, w_fds;
int selrtn;
@@ -805,6 +847,7 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx,
return False;
}
*buffer_len = msg->buf.length;
+ *p_encrypted = msg->encrypted;
/* We leave this message on the queue so the open code can
know this is a retry. */
@@ -921,7 +964,8 @@ static bool receive_message_or_smb(TALLOC_CTX *mem_ctx,
goto again;
}
- len = receive_smb_talloc(mem_ctx, smbd_server_fd(), buffer, 0, p_unread);
+ len = receive_smb_talloc(mem_ctx, smbd_server_fd(),
+ buffer, 0, p_unread, p_encrypted);
if (len == -1) {
return False;
@@ -1001,7 +1045,7 @@ force write permissions on print services.
*/
static const struct smb_message_struct {
const char *name;
- void (*fn_new)(connection_struct *conn, struct smb_request *req);
+ void (*fn_new)(struct smb_request *req);
int flags;
} smb_messages[256] = {
@@ -1288,8 +1332,7 @@ void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
}
construct_reply_common((char *)req->inbuf, (char *)req->outbuf);
- srv_set_message((const char *)req->inbuf,
- (char *)req->outbuf, num_words, num_bytes, false);
+ srv_set_message((char *)req->outbuf, num_words, num_bytes, false);
/*
* Zero out the word area, the caller has to take care of the bcc area
* himself
@@ -1347,11 +1390,11 @@ static void smb_dump(const char *name, int type, const char *data, ssize_t len)
find.
****************************************************************************/
-static void switch_message(uint8 type, struct smb_request *req, int size)
+static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
{
int flags;
uint16 session_tag;
- connection_struct *conn;
+ connection_struct *conn = NULL;
static uint16 last_session_tag = UID_FIELD_INVALID;
@@ -1359,7 +1402,7 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
/* Make sure this is an SMB packet. smb_size contains NetBIOS header
* so subtract 4 from it. */
- if (!valid_smb_header((const char *)req->inbuf)
+ if (!valid_smb_header(req->inbuf)
|| (size < (smb_size - 4))) {
DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
smb_len(req->inbuf)));
@@ -1370,7 +1413,7 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
DEBUG(0,("Unknown message type %d!\n",type));
smb_dump("Unknown", 1, (char *)req->inbuf, size);
reply_unknown_new(req, type);
- return;
+ return NULL;
}
flags = smb_messages[type].flags;
@@ -1378,7 +1421,7 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
/* In share mode security we must ignore the vuid. */
session_tag = (lp_security() == SEC_SHARE)
? UID_FIELD_INVALID : req->vuid;
- conn = conn_find(req->tid);
+ conn = req->conn;
DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
(int)sys_getpid(), (unsigned long)conn));
@@ -1423,12 +1466,12 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
} else {
reply_doserror(req, ERRSRV, ERRinvnid);
}
- return;
+ return NULL;
}
if (!change_to_user(conn,session_tag)) {
reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
- return;
+ return conn;
}
/* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
@@ -1436,13 +1479,13 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
/* Does it need write permission? */
if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
- return;
+ return conn;
}
/* IPC services are limited */
if (IS_IPC(conn) && !(flags & CAN_IPC)) {
reply_doserror(req, ERRSRV,ERRaccess);
- return;
+ return conn;
}
} else {
/* This call needs to be run as root */
@@ -1451,21 +1494,24 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
/* load service specific parameters */
if (conn) {
+ if (req->encrypted) {
+ conn->encrypted_tid = true;
+ /* encrypted required from now on. */
+ conn->encrypt_level = Required;
+ } else if (ENCRYPTION_REQUIRED(conn)) {
+ uint8 com = CVAL(req->inbuf,smb_com);
+ if (com != SMBtrans2 && com != SMBtranss2) {
+ exit_server_cleanly("encryption required "
+ "on connection");
+ return conn;
+ }
+ }
+
if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
(flags & (AS_USER|DO_CHDIR)
?True:False))) {
reply_doserror(req, ERRSRV, ERRaccess);
- return;
- }
-
- if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
- /* An encrypted packet has 0xFF 'E' at offset 4
- * which is little endian 0x45FF */
- uint8 com = CVAL(req->inbuf,smb_com);
- if (com != SMBtrans2 && com != SMBtranss2) {
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
- }
+ return conn;
}
conn->num_smb_operations++;
}
@@ -1476,19 +1522,21 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
!check_access(smbd_server_fd(), lp_hostsallow(-1),
lp_hostsdeny(-1)))) {
reply_doserror(req, ERRSRV, ERRaccess);
- return;
+ return conn;
}
- smb_messages[type].fn_new(conn, req);
+ smb_messages[type].fn_new(req);
+ return req->conn;
}
/****************************************************************************
Construct a reply to the incoming packet.
****************************************************************************/
-static void construct_reply(char *inbuf, int size, size_t unread_bytes)
+static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted)
{
uint8 type = CVAL(inbuf,smb_com);
+ connection_struct *conn;
struct smb_request *req;
chain_size = 0;
@@ -1498,9 +1546,9 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes)
if (!(req = talloc(talloc_tos(), struct smb_request))) {
smb_panic("could not allocate smb_request");
}
- init_smb_request(req, (uint8 *)inbuf, unread_bytes);
+ init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
- switch_message(type, req, size);
+ conn = switch_message(type, req, size);
if (req->unread_bytes) {
/* writeX failed. drain socket. */
@@ -1519,8 +1567,10 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes)
show_msg((char *)req->outbuf);
}
- if (!send_smb(smbd_server_fd(), (char *)req->outbuf)) {
- exit_server_cleanly("construct_reply: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)||req->encrypted)) {
+ exit_server_cleanly("construct_reply: srv_send_smb failed.");
}
TALLOC_FREE(req);
@@ -1532,7 +1582,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes)
Process an smb from the client
****************************************************************************/
-static void process_smb(char *inbuf, size_t nread, size_t unread_bytes)
+static void process_smb(char *inbuf, size_t nread, size_t unread_bytes, bool encrypted)
{
static int trans_num;
int msg_type = CVAL(inbuf,0);
@@ -1553,7 +1603,7 @@ static void process_smb(char *inbuf, size_t nread, size_t unread_bytes)
static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ( "Connection denied from %s\n",
client_addr(get_client_fd(),addr,sizeof(addr)) ) );
- (void)send_smb(smbd_server_fd(),(char *)buf);
+ (void)srv_send_smb(smbd_server_fd(),(char *)buf,false);
exit_server_cleanly("connection denied");
}
}
@@ -1574,7 +1624,7 @@ static void process_smb(char *inbuf, size_t nread, size_t unread_bytes)
show_msg(inbuf);
- construct_reply(inbuf,nread,unread_bytes);
+ construct_reply(inbuf,nread,unread_bytes,encrypted);
trans_num++;
}
@@ -1611,7 +1661,7 @@ void remove_from_common_flags2(uint32 v)
void construct_reply_common(const char *inbuf, char *outbuf)
{
- srv_set_message(inbuf,outbuf,0,0,false);
+ srv_set_message(outbuf,0,0,false);
SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
SIVAL(outbuf,smb_rcls,0);
@@ -1734,7 +1784,7 @@ void chain_reply(struct smb_request *req)
if (!(req2 = talloc(talloc_tos(), struct smb_request))) {
smb_panic("could not allocate smb_request");
}
- init_smb_request(req2, (uint8 *)inbuf2,0);
+ init_smb_request(req2, (uint8 *)inbuf2,0, req->encrypted);
/* process the request */
switch_message(smb_com2, req2, new_size);
@@ -2020,6 +2070,7 @@ void smbd_process(void)
int num_echos;
char *inbuf;
size_t inbuf_len;
+ bool encrypted = false;
TALLOC_CTX *frame = talloc_stackframe();
errno = 0;
@@ -2035,7 +2086,9 @@ void smbd_process(void)
run_events(smbd_event_context(), 0, NULL, NULL);
while (!receive_message_or_smb(NULL, &inbuf, &inbuf_len,
- select_timeout, &unread_bytes)) {
+ select_timeout,
+ &unread_bytes,
+ &encrypted)) {
if(!timeout_processing(&select_timeout,
&last_timeout_processing_time))
return;
@@ -2054,7 +2107,7 @@ void smbd_process(void)
*/
num_echos = smb_echo_count;
- process_smb(inbuf, inbuf_len, unread_bytes);
+ process_smb(inbuf, inbuf_len, unread_bytes, encrypted);
TALLOC_FREE(inbuf);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 2707aee9c8..d5e683ca3c 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -391,7 +391,7 @@ void reply_special(char *inbuf)
/*
* We only really use 4 bytes of the outbuf, but for the smb_setlen
- * calculation & friends (send_smb uses that) we need the full smb
+ * calculation & friends (srv_send_smb uses that) we need the full smb
* header.
*/
char outbuf[smb_size];
@@ -470,7 +470,7 @@ void reply_special(char *inbuf)
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
msg_type, msg_flags));
- send_smb(smbd_server_fd(), outbuf);
+ srv_send_smb(smbd_server_fd(), outbuf, false);
return;
}
@@ -479,8 +479,9 @@ void reply_special(char *inbuf)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_tcon(connection_struct *conn, struct smb_request *req)
+void reply_tcon(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
const char *service;
char *service_buf = NULL;
char *password = NULL;
@@ -523,6 +524,7 @@ void reply_tcon(connection_struct *conn, struct smb_request *req)
password_blob = data_blob(password, pwlen+1);
conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
+ req->conn = conn;
data_blob_clear_free(&password_blob);
@@ -549,8 +551,9 @@ void reply_tcon(connection_struct *conn, struct smb_request *req)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
+void reply_tcon_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *service = NULL;
DATA_BLOB password;
TALLOC_CTX *ctx = talloc_tos();
@@ -578,6 +581,8 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
/* we might have to close an old one */
if ((tcon_flags & 0x1) && conn) {
close_cnum(conn,req->vuid);
+ req->conn = NULL;
+ conn = NULL;
}
if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
@@ -646,6 +651,7 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
conn = make_connection(service, password, client_devicetype,
req->vuid, &nt_status);
+ req->conn =conn;
data_blob_clear_free(&password);
@@ -731,17 +737,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
Reply to an unknown type.
****************************************************************************/
-int reply_unknown(char *inbuf,char *outbuf)
-{
- int type;
- type = CVAL(inbuf,smb_com);
-
- DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
- smb_fn_name(type), type, type));
-
- return(ERROR_DOS(ERRSRV,ERRunknownsmb));
-}
-
void reply_unknown_new(struct smb_request *req, uint8 type)
{
DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
@@ -755,8 +750,9 @@ void reply_unknown_new(struct smb_request *req, uint8 type)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_ioctl(connection_struct *conn, struct smb_request *req)
+void reply_ioctl(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
uint16 device;
uint16 function;
uint32 ioctl_code;
@@ -844,8 +840,9 @@ static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
Reply to a checkpath.
****************************************************************************/
-void reply_checkpath(connection_struct *conn, struct smb_request *req)
+void reply_checkpath(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *name = NULL;
SMB_STRUCT_STAT sbuf;
NTSTATUS status;
@@ -938,8 +935,9 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
Reply to a getatr.
****************************************************************************/
-void reply_getatr(connection_struct *conn, struct smb_request *req)
+void reply_getatr(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
SMB_STRUCT_STAT sbuf;
int mode=0;
@@ -1039,8 +1037,9 @@ void reply_getatr(connection_struct *conn, struct smb_request *req)
Reply to a setatr.
****************************************************************************/
-void reply_setatr(connection_struct *conn, struct smb_request *req)
+void reply_setatr(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
int mode;
time_t mtime;
@@ -1139,8 +1138,9 @@ void reply_setatr(connection_struct *conn, struct smb_request *req)
Reply to a dskattr.
****************************************************************************/
-void reply_dskattr(connection_struct *conn, struct smb_request *req)
+void reply_dskattr(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_BIG_UINT dfree,dsize,bsize;
START_PROFILE(SMBdskattr);
@@ -1191,8 +1191,9 @@ void reply_dskattr(connection_struct *conn, struct smb_request *req)
Can be called from SMBsearch, SMBffirst or SMBfunique.
****************************************************************************/
-void reply_search(connection_struct *conn, struct smb_request *req)
+void reply_search(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *mask = NULL;
char *directory = NULL;
char *fname = NULL;
@@ -1493,7 +1494,7 @@ void reply_search(connection_struct *conn, struct smb_request *req)
Reply to a fclose (stop directory search).
****************************************************************************/
-void reply_fclose(connection_struct *conn, struct smb_request *req)
+void reply_fclose(struct smb_request *req)
{
int status_len;
char status[21];
@@ -1557,8 +1558,9 @@ void reply_fclose(connection_struct *conn, struct smb_request *req)
Reply to an open.
****************************************************************************/
-void reply_open(connection_struct *conn, struct smb_request *req)
+void reply_open(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
uint32 fattr=0;
SMB_OFF_T size = 0;
@@ -1597,51 +1599,30 @@ void reply_open(connection_struct *conn, struct smb_request *req)
return;
}
- status = resolve_dfspath(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- END_PROFILE(SMBopen);
- return;
- }
- reply_nterror(req, status);
- END_PROFILE(SMBopen);
- return;
- }
-
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBopen);
- return;
- }
-
- status = check_name(conn, fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBopen);
- return;
- }
-
- if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
- &access_mask, &share_mode, &create_disposition, &create_options)) {
+ if (!map_open_params_to_ntcreate(
+ fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
+ &share_mode, &create_disposition, &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
END_PROFILE(SMBopen);
return;
}
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- access_mask,
- share_mode,
- create_disposition,
- create_options,
- dos_attr,
- oplock_request,
- &info, &fsp);
+ status = create_file(conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ dos_attr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ &info, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
@@ -1694,8 +1675,9 @@ void reply_open(connection_struct *conn, struct smb_request *req)
Reply to an open and X.
****************************************************************************/
-void reply_open_and_X(connection_struct *conn, struct smb_request *req)
+void reply_open_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
uint16 open_flags;
int deny_mode;
@@ -1762,53 +1744,30 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
return;
}
- status = resolve_dfspath(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBopenX);
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- return;
- }
- reply_nterror(req, status);
- return;
- }
-
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBopenX);
- return;
- }
-
- status = check_name(conn, fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBopenX);
- return;
- }
-
- if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun,
- &access_mask,
- &share_mode,
- &create_disposition,
- &create_options)) {
+ if (!map_open_params_to_ntcreate(
+ fname, deny_mode, smb_ofun, &access_mask,
+ &share_mode, &create_disposition, &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
END_PROFILE(SMBopenX);
return;
}
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- access_mask,
- share_mode,
- create_disposition,
- create_options,
- smb_attr,
- oplock_request,
- &smb_action, &fsp);
+ status = create_file(conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ smb_attr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ &smb_action, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBopenX);
@@ -1905,10 +1864,9 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
/****************************************************************************
Reply to a SMBulogoffX.
- conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_ulogoffX(connection_struct *conn, struct smb_request *req)
+void reply_ulogoffX(struct smb_request *req)
{
user_struct *vuser;
@@ -1941,8 +1899,9 @@ void reply_ulogoffX(connection_struct *conn, struct smb_request *req)
Reply to a mknew or a create.
****************************************************************************/
-void reply_mknew(connection_struct *conn, struct smb_request *req)
+void reply_mknew(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
int com;
uint32 fattr = 0;
@@ -1982,35 +1941,6 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
return;
}
- status = resolve_dfspath(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBcreate);
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- return;
- }
- reply_nterror(req, status);
- return;
- }
-
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBcreate);
- return;
- }
-
- status = check_name(conn, fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBcreate);
- return;
- }
-
if (fattr & aVOLID) {
DEBUG(0,("Attempt to create file (%s) with volid set - "
"please report this\n", fname));
@@ -2024,15 +1954,22 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
create_disposition = FILE_OVERWRITE_IF;
}
- /* Open file using ntcreate. */
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- access_mask,
- share_mode,
- create_disposition,
- create_options,
- fattr,
- oplock_request,
- NULL, &fsp);
+ status = create_file(conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ fattr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ NULL, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
@@ -2072,8 +2009,9 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
Reply to a create temporary file.
****************************************************************************/
-void reply_ctemp(connection_struct *conn, struct smb_request *req)
+void reply_ctemp(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
uint32 fattr;
files_struct *fsp;
@@ -2538,8 +2476,9 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
Reply to a unlink
****************************************************************************/
-void reply_unlink(connection_struct *conn, struct smb_request *req)
+void reply_unlink(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *name = NULL;
uint32 dirtype;
NTSTATUS status;
@@ -2780,8 +2719,9 @@ normal_readbraw:
Reply to a readbraw (core+ protocol).
****************************************************************************/
-void reply_readbraw(connection_struct *conn, struct smb_request *req)
+void reply_readbraw(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
ssize_t maxcount,mincount;
size_t nread = 0;
SMB_OFF_T startpos;
@@ -2791,7 +2731,7 @@ void reply_readbraw(connection_struct *conn, struct smb_request *req)
START_PROFILE(SMBreadbraw);
- if (srv_is_signing_active() || srv_encryption_on()) {
+ if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
"raw reads/writes are disallowed.");
}
@@ -2930,8 +2870,9 @@ void reply_readbraw(connection_struct *conn, struct smb_request *req)
Reply to a lockread (core+ protocol).
****************************************************************************/
-void reply_lockread(connection_struct *conn, struct smb_request *req)
+void reply_lockread(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
ssize_t nread = -1;
char *data;
SMB_OFF_T startpos;
@@ -3017,8 +2958,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
return;
}
- srv_set_message((const char *)req->inbuf,
- (char *)req->outbuf, 5, nread+3, False);
+ srv_set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
SSVAL(req->outbuf,smb_vwv5,nread+3);
@@ -3040,8 +2980,9 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
Reply to a read.
****************************************************************************/
-void reply_read(connection_struct *conn, struct smb_request *req)
+void reply_read(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
size_t numtoread;
ssize_t nread = 0;
char *data;
@@ -3105,8 +3046,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
return;
}
- srv_set_message((const char *)req->inbuf,
- (char *)req->outbuf, 5, nread+3, False);
+ srv_set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
SSVAL(req->outbuf,smb_vwv5,nread+3);
@@ -3124,12 +3064,12 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
Setup readX header.
****************************************************************************/
-static int setup_readX_header(const char *inbuf, char *outbuf, size_t smb_maxcnt)
+static int setup_readX_header(char *outbuf, size_t smb_maxcnt)
{
int outsize;
char *data;
- outsize = srv_set_message(inbuf, outbuf,12,smb_maxcnt,False);
+ outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
data = smb_buf(outbuf);
memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
@@ -3179,6 +3119,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
*/
if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
+ !is_encrypted_packet(req->inbuf) &&
lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
uint8 headerbuf[smb_size + 12 * 2];
DATA_BLOB header;
@@ -3192,8 +3133,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
header = data_blob_const(headerbuf, sizeof(headerbuf));
construct_reply_common((char *)req->inbuf, (char *)headerbuf);
- setup_readX_header((const char *)req->inbuf,
- (char *)headerbuf, smb_maxcnt);
+ setup_readX_header((char *)headerbuf, smb_maxcnt);
if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) {
/* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
@@ -3244,8 +3184,7 @@ normal_read:
uint8 headerbuf[smb_size + 2*12];
construct_reply_common((char *)req->inbuf, (char *)headerbuf);
- setup_readX_header((const char *)req->inbuf,
- (char *)headerbuf, smb_maxcnt);
+ setup_readX_header((char *)headerbuf, smb_maxcnt);
/* Send out the header. */
if (write_data(smbd_server_fd(), (char *)headerbuf,
@@ -3272,8 +3211,7 @@ normal_read:
return;
}
- setup_readX_header((const char *)req->inbuf,
- (char *)req->outbuf, nread);
+ setup_readX_header((char *)req->outbuf, nread);
DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
@@ -3288,8 +3226,9 @@ normal_read:
Reply to a read and X.
****************************************************************************/
-void reply_read_and_X(connection_struct *conn, struct smb_request *req)
+void reply_read_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
SMB_OFF_T startpos;
size_t smb_maxcnt;
@@ -3338,7 +3277,7 @@ void reply_read_and_X(connection_struct *conn, struct smb_request *req)
return;
}
/* We currently don't do this on signed or sealed data. */
- if (srv_is_signing_active() || srv_encryption_on()) {
+ if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
END_PROFILE(SMBreadX);
return;
@@ -3417,8 +3356,9 @@ void error_to_writebrawerr(struct smb_request *req)
Reply to a writebraw (core+ or LANMAN1.0 protocol).
****************************************************************************/
-void reply_writebraw(connection_struct *conn, struct smb_request *req)
+void reply_writebraw(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
int outsize = 0;
char *buf = NULL;
ssize_t nwritten=0;
@@ -3529,13 +3469,15 @@ void reply_writebraw(connection_struct *conn, struct smb_request *req)
* it to send more bytes */
memcpy(buf, req->inbuf, smb_size);
- outsize = srv_set_message((const char *)req->inbuf, buf,
+ outsize = srv_set_message(buf,
Protocol>PROTOCOL_COREPLUS?1:0,0,True);
SCVAL(buf,smb_com,SMBwritebraw);
SSVALS(buf,smb_vwv0,0xFFFF);
show_msg(buf);
- if (!send_smb(smbd_server_fd(),buf)) {
- exit_server_cleanly("reply_writebraw: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),
+ buf,
+ IS_CONN_ENCRYPTED(conn))) {
+ exit_server_cleanly("reply_writebraw: srv_send_smb "
"failed.");
}
@@ -3644,8 +3586,9 @@ void reply_writebraw(connection_struct *conn, struct smb_request *req)
Reply to a writeunlock (core+).
****************************************************************************/
-void reply_writeunlock(connection_struct *conn, struct smb_request *req)
+void reply_writeunlock(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
ssize_t nwritten = -1;
size_t numtowrite;
SMB_OFF_T startpos;
@@ -3743,8 +3686,9 @@ void reply_writeunlock(connection_struct *conn, struct smb_request *req)
Reply to a write.
****************************************************************************/
-void reply_write(connection_struct *conn, struct smb_request *req)
+void reply_write(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
size_t numtowrite;
ssize_t nwritten = -1;
SMB_OFF_T startpos;
@@ -3854,14 +3798,14 @@ void reply_write(connection_struct *conn, struct smb_request *req)
(2*14) + /* word count (including bcc) */ \
1 /* pad byte */)
-bool is_valid_writeX_buffer(const char *inbuf)
+bool is_valid_writeX_buffer(const uint8_t *inbuf)
{
size_t numtowrite;
connection_struct *conn = NULL;
unsigned int doff = 0;
size_t len = smb_len_large(inbuf);
- if (srv_encryption_on()) {
+ if (is_encrypted_packet(inbuf)) {
/* Can't do this on encrypted
* connections. */
return false;
@@ -3931,8 +3875,9 @@ bool is_valid_writeX_buffer(const char *inbuf)
Reply to a write and X.
****************************************************************************/
-void reply_write_and_X(connection_struct *conn, struct smb_request *req)
+void reply_write_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
SMB_OFF_T startpos;
size_t numtowrite;
@@ -4099,8 +4044,9 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
Reply to a lseek.
****************************************************************************/
-void reply_lseek(connection_struct *conn, struct smb_request *req)
+void reply_lseek(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_OFF_T startpos;
SMB_OFF_T res= -1;
int mode,umode;
@@ -4186,8 +4132,9 @@ void reply_lseek(connection_struct *conn, struct smb_request *req)
Reply to a flush.
****************************************************************************/
-void reply_flush(connection_struct *conn, struct smb_request *req)
+void reply_flush(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
uint16 fnum;
files_struct *fsp;
@@ -4230,7 +4177,7 @@ void reply_flush(connection_struct *conn, struct smb_request *req)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_exit(connection_struct *conn, struct smb_request *req)
+void reply_exit(struct smb_request *req)
{
START_PROFILE(SMBexit);
@@ -4248,8 +4195,9 @@ void reply_exit(connection_struct *conn, struct smb_request *req)
Reply to a close - has to deal with closing a directory opened by NT SMB's.
****************************************************************************/
-void reply_close(connection_struct *conn, struct smb_request *req)
+void reply_close(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp = NULL;
START_PROFILE(SMBclose);
@@ -4326,8 +4274,9 @@ void reply_close(connection_struct *conn, struct smb_request *req)
Reply to a writeclose (Core+ protocol).
****************************************************************************/
-void reply_writeclose(connection_struct *conn, struct smb_request *req)
+void reply_writeclose(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
size_t numtowrite;
ssize_t nwritten = -1;
NTSTATUS close_status = NT_STATUS_OK;
@@ -4415,8 +4364,9 @@ void reply_writeclose(connection_struct *conn, struct smb_request *req)
Reply to a lock.
****************************************************************************/
-void reply_lock(connection_struct *conn, struct smb_request *req)
+void reply_lock(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_BIG_UINT count,offset;
NTSTATUS status;
files_struct *fsp;
@@ -4474,8 +4424,9 @@ void reply_lock(connection_struct *conn, struct smb_request *req)
Reply to a unlock.
****************************************************************************/
-void reply_unlock(connection_struct *conn, struct smb_request *req)
+void reply_unlock(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_BIG_UINT count,offset;
NTSTATUS status;
files_struct *fsp;
@@ -4528,8 +4479,9 @@ void reply_unlock(connection_struct *conn, struct smb_request *req)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_tdis(connection_struct *conn, struct smb_request *req)
+void reply_tdis(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
START_PROFILE(SMBtdis);
if (!conn) {
@@ -4542,6 +4494,7 @@ void reply_tdis(connection_struct *conn, struct smb_request *req)
conn->used = False;
close_cnum(conn,req->vuid);
+ req->conn = NULL;
reply_outbuf(req, 0, 0);
END_PROFILE(SMBtdis);
@@ -4553,8 +4506,9 @@ void reply_tdis(connection_struct *conn, struct smb_request *req)
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_echo(connection_struct *conn, struct smb_request *req)
+void reply_echo(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
int smb_reverb;
int seq_num;
unsigned int data_len = smb_buflen(req->inbuf);
@@ -4592,8 +4546,10 @@ void reply_echo(connection_struct *conn, struct smb_request *req)
SSVAL(req->outbuf,smb_vwv0,seq_num);
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
- exit_server_cleanly("reply_echo: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)||req->encrypted))
+ exit_server_cleanly("reply_echo: srv_send_smb failed.");
}
DEBUG(3,("echo %d times\n", smb_reverb));
@@ -4610,8 +4566,9 @@ void reply_echo(connection_struct *conn, struct smb_request *req)
Reply to a printopen.
****************************************************************************/
-void reply_printopen(connection_struct *conn, struct smb_request *req)
+void reply_printopen(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
NTSTATUS status;
@@ -4652,8 +4609,9 @@ void reply_printopen(connection_struct *conn, struct smb_request *req)
Reply to a printclose.
****************************************************************************/
-void reply_printclose(connection_struct *conn, struct smb_request *req)
+void reply_printclose(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
NTSTATUS status;
@@ -4697,8 +4655,9 @@ void reply_printclose(connection_struct *conn, struct smb_request *req)
Reply to a printqueue.
****************************************************************************/
-void reply_printqueue(connection_struct *conn, struct smb_request *req)
+void reply_printqueue(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
int max_count;
int start_index;
@@ -4789,8 +4748,9 @@ void reply_printqueue(connection_struct *conn, struct smb_request *req)
Reply to a printwrite.
****************************************************************************/
-void reply_printwrite(connection_struct *conn, struct smb_request *req)
+void reply_printwrite(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
int numtowrite;
char *data;
files_struct *fsp;
@@ -4848,8 +4808,9 @@ void reply_printwrite(connection_struct *conn, struct smb_request *req)
Reply to a mkdir.
****************************************************************************/
-void reply_mkdir(connection_struct *conn, struct smb_request *req)
+void reply_mkdir(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *directory = NULL;
NTSTATUS status;
SMB_STRUCT_STAT sbuf;
@@ -4896,7 +4857,7 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
return;
}
- status = create_directory(conn, directory);
+ status = create_directory(conn, req, directory);
DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
@@ -5116,8 +5077,9 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
Reply to a rmdir.
****************************************************************************/
-void reply_rmdir(connection_struct *conn, struct smb_request *req)
+void reply_rmdir(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *directory = NULL;
SMB_STRUCT_STAT sbuf;
NTSTATUS status;
@@ -5900,8 +5862,9 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
Reply to a mv.
****************************************************************************/
-void reply_mv(connection_struct *conn, struct smb_request *req)
+void reply_mv(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *name = NULL;
char *newname = NULL;
char *p;
@@ -6131,8 +6094,9 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
Reply to a file copy.
****************************************************************************/
-void reply_copy(connection_struct *conn, struct smb_request *req)
+void reply_copy(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *name = NULL;
char *newname = NULL;
char *directory = NULL;
@@ -6594,8 +6558,9 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_forma
Reply to a lockingX request.
****************************************************************************/
-void reply_lockingX(connection_struct *conn, struct smb_request *req)
+void reply_lockingX(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
unsigned char locktype;
unsigned char oplocklevel;
@@ -6869,8 +6834,7 @@ void reply_lockingX(connection_struct *conn, struct smb_request *req)
* onto the blocking lock queue.
*/
if(push_blocking_lock_request(br_lck,
- (char *)req->inbuf,
- smb_len(req->inbuf)+4,
+ req,
fsp,
lock_timeout,
i,
@@ -6953,7 +6917,7 @@ void reply_lockingX(connection_struct *conn, struct smb_request *req)
please contact vl@samba.org
****************************************************************************/
-void reply_readbmpx(connection_struct *conn, struct smb_request *req)
+void reply_readbmpx(struct smb_request *req)
{
START_PROFILE(SMBreadBmpx);
reply_doserror(req, ERRSRV, ERRuseSTD);
@@ -6967,7 +6931,7 @@ void reply_readbmpx(connection_struct *conn, struct smb_request *req)
please contact vl@samba.org
****************************************************************************/
-void reply_readbs(connection_struct *conn, struct smb_request *req)
+void reply_readbs(struct smb_request *req)
{
START_PROFILE(SMBreadBs);
reply_doserror(req, ERRSRV, ERRuseSTD);
@@ -6979,8 +6943,9 @@ void reply_readbs(connection_struct *conn, struct smb_request *req)
Reply to a SMBsetattrE.
****************************************************************************/
-void reply_setattrE(connection_struct *conn, struct smb_request *req)
+void reply_setattrE(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
struct timespec ts[2];
files_struct *fsp;
@@ -7057,7 +7022,7 @@ void reply_setattrE(connection_struct *conn, struct smb_request *req)
please contact vl@samba.org
****************************************************************************/
-void reply_writebmpx(connection_struct *conn, struct smb_request *req)
+void reply_writebmpx(struct smb_request *req)
{
START_PROFILE(SMBwriteBmpx);
reply_doserror(req, ERRSRV, ERRuseSTD);
@@ -7071,7 +7036,7 @@ void reply_writebmpx(connection_struct *conn, struct smb_request *req)
please contact vl@samba.org
****************************************************************************/
-void reply_writebs(connection_struct *conn, struct smb_request *req)
+void reply_writebs(struct smb_request *req)
{
START_PROFILE(SMBwriteBs);
reply_doserror(req, ERRSRV, ERRuseSTD);
@@ -7083,8 +7048,9 @@ void reply_writebs(connection_struct *conn, struct smb_request *req)
Reply to a SMBgetattrE.
****************************************************************************/
-void reply_getattrE(connection_struct *conn, struct smb_request *req)
+void reply_getattrE(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_STRUCT_STAT sbuf;
int mode;
files_struct *fsp;
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c
index 24ecb77fd5..21fca73fea 100644
--- a/source3/smbd/seal.c
+++ b/source3/smbd/seal.c
@@ -36,24 +36,37 @@ static struct smb_srv_trans_enc_ctx *partial_srv_trans_enc_ctx;
static struct smb_srv_trans_enc_ctx *srv_trans_enc_ctx;
/******************************************************************************
- Is server encryption on ?
+ Return global enc context - this must change if we ever do multiple contexts.
******************************************************************************/
-bool srv_encryption_on(void)
+uint16_t srv_enc_ctx(void)
{
- if (srv_trans_enc_ctx) {
- return common_encryption_on(srv_trans_enc_ctx->es);
- }
- return false;
+ return srv_trans_enc_ctx->es->enc_ctx_num;
}
/******************************************************************************
- Return global enc context - this must change if we ever do multiple contexts.
+ Is this an incoming encrypted packet ?
******************************************************************************/
-uint16 srv_enc_ctx(void)
+bool is_encrypted_packet(const uint8_t *inbuf)
{
- return srv_trans_enc_ctx->es->enc_ctx_num;
+ NTSTATUS status;
+ uint16_t enc_num;
+
+ /* Ignore non-session messages. */
+ if(CVAL(inbuf,0)) {
+ return false;
+ }
+
+ status = get_enc_ctx_num(inbuf, &enc_num);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ if (srv_trans_enc_ctx && enc_num == srv_enc_ctx()) {
+ return true;
+ }
+ return false;
}
/******************************************************************************
@@ -292,9 +305,9 @@ void srv_free_enc_buffer(char *buf)
{
/* We know this is an smb buffer, and we
* didn't malloc, only copy, for a keepalive,
- * so ignore session keepalives. */
+ * so ignore non-session messages. */
- if(CVAL(buf,0) == SMBkeepalive) {
+ if(CVAL(buf,0)) {
return;
}
@@ -309,8 +322,8 @@ void srv_free_enc_buffer(char *buf)
NTSTATUS srv_decrypt_buffer(char *buf)
{
- /* Ignore session keepalives. */
- if(CVAL(buf,0) == SMBkeepalive) {
+ /* Ignore non-session messages. */
+ if(CVAL(buf,0)) {
return NT_STATUS_OK;
}
@@ -329,8 +342,8 @@ NTSTATUS srv_encrypt_buffer(char *buf, char **buf_out)
{
*buf_out = buf;
- /* Ignore session keepalives. */
- if(CVAL(buf,0) == SMBkeepalive) {
+ /* Ignore non-session messages. */
+ if(CVAL(buf,0)) {
return NT_STATUS_OK;
}
@@ -698,6 +711,7 @@ NTSTATUS srv_encryption_start(connection_struct *conn)
srv_trans_enc_ctx->es->enc_on = true;
partial_srv_trans_enc_ctx = NULL;
+
return NT_STATUS_OK;
}
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 8ca012ff24..167682ede2 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -118,8 +118,7 @@ static void sessionsetup_start_signing_engine(
Send a security blob via a session setup reply.
****************************************************************************/
-static void reply_sesssetup_blob(connection_struct *conn,
- struct smb_request *req,
+static void reply_sesssetup_blob(struct smb_request *req,
DATA_BLOB blob,
NTSTATUS nt_status)
{
@@ -139,7 +138,7 @@ static void reply_sesssetup_blob(connection_struct *conn,
}
show_msg((char *)req->outbuf);
- send_smb(smbd_server_fd(),(char *)req->outbuf);
+ srv_send_smb(smbd_server_fd(),(char *)req->outbuf,req->encrypted);
TALLOC_FREE(req->outbuf);
}
@@ -247,8 +246,7 @@ static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
Reply to a session setup spnego negotiate packet for kerberos.
****************************************************************************/
-static void reply_spnego_kerberos(connection_struct *conn,
- struct smb_request *req,
+static void reply_spnego_kerberos(struct smb_request *req,
DATA_BLOB *secblob,
uint16 vuid,
bool *p_invalidate_vuid)
@@ -605,7 +603,7 @@ static void reply_spnego_kerberos(connection_struct *conn,
}
response = spnego_gen_auth_response(&ap_rep_wrapped, ret,
OID_KERBEROS5_OLD);
- reply_sesssetup_blob(conn, req, response, ret);
+ reply_sesssetup_blob(req, response, ret);
data_blob_free(&ap_rep);
data_blob_free(&ap_rep_wrapped);
@@ -623,8 +621,7 @@ static void reply_spnego_kerberos(connection_struct *conn,
leg of the NTLM auth steps.
***************************************************************************/
-static void reply_spnego_ntlmssp(connection_struct *conn,
- struct smb_request *req,
+static void reply_spnego_ntlmssp(struct smb_request *req,
uint16 vuid,
AUTH_NTLMSSP_STATE **auth_ntlmssp_state,
DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
@@ -693,7 +690,7 @@ static void reply_spnego_ntlmssp(connection_struct *conn,
response = *ntlmssp_blob;
}
- reply_sesssetup_blob(conn, req, response, nt_status);
+ reply_sesssetup_blob(req, response, nt_status);
if (wrap) {
data_blob_free(&response);
}
@@ -756,8 +753,7 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out,
Reply to a session setup spnego negotiate packet.
****************************************************************************/
-static void reply_spnego_negotiate(connection_struct *conn,
- struct smb_request *req,
+static void reply_spnego_negotiate(struct smb_request *req,
uint16 vuid,
DATA_BLOB blob1,
AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
@@ -783,7 +779,7 @@ static void reply_spnego_negotiate(connection_struct *conn,
if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) ||
lp_use_kerberos_keytab()) ) {
bool destroy_vuid = True;
- reply_spnego_kerberos(conn, req, &secblob, vuid,
+ reply_spnego_kerberos(req, &secblob, vuid,
&destroy_vuid);
data_blob_free(&secblob);
if (destroy_vuid) {
@@ -811,7 +807,7 @@ static void reply_spnego_negotiate(connection_struct *conn,
data_blob_free(&secblob);
- reply_spnego_ntlmssp(conn, req, vuid, auth_ntlmssp_state,
+ reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
&chal, status, True);
data_blob_free(&chal);
@@ -824,8 +820,7 @@ static void reply_spnego_negotiate(connection_struct *conn,
Reply to a session setup spnego auth packet.
****************************************************************************/
-static void reply_spnego_auth(connection_struct *conn,
- struct smb_request *req,
+static void reply_spnego_auth(struct smb_request *req,
uint16 vuid,
DATA_BLOB blob1,
AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
@@ -860,7 +855,7 @@ static void reply_spnego_auth(connection_struct *conn,
if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) ||
lp_use_kerberos_keytab()) ) {
bool destroy_vuid = True;
- reply_spnego_kerberos(conn, req, &secblob,
+ reply_spnego_kerberos(req, &secblob,
vuid, &destroy_vuid);
data_blob_free(&secblob);
data_blob_free(&auth);
@@ -892,7 +887,7 @@ static void reply_spnego_auth(connection_struct *conn,
data_blob_free(&auth);
- reply_spnego_ntlmssp(conn, req, vuid,
+ reply_spnego_ntlmssp(req, vuid,
auth_ntlmssp_state,
&auth_reply, status, True);
@@ -1104,8 +1099,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-static void reply_sesssetup_and_X_spnego(connection_struct *conn,
- struct smb_request *req)
+static void reply_sesssetup_and_X_spnego(struct smb_request *req)
{
uint8 *p;
DATA_BLOB blob1;
@@ -1225,7 +1219,7 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn,
/* its a negTokenTarg packet */
- reply_spnego_negotiate(conn, req, vuid, blob1,
+ reply_spnego_negotiate(req, vuid, blob1,
&vuser->auth_ntlmssp_state);
data_blob_free(&blob1);
return;
@@ -1235,7 +1229,7 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn,
/* its a auth packet */
- reply_spnego_auth(conn, req, vuid, blob1,
+ reply_spnego_auth(req, vuid, blob1,
&vuser->auth_ntlmssp_state);
data_blob_free(&blob1);
return;
@@ -1260,7 +1254,7 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn,
data_blob_free(&blob1);
- reply_spnego_ntlmssp(conn, req, vuid,
+ reply_spnego_ntlmssp(req, vuid,
&vuser->auth_ntlmssp_state,
&chal, status, False);
data_blob_free(&chal);
@@ -1326,7 +1320,7 @@ static void setup_new_vc_session(void)
Reply to a session setup command.
****************************************************************************/
-void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req)
+void reply_sesssetup_and_X(struct smb_request *req)
{
int sess_vuid;
int smb_bufsize;
@@ -1377,7 +1371,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req)
setup_new_vc_session();
}
- reply_sesssetup_and_X_spnego(conn, req);
+ reply_sesssetup_and_X_spnego(req);
END_PROFILE(SMBsesssetupX);
return;
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 656925502b..c3b5f9fa2f 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -575,7 +575,8 @@ static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-void send_trans2_replies(struct smb_request *req,
+void send_trans2_replies(connection_struct *conn,
+ struct smb_request *req,
const char *params,
int paramsize,
const char *pdata,
@@ -737,8 +738,10 @@ void send_trans2_replies(struct smb_request *req,
/* Send the packet */
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
- exit_server_cleanly("send_trans2_replies: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
TALLOC_FREE(req->outbuf);
@@ -841,20 +844,6 @@ static void call_trans2open(connection_struct *conn,
fname, (unsigned int)deny_mode, (unsigned int)open_attr,
(unsigned int)open_ofun, open_size));
- /* XXXX we need to handle passed times, sattr and flags */
-
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
- status = check_name(conn, fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
if (open_ofun == 0) {
reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
return;
@@ -899,14 +888,22 @@ static void call_trans2open(connection_struct *conn,
return;
}
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- access_mask,
- share_mode,
- create_disposition,
- create_options,
- open_attr,
- oplock_request,
- &smb_action, &fsp);
+ status = create_file(conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ open_attr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ open_size, /* allocation_size */
+ NULL, /* sd */
+ ea_list, /* ea_list */
+ &fsp, /* result */
+ &smb_action, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
@@ -927,41 +924,6 @@ static void call_trans2open(connection_struct *conn,
return;
}
- /* Save the requested allocation size. */
- /* Allocate space for the file if a size hint is supplied */
- if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
- SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size;
- if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) {
- fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
- if (fsp->is_directory) {
- close_file(fsp,ERROR_CLOSE);
- /* Can't set allocation size on a directory. */
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
- }
- if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
- close_file(fsp,ERROR_CLOSE);
- reply_nterror(req, NT_STATUS_DISK_FULL);
- return;
- }
-
- /* Adjust size here to return the right size in the reply.
- Windows does it this way. */
- size = fsp->initial_allocation_size;
- } else {
- fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size);
- }
- }
-
- if (ea_list && smb_action == FILE_WAS_CREATED) {
- status = set_ea(conn, fsp, fname, ea_list);
- if (!NT_STATUS_IS_OK(status)) {
- close_file(fsp,ERROR_CLOSE);
- reply_nterror(req, status);
- return;
- }
- }
-
/* Realloc the size of parameters and data we will return */
*pparams = (char *)SMB_REALLOC(*pparams, 30);
if(*pparams == NULL ) {
@@ -997,7 +959,7 @@ static void call_trans2open(connection_struct *conn,
}
/* Send the required number of replies */
- send_trans2_replies(req, params, 30, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
}
/*********************************************************
@@ -2067,7 +2029,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
SSVAL(params,6,0); /* Never an EA error */
SSVAL(params,8,last_entry_off);
- send_trans2_replies(req, params, 10, pdata, PTR_DIFF(p,pdata),
+ send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
max_data_bytes);
if ((! *directory) && dptr_path(dptr_num)) {
@@ -2391,7 +2353,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
SSVAL(params,4,0); /* Never an EA error */
SSVAL(params,6,last_entry_off);
- send_trans2_replies(req, params, 8, pdata, PTR_DIFF(p,pdata),
+ send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
max_data_bytes);
return;
@@ -2430,13 +2392,23 @@ static void call_trans2qfsinfo(connection_struct *conn,
info_level = SVAL(params,0);
- if (IS_IPC(conn) ||
- (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF )) {
+ if (IS_IPC(conn)) {
+ if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
+ DEBUG(0,("call_trans2qfsinfo: not an allowed "
+ "info level (0x%x) on IPC$.\n",
+ (unsigned int)info_level));
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return;
+ }
+ }
+
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
DEBUG(0,("call_trans2qfsinfo: encryption required "
"and info level 0x%x sent.\n",
(unsigned int)info_level));
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ exit_server_cleanly("encryption required "
+ "on connection");
return;
}
}
@@ -2947,7 +2919,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
}
- send_trans2_replies(req, params, 0, pdata, data_len,
+ send_trans2_replies(conn, req, params, 0, pdata, data_len,
max_data_bytes);
DEBUG( 4, ( "%s info_level = %d\n",
@@ -2993,12 +2965,13 @@ static void call_trans2setfsinfo(connection_struct *conn,
}
}
- if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
DEBUG(0,("call_trans2setfsinfo: encryption required "
"and info level 0x%x sent.\n",
(unsigned int)info_level));
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ exit_server_cleanly("encryption required "
+ "on connection");
return;
}
}
@@ -3089,7 +3062,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
return;
}
- send_trans2_replies(req,
+ send_trans2_replies(conn, req,
*pparams,
param_len,
*ppdata,
@@ -3565,7 +3538,7 @@ static void call_trans2qpipeinfo(connection_struct *conn,
return;
}
- send_trans2_replies(req, params, param_size, *ppdata, data_size,
+ send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
max_data_bytes);
return;
@@ -4497,7 +4470,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
return;
}
- send_trans2_replies(req, params, param_size, *ppdata, data_size,
+ send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
max_data_bytes);
return;
@@ -5201,8 +5174,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_set_posix_lock(connection_struct *conn,
- const uint8 *inbuf,
- int length,
+ const struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp)
@@ -5212,6 +5184,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
uint32 lock_pid;
bool blocking_lock = False;
enum brl_type lock_type;
+
NTSTATUS status = NT_STATUS_OK;
if (fsp == NULL || fsp->fh->fd == -1) {
@@ -5299,7 +5272,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
* onto the blocking lock queue.
*/
if(push_blocking_lock_request(br_lck,
- (char *)inbuf, length,
+ req,
fsp,
-1, /* infinite timeout. */
0,
@@ -6357,7 +6330,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2,
+ send_trans2_replies(conn, req, params, 2,
*ppdata, 0,
max_data_bytes);
return;
@@ -6647,8 +6620,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
return;
}
- status = smb_set_posix_lock(conn, req->inbuf,
- smb_len(req->inbuf) + 4,
+ status = smb_set_posix_lock(conn, req,
pdata, total_data, fsp);
break;
}
@@ -6716,7 +6688,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
}
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2, *ppdata, data_return_size,
+ send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
max_data_bytes);
return;
@@ -6808,7 +6780,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
return;
}
- status = create_directory(conn, directory);
+ status = create_directory(conn, req, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -6834,7 +6806,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
return;
}
@@ -6888,7 +6860,7 @@ static void call_trans2findnotifyfirst(connection_struct *conn,
if(fnf_handle == 0)
fnf_handle = 257;
- send_trans2_replies(req, params, 6, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
return;
}
@@ -6919,7 +6891,7 @@ static void call_trans2findnotifynext(connection_struct *conn,
SSVAL(params,0,0); /* No changes */
SSVAL(params,2,0); /* No EA errors */
- send_trans2_replies(req, params, 4, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
return;
}
@@ -6969,7 +6941,7 @@ static void call_trans2getdfsreferral(connection_struct *conn,
SSVAL(req->inbuf, smb_flg2,
SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
- send_trans2_replies(req,0,0,*ppdata,reply_size, max_data_bytes);
+ send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
return;
}
@@ -7016,7 +6988,7 @@ static void call_trans2ioctl(connection_struct *conn,
srvstr_push(pdata, req->flags2, pdata+18,
lp_servicename(SNUM(conn)), 13,
STR_ASCII|STR_TERMINATE); /* Service name */
- send_trans2_replies(req, *pparams, 0, *ppdata, 32,
+ send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
max_data_bytes);
return;
}
@@ -7029,7 +7001,7 @@ static void call_trans2ioctl(connection_struct *conn,
Reply to a SMBfindclose (stop trans2 directory search).
****************************************************************************/
-void reply_findclose(connection_struct *conn, struct smb_request *req)
+void reply_findclose(struct smb_request *req)
{
int dptr_num;
@@ -7059,7 +7031,7 @@ void reply_findclose(connection_struct *conn, struct smb_request *req)
Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
****************************************************************************/
-void reply_findnclose(connection_struct *conn, struct smb_request *req)
+void reply_findnclose(struct smb_request *req)
{
int dptr_num;
@@ -7095,7 +7067,7 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req,
SSVAL(req->inbuf,smb_flg2,req->flags2);
}
- if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
+ if (conn->encrypt_level == Required && !req->encrypted) {
if (state->call != TRANSACT2_QFSINFO &&
state->call != TRANSACT2_SETFSINFO) {
DEBUG(0,("handle_trans2: encryption required "
@@ -7253,8 +7225,9 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req,
Reply to a SMBtrans2.
****************************************************************************/
-void reply_trans2(connection_struct *conn, struct smb_request *req)
+void reply_trans2(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
unsigned int dsoff;
unsigned int dscnt;
unsigned int psoff;
@@ -7442,8 +7415,9 @@ void reply_trans2(connection_struct *conn, struct smb_request *req)
Reply to a SMBtranss2
****************************************************************************/
-void reply_transs2(connection_struct *conn, struct smb_request *req)
+void reply_transs2(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
int size;
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 082949e0af..05b41413b4 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -37,6 +37,7 @@ static const char *client_txt = "client_oplocks.txt";
static bool use_kerberos;
static fstring multishare_conn_fname;
static bool use_multishare_conn = False;
+static bool do_encrypt;
bool torture_showall = False;
@@ -95,6 +96,57 @@ void *shm_setup(int size)
return ret;
}
+/********************************************************************
+ Ensure a connection is encrypted.
+********************************************************************/
+
+static bool force_cli_encryption(struct cli_state *c,
+ const char *sharename)
+{
+ uint16 major, minor;
+ uint32 caplow, caphigh;
+ NTSTATUS status;
+
+ if (!SERVER_HAS_UNIX_CIFS(c)) {
+ d_printf("Encryption required and "
+ "server that doesn't support "
+ "UNIX extensions - failing connect\n");
+ return false;
+ }
+
+ if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
+ d_printf("Encryption required and "
+ "can't get UNIX CIFS extensions "
+ "version from server.\n");
+ return false;
+ }
+
+ if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
+ d_printf("Encryption required and "
+ "share %s doesn't support "
+ "encryption.\n", sharename);
+ return false;
+ }
+
+ if (c->use_kerberos) {
+ status = cli_gss_smb_encryption_start(c);
+ } else {
+ status = cli_raw_ntlm_smb_encryption_start(c,
+ username,
+ password,
+ workgroup);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("Encryption required and "
+ "setup failed with error %s.\n",
+ nt_errstr(status));
+ return false;
+ }
+
+ return true;
+}
+
static struct cli_state *open_nbt_connection(void)
{
@@ -235,6 +287,10 @@ static bool torture_open_connection_share(struct cli_state **c,
if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
(*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
+ if (do_encrypt) {
+ return force_cli_encryption(*c,
+ sharename);
+ }
return True;
}
@@ -5425,7 +5481,7 @@ static void usage(void)
fstrcpy(workgroup, lp_workgroup());
- while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:b:")) != EOF) {
+ while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:")) != EOF) {
switch (opt) {
case 'p':
port_to_use = atoi(optarg);
@@ -5463,6 +5519,9 @@ static void usage(void)
case 'c':
client_txt = optarg;
break;
+ case 'e':
+ do_encrypt = true;
+ break;
case 'k':
#ifdef HAVE_KRB5
use_kerberos = True;
diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c
index 29bbc83ec3..38cdeacc11 100644
--- a/source3/utils/net_conf.c
+++ b/source3/utils/net_conf.c
@@ -2,7 +2,7 @@
* Samba Unix/Linux SMB client library
* Distributed SMB/CIFS Server Management Utility
* Local configuration interface
- * Copyright (C) Michael Adam 2007
+ * Copyright (C) Michael Adam 2007-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
@@ -19,9 +19,12 @@
*/
/*
- * This is an interface to the configuration stored inside the
- * samba registry. In the future there might be support for other
- * configuration backends as well.
+ * This is an interface to Samba's configuration as made available
+ * by the libnet_conf interface (source/libnet/libnet_conf.c).
+ *
+ * This currently supports local interaction with the configuration
+ * stored in the registry. But other backends and remote access via
+ * rpc might get implemented in the future.
*/
#include "includes.h"
@@ -43,9 +46,9 @@ static int net_conf_import_usage(int argc, const char**argv)
d_printf("USAGE: net conf import [--test|-T] <filename> "
"[<servicename>]\n"
"\t[--test|-T] testmode - do not act, just print "
- "what would be done\n"
+ "what would be done\n"
"\t<servicename> only import service <servicename>, "
- "ignore the rest\n");
+ "ignore the rest\n");
return -1;
}
@@ -136,14 +139,14 @@ static char *parm_valstr(TALLOC_CTX *ctx, struct parm_struct *parm,
valstr = talloc_asprintf(ctx, "%s", BOOLSTR(!*(bool *)ptr));
break;
case P_ENUM:
- for (i = 0; parm->enum_list[i].name; i++) {
- if (*(int *)ptr == parm->enum_list[i].value)
+ for (i = 0; parm->enum_list[i].name; i++) {
+ if (*(int *)ptr == parm->enum_list[i].value)
{
valstr = talloc_asprintf(ctx, "%s",
- parm->enum_list[i].name);
- break;
- }
- }
+ parm->enum_list[i].name);
+ break;
+ }
+ }
break;
case P_OCTAL: {
char *o = octal_string(*(int *)ptr);
@@ -191,7 +194,6 @@ static int import_process_service(TALLOC_CTX *ctx,
struct parm_struct *parm;
int pnum = 0;
const char *servicename;
- struct registry_key *key;
WERROR werr;
char *valstr = NULL;
TALLOC_CTX *tmp_ctx = NULL;
@@ -208,23 +210,21 @@ static int import_process_service(TALLOC_CTX *ctx,
if (opt_testmode) {
d_printf("[%s]\n", servicename);
} else {
- if (libnet_smbconf_key_exists(servicename)) {
- werr = libnet_smbconf_delshare(servicename);
+ if (libnet_conf_share_exists(servicename)) {
+ werr = libnet_conf_delete_share(servicename);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
}
- werr = libnet_smbconf_reg_createkey_internal(tmp_ctx, servicename, &key);
- if (!W_ERROR_IS_OK(werr)) {
- goto done;
- }
}
while ((parm = lp_next_parameter(share->service, &pnum, 0)))
{
- if ((share->service < 0 && parm->p_class == P_LOCAL)
+ if ((share->service < 0) && (parm->p_class == P_LOCAL)
&& !(parm->flags & FLAG_GLOBAL))
+ {
continue;
+ }
valstr = parm_valstr(tmp_ctx, parm, share);
@@ -232,9 +232,14 @@ static int import_process_service(TALLOC_CTX *ctx,
if (opt_testmode) {
d_printf("\t%s = %s\n", parm->label, valstr);
} else {
- werr = libnet_smbconf_reg_setvalue_internal(key,
- parm->label, valstr);
+ werr = libnet_conf_set_parameter(servicename,
+ parm->label,
+ valstr);
if (!W_ERROR_IS_OK(werr)) {
+ d_fprintf(stderr,
+ "Error setting parameter '%s'"
+ ": %s\n", parm->label,
+ dos_errstr(werr));
goto done;
}
}
@@ -289,9 +294,9 @@ static int net_conf_list(int argc, const char **argv)
goto done;
}
- werr = libnet_smbconf_get_config(ctx, &num_shares, &share_names,
- &num_params, &param_names,
- &param_values);
+ werr = libnet_conf_get_config(ctx, &num_shares, &share_names,
+ &num_params, &param_names,
+ &param_values);
if (!W_ERROR_IS_OK(werr)) {
d_fprintf(stderr, "Error getting config: %s\n",
dos_errstr(werr));
@@ -418,7 +423,7 @@ static int net_conf_listshares(int argc, const char **argv)
goto done;
}
- werr = libnet_smbconf_get_share_names(ctx, &num_shares, &share_names);
+ werr = libnet_conf_get_share_names(ctx, &num_shares, &share_names);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -445,7 +450,7 @@ static int net_conf_drop(int argc, const char **argv)
goto done;
}
- werr = libnet_smbconf_drop();
+ werr = libnet_conf_drop();
if (!W_ERROR_IS_OK(werr)) {
d_fprintf(stderr, "Error deleting configuration: %s\n",
dos_errstr(werr));
@@ -462,7 +467,6 @@ static int net_conf_showshare(int argc, const char **argv)
{
int ret = -1;
WERROR werr = WERR_OK;
- struct registry_key *key = NULL;
const char *sharename = NULL;
TALLOC_CTX *ctx;
uint32_t num_params;
@@ -479,8 +483,8 @@ static int net_conf_showshare(int argc, const char **argv)
sharename = argv[0];
- werr = libnet_smbconf_getshare(ctx, sharename, &num_params,
- &param_names, &param_values);
+ werr = libnet_conf_get_share(ctx, sharename, &num_params,
+ &param_names, &param_values);
if (!W_ERROR_IS_OK(werr)) {
d_printf("error getting share parameters: %s\n",
dos_errstr(werr));
@@ -501,11 +505,16 @@ done:
return ret;
}
+/**
+ * Add a share, with a couple of standard parameters, partly optional.
+ *
+ * This is a high level utility function of the net conf utility,
+ * not a direct frontend to the libnet_conf API.
+ */
static int net_conf_addshare(int argc, const char **argv)
{
int ret = -1;
WERROR werr = WERR_OK;
- struct registry_key *newkey = NULL;
char *sharename = NULL;
const char *path = NULL;
const char *comment = NULL;
@@ -557,7 +566,6 @@ static int net_conf_addshare(int argc, const char **argv)
net_conf_addshare_usage(argc, argv);
goto done;
}
-
case 2:
path = argv[1];
sharename = strdup_lower(argv[0]);
@@ -591,6 +599,12 @@ static int net_conf_addshare(int argc, const char **argv)
goto done;
}
+ if (libnet_conf_share_exists(sharename)) {
+ d_fprintf(stderr, "ERROR: share %s already exists.\n",
+ sharename);
+ goto done;
+ }
+
/* validate path */
if (path[0] != '/') {
@@ -620,38 +634,50 @@ static int net_conf_addshare(int argc, const char **argv)
* create the share
*/
- werr = libnet_smbconf_reg_createkey_internal(NULL, argv[0], &newkey);
+ werr = libnet_conf_create_share(sharename);
if (!W_ERROR_IS_OK(werr)) {
+ d_fprintf(stderr, "Error creating share %s: %s\n",
+ sharename, dos_errstr(werr));
goto done;
}
- /* add config params as values */
+ /*
+ * fill the share with parameters
+ */
- werr = libnet_smbconf_reg_setvalue_internal(newkey, "path", path);
- if (!W_ERROR_IS_OK(werr))
+ werr = libnet_conf_set_parameter(sharename, "path", path);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_fprintf(stderr, "Error setting parameter %s: %s\n",
+ "path", dos_errstr(werr));
goto done;
+ }
if (comment != NULL) {
- werr = libnet_smbconf_reg_setvalue_internal(newkey, "comment",
- comment);
- if (!W_ERROR_IS_OK(werr))
+ werr = libnet_conf_set_parameter(sharename, "comment", comment);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_fprintf(stderr, "Error setting parameter %s: %s\n",
+ "comment", dos_errstr(werr));
goto done;
+ }
}
- werr = libnet_smbconf_reg_setvalue_internal(newkey, "guest ok",
- guest_ok);
- if (!W_ERROR_IS_OK(werr))
+ werr = libnet_conf_set_parameter(sharename, "guest ok", guest_ok);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_fprintf(stderr, "Error setting parameter %s: %s\n",
+ "'guest ok'", dos_errstr(werr));
goto done;
+ }
- werr = libnet_smbconf_reg_setvalue_internal(newkey, "writeable",
- writeable);
- if (!W_ERROR_IS_OK(werr))
+ werr = libnet_conf_set_parameter(sharename, "writeable", writeable);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_fprintf(stderr, "Error setting parameter %s: %s\n",
+ "writeable", dos_errstr(werr));
goto done;
+ }
ret = 0;
done:
- TALLOC_FREE(newkey);
SAFE_FREE(sharename);
return ret;
}
@@ -668,7 +694,7 @@ static int net_conf_delshare(int argc, const char **argv)
}
sharename = argv[0];
- werr = libnet_smbconf_delshare(sharename);
+ werr = libnet_conf_delete_share(sharename);
if (!W_ERROR_IS_OK(werr)) {
d_fprintf(stderr, "Error deleting share %s: %s\n",
sharename, dos_errstr(werr));
@@ -696,7 +722,16 @@ static int net_conf_setparm(int argc, const char **argv)
param = strdup_lower(argv[1]);
value_str = argv[2];
- werr = libnet_smbconf_setparm(service, param, value_str);
+ if (!libnet_conf_share_exists(service)) {
+ werr = libnet_conf_create_share(service);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_fprintf(stderr, "Error creating share '%s': %s\n",
+ service, dos_errstr(werr));
+ goto done;
+ }
+ }
+
+ werr = libnet_conf_set_parameter(service, param, value_str);
if (!W_ERROR_IS_OK(werr)) {
d_fprintf(stderr, "Error setting value '%s': %s\n",
@@ -730,7 +765,7 @@ static int net_conf_getparm(int argc, const char **argv)
service = strdup_lower(argv[0]);
param = strdup_lower(argv[1]);
- werr = libnet_smbconf_getparm(ctx, service, param, &valstr);
+ werr = libnet_conf_get_parameter(ctx, service, param, &valstr);
if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
d_fprintf(stderr,
@@ -772,7 +807,7 @@ static int net_conf_delparm(int argc, const char **argv)
service = strdup_lower(argv[0]);
param = strdup_lower(argv[1]);
- werr = libnet_smbconf_delparm(service, param);
+ werr = libnet_conf_delete_parameter(service, param);
if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
d_fprintf(stderr,
@@ -811,15 +846,15 @@ int net_conf(int argc, const char **argv)
{"import", net_conf_import,
"Import configuration from file in smb.conf format."},
{"listshares", net_conf_listshares,
- "List the registry shares."},
+ "List the share names."},
{"drop", net_conf_drop,
- "Delete the complete configuration from registry."},
+ "Delete the complete configuration."},
{"showshare", net_conf_showshare,
- "Show the definition of a registry share."},
+ "Show the definition of a share."},
{"addshare", net_conf_addshare,
- "Create a new registry share."},
+ "Create a new share."},
{"delshare", net_conf_delshare,
- "Delete a registry share."},
+ "Delete a share."},
{"setparm", net_conf_setparm,
"Store a parameter."},
{"getparm", net_conf_getparm,
@@ -829,16 +864,8 @@ int net_conf(int argc, const char **argv)
{NULL, NULL, NULL}
};
- if (!registry_init_regdb()) {
- d_fprintf(stderr, "Error initializing the registry!\n");
- goto done;
- }
-
ret = net_run_function2(argc, argv, "net conf", func);
- regdb_close();
-
-done:
return ret;
}
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 958f8e255e..ef4254ead2 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -840,7 +840,7 @@ static struct cli_state *connect_one(const char *server, const char *share)
get_cmdline_auth_info_username(),
lp_workgroup(),
get_cmdline_auth_info_password(),
- 0,
+ get_cmdline_auth_info_use_kerberos() ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
get_cmdline_auth_info_signing_state(),
NULL))) {
return c;
diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c
index 912d575c60..8db969722a 100644
--- a/source3/utils/smbfilter.c
+++ b/source3/utils/smbfilter.c
@@ -114,6 +114,30 @@ static void filter_request(char *buf)
}
+/****************************************************************************
+ Send an smb to a fd.
+****************************************************************************/
+
+static bool send_smb(int fd, char *buffer)
+{
+ size_t len;
+ size_t nwritten=0;
+ ssize_t ret;
+
+ len = smb_len(buffer) + 4;
+
+ while (nwritten < len) {
+ ret = write_data(fd,buffer+nwritten,len - nwritten);
+ if (ret <= 0) {
+ DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
+ (int)len,(int)ret, strerror(errno) ));
+ return false;
+ }
+ nwritten += ret;
+ }
+
+ return true;
+}
static void filter_child(int c, struct sockaddr_storage *dest_ss)
{
@@ -145,7 +169,7 @@ static void filter_child(int c, struct sockaddr_storage *dest_ss)
if (num <= 0) continue;
if (c != -1 && FD_ISSET(c, &fds)) {
- if (!receive_smb(c, packet, 0, NULL)) {
+ if (!receive_smb_raw(c, packet, 0, 0, NULL)) {
d_printf("client closed connection\n");
exit(0);
}
@@ -156,7 +180,7 @@ static void filter_child(int c, struct sockaddr_storage *dest_ss)
}
}
if (s != -1 && FD_ISSET(s, &fds)) {
- if (!receive_smb(s, packet, 0, NULL)) {
+ if (!receive_smb_raw(s, packet, 0, 0, NULL)) {
d_printf("server closed connection\n");
exit(0);
}
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index c9b2a52388..3aba824b0b 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -1270,12 +1270,24 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
d.domain_type = domains[i].trust_type;
d.domain_trust_attribs = domains[i].trust_attributes;
} else {
+ /* Look up the record in the cache */
+ struct winbindd_tdc_domain *parent;
+
DEBUG(10,("trusted_domains(ads): Inheriting trust "
"flags for domain %s\n", d.alt_name));
+
+ parent = wcache_tdc_fetch_domain(NULL, domain->name);
+ if (parent) {
+ d.domain_flags = parent->trust_flags;
+ d.domain_type = parent->trust_type;
+ d.domain_trust_attribs = parent->trust_attribs;
+ } else {
d.domain_flags = domain->domain_flags;
d.domain_type = domain->domain_type;
d.domain_trust_attribs = domain->domain_trust_attribs;
}
+ TALLOC_FREE(parent);
+ }
wcache_tdc_add_domain( &d );
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 33674d2cf7..99e401d53f 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -601,8 +601,34 @@ static bool get_dc_name_via_netlogon(const struct winbindd_domain *domain,
orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
- werr = rpccli_netlogon_getanydcname(netlogon_pipe, mem_ctx, our_domain->dcname,
+ if (our_domain->active_directory) {
+ struct DS_DOMAIN_CONTROLLER_INFO *domain_info = NULL;
+
+ werr = rpccli_netlogon_dsr_getdcname(netlogon_pipe,
+ mem_ctx,
+ our_domain->dcname,
+ domain->name,
+ NULL,
+ NULL,
+ DS_RETURN_DNS_NAME,
+ &domain_info);
+ if (W_ERROR_IS_OK(werr)) {
+ fstrcpy(tmp, domain_info->domain_controller_name);
+ if (strlen(domain->alt_name) == 0) {
+ fstrcpy(domain->alt_name,
+ CONST_DISCARD(char*, domain_info->domain_name));
+ }
+ if (strlen(domain->forest_name) == 0) {
+ fstrcpy(domain->forest_name,
+ CONST_DISCARD(char*, domain_info->dns_forest_name));
+ }
+ }
+ } else {
+
+ werr = rpccli_netlogon_getanydcname(netlogon_pipe, mem_ctx,
+ our_domain->dcname,
domain->name, &tmp);
+ }
/* And restore our original timeout. */
cli_set_timeout(netlogon_pipe->cli, orig_timeout);
@@ -1869,9 +1895,17 @@ no_lsarpc_ds:
if (dns_name)
fstrcpy(domain->alt_name, dns_name);
- if ( forest_name )
+ /* See if we can set some domain trust flags about
+ ourself */
+
+ if ( forest_name ) {
fstrcpy(domain->forest_name, forest_name);
+ if (strequal(domain->forest_name, domain->alt_name)) {
+ domain->domain_flags = DS_DOMAIN_TREE_ROOT;
+ }
+ }
+
if (dom_sid)
sid_copy(&domain->sid, dom_sid);
} else {
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index fbd2fee692..62e8d1c40b 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -1494,9 +1494,18 @@ void winbindd_getgroups(struct winbindd_cli_state *state)
s->username = talloc_strdup( state->mem_ctx, state->request.data.username );
}
- /* Get info for the domain */
+ /* Get info for the domain (either by short domain name or
+ DNS name in the case of a UPN) */
s->domain = find_domain_from_name_noinit(s->domname);
+ if (!s->domain) {
+ char *p = strchr(s->username, '@');
+
+ if (p) {
+ s->domain = find_domain_from_name_noinit(p+1);
+ }
+
+ }
if (s->domain == NULL) {
DEBUG(7, ("could not find domain entry for domain %s\n",
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index ffb47692cb..f5e1226447 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -456,6 +456,12 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
+ if ( !winbindd_can_contact_domain( domain ) ) {
+ DEBUG(10,("query_user: No incoming trust for domain %s\n",
+ domain->name));
+ return NT_STATUS_OK;
+ }
+
/* no cache; hit the wire */
result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 70468b6bcd..cc12d4b7ea 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -500,9 +500,13 @@ void rescan_trusted_domains( void )
((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) )
return;
- /* clear the TRUSTDOM cache first */
-
- wcache_tdc_clear();
+ /* I use to clear the cache here and start over but that
+ caused problems in child processes that needed the
+ trust dom list early on. Removing it means we
+ could have some trusted domains listed that have been
+ removed from our primary domain's DC until a full
+ restart. This should be ok since I think this is what
+ Windows does as well. */
/* this will only add new domains we didn't already know about
in the domain_list()*/