2 Unix SMB/Netbios implementation.
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.
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 static char packet[BUFFER_SIZE];
38 extern int DEBUGLEVEL;
41 static uint16 mid_offset = 0x0;
43 /****************************************************************************
44 terminate sockent connection
45 ****************************************************************************/
46 static void free_sock(void *sock)
50 struct cli_state *n = (struct cli_state*)sock;
51 cli_net_use_del(n->desthost, &n->usr,
57 static struct cli_state *init_client_connection(int c)
60 struct user_creds usr;
74 DEBUG(10,("init_client_connection: first request\n"));
76 rl = read(c, &buf, sizeof(len));
78 if (rl != sizeof(len))
80 DEBUG(0,("Unable to read length\n"));
81 dump_data(0, buf, sizeof(len));
87 if (len > sizeof(buf))
89 DEBUG(0,("length %d too long\n", len));
93 rl = read(c, buf, len);
97 DEBUG(0,("Unable to read from connection\n"));
101 #ifdef DEBUG_PASSWORD
102 dump_data(100, buf, rl);
104 /* make a static data parsing structure from the api_fd_reply data */
105 prs_init(&ps, 0, 4, 0, True);
106 mem_create(ps.data, buf, 0, len, 0, False);
108 if (!creds_io_cmd("creds", &cmd, &ps, 0))
110 DEBUG(0,("Unable to parse credentials\n"));
111 mem_free_data(ps.data);
115 mem_free_data(ps.data);
119 DEBUG(0,("Buffer size %d %d!\n", ps.offset, rl));
130 case AGENT_CMD_CON_REUSE:
138 DEBUG(0,("unknown command %d\n", cmd.command));
146 n = cli_net_use_add(cmd.name, &usr.ntc, False, reuse);
150 DEBUG(0,("Unable to connect to %s\n", cmd.name));
154 mid_offset += MIN(MAX(n->max_mux, 1), MAX_MAX_MUX_LIMIT);
156 if (mid_offset > 0xffff)
160 DEBUG(10,("new mid offset: %d\n", mid_offset));
162 if (write(c, n, sizeof(*n)) < 0)
164 DEBUG(0,("Could not write connection down pipe.\n"));
165 cli_net_use_del(cmd.name, &usr.ntc, False, NULL);
173 static void filter_reply(char *buf, int moff)
175 int msg_type = CVAL(buf,0);
178 if (msg_type != 0x0) return;
181 x = SVAL(buf, smb_mid);
193 SCVAL(buf, smb_mid, x);
197 static BOOL process_cli_sock(struct sock_redir **socks, uint32 num_socks,
198 struct sock_redir *sock)
200 struct cli_state *n = (struct cli_state*)sock->n;
203 n = init_client_connection(sock->c);
209 sock->s_id = mid_offset;
214 if (!receive_smb(sock->c, packet, 0))
216 DEBUG(0,("client closed connection\n"));
220 filter_reply(packet, sock->s_id);
221 /* ignore keep-alives */
222 if (CVAL(packet, 0) != 0x85)
224 if (!send_smb(sock->s, packet))
226 DEBUG(0,("server is dead\n"));
234 static int get_smbmid(char *buf)
236 int msg_type = CVAL(buf,0);
243 return SVAL(buf,smb_mid);
246 static BOOL process_srv_sock(struct sock_redir **socks, uint32 num_socks,
251 if (!receive_smb(fd, packet, 0))
253 DEBUG(0,("server closed connection\n"));
257 smbmid = get_smbmid(packet);
259 DEBUG(10,("process_srv_sock:\tfd:\t%d\tmid:\t%d\n", fd, smbmid));
266 for (i = 0; i < num_socks; i++)
270 if (socks[i] == NULL || socks[i]->n == NULL)
274 moff = socks[i]->s_id;
275 n = (struct cli_state*)socks[i]->n;
276 DEBUG(10,("list:\tfd:\t%d\tmid:\t%d\tmoff:\t%d\n",
280 if (smbmid != n->mid + moff)
284 filter_reply(packet, -moff);
285 if (!send_smb(socks[i]->c, packet))
287 DEBUG(0,("client is dead\n"));
295 static int get_agent_sock(char *id)
300 slprintf(dir, sizeof(dir)-1, "/tmp/.smb.%d", getuid());
301 slprintf(path, sizeof(path)-1, "%s/agent", dir);
303 return create_pipe_socket(dir, S_IRUSR|S_IWUSR|S_IXUSR, path, 0);
306 static void start_smb_agent(void)
308 struct vagent_ops va =
324 /****************************************************************************
326 ****************************************************************************/
327 static void usage(char *pname)
329 printf("Usage: %s [-D]", pname);
331 printf("\nVersion %s\n",VERSION);
332 printf("\t-D run as a daemon\n");
333 printf("\t-h usage\n");
337 int main(int argc, char *argv[])
340 BOOL is_daemon = False;
342 extern pstring debugf;
346 pstrcpy(configfile,CONFIGFILE);
348 while ((opt = getopt(argc, argv, "Dh")) != EOF)
366 slprintf(debugf, sizeof(debugf)-1, "log.%s", argv[0]);
367 setup_logging(argv[0], !is_daemon);
369 charset_initialise();
371 if (!lp_load(configfile,True,False,False))
373 DEBUG(0,("Unable to load config file\n"));
378 DEBUG(0,("%s: becoming daemon\n", argv[0]));