1 /* $NetBSD: admin.c,v 1.38 2010/12/08 07:38:35 tteras Exp $ */ 2 3 /* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "config.h" 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/socket.h> 39 #include <sys/signal.h> 40 #include <sys/stat.h> 41 #include <sys/un.h> 42 43 #include <net/pfkeyv2.h> 44 45 #include <netinet/in.h> 46 #include PATH_IPSEC_H 47 48 49 #include <stdlib.h> 50 #include <stdio.h> 51 #include <string.h> 52 #include <errno.h> 53 #include <netdb.h> 54 #ifdef HAVE_UNISTD_H 55 #include <unistd.h> 56 #endif 57 #ifdef ENABLE_HYBRID 58 #include <resolv.h> 59 #endif 60 61 #include "var.h" 62 #include "misc.h" 63 #include "vmbuf.h" 64 #include "plog.h" 65 #include "sockmisc.h" 66 #include "debug.h" 67 68 #include "schedule.h" 69 #include "localconf.h" 70 #include "remoteconf.h" 71 #include "grabmyaddr.h" 72 #include "isakmp_var.h" 73 #include "isakmp.h" 74 #include "oakley.h" 75 #include "handler.h" 76 #include "evt.h" 77 #include "pfkey.h" 78 #include "ipsec_doi.h" 79 #include "policy.h" 80 #include "admin.h" 81 #include "admin_var.h" 82 #include "isakmp_inf.h" 83 #ifdef ENABLE_HYBRID 84 #include "isakmp_cfg.h" 85 #endif 86 #include "session.h" 87 #include "gcmalloc.h" 88 89 #ifdef ENABLE_ADMINPORT 90 char *adminsock_path = ADMINSOCK_PATH; 91 uid_t adminsock_owner = 0; 92 gid_t adminsock_group = 0; 93 mode_t adminsock_mode = 0600; 94 95 static struct sockaddr_un sunaddr; 96 static int admin_process __P((int, char *)); 97 static int admin_reply __P((int, struct admin_com *, int, vchar_t *)); 98 99 static int 100 admin_handler(ctx, fd) 101 void *ctx; 102 int fd; 103 { 104 int so2; 105 struct sockaddr_storage from; 106 socklen_t fromlen = sizeof(from); 107 struct admin_com com; 108 char *combuf = NULL; 109 int len, error = -1; 110 111 so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen); 112 if (so2 < 0) { 113 plog(LLV_ERROR, LOCATION, NULL, 114 "failed to accept admin command: %s\n", 115 strerror(errno)); 116 return -1; 117 } 118 close_on_exec(so2); 119 120 /* get buffer length */ 121 while ((len = recv(so2, (char *)&com, sizeof(com), MSG_PEEK)) < 0) { 122 if (errno == EINTR) 123 continue; 124 plog(LLV_ERROR, LOCATION, NULL, 125 "failed to recv admin command: %s\n", 126 strerror(errno)); 127 goto end; 128 } 129 130 /* sanity check */ 131 if (len < sizeof(com)) { 132 plog(LLV_ERROR, LOCATION, NULL, 133 "invalid header length of admin command\n"); 134 goto end; 135 } 136 137 /* get buffer to receive */ 138 if ((combuf = racoon_malloc(com.ac_len)) == 0) { 139 plog(LLV_ERROR, LOCATION, NULL, 140 "failed to alloc buffer for admin command\n"); 141 goto end; 142 } 143 144 /* get real data */ 145 while ((len = recv(so2, combuf, com.ac_len, 0)) < 0) { 146 if (errno == EINTR) 147 continue; 148 plog(LLV_ERROR, LOCATION, NULL, 149 "failed to recv admin command: %s\n", 150 strerror(errno)); 151 goto end; 152 } 153 154 error = admin_process(so2, combuf); 155 156 end: 157 if (error == -2) { 158 plog(LLV_DEBUG, LOCATION, NULL, 159 "[%d] admin connection established\n", so2); 160 } else { 161 (void)close(so2); 162 } 163 164 if (combuf) 165 racoon_free(combuf); 166 167 return error; 168 } 169 170 static int admin_ph1_delete_sa(struct ph1handle *iph1, void *arg) 171 { 172 if (iph1->status >= PHASE1ST_ESTABLISHED) 173 isakmp_info_send_d1(iph1); 174 purge_remote(iph1); 175 return 0; 176 } 177 178 /* 179 * main child's process. 180 */ 181 static int 182 admin_process(so2, combuf) 183 int so2; 184 char *combuf; 185 { 186 struct admin_com *com = (struct admin_com *)combuf; 187 vchar_t *buf = NULL; 188 vchar_t *id = NULL; 189 vchar_t *key = NULL; 190 int idtype = 0; 191 int error = 0, l_ac_errno = 0; 192 struct evt_listener_list *event_list = NULL; 193 194 if (com->ac_cmd & ADMIN_FLAG_VERSION) 195 com->ac_cmd &= ~ADMIN_FLAG_VERSION; 196 else 197 com->ac_version = 0; 198 199 switch (com->ac_cmd) { 200 case ADMIN_RELOAD_CONF: 201 signal_handler(SIGHUP); 202 break; 203 204 case ADMIN_SHOW_SCHED: { 205 caddr_t p = NULL; 206 int len; 207 208 if (sched_dump(&p, &len) != -1) { 209 buf = vmalloc(len); 210 if (buf != NULL) 211 memcpy(buf->v, p, len); 212 else 213 l_ac_errno = ENOMEM; 214 racoon_free(p); 215 } else 216 l_ac_errno = ENOMEM; 217 break; 218 } 219 220 case ADMIN_SHOW_EVT: 221 if (com->ac_version == 0) { 222 buf = evt_dump(); 223 l_ac_errno = 0; 224 } 225 break; 226 227 case ADMIN_SHOW_SA: 228 switch (com->ac_proto) { 229 case ADMIN_PROTO_ISAKMP: 230 buf = dumpph1(); 231 if (buf == NULL) 232 l_ac_errno = ENOMEM; 233 break; 234 case ADMIN_PROTO_IPSEC: 235 case ADMIN_PROTO_AH: 236 case ADMIN_PROTO_ESP: { 237 u_int p; 238 p = admin2pfkey_proto(com->ac_proto); 239 if (p != -1) { 240 buf = pfkey_dump_sadb(p); 241 if (buf == NULL) 242 l_ac_errno = ENOMEM; 243 } else 244 l_ac_errno = EINVAL; 245 break; 246 } 247 case ADMIN_PROTO_INTERNAL: 248 default: 249 l_ac_errno = ENOTSUP; 250 break; 251 } 252 break; 253 254 case ADMIN_GET_SA_CERT: { 255 struct admin_com_indexes *ndx; 256 struct sockaddr *src, *dst; 257 struct ph1handle *iph1; 258 259 ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)); 260 src = (struct sockaddr *) &ndx->src; 261 dst = (struct sockaddr *) &ndx->dst; 262 263 if (com->ac_proto != ADMIN_PROTO_ISAKMP) { 264 l_ac_errno = ENOTSUP; 265 break; 266 } 267 268 iph1 = getph1byaddr(src, dst, 0); 269 if (iph1 == NULL) { 270 l_ac_errno = ENOENT; 271 break; 272 } 273 274 if (iph1->cert_p != NULL) { 275 vchar_t tmp; 276 tmp.v = iph1->cert_p->v + 1; 277 tmp.l = iph1->cert_p->l - 1; 278 buf = vdup(&tmp); 279 } 280 break; 281 } 282 283 case ADMIN_FLUSH_SA: 284 switch (com->ac_proto) { 285 case ADMIN_PROTO_ISAKMP: 286 flushph1(); 287 break; 288 case ADMIN_PROTO_IPSEC: 289 case ADMIN_PROTO_AH: 290 case ADMIN_PROTO_ESP: 291 pfkey_flush_sadb(com->ac_proto); 292 break; 293 case ADMIN_PROTO_INTERNAL: 294 /*XXX flushph2();*/ 295 default: 296 l_ac_errno = ENOTSUP; 297 break; 298 } 299 break; 300 301 case ADMIN_DELETE_SA: { 302 char *loc, *rem; 303 struct ph1selector sel; 304 305 memset(&sel, 0, sizeof(sel)); 306 sel.local = (struct sockaddr *) 307 &((struct admin_com_indexes *) 308 ((caddr_t)com + sizeof(*com)))->src; 309 sel.remote = (struct sockaddr *) 310 &((struct admin_com_indexes *) 311 ((caddr_t)com + sizeof(*com)))->dst; 312 313 loc = racoon_strdup(saddr2str(sel.local)); 314 rem = racoon_strdup(saddr2str(sel.remote)); 315 STRDUP_FATAL(loc); 316 STRDUP_FATAL(rem); 317 318 plog(LLV_INFO, LOCATION, NULL, 319 "admin delete-sa %s %s\n", loc, rem); 320 enumph1(&sel, admin_ph1_delete_sa, NULL); 321 remcontacted(sel.remote); 322 323 racoon_free(loc); 324 racoon_free(rem); 325 break; 326 } 327 328 #ifdef ENABLE_HYBRID 329 case ADMIN_LOGOUT_USER: { 330 struct ph1handle *iph1; 331 char user[LOGINLEN+1]; 332 int found = 0, len = com->ac_len - sizeof(*com); 333 334 if (len > LOGINLEN) { 335 plog(LLV_ERROR, LOCATION, NULL, 336 "malformed message (login too long)\n"); 337 break; 338 } 339 340 memcpy(user, (char *)(com + 1), len); 341 user[len] = 0; 342 343 found = purgeph1bylogin(user); 344 plog(LLV_INFO, LOCATION, NULL, 345 "deleted %d SA for user \"%s\"\n", found, user); 346 347 break; 348 } 349 #endif 350 351 case ADMIN_DELETE_ALL_SA_DST: { 352 struct ph1handle *iph1; 353 struct sockaddr *dst; 354 char *loc, *rem; 355 356 dst = (struct sockaddr *) 357 &((struct admin_com_indexes *) 358 ((caddr_t)com + sizeof(*com)))->dst; 359 360 rem = racoon_strdup(saddrwop2str(dst)); 361 STRDUP_FATAL(rem); 362 363 plog(LLV_INFO, LOCATION, NULL, 364 "Flushing all SAs for peer %s\n", rem); 365 366 while ((iph1 = getph1bydstaddr(dst)) != NULL) { 367 loc = racoon_strdup(saddrwop2str(iph1->local)); 368 STRDUP_FATAL(loc); 369 370 if (iph1->status >= PHASE1ST_ESTABLISHED) 371 isakmp_info_send_d1(iph1); 372 purge_remote(iph1); 373 374 racoon_free(loc); 375 } 376 377 racoon_free(rem); 378 break; 379 } 380 381 case ADMIN_ESTABLISH_SA_PSK: { 382 struct admin_com_psk *acp; 383 char *data; 384 385 acp = (struct admin_com_psk *) 386 ((char *)com + sizeof(*com) + 387 sizeof(struct admin_com_indexes)); 388 389 idtype = acp->id_type; 390 391 if ((id = vmalloc(acp->id_len)) == NULL) { 392 plog(LLV_ERROR, LOCATION, NULL, 393 "cannot allocate memory: %s\n", 394 strerror(errno)); 395 break; 396 } 397 data = (char *)(acp + 1); 398 memcpy(id->v, data, id->l); 399 400 if ((key = vmalloc(acp->key_len)) == NULL) { 401 plog(LLV_ERROR, LOCATION, NULL, 402 "cannot allocate memory: %s\n", 403 strerror(errno)); 404 vfree(id); 405 id = NULL; 406 break; 407 } 408 data = (char *)(data + acp->id_len); 409 memcpy(key->v, data, key->l); 410 } 411 /* FALLTHROUGH */ 412 case ADMIN_ESTABLISH_SA: { 413 struct admin_com_indexes *ndx; 414 struct sockaddr *dst; 415 struct sockaddr *src; 416 char *name = NULL; 417 418 ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com)); 419 src = (struct sockaddr *) &ndx->src; 420 dst = (struct sockaddr *) &ndx->dst; 421 422 if (com->ac_cmd == ADMIN_ESTABLISH_SA && 423 com->ac_len > sizeof(*com) + sizeof(*ndx)) 424 name = (char *) ((caddr_t) ndx + sizeof(*ndx)); 425 426 switch (com->ac_proto) { 427 case ADMIN_PROTO_ISAKMP: { 428 struct ph1handle *ph1; 429 struct remoteconf *rmconf; 430 u_int16_t port; 431 432 l_ac_errno = -1; 433 434 /* connected already? */ 435 ph1 = getph1byaddr(src, dst, 0); 436 if (ph1 != NULL) { 437 event_list = &ph1->evt_listeners; 438 if (ph1->status == PHASE1ST_ESTABLISHED) 439 l_ac_errno = EEXIST; 440 else 441 l_ac_errno = 0; 442 break; 443 } 444 445 /* search appropreate configuration */ 446 if (name == NULL) 447 rmconf = getrmconf(dst, 0); 448 else 449 rmconf = getrmconf_by_name(name); 450 if (rmconf == NULL) { 451 plog(LLV_ERROR, LOCATION, NULL, 452 "no configuration found " 453 "for %s\n", saddrwop2str(dst)); 454 break; 455 } 456 457 #ifdef ENABLE_HYBRID 458 /* XXX This overwrites rmconf information globally. */ 459 /* Set the id and key */ 460 if (id && key) { 461 if (xauth_rmconf_used(&rmconf->xauth) == -1) 462 break; 463 464 if (rmconf->xauth->login != NULL) { 465 vfree(rmconf->xauth->login); 466 rmconf->xauth->login = NULL; 467 } 468 if (rmconf->xauth->pass != NULL) { 469 vfree(rmconf->xauth->pass); 470 rmconf->xauth->pass = NULL; 471 } 472 473 rmconf->xauth->login = id; 474 rmconf->xauth->pass = key; 475 } 476 #endif 477 478 plog(LLV_INFO, LOCATION, NULL, 479 "accept a request to establish IKE-SA: " 480 "%s\n", saddrwop2str(dst)); 481 482 /* begin ident mode */ 483 ph1 = isakmp_ph1begin_i(rmconf, dst, src); 484 if (ph1 == NULL) 485 break; 486 487 event_list = &ph1->evt_listeners; 488 l_ac_errno = 0; 489 break; 490 } 491 case ADMIN_PROTO_AH: 492 case ADMIN_PROTO_ESP: { 493 struct ph2handle *iph2; 494 struct secpolicy *sp_out = NULL, *sp_in = NULL; 495 struct policyindex spidx; 496 497 l_ac_errno = -1; 498 499 /* got outbound policy */ 500 memset(&spidx, 0, sizeof(spidx)); 501 spidx.dir = IPSEC_DIR_OUTBOUND; 502 memcpy(&spidx.src, src, sizeof(spidx.src)); 503 memcpy(&spidx.dst, dst, sizeof(spidx.dst)); 504 spidx.prefs = ndx->prefs; 505 spidx.prefd = ndx->prefd; 506 spidx.ul_proto = ndx->ul_proto; 507 508 sp_out = getsp_r(&spidx); 509 if (sp_out) { 510 plog(LLV_DEBUG, LOCATION, NULL, 511 "suitable outbound SP found: %s.\n", 512 spidx2str(&sp_out->spidx)); 513 } else { 514 l_ac_errno = ENOENT; 515 plog(LLV_NOTIFY, LOCATION, NULL, 516 "no outbound policy found: %s\n", 517 spidx2str(&spidx)); 518 break; 519 } 520 521 iph2 = getph2byid(src, dst, sp_out->id); 522 if (iph2 != NULL) { 523 event_list = &iph2->evt_listeners; 524 if (iph2->status == PHASE2ST_ESTABLISHED) 525 l_ac_errno = EEXIST; 526 else 527 l_ac_errno = 0; 528 break; 529 } 530 531 /* get inbound policy */ 532 memset(&spidx, 0, sizeof(spidx)); 533 spidx.dir = IPSEC_DIR_INBOUND; 534 memcpy(&spidx.src, dst, sizeof(spidx.src)); 535 memcpy(&spidx.dst, src, sizeof(spidx.dst)); 536 spidx.prefs = ndx->prefd; 537 spidx.prefd = ndx->prefs; 538 spidx.ul_proto = ndx->ul_proto; 539 540 sp_in = getsp_r(&spidx); 541 if (sp_in) { 542 plog(LLV_DEBUG, LOCATION, NULL, 543 "suitable inbound SP found: %s.\n", 544 spidx2str(&sp_in->spidx)); 545 } else { 546 l_ac_errno = ENOENT; 547 plog(LLV_NOTIFY, LOCATION, NULL, 548 "no inbound policy found: %s\n", 549 spidx2str(&spidx)); 550 break; 551 } 552 553 /* allocate a phase 2 */ 554 iph2 = newph2(); 555 if (iph2 == NULL) { 556 plog(LLV_ERROR, LOCATION, NULL, 557 "failed to allocate phase2 entry.\n"); 558 break; 559 } 560 iph2->side = INITIATOR; 561 iph2->satype = admin2pfkey_proto(com->ac_proto); 562 iph2->spid = sp_out->id; 563 iph2->seq = pk_getseq(); 564 iph2->status = PHASE2ST_STATUS2; 565 566 /* set end addresses of SA */ 567 iph2->sa_dst = dupsaddr(dst); 568 iph2->sa_src = dupsaddr(src); 569 iph2->dst = dupsaddr(dst); 570 iph2->src = dupsaddr(src); 571 if (iph2->sa_src == NULL || iph2->sa_dst == NULL || 572 iph2->dst == NULL || iph2->src == NULL) { 573 delph2(iph2); 574 break; 575 } 576 set_port(iph2->dst, 0); 577 set_port(iph2->src, 0); 578 579 if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) { 580 delph2(iph2); 581 break; 582 } 583 584 insph2(iph2); 585 if (isakmp_post_acquire(iph2, NULL, FALSE) < 0) { 586 remph2(iph2); 587 delph2(iph2); 588 break; 589 } 590 591 event_list = &iph2->evt_listeners; 592 l_ac_errno = 0; 593 break; 594 } 595 default: 596 /* ignore */ 597 l_ac_errno = ENOTSUP; 598 } 599 break; 600 } 601 602 default: 603 plog(LLV_ERROR, LOCATION, NULL, 604 "invalid command: %d\n", com->ac_cmd); 605 l_ac_errno = ENOTSUP; 606 } 607 608 if ((error = admin_reply(so2, com, l_ac_errno, buf)) != 0) 609 goto out; 610 611 /* start pushing events if so requested */ 612 if ((l_ac_errno == 0) && 613 (com->ac_version >= 1) && 614 (com->ac_cmd == ADMIN_SHOW_EVT || event_list != NULL)) 615 error = evt_subscribe(event_list, so2); 616 out: 617 if (buf != NULL) 618 vfree(buf); 619 620 return error; 621 } 622 623 static int 624 admin_reply(so, req, l_ac_errno, buf) 625 int so, l_ac_errno; 626 struct admin_com *req; 627 vchar_t *buf; 628 { 629 int tlen; 630 struct admin_com *combuf; 631 char *retbuf = NULL; 632 633 if (buf != NULL) 634 tlen = sizeof(*combuf) + buf->l; 635 else 636 tlen = sizeof(*combuf); 637 638 retbuf = racoon_calloc(1, tlen); 639 if (retbuf == NULL) { 640 plog(LLV_ERROR, LOCATION, NULL, 641 "failed to allocate admin buffer\n"); 642 return -1; 643 } 644 645 combuf = (struct admin_com *) retbuf; 646 combuf->ac_len = (u_int16_t) tlen; 647 combuf->ac_cmd = req->ac_cmd & ~ADMIN_FLAG_VERSION; 648 if (tlen != (u_int32_t) combuf->ac_len && 649 l_ac_errno == 0) { 650 combuf->ac_len_high = tlen >> 16; 651 combuf->ac_cmd |= ADMIN_FLAG_LONG_REPLY; 652 } else { 653 combuf->ac_errno = l_ac_errno; 654 } 655 combuf->ac_proto = req->ac_proto; 656 657 if (buf != NULL) 658 memcpy(retbuf + sizeof(*combuf), buf->v, buf->l); 659 660 tlen = send(so, retbuf, tlen, 0); 661 racoon_free(retbuf); 662 if (tlen < 0) { 663 plog(LLV_ERROR, LOCATION, NULL, 664 "failed to send admin command: %s\n", 665 strerror(errno)); 666 return -1; 667 } 668 669 return 0; 670 } 671 672 /* ADMIN_PROTO -> SADB_SATYPE */ 673 int 674 admin2pfkey_proto(proto) 675 u_int proto; 676 { 677 switch (proto) { 678 case ADMIN_PROTO_IPSEC: 679 return SADB_SATYPE_UNSPEC; 680 case ADMIN_PROTO_AH: 681 return SADB_SATYPE_AH; 682 case ADMIN_PROTO_ESP: 683 return SADB_SATYPE_ESP; 684 default: 685 plog(LLV_ERROR, LOCATION, NULL, 686 "unsupported proto for admin: %d\n", proto); 687 return -1; 688 } 689 /*NOTREACHED*/ 690 } 691 692 int 693 admin_init() 694 { 695 if (adminsock_path == NULL) { 696 lcconf->sock_admin = -1; 697 return 0; 698 } 699 700 memset(&sunaddr, 0, sizeof(sunaddr)); 701 sunaddr.sun_family = AF_UNIX; 702 snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), 703 "%s", adminsock_path); 704 705 lcconf->sock_admin = socket(AF_UNIX, SOCK_STREAM, 0); 706 if (lcconf->sock_admin == -1) { 707 plog(LLV_ERROR, LOCATION, NULL, 708 "socket: %s\n", strerror(errno)); 709 return -1; 710 } 711 close_on_exec(lcconf->sock_admin); 712 713 unlink(sunaddr.sun_path); 714 if (bind(lcconf->sock_admin, (struct sockaddr *)&sunaddr, 715 sizeof(sunaddr)) != 0) { 716 plog(LLV_ERROR, LOCATION, NULL, 717 "bind(sockname:%s): %s\n", 718 sunaddr.sun_path, strerror(errno)); 719 (void)close(lcconf->sock_admin); 720 return -1; 721 } 722 723 if (chown(sunaddr.sun_path, adminsock_owner, adminsock_group) != 0) { 724 plog(LLV_ERROR, LOCATION, NULL, 725 "chown(%s, %d, %d): %s\n", 726 sunaddr.sun_path, adminsock_owner, 727 adminsock_group, strerror(errno)); 728 (void)close(lcconf->sock_admin); 729 return -1; 730 } 731 732 if (chmod(sunaddr.sun_path, adminsock_mode) != 0) { 733 plog(LLV_ERROR, LOCATION, NULL, 734 "chmod(%s, 0%03o): %s\n", 735 sunaddr.sun_path, adminsock_mode, strerror(errno)); 736 (void)close(lcconf->sock_admin); 737 return -1; 738 } 739 740 if (listen(lcconf->sock_admin, 5) != 0) { 741 plog(LLV_ERROR, LOCATION, NULL, 742 "listen(sockname:%s): %s\n", 743 sunaddr.sun_path, strerror(errno)); 744 (void)close(lcconf->sock_admin); 745 return -1; 746 } 747 748 monitor_fd(lcconf->sock_admin, admin_handler, NULL, 0); 749 plog(LLV_DEBUG, LOCATION, NULL, 750 "open %s as racoon management.\n", sunaddr.sun_path); 751 752 return 0; 753 } 754 755 int 756 admin_close() 757 { 758 unmonitor_fd(lcconf->sock_admin); 759 close(lcconf->sock_admin); 760 return 0; 761 } 762 763 #endif 764