preparing for release of alpha.2.5
[Samba.git] / source / utils / nmb-agent.c
blobcdb260ad86335cb57d96711cc04dee7b982c71ec
1 /*
2 Unix SMB/Netbios implementation.
3 Version 2
4 SMB agent/socket plugin
5 Copyright (C) Andrew Tridgell 1999
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
23 #include "smb.h"
25 #define SECURITY_MASK 0
26 #define SECURITY_SET 0
28 /* this forces non-unicode */
29 #define CAPABILITY_MASK CAP_UNICODE
30 #define CAPABILITY_SET 0
32 /* and non-unicode for the client too */
33 #define CLI_CAPABILITY_MASK CAP_UNICODE
34 #define CLI_CAPABILITY_SET 0
36 extern int DEBUGLEVEL;
38 static int ClientNMB = -1;
40 /****************************************************************************
41 terminate sockent connection
42 ****************************************************************************/
43 static void free_sock(void *sock)
45 if (sock != NULL)
47 free(sock);
51 static void filter_reply(struct packet_struct *p, int tr_id)
53 p->packet.nmb.header.name_trn_id = tr_id;
56 static BOOL process_cli_sock(struct sock_redir **socks,
57 uint32 num_socks,
58 struct sock_redir *sock)
60 struct packet_struct *p;
61 struct nmb_state *nmb;
62 static uint16 trn_id = 0x0;
64 p = receive_packet(sock->c, NMB_SOCK_PACKET, 0);
65 if (p == NULL)
67 DEBUG(0,("client closed connection\n"));
68 return False;
71 nmb = (struct nmb_state*)malloc(sizeof(struct nmb_state));
72 if (nmb == NULL)
74 free_packet(p);
75 return False;
78 sock->s = ClientNMB;
79 sock->n = nmb;
80 sock->c_id = p->packet.nmb.header.name_trn_id;
81 sock->s_id = trn_id;
83 trn_id++;
84 if (trn_id > 0xffff)
86 trn_id = 0x0;
89 DEBUG(10,("new trn_id: %d\n", trn_id));
91 filter_reply(p, sock->s_id);
93 nmb->ip = p->ip;
94 nmb->port = p->port;
96 p->fd = ClientNMB;
97 p->packet_type = NMB_PACKET;
99 if (!send_packet(p))
101 DEBUG(0,("server is dead\n"));
102 free_packet(p);
103 return False;
105 free_packet(p);
106 return True;
109 static BOOL process_srv_sock(struct sock_redir **socks,
110 uint32 num_socks,
111 int fd)
113 int nmb_id;
114 int tr_id;
115 int i;
117 struct packet_struct *p;
119 p = receive_packet(fd, NMB_PACKET, 0);
120 if (p == NULL)
122 return True;
125 #if 0
126 if (!p->packet.nmb.header.response)
128 DEBUG(10,("skipping response packet\n"));
129 free_packet(p);
130 return True;
132 #endif
134 nmb_id = p->packet.nmb.header.name_trn_id;
135 DEBUG(10,("process_srv_sock:\tnmb_id:\t%d\n", nmb_id));
137 for (i = 0; i < num_socks; i++)
139 if (socks[i] == NULL)
141 continue;
144 tr_id = socks[i]->s_id;
146 DEBUG(10,("list:\tfd:\t%d\tc_id:\t%d\ttr_id:\t%d\n",
147 socks[i]->c,
148 socks[i]->c_id,
149 tr_id));
151 if (nmb_id != tr_id)
153 continue;
156 filter_reply(p, socks[i]->c_id);
157 p->fd = socks[i]->c;
158 p->packet_type = NMB_SOCK_PACKET;
160 if (!send_packet(p))
162 DEBUG(0,("client is dead\n"));
163 return False;
165 return True;
167 return True;
170 static int get_agent_sock(char *id)
172 int s;
173 fstring dir;
174 fstring path;
176 slprintf(dir, sizeof(dir)-1, "/tmp/.nmb");
177 slprintf(path, sizeof(path)-1, "%s/agent", dir);
179 s = create_pipe_socket(dir, 0777, path, 0777);
181 if (s == -1)
182 return -1;
183 /* ready to listen */
184 if (listen(s, 5) == -1) {
185 DEBUG(0,("listen: %s\n", strerror(errno)));
186 close(s);
187 return -1;
189 return s;
192 static void start_nmb_agent(void)
194 struct vagent_ops va =
196 free_sock,
197 get_agent_sock,
198 process_cli_sock,
199 process_srv_sock,
200 NULL,
201 NULL,
205 CatchChild();
207 start_agent(&va);
210 /******************************************************************************
211 open the socket communication
212 *****************************************************************************/
213 static BOOL open_sockets(BOOL isdaemon, int port)
215 /* The sockets opened here will be used to receive broadcast
216 packets *only*. Interface specific sockets are opened in
217 make_subnet() in namedbsubnet.c. Thus we bind to the
218 address "0.0.0.0". The parameter 'socket address' is
219 now deprecated.
222 if ( isdaemon )
223 ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
224 else
225 ClientNMB = 0;
227 if ( ClientNMB == -1 )
228 return( False );
230 /* we are never interested in SIGPIPE */
231 BlockSignals(True,SIGPIPE);
233 set_socket_options( ClientNMB, "SO_BROADCAST" );
235 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
236 return( True );
237 } /* open_sockets */
239 /****************************************************************************
240 usage on the program
241 ****************************************************************************/
242 static void usage(char *pname)
244 printf("Usage: %s [-D]", pname);
246 printf("\nVersion %s\n",VERSION);
247 printf("\t-D run as a daemon\n");
248 printf("\t-h usage\n");
249 printf("\n");
252 int main(int argc, char *argv[])
254 pstring configfile;
255 BOOL is_daemon = False;
256 int opt;
257 extern pstring debugf;
258 int global_nmb_port = NMB_PORT;
260 TimeInit();
262 pstrcpy(configfile,CONFIGFILE);
264 while ((opt = getopt(argc, argv, "Dh")) != EOF)
266 switch (opt)
268 case 'D':
270 is_daemon = True;
271 break;
273 case 'h':
274 default:
276 usage(argv[0]);
277 break;
282 slprintf(debugf, sizeof(debugf)-1, "log.%s", argv[0]);
283 setup_logging(argv[0], !is_daemon);
285 charset_initialise();
287 if (!lp_load(configfile,True,False,False))
289 DEBUG(0,("Unable to load config file\n"));
292 if (is_daemon)
294 DEBUG(0,("%s: becoming daemon\n", argv[0]));
295 become_daemon();
298 if (!open_sockets(True, global_nmb_port))
300 return 1;
303 start_nmb_agent();
305 return 0;