Merge branch 'v3-2-test' of ssh://jra@git.samba.org/data/git/samba into v3-2-test
authorJeremy Allison <jra@samba.org>
Sat, 5 Jan 2008 03:06:37 +0000 (19:06 -0800)
committerJeremy Allison <jra@samba.org>
Sat, 5 Jan 2008 03:06:37 +0000 (19:06 -0800)
(This used to be commit 3a45f62310faf63cd6864d2cb10f941492eda818)

69 files changed:
.gitignore
source3/Makefile.in
source3/client/client.c
source3/configure.in
source3/include/ads_protos.h
source3/include/doserr.h
source3/include/memcache.h
source3/include/smb.h
source3/include/smb_macros.h
source3/lib/dummysmbd.c
source3/lib/netapi/examples/netdomjoin-gui/logo-small.png [new file with mode: 0644]
source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
source3/lib/netapi/examples/netdomjoin/netdomjoin.c
source3/lib/netapi/joindomain.c
source3/lib/netapi/serverinfo.c
source3/lib/util_reg_smbconf.c
source3/lib/util_sock.c
source3/lib/winbind_util.c
source3/libads/ldap.c
source3/libnet/libnet_conf.c
source3/libnet/libnet_join.c
source3/libnet/libnet_join.h
source3/libsmb/doserr.c
source3/libsmb/smb_seal.c
source3/libsmb/smb_signing.c
source3/libsmb/smbencrypt.c
source3/locking/locking.c
source3/nmbd/nmbd_packets.c
source3/nmbd/nmbd_responserecordsdb.c
source3/nsswitch/libwbclient/wbc_pam.c
source3/nsswitch/libwbclient/wbc_pwd.c
source3/nsswitch/libwbclient/wbc_sid.c
source3/nsswitch/libwbclient/wbc_util.c
source3/nsswitch/libwbclient/wbclient.h
source3/param/loadparm.c
source3/passdb/pdb_ldap.c
source3/printing/nt_printing.c
source3/registry/reg_api.c
source3/registry/reg_cachehook.c
source3/registry/reg_db.c
source3/script/tests/test_smbclient_s3.sh
source3/script/tests/test_smbtorture_s3.sh
source3/script/tests/tests_all.sh
source3/smbd/aio.c
source3/smbd/blocking.c
source3/smbd/error.c
source3/smbd/ipc.c
source3/smbd/lanman.c
source3/smbd/message.c
source3/smbd/negprot.c
source3/smbd/notify.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/oplock.c
source3/smbd/pipes.c
source3/smbd/process.c
source3/smbd/reply.c
source3/smbd/seal.c
source3/smbd/sesssetup.c
source3/smbd/trans2.c
source3/torture/torture.c
source3/utils/net_conf.c
source3/utils/smbcacls.c
source3/utils/smbfilter.c
source3/winbindd/winbindd_ads.c
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_group.c
source3/winbindd/winbindd_rpc.c
source3/winbindd/winbindd_util.c

index d3266edbbedb144f51c21b61adbdf8930451ca7a..00ad9c82c0ba9d446920322eebb14f5575b18075 100644 (file)
@@ -34,3 +34,4 @@ source/proto_exists
 source/winbindd/winbindd_proto.h
 source/cscope.out
 source/torture.tdb
