lib/util: remove extra safe_string.h file
[samba.git] / source4 / ntvfs / ipc / vfs_ipc.c
index 8c9e8e91ce4edb6355e1120aecfc1b87939ac734..967c80d299591f9b4837947725c3956f5d413ac4 100644 (file)
@@ -29,7 +29,7 @@
 #include "ntvfs/ntvfs.h"
 #include "../librpc/gen_ndr/rap.h"
 #include "ntvfs/ipc/proto.h"
-#include "libcli/raw/ioctl.h"
+#include "../libcli/smb/smb_constants.h"
 #include "param/param.h"
 #include "../lib/tsocket/tsocket.h"
 #include "../libcli/named_pipe_auth/npa_tstream.h"
 #include "lib/socket/socket.h"
 #include "auth/credentials/credentials.h"
 #include "auth/credentials/credentials_krb5.h"
-#include <gssapi/gssapi.h>
+#include "system/kerberos.h"
+#include "system/gssapi.h"
 #include "system/locale.h"
+#include "system/filesys.h"
+
+#undef strncasecmp
 
 /* this is the private structure used to keep the state of an open
    ipc$ connection. It needs to keep information about all open
@@ -217,7 +221,7 @@ struct ipc_open_state {
        struct pipe_state *p;
        struct ntvfs_request *req;
        union smb_open *oi;
-       struct netr_SamInfo3 *info3;
+       struct auth_session_info_transport *session_info_transport;
 };
 
 static void ipc_open_done(struct tevent_req *subreq);
@@ -228,7 +232,9 @@ static void ipc_open_done(struct tevent_req *subreq);
 static NTSTATUS validate_pipename(const char *name)
 {
        while (*name) {
-               if (!isalnum(*name)) return NT_STATUS_INVALID_PARAMETER;
+               if (!isalnum(*name) && *name != '_') {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
                name++;
        }
        return NT_STATUS_OK;
@@ -244,25 +250,27 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
        struct pipe_state *p;
        struct ipc_private *ipriv = talloc_get_type_abort(ntvfs->private_data,
                                    struct ipc_private);
-       struct smb_iconv_convenience *smb_ic
-               = lp_iconv_convenience(ipriv->ntvfs->ctx->lp_ctx);
        struct ntvfs_handle *h;
        struct ipc_open_state *state;
        struct tevent_req *subreq;
        const char *fname;
        const char *directory;
-       struct tsocket_address *client_addr;
-       struct tsocket_address *server_addr;
-       int ret;
-       DATA_BLOB delegated_creds = data_blob_null;
+       const struct tsocket_address *remote_client_addr;
+       const struct tsocket_address *local_server_addr;
 
        switch (oi->generic.level) {
        case RAW_OPEN_NTCREATEX:
        case RAW_OPEN_NTTRANS_CREATE:
                fname = oi->ntcreatex.in.fname;
+               while (fname[0] == '\\') fname++;
                break;
        case RAW_OPEN_OPENX:
                fname = oi->openx.in.fname;
+               while (fname[0] == '\\') fname++;
+               if (strncasecmp(fname, "PIPE\\", 5) != 0) {
+                       return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
+               }
+               while (fname[0] == '\\') fname++;
                break;
        case RAW_OPEN_SMB2:
                fname = oi->smb2.in.fname;
@@ -272,7 +280,7 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
        }
 
        directory = talloc_asprintf(req, "%s/np",
-                                   lp_ncalrpc_dir(ipriv->ntvfs->ctx->lp_ctx));
+                                   lpcfg_ncalrpc_dir(ipriv->ntvfs->ctx->lp_ctx));
        NT_STATUS_HAVE_NO_MEMORY(directory);
 
        state = talloc(req, struct ipc_open_state);
@@ -284,8 +292,6 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
        p = talloc(h, struct pipe_state);
        NT_STATUS_HAVE_NO_MEMORY(p);
 
-       while (fname[0] == '\\') fname++;
-
        /* check for valid characters in name */
        fname = strlower_talloc(p, fname);
 
@@ -309,59 +315,26 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
        state->req = req;
        state->oi = oi;
 
