summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in35
-rw-r--r--source3/include/fake_file.h3
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c184
-rw-r--r--source3/smbd/files.c5
-rw-r--r--source3/smbd/nttrans.c15
-rw-r--r--source3/smbd/pipes.c16
7 files changed, 194 insertions, 68 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 01ea90ab9e..ac9770dae7 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -2723,7 +2723,40 @@ proto::
etags::
etags `find $(srcdir) -name "*.[ch]"`
etags --append `find $(srcdir)/../lib -name "*.[ch]"`
- etags --append `find $(srcdir)/../source4 -name "*.[ch]"`
+ etags --append `find $(srcdir)/../librpc -name "*.[ch]"`
+ etags --append `find $(srcdir)/../libcli -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/client -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/auth -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/rpc_server -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/kdc -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/winbind -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/scripting -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/heimdal_build -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/libcli -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/ntp_signd -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/ldap_server -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/smb_server -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/include -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/nsswitch -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/cldap_server -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/utils -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/librpc -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/libnet -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/web_server -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/heimdal -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/wrepl_server -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/dynconfig -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/param -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/lib -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/nbt_server -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/build -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/ntvfs -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/torture -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/cluster -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/ntptr -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/smbd -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/script -name "*.[ch]"`
+ etags --append `find $(srcdir)/../source4/dsdb -name "*.[ch]"`
ctags::
ctags `find $(srcdir)/.. -name "*.[ch]"`
diff --git a/source3/include/fake_file.h b/source3/include/fake_file.h
index c4b271f85d..6b34005625 100644
--- a/source3/include/fake_file.h
+++ b/source3/include/fake_file.h
@@ -23,7 +23,8 @@
enum FAKE_FILE_TYPE {
FAKE_FILE_TYPE_NONE = 0,
FAKE_FILE_TYPE_QUOTA,
- FAKE_FILE_TYPE_NAMED_PIPE
+ FAKE_FILE_TYPE_NAMED_PIPE,
+ FAKE_FILE_TYPE_NAMED_PIPE_PROXY
};
/*
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 83cd740a78..e4a445bcd0 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1663,6 +1663,9 @@ size_t str_list_length( const char * const*list );
bool str_list_sub_basic( char **list, const char *smb_name,
const char *domain_name );
bool str_list_substitute(char **list, const char *pattern, const char *insert);
+bool str_list_check(const char **list, const char *s);
+bool str_list_check_ci(const char **list, const char *s);
+
char *ipstr_list_make(char **ipstr_list,
const struct ip_service *ip_list,
int ip_count);
@@ -7110,7 +7113,6 @@ bool api_pipe_request(pipes_struct *p);
pipes_struct *get_first_internal_pipe(void);
pipes_struct *get_next_internal_pipe(pipes_struct *p);
-void set_pipe_handle_offset(int max_open_files);
void init_rpc_pipe_hnd(void);
bool fsp_is_np(struct files_struct *fsp);
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index c8037e6e43..b892755396 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -55,22 +55,6 @@ pipes_struct *get_next_internal_pipe(pipes_struct *p)
return p->next;
}
-/* this must be larger than the sum of the open files and directories */
-static int pipe_handle_offset;
-
-/****************************************************************************
- Set the pipe_handle_offset. Called from smbd/files.c
-****************************************************************************/
-
-void set_pipe_handle_offset(int max_open_files)
-{
- if(max_open_files < 0x7000) {
- pipe_handle_offset = 0x7000;
- } else {
- pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
- }
-}
-
/****************************************************************************
Initialise pipe handle states.
****************************************************************************/
@@ -929,9 +913,74 @@ static int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
bool fsp_is_np(struct files_struct *fsp)
{
- return ((fsp != NULL)
- && (fsp->fake_file_handle != NULL)
- && (fsp->fake_file_handle->type == FAKE_FILE_TYPE_NAMED_PIPE));
+ enum FAKE_FILE_TYPE type;
+
+ if ((fsp == NULL) || (fsp->fake_file_handle == NULL)) {
+ return false;
+ }
+
+ type = fsp->fake_file_handle->type;
+
+ return ((type == FAKE_FILE_TYPE_NAMED_PIPE)
+ || (type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY));
+}
+
+struct np_proxy_state {
+ int fd;
+};
+
+static int np_proxy_state_destructor(struct np_proxy_state *state)
+{
+ if (state->fd != -1) {
+ close(state->fd);
+ }
+ return 0;
+}
+
+static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
+ const char *pipe_name,
+ struct auth_serversupplied_info *server_info)
+{
+ struct np_proxy_state *result;
+ struct sockaddr_un addr;
+ char *socket_path;
+
+ result = talloc(mem_ctx, struct np_proxy_state);
+ if (result == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (result->fd == -1) {
+ DEBUG(10, ("socket(2) failed: %s\n", strerror(errno)));
+ goto fail;
+ }
+ talloc_set_destructor(result, np_proxy_state_destructor);
+
+ ZERO_STRUCT(addr);
+ addr.sun_family = AF_UNIX;
+
+ socket_path = talloc_asprintf(talloc_tos(), "%s/%s",
+ get_dyn_NCALRPCDIR(), "DEFAULT");
+ if (socket_path == NULL) {
+ DEBUG(0, ("talloc_asprintf failed\n"));
+ goto fail;
+ }
+ strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
+ TALLOC_FREE(socket_path);
+
+ if (sys_connect(result->fd, (struct sockaddr *)&addr) == -1) {
+ DEBUG(0, ("connect(%s) failed: %s\n", addr.sun_path,
+ strerror(errno)));
+ goto fail;
+ }
+
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
}
NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
@@ -939,7 +988,9 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
{
NTSTATUS status;
struct files_struct *fsp;
- struct pipes_struct *p;
+ const char **proxy_list;
+
+ proxy_list = lp_parm_string_list(SNUM(conn), "np", "proxy", NULL);
status = file_new(smb_req, conn, &fsp);
if (!NT_STATUS_IS_OK(status)) {
@@ -959,16 +1010,36 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
file_free(smb_req, fsp);
return NT_STATUS_NO_MEMORY;
}
- fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
- p = make_internal_rpc_pipe_p(fsp->fake_file_handle, name,
- conn->client_address, conn->server_info,
- smb_req->vuid);
- if (p == NULL) {
+ if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) {
+ struct np_proxy_state *p;
+
+ p = make_external_rpc_pipe_p(fsp->fake_file_handle, name,
+ conn->server_info);
+
+ fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY;
+ fsp->fake_file_handle->private_data = p;
+ } else {
+ struct pipes_struct *p;
+
+ if (!is_known_pipename(name)) {
+ file_free(smb_req, fsp);
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ p = make_internal_rpc_pipe_p(fsp->fake_file_handle, name,
+ conn->client_address,
+ conn->server_info,
+ smb_req->vuid);
+
+ fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
+ fsp->fake_file_handle->private_data = p;
+ }
+
+ if (fsp->fake_file_handle->private_data == NULL) {
file_free(smb_req, fsp);
return NT_STATUS_PIPE_NOT_AVAILABLE;
}
- fsp->fake_file_handle->private_data = p;
*pfsp = fsp;
@@ -978,20 +1049,33 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
NTSTATUS np_write(struct files_struct *fsp, uint8_t *data, size_t len,
ssize_t *nwritten)
{
- struct pipes_struct *p;
-
if (!fsp_is_np(fsp)) {
return NT_STATUS_INVALID_HANDLE;
}
- p = talloc_get_type_abort(
- fsp->fake_file_handle->private_data, struct pipes_struct);
-
DEBUG(6, ("np_write: %x name: %s len: %d\n", (int)fsp->fnum,
fsp->fsp_name, (int)len));
dump_data(50, data, len);
- *nwritten = write_to_internal_pipe(p, (char *)data, len);
+ switch (fsp->fake_file_handle->type) {
+ case FAKE_FILE_TYPE_NAMED_PIPE: {
+ struct pipes_struct *p = talloc_get_type_abort(
+ fsp->fake_file_handle->private_data,
+ struct pipes_struct);
+ *nwritten = write_to_internal_pipe(p, (char *)data, len);
+ break;
+ }
+ case FAKE_FILE_TYPE_NAMED_PIPE_PROXY: {
+ struct np_proxy_state *p = talloc_get_type_abort(
+ fsp->fake_file_handle->private_data,
+ struct np_proxy_state);
+ *nwritten = write_data(p->fd, (char *)data, len);
+ break;
+ }
+ default:
+ return NT_STATUS_INVALID_HANDLE;
+ break;
+ }
return ((*nwritten) >= 0)
? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
@@ -1000,19 +1084,41 @@ NTSTATUS np_write(struct files_struct *fsp, uint8_t *data, size_t len,
NTSTATUS np_read(struct files_struct *fsp, uint8_t *data, size_t len,
ssize_t *nread, bool *is_data_outstanding)
{
- struct pipes_struct *p;
-
if (!fsp_is_np(fsp)) {
return NT_STATUS_INVALID_HANDLE;
}
- p = talloc_get_type_abort(
- fsp->fake_file_handle->private_data, struct pipes_struct);
+ switch (fsp->fake_file_handle->type) {
+ case FAKE_FILE_TYPE_NAMED_PIPE: {
+ struct pipes_struct *p = talloc_get_type_abort(
+ fsp->fake_file_handle->private_data,
+ struct pipes_struct);
+ *nread = read_from_internal_pipe(p, (char *)data, len,
+ is_data_outstanding);
+ break;
+ }
+ case FAKE_FILE_TYPE_NAMED_PIPE_PROXY: {
+ struct np_proxy_state *p = talloc_get_type_abort(
+ fsp->fake_file_handle->private_data,
+ struct np_proxy_state);
+ int available = 0;
+
+ *nread = sys_read(p->fd, (char *)data, len);
- *nread = read_from_internal_pipe(p, (char *)data, len,
- is_data_outstanding);
+ /*
+ * We don't look at the ioctl result. We don't really care
+ * if there is data available, because this is racy anyway.
+ */
+ ioctl(p->fd, FIONREAD, &available);
+ *is_data_outstanding = (available > 0);
+
+ break;
+ }
+ default:
+ return NT_STATUS_INVALID_HANDLE;
+ break;
+ }
return ((*nread) >= 0)
? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
-
}
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 4a27d02cfe..d3bfce7499 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -200,11 +200,6 @@ open files, %d are available.\n", request_max_open_files, real_max_open_files));
if (!file_bmap) {
exit_server("out of memory in file_init");
}
-
- /*
- * Ensure that pipe_handle_oppset is set correctly.
- */
- set_pipe_handle_offset(real_max_open_files);
}
/****************************************************************************
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index b78c946388..30841686fb 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -276,21 +276,16 @@ static void nt_open_pipe(char *fname, connection_struct *conn,
DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
- /* See if it is one we want to handle. */
-
- if (!is_known_pipename(fname)) {
- reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
- ERRDOS, ERRbadpipe);
- return;
- }
-
/* Strip \\ off the name. */
fname++;
- DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
-
status = np_open(req, conn, fname, &fsp);
if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+ ERRDOS, ERRbadpipe);
+ return;
+ }
reply_nterror(req, status);
return;
}
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 25a1fe2e63..d971e9dc62 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -66,13 +66,6 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
DEBUG(4,("Opening pipe %s.\n", pipe_name));
- /* See if it is one we want to handle. */
- if (!is_known_pipename(pipe_name)) {
- reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
- ERRDOS, ERRbadpipe);
- return;
- }
-
/* Strip \PIPE\ off the name. */
fname = pipe_name + PIPELEN;
@@ -86,12 +79,13 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
}
#endif
- /* Known pipes arrive with DIR attribs. Remove it so a regular file */
- /* can be opened and add it in after the open. */
- DEBUG(3,("Known pipe %s opening.\n",fname));
-
status = np_open(req, conn, fname, &fsp);
if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+ ERRDOS, ERRbadpipe);
+ return;
+ }
reply_nterror(req, status);
return;
}