+source/pkgconfig/*.pc
index 01f2988b8803edd342a402b060f5dc80d029c461..2267be4680d44e478bf9b8552ae99b39e4ecdca4 100644 (file)
@@ -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) "
index 6c00638eb9b9781afb1d39a0621fc1fc12adfdb5..a5e4a3863aeb85c69d14df019153914f1969b2da 100644 (file)
@@ -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;
        }
 
index d7fde01619ad93ea2d93fcfe543b5cea03cf191d..934a99462bd61da1419a22423b62b94d5653e185 100644 (file)
@@ -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)
index 0292d91f4f0c64b852a01ddf1a61747da7312005..738df3ed40cabbf99688bc8327927ed3cfab8489 100644 (file)
@@ -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);
index 079a5664dd5a86608d3beb5e36ef692543d173ac..08f5b3e39dc7e43a76af584aab2d68de0542bc6b 100644 (file)
 #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)
index 5a0ce63cb76c8d75cab1efbdabe69fd8da25706f..0a596b91a52b2bb2acb70c7c35659655bdce37cd 100644 (file)
@@ -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
 
 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
index aca0009688671f760d742b068dd82ad6d5cf9acf..49245eaa8302c5ce65d7aba832fa22762cdbec94 100644 (file)
@@ -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;
 };
index 9bacdce1db7d8ea817d52c997caa809823c7007a..3324f3fc02de6891fe6a7559c4153af266cefe80 100644 (file)
 #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__)
 #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
index 464ba9230636b55c06669cebd67dfb7e64b13248..dbe886e3d130c776753a41fbd93405621d0a4e52 100644 (file)
@@ -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 (file)
index 0000000..f041198
Binary files /dev/null and b/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png differ
index beb12be8b1d95214f002cea1bf4eaedd17736a62..d12e66bb26372a924bc441498ee6a8aa7a2ff966 100644 (file)
@@ -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);
index e8b529927ff48fe100f3d34c877b175ff666568e..634d265597236b126033250b70a9d1dea02c6002 100644 (file)
@@ -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,
index e3d5eada0277271c6a681030e913167f6ff29818..c7849c952fac366716070484c7352e527c38a2d5 100644 (file)
@@ -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,
index 27c7c4b2fce3a80ac205677ec8db51047ac24ca2..0e356e0ee7c07cfb2083aacc79f4e5dbb2fd4151 100644 (file)
@@ -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,
index 154c67ab8fd52411a206c0106febfb44a2963c80..fa58f28d034e93b9d1bb7b88936c1ec98acfb115 100644 (file)
@@ -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;
index d16a8f079a0c3d95c3017da0175646f6afb637f7..945506ea7776a0fe9e4d252d758e342db4e2d04f 100644 (file)
@@ -1276,80 +1276,6 @@ ssize_t receive_smb_raw(int fd,
        return len;
 }
 
-/****************************************************************************
- 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;
 }
 
 /************************************************************
index f51a0171a23998e4b1f6950cd94cd536c5e729a3..3cf068a6e0da11d812a89c4f3954ce066f960e90 100644 (file)
@@ -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 */
index 953693ce48972ca4fb7901afcd3635bb37b1ac6a..975e9268649a7f866217000ae648e02c42e08465 100644 (file)
@@ -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)) {
@@ -2790,6 +2797,66 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix
        return status;
 }
 
+/**
+ * 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 
index 1069abcfbdff8e5e9aa2615d825ddcc751bfaeef..c8e55a70b277fdd32c45c4e472dd7f6bae470917 100644 (file)
@@ -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
 #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)
 /**
  * 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;
                }
@@ -584,24 +623,65 @@ done:
        return werr;
 }
 
+/**
+ * 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);
 }
 
index 6edcdb89457d8fd6505d5bf84c2f4b3e4ad1cc98..95b643ffa6805b873cc2d26e4a59c81a70775354 100644 (file)
@@ -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
 #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);
index 46ab27e8b0f94261029f14ac351edd930c5b3fab..9e7b8a9813bf022c9cabb0dd18f34b760b5e7f26 100644 (file)
@@ -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
 
 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;
index dd556bba5aade5b82776dfd3a105aae280513097..79445a241057e1a683f4fe0c7bd7bbeaa9e53b4a 100644 (file)
@@ -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" },
 };
 
 /*****************************************************************************
index 055a27d05af546c49d479458e09bc037f1f00f99..b5befbf7cdcecba0e7adc2fd83adf28f781927a2 100644 (file)
  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;
        }
 
index d5cbe3b12535aec2eb323184b30c83a7546fb10b..f03c21bd0e0c59e6a569c8afaebb0b257ed29354 100644 (file)
@@ -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;
        }
 
index 9e37d1d6cfa4b98b822559471b4ac1ceacb01796..d7f6f604f7f42e2605daba1ddde0a2a823168825 100644 (file)
@@ -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,
index dab21e53b3b5366fb73799bd71dff28635ccd8f6..270c6d22610a092ed8d6e087da429c795790c25c 100644 (file)
@@ -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)) {
index 3bb151420343fbf3a5114bea0681125d27b5797a..c1d373aa189038af44a036c8eb70b70381138ba4 100644 (file)
@@ -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 */
index 22a038ef2ea8496b2a98fd835219ae4695329a98..6498ce04cf32485c389092fdfde7626a66e2bf6a 100644 (file)
@@ -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) {
index 1548c3344ac09bcca48bf3b906b0293b8d0bc388..7f7c7b814030bbfed373e2c1d6b18f2413a80151 100644 (file)
@@ -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;
 }
index 4e3b0d396764e89c3218102ec9ee47af84cb9a24..b24e198bc5cdaba7d7c70d3c51db0dda28105eeb 100644 (file)
@@ -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:
index c877e1d9d4df1359b7e762428ea143cf3b167195..abe1457cc1483d7a205648b02e8c3462a2eaa057 100644 (file)
@@ -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;
        }
index c6acb27e558e67ef14ee8107f548810d1a68bf5a..ff3cec8689d9568a083cb1fe4d4d2ceaf49b0891 100644 (file)
@@ -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:
index 2867aad69e7c4fc6aab1384c23a714f325badcb2..6b85d7e8b30c86fd1ca0511e44b5eaeee727ac9a 100644 (file)
@@ -177,7 +177,7 @@ wbcErr wbcDomainSequenceNumbers(void);
  * Athenticate functions
  */
 
