summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in13
-rw-r--r--source3/configure.in45
-rw-r--r--source3/include/proto.h5
-rw-r--r--source3/include/rpc_dce.h2
-rw-r--r--source3/librpc/rpc/dcerpc.h6
-rw-r--r--source3/librpc/rpc/dcerpc_helpers.c36
-rw-r--r--source3/librpc/rpc/rpc_common.c238
-rw-r--r--source3/modules/vfs_aio_fork.c5
-rw-r--r--source3/rpc_client/cli_pipe.c234
-rw-r--r--source3/rpc_client/cli_samr.c27
-rw-r--r--source3/rpc_server/rpc_server.h26
-rw-r--r--source3/rpc_server/srv_pipe.c473
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c465
-rw-r--r--source3/smbd/aio.c29
-rw-r--r--source3/smbd/sesssetup.c9
-rw-r--r--source3/smbd/smb2_sesssetup.c35
-rw-r--r--source3/utils/net_dns.c10
-rw-r--r--source3/winbindd/winbindd_dual.c8
-rw-r--r--source3/wscript_build12
19 files changed, 893 insertions, 785 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 9676b37927..26879c4412 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -334,6 +334,9 @@ LIBNDR_NTPRINTING_OBJ = librpc/gen_ndr/ndr_ntprinting.o \
LIBNDR_PREG_OBJ = librpc/gen_ndr/ndr_preg.o \
librpc/ndr/ndr_preg.o
+LIBNDR_XATTR_OBJ = librpc/gen_ndr/ndr_xattr.o \
+ ../librpc/ndr/ndr_xattr.o
+
LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \
$(LIBNDR_GEN_OBJ0) \
librpc/gen_ndr/ndr_dfs.o \
@@ -345,8 +348,7 @@ LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \
$(LIBNDR_NETLOGON_OBJ) \
librpc/gen_ndr/ndr_dssetup.o \
librpc/gen_ndr/ndr_notify.o \
- librpc/gen_ndr/ndr_xattr.o \
- ../librpc/ndr/ndr_xattr.o \
+ $(LIBNDR_XATTR_OBJ) \
librpc/gen_ndr/ndr_epmapper.o \
librpc/gen_ndr/ndr_named_pipe_auth.o \
librpc/gen_ndr/ndr_ntsvcs.o \
@@ -673,8 +675,10 @@ RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ) $(NPA_TSTREAM_OBJ)
RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2)
-RPC_CLIENT_OBJ = rpc_client/cli_pipe.o rpc_client/rpc_transport_np.o \
- rpc_client/rpc_transport_sock.o rpc_client/rpc_transport_smbd.o
+RPC_CLIENT_OBJ = rpc_client/cli_pipe.o librpc/rpc/rpc_common.o \
+ rpc_client/rpc_transport_np.o \
+ rpc_client/rpc_transport_sock.o \
+ rpc_client/rpc_transport_smbd.o
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
@@ -1341,6 +1345,7 @@ RPC_OPEN_TCP_OBJ = torture/rpc_open_tcp.o \
$(KRBCLIENT_OBJ) \
$(RPC_PARSE_OBJ2) \
$(RPC_CLIENT_OBJ1) \
+ librpc/rpc/rpc_common.o \
rpc_client/cli_pipe.o \
../librpc/rpc/binding.o \
$(LIBMSRPC_GEN_OBJ)
diff --git a/source3/configure.in b/source3/configure.in
index 4c17e4c928..43119fb246 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -1799,39 +1799,6 @@ fi
AC_MSG_RESULT($BLDSHARED)
-saved_before_as_needed_ldflags="$LDFLAGS"
-for flags in "-Wl,--as-needed" "-Wl,-z,ignore" "-z ignore" ; do
- saved_ldflags="$LDFLAGS"
- AC_MSG_CHECKING([if $flags works])
- LDFLAGS="$flags $saved_ldflags"
- AC_TRY_LINK([],[],
- [AC_MSG_RESULT([yes])
- LD_AS_NEEDED_FLAG=$flags
- ld_as_needed_flag_found=yes],
- AC_MSG_RESULT([no]))
- LDFLAGS="$LD_AS_NEEDED_FLAG $saved_ldflags"
- test x"$ld_as_needed_flag_found" = xyes && break
-done
-
-# check if we have to disable LD_AS_NEEDED_FLAG:
-# On some systems for a veriety of reasons linking with
-# -Wl,--as-needed -lreadline -lncurses fails
-# we have to retest, if these combination is detected before.
-# Bugzilla #7209
-
-if test x$ac_cv_lib_readline_rl_callback_handler_install = xyes ; then
- if test x$ld_as_needed_flag_found = xyes ; then
- AC_MSG_CHECKING([if $LD_AS_NEEDED_FLAG works with readline])
- # try if check no fails
- save_LIBS=$LIBS
- LIBS="$LIBS $TERMLIBS"
- AC_TRY_LINK([], [rl_callback_handler_install();], [AC_MSG_RESULT([yes])],[ AC_MSG_RESULT([no]); LDFLAGS="$saved_before_as_needed_ldflags"])
- LIBS="$save_LIBS"
- fi
-fi
-
-
-
# for historical reasons almost all linkers don't complain about unresolved
# symbols in shared libs. Except for the internal samba modules we want to get
# errors when we produce a shared lib with unresolved symbols. On some
@@ -6855,17 +6822,7 @@ if test -f Makefile-noincludes -a ! -f Makefile -a ! -h Makefile ; then
fi
])
-AC_SUBST(MAKEFILE)
-if test x$samba_cv_gnu_make = xyes; then
- MAKEFILE=Makefile
-else
- # When we don't have GNU Make, generate a copy of Makefile.in
- # that doesn't have the "include " statements but just includes
- # the files verbatim.
- MAKEFILE=Makefile-noincludes
- $PERL ./script/expand-includes.pl Makefile.in > $MAKEFILE.in
-fi
-AC_OUTPUT($MAKEFILE
+AC_OUTPUT(Makefile
script/findsmb smbadduser script/gen-8bit-gap.sh script/installbin.sh script/uninstallbin.sh
lib/netapi/examples/Makefile
lib/netapi/tests/Makefile
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ad16e7e52f..9471f63195 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2937,6 +2937,7 @@ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code);
void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v);
uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob);
void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v);
+uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob);
NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt,
TALLOC_CTX *mem_ctx,
DATA_BLOB *pkt_auth_blob,
@@ -6166,6 +6167,10 @@ int sessionid_traverse_read(int (*fn)(const char *key,
/* The following definitions come from smbd/sesssetup.c */
+NTSTATUS do_map_to_guest(NTSTATUS status,
+ struct auth_serversupplied_info **server_info,
+ const char *user, const char *domain);
+
NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in,
DATA_BLOB *pblob_out,
char **kerb_mechOID);
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
index 7be8a8a6f7..2cc770e11c 100644
--- a/source3/include/rpc_dce.h
+++ b/source3/include/rpc_dce.h
@@ -22,8 +22,6 @@
#ifndef _DCE_RPC_H /* _DCE_RPC_H */
#define _DCE_RPC_H
-#define SCHANNEL_SIG_SIZE 0x20
-
/* Maximum size of the signing data in a fragment. */
#define RPC_MAX_SIGN_SIZE 0x38 /* 56 */
diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
index d18920ca0d..bb7bd34de8 100644
--- a/source3/librpc/rpc/dcerpc.h
+++ b/source3/librpc/rpc/dcerpc.h
@@ -123,7 +123,8 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
DATA_BLOB *blob);
NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
const DATA_BLOB *blob,
- struct ncacn_packet *r);
+ struct ncacn_packet *r,
+ bool bigendian);
NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
struct NL_AUTH_MESSAGE *r,
DATA_BLOB *blob);
@@ -136,6 +137,7 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
DATA_BLOB *blob);
NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
const DATA_BLOB *blob,
- struct dcerpc_auth *r);
+ struct dcerpc_auth *r,
+ bool bigendian);
#endif /* __DCERPC_H__ */
diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
index ce48a691ac..5c92a792e9 100644
--- a/source3/librpc/rpc/dcerpc_helpers.c
+++ b/source3/librpc/rpc/dcerpc_helpers.c
@@ -92,15 +92,27 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
*/
NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
const DATA_BLOB *blob,
- struct ncacn_packet *r)
+ struct ncacn_packet *r,
+ bool bigendian)
{
enum ndr_err_code ndr_err;
+ struct ndr_pull *ndr;
+
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (bigendian) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, r);
- ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
- (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ talloc_free(ndr);
return ndr_map_error2ntstatus(ndr_err);
}
+ talloc_free(ndr);
if (DEBUGLEVEL >= 10) {
NDR_PRINT_DEBUG(ncacn_packet, r);
@@ -194,15 +206,27 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
*/
NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
const DATA_BLOB *blob,
- struct dcerpc_auth *r)
+ struct dcerpc_auth *r,
+ bool bigendian)
{
enum ndr_err_code ndr_err;
+ struct ndr_pull *ndr;
+
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (bigendian) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r);
- ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
- (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ talloc_free(ndr);
return ndr_map_error2ntstatus(ndr_err);
}
+ talloc_free(ndr);
if (DEBUGLEVEL >= 10) {
NDR_PRINT_DEBUG(dcerpc_auth, r);
diff --git a/source3/librpc/rpc/rpc_common.c b/source3/librpc/rpc/rpc_common.c
new file mode 100644
index 0000000000..78b88f7e33
--- /dev/null
+++ b/source3/librpc/rpc/rpc_common.c
@@ -0,0 +1,238 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Largely rewritten by Jeremy Allison 2005.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "../librpc/gen_ndr/ndr_schannel.h"
+#include "../librpc/gen_ndr/ndr_lsa.h"
+#include "../librpc/gen_ndr/ndr_dssetup.h"
+#include "../librpc/gen_ndr/ndr_samr.h"
+#include "../librpc/gen_ndr/ndr_netlogon.h"
+#include "../librpc/gen_ndr/ndr_srvsvc.h"
+#include "../librpc/gen_ndr/ndr_wkssvc.h"
+#include "../librpc/gen_ndr/ndr_winreg.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
+#include "../librpc/gen_ndr/ndr_dfs.h"
+#include "../librpc/gen_ndr/ndr_echo.h"
+#include "../librpc/gen_ndr/ndr_initshutdown.h"
+#include "../librpc/gen_ndr/ndr_svcctl.h"
+#include "../librpc/gen_ndr/ndr_eventlog.h"
+#include "../librpc/gen_ndr/ndr_ntsvcs.h"
+#include "../librpc/gen_ndr/ndr_epmapper.h"
+#include "../librpc/gen_ndr/ndr_drsuapi.h"
+
+static const char *get_pipe_name_from_iface(
+ TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
+{
+ int i;
+ const struct ndr_interface_string_array *ep = interface->endpoints;
+ char *p;
+
+ for (i=0; i<ep->count; i++) {
+ if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
+ break;
+ }
+ }
+ if (i == ep->count) {
+ return NULL;
+ }
+
+ /*
+ * extract the pipe name without \\pipe from for example
+ * ncacn_np:[\\pipe\\epmapper]
+ */
+ p = strchr(ep->names[i]+15, ']');
+ if (p == NULL) {
+ return "PIPE";
+ }
+ return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
+}
+
+static const struct ndr_interface_table **interfaces;
+
+bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
+{
+ int num_interfaces = talloc_array_length(interfaces);
+ const struct ndr_interface_table **tmp;
+ int i;
+
+ for (i=0; i<num_interfaces; i++) {
+ if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
+ &interface->syntax_id)) {
+ return true;
+ }
+ }
+
+ tmp = talloc_realloc(NULL, interfaces,
+ const struct ndr_interface_table *,
+ num_interfaces + 1);
+ if (tmp == NULL) {
+ DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
+ return false;
+ }
+ interfaces = tmp;
+ interfaces[num_interfaces] = interface;
+ return true;
+}
+
+static bool initialize_interfaces(void)
+{
+ if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_samr)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_winreg)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
+ return false;
+ }
+ if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
+ return false;
+ }
+ return true;
+}
+
+const struct ndr_interface_table *get_iface_from_syntax(
+ const struct ndr_syntax_id *syntax)
+{
+ int num_interfaces;
+ int i;
+
+ if (interfaces == NULL) {
+ if (!initialize_interfaces()) {
+ return NULL;
+ }
+ }
+ num_interfaces = talloc_array_length(interfaces);
+
+ for (i=0; i<num_interfaces; i++) {
+ if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
+ return interfaces[i];
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ Return the pipe name from the interface.
+ ****************************************************************************/
+
+const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
+ const struct ndr_syntax_id *syntax)
+{
+ const struct ndr_interface_table *interface;
+ char *guid_str;
+ const char *result;
+
+ interface = get_iface_from_syntax(syntax);
+ if (interface != NULL) {
+ result = get_pipe_name_from_iface(mem_ctx, interface);
+ if (result != NULL) {
+ return result;
+ }
+ }
+
+ /*
+ * Here we should ask \\epmapper, but for now our code is only
+ * interested in the known pipes mentioned in pipe_names[]
+ */
+
+ guid_str = GUID_string(talloc_tos(), &syntax->uuid);
+ if (guid_str == NULL) {
+ return NULL;
+ }
+ result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
+ (int)syntax->if_version);
+ TALLOC_FREE(guid_str);
+
+ if (result == NULL) {
+ return "PIPE";
+ }
+ return result;
+}
+
+/********************************************************************
+ Map internal value to wire value.
+ ********************************************************************/
+
+enum dcerpc_AuthType map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
+{
+ switch (auth_type) {
+
+ case PIPE_AUTH_TYPE_NONE:
+ return DCERPC_AUTH_TYPE_NONE;
+
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ return DCERPC_AUTH_TYPE_NTLMSSP;
+
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ case PIPE_AUTH_TYPE_SPNEGO_KRB5:
+ return DCERPC_AUTH_TYPE_SPNEGO;
+
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ return DCERPC_AUTH_TYPE_SCHANNEL;
+
+ case PIPE_AUTH_TYPE_KRB5:
+ return DCERPC_AUTH_TYPE_KRB5;
+
+ default:
+ DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
+ "auth type %u\n",
+ (unsigned int)auth_type ));
+ break;
+ }
+ return -1;
+}
+
diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c
index b43aad2df4..02b1394216 100644
--- a/source3/modules/vfs_aio_fork.c
+++ b/source3/modules/vfs_aio_fork.c
@@ -765,10 +765,11 @@ static int aio_fork_suspend(struct vfs_handle_struct *handle,
}
if (timeout) {
- struct timeval tv;
+ struct timeval tv = convert_timespec_to_timeval(*timeout);
struct tevent_timer *te = tevent_add_timer(ev,
frame,
- timeval_current_ofs(tv.tv_sec,0),
+ timeval_current_ofs(tv.tv_sec,
+ tv.tv_usec),
aio_fork_suspend_timed_out,
&timed_out);
if (!te) {
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index c90e06095c..a61200a104 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -20,22 +20,8 @@
#include "includes.h"
#include "librpc/gen_ndr/cli_epmapper.h"
#include "../librpc/gen_ndr/ndr_schannel.h"
-#include "../librpc/gen_ndr/ndr_lsa.h"
#include "../librpc/gen_ndr/ndr_dssetup.h"
-#include "../librpc/gen_ndr/ndr_samr.h"
#include "../librpc/gen_ndr/ndr_netlogon.h"
-#include "../librpc/gen_ndr/ndr_srvsvc.h"
-#include "../librpc/gen_ndr/ndr_wkssvc.h"
-#include "../librpc/gen_ndr/ndr_winreg.h"
-#include "../librpc/gen_ndr/ndr_spoolss.h"
-#include "../librpc/gen_ndr/ndr_dfs.h"
-#include "../librpc/gen_ndr/ndr_echo.h"
-#include "../librpc/gen_ndr/ndr_initshutdown.h"
-#include "../librpc/gen_ndr/ndr_svcctl.h"
-#include "../librpc/gen_ndr/ndr_eventlog.h"
-#include "../librpc/gen_ndr/ndr_ntsvcs.h"
-#include "../librpc/gen_ndr/ndr_epmapper.h"
-#include "../librpc/gen_ndr/ndr_drsuapi.h"
#include "../libcli/auth/schannel.h"
#include "../libcli/auth/spnego.h"
#include "smb_krb5.h"
@@ -47,206 +33,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_CLI
-static const char *get_pipe_name_from_iface(
- TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
-{
- int i;
- const struct ndr_interface_string_array *ep = interface->endpoints;
- char *p;
-
- for (i=0; i<ep->count; i++) {
- if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
- break;
- }
- }
- if (i == ep->count) {
- return NULL;
- }
-
- /*
- * extract the pipe name without \\pipe from for example
- * ncacn_np:[\\pipe\\epmapper]
- */
- p = strchr(ep->names[i]+15, ']');
- if (p == NULL) {
- return "PIPE";
- }
- return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
-}
-
-static const struct ndr_interface_table **interfaces;
-
-bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
-{
- int num_interfaces = talloc_array_length(interfaces);
- const struct ndr_interface_table **tmp;
- int i;
-
- for (i=0; i<num_interfaces; i++) {
- if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
- &interface->syntax_id)) {
- return true;
- }
- }
-
- tmp = talloc_realloc(NULL, interfaces,
- const struct ndr_interface_table *,
- num_interfaces + 1);
- if (tmp == NULL) {
- DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
- return false;
- }
- interfaces = tmp;
- interfaces[num_interfaces] = interface;
- return true;
-}
-
-static bool initialize_interfaces(void)
-{
- if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_samr)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_winreg)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
- return false;
- }
- if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
- return false;
- }
- return true;
-}
-
-const struct ndr_interface_table *get_iface_from_syntax(
- const struct ndr_syntax_id *syntax)
-{
- int num_interfaces;
- int i;
-
- if (interfaces == NULL) {
- if (!initialize_interfaces()) {
- return NULL;
- }
- }
- num_interfaces = talloc_array_length(interfaces);
-
- for (i=0; i<num_interfaces; i++) {
- if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
- return interfaces[i];
- }
- }
-
- return NULL;
-}
-
-/****************************************************************************
- Return the pipe name from the interface.
- ****************************************************************************/
-
-const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
- const struct ndr_syntax_id *syntax)
-{
- const struct ndr_interface_table *interface;
- char *guid_str;
- const char *result;
-
- interface = get_iface_from_syntax(syntax);
- if (interface != NULL) {
- result = get_pipe_name_from_iface(mem_ctx, interface);
- if (result != NULL) {
- return result;
- }
- }
-
- /*
- * Here we should ask \\epmapper, but for now our code is only
- * interested in the known pipes mentioned in pipe_names[]
- */
-
- guid_str = GUID_string(talloc_tos(), &syntax->uuid);
- if (guid_str == NULL) {
- return NULL;
- }
- result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
- (int)syntax->if_version);
- TALLOC_FREE(guid_str);
-
- if (result == NULL) {
- return "PIPE";
- }
- return result;
-}
-
-/********************************************************************
- Map internal value to wire value.
- ********************************************************************/
-
-enum dcerpc_AuthType map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
-{
- switch (auth_type) {
-
- case PIPE_AUTH_TYPE_NONE:
- return DCERPC_AUTH_TYPE_NONE;
-
- case PIPE_AUTH_TYPE_NTLMSSP:
- return DCERPC_AUTH_TYPE_NTLMSSP;
-
- case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
- case PIPE_AUTH_TYPE_SPNEGO_KRB5:
- return DCERPC_AUTH_TYPE_SPNEGO;
-
- case PIPE_AUTH_TYPE_SCHANNEL:
- return DCERPC_AUTH_TYPE_SCHANNEL;
-
- case PIPE_AUTH_TYPE_KRB5:
- return DCERPC_AUTH_TYPE_KRB5;
-
- default:
- DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
- "auth type %u\n",
- (unsigned int)auth_type ));
- break;
- }
- return -1;
-}
-
/********************************************************************
Pipe description for a DEBUG
********************************************************************/
@@ -619,7 +405,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
DCERPC_AUTH_TRAILER_LENGTH
+ pkt->auth_length);
- status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
+ status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info, false);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
return status;
@@ -722,7 +508,7 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
return NT_STATUS_OK;
}
- if (pkt->auth_length < SCHANNEL_SIG_SIZE) {
+ if (pkt->auth_length < NL_AUTH_SIGNATURE_SIZE) {
DEBUG(0, ("auth_len %u.\n", (unsigned int)pkt->auth_length));
return NT_STATUS_INVALID_PARAMETER;
}
@@ -749,7 +535,7 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
+ pkt->auth_length);
- status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
+ status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info, false);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
return status;
@@ -915,7 +701,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
NTSTATUS ret = NT_STATUS_OK;
uint8 ss_padding_len = 0;
- ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt);
+ ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
if (!NT_STATUS_IS_OK(ret)) {
return ret;
}
@@ -976,7 +762,9 @@ static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
}
DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
- pdu->length, rdata->length, ss_padding_len));
+ (long unsigned int)pdu->length,
+ (long unsigned int)rdata->length,
+ (unsigned int)ss_padding_len));
/*
* If this is the first reply, and the allocation hint is
@@ -1991,7 +1779,7 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
*p_auth_len = NTLMSSP_SIG_SIZE;
break;
case PIPE_AUTH_TYPE_SCHANNEL:
- *p_auth_len = SCHANNEL_SIG_SIZE;
+ *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
break;
default:
smb_panic("bad auth type");
@@ -2612,7 +2400,7 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
status = dcerpc_pull_dcerpc_auth(talloc_tos(),
&r->u.bind_ack.auth_info,
- &auth);
+ &auth, false);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
nt_errstr(status)));
@@ -2694,7 +2482,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
DCERPC_AUTH_TRAILER_LENGTH
+ r->auth_length);
- status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
+ status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info, false);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
return status;
@@ -2778,7 +2566,7 @@ static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
status = dcerpc_pull_dcerpc_auth(pkt,
&pkt->u.alter_resp.auth_info,
- &auth);
+ &auth, false);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index 8c92ebb059..8c1011293a 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -165,10 +165,29 @@ NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
init_lsa_String(&server, cli->srv_name_slash);
init_lsa_String(&account, username);
- memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
- memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
- memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
- memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
+ if (new_nt_password_blob.length > 0) {
+ memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
+ } else {
+ ZERO_STRUCT(new_nt_password_blob);
+ }
+
+ if (new_lm_password_blob.length > 0) {
+ memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
+ } else {
+ ZERO_STRUCT(new_lm_password);
+ }
+
+ if (old_nt_hash_enc_blob.length > 0) {
+ memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
+ } else {
+ ZERO_STRUCT(old_nt_hash_enc);
+ }
+
+ if (old_lm_hash_enc_blob.length > 0) {
+ memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
+ } else {
+ ZERO_STRUCT(old_lm_hash_enc);
+ }
result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
&server,
diff --git a/source3/rpc_server/rpc_server.h b/source3/rpc_server/rpc_server.h
new file mode 100644
index 0000000000..f212773f4d
--- /dev/null
+++ b/source3/rpc_server/rpc_server.h
@@ -0,0 +1,26 @@
+/*
+ * RPC Pipe server helper headers
+ * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
+ * Copyright (C) Simo Sorce <idra@samba.org> - 2010
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _RPC_SERVER_H_
+#define _RPC_SERVER_H_
+
+void set_incoming_fault(pipes_struct *p);
+void process_complete_pdu(pipes_struct *p);
+
+#endif /* _PRC_SERVER_H_ */
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 6d37ec2bc2..a7a5f4d676 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -33,6 +33,7 @@
#include "../libcli/auth/schannel.h"
#include "../libcli/auth/spnego.h"
#include "../libcli/auth/ntlmssp.h"
+#include "rpc_server.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
@@ -427,7 +428,7 @@ bool create_next_pdu(pipes_struct *p)
case PIPE_AUTH_TYPE_SCHANNEL:
if (!create_next_packet(p, auth_type,
p->auth.auth_level,
- SCHANNEL_SIG_SIZE)) {
+ NL_AUTH_SIGNATURE_SIZE)) {
return false;
}
return add_schannel_auth(p);
@@ -568,7 +569,7 @@ bool api_pipe_bind_auth3(pipes_struct *p, struct ncacn_packet *pkt)
status = dcerpc_pull_dcerpc_auth(pkt,
&pkt->u.auth3.auth_info,
- &auth_info);
+ &auth_info, p->endian);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
goto err;
@@ -1303,7 +1304,7 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
*/
status = dcerpc_pull_dcerpc_auth(pkt,
&pkt->u.bind.auth_info,
- &auth_info);
+ &auth_info, p->endian);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
goto err_exit;
@@ -1524,7 +1525,7 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt)
status = dcerpc_pull_dcerpc_auth(pkt,
&pkt->u.bind.auth_info,
- &auth_info);
+ &auth_info, p->endian);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
goto err_exit;
@@ -1838,3 +1839,467 @@ static bool api_rpcTNP(pipes_struct *p, struct ncacn_packet *pkt,
return True;
}
+
+/****************************************************************************
+ Initialise an outgoing packet.
+****************************************************************************/
+
+static bool pipe_init_outgoing_data(pipes_struct *p)
+{
+ output_data *o_data = &p->out_data;
+
+ /* Reset the offset counters. */
+ o_data->data_sent_length = 0;
+ o_data->current_pdu_sent = 0;
+
+ data_blob_free(&o_data->frag);
+
+ /* Free any memory in the current return data buffer. */
+ data_blob_free(&o_data->rdata);
+
+ return True;
+}
+
+/****************************************************************************
+ Sets the fault state on incoming packets.
+****************************************************************************/
+
+void set_incoming_fault(pipes_struct *p)
+{
+ data_blob_free(&p->in_data.data);
+ p->in_data.pdu_needed_len = 0;
+ p->in_data.pdu.length = 0;
+ p->fault_state = True;
+ DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
+ get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
+}
+
+static bool dcesrv_auth_request(pipes_struct *p, struct ncacn_packet *pkt)
+{
+ NTSTATUS status;
+ size_t hdr_size = DCERPC_REQUEST_LENGTH;
+ struct dcerpc_auth auth;
+ uint32_t auth_length;
+ DATA_BLOB data;
+ DATA_BLOB full_pkt;
+
+ DEBUG(10, ("Checking request auth.\n"));
+
+ if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
+ hdr_size += 16;
+ }
+
+ switch (p->auth.auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ DEBUG(10, ("Requested Privacy.\n"));
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ DEBUG(10, ("Requested Integrity.\n"));
+ break;
+
+ case DCERPC_AUTH_LEVEL_CONNECT:
+ if (pkt->auth_length != 0) {
+ break;
+ }
+ return true;
+ case DCERPC_AUTH_LEVEL_NONE:
+ if (pkt->auth_length != 0) {
+ return false;
+ }
+ return true;
+
+ default:
+ return false;
+ }
+
+ status = dcerpc_pull_auth_trailer(pkt, pkt,
+ &pkt->u.request.stub_and_verifier,
+ &auth, &auth_length, false);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ pkt->u.request.stub_and_verifier.length -= auth_length;
+
+ data.data = p->in_data.pdu.data + hdr_size;
+ data.length = pkt->u.request.stub_and_verifier.length;
+ full_pkt.data = p->in_data.pdu.data;
+ full_pkt.length = p->in_data.pdu.length - auth.credentials.length;
+
+ switch (p->auth.auth_type) {
+ case PIPE_AUTH_TYPE_NONE:
+ return true;
+
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ case PIPE_AUTH_TYPE_NTLMSSP:
+
+ DEBUG(10, ("NTLMSSP auth\n"));
+
+ if (!p->auth.a_u.auth_ntlmssp_state) {
+ DEBUG(0, ("Invalid auth level, "
+ "failed to process packet auth.\n"));
+ return false;
+ }
+
+ switch (p->auth.auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ status = auth_ntlmssp_unseal_packet(
+ p->auth.a_u.auth_ntlmssp_state,
+ data.data, data.length,
+ full_pkt.data, full_pkt.length,
+ &auth.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+ memcpy(pkt->u.request.stub_and_verifier.data,
+ data.data, data.length);
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ status = auth_ntlmssp_check_packet(
+ p->auth.a_u.auth_ntlmssp_state,
+ data.data, data.length,
+ full_pkt.data, full_pkt.length,
+ &auth.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+ break;
+
+ default:
+ DEBUG(0, ("Invalid auth level, "
+ "failed to process packet auth.\n"));
+ return false;
+ }
+ break;
+
+ case PIPE_AUTH_TYPE_SCHANNEL:
+
+ DEBUG(10, ("SCHANNEL auth\n"));
+
+ switch (p->auth.auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ status = netsec_incoming_packet(
+ p->auth.a_u.schannel_auth,
+ pkt, true,
+ data.data, data.length,
+ &auth.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+ memcpy(pkt->u.request.stub_and_verifier.data,
+ data.data, data.length);
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ status = netsec_incoming_packet(
+ p->auth.a_u.schannel_auth,
+ pkt, false,
+ data.data, data.length,
+ &auth.credentials);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+ break;
+
+ default:
+ DEBUG(0, ("Invalid auth level, "
+ "failed to process packet auth.\n"));
+ return false;
+ }
+ break;
+
+ default:
+ DEBUG(0, ("process_request_pdu: "
+ "unknown auth type %u set.\n",
+ (unsigned int)p->auth.auth_type));
+ set_incoming_fault(p);
+ return false;
+ }
+
+ /* remove the indicated amount of padding */
+ if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) {
+ return false;
+ }
+ pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length;
+
+ return true;
+}
+
+/****************************************************************************
+ Processes a request pdu. This will do auth processing if needed, and
+ appends the data into the complete stream if the LAST flag is not set.
+****************************************************************************/
+
+static bool process_request_pdu(pipes_struct *p, struct ncacn_packet *pkt)
+{
+ DATA_BLOB data;
+
+ if (!p->pipe_bound) {
+ DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
+ set_incoming_fault(p);
+ return False;
+ }
+
+ /* Store the opnum */
+ p->opnum = pkt->u.request.opnum;
+
+ if (!dcesrv_auth_request(p, pkt)) {
+ DEBUG(0,("Failed to check packet auth.\n"));
+ set_incoming_fault(p);
+ return false;
+ }
+
+ data = pkt->u.request.stub_and_verifier;
+
+ /*
+ * Check the data length doesn't go over the 15Mb limit.
+ * increased after observing a bug in the Windows NT 4.0 SP6a
+ * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
+ * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
+ */
+
+ if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
+ DEBUG(0, ("process_request_pdu: "
+ "rpc data buffer too large (%u) + (%u)\n",
+ (unsigned int)p->in_data.data.length,
+ (unsigned int)data.length));
+ set_incoming_fault(p);
+ return False;
+ }
+
+ /*
+ * Append the data portion into the buffer and return.
+ */
+
+ if (data.length) {
+ if (!data_blob_append(p->mem_ctx, &p->in_data.data,
+ data.data, data.length)) {
+ DEBUG(0, ("Unable to append data size %u "
+ "to parse buffer of size %u.\n",
+ (unsigned int)data.length,
+ (unsigned int)p->in_data.data.length));
+ set_incoming_fault(p);
+ return False;
+ }
+ }
+
+ if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
+ bool ret = False;
+ /*
+ * Ok - we finally have a complete RPC stream.
+ * Call the rpc command to process it.
+ */
+
+ /*
+ * Process the complete data stream here.
+ */
+ if (pipe_init_outgoing_data(p)) {
+ ret = api_pipe_request(p, pkt);
+ }
+
+ return ret;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ Processes a finished PDU stored in p->in_data.pdu.
+****************************************************************************/
+
+void process_complete_pdu(pipes_struct *p)
+{
+ struct ncacn_packet *pkt = NULL;
+ NTSTATUS status;
+ bool reply = False;
+
+ if(p->fault_state) {
+ DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
+ get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
+ goto done;
+ }
+
+ pkt = talloc(p->mem_ctx, struct ncacn_packet);
+ if (!pkt) {
+ DEBUG(0, ("Out of memory!\n"));
+ goto done;
+ }
+
+ /*
+ * Ensure we're using the corrent endianness for both the
+ * RPC header flags and the raw data we will be reading from.
+ */
+ if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
+ p->endian = RPC_LITTLE_ENDIAN;
+ } else {
+ p->endian = RPC_BIG_ENDIAN;
+ }
+ DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
+
+ status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
+ pkt, p->endian);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
+ nt_errstr(status)));
+ goto done;
+ }
+
+ /* Store the call_id */
+ p->call_id = pkt->call_id;
+
+ DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
+
+ switch (pkt->ptype) {
+ case DCERPC_PKT_REQUEST:
+ reply = process_request_pdu(p, pkt);
+ break;
+
+ case DCERPC_PKT_PING: /* CL request - ignore... */
+ DEBUG(0, ("process_complete_pdu: Error. "
+ "Connectionless packet type %d received on "
+ "pipe %s.\n", (int)pkt->ptype,
+ get_pipe_name_from_syntax(talloc_tos(),
+ &p->syntax)));
+ break;
+
+ case DCERPC_PKT_RESPONSE: /* No responses here. */
+ DEBUG(0, ("process_complete_pdu: Error. "
+ "DCERPC_PKT_RESPONSE received from client "
+ "on pipe %s.\n",
+ get_pipe_name_from_syntax(talloc_tos(),
+ &p->syntax)));
+ break;
+
+ case DCERPC_PKT_FAULT:
+ case DCERPC_PKT_WORKING:
+ /* CL request - reply to a ping when a call in process. */
+ case DCERPC_PKT_NOCALL:
+ /* CL - server reply to a ping call. */
+ case DCERPC_PKT_REJECT:
+ case DCERPC_PKT_ACK:
+ case DCERPC_PKT_CL_CANCEL:
+ case DCERPC_PKT_FACK:
+ case DCERPC_PKT_CANCEL_ACK:
+ DEBUG(0, ("process_complete_pdu: Error. "
+ "Connectionless packet type %u received on "
+ "pipe %s.\n", (unsigned int)pkt->ptype,
+ get_pipe_name_from_syntax(talloc_tos(),
+ &p->syntax)));
+ break;
+
+ case DCERPC_PKT_BIND:
+ /*
+ * We assume that a pipe bind is only in one pdu.
+ */
+ if (pipe_init_outgoing_data(p)) {
+ reply = api_pipe_bind_req(p, pkt);
+ }
+ break;
+
+ case DCERPC_PKT_BIND_ACK:
+ case DCERPC_PKT_BIND_NAK:
+ DEBUG(0, ("process_complete_pdu: Error. "
+ "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
+ "packet type %u received on pipe %s.\n",
+ (unsigned int)pkt->ptype,
+ get_pipe_name_from_syntax(talloc_tos(),
+ &p->syntax)));
+ break;
+
+
+ case DCERPC_PKT_ALTER:
+ /*
+ * We assume that a pipe bind is only in one pdu.
+ */
+ if (pipe_init_outgoing_data(p)) {
+ reply = api_pipe_alter_context(p, pkt);
+ }
+ break;
+
+ case DCERPC_PKT_ALTER_RESP:
+ DEBUG(0, ("process_complete_pdu: Error. "
+ "DCERPC_PKT_ALTER_RESP on pipe %s: "
+ "Should only be server -> client.\n",
+ get_pipe_name_from_syntax(talloc_tos(),
+ &p->syntax)));
+ break;
+
+ case DCERPC_PKT_AUTH3:
+ /*
+ * The third packet in an NTLMSSP auth exchange.
+ */
+ if (pipe_init_outgoing_data(p)) {
+ reply = api_pipe_bind_auth3(p, pkt);
+ }
+ break;
+
+ case DCERPC_PKT_SHUTDOWN:
+ DEBUG(0, ("process_complete_pdu: Error. "
+ "DCERPC_PKT_SHUTDOWN on pipe %s: "
+ "Should only be server -> client.\n",
+ get_pipe_name_from_syntax(talloc_tos(),
+ &p->syntax)));
+ break;
+
+ case DCERPC_PKT_CO_CANCEL:
+ /* For now just free all client data and continue
+ * processing. */
+ DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
+ " Abandoning rpc call.\n"));
+ /* As we never do asynchronous RPC serving, we can
+ * never cancel a call (as far as I know).
+ * If we ever did we'd have to send a cancel_ack reply.
+ * For now, just free all client data and continue
+ * processing. */
+ reply = True;
+ break;
+
+#if 0
+ /* Enable this if we're doing async rpc. */
+ /* We must check the outstanding callid matches. */
+ if (pipe_init_outgoing_data(p)) {
+ /* Send a cancel_ack PDU reply. */
+ /* We should probably check the auth-verifier here. */
+ reply = setup_cancel_ack_reply(p, pkt);
+ }
+ break;
+#endif
+
+ case DCERPC_PKT_ORPHANED:
+ /* We should probably check the auth-verifier here.
+ * For now just free all client data and continue
+ * processing. */
+ DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
+ " Abandoning rpc call.\n"));
+ reply = True;
+ break;
+
+ default:
+ DEBUG(0, ("process_complete_pdu: "
+ "Unknown rpc type = %u received.\n",
+ (unsigned int)pkt->ptype));
+ break;
+ }
+
+done:
+ if (!reply) {
+ DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
+ "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
+ &p->syntax)));
+ set_incoming_fault(p);
+ setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
+ TALLOC_FREE(pkt);
+ } else {
+ /*
+ * Reset the lengths. We're ready for a new pdu.
+ */
+ TALLOC_FREE(p->in_data.pdu.data);
+ p->in_data.pdu_needed_len = 0;
+ p->in_data.pdu.length = 0;
+ }
+
+ TALLOC_FREE(pkt);
+}
+
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 3055e1a29c..7c4895fe7c 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -23,48 +23,12 @@
#include "../librpc/gen_ndr/srv_spoolss.h"
#include "librpc/gen_ndr/ndr_named_pipe_auth.h"
#include "../libcli/named_pipe_auth/npa_tstream.h"
-#include "../libcli/auth/schannel.h"
-#include "../libcli/auth/spnego.h"
-#include "../libcli/auth/ntlmssp.h"
+#include "rpc_server.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
/****************************************************************************
- Initialise an outgoing packet.
-****************************************************************************/
-
-static bool pipe_init_outgoing_data(pipes_struct *p)
-{
- output_data *o_data = &p->out_data;
-
- /* Reset the offset counters. */
- o_data->data_sent_length = 0;
- o_data->current_pdu_sent = 0;
-
- data_blob_free(&o_data->frag);
-
- /* Free any memory in the current return data buffer. */
- data_blob_free(&o_data->rdata);
-
- return True;
-}
-
-/****************************************************************************
- Sets the fault state on incoming packets.
-****************************************************************************/
-
-static void set_incoming_fault(pipes_struct *p)
-{
- data_blob_free(&p->in_data.data);
- p->in_data.pdu_needed_len = 0;
- p->in_data.pdu.length = 0;
- p->fault_state = True;
- DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
- get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
-}
-
-/****************************************************************************
Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
****************************************************************************/
@@ -154,433 +118,6 @@ static void free_pipe_context(pipes_struct *p)
}
/****************************************************************************
- Processes a request pdu. This will do auth processing if needed, and
- appends the data into the complete stream if the LAST flag is not set.
-****************************************************************************/
-
-static bool dcesrv_auth_request(pipes_struct *p, struct ncacn_packet *pkt)
-{
- NTSTATUS status;
- size_t hdr_size = DCERPC_REQUEST_LENGTH;
- struct dcerpc_auth auth;
- uint32_t auth_length;
- DATA_BLOB data;
- DATA_BLOB full_pkt;
-
- DEBUG(10, ("Checking request auth.\n"));
-
- if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
- hdr_size += 16;
- }
-
- switch (p->auth.auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- DEBUG(10, ("Requested Privacy.\n"));
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- DEBUG(10, ("Requested Integrity.\n"));
- break;
-
- case DCERPC_AUTH_LEVEL_CONNECT:
- if (pkt->auth_length != 0) {
- break;
- }
- return true;
- case DCERPC_AUTH_LEVEL_NONE:
- if (pkt->auth_length != 0) {
- return false;
- }
- return true;
-
- default:
- return false;
- }
-
- status = dcerpc_pull_auth_trailer(pkt, pkt,
- &pkt->u.request.stub_and_verifier,
- &auth, &auth_length, false);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
-
- pkt->u.request.stub_and_verifier.length -= auth_length;
-
- data.data = p->in_data.pdu.data + hdr_size;
- data.length = pkt->u.request.stub_and_verifier.length;
- full_pkt.data = p->in_data.pdu.data;
- full_pkt.length = p->in_data.pdu.length - auth.credentials.length;
-
- switch (p->auth.auth_type) {
- case PIPE_AUTH_TYPE_NONE:
- return true;
-
- case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
- case PIPE_AUTH_TYPE_NTLMSSP:
-
- DEBUG(10, ("NTLMSSP auth\n"));
-
- if (!p->auth.a_u.auth_ntlmssp_state) {
- DEBUG(0, ("Invalid auth level, "
- "failed to process packet auth.\n"));
- return false;
- }
-
- switch (p->auth.auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- status = auth_ntlmssp_unseal_packet(
- p->auth.a_u.auth_ntlmssp_state,
- data.data, data.length,
- full_pkt.data, full_pkt.length,
- &auth.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
- memcpy(pkt->u.request.stub_and_verifier.data,
- data.data, data.length);
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = auth_ntlmssp_check_packet(
- p->auth.a_u.auth_ntlmssp_state,
- data.data, data.length,
- full_pkt.data, full_pkt.length,
- &auth.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
- break;
-
- default:
- DEBUG(0, ("Invalid auth level, "
- "failed to process packet auth.\n"));
- return false;
- }
- break;
-
- case PIPE_AUTH_TYPE_SCHANNEL:
-
- DEBUG(10, ("SCHANNEL auth\n"));
-
- switch (p->auth.auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- status = netsec_incoming_packet(
- p->auth.a_u.schannel_auth,
- pkt, true,
- data.data, data.length,
- &auth.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
- memcpy(pkt->u.request.stub_and_verifier.data,
- data.data, data.length);
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = netsec_incoming_packet(
- p->auth.a_u.schannel_auth,
- pkt, false,
- data.data, data.length,
- &auth.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
- break;
-
- default:
- DEBUG(0, ("Invalid auth level, "
- "failed to process packet auth.\n"));
- return false;
- }
- break;
-
- default:
- DEBUG(0, ("process_request_pdu: "
- "unknown auth type %u set.\n",
- (unsigned int)p->auth.auth_type));
- set_incoming_fault(p);
- return false;
- }
-
- /* remove the indicated amount of padding */
- if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) {
- return false;
- }
- pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length;
-
- return true;
-}
-
-static bool process_request_pdu(pipes_struct *p, struct ncacn_packet *pkt)
-{
- DATA_BLOB data;
-
- if (!p->pipe_bound) {
- DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
- set_incoming_fault(p);
- return False;
- }
-
- /* Store the opnum */
- p->opnum = pkt->u.request.opnum;
-
- if (!dcesrv_auth_request(p, pkt)) {
- DEBUG(0,("Failed to check packet auth.\n"));
- set_incoming_fault(p);
- return false;
- }
-
- data = pkt->u.request.stub_and_verifier;
-
- /*
- * Check the data length doesn't go over the 15Mb limit.
- * increased after observing a bug in the Windows NT 4.0 SP6a
- * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
- * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
- */
-
- if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
- DEBUG(0, ("process_request_pdu: "
- "rpc data buffer too large (%u) + (%u)\n",
- (unsigned int)p->in_data.data.length,
- (unsigned int)data.length));
- set_incoming_fault(p);
- return False;
- }
-
- /*
- * Append the data portion into the buffer and return.
- */
-
- if (data.length) {
- if (!data_blob_append(p->mem_ctx, &p->in_data.data,
- data.data, data.length)) {
- DEBUG(0, ("Unable to append data size %u "
- "to parse buffer of size %u.\n",
- (unsigned int)data.length,
- (unsigned int)p->in_data.data.length));
- set_incoming_fault(p);
- return False;
- }
- }
-
- if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
- bool ret = False;
- /*
- * Ok - we finally have a complete RPC stream.
- * Call the rpc command to process it.
- */
-
- /*
- * Process the complete data stream here.
- */
- if (pipe_init_outgoing_data(p)) {
- ret = api_pipe_request(p, pkt);
- }
-
- return ret;
- }
-
- return True;
-}
-
-/****************************************************************************
- Processes a finished PDU stored in p->in_data.pdu.
-****************************************************************************/
-
-static void process_complete_pdu(pipes_struct *p)
-{
- struct ncacn_packet *pkt = NULL;
- NTSTATUS status;
- bool reply = False;
-
- if(p->fault_state) {
- DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
- get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
- goto done;
- }
-
- pkt = talloc(p->mem_ctx, struct ncacn_packet);
- if (!pkt) {
- DEBUG(0, ("Out of memory!\n"));
- goto done;
- }
-
- status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu, pkt);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
- nt_errstr(status)));
- goto done;
- }
-
- /* Store the call_id */
- p->call_id = pkt->call_id;
-
- /*
- * Ensure we're using the corrent endianness for both the
- * RPC header flags and the raw data we will be reading from.
- */
- if (pkt->drep[0] == DCERPC_DREP_LE) {
- p->endian = RPC_LITTLE_ENDIAN;
- } else {
- p->endian = RPC_BIG_ENDIAN;
- }
-
- DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
-
- switch (pkt->ptype) {
- case DCERPC_PKT_REQUEST:
- reply = process_request_pdu(p, pkt);
- break;
-
- case DCERPC_PKT_PING: /* CL request - ignore... */
- DEBUG(0, ("process_complete_pdu: Error. "
- "Connectionless packet type %d received on "
- "pipe %s.\n", (int)pkt->ptype,
- get_pipe_name_from_syntax(talloc_tos(),
- &p->syntax)));
- break;
-
- case DCERPC_PKT_RESPONSE: /* No responses here. */
- DEBUG(0, ("process_complete_pdu: Error. "
- "DCERPC_PKT_RESPONSE received from client "
- "on pipe %s.\n",
- get_pipe_name_from_syntax(talloc_tos(),
- &p->syntax)));
- break;
-
- case DCERPC_PKT_FAULT:
- case DCERPC_PKT_WORKING:
- /* CL request - reply to a ping when a call in process. */
- case DCERPC_PKT_NOCALL:
- /* CL - server reply to a ping call. */
- case DCERPC_PKT_REJECT:
- case DCERPC_PKT_ACK:
- case DCERPC_PKT_CL_CANCEL:
- case DCERPC_PKT_FACK:
- case DCERPC_PKT_CANCEL_ACK:
- DEBUG(0, ("process_complete_pdu: Error. "
- "Connectionless packet type %u received on "
- "pipe %s.\n", (unsigned int)pkt->ptype,
- get_pipe_name_from_syntax(talloc_tos(),
- &p->syntax)));
- break;
-
- case DCERPC_PKT_BIND:
- /*
- * We assume that a pipe bind is only in one pdu.
- */
- if (pipe_init_outgoing_data(p)) {
- reply = api_pipe_bind_req(p, pkt);
- }
- break;
-
- case DCERPC_PKT_BIND_ACK:
- case DCERPC_PKT_BIND_NAK:
- DEBUG(0, ("process_complete_pdu: Error. "
- "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
- "packet type %u received on pipe %s.\n",
- (unsigned int)pkt->ptype,
- get_pipe_name_from_syntax(talloc_tos(),
- &p->syntax)));
- break;
-
-
- case DCERPC_PKT_ALTER:
- /*
- * We assume that a pipe bind is only in one pdu.
- */
- if (pipe_init_outgoing_data(p)) {
- reply = api_pipe_alter_context(p, pkt);
- }
- break;
-
- case DCERPC_PKT_ALTER_RESP:
- DEBUG(0, ("process_complete_pdu: Error. "
- "DCERPC_PKT_ALTER_RESP on pipe %s: "
- "Should only be server -> client.\n",
- get_pipe_name_from_syntax(talloc_tos(),
- &p->syntax)));
- break;
-
- case DCERPC_PKT_AUTH3:
- /*
- * The third packet in an NTLMSSP auth exchange.
- */
- if (pipe_init_outgoing_data(p)) {
- reply = api_pipe_bind_auth3(p, pkt);
- }
- break;
-
- case DCERPC_PKT_SHUTDOWN:
- DEBUG(0, ("process_complete_pdu: Error. "
- "DCERPC_PKT_SHUTDOWN on pipe %s: "
- "Should only be server -> client.\n",
- get_pipe_name_from_syntax(talloc_tos(),
- &p->syntax)));
- break;
-
- case DCERPC_PKT_CO_CANCEL:
- /* For now just free all client data and continue
- * processing. */
- DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
- " Abandoning rpc call.\n"));
- /* As we never do asynchronous RPC serving, we can
- * never cancel a call (as far as I know).
- * If we ever did we'd have to send a cancel_ack reply.
- * For now, just free all client data and continue
- * processing. */
- reply = True;
- break;
-
-#if 0
- /* Enable this if we're doing async rpc. */
- /* We must check the outstanding callid matches. */
- if (pipe_init_outgoing_data(p)) {
- /* Send a cancel_ack PDU reply. */
- /* We should probably check the auth-verifier here. */
- reply = setup_cancel_ack_reply(p, pkt);
- }
- break;
-#endif
-
- case DCERPC_PKT_ORPHANED:
- /* We should probably check the auth-verifier here.
- * For now just free all client data and continue
- * processing. */
- DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
- " Abandoning rpc call.\n"));
- reply = True;
- break;
-
- default:
- DEBUG(0, ("process_complete_pdu: "
- "Unknown rpc type = %u received.\n",
- (unsigned int)pkt->ptype));
- break;
- }
-
-done:
- if (!reply) {
- DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
- "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
- &p->syntax)));
- set_incoming_fault(p);
- setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
- TALLOC_FREE(pkt);
- } else {
- /*
- * Reset the lengths. We're ready for a new pdu.
- */
- TALLOC_FREE(p->in_data.pdu.data);
- p->in_data.pdu_needed_len = 0;
- p->in_data.pdu.length = 0;
- }
-
- TALLOC_FREE(pkt);
-}
-
-/****************************************************************************
Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
****************************************************************************/
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index a5a0e44738..dbce120dc6 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -67,11 +67,17 @@ static void smbd_aio_signal_handler(struct tevent_context *ev_ctx,
}
-static void initialize_async_io_handler(void)
+static bool initialize_async_io_handler(void)
{
+ static bool tried_signal_setup = false;
+
if (aio_signal_event) {
- return;
+ return true;
+ }
+ if (tried_signal_setup) {
+ return false;
}
+ tried_signal_setup = true;
aio_signal_event = tevent_add_signal(smbd_event_context(),
smbd_event_context(),
@@ -79,7 +85,8 @@ static void initialize_async_io_handler(void)
smbd_aio_signal_handler,
NULL);
if (!aio_signal_event) {
- exit_server("Failed to setup RT_SIGNAL_AIO handler");
+ DEBUG(10, ("Failed to setup RT_SIGNAL_AIO handler\n"));
+ return false;
}
/* tevent supports 100 signal with SA_SIGINFO */
@@ -145,7 +152,9 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
int ret;
/* Ensure aio is initialized. */
- initialize_async_io_handler();
+ if (!initialize_async_io_handler()) {
+ return NT_STATUS_RETRY;
+ }
if (fsp->base_fsp != NULL) {
/* No AIO on streams yet */
@@ -250,7 +259,9 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
int ret;
/* Ensure aio is initialized. */
- initialize_async_io_handler();
+ if (!initialize_async_io_handler()) {
+ return NT_STATUS_RETRY;
+ }
if (fsp->base_fsp != NULL) {
/* No AIO on streams yet */
@@ -382,7 +393,9 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
int ret;
/* Ensure aio is initialized. */
- initialize_async_io_handler();
+ if (!initialize_async_io_handler()) {
+ return NT_STATUS_RETRY;
+ }
if (fsp->base_fsp != NULL) {
/* No AIO on streams yet */
@@ -478,7 +491,9 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
int ret;
/* Ensure aio is initialized. */
- initialize_async_io_handler();
+ if (!initialize_async_io_handler()) {
+ return NT_STATUS_RETRY;
+ }
if (fsp->base_fsp != NULL) {
/* No AIO on streams yet */
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 80a5239de3..52fcd282a6 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -41,10 +41,13 @@ struct pending_auth_data {
on a logon error possibly map the error to success if "map to guest"
is set approriately
*/
-static NTSTATUS do_map_to_guest(NTSTATUS status,
- struct auth_serversupplied_info **server_info,
- const char *user, const char *domain)
+NTSTATUS do_map_to_guest(NTSTATUS status,
+ struct auth_serversupplied_info **server_info,
+ const char *user, const char *domain)
{
+ user = user ? user : "";
+ domain = domain ? domain : "";
+
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
(lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 6586a45439..493e74802d 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -143,6 +143,26 @@ static int smbd_smb2_session_destructor(struct smbd_smb2_session *session)
return 0;
}
+static NTSTATUS setup_ntlmssp_server_info(struct smbd_smb2_session *session,
+ NTSTATUS status)
+{
+ if (NT_STATUS_IS_OK(status)) {
+ status = auth_ntlmssp_server_info(session,
+ session->auth_ntlmssp_state,
+ &session->server_info);
+ } else {
+ /* Note that this server_info won't have a session
+ * key. But for map to guest, that's exactly the right
+ * thing - we can't reasonably guess the key the
+ * client wants, as the password was wrong */
+ status = do_map_to_guest(status,
+ &session->server_info,
+ auth_ntlmssp_get_username(session->auth_ntlmssp_state),
+ auth_ntlmssp_get_domain(session->auth_ntlmssp_state));
+ }
+ return status;
+}
+
#ifdef HAVE_KRB5
static NTSTATUS smbd_smb2_session_setup_krb5(struct smbd_smb2_session *session,
struct smbd_smb2_request *smb2req,
@@ -615,13 +635,6 @@ static NTSTATUS smbd_smb2_common_ntlmssp_auth_return(struct smbd_smb2_session *s
uint64_t *out_session_id)
{
fstring tmp;
- NTSTATUS status = auth_ntlmssp_server_info(session, session->auth_ntlmssp_state,
- &session->server_info);
- if (!NT_STATUS_IS_OK(status)) {
- auth_ntlmssp_end(&session->auth_ntlmssp_state);
- TALLOC_FREE(session);
- return status;
- }
if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
lp_server_signing() == Required) {
@@ -775,6 +788,11 @@ static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session,
&auth_out);
if (!NT_STATUS_IS_OK(status) &&
!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ status = setup_ntlmssp_server_info(session, status);
+ }
+
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
auth_ntlmssp_end(&session->auth_ntlmssp_state);
data_blob_free(&auth);
TALLOC_FREE(session);
@@ -850,6 +868,9 @@ static NTSTATUS smbd_smb2_raw_ntlmssp_auth(struct smbd_smb2_session *session,
*out_session_id = session->vuid;
return status;
}
+
+ status = setup_ntlmssp_server_info(session, status);
+
if (!NT_STATUS_IS_OK(status)) {
auth_ntlmssp_end(&session->auth_ntlmssp_state);
TALLOC_FREE(session);
diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c
index f4ad6f7b47..61cb89d0f7 100644
--- a/source3/utils/net_dns.c
+++ b/source3/utils/net_dns.c
@@ -1,4 +1,3 @@
-
/*
Samba Unix/Linux Dynamic DNS Update
net ads commands
@@ -10,12 +9,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -55,7 +54,7 @@ DNS_ERROR DoDNSUpdate(char *pszServerName,
if (!(mem_ctx = talloc_init("DoDNSUpdate"))) {
return ERROR_DNS_NO_MEMORY;
}
-
+
err = dns_open_connection( pszServerName, DNS_TCP, mem_ctx, &conn );
if (!ERR_DNS_IS_OK(err)) {
goto error;
@@ -114,10 +113,9 @@ DNS_ERROR DoDNSUpdate(char *pszServerName,
keyname, &gss_context,
DNS_SRV_WIN2000 );
}
-
+
if (!ERR_DNS_IS_OK(err))
goto error;
-
err = dns_sign_update(req, gss_context, keyname,
"gss.microsoft.com", time(NULL), 3600);
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index ed8eb1339f..47348b997f 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -1129,9 +1129,11 @@ bool winbindd_reinit_after_fork(const char *logfilename)
struct winbindd_child *cl;
NTSTATUS status;
- status = reinit_after_fork(winbind_messaging_context(),
- winbind_event_context(),
- procid_self(), true);
+ status = reinit_after_fork(
+ winbind_messaging_context(),
+ winbind_event_context(),
+ messaging_server_id(winbind_messaging_context()),
+ true);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("reinit_after_fork() failed\n"));
return false;
diff --git a/source3/wscript_build b/source3/wscript_build
index 38d680518f..f5265011f7 100644
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -68,6 +68,9 @@ LIBNDR_SCHANNEL_SRC = '''../librpc/gen_ndr/ndr_schannel.c
LIBNDR_SPOOLSS_SRC = '''../librpc/gen_ndr/ndr_spoolss.c
../librpc/ndr/ndr_spoolss_buf.c'''
+LIBNDR_XATTR_SRC = '''../librpc/gen_ndr/ndr_xattr.c
+ ../librpc/ndr/ndr_xattr.c'''
+
LIBNDR_GEN_SRC = '''../librpc/gen_ndr/ndr_wkssvc.c
${LIBNDR_GEN_SRC0}
../librpc/gen_ndr/ndr_dfs.c
@@ -79,8 +82,7 @@ LIBNDR_GEN_SRC = '''../librpc/gen_ndr/ndr_wkssvc.c
${LIBNDR_NETLOGON_SRC}
../librpc/gen_ndr/ndr_dssetup.c
librpc/gen_ndr/ndr_notify.c
- ../librpc/gen_ndr/ndr_xattr.c
- ../librpc/ndr/ndr_xattr.c
+ ${LIBNDR_XATTR_SRC}
../librpc/gen_ndr/ndr_epmapper.c
../librpc/gen_ndr/ndr_named_pipe_auth.c
../librpc/gen_ndr/ndr_ntsvcs.c
@@ -413,8 +415,10 @@ RPC_SERVER_SRC = '''${RPC_PIPE_SRC} ${NPA_TSTREAM_SRC}'''
RPC_PARSE_SRC = '''${RPC_PARSE_SRC2}'''
-RPC_CLIENT_SRC = '''rpc_client/cli_pipe.c rpc_client/rpc_transport_np.c
- rpc_client/rpc_transport_sock.c rpc_client/rpc_transport_smbd.c'''
+RPC_CLIENT_SRC = '''rpc_client/cli_pipe.c librpc/rpc/rpc_common.c
+ rpc_client/rpc_transport_np.c
+ rpc_client/rpc_transport_sock.c
+ rpc_client/rpc_transport_smbd.c'''
LOCKING_SRC = '''locking/locking.c locking/brlock.c locking/posix.c'''