smbd/pipes.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Pipe SMB reply routines
00004    Copyright (C) Andrew Tridgell 1992-1998
00005    Copyright (C) Luke Kenneth Casson Leighton 1996-1998
00006    Copyright (C) Paul Ashton  1997-1998.
00007    Copyright (C) Jeremy Allison 2005.
00008    
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013    
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018    
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022 */
00023 /*
00024    This file handles reply_ calls on named pipes that the server
00025    makes to handle specific protocols
00026 */
00027 
00028 
00029 #include "includes.h"
00030 
00031 #define PIPE            "\\PIPE\\"
00032 #define PIPELEN         strlen(PIPE)
00033 
00034 #define MAX_PIPE_NAME_LEN       24
00035 
00036 /* PIPE/<name>/<pid>/<pnum> */
00037 #define PIPEDB_KEY_FORMAT "PIPE/%s/%u/%d"
00038 
00039 struct pipe_dbrec {
00040         struct process_id pid;
00041         int pnum;
00042         uid_t uid;
00043 
00044         char name[MAX_PIPE_NAME_LEN];
00045         fstring user;
00046 };
00047 
00048 
00049 extern struct pipe_id_info pipe_names[];
00050 
00051 /****************************************************************************
00052  Reply to an open and X on a named pipe.
00053  This code is basically stolen from reply_open_and_X with some
00054  wrinkles to handle pipes.
00055 ****************************************************************************/
00056 
00057 int reply_open_pipe_and_X(connection_struct *conn,
00058                           char *inbuf,char *outbuf,int length,int bufsize)
00059 {
00060         pstring fname;
00061         pstring pipe_name;
00062         uint16 vuid = SVAL(inbuf, smb_uid);
00063         smb_np_struct *p;
00064         int size=0,fmode=0,mtime=0,rmode=0;
00065         int i;
00066 
00067         /* XXXX we need to handle passed times, sattr and flags */
00068         srvstr_pull_buf(inbuf, pipe_name, smb_buf(inbuf), sizeof(pipe_name), STR_TERMINATE);
00069 
00070         /* If the name doesn't start \PIPE\ then this is directed */
00071         /* at a mailslot or something we really, really don't understand, */
00072         /* not just something we really don't understand. */
00073         if ( strncmp(pipe_name,PIPE,PIPELEN) != 0 ) {
00074                 return(ERROR_DOS(ERRSRV,ERRaccess));
00075         }
00076 
00077         DEBUG(4,("Opening pipe %s.\n", pipe_name));
00078 
00079         /* See if it is one we want to handle. */
00080         for( i = 0; pipe_names[i].client_pipe ; i++ ) {
00081                 if( strequal(pipe_name,pipe_names[i].client_pipe)) {
00082                         break;
00083                 }
00084         }
00085 
00086         if (pipe_names[i].client_pipe == NULL) {
00087                 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
00088         }
00089 
00090         /* Strip \PIPE\ off the name. */
00091         pstrcpy(fname, pipe_name + PIPELEN);
00092 
00093 #if 0
00094         /*
00095          * Hack for NT printers... JRA.
00096          */
00097     if(should_fail_next_srvsvc_open(fname))
00098       return(ERROR(ERRSRV,ERRaccess));
00099 #endif
00100 
00101         /* Known pipes arrive with DIR attribs. Remove it so a regular file */
00102         /* can be opened and add it in after the open. */
00103         DEBUG(3,("Known pipe %s opening.\n",fname));
00104 
00105         p = open_rpc_pipe_p(fname, conn, vuid);
00106         if (!p) {
00107                 return(ERROR_DOS(ERRSRV,ERRnofids));
00108         }
00109 
00110         /* Prepare the reply */
00111         set_message(outbuf,15,0,True);
00112 
00113         /* Mark the opened file as an existing named pipe in message mode. */
00114         SSVAL(outbuf,smb_vwv9,2);
00115         SSVAL(outbuf,smb_vwv10,0xc700);
00116 
00117         if (rmode == 2) {
00118                 DEBUG(4,("Resetting open result to open from create.\n"));
00119                 rmode = 1;
00120         }
00121 
00122         SSVAL(outbuf,smb_vwv2, p->pnum);
00123         SSVAL(outbuf,smb_vwv3,fmode);
00124         srv_put_dos_date3(outbuf,smb_vwv4,mtime);
00125         SIVAL(outbuf,smb_vwv6,size);
00126         SSVAL(outbuf,smb_vwv8,rmode);
00127         SSVAL(outbuf,smb_vwv11,0x0001);
00128 
00129         return chain_reply(inbuf,outbuf,length,bufsize);
00130 }
00131 
00132 /****************************************************************************
00133  Reply to a write on a pipe.
00134 ****************************************************************************/
00135 
00136 int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
00137 {
00138         smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
00139         uint16 vuid = SVAL(inbuf,smb_uid);
00140         size_t numtowrite = SVAL(inbuf,smb_vwv1);
00141         int nwritten;
00142         int outsize;
00143         char *data;
00144 
00145         if (!p) {
00146                 return(ERROR_DOS(ERRDOS,ERRbadfid));
00147         }
00148 
00149         if (p->vuid != vuid) {
00150                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
00151         }
00152 
00153         data = smb_buf(inbuf) + 3;
00154 
00155         if (numtowrite == 0) {
00156                 nwritten = 0;
00157         } else {
00158                 nwritten = write_to_pipe(p, data, numtowrite);
00159         }
00160 
00161         if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) {
00162                 return (UNIXERROR(ERRDOS,ERRnoaccess));
00163         }
00164   
00165         outsize = set_message(outbuf,1,0,True);
00166 
00167         SSVAL(outbuf,smb_vwv0,nwritten);
00168   
00169         DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
00170 
00171         return(outsize);
00172 }
00173 
00174 /****************************************************************************
00175  Reply to a write and X.
00176 
00177  This code is basically stolen from reply_write_and_X with some
00178  wrinkles to handle pipes.
00179 ****************************************************************************/
00180 
00181 int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
00182 {
00183         smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
00184         uint16 vuid = SVAL(inbuf,smb_uid);
00185         size_t numtowrite = SVAL(inbuf,smb_vwv10);
00186         int nwritten = -1;
00187         int smb_doff = SVAL(inbuf, smb_vwv11);
00188         BOOL pipe_start_message_raw = ((SVAL(inbuf, smb_vwv7) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) ==
00189                                                                 (PIPE_START_MESSAGE|PIPE_RAW_MODE));
00190         char *data;
00191 
00192         if (!p) {
00193                 return(ERROR_DOS(ERRDOS,ERRbadfid));
00194         }
00195 
00196         if (p->vuid != vuid) {
00197                 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
00198         }
00199 
00200         data = smb_base(inbuf) + smb_doff;
00201 
00202         if (numtowrite == 0) {
00203                 nwritten = 0;
00204         } else {
00205                 if(pipe_start_message_raw) {
00206                         /*
00207                          * For the start of a message in named pipe byte mode,
00208                          * the first two bytes are a length-of-pdu field. Ignore
00209                          * them (we don't trust the client). JRA.
00210                          */
00211                        if(numtowrite < 2) {
00212                                 DEBUG(0,("reply_pipe_write_and_X: start of message set and not enough data sent.(%u)\n",
00213                                         (unsigned int)numtowrite ));
00214                                 return (UNIXERROR(ERRDOS,ERRnoaccess));
00215                         }
00216 
00217                         data += 2;
00218                         numtowrite -= 2;
00219                 }                        
00220                 nwritten = write_to_pipe(p, data, numtowrite);
00221         }
00222 
00223         if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) {
00224                 return (UNIXERROR(ERRDOS,ERRnoaccess));
00225         }
00226   
00227         set_message(outbuf,6,0,True);
00228 
00229         nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten);
00230         SSVAL(outbuf,smb_vwv2,nwritten);
00231   
00232         DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
00233 
00234         return chain_reply(inbuf,outbuf,length,bufsize);
00235 }
00236 
00237 /****************************************************************************
00238  Reply to a read and X.
00239  This code is basically stolen from reply_read_and_X with some
00240  wrinkles to handle pipes.
00241 ****************************************************************************/
00242 
00243 int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
00244 {
00245         smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
00246         int smb_maxcnt = SVAL(inbuf,smb_vwv5);
00247         int smb_mincnt = SVAL(inbuf,smb_vwv6);
00248         int nread = -1;
00249         char *data;
00250         BOOL unused;
00251 
00252         /* we don't use the offset given to use for pipe reads. This
00253            is deliberate, instead we always return the next lump of
00254            data on the pipe */
00255 #if 0
00256         uint32 smb_offs = IVAL(inbuf,smb_vwv3);
00257 #endif
00258 
00259         if (!p) {
00260                 return(ERROR_DOS(ERRDOS,ERRbadfid));
00261         }
00262 
00263         set_message(outbuf,12,0,True);
00264         data = smb_buf(outbuf);
00265 
00266         nread = read_from_pipe(p, data, smb_maxcnt, &unused);
00267 
00268         if (nread < 0) {
00269                 return(UNIXERROR(ERRDOS,ERRnoaccess));
00270         }
00271   
00272         SSVAL(outbuf,smb_vwv5,nread);
00273         SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
00274         SSVAL(smb_buf(outbuf),-2,nread);
00275   
00276         DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
00277                  p->pnum, smb_mincnt, smb_maxcnt, nread));
00278 
00279         /* Ensure we set up the message length to include the data length read. */
00280         set_message_bcc(outbuf,nread);
00281         return chain_reply(inbuf,outbuf,length,bufsize);
00282 }
00283 
00284 /****************************************************************************
00285  Reply to a close.
00286 ****************************************************************************/
00287 
00288 int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
00289 {
00290         smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
00291         int outsize = set_message(outbuf,0,0,True);
00292 
00293         if (!p) {
00294                 return(ERROR_DOS(ERRDOS,ERRbadfid));
00295         }
00296 
00297         DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
00298 
00299         if (!close_rpc_pipe_hnd(p)) {
00300                 return ERROR_DOS(ERRDOS,ERRbadfid);
00301         }
00302         
00303         return(outsize);
00304 }

Sambaに対してSat Aug 29 21:23:24 2009に生成されました。  doxygen 1.4.7