utils/smbfilter.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    SMB filter/socket plugin
00004    Copyright (C) Andrew Tridgell 1999
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "includes.h"
00022 
00023 #define SECURITY_MASK 0
00024 #define SECURITY_SET  0
00025 
00026 /* this forces non-unicode */
00027 #define CAPABILITY_MASK 0
00028 #define CAPABILITY_SET  0
00029 
00030 /* and non-unicode for the client too */
00031 #define CLI_CAPABILITY_MASK 0
00032 #define CLI_CAPABILITY_SET  0
00033 
00034 static char *netbiosname;
00035 static char packet[BUFFER_SIZE];
00036 
00037 static void save_file(const char *fname, void *ppacket, size_t length)
00038 {
00039         int fd;
00040         fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
00041         if (fd == -1) {
00042                 perror(fname);
00043                 return;
00044         }
00045         if (write(fd, ppacket, length) != length) {
00046                 fprintf(stderr,"Failed to write %s\n", fname);
00047                 return;
00048         }
00049         close(fd);
00050         printf("Wrote %ld bytes to %s\n", (unsigned long)length, fname);
00051 }
00052 
00053 static void filter_reply(char *buf)
00054 {
00055         int msg_type = CVAL(buf,0);
00056         int type = CVAL(buf,smb_com);
00057         unsigned x;
00058 
00059         if (msg_type) return;
00060 
00061         switch (type) {
00062 
00063         case SMBnegprot:
00064                 /* force the security bits */
00065                 x = CVAL(buf, smb_vwv1);
00066                 x = (x | SECURITY_SET) & ~SECURITY_MASK;
00067                 SCVAL(buf, smb_vwv1, x);
00068 
00069                 /* force the capabilities */
00070                 x = IVAL(buf,smb_vwv9+1);
00071                 x = (x | CAPABILITY_SET) & ~CAPABILITY_MASK;
00072                 SIVAL(buf, smb_vwv9+1, x);
00073                 break;
00074 
00075         }
00076 }
00077 
00078 static void filter_request(char *buf)
00079 {
00080         int msg_type = CVAL(buf,0);
00081         int type = CVAL(buf,smb_com);
00082         pstring name1,name2;
00083         unsigned x;
00084 
00085         if (msg_type) {
00086                 /* it's a netbios special */
00087                 switch (msg_type) {
00088                 case 0x81:
00089                         /* session request */
00090                         name_extract(buf,4,name1);
00091                         name_extract(buf,4 + name_len(buf + 4),name2);
00092                         d_printf("sesion_request: %s -> %s\n",
00093                                  name1, name2);
00094                         if (netbiosname) {
00095                                 /* replace the destination netbios name */
00096                                 name_mangle(netbiosname, buf+4, 0x20);
00097                         }
00098                 }
00099                 return;
00100         }
00101 
00102         /* it's an ordinary SMB request */
00103         switch (type) {
00104         case SMBsesssetupX:
00105                 /* force the client capabilities */
00106                 x = IVAL(buf,smb_vwv11);
00107                 d_printf("SMBsesssetupX cap=0x%08x\n", x);
00108                 d_printf("pwlen=%d/%d\n", SVAL(buf, smb_vwv7), SVAL(buf, smb_vwv8));
00109                 system("mv sessionsetup.dat sessionsetup1.dat");
00110                 save_file("sessionsetup.dat", smb_buf(buf), SVAL(buf, smb_vwv7));
00111                 x = (x | CLI_CAPABILITY_SET) & ~CLI_CAPABILITY_MASK;
00112                 SIVAL(buf, smb_vwv11, x);
00113                 break;
00114         }
00115 
00116 }
00117 
00118 
00119 static void filter_child(int c, struct in_addr dest_ip)
00120 {
00121         int s;
00122 
00123         /* we have a connection from a new client, now connect to the server */
00124         s = open_socket_out(SOCK_STREAM, &dest_ip, 445, LONG_CONNECT_TIMEOUT);
00125 
00126         if (s == -1) {
00127                 d_printf("Unable to connect to %s\n", inet_ntoa(dest_ip));
00128                 exit(1);
00129         }
00130 
00131         while (c != -1 || s != -1) {
00132                 fd_set fds;
00133                 int num;
00134                 
00135                 FD_ZERO(&fds);
00136                 if (s != -1) FD_SET(s, &fds);
00137                 if (c != -1) FD_SET(c, &fds);
00138 
00139                 num = sys_select_intr(MAX(s+1, c+1),&fds,NULL,NULL,NULL);
00140                 if (num <= 0) continue;
00141                 
00142                 if (c != -1 && FD_ISSET(c, &fds)) {
00143                         if (!receive_smb(c, packet, BUFFER_SIZE, 0)) {
00144                                 d_printf("client closed connection\n");
00145                                 exit(0);
00146                         }
00147                         filter_request(packet);
00148                         if (!send_smb(s, packet)) {
00149                                 d_printf("server is dead\n");
00150                                 exit(1);
00151                         }                       
00152                 }
00153                 if (s != -1 && FD_ISSET(s, &fds)) {
00154                         if (!receive_smb(s, packet, BUFFER_SIZE, 0)) {
00155                                 d_printf("server closed connection\n");
00156                                 exit(0);
00157                         }
00158                         filter_reply(packet);
00159                         if (!send_smb(c, packet)) {
00160                                 d_printf("client is dead\n");
00161                                 exit(1);
00162                         }                       
00163                 }
00164         }
00165         d_printf("Connection closed\n");
00166         exit(0);
00167 }
00168 
00169 
00170 static void start_filter(char *desthost)
00171 {
00172         int s, c;
00173         struct in_addr dest_ip;
00174 
00175         CatchChild();
00176 
00177         /* start listening on port 445 locally */
00178         s = open_socket_in(SOCK_STREAM, 445, 0, 0, True);
00179         
00180         if (s == -1) {
00181                 d_printf("bind failed\n");
00182                 exit(1);
00183         }
00184 
00185         if (listen(s, 5) == -1) {
00186                 d_printf("listen failed\n");
00187         }
00188 
00189         if (!resolve_name(desthost, &dest_ip, 0x20)) {
00190                 d_printf("Unable to resolve host %s\n", desthost);
00191                 exit(1);
00192         }
00193 
00194         while (1) {
00195                 fd_set fds;
00196                 int num;
00197                 struct sockaddr addr;
00198                 socklen_t in_addrlen = sizeof(addr);
00199                 
00200                 FD_ZERO(&fds);
00201                 FD_SET(s, &fds);
00202 
00203                 num = sys_select_intr(s+1,&fds,NULL,NULL,NULL);
00204                 if (num > 0) {
00205                         c = accept(s, &addr, &in_addrlen);
00206                         if (c != -1) {
00207                                 if (fork() == 0) {
00208                                         close(s);
00209                                         filter_child(c, dest_ip);
00210                                         exit(0);
00211                                 } else {
00212                                         close(c);
00213                                 }
00214                         }
00215                 }
00216         }
00217 }
00218 
00219 
00220 int main(int argc, char *argv[])
00221 {
00222         char *desthost;
00223         pstring configfile;
00224 
00225         setup_logging(argv[0],True);
00226   
00227         pstrcpy(configfile,dyn_CONFIGFILE);
00228  
00229         if (argc < 2) {
00230                 fprintf(stderr,"smbfilter <desthost> <netbiosname>\n");
00231                 exit(1);
00232         }
00233 
00234         desthost = argv[1];
00235         if (argc > 2) {
00236                 netbiosname = argv[2];
00237         }
00238 
00239         if (!lp_load(configfile,True,False,False,True)) {
00240                 d_printf("Unable to load config file\n");
00241         }
00242 
00243         start_filter(desthost);
00244         return 0;
00245 }

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