-wbcErr wbcAuthenticateUser(const char *username, 
+wbcErr wbcAuthenticateUser(const char *username,
                           const char *password);
 
 
index 16e937200983ef6110d816da9925482cdbd9673b..29166cf02ece95602ce32717900ae319eef74174 100644 (file)
@@ -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());
 }
 
 /*******************************************************************
index b63821946695e7e7f900e7391654b7ca28d42631..205b178a93f8bae746e5f8a93e6ce25ed8b7f7cd 100644 (file)
@@ -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)));
index f115fba91f0245da66f2f83430a9c4a5ba57ca77..bae32e89f75a4edded53f52bc839ab8417f648dd 100644 (file)
@@ -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:
index bc4508ff94a27406ca8ca3f9c797aa8a4ff4e580..bb410e646b06a5ce008c11a2a5f182bcc2dcc291 100644 (file)
@@ -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;
        }
index 289d4e50cec788bfbc7d758d328ea31c73459808..74670aac30ec211c9b50bd1646cf3cdcc3fa2725 100644 (file)
 #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);
 }
 
 /**********************************************************************
index 25c6557c87ae339fff16f6489420137f0d0dfc85..f50a41816c114ff57b289de9e8058ceca3ef2e16 100644 (file)
@@ -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);
index fdade5a61739df3a8fa7fdb50d16e4ee397d643a..8bf9cd1ec425c38134e338334818e83edf26dffe 100755 (executable)
@@ -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
index f662eacd3ecf97f5674a80e66fb7cefb611178a0..acb641b9fbac8d56dc4c256009841b6c0b1537f8 100755 (executable)
@@ -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
index 109e9c292090e657997c5d7ed7595e5c179459a7..c9fd748296ce9c409f5925fa620e036c8ea7f94c 100755 (executable)
@@ -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"
index a439c3a4f0517c8871ef8306e80e74a38365393c..bc1761b0fdaded0c8615e00ab966010c82dbdb85 100644 (file)
@@ -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 "
index 0078bb7d13dd11226af0c513c6800539df01dede..41963166f7d119c60b7b70fc515c7715e16432d7 100644 (file)
@@ -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;
                }
        }
 }
index c669e741461536ec687629b4952c188c8fabbae7..de2de088ec222f30d0c7328bf628217173b49a77 100644 (file)
@@ -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;
 }
index f28016ccb3f3a34ace57bd0f47db1a0d374f4860..68a13d692f6189fb9b7a6b270767109175cdc574 100644 (file)
@@ -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;
index 3ab216c062acda94dd08dffc00bf8c88e5dc223b..5a6df1f13911dd98e8210b800061cd1e5ce8aa36 100644 (file)
@@ -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);
        }
 
index d0b524da0e65adbb39aa70f2d3fcbf11606d6feb..a870f03df98c945add02c81ba3b13b15292e3adb 100644 (file)
@@ -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);
 
index 02f752fd679a74cfd5729491dafc7b723af3b5b8..9f56949eeb2f765caf9b8f2eaeb8c4c5a9f8ba24 100644 (file)
@@ -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;
index baab48f77ef4713865bc7b27a003c9c77abc122d..72872108029b5e1a4acac15a88ac1ad524a202d5 100644 (file)
@@ -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);
 
index 69772b6becc6148e0d208194d3fa2e8e3377eeb6..a51f3afd82749715a109677990368fc0f14c4ee5 100644 (file)
@@ -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;
 
index d3ba9e076c651b24e49563a2d6834ee37c9f0ef2..e3fae02b83291d6892380cf7cbef87e82dd7df2d 100644 (file)
@@ -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;
                }
 
index 8a5b1f4ecd5397d95a6a844212d6db84d1ffc017..277e07c178e83f87f09e772f746b80c38710b927 100644 (file)
@@ -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. */
index 88b67c03e57aa658d6248df315b0c85e6a5b60ff..6b4b83d97dd446006a2c5598a426d403f8eba189 100644 (file)
@@ -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));
index 48a6d18bc92c6432c909079536b8b8e1824c5699..fe32d57ff7ccada3cddfc30e4249df99bab99d9d 100644 (file)
@@ -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);
 
index 2707aee9c821b15d2a3c7e339aee7b6bc309879d..d5e683ca3cbf85153970d8be4b79bb44037e8238 100644 (file)
@@ -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;
index 24ecb77fd5985515643a9109458785a637e24035..21fca73feaede3c3e5fbe795264ad5dd17e791f5 100644 (file)
@@ -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;
 }
 
index 8ca012ff248f6dacb032d85edbbfa80dc6822d2b..167682ede23f1020edc021198b01b73fac58bbca 100644 (file)
@@ -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;
        }
index 656925502b81c47f161f1fbc95c8b811354d37ba..c3b5f9fa2f02d50ea13f4a96a7393d56d2ba7721 100644 (file)
@@ -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);
- &nbs