-       status = auth_convert_server_info_saminfo3(state,
-                                                  req->session_info->server_info,
-                                                  &state->info3);
-       NT_STATUS_NOT_OK_RETURN(status);
-
-       client_addr = ntvfs_get_local_address(ipriv->ntvfs);
-       server_addr = ntvfs_get_remote_address(ipriv->ntvfs);
-
-       if (req->session_info->credentials) {
-               struct gssapi_creds_container *gcc;
-               OM_uint32 gret;
-               OM_uint32 minor_status;
-               gss_buffer_desc cred_token;
-               const char *error_string;
-
-               ret = cli_credentials_get_client_gss_creds(req->session_info->credentials,
-                                                          ipriv->ntvfs->ctx->event_ctx,
-                                                          ipriv->ntvfs->ctx->lp_ctx,
-                                                          &gcc, &error_string);
-               if (ret) {
-                       goto skip;
-               }
-
-               gret = gss_export_cred(&minor_status,
-                                      gcc->creds,
-                                      &cred_token);
-               if (gret != GSS_S_COMPLETE) {
-                       return NT_STATUS_INTERNAL_ERROR;
-               }
+       status = auth_session_info_transport_from_session(state,
+                                                         req->session_info,
+                                                         ipriv->ntvfs->ctx->event_ctx,
+                                                         ipriv->ntvfs->ctx->lp_ctx,
+                                                         &state->session_info_transport);
 
-               if (cred_token.length) {
-                       delegated_creds = data_blob_talloc(req,
-                                                          cred_token.value,
-                                                          cred_token.length);
-                       gss_release_buffer(&minor_status, &cred_token);
-                       NT_STATUS_HAVE_NO_MEMORY(delegated_creds.data);
-               }
-       }
+       NT_STATUS_NOT_OK_RETURN(status);
 
-skip:
+       local_server_addr = ntvfs_get_local_address(ipriv->ntvfs);
+       remote_client_addr = ntvfs_get_remote_address(ipriv->ntvfs);
 
        subreq = tstream_npa_connect_send(p,
                                          ipriv->ntvfs->ctx->event_ctx,
-                                         smb_ic,
                                          directory,
                                          fname,
-                                         client_addr,
+                                         remote_client_addr,
                                          NULL,
-                                         server_addr,
+                                         local_server_addr,
                                          NULL,
-                                         state->info3,
-                                         req->session_info->session_key,
-                                         delegated_creds);
+                                         state->session_info_transport);
        NT_STATUS_HAVE_NO_MEMORY(subreq);
        tevent_req_set_callback(subreq, ipc_open_done, state);
 
@@ -388,7 +361,7 @@ static void ipc_open_done(struct tevent_req *subreq)
                                       &p->allocation_size);
        TALLOC_FREE(subreq);
        if (ret == -1) {
-               status = map_nt_error_from_unix(sys_errno);
+               status = map_nt_error_from_unix_common(sys_errno);
                goto reply;
        }
 
@@ -556,7 +529,7 @@ static int ipc_readv_next_vector(struct tstream_context *stream,
                return -1;
        }
 
-       vector[0].iov_base = state->buf + state->ofs;
+       vector[0].iov_base = (char *) (state->buf + state->ofs);
        vector[0].iov_len = wanted;
 
        state->ofs += wanted;
@@ -637,7 +610,7 @@ static void ipc_read_done(struct tevent_req *subreq)
        ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno);
        TALLOC_FREE(subreq);
        if (ret == -1) {
-               status = map_nt_error_from_unix(sys_errno);
+               status = map_nt_error_from_unix_common(sys_errno);
                goto reply;
        }
 
@@ -722,7 +695,7 @@ static void ipc_write_done(struct tevent_req *subreq)
        ret = tstream_writev_queue_recv(subreq, &sys_errno);
        TALLOC_FREE(subreq);
        if (ret == -1) {
-               status = map_nt_error_from_unix(sys_errno);
+               status = map_nt_error_from_unix_common(sys_errno);
                goto reply;
        }
 
