NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name, const struct tsocket_address *local_address, const struct tsocket_address *remote_address, struct auth_session_info *session_info, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, struct fake_file_handle **phandle) { enum rpc_service_mode_e pipe_mode; const char **proxy_list; struct fake_file_handle *handle; struct ndr_syntax_id syntax; struct npa_state *npa = NULL; NTSTATUS status; bool ok; proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL); handle = talloc(mem_ctx, struct fake_file_handle); if (handle == NULL) { return NT_STATUS_NO_MEMORY; } /* Check what is the server type for this pipe. Defaults to "embedded" */ pipe_mode = rpc_service_mode(name); /* Still support the old method for defining external servers */ if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) { pipe_mode = RPC_SERVICE_MODE_EXTERNAL; } switch (pipe_mode) { case RPC_SERVICE_MODE_EXTERNAL: status = make_external_rpc_pipe(handle, name, local_address, remote_address, session_info, &npa); if (!NT_STATUS_IS_OK(status)) { talloc_free(handle); return status; } handle->private_data = (void *)npa; handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY; break; case RPC_SERVICE_MODE_EMBEDDED: /* Check if we handle this pipe internally */ ok = is_known_pipename(name, &syntax); if (!ok) { DEBUG(2, ("'%s' is not a registered pipe!\n", name)); talloc_free(handle); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } status = make_internal_rpc_pipe_socketpair(handle, ev_ctx, msg_ctx, name, &syntax, remote_address, session_info, &npa); if (!NT_STATUS_IS_OK(status)) { talloc_free(handle); return status; } handle->private_data = (void *)npa; handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY; break; case RPC_SERVICE_MODE_DISABLED: talloc_free(handle); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } *phandle = handle; return NT_STATUS_OK; }
NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name, const struct tsocket_address *local_address, const struct tsocket_address *remote_address, struct client_address *client_id, struct auth_serversupplied_info *session_info, struct messaging_context *msg_ctx, struct fake_file_handle **phandle) { const char *rpcsrv_type; const char **proxy_list; struct fake_file_handle *handle; bool external = false; proxy_list = lp_parm_string_list(-1, "np", "proxy", NULL); handle = talloc(mem_ctx, struct fake_file_handle); if (handle == NULL) { return NT_STATUS_NO_MEMORY; } /* Check what is the server type for this pipe. Defaults to "embedded" */ rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM, "rpc_server", name, "embedded"); if (StrCaseCmp(rpcsrv_type, "embedded") != 0) { external = true; } /* Still support the old method for defining external servers */ if ((proxy_list != NULL) && str_list_check_ci(proxy_list, name)) { external = true; } if (external) { struct np_proxy_state *p; p = make_external_rpc_pipe_p(handle, name, local_address, remote_address, session_info); handle->type = FAKE_FILE_TYPE_NAMED_PIPE_PROXY; handle->private_data = p; } else { struct pipes_struct *p; struct ndr_syntax_id syntax; if (!is_known_pipename(name, &syntax)) { TALLOC_FREE(handle); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } p = make_internal_rpc_pipe_p(handle, &syntax, client_id, session_info, msg_ctx); handle->type = FAKE_FILE_TYPE_NAMED_PIPE; handle->private_data = p; } if (handle->private_data == NULL) { TALLOC_FREE(handle); return NT_STATUS_PIPE_NOT_AVAILABLE; } *phandle = handle; return NT_STATUS_OK; }
void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) { const char *fname = NULL; char *pipe_name = NULL; smb_np_struct *p; int size=0,fmode=0,mtime=0,rmode=0; TALLOC_CTX *ctx = talloc_tos(); /* XXXX we need to handle passed times, sattr and flags */ srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &pipe_name, smb_buf(req->inbuf), STR_TERMINATE); if (!pipe_name) { reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, ERRDOS, ERRbadpipe); return; } /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ /* not just something we really don't understand. */ if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) { reply_doserror(req, ERRSRV, ERRaccess); return; } 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; #if 0 /* * Hack for NT printers... JRA. */ if(should_fail_next_srvsvc_open(fname)) { reply_doserror(req, ERRSRV, ERRaccess); return; } #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)); p = open_rpc_pipe_p(fname, conn, req->vuid); if (!p) { reply_doserror(req, ERRSRV, ERRnofids); return; } /* Prepare the reply */ reply_outbuf(req, 15, 0); /* Mark the opened file as an existing named pipe in message mode. */ SSVAL(req->outbuf,smb_vwv9,2); SSVAL(req->outbuf,smb_vwv10,0xc700); if (rmode == 2) { DEBUG(4,("Resetting open result to open from create.\n")); rmode = 1; } SSVAL(req->outbuf,smb_vwv2, p->pnum); SSVAL(req->outbuf,smb_vwv3,fmode); srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime); SIVAL(req->outbuf,smb_vwv6,size); SSVAL(req->outbuf,smb_vwv8,rmode); SSVAL(req->outbuf,smb_vwv11,0x0001); chain_reply(req); return; }