Merge branch 'master' of ssh://git.samba.org/data/git/samba
authorJelmer Vernooij <jelmer@samba.org>
Sat, 25 Oct 2008 22:41:34 +0000 (00:41 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Sat, 25 Oct 2008 22:41:34 +0000 (00:41 +0200)
source3/Makefile.in
source3/include/fake_file.h
source3/include/proto.h
source3/rpc_server/srv_pipe_hnd.c
source3/smbd/files.c
source3/smbd/nttrans.c
source3/smbd/pipes.c

index 01ea90ab9e5ae914bf7fab69225d9dcc407a4c19..ac9770dae7bf187c5a26acdd4577421d600c9ea1 100644 (file)
@@ -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]"`
index c4b271f85d83f3874d670d4fb1884390139d253a..6b3400562516b39c78bf99078620407861d4c6d2 100644 (file)
@@ -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
 };
 
 /*
index 83cd740a788d1004997055ef4fe4ab2e4d5c0f63..e4a445bcd0a7c0bb539d231f20dc0c516240abee 100644 (file)
@@ -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);
index c8037e6e4321a524340d23477457b8575e9527ca..b892755396fabaf75110ddd5d1e656779fbbc811 100644 (file)
@@ -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;
-
 }
index 4a27d02cfec2891b1af1b3ff75ff86d4a300e3cf..d3bfce749905d40f55aec47ee50cc59516162c8a 100644 (file)
@@ -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);
 }
 
 /****************************************************************************
index b78c946388eff77de8e12ef11b802108eb5fd240..30841686fb4139470bfe174b2aa70ce697c7246c 100644 (file)
@@ -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;
        }
index 25a1fe2e634045259cc00b118ffff0eb33eb5a5e..d971e9dc6201941da435e5d21a41e073780fead2 100644 (file)
@@ -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;
        }