lib: Fix error talloc leaks in ctdb_read_packet()
[vlendec/samba-autobuild/.git] / source3 / lib / ctdbd_conn.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba internal messaging functions
4    Copyright (C) 2007 by Volker Lendecke
5    Copyright (C) 2007 by Andrew Tridgell
6
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 3 of the License, or
10    (at your option) any later version.
11
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.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "util_tdb.h"
23 #include "serverid.h"
24 #include "ctdbd_conn.h"
25 #include "system/select.h"
26 #include "lib/sys_rw_data.h"
27 #include "lib/util/iov_buf.h"
28
29 #include "messages.h"
30
31 /* paths to these include files come from --with-ctdb= in configure */
32
33 #include "ctdb.h"
34 #include "ctdb_private.h"
35
36 struct ctdbd_srvid_cb {
37         uint64_t srvid;
38         int (*cb)(uint32_t src_vnn, uint32_t dst_vnn,
39                   uint64_t dst_srvid,
40                   const uint8_t *msg, size_t msglen,
41                   void *private_data);
42         void *private_data;
43 };
44
45 struct ctdbd_connection {
46         const char *sockname;   /* Needed in ctdbd_traverse */
47         struct messaging_context *msg_ctx;
48         uint32_t reqid;
49         uint32_t our_vnn;
50         uint64_t rand_srvid;
51         struct ctdbd_srvid_cb *callbacks;
52         int fd;
53         struct tevent_fd *fde;
54         int timeout;
55 };
56
57 static uint32_t ctdbd_next_reqid(struct ctdbd_connection *conn)
58 {
59         conn->reqid += 1;
60         if (conn->reqid == 0) {
61                 conn->reqid += 1;
62         }
63         return conn->reqid;
64 }
65
66 static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
67                               uint32_t vnn, uint32_t opcode,
68                               uint64_t srvid, uint32_t flags, TDB_DATA data,
69                               TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
70                               int *cstatus);
71
72 /*
73  * exit on fatal communications errors with the ctdbd daemon
74  */
75 static void cluster_fatal(const char *why)
76 {
77         DEBUG(0,("cluster fatal event: %s - exiting immediately\n", why));
78         /* we don't use smb_panic() as we don't want to delay to write
79            a core file. We need to release this process id immediately
80            so that someone else can take over without getting sharing
81            violations */
82         _exit(1);
83 }
84
85 /*
86  *
87  */
88 static void ctdb_packet_dump(struct ctdb_req_header *hdr)
89 {
90         if (DEBUGLEVEL < 11) {
91                 return;
92         }
93         DEBUGADD(11, ("len=%d, magic=%x, vers=%d, gen=%d, op=%d, reqid=%d\n",
94                       (int)hdr->length, (int)hdr->ctdb_magic,
95                       (int)hdr->ctdb_version, (int)hdr->generation,
96                       (int)hdr->operation, (int)hdr->reqid));
97 }
98
99 /*
100  * Register a srvid with ctdbd
101  */
102 NTSTATUS register_with_ctdbd(struct ctdbd_connection *conn, uint64_t srvid,
103                              int (*cb)(uint32_t src_vnn, uint32_t dst_vnn,
104                                        uint64_t dst_srvid,
105                                        const uint8_t *msg, size_t msglen,
106                                        void *private_data),
107                              void *private_data)
108 {
109
110         NTSTATUS status;
111         int cstatus;
112         size_t num_callbacks;
113         struct ctdbd_srvid_cb *tmp;
114
115         status = ctdbd_control(conn, CTDB_CURRENT_NODE,
116                                CTDB_CONTROL_REGISTER_SRVID, srvid, 0,
117                                tdb_null, NULL, NULL, &cstatus);
118         if (!NT_STATUS_IS_OK(status)) {
119                 return status;
120         }
121
122         num_callbacks = talloc_array_length(conn->callbacks);
123
124         tmp = talloc_realloc(conn, conn->callbacks, struct ctdbd_srvid_cb,
125                              num_callbacks + 1);
126         if (tmp == NULL) {
127                 return NT_STATUS_NO_MEMORY;
128         }
129         conn->callbacks = tmp;
130
131         conn->callbacks[num_callbacks] = (struct ctdbd_srvid_cb) {
132                 .srvid = srvid, .cb = cb, .private_data = private_data
133         };
134
135         return NT_STATUS_OK;
136 }
137
138 static int ctdbd_msg_call_back(struct ctdbd_connection *conn,
139                                struct ctdb_req_message *msg)
140 {
141         size_t msg_len;
142         size_t i, num_callbacks;
143
144         msg_len = msg->hdr.length;
145         if (msg_len < offsetof(struct ctdb_req_message, data)) {
146                 DEBUG(10, ("%s: len %u too small\n", __func__,
147                            (unsigned)msg_len));
148                 return 0;
149         }
150         msg_len -= offsetof(struct ctdb_req_message, data);
151
152         if (msg_len < msg->datalen) {
153                 DEBUG(10, ("%s: msg_len=%u < msg->datalen=%u\n", __func__,
154                            (unsigned)msg_len, (unsigned)msg->datalen));
155                 return 0;
156         }
157
158         num_callbacks = talloc_array_length(conn->callbacks);
159
160         for (i=0; i<num_callbacks; i++) {
161                 struct ctdbd_srvid_cb *cb = &conn->callbacks[i];
162
163                 if ((cb->srvid == msg->srvid) && (cb->cb != NULL)) {
164                         int ret;
165
166                         ret = cb->cb(msg->hdr.srcnode, msg->hdr.destnode,
167                                      msg->srvid, msg->data, msg->datalen,
168                                      cb->private_data);
169                         if (ret != 0) {
170                                 return ret;
171                         }
172                 }
173         }
174         return 0;
175 }
176
177 /*
178  * get our vnn from the cluster
179  */
180 static NTSTATUS get_cluster_vnn(struct ctdbd_connection *conn, uint32_t *vnn)
181 {
182         int32_t cstatus=-1;
183         NTSTATUS status;
184         status = ctdbd_control(conn,
185                                CTDB_CURRENT_NODE, CTDB_CONTROL_GET_PNN, 0, 0,
186                                tdb_null, NULL, NULL, &cstatus);
187         if (!NT_STATUS_IS_OK(status)) {
188                 DEBUG(1, ("ctdbd_control failed: %s\n", nt_errstr(status)));
189                 return status;
190         }
191         *vnn = (uint32_t)cstatus;
192         return status;
193 }
194
195 /*
196  * Are we active (i.e. not banned or stopped?)
197  */
198 static bool ctdbd_working(struct ctdbd_connection *conn, uint32_t vnn)
199 {
200         int32_t cstatus=-1;
201         NTSTATUS status;
202         TDB_DATA outdata;
203         struct ctdb_node_map *m;
204         uint32_t failure_flags;
205         bool ret = false;
206         int i;
207
208         status = ctdbd_control(conn, CTDB_CURRENT_NODE,
209                                CTDB_CONTROL_GET_NODEMAP, 0, 0,
210                                tdb_null, talloc_tos(), &outdata, &cstatus);
211         if (!NT_STATUS_IS_OK(status)) {
212                 DEBUG(1, ("ctdbd_control failed: %s\n", nt_errstr(status)));
213                 return false;
214         }
215         if ((cstatus != 0) || (outdata.dptr == NULL)) {
216                 DEBUG(2, ("Received invalid ctdb data\n"));
217                 return false;
218         }
219
220         m = (struct ctdb_node_map *)outdata.dptr;
221
222         for (i=0; i<m->num; i++) {
223                 if (vnn == m->nodes[i].pnn) {
224                         break;
225                 }
226         }
227
228         if (i == m->num) {
229                 DEBUG(2, ("Did not find ourselves (node %d) in nodemap\n",
230                           (int)vnn));
231                 goto fail;
232         }
233
234         failure_flags = NODE_FLAGS_BANNED | NODE_FLAGS_DISCONNECTED
235                 | NODE_FLAGS_PERMANENTLY_DISABLED | NODE_FLAGS_STOPPED;
236
237         if ((m->nodes[i].flags & failure_flags) != 0) {
238                 DEBUG(2, ("Node has status %x, not active\n",
239                           (int)m->nodes[i].flags));
240                 goto fail;
241         }
242
243         ret = true;
244 fail:
245         TALLOC_FREE(outdata.dptr);
246         return ret;
247 }
248
249 uint32_t ctdbd_vnn(const struct ctdbd_connection *conn)
250 {
251         return conn->our_vnn;
252 }
253
254 /*
255  * Get us a ctdb connection
256  */
257
258 static int ctdbd_connect(const char *sockname, int *pfd)
259 {
260         struct sockaddr_un addr = { 0, };
261         int fd;
262         socklen_t salen;
263         size_t namelen;
264
265         fd = socket(AF_UNIX, SOCK_STREAM, 0);
266         if (fd == -1) {
267                 int err = errno;
268                 DEBUG(3, ("Could not create socket: %s\n", strerror(err)));
269                 return err;
270         }
271
272         addr.sun_family = AF_UNIX;
273
274         namelen = strlcpy(addr.sun_path, sockname, sizeof(addr.sun_path));
275         if (namelen >= sizeof(addr.sun_path)) {
276                 DEBUG(3, ("%s: Socket name too long: %s\n", __func__,
277                           sockname));
278                 close(fd);
279                 return ENAMETOOLONG;
280         }
281
282         salen = sizeof(struct sockaddr_un);
283
284         if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
285                 int err = errno;
286                 DEBUG(1, ("connect(%s) failed: %s\n", sockname,
287                           strerror(err)));
288                 close(fd);
289                 return err;
290         }
291
292         *pfd = fd;
293         return 0;
294 }
295
296 static int ctdb_read_packet(int fd, int timeout, TALLOC_CTX *mem_ctx,
297                             struct ctdb_req_header **result)
298 {
299         struct ctdb_req_header *req;
300         int ret, revents;
301         uint32_t msglen;
302         ssize_t nread;
303
304         if (timeout != -1) {
305                 ret = poll_one_fd(fd, POLLIN, timeout, &revents);
306                 if (ret == -1) {
307                         return errno;
308                 }
309                 if (ret == 0) {
310                         return ETIMEDOUT;
311                 }
312                 if (ret != 1) {
313                         return EIO;
314                 }
315         }
316
317         nread = read_data(fd, &msglen, sizeof(msglen));
318         if (nread == -1) {
319                 return errno;
320         }
321         if (nread == 0) {
322                 return EIO;
323         }
324
325         if (msglen < sizeof(struct ctdb_req_header)) {
326                 return EIO;
327         }
328
329         req = talloc_size(mem_ctx, msglen);
330         if (req == NULL) {
331                 return ENOMEM;
332         }
333         talloc_set_name_const(req, "struct ctdb_req_header");
334
335         req->length = msglen;
336
337         nread = read_data(fd, ((char *)req) + sizeof(msglen),
338                           msglen - sizeof(msglen));
339         if (nread == -1) {
340                 TALLOC_FREE(req);
341                 return errno;
342         }
343         if (nread == 0) {
344                 TALLOC_FREE(req);
345                 return EIO;
346         }
347
348         *result = req;
349         return 0;
350 }
351
352 /*
353  * Read a full ctdbd request. If we have a messaging context, defer incoming
354  * messages that might come in between.
355  */
356
357 static int ctdb_read_req(struct ctdbd_connection *conn, uint32_t reqid,
358                          TALLOC_CTX *mem_ctx, struct ctdb_req_header **result)
359 {
360         struct ctdb_req_header *hdr;
361         int ret;
362
363  next_pkt:
364
365         ret = ctdb_read_packet(conn->fd, conn->timeout, mem_ctx, &hdr);
366         if (ret != 0) {
367                 DEBUG(0, ("ctdb_read_packet failed: %s\n", strerror(ret)));
368                 cluster_fatal("ctdbd died\n");
369         }
370
371         DEBUG(11, ("Received ctdb packet\n"));
372         ctdb_packet_dump(hdr);
373
374         if (hdr->operation == CTDB_REQ_MESSAGE) {
375                 struct ctdb_req_message *msg = (struct ctdb_req_message *)hdr;
376
377                 if (conn->msg_ctx == NULL) {
378                         DEBUG(1, ("Got a message without having a msg ctx, "
379                                   "dropping msg %llu\n",
380                                   (long long unsigned)msg->srvid));
381                         TALLOC_FREE(hdr);
382                         goto next_pkt;
383                 }
384
385                 ret = ctdbd_msg_call_back(conn, msg);
386                 if (ret != 0) {
387                         TALLOC_FREE(hdr);
388                         return ret;
389                 }
390
391                 TALLOC_FREE(hdr);
392                 goto next_pkt;
393         }
394
395         if ((reqid != 0) && (hdr->reqid != reqid)) {
396                 /* we got the wrong reply */
397                 DEBUG(0,("Discarding mismatched ctdb reqid %u should have "
398                          "been %u\n", hdr->reqid, reqid));
399                 TALLOC_FREE(hdr);
400                 goto next_pkt;
401         }
402
403         *result = talloc_move(mem_ctx, &hdr);
404
405         return 0;
406 }
407
408 static int ctdbd_connection_destructor(struct ctdbd_connection *c)
409 {
410         TALLOC_FREE(c->fde);
411         if (c->fd != -1) {
412                 close(c->fd);
413                 c->fd = -1;
414         }
415         return 0;
416 }
417 /*
418  * Get us a ctdbd connection
419  */
420
421 static NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,
422                                       const char *sockname, int timeout,
423                                       struct ctdbd_connection **pconn)
424 {
425         struct ctdbd_connection *conn;
426         int ret;
427         NTSTATUS status;
428
429         if (!(conn = talloc_zero(mem_ctx, struct ctdbd_connection))) {
430                 DEBUG(0, ("talloc failed\n"));
431                 return NT_STATUS_NO_MEMORY;
432         }
433
434         conn->sockname = talloc_strdup(conn, sockname);
435         if (conn->sockname == NULL) {
436                 DBG_ERR("%s: talloc failed\n", __func__);
437                 status = NT_STATUS_NO_MEMORY;
438                 goto fail;
439         }
440
441         conn->timeout = timeout;
442
443         if (conn->timeout == 0) {
444                 conn->timeout = -1;
445         }
446
447         ret = ctdbd_connect(conn->sockname, &conn->fd);
448         if (ret != 0) {
449                 status = map_nt_error_from_unix(ret);
450                 DEBUG(1, ("ctdbd_connect failed: %s\n", strerror(ret)));
451                 goto fail;
452         }
453         talloc_set_destructor(conn, ctdbd_connection_destructor);
454
455         status = get_cluster_vnn(conn, &conn->our_vnn);
456
457         if (!NT_STATUS_IS_OK(status)) {
458                 DEBUG(10, ("get_cluster_vnn failed: %s\n", nt_errstr(status)));
459                 goto fail;
460         }
461
462         if (!ctdbd_working(conn, conn->our_vnn)) {
463                 DEBUG(2, ("Node is not working, can not connect\n"));
464                 status = NT_STATUS_INTERNAL_DB_ERROR;
465                 goto fail;
466         }
467
468         generate_random_buffer((unsigned char *)&conn->rand_srvid,
469                                sizeof(conn->rand_srvid));
470
471         status = register_with_ctdbd(conn, conn->rand_srvid, NULL, NULL);
472
473         if (!NT_STATUS_IS_OK(status)) {
474                 DEBUG(5, ("Could not register random srvid: %s\n",
475                           nt_errstr(status)));
476                 goto fail;
477         }
478
479         *pconn = conn;
480         return NT_STATUS_OK;
481
482  fail:
483         TALLOC_FREE(conn);
484         return status;
485 }
486
487 /*
488  * Get us a ctdbd connection and register us as a process
489  */
490
491 NTSTATUS ctdbd_messaging_connection(TALLOC_CTX *mem_ctx,
492                                     const char *sockname, int timeout,
493                                     struct ctdbd_connection **pconn)
494 {
495         struct ctdbd_connection *conn;
496         NTSTATUS status;
497
498         status = ctdbd_init_connection(mem_ctx, sockname, timeout, &conn);
499
500         if (!NT_STATUS_IS_OK(status)) {
501                 return status;
502         }
503
504         status = register_with_ctdbd(conn, MSG_SRVID_SAMBA, NULL, NULL);
505         if (!NT_STATUS_IS_OK(status)) {
506                 goto fail;
507         }
508
509         *pconn = conn;
510         return NT_STATUS_OK;
511
512  fail:
513         TALLOC_FREE(conn);
514         return status;
515 }
516
517 struct messaging_context *ctdb_conn_msg_ctx(struct ctdbd_connection *conn)
518 {
519         return conn->msg_ctx;
520 }
521
522 int ctdbd_conn_get_fd(struct ctdbd_connection *conn)
523 {
524         return conn->fd;
525 }
526
527 /*
528  * Packet handler to receive and handle a ctdb message
529  */
530 static int ctdb_handle_message(struct ctdbd_connection *conn,
531                                struct ctdb_req_header *hdr)
532 {
533         struct ctdb_req_message *msg;
534
535         if (hdr->operation != CTDB_REQ_MESSAGE) {
536                 DEBUG(0, ("Received async msg of type %u, discarding\n",
537                           hdr->operation));
538                 return EINVAL;
539         }
540
541         msg = (struct ctdb_req_message *)hdr;
542
543         ctdbd_msg_call_back(conn, msg);
544
545         return 0;
546 }
547
548 /*
549  * The ctdbd socket is readable asynchronuously
550  */
551
552 static void ctdbd_socket_handler(struct tevent_context *event_ctx,
553                                  struct tevent_fd *event,
554                                  uint16_t flags,
555                                  void *private_data)
556 {
557         struct ctdbd_connection *conn = talloc_get_type_abort(
558                 private_data, struct ctdbd_connection);
559         struct ctdb_req_header *hdr = NULL;
560         int ret;
561
562         ret = ctdb_read_packet(conn->fd, conn->timeout, talloc_tos(), &hdr);
563         if (ret != 0) {
564                 DEBUG(0, ("ctdb_read_packet failed: %s\n", strerror(ret)));
565                 cluster_fatal("ctdbd died\n");
566         }
567
568         ret = ctdb_handle_message(conn, hdr);
569
570         TALLOC_FREE(hdr);
571
572         if (ret != 0) {
573                 DEBUG(10, ("could not handle incoming message: %s\n",
574                            strerror(ret)));
575         }
576 }
577
578 /*
579  * Prepare a ctdbd connection to receive messages
580  */
581
582 NTSTATUS ctdbd_register_msg_ctx(struct ctdbd_connection *conn,
583                                 struct messaging_context *msg_ctx)
584 {
585         SMB_ASSERT(conn->msg_ctx == NULL);
586         SMB_ASSERT(conn->fde == NULL);
587
588         if (!(conn->fde = tevent_add_fd(messaging_tevent_context(msg_ctx),
589                                        conn,
590                                        conn->fd,
591                                        TEVENT_FD_READ,
592                                        ctdbd_socket_handler,
593                                        conn))) {
594                 DEBUG(0, ("event_add_fd failed\n"));
595                 return NT_STATUS_NO_MEMORY;
596         }
597
598         conn->msg_ctx = msg_ctx;
599
600         return NT_STATUS_OK;
601 }
602
603 NTSTATUS ctdbd_messaging_send_iov(struct ctdbd_connection *conn,
604                                   uint32_t dst_vnn, uint64_t dst_srvid,
605                                   const struct iovec *iov, int iovlen)
606 {
607         struct ctdb_req_message r;
608         struct iovec iov2[iovlen+1];
609         size_t buflen = iov_buflen(iov, iovlen);
610         ssize_t nwritten;
611
612         r.hdr.length = offsetof(struct ctdb_req_message, data) + buflen;
613         r.hdr.ctdb_magic = CTDB_MAGIC;
614         r.hdr.ctdb_version = CTDB_PROTOCOL;
615         r.hdr.generation = 1;
616         r.hdr.operation  = CTDB_REQ_MESSAGE;
617         r.hdr.destnode   = dst_vnn;
618         r.hdr.srcnode    = conn->our_vnn;
619         r.hdr.reqid      = 0;
620         r.srvid          = dst_srvid;
621         r.datalen        = buflen;
622
623         DEBUG(10, ("ctdbd_messaging_send: Sending ctdb packet\n"));
624         ctdb_packet_dump(&r.hdr);
625
626         iov2[0].iov_base = &r;
627         iov2[0].iov_len = offsetof(struct ctdb_req_message, data);
628         memcpy(&iov2[1], iov, iovlen * sizeof(struct iovec));
629
630         nwritten = write_data_iov(conn->fd, iov2, iovlen+1);
631         if (nwritten == -1) {
632                 DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
633                 cluster_fatal("cluster dispatch daemon msg write error\n");
634         }
635
636         return NT_STATUS_OK;
637 }
638
639 /*
640  * send/recv a generic ctdb control message
641  */
642 static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
643                               uint32_t vnn, uint32_t opcode,
644                               uint64_t srvid, uint32_t flags,
645                               TDB_DATA data,
646                               TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
647                               int *cstatus)
648 {
649         struct ctdb_req_control req;
650         struct ctdb_req_header *hdr;
651         struct ctdb_reply_control *reply = NULL;
652         struct iovec iov[2];
653         ssize_t nwritten;
654         NTSTATUS status;
655         int ret;
656
657         ZERO_STRUCT(req);
658         req.hdr.length = offsetof(struct ctdb_req_control, data) + data.dsize;
659         req.hdr.ctdb_magic   = CTDB_MAGIC;
660         req.hdr.ctdb_version = CTDB_PROTOCOL;
661         req.hdr.operation    = CTDB_REQ_CONTROL;
662         req.hdr.reqid        = ctdbd_next_reqid(conn);
663         req.hdr.destnode     = vnn;
664         req.opcode           = opcode;
665         req.srvid            = srvid;
666         req.datalen          = data.dsize;
667         req.flags            = flags;
668
669         DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
670         ctdb_packet_dump(&req.hdr);
671
672         iov[0].iov_base = &req;
673         iov[0].iov_len = offsetof(struct ctdb_req_control, data);
674         iov[1].iov_base = data.dptr;
675         iov[1].iov_len = data.dsize;
676
677         nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
678         if (nwritten == -1) {
679                 DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
680                 cluster_fatal("cluster dispatch daemon msg write error\n");
681         }
682
683         if (flags & CTDB_CTRL_FLAG_NOREPLY) {
684                 if (cstatus) {
685                         *cstatus = 0;
686                 }
687                 return NT_STATUS_OK;
688         }
689
690         ret = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
691         if (ret != 0) {
692                 DEBUG(10, ("ctdb_read_req failed: %s\n", strerror(ret)));
693                 status = map_nt_error_from_unix(ret);
694                 goto fail;
695         }
696
697         if (hdr->operation != CTDB_REPLY_CONTROL) {
698                 DEBUG(0, ("received invalid reply\n"));
699                 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
700                 goto fail;
701         }
702         reply = (struct ctdb_reply_control *)hdr;
703
704         if (outdata) {
705                 if (!(outdata->dptr = (uint8_t *)talloc_memdup(
706                               mem_ctx, reply->data, reply->datalen))) {
707                         TALLOC_FREE(reply);
708                         return NT_STATUS_NO_MEMORY;
709                 }
710                 outdata->dsize = reply->datalen;
711         }
712         if (cstatus) {
713                 (*cstatus) = reply->status;
714         }
715
716         status = NT_STATUS_OK;
717
718  fail:
719         TALLOC_FREE(reply);
720         return status;
721 }
722
723 /*
724  * see if a remote process exists
725  */
726 bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32_t vnn, pid_t pid)
727 {
728         struct server_id id;
729         bool result;
730
731         id.pid = pid;
732         id.vnn = vnn;
733
734         if (!ctdb_processes_exist(conn, &id, 1, &result)) {
735                 DEBUG(10, ("ctdb_processes_exist failed\n"));
736                 return false;
737         }
738         return result;
739 }
740
741 bool ctdb_processes_exist(struct ctdbd_connection *conn,
742                           const struct server_id *pids, int num_pids,
743                           bool *results)
744 {
745         TALLOC_CTX *frame = talloc_stackframe();
746         int i, num_received;
747         uint32_t *reqids;
748         bool result = false;
749
750         reqids = talloc_array(talloc_tos(), uint32_t, num_pids);
751         if (reqids == NULL) {
752                 goto fail;
753         }
754
755         for (i=0; i<num_pids; i++) {
756                 struct ctdb_req_control req;
757                 pid_t pid;
758                 struct iovec iov[2];
759                 ssize_t nwritten;
760
761                 results[i] = false;
762                 reqids[i] = ctdbd_next_reqid(conn);
763
764                 ZERO_STRUCT(req);
765
766                 /*
767                  * pids[i].pid is uint64_t, scale down to pid_t which
768                  * is the wire protocol towards ctdb.
769                  */
770                 pid = pids[i].pid;
771
772                 DEBUG(10, ("Requesting PID %d/%d, reqid=%d\n",
773                            (int)pids[i].vnn, (int)pid,
774                            (int)reqids[i]));
775
776                 req.hdr.length = offsetof(struct ctdb_req_control, data);
777                 req.hdr.length += sizeof(pid);
778                 req.hdr.ctdb_magic   = CTDB_MAGIC;
779                 req.hdr.ctdb_version = CTDB_PROTOCOL;
780                 req.hdr.operation    = CTDB_REQ_CONTROL;
781                 req.hdr.reqid        = reqids[i];
782                 req.hdr.destnode     = pids[i].vnn;
783                 req.opcode           = CTDB_CONTROL_PROCESS_EXISTS;
784                 req.srvid            = 0;
785                 req.datalen          = sizeof(pid);
786                 req.flags            = 0;
787
788                 DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
789                 ctdb_packet_dump(&req.hdr);
790
791                 iov[0].iov_base = &req;
792                 iov[0].iov_len = offsetof(struct ctdb_req_control, data);
793                 iov[1].iov_base = &pid;
794                 iov[1].iov_len = sizeof(pid);
795
796                 nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
797                 if (nwritten == -1) {
798                         DEBUG(10, ("write_data_iov failed: %s\n",
799                                    strerror(errno)));
800                         goto fail;
801                 }
802         }
803
804         num_received = 0;
805
806         while (num_received < num_pids) {
807                 struct ctdb_req_header *hdr;
808                 struct ctdb_reply_control *reply;
809                 uint32_t reqid;
810                 int ret;
811
812                 ret = ctdb_read_req(conn, 0, talloc_tos(), &hdr);
813                 if (ret != 0) {
814                         DEBUG(10, ("ctdb_read_req failed: %s\n",
815                                    strerror(ret)));
816                         goto fail;
817                 }
818
819                 if (hdr->operation != CTDB_REPLY_CONTROL) {
820                         DEBUG(10, ("Received invalid reply\n"));
821                         goto fail;
822                 }
823                 reply = (struct ctdb_reply_control *)hdr;
824
825                 reqid = reply->hdr.reqid;
826
827                 DEBUG(10, ("Received reqid %d\n", (int)reqid));
828
829                 for (i=0; i<num_pids; i++) {
830                         if (reqid == reqids[i]) {
831                                 break;
832                         }
833                 }
834                 if (i == num_pids) {
835                         DEBUG(10, ("Received unknown record number %u\n",
836                                    (unsigned)reqid));
837                         goto fail;
838                 }
839                 results[i] = ((reply->status) == 0);
840                 TALLOC_FREE(reply);
841                 num_received += 1;
842         }
843
844         result = true;
845 fail:
846         TALLOC_FREE(frame);
847         return result;
848 }
849
850 /*
851  * Get a db path
852  */
853 char *ctdbd_dbpath(struct ctdbd_connection *conn,
854                    TALLOC_CTX *mem_ctx, uint32_t db_id)
855 {
856         NTSTATUS status;
857         TDB_DATA data;
858         TDB_DATA rdata = {0};
859         int32_t cstatus = 0;
860
861         data.dptr = (uint8_t*)&db_id;
862         data.dsize = sizeof(db_id);
863
864         status = ctdbd_control(conn, CTDB_CURRENT_NODE,
865                                CTDB_CONTROL_GETDBPATH, 0, 0, data,
866                                mem_ctx, &rdata, &cstatus);
867         if (!NT_STATUS_IS_OK(status) || cstatus != 0) {
868                 DEBUG(0,(__location__ " ctdb_control for getdbpath failed\n"));
869                 return NULL;
870         }
871
872         return (char *)rdata.dptr;
873 }
874
875 /*
876  * attach to a ctdb database
877  */
878 NTSTATUS ctdbd_db_attach(struct ctdbd_connection *conn,
879                          const char *name, uint32_t *db_id, int tdb_flags)
880 {
881         NTSTATUS status;
882         TDB_DATA data;
883         int32_t cstatus;
884         bool persistent = (tdb_flags & TDB_CLEAR_IF_FIRST) == 0;
885
886         data = string_term_tdb_data(name);
887
888         status = ctdbd_control(conn, CTDB_CURRENT_NODE,
889                                persistent
890                                ? CTDB_CONTROL_DB_ATTACH_PERSISTENT
891                                : CTDB_CONTROL_DB_ATTACH,
892                                tdb_flags, 0, data, NULL, &data, &cstatus);
893         if (!NT_STATUS_IS_OK(status)) {
894                 DEBUG(0, (__location__ " ctdb_control for db_attach "
895                           "failed: %s\n", nt_errstr(status)));
896                 return status;
897         }
898
899         if (cstatus != 0 || data.dsize != sizeof(uint32_t)) {
900                 DEBUG(0,(__location__ " ctdb_control for db_attach failed\n"));
901                 return NT_STATUS_INTERNAL_ERROR;
902         }
903
904         *db_id = *(uint32_t *)data.dptr;
905         talloc_free(data.dptr);
906
907         if (!(tdb_flags & TDB_SEQNUM)) {
908                 return NT_STATUS_OK;
909         }
910
911         data.dptr = (uint8_t *)db_id;
912         data.dsize = sizeof(*db_id);
913
914         status = ctdbd_control(conn, CTDB_CURRENT_NODE,
915                                CTDB_CONTROL_ENABLE_SEQNUM, 0, 0, data,
916                                NULL, NULL, &cstatus);
917         if (!NT_STATUS_IS_OK(status) || cstatus != 0) {
918                 DEBUG(0,(__location__ " ctdb_control for enable seqnum "
919                          "failed\n"));
920                 return NT_STATUS_IS_OK(status) ? NT_STATUS_INTERNAL_ERROR :
921                         status;
922         }
923
924         return NT_STATUS_OK;
925 }
926
927 /*
928  * force the migration of a record to this node
929  */
930 NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32_t db_id,
931                        TDB_DATA key)
932 {
933         struct ctdb_req_call req;
934         struct ctdb_req_header *hdr;
935         struct iovec iov[2];
936         ssize_t nwritten;
937         NTSTATUS status;
938         int ret;
939
940         ZERO_STRUCT(req);
941
942         req.hdr.length = offsetof(struct ctdb_req_call, data) + key.dsize;
943         req.hdr.ctdb_magic   = CTDB_MAGIC;
944         req.hdr.ctdb_version = CTDB_PROTOCOL;
945         req.hdr.operation    = CTDB_REQ_CALL;
946         req.hdr.reqid        = ctdbd_next_reqid(conn);
947         req.flags            = CTDB_IMMEDIATE_MIGRATION;
948         req.callid           = CTDB_NULL_FUNC;
949         req.db_id            = db_id;
950         req.keylen           = key.dsize;
951
952         DEBUG(10, ("ctdbd_migrate: Sending ctdb packet\n"));
953         ctdb_packet_dump(&req.hdr);
954
955         iov[0].iov_base = &req;
956         iov[0].iov_len = offsetof(struct ctdb_req_call, data);
957         iov[1].iov_base = key.dptr;
958         iov[1].iov_len = key.dsize;
959
960         nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
961         if (nwritten == -1) {
962                 DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
963                 cluster_fatal("cluster dispatch daemon msg write error\n");
964         }
965
966         ret = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
967         if (ret != 0) {
968                 DEBUG(10, ("ctdb_read_req failed: %s\n", strerror(ret)));
969                 status = map_nt_error_from_unix(ret);
970                 goto fail;
971         }
972
973         if (hdr->operation != CTDB_REPLY_CALL) {
974                 DEBUG(0, ("received invalid reply\n"));
975                 status = NT_STATUS_INTERNAL_ERROR;
976                 goto fail;
977         }
978
979         status = NT_STATUS_OK;
980  fail:
981
982         TALLOC_FREE(hdr);
983         return status;
984 }
985
986 /*
987  * Fetch a record and parse it
988  */
989 NTSTATUS ctdbd_parse(struct ctdbd_connection *conn, uint32_t db_id,
990                      TDB_DATA key, bool local_copy,
991                      void (*parser)(TDB_DATA key, TDB_DATA data,
992                                     void *private_data),
993                      void *private_data)
994 {
995         struct ctdb_req_call req;
996         struct ctdb_req_header *hdr = NULL;
997         struct ctdb_reply_call *reply;
998         struct iovec iov[2];
999         ssize_t nwritten;
1000         NTSTATUS status;
1001         uint32_t flags;
1002         int ret;
1003
1004         flags = local_copy ? CTDB_WANT_READONLY : 0;
1005
1006         ZERO_STRUCT(req);
1007
1008         req.hdr.length = offsetof(struct ctdb_req_call, data) + key.dsize;
1009         req.hdr.ctdb_magic   = CTDB_MAGIC;
1010         req.hdr.ctdb_version = CTDB_PROTOCOL;
1011         req.hdr.operation    = CTDB_REQ_CALL;
1012         req.hdr.reqid        = ctdbd_next_reqid(conn);
1013         req.flags            = flags;
1014         req.callid           = CTDB_FETCH_FUNC;
1015         req.db_id            = db_id;
1016         req.keylen           = key.dsize;
1017
1018         iov[0].iov_base = &req;
1019         iov[0].iov_len = offsetof(struct ctdb_req_call, data);
1020         iov[1].iov_base = key.dptr;
1021         iov[1].iov_len = key.dsize;
1022
1023         nwritten = write_data_iov(conn->fd, iov, ARRAY_SIZE(iov));
1024         if (nwritten == -1) {
1025                 DEBUG(3, ("write_data_iov failed: %s\n", strerror(errno)));
1026                 cluster_fatal("cluster dispatch daemon msg write error\n");
1027         }
1028
1029         ret = ctdb_read_req(conn, req.hdr.reqid, NULL, &hdr);
1030         if (ret != 0) {
1031                 DEBUG(10, ("ctdb_read_req failed: %s\n", strerror(ret)));
1032                 status = map_nt_error_from_unix(ret);
1033                 goto fail;
1034         }
1035
1036         if ((hdr == NULL) || (hdr->operation != CTDB_REPLY_CALL)) {
1037                 DEBUG(0, ("received invalid reply\n"));
1038                 status = NT_STATUS_INTERNAL_ERROR;
1039                 goto fail;
1040         }
1041         reply = (struct ctdb_reply_call *)hdr;
1042
1043         if (reply->datalen == 0) {
1044                 /*
1045                  * Treat an empty record as non-existing
1046                  */
1047                 status = NT_STATUS_NOT_FOUND;
1048                 goto fail;
1049         }
1050
1051         parser(key, make_tdb_data(&reply->data[0], reply->datalen),
1052                private_data);
1053
1054         status = NT_STATUS_OK;
1055  fail:
1056         TALLOC_FREE(hdr);
1057         return status;
1058 }
1059
1060 /*
1061   Traverse a ctdb database. This uses a kind-of hackish way to open a second
1062   connection to ctdbd to avoid the hairy recursive and async problems with
1063   everything in-line.
1064 */
1065
1066 NTSTATUS ctdbd_traverse(struct ctdbd_connection *master, uint32_t db_id,
1067                         void (*fn)(TDB_DATA key, TDB_DATA data,
1068                                    void *private_data),
1069                         void *private_data)
1070 {
1071         struct ctdbd_connection *conn;
1072         NTSTATUS status;
1073
1074         TDB_DATA key, data;
1075         struct ctdb_traverse_start t;
1076         int cstatus;
1077
1078         become_root();
1079         status = ctdbd_init_connection(NULL, master->sockname, master->timeout,
1080                                        &conn);
1081         unbecome_root();
1082         if (!NT_STATUS_IS_OK(status)) {
1083                 DEBUG(0, ("ctdbd_init_connection failed: %s\n",
1084                           nt_errstr(status)));
1085                 return status;
1086         }
1087
1088         t.db_id = db_id;
1089         t.srvid = conn->rand_srvid;
1090         t.reqid = ctdbd_next_reqid(conn);
1091
1092         data.dptr = (uint8_t *)&t;
1093         data.dsize = sizeof(t);
1094
1095         status = ctdbd_control(conn, CTDB_CURRENT_NODE,
1096                                CTDB_CONTROL_TRAVERSE_START, conn->rand_srvid, 0,
1097                                data, NULL, NULL, &cstatus);
1098
1099         if (!NT_STATUS_IS_OK(status) || (cstatus != 0)) {
1100
1101                 DEBUG(0,("ctdbd_control failed: %s, %d\n", nt_errstr(status),
1102                          cstatus));
1103
1104                 if (NT_STATUS_IS_OK(status)) {
1105                         /*
1106                          * We need a mapping here
1107                          */
1108                         status = NT_STATUS_UNSUCCESSFUL;
1109                 }
1110                 TALLOC_FREE(conn);
1111                 return status;
1112         }
1113
1114         while (True) {
1115                 struct ctdb_req_header *hdr = NULL;
1116                 struct ctdb_req_message *m;
1117                 struct ctdb_rec_data *d;
1118                 int ret;
1119
1120                 ret = ctdb_read_packet(conn->fd, conn->timeout, conn, &hdr);
1121                 if (ret != 0) {
1122                         DEBUG(0, ("ctdb_read_packet failed: %s\n",
1123                                   strerror(ret)));
1124                         cluster_fatal("ctdbd died\n");
1125                 }
1126
1127                 if (hdr->operation != CTDB_REQ_MESSAGE) {
1128                         DEBUG(0, ("Got operation %u, expected a message\n",
1129                                   (unsigned)hdr->operation));
1130                         TALLOC_FREE(conn);
1131                         return NT_STATUS_UNEXPECTED_IO_ERROR;
1132                 }
1133
1134                 m = (struct ctdb_req_message *)hdr;
1135                 d = (struct ctdb_rec_data *)&m->data[0];
1136                 if (m->datalen < sizeof(uint32_t) || m->datalen != d->length) {
1137                         DEBUG(0, ("Got invalid traverse data of length %d\n",
1138                                   (int)m->datalen));
1139                         TALLOC_FREE(conn);
1140                         return NT_STATUS_UNEXPECTED_IO_ERROR;
1141                 }
1142
1143                 key.dsize = d->keylen;
1144                 key.dptr  = &d->data[0];
1145                 data.dsize = d->datalen;
1146                 data.dptr = &d->data[d->keylen];
1147
1148                 if (key.dsize == 0 && data.dsize == 0) {
1149                         /* end of traverse */
1150                         TALLOC_FREE(conn);
1151                         return NT_STATUS_OK;
1152                 }
1153
1154                 if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
1155                         DEBUG(0, ("Got invalid ltdb header length %d\n",
1156                                   (int)data.dsize));
1157                         TALLOC_FREE(conn);
1158                         return NT_STATUS_UNEXPECTED_IO_ERROR;
1159                 }
1160                 data.dsize -= sizeof(struct ctdb_ltdb_header);
1161                 data.dptr += sizeof(struct ctdb_ltdb_header);
1162
1163                 if (fn != NULL) {
1164                         fn(key, data, private_data);
1165                 }
1166         }
1167         return NT_STATUS_OK;
1168 }
1169
1170 /*
1171    This is used to canonicalize a ctdb_sock_addr structure.
1172 */
1173 static void smbd_ctdb_canonicalize_ip(const struct sockaddr_storage *in,
1174                                       struct sockaddr_storage *out)
1175 {
1176         memcpy(out, in, sizeof (*out));
1177
1178 #ifdef HAVE_IPV6
1179         if (in->ss_family == AF_INET6) {
1180                 const char prefix[12] = { 0,0,0,0,0,0,0,0,0,0,0xff,0xff };
1181                 const struct sockaddr_in6 *in6 =
1182                         (const struct sockaddr_in6 *)in;
1183                 struct sockaddr_in *out4 = (struct sockaddr_in *)out;
1184                 if (memcmp(&in6->sin6_addr, prefix, 12) == 0) {
1185                         memset(out, 0, sizeof(*out));
1186 #ifdef HAVE_SOCK_SIN_LEN
1187                         out4->sin_len = sizeof(*out);
1188 #endif
1189                         out4->sin_family = AF_INET;
1190                         out4->sin_port   = in6->sin6_port;
1191                         memcpy(&out4->sin_addr, &in6->sin6_addr.s6_addr[12], 4);
1192                 }
1193         }
1194 #endif
1195 }
1196
1197 /*
1198  * Register us as a server for a particular tcp connection
1199  */
1200
1201 NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
1202                             const struct sockaddr_storage *_server,
1203                             const struct sockaddr_storage *_client,
1204                             int (*cb)(uint32_t src_vnn, uint32_t dst_vnn,
1205                                       uint64_t dst_srvid,
1206                                       const uint8_t *msg, size_t msglen,
1207                                       void *private_data),
1208                             void *private_data)
1209 {
1210         struct ctdb_control_tcp_addr p;
1211         TDB_DATA data = { .dptr = (uint8_t *)&p, .dsize = sizeof(p) };
1212         NTSTATUS status;
1213         struct sockaddr_storage client;
1214         struct sockaddr_storage server;
1215
1216         /*
1217          * Only one connection so far
1218          */
1219
1220         smbd_ctdb_canonicalize_ip(_client, &client);
1221         smbd_ctdb_canonicalize_ip(_server, &server);
1222
1223         switch (client.ss_family) {
1224         case AF_INET:
1225                 memcpy(&p.dest.ip, &server, sizeof(p.dest.ip));
1226                 memcpy(&p.src.ip, &client, sizeof(p.src.ip));
1227                 break;
1228         case AF_INET6:
1229                 memcpy(&p.dest.ip6, &server, sizeof(p.dest.ip6));
1230                 memcpy(&p.src.ip6, &client, sizeof(p.src.ip6));
1231                 break;
1232         default:
1233                 return NT_STATUS_INTERNAL_ERROR;
1234         }
1235
1236         /*
1237          * We want to be told about IP releases
1238          */
1239
1240         status = register_with_ctdbd(conn, CTDB_SRVID_RELEASE_IP,
1241                                      cb, private_data);
1242         if (!NT_STATUS_IS_OK(status)) {
1243                 return status;
1244         }
1245
1246         /*
1247          * inform ctdb of our tcp connection, so if IP takeover happens ctdb
1248          * can send an extra ack to trigger a reset for our client, so it
1249          * immediately reconnects
1250          */
1251         return ctdbd_control(conn, CTDB_CURRENT_NODE,
1252                              CTDB_CONTROL_TCP_CLIENT, 0,
1253                              CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL, NULL);
1254 }
1255
1256 /*
1257   call a control on the local node
1258  */
1259 NTSTATUS ctdbd_control_local(struct ctdbd_connection *conn, uint32_t opcode,
1260                              uint64_t srvid, uint32_t flags, TDB_DATA data,
1261                              TALLOC_CTX *mem_ctx, TDB_DATA *outdata,
1262                              int *cstatus)
1263 {
1264         return ctdbd_control(conn, CTDB_CURRENT_NODE, opcode, srvid, flags, data, mem_ctx, outdata, cstatus);
1265 }
1266
1267 NTSTATUS ctdb_watch_us(struct ctdbd_connection *conn)
1268 {
1269         struct ctdb_client_notify_register reg_data;
1270         size_t struct_len;
1271         NTSTATUS status;
1272         int cstatus;
1273
1274         reg_data.srvid = CTDB_SRVID_SAMBA_NOTIFY;
1275         reg_data.len = 1;
1276         reg_data.notify_data[0] = 0;
1277
1278         struct_len = offsetof(struct ctdb_client_notify_register,
1279                               notify_data) + reg_data.len;
1280
1281         status = ctdbd_control_local(
1282                 conn, CTDB_CONTROL_REGISTER_NOTIFY, conn->rand_srvid, 0,
1283                 make_tdb_data((uint8_t *)&reg_data, struct_len),
1284                 NULL, NULL, &cstatus);
1285         if (!NT_STATUS_IS_OK(status)) {
1286                 DEBUG(1, ("ctdbd_control_local failed: %s\n",
1287                           nt_errstr(status)));
1288         }
1289         return status;
1290 }
1291
1292 NTSTATUS ctdb_unwatch(struct ctdbd_connection *conn)
1293 {
1294         struct ctdb_client_notify_deregister dereg_data;
1295         NTSTATUS status;
1296         int cstatus;
1297
1298         dereg_data.srvid = CTDB_SRVID_SAMBA_NOTIFY;
1299
1300         status = ctdbd_control_local(
1301                 conn, CTDB_CONTROL_DEREGISTER_NOTIFY, conn->rand_srvid, 0,
1302                 make_tdb_data((uint8_t *)&dereg_data, sizeof(dereg_data)),
1303                 NULL, NULL, &cstatus);
1304         if (!NT_STATUS_IS_OK(status)) {
1305                 DEBUG(1, ("ctdbd_control_local failed: %s\n",
1306                           nt_errstr(status)));
1307         }
1308         return status;
1309 }
1310
1311 NTSTATUS ctdbd_probe(const char *sockname, int timeout)
1312 {
1313         /*
1314          * Do a very early check if ctdbd is around to avoid an abort and core
1315          * later
1316          */
1317         struct ctdbd_connection *conn = NULL;
1318         NTSTATUS status;
1319
1320         status = ctdbd_messaging_connection(talloc_tos(), sockname, timeout,
1321                                             &conn);
1322
1323         /*
1324          * We only care if we can connect.
1325          */
1326         TALLOC_FREE(conn);
1327
1328         return status;
1329 }