From ff211be69681c8dbbd7b6364fafb7aa6e8b5a1f5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 25 Oct 2008 12:09:58 +0200 Subject: Remove "pipe_handle_offset" -- pipes now use "struct files_struct" --- source3/include/proto.h | 1 - source3/rpc_server/srv_pipe_hnd.c | 16 ---------------- source3/smbd/files.c | 5 ----- 3 files changed, 22 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 83cd740a78..d04968ed8a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7110,7 +7110,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..aaa355790d 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. ****************************************************************************/ 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); } /**************************************************************************** -- cgit From 56164805147935b8e3b03c22adee7cc2b1e1c3b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 25 Oct 2008 13:33:21 +0200 Subject: Fix "make etags" -- the args list gets really long for s4 with the prefix --- source3/Makefile.in | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'source3') 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]"` -- cgit From 1ad54998a971b58f870263b4b8d6e051d627c79e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 25 Oct 2008 13:50:25 +0200 Subject: Add str_list_check[_ci] to s3's proto.h Jelmer, when I include lib/util/util.h into some s3 file I get errors, this is why I put those prototypes here as a workaround. Might be fixed differently later. --- source3/include/proto.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index d04968ed8a..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); -- cgit From f87219d6e6e049a6d233696d126ea231cbbc1672 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 25 Oct 2008 15:23:36 +0200 Subject: Move the is_known_pipename check into np_open --- source3/rpc_server/srv_pipe_hnd.c | 6 ++++++ source3/smbd/nttrans.c | 15 +++++---------- source3/smbd/pipes.c | 16 +++++----------- 3 files changed, 16 insertions(+), 21 deletions(-) (limited to 'source3') diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index aaa355790d..822d50aa54 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -925,6 +925,12 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn, struct files_struct *fsp; struct pipes_struct *p; + /* See if it is one we want to handle. */ + + if (!is_known_pipename(name)) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + status = file_new(smb_req, conn, &fsp); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("file_new failed: %s\n", nt_errstr(status))); 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; } -- cgit From 7bea6684c23f34319feb393023e634b1f069f20f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 25 Oct 2008 15:37:13 +0200 Subject: Add proxied named pipe support This is a central piece of the "merged build" thing: Forward named pipes from samba3 to samba4. This patch is not finished yet, as we will have to forward the smb-level authentication information to samba4, but I'm pushing this patch already to demonstrate the implementation without clutter. It adds an intermediate parameter np:proxy = srvsvc samr winreg wkssvc ... and so on that states which of the pipes should be forwarded to the s4 unix domain socket DEFAULT. The parameter is intermediate because once we have a proper endpoint mapper implementation, this information will be retrieved out of a database. If anybody wants to try this, do the merged build and configure s4 with server services = samba3_smb, rpc, nbt, wrepl, ldap, cldap, kdc, drepl samba3:smbd = /data/inst/sbin/smbd and s3 with auth methods = guest netlogond np:proxy = srvsvc samr winreg wkssvc netlogon ntlsa ntsvcs lsass lsarpc netdfs \ rpcecho initshutdown epmapper svcctl eventlog drsuapi Then run rpcclient against samba4. It will fork s3, which authenticates against s4, and then forwards the rpc requests to s4. Volker --- source3/include/fake_file.h | 3 +- source3/rpc_server/srv_pipe_hnd.c | 172 +++++++++++++++++++++++++++++++------- 2 files changed, 146 insertions(+), 29 deletions(-) (limited to 'source3') 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/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 822d50aa54..b892755396 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -913,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, @@ -923,13 +988,9 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn, { NTSTATUS status; struct files_struct *fsp; - struct pipes_struct *p; - - /* See if it is one we want to handle. */ + const char **proxy_list; - if (!is_known_pipename(name)) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } + proxy_list = lp_parm_string_list(SNUM(conn), "np", "proxy", NULL); status = file_new(smb_req, conn, &fsp); if (!NT_STATUS_IS_OK(status)) { @@ -949,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; @@ -968,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; @@ -990,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); + + /* + * 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); - *nread = read_from_internal_pipe(p, (char *)data, len, - is_data_outstanding); + break; + } + default: + return NT_STATUS_INVALID_HANDLE; + break; + } return ((*nread) >= 0) ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR; - } -- cgit