@@ -766,11 +739,13 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs,
                                    struct ipc_private);
        struct pipe_state *p;
 
-       if (io->generic.level != RAW_CLOSE_CLOSE) {
+       if (io->generic.level != RAW_CLOSE_GENERIC) {
                return ntvfs_map_close(ntvfs, req, io);
        }
 
-       p = pipe_state_find(ipriv, io->close.in.file.ntvfs);
+       ZERO_STRUCT(io->generic.out);
+
+       p = pipe_state_find(ipriv, io->generic.in.file.ntvfs);
        if (!p) {
                return NT_STATUS_INVALID_HANDLE;
        }
@@ -896,8 +871,6 @@ static NTSTATUS ipc_qfileinfo(struct ntvfs_module_context *ntvfs,
        default:
                return ntvfs_map_qfileinfo(ntvfs, req, info);
        }
-       
-       return NT_STATUS_ACCESS_DENIED;
 }
 
 
@@ -1009,7 +982,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs,
        state->p = p;
        state->req = req;
        state->trans = trans;
-       state->writev_iov.iov_base = trans->in.data.data;
+       state->writev_iov.iov_base = (char *) trans->in.data.data;
        state->writev_iov.iov_len = trans->in.data.length;
 
        ipc_readv_next_vector_init(&state->next_vector,
@@ -1046,7 +1019,7 @@ static void ipc_trans_writev_done(struct tevent_req *subreq)
                status = NT_STATUS_PIPE_DISCONNECTED;
                goto reply;
        } else if (ret == -1) {
-               status = map_nt_error_from_unix(sys_errno);
+               status = map_nt_error_from_unix_common(sys_errno);
                goto reply;
        }
 
@@ -1082,7 +1055,7 @@ static void ipc_trans_readv_done(struct tevent_req *subreq)
        ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno);
        TALLOC_FREE(subreq);
        if (ret == -1) {
-               status = map_nt_error_from_unix(sys_errno);
+               status = map_nt_error_from_unix_common(sys_errno);
                goto reply;
        }
 
