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