2 Unix SMB/CIFS implementation.
4 packet handling for mailslot requests.
6 Copyright (C) Andrew Tridgell 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 This implements "Class 2 mailslots", i.e. the communication mechanism
25 used for all mailslot packets smaller then 425 bytes.
27 "Class 1 mailslots" (which use SMB) are used for messages larger
28 then 426 bytes and are supported on some systems. These are not implemented
29 in Samba4 yet, as there don't appear to be any core services that use
32 425 and 426-byte sized messages are not supported at all.
36 #include "lib/events/events.h"
37 #include "dlinklist.h"
38 #include "libcli/dgram/libdgram.h"
39 #include "lib/socket/socket.h"
42 destroy a mailslot handler
44 static int dgram_mailslot_destructor(void *ptr)
46 struct dgram_mailslot_handler *dgmslot =
47 talloc_get_type(ptr, struct dgram_mailslot_handler);
49 DLIST_REMOVE(dgmslot->dgmsock->mailslot_handlers, dgmslot);
54 start listening on a mailslot. talloc_free() the handle to stop listening
56 struct dgram_mailslot_handler *dgram_mailslot_listen(struct nbt_dgram_socket *dgmsock,
57 const char *mailslot_name,
58 dgram_mailslot_handler_t handler,
61 struct dgram_mailslot_handler *dgmslot;
63 dgmslot = talloc(dgmsock, struct dgram_mailslot_handler);
64 if (dgmslot == NULL) return NULL;
66 dgmslot->dgmsock = dgmsock;
67 dgmslot->mailslot_name = talloc_strdup(dgmslot, mailslot_name);
68 if (dgmslot->mailslot_name == NULL) {
72 dgmslot->handler = handler;
73 dgmslot->private = private;
75 DLIST_ADD(dgmsock->mailslot_handlers, dgmslot);
76 talloc_set_destructor(dgmslot, dgram_mailslot_destructor);
78 EVENT_FD_READABLE(dgmsock->fde);
84 find the handler for a specific mailslot name
86 struct dgram_mailslot_handler *dgram_mailslot_find(struct nbt_dgram_socket *dgmsock,
87 const char *mailslot_name)
89 struct dgram_mailslot_handler *h;
90 for (h=dgmsock->mailslot_handlers;h;h=h->next) {
91 if (strcasecmp(h->mailslot_name, mailslot_name) == 0) {
99 check that a datagram packet is a valid mailslot request, and return the
100 mailslot name if it is, otherwise return NULL
102 const char *dgram_mailslot_name(struct nbt_dgram_packet *packet)
104 if (packet->msg_type != DGRAM_DIRECT_UNIQUE &&
105 packet->msg_type != DGRAM_DIRECT_GROUP &&
106 packet->msg_type != DGRAM_BCAST) {
109 if (packet->data.msg.dgram_body_type != DGRAM_SMB) return NULL;
110 if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL;
111 return packet->data.msg.body.smb.body.trans.mailslot_name;
116 create a temporary mailslot handler for a reply mailslot, allocating
117 a new mailslot name using the given base name and a random integer extension
119 struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgmsock,
120 const char *mailslot_name,
121 dgram_mailslot_handler_t handler,
126 struct dgram_mailslot_handler *dgmslot;
128 /* try a 100 times at most */
129 for (i=0;i<100;i++) {
130 name = talloc_asprintf(dgmsock, "%s%03u",
132 generate_random() % 1000);
133 if (name == NULL) return NULL;
134 if (dgram_mailslot_find(dgmsock, name)) {
138 dgmslot = dgram_mailslot_listen(dgmsock, name, handler, private);
142 DEBUG(2,("Unable to create temporary mailslot from %s\n", mailslot_name));
148 send a mailslot request
150 NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock,
151 enum dgram_msg_type msg_type,
152 const char *mailslot_name,
153 struct nbt_name *dest_name,
154 const struct nbt_peer_socket *_dest,
155 struct nbt_name *src_name,
158 TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
159 struct nbt_dgram_packet packet;
160 struct nbt_peer_socket dest = *_dest;
161 struct dgram_message *msg;
162 struct dgram_smb_packet *smb;
163 struct smb_trans_body *trans;
166 if (dest.port == 0) {
167 dest.port = lp_dgram_port();
171 packet.msg_type = msg_type;
172 packet.flags = DGRAM_FLAG_FIRST | DGRAM_NODE_NBDD;
173 packet.dgram_id = generate_random() % UINT16_MAX;
174 packet.src_addr = socket_get_my_addr(dgmsock->sock, tmp_ctx);
175 packet.src_port = socket_get_my_port(dgmsock->sock);
177 msg = &packet.data.msg;
178 /* this length calculation is very crude - it should be based on gensize
180 msg->length = 138 + strlen(mailslot_name) + request->length;
183 msg->source_name = *src_name;
184 msg->dest_name = *dest_name;
185 msg->dgram_body_type = DGRAM_SMB;
187 smb = &msg->body.smb;
188 smb->smb_command = SMB_TRANSACTION;
190 trans = &smb->body.trans;
191 trans->total_data_count = request->length;
192 trans->timeout = 1000;
193 trans->data_count = request->length;
194 trans->data_offset = 70 + strlen(mailslot_name);
195 trans->opcode = 1; /* write mail slot */
198 trans->mailslot_name = mailslot_name;
199 trans->data = *request;
201 status = nbt_dgram_send(dgmsock, &packet, &dest);
203 talloc_free(tmp_ctx);
209 return the mailslot data portion from a mailslot packet
211 DATA_BLOB dgram_mailslot_data(struct nbt_dgram_packet *dgram)
213 struct smb_trans_body *trans = &dgram->data.msg.body.smb.body.trans;
214 DATA_BLOB ret = trans->data;
215 int pad = trans->data_offset - (70 + strlen(trans->mailslot_name));
217 if (pad < 0 || pad > ret.length) {
218 DEBUG(2,("Badly formatted data in mailslot - pad = %d\n", pad));
219 return data_blob(NULL, 0);