@@ -1206,19 +1179,19 @@ static NTSTATUS ipc_ioctl_smb2(struct ntvfs_module_context *ntvfs,
        state = talloc(req, struct ipc_ioctl_state);
        NT_STATUS_HAVE_NO_MEMORY(state);
 
-       io->smb2.out._pad       = 0;
+       io->smb2.out.reserved   = 0;
        io->smb2.out.function   = io->smb2.in.function;
-       io->smb2.out.unknown2   = 0;
-       io->smb2.out.unknown3   = 0;
-       io->smb2.out.in         = io->smb2.in.out;
-       io->smb2.out.out = data_blob_talloc(req, NULL, io->smb2.in.max_response_size);
+       io->smb2.out.flags      = 0;
+       io->smb2.out.reserved2  = 0;
+       io->smb2.out.in         = data_blob_null;
+       io->smb2.out.out = data_blob_talloc(req, NULL, io->smb2.in.max_output_response);
        NT_STATUS_HAVE_NO_MEMORY(io->smb2.out.out.data);
 
        state->ipriv = ipriv;
        state->p = p;
        state->req = req;
        state->io = io;
-       state->writev_iov.iov_base = io->smb2.in.out.data;
+       state->writev_iov.iov_base = (char *) io->smb2.in.out.data;
        state->writev_iov.iov_len = io->smb2.in.out.length;
 
        ipc_readv_next_vector_init(&state->next_vector,
@@ -1252,7 +1225,7 @@ static void ipc_ioctl_writev_done(struct tevent_req *subreq)
        ret = tstream_writev_queue_recv(subreq, &sys_errno);
        TALLOC_FREE(subreq);
        if (ret == -1) {
-               status = map_nt_error_from_unix(sys_errno);
+               status = map_nt_error_from_unix_common(sys_errno);
                goto reply;
        }
 
@@ -1288,7 +1261,7 @@ static void ipc_ioctl_readv_done(struct tevent_req *subreq)
        ret = tstream_readv_pdu_queue_recv(subreq, &sys_errno);
        TALLOC_FREE(subreq);
        if (ret == -1) {
-               status = map_nt_error_from_unix(sys_errno);
+               status = map_nt_error_from_unix_common(sys_errno);
                goto reply;
        }
 
@@ -1320,15 +1293,13 @@ static NTSTATUS ipc_ioctl(struct ntvfs_module_context *ntvfs,
        default:
                return NT_STATUS_ACCESS_DENIED;
        }
-
-       return NT_STATUS_ACCESS_DENIED;
 }
 
 
 /*
   initialialise the IPC backend, registering ourselves with the ntvfs subsystem
  */
-NTSTATUS ntvfs_ipc_init(void)
+NTSTATUS ntvfs_ipc_init(TALLOC_CTX *ctx)
 {
        NTSTATUS ret;
        struct ntvfs_ops ops;
@@ -1341,36 +1312,36 @@ NTSTATUS ntvfs_ipc_init(void)
        ops.type = NTVFS_IPC;
 
        /* fill in all the operations */
-       ops.connect = ipc_connect;
-       ops.disconnect = ipc_disconnect;
-       ops.unlink = ipc_unlink;
-       ops.chkpath = ipc_chkpath;
-       ops.qpathinfo = ipc_qpathinfo;
-       ops.setpathinfo = ipc_setpathinfo;
-       ops.open = ipc_open;
-       ops.mkdir = ipc_mkdir;
-       ops.rmdir = ipc_rmdir;
-       ops.rename = ipc_rename;
-       ops.copy = ipc_copy;
-       ops.ioctl = ipc_ioctl;
-       ops.read = ipc_read;
-       ops.write = ipc_write;
-       ops.seek = ipc_seek;
-       ops.flush = ipc_flush;  
-       ops.close = ipc_close;
-       ops.exit = ipc_exit;
-       ops.lock = ipc_lock;
-       ops.setfileinfo = ipc_setfileinfo;
-       ops.qfileinfo = ipc_qfileinfo;
-       ops.fsinfo = ipc_fsinfo;
-       ops.lpq = ipc_lpq;
-       ops.search_first = ipc_search_first;
-       ops.search_next = ipc_search_next;
-       ops.search_close = ipc_search_close;
-       ops.trans = ipc_trans;
-       ops.logoff = ipc_logoff;
-       ops.async_setup = ipc_async_setup;
-       ops.cancel = ipc_cancel;
+       ops.connect_fn = ipc_connect;
+       ops.disconnect_fn = ipc_disconnect;
+       ops.unlink_fn = ipc_unlink;
+       ops.chkpath_fn = ipc_chkpath;
+       ops.qpathinfo_fn = ipc_qpathinfo;
+       ops.setpathinfo_fn = ipc_setpathinfo;
+       ops.open_fn = ipc_open;
+       ops.mkdir_fn = ipc_mkdir;
+       ops.rmdir_fn = ipc_rmdir;
+       ops.rename_fn = ipc_rename;
+       ops.copy_fn = ipc_copy;
+       ops.ioctl_fn = ipc_ioctl;
+       ops.read_fn = ipc_read;
+       ops.write_fn = ipc_write;
+       ops.seek_fn = ipc_seek;
+       ops.flush_fn = ipc_flush;
+       ops.close_fn = ipc_close;
+       ops.exit_fn = ipc_exit;
+       ops.lock_fn = ipc_lock;
+       ops.setfileinfo_fn = ipc_setfileinfo;
+       ops.qfileinfo_fn = ipc_qfileinfo;
+       ops.fsinfo_fn = ipc_fsinfo;
+       ops.lpq_fn = ipc_lpq;
+       ops.search_first_fn = ipc_search_first;
+       ops.search_next_fn = ipc_search_next;
+       ops.search_close_fn = ipc_search_close;
+       ops.trans_fn = ipc_trans;
+       ops.logoff_fn = ipc_logoff;
+       ops.async_setup_fn = ipc_async_setup;
+       ops.cancel_fn = ipc_cancel;
 
        /* register ourselves with the NTVFS subsystem. */
        ret = ntvfs_register(&ops, &vers);