コード例 #1
0
ファイル: rblcheck.c プロジェクト: asyr625/mini_sip
static int addzonefile(const char *fname) {
  FILE *f = fopen(fname, "r");
  char linebuf[2048];
  if (!f)
    return 0;
  while(fgets(linebuf, sizeof(linebuf), f)) {
    char *p = linebuf, *e;
    while(*p == ' ' || *p == '\t') ++p;
    if (*p == '#' || *p == '\n') continue;
    e = p;
    while(*e && *e != ' ' && *e != '\t' && *e != '\n')
      ++e;
    *e = '\0';
    addzone(p);
  }
  fclose(f);
  return 1;
}
コード例 #2
0
ファイル: rblcheck.c プロジェクト: asyr625/mini_sip
int main(int argc, char **argv) {
  int c;
  struct ipcheck ipc;
  char *nameserver = NULL;
  int zgiven = 0;

  if (!(progname = strrchr(argv[0], '/'))) progname = argv[0];
  else argv[0] = ++progname;

  while((c = getopt(argc, argv, "hqtvms:S:cn:")) != EOF) switch(c) {
  case 's': ++zgiven; addzone(optarg); break;
  case 'S':
    ++zgiven;
    if (addzonefile(optarg)) break;
    fprintf(stderr, "%s: unable to read %s\n", progname, optarg);
    return 1;
  case 'c': ++zgiven; nzones = 0; break;
  case 'q': --verbose; break;
  case 'v': ++verbose; break;
  case 't': do_txt = 1; break;
  case 'n': nameserver = optarg; break;
  case 'm': ++stopfirst; break;
  case 'h':
    printf("%s: %s.\n", progname, version);
    printf("Usage is: %s [options] address..\n", progname);
    printf(
"Where options are:\n"
" -h - print this help and exit\n"
" -s service - add the service (DNSBL zone) to the serice list\n"
" -S service-file - add the DNSBL zone(s) read from the given file\n"
" -c - clear service list\n"
" -v - increase verbosity level (more -vs => more verbose)\n"
" -q - decrease verbosity level (opposite of -v)\n"
" -t - obtain and print TXT records if any\n"
" -m - stop checking after first address match in any list\n"
" -n ipaddr - use the given nameserver instead of the default\n"
"(if no -s or -S option is given, use $RBLCHECK_ZONES, ~/.rblcheckrc\n"
"or /etc/rblcheckrc in that order)\n"
    );
    return 0;
  default:
    fprintf(stderr, "%s: use `%s -h' for help\n", progname, progname);
    return 1;
  }

  if (!zgiven) {
    char *s = getenv("RBLCHECK_ZONES");
    if (s) {
      char *k;
      s = strdup(s);
      k = strtok(s, " \t");
      while(k) {
        addzone(k);
        k = strtok(NULL, " \t");
      }
      free(s);
    }
    else {
      char *path;
      char *home = getenv("HOME");
      if (!home) home = ".";
      path = malloc(strlen(home) + 1 + sizeof(".rblcheckrc"));
      sprintf(path, "%s/.rblcheckrc", home);
      if (!addzonefile(path))
        addzonefile("/etc/rblcheckrc");
      free(path);
    }
  }
  if (!nzones) {
    fprintf(stderr, "%s: no service (zone) list specified (-s or -S option)\n",
            progname);
    return 1;
  }

  argv += optind;
  argc -= optind;

  if (!argc)
    return 0;

  if (dns_init(0) < 0) {
    fprintf(stderr, "%s: unable to initialize DNS library: %s\n",
            progname, strerror(errno));
    return 1;
  }
  if (nameserver) {
    dns_add_serv(NULL, NULL);
    if (dns_add_serv(NULL, nameserver) < 0)
      fprintf(stderr, "%s: unable to use nameserver %s: %s\n",
              progname, nameserver, strerror(errno));
  }
  if (dns_open(NULL) < 0) {
    fprintf(stderr, "%s: unable to initialize DNS library: %s\n",
            progname, strerror(errno));
    return 1;
  }

  for (c = 0; c < argc; ++c) {
    if (c && (verbose > 1 || (verbose == 1 && do_txt))) putchar('\n');
    ipc.name = argv[c];
    submit(&ipc);
    waitdns(&ipc);
    display_result(&ipc);
    if (stopfirst > 1 && listed) break;
  }

  return listed ? 100 : failures ? 2 : 0;
}
コード例 #3
0
ファイル: rbldnsd.c プロジェクト: 0xxon/rbldnsd
static void init(int argc, char **argv) {
  int c;
  char *p;
  const char *user = NULL;
  const char *rootdir = NULL, *workdir = NULL, *pidfile = NULL;
  const char *bindaddr[MAXSOCK];
  int nba = 0;
  uid_t uid = 0;
  gid_t gid = 0;
  int nodaemon = 0, quickstart = 0, dump = 0, nover = 0, forkon = 0;
  int family = AF_UNSPEC;
  int cfd = -1;
  const struct zone *z;
#ifndef NO_DSO
  char *ext = NULL, *extarg = NULL;
  int (*extinit)(const char *arg, struct zone *zonelist) = NULL;
#endif

  if ((progname = strrchr(argv[0], '/')) != NULL)
    argv[0] = ++progname;
  else
    progname = argv[0];

  if (argc <= 1) usage(1);

  const char *const getopt_fmt = "u:r:b:w:t:c:p:nel:Lqs:h46dvaAfCx:X:zg";
  while((c = getopt(argc, argv, getopt_fmt)) != EOF)
    switch(c) {
    case 'u': user = optarg; break;
    case 'r': rootdir = optarg; break;
    case 'b':
      if (nba >= MAXSOCK)
        error(0, "too many addresses to listen on (%d max)", MAXSOCK);
      bindaddr[nba++] = optarg;
      break;
#ifndef NO_IPv6
    case '4': family = AF_INET; break;
    case '6': family = AF_INET6; break;
#else
    case '4': break;
    case '6': error(0, "IPv6 support isn't compiled in");
#endif
    case 'w': workdir = optarg; break;
    case 'p': pidfile = optarg; break;
    case 't':
      p = optarg;
      if (*p == ':') ++p;
      else {
        if (!(p = parse_time(p, &def_ttl)) || !def_ttl ||
            (*p && *p++ != ':'))
          error(0, "invalid ttl (-t) value `%.50s'", optarg);
      }
      if (*p == ':') ++p;
      else if (*p) {
        if (!(p = parse_time(p, &min_ttl)) || (*p && *p++ != ':'))
          error(0, "invalid minttl (-t) value `%.50s'", optarg);
      }
      if (*p == ':') ++p;
      else if (*p) {
        if (!(p = parse_time(p, &max_ttl)) || (*p && *p++ != ':'))
          error(0, "invalid maxttl (-t) value `%.50s'", optarg);
      }
      if (*p)
        error(0, "invalid value for -t (ttl) option: `%.50s'", optarg);
      if ((min_ttl && max_ttl && min_ttl > max_ttl) ||
          (min_ttl && def_ttl < min_ttl) ||
          (max_ttl && def_ttl > max_ttl))
        error(0, "inconsistent def:min:max ttl: %u:%u:%u",
              def_ttl, min_ttl, max_ttl);
      break;
    case 'c':
      if (!(p = parse_time(optarg, &recheck)) || *p)
        error(0, "invalid check interval (-c) value `%.50s'", optarg);
      break;
    case 'n': nodaemon = 1; break;
    case 'e': accept_in_cidr = 1; break;
    case 'l':
      logfile = optarg;
      if (*logfile != '+') flushlog = 0;
      else ++logfile, flushlog = 1;
      if (!*logfile) logfile = NULL, flushlog = 0;
      else if (logfile[0] == '-' && logfile[1] == '\0')
        logfile = NULL, flog = stdout;
      break;
    case 'L':
      verbose = 1; break;
break;
    case 's':
#ifdef NO_STATS
      fprintf(stderr,
        "%s: warning: no statistics counters support is compiled in\n",
        progname);
#else
      statsfile = optarg;
      if (*statsfile != '+') stats_relative = 0;
      else ++statsfile, stats_relative = 1;
      if (!*statsfile) statsfile = NULL;
#endif
      break;
    case 'q': quickstart = 1; break;
    case 'd':
#ifdef NO_MASTER_DUMP
      error(0, "master-format dump option (-d) isn't compiled in");
#endif
      dump = 1;
      break;
    case 'v': show_version = nover++ ? NULL : "rbldnsd"; break;
    case 'a': lazy = 1; break;
    case 'A': lazy = 0; break;
    case 'f': forkon = 1; break;
    case 'C': nouncompress = 1; break;
#ifndef NO_DSO
    case 'x': ext = optarg; break;
    case 'X': extarg = optarg; break;
#else
    case 'x':
    case 'X':
      error(0, "extension support is not compiled in");
#endif
#ifndef NO_ANONYMIZE
    case 'z': anonymize = 1; break;
#else
    case 'z':
      error(0, "anonymization support is not compiled in");
#endif
#ifndef NO_GEOIP
    case 'g': geoip = 1; break;
    case 'G': geoip = 1; geoip_path = optarg; break;

#else
    case 'g':
    case 'G':
      error(0, "geoip support is not compiled in");
#endif
    case 'h': usage(0);
    default: error(0, "type `%.50s -h' for help", progname);
    }

  if (!(argc -= optind))
    error(0, "no zone(s) to service specified (-h for help)");
  argv += optind;

#ifndef NO_MASTER_DUMP
  if (dump) {
    time_t now;
    logto = LOGTO_STDERR;
    for(c = 0; c < argc; ++c)
      zonelist = addzone(zonelist, argv[c]);
    init_zones_caches(zonelist);
    if (rootdir && (chdir(rootdir) < 0 || chroot(rootdir) < 0))
      error(errno, "unable to chroot to %.50s", rootdir);
    if (workdir && chdir(workdir) < 0)
      error(errno, "unable to chdir to %.50s", workdir);
    if (!do_reload(0))
      error(0, "zone loading errors, aborting");
    now = time(NULL);
    printf("; zone dump made %s", ctime(&now));
    printf("; rbldnsd version %s\n", version);
    for (z = zonelist; z; z = z->z_next)
      dumpzone(z, stdout);
    fflush(stdout);
    exit(ferror(stdout) ? 1 : 0);
  }
#endif

  if (!nba)
    error(0, "no address to listen on (-b option) specified");

  tzset();
  if (nodaemon)
    logto = LOGTO_STDOUT|LOGTO_STDERR;
  else {
    /* fork early so that logging will be from right pid */
    int pfd[2];
    if (pipe(pfd) < 0) error(errno, "pipe() failed");
    c = fork();
    if (c < 0) error(errno, "fork() failed");
    if (c > 0) {
      close(pfd[1]);
      if (read(pfd[0], &c, 1) < 1) exit(1);
      else exit(0);
    }
    cfd = pfd[1];
    close(pfd[0]);
    openlog(progname, LOG_PID|LOG_NDELAY, LOG_DAEMON);
    logto = LOGTO_STDERR|LOGTO_SYSLOG;
    if (!quickstart && !flog) logto |= LOGTO_STDOUT;
  }

  initsockets(bindaddr, nba, family);

#ifndef NO_DSO
  if (ext) {
    void *handle = dlopen(ext, RTLD_NOW);
    if (!handle)
      error(0, "unable to load extension `%s': %s", ext, dlerror());
    extinit = dlsym(handle, "rbldnsd_extension_init");
    if (!extinit)
      error(0, "unable to find extension init routine in `%s'", ext);
  }
#endif

  if (!user && !(uid = getuid()))
    user = "******";

  if (!user)
    p = NULL;
  else {
    if ((p = strchr(user, ':')) != NULL)
      *p++ = '\0';
    if ((c = satoi(user)) >= 0)
      uid = c, gid = c;
    else {
      struct passwd *pw = getpwnam(user);
      if (!pw)
        error(0, "unknown user `%s'", user);
      uid = pw->pw_uid;
      gid = pw->pw_gid;
      endpwent();
    }
  }
  if (!uid)
    error(0, "daemon should not run as root, specify -u option");
  if (p) {
    if ((c = satoi(p)) >= 0)
      gid = c;
    else {
      struct group *gr = getgrnam(p);
      if (!gr)
        error(0, "unknown group `%s'", p);
      gid = gr->gr_gid;
      endgrent();
    }
    p[-1] = ':';
  }

  if (pidfile) {
    int fdpid;
    char buf[40];
    c = sprintf(buf, "%ld\n", (long)getpid());
    fdpid = open(pidfile, O_CREAT|O_WRONLY|O_TRUNC, 0644);
    if (fdpid < 0 || write(fdpid, buf, c) < c)
      error(errno, "unable to write pidfile");
    close(fdpid);
  }

  if (rootdir && (chdir(rootdir) < 0 || chroot(rootdir) < 0))
    error(errno, "unable to chroot to %.50s", rootdir);
  if (workdir && chdir(workdir) < 0)
    error(errno, "unable to chdir to %.50s", workdir);

  if (user)
    if (setgroups(1, &gid) < 0 || setgid(gid) < 0 || setuid(uid) < 0)
      error(errno, "unable to setuid(%d:%d)", (int)uid, (int)gid);

  for(c = 0; c < argc; ++c)
    zonelist = addzone(zonelist, argv[c]);
  init_zones_caches(zonelist);

#ifndef NO_DSO
  if (extinit && extinit(extarg, zonelist) != 0)
    error(0, "unable to iniitialize extension `%s'", ext);
#endif

  if (!quickstart && !do_reload(0))
    error(0, "zone loading errors, aborting");

  /* count number of zones */
  for(c = 0, z = zonelist; z; z = z->z_next)
    ++c;
  numzones = c;

#if STATS_IPC_IOVEC
  stats_iov = (struct iovec *)emalloc(numzones * sizeof(struct iovec));
  for(c = 0, z = zonelist; z; z = z->z_next, ++c) {
    stats_iov[c].iov_base = (char*)&z->z_stats;
    stats_iov[c].iov_len = sizeof(z->z_stats);
  }
#endif
  dslog(LOG_INFO, 0, "rbldnsd version %s started (%d socket(s), %d zone(s))",
        version, numsock, numzones);
  initialized = 1;

  if (cfd >= 0) {
    write(cfd, "", 1);
    close(cfd);
    close(0); close(2);
    if (!flog) close(1);
    setsid();
    logto = LOGTO_SYSLOG;
  }

  if (quickstart)
    do_reload(0);

  /* only set "main" fork_on_reload after first reload */
  fork_on_reload = forkon;
}