Пример #1
0
/* Open the part NAME.  NAME consists of a partition number, a ':', a another
   store class name, a ':' and a name for to by passed to the store class.
   E.g. "2:device:hd0" would open the second partition on a DEVICE store
   named "hd0".  FLAGS indicate how to open the store.  CLASSES is used to
   select classes specified by the type NAME; if it is 0, STORE_STD_CLASSES
   is used.  The new store is returned in *STORE.  */
error_t
store_part_open (const char *name, int flags,
		 const struct store_class *const *classes,
		 struct store **store)
{
  int part;
  char *endp;
  struct store *source;
  error_t err;

  part = strtol (name, &endp, 0);
  if (endp == name || *endp != ':')
    return EINVAL;

  name = endp + 1;
  if (*name == '\0')
    return EINVAL;

  err = store_typed_open (name, flags, classes, &source);
  if (! err)
    {
      err = store_part_create (source, part, flags, store);
      if (err)
	store_free (source);
    }

  return err;
}
void ipv4_exec_reply_get_addr(struct finsFrame *ff, uint64_t src_mac, uint64_t dst_mac) {
	PRINT_DEBUG("Entered: ff=%p, src_mac=%llx, dst_mac=%llx", ff, src_mac, dst_mac);

	struct ip4_store *store = store_list_find(ff->ctrlFrame.serial_num);
	if (store) {
		store_list_remove(store);

		metadata *params = store->ff->metaData;

		uint32_t ether_type = IP4_ETH_TYPE;
		metadata_writeToElement(params, "send_dst_mac", &dst_mac, META_TYPE_INT64);
		metadata_writeToElement(params, "send_src_mac", &src_mac, META_TYPE_INT64);
		metadata_writeToElement(params, "send_ether_type", &ether_type, META_TYPE_INT32);

		PRINT_DEBUG("recv frame: dst=0x%12.12llx, src=0x%12.12llx, type=0x%x", dst_mac, src_mac, ether_type);

		//print_finsFrame(fins_frame);
		ipv4_to_switch(store->ff);
		store->ff = NULL;

		store_free(store);

		freeFinsFrame(ff);
	} else {
		PRINT_ERROR("todo error");
		//TODO error sending back FDF as FCF? saved pdu for that
	}
}
Пример #3
0
void*
channel_read (channel_t *channel)
{
  ensure(pthread_mutex_lock(&channel->mutex) == 0);
  channel->readers++;

  while (channel->backlog == 0)
    ensure(pthread_cond_wait(&channel->cond_read, &channel->mutex) == 0);

  channel->backlog--;

  channel_node_t *node = channel->list;
  channel->list = node->next;

  if (node == channel->last)
    channel->last = NULL;

  if (channel->writers)
    ensure(pthread_cond_signal(&channel->cond_write) == 0);

  channel->readers--;
  ensure(pthread_mutex_unlock(&channel->mutex) == 0);

  void *msg = malloc(node->length);
  memmove(msg, node->payload, node->length);

  store_free(global.store, node);
  return msg;
}
Пример #4
0
void
channel_free (channel_t *channel)
{
  if (channel->used)
  {
    while (channel->list)
    {
      channel_node_t *node = channel->list;
      channel->list = node->next;
      store_free(global.store, node);
    }
    pthread_mutex_destroy(&channel->mutex);
    pthread_cond_destroy(&channel->cond_read);
    pthread_cond_destroy(&channel->cond_write);
    store_free(global.store, channel->list);
    channel->used = 0;
  }
}
Пример #5
0
void ipv4_release(void) {
	PRINT_DEBUG("Entered");

	//TODO free all module related mem

	struct ip4_store *store;
	while (!store_list_is_empty()) {
		store = store_list;
		store_list_remove(store);
		store_free(store);
	}

	struct ip4_routing_table *table;
	while (routing_table) {
		table = routing_table;
		routing_table = routing_table->next_entry;

		free(table);
	}

	term_queue(IPv4_to_Switch_Queue); //TODO uncomment
	term_queue(Switch_to_IPv4_Queue);
}
void ipv4_exec_reply(struct finsFrame *ff) {
	PRINT_DEBUG("Entered: ff=%p, meta=%p", ff, ff->metaData);

	int ret = 0;

	metadata *params = ff->metaData;
	if (params) {
		switch (ff->ctrlFrame.param_id) {
		case EXEC_ARP_GET_ADDR:
			PRINT_DEBUG("param_id=EXEC_ARP_GET_ADDR (%d)", ff->ctrlFrame.param_id);

			if (ff->ctrlFrame.ret_val) {
				uint64_t src_mac, dst_mac;
				ret += metadata_readFromElement(params, "src_mac", &src_mac) == META_FALSE;
				ret += metadata_readFromElement(params, "dst_mac", &dst_mac) == META_FALSE;

				if (ret) {
					PRINT_ERROR("ret=%d", ret);
					//TODO send nack
				} else {
					//ipv4_exec_reply_get_addr(ff, src_mac, dst_mac);
					struct ip4_store *store = store_list_find(ff->ctrlFrame.serial_num);
					if (store) {
						PRINT_DEBUG("store=%p, ff=%p, serial_num=%u", store, store->ff, store->serial_num);
						store_list_remove(store);

						uint32_t ether_type = IP4_ETH_TYPE;
						metadata_writeToElement(store->ff->metaData, "send_ether_type", &ether_type, META_TYPE_INT32);
						metadata_writeToElement(store->ff->metaData, "send_dst_mac", &dst_mac, META_TYPE_INT64);
						metadata_writeToElement(store->ff->metaData, "send_src_mac", &src_mac, META_TYPE_INT64);

						PRINT_DEBUG("recv frame: dst=0x%12.12llx, src=0x%12.12llx, type=0x%x", dst_mac, src_mac, ether_type);

						//print_finsFrame(fins_frame);
						ipv4_to_switch(store->ff);
						store->ff = NULL;

						store_free(store);

						freeFinsFrame(ff);
					} else {
						PRINT_ERROR("todo error");
					}
				}
			} else {
				//TODO error sending back FDF as FCF? saved pdu for that
				PRINT_ERROR("todo error");
			}
			break;
		default:
			PRINT_ERROR("Error unknown param_id=%d", ff->ctrlFrame.param_id);
			//TODO implement?
			freeFinsFrame(ff);
			break;
		}
	} else {
		//TODO send nack
		PRINT_ERROR("Error fcf.metadata==NULL");
		freeFinsFrame(ff);
	}
}
Пример #7
0
static void ActOnMessage(uschar *id, uschar *action, uschar *address_arg)
{
int pid;
int pipe_fd[2];
int delivery = Ustrcmp(action + Ustrlen(action) - 2, "-M") == 0;
uschar *quote = US"";
uschar *at = US"";
uschar *qualify = US"";
uschar buffer[256];
queue_item *qq;
Widget text = NULL;

/* If the address arg is not empty and does not contain @ and there is a
qualify domain, qualify it. (But don't qualify '<>'.)*/

if (address_arg[0] != 0)
  {
  quote = US"\'";
  if (Ustrchr(address_arg, '@') == NULL &&
      Ustrcmp(address_arg, "<>") != 0 &&
      qualify_domain != NULL &&
      qualify_domain[0] != 0)
    {
    at = US"@";
    qualify = qualify_domain;
    }
  }
sprintf(CS buffer, "%s %s %s %s %s %s%s%s%s%s", exim_path,
  (alternate_config == NULL)? US"" : US"-C",
  (alternate_config == NULL)? US"" : alternate_config,
  action, id, quote, address_arg, at, qualify, quote);

/* If we know we are going to need the window, create it now. */

if (action_output || delivery)
  {
  text = text_create(id, text_depth);
  text_showf(text, "%s\n", buffer);
  }

/* Create the pipe for output. Remember, on most systems pipe[0] is
for reading and pipe[1] is for writing! Solaris, with its two-way
pipes is a trap! */

if (pipe(pipe_fd) != 0)
  {
  if (text == NULL)
    {
    text = text_create(id, text_depth);
    text_showf(text, "%s\n", buffer);
    }
  text_show(text, US"*** Failed to create pipe ***\n");
  return;
  }

if (  fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK)
   || fcntl(pipe_fd[1], F_SETFL, O_NONBLOCK))
  {
  perror("set nonblocking on pipe");
  exit(1);
  }

/* Delivering a message can take some time, and we want to show the
output as it goes along. This requires subprocesses and is coded below. For
other commands, we can assume an immediate response, and so need not waste
resources with subprocesses. If action_output is FALSE, don't show the
output at all. */

if (!delivery)
  {
  int count, rc;
  int save_stdout = dup(1);
  int save_stderr = dup(2);

  close(1);
  close(2);

  dup2(pipe_fd[1], 1);
  dup2(pipe_fd[1], 2);
  close(pipe_fd[1]);

  rc = system(CS buffer);

  close(1);
  close(2);

  if (action_output || rc != 0)
    {
    if (text == NULL)
      {
      text = text_create(id, text_depth);
      text_showf(text, "%s\n", buffer);
      }
    while ((count = read(pipe_fd[0], buffer, 254)) > 0)
      {
      buffer[count] = 0;
      text_show(text, buffer);
      }
    }

  close(pipe_fd[0]);

  dup2(save_stdout, 1);
  dup2(save_stderr, 2);
  close(save_stdout);
  close(save_stderr);

  /* If action was to change the sender, and it succeeded, we have to
  update the in-store data. */

  if (rc == 0 && Ustrcmp(action + Ustrlen(action) - 4, "-Mes") == 0)
    {
    queue_item *q = find_queue(id, queue_noop, 0);
    if (q)
      {
      if (q->sender) store_free(q->sender);
      q->sender = store_malloc(Ustrlen(address_arg) + 1);
      Ustrcpy(q->sender, address_arg);
      }
    }

  /* If configured, cause a display update and return */

  if (action_queue_update) tick_queue_accumulator = 999999;
  return;
  }

/* Message is to be delivered. Ensure that it is marked unfrozen,
because nothing will get written to the log to show that this has
happened. (Other freezing/unfreezings get logged and picked up from
there.) */

qq = find_queue(id, queue_noop, 0);
if (qq != NULL) qq->frozen = FALSE;

/* New, asynchronous code runs in a subprocess for commands that
will take some time. The main process does not wait. There is a
SIGCHLD handler in the main program that cleans up any terminating
sub processes. */

if ((pid = fork()) == 0)
  {
  close(1);
  close(2);

  dup2(pipe_fd[1], 1);
  dup2(pipe_fd[1], 2);
  close(pipe_fd[1]);

  system(CS buffer);

  close(1);
  close(2);
  close(pipe_fd[0]);
  _exit(0);
  }

/* Main process - set up an item for the main ticker to watch. */

if (pid < 0) text_showf(text, "Failed to fork: %s\n", strerror(errno)); else
  {
  pipe_item *p = (pipe_item *)store_malloc(sizeof(pipe_item));

  if (p == NULL)
    {
    text_show(text, US"Run out of store\n");
    return;
    }

  p->widget = text;
  p->fd = pipe_fd[0];

  p->next = pipe_chain;
  pipe_chain = p;

  close(pipe_fd[1]);
  }
}
Пример #8
0
void
auth_heimdal_gssapi_init(auth_instance *ablock)
{
  krb5_context context;
  krb5_keytab keytab;
  krb5_kt_cursor cursor;
  krb5_keytab_entry entry;
  krb5_error_code krc;
  char *principal, *enctype_s;
  const char *k_keytab_typed_name = NULL;
  auth_heimdal_gssapi_options_block *ob =
    (auth_heimdal_gssapi_options_block *)(ablock->options_block);

  ablock->server = FALSE;
  ablock->client = FALSE;

  if (!ob->server_service || !*ob->server_service) {
    HDEBUG(D_auth) debug_printf("heimdal: missing server_service\n");
    return;
  }

  krc = krb5_init_context(&context);
  if (krc != 0) {
    int kerr = errno;
    HDEBUG(D_auth) debug_printf("heimdal: failed to initialise krb5 context: %s\n",
        strerror(kerr));
    return;
  }

  if (ob->server_keytab) {
    k_keytab_typed_name = CCS string_sprintf("file:%s", expand_string(ob->server_keytab));
    HDEBUG(D_auth) debug_printf("heimdal: using keytab %s\n", k_keytab_typed_name);
    krc = krb5_kt_resolve(context, k_keytab_typed_name, &keytab);
    if (krc) {
      HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_resolve", context, krc);
      return;
    }
  } else {
    HDEBUG(D_auth) debug_printf("heimdal: using system default keytab\n");
    krc = krb5_kt_default(context, &keytab);
    if (krc) {
      HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_default", context, krc);
      return;
    }
  }

  HDEBUG(D_auth) {
    /* http://www.h5l.org/manual/HEAD/krb5/krb5_keytab_intro.html */
    krc = krb5_kt_start_seq_get(context, keytab, &cursor);
    if (krc)
      exim_heimdal_error_debug("krb5_kt_start_seq_get", context, krc);
    else {
      while ((krc = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
        principal = enctype_s = NULL;
        krb5_unparse_name(context, entry.principal, &principal);
        krb5_enctype_to_string(context, entry.keyblock.keytype, &enctype_s);
        debug_printf("heimdal: keytab principal: %s  vno=%d  type=%s\n",
            principal ? principal : "??",
            entry.vno,
            enctype_s ? enctype_s : "??");
        free(principal);
        free(enctype_s);
        krb5_kt_free_entry(context, &entry);
      }
      krc = krb5_kt_end_seq_get(context, keytab, &cursor);
      if (krc)
        exim_heimdal_error_debug("krb5_kt_end_seq_get", context, krc);
    }
  }

  krc = krb5_kt_close(context, keytab);
  if (krc)
    HDEBUG(D_auth) exim_heimdal_error_debug("krb5_kt_close", context, krc);

  krb5_free_context(context);

  /* RFC 4121 section 5.2, SHOULD support 64K input buffers */
  if (big_buffer_size < (64 * 1024)) {
    uschar *newbuf;
    big_buffer_size = 64 * 1024;
    newbuf = store_malloc(big_buffer_size);
    store_free(big_buffer);
    big_buffer = newbuf;
  }

  ablock->server = TRUE;
}
Пример #9
0
void init_lookup_list(void)
{
#ifdef LOOKUP_MODULE_DIR
  DIR *dd;
  struct dirent *ent;
  int countmodules = 0;
  int moduleerrors = 0;
#endif
  struct lookupmodulestr *p;
  const pcre *regex_islookupmod = regex_must_compile(
      US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);

  if (lookup_list_init_done)
    return;
  lookup_list_init_done = 1;

#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
  addlookupmodule(NULL, &cdb_lookup_module_info);
#endif

#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
  addlookupmodule(NULL, &dbmdb_lookup_module_info);
#endif

#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
  addlookupmodule(NULL, &dnsdb_lookup_module_info);
#endif

#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
  addlookupmodule(NULL, &dsearch_lookup_module_info);
#endif

#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
  addlookupmodule(NULL, &ibase_lookup_module_info);
#endif

#ifdef LOOKUP_LDAP
  addlookupmodule(NULL, &ldap_lookup_module_info);
#endif

#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
  addlookupmodule(NULL, &lsearch_lookup_module_info);
#endif

#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
  addlookupmodule(NULL, &mysql_lookup_module_info);
#endif

#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
  addlookupmodule(NULL, &nis_lookup_module_info);
#endif

#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
  addlookupmodule(NULL, &nisplus_lookup_module_info);
#endif

#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
  addlookupmodule(NULL, &oracle_lookup_module_info);
#endif

#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
  addlookupmodule(NULL, &passwd_lookup_module_info);
#endif

#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
  addlookupmodule(NULL, &pgsql_lookup_module_info);
#endif

#ifdef EXPERIMENTAL_REDIS
  addlookupmodule(NULL, &redis_lookup_module_info);
#endif

#ifdef EXPERIMENTAL_SPF
  addlookupmodule(NULL, &spf_lookup_module_info);
#endif

#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
  addlookupmodule(NULL, &sqlite_lookup_module_info);
#endif

#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
  addlookupmodule(NULL, &testdb_lookup_module_info);
#endif

#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
  addlookupmodule(NULL, &whoson_lookup_module_info);
#endif

#ifdef LOOKUP_MODULE_DIR
  dd = opendir(LOOKUP_MODULE_DIR);
  if (dd == NULL) {
    DEBUG(D_lookup) debug_printf("Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
    log_write(0, LOG_MAIN, "Couldn't open %s: not loading lookup modules\n", LOOKUP_MODULE_DIR);
  }
  else {
    DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
    while ((ent = readdir(dd)) != NULL) {
      char *name = ent->d_name;
      int len = (int)strlen(name);
      if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0) {
        int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
        void *dl;
        struct lookup_module_info *info;
        const char *errormsg;

        /* SRH: am I being paranoid here or what? */
        if (pathnamelen > big_buffer_size) {
          fprintf(stderr, "Loading lookup modules: %s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
          log_write(0, LOG_MAIN|LOG_PANIC, "%s/%s: name too long\n", LOOKUP_MODULE_DIR, name);
          continue;
        }

        /* SRH: snprintf here? */
        sprintf(CS big_buffer, "%s/%s", LOOKUP_MODULE_DIR, name);

        dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY
        if (dl == NULL) {
          fprintf(stderr, "Error loading %s: %s\n", name, dlerror());
          moduleerrors++;
          log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror());
          continue;
        }

        /* FreeBSD nsdispatch() can trigger dlerror() errors about
         * _nss_cache_cycle_prevention_function; we need to clear the dlerror()
         * state before calling dlsym(), so that any error afterwards only
         * comes from dlsym().
         */
        errormsg = dlerror();

        info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info");
        if ((errormsg = dlerror()) != NULL) {
          fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
          dlclose(dl);
          moduleerrors++;
          log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg);
          continue;
        }
        if (info->magic != LOOKUP_MODULE_INFO_MAGIC) {
          fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name);
          dlclose(dl);
          moduleerrors++;
          log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name);
          continue;
        }

        addlookupmodule(dl, info);
        DEBUG(D_lookup) debug_printf("Loaded \"%s\" (%d lookup types)\n", name, info->lookupcount);
        countmodules++;
      }
    }
    closedir(dd);
  }

  DEBUG(D_lookup) debug_printf("Loaded %d lookup modules\n", countmodules);
#endif

  store_free((void*)regex_islookupmod);

  DEBUG(D_lookup) debug_printf("Total %d lookups\n", lookup_list_count);

  lookup_list = store_malloc(sizeof(lookup_info *) * lookup_list_count);
  memset(lookup_list, 0, sizeof(lookup_info *) * lookup_list_count);

  /* now add all lookups to the real list */
  p = lookupmodules;
  while (p) {
    int j;
    struct lookupmodulestr *pnext;

    for (j = 0; j < p->info->lookupcount; j++)
      add_lookup_to_list(p->info->lookups[j]);

    pnext = p->next;
    store_free(p);
    p = pnext;
  }
  /* just to be sure */
  lookupmodules = NULL;
}
Пример #10
0
error_t
trivfs_S_file_get_storage_info (struct trivfs_protid *cred,
                                mach_port_t reply,
                                mach_msg_type_name_t reply_type,
                                mach_port_t **ports,
                                mach_msg_type_name_t *ports_type,
                                mach_msg_type_number_t *num_ports,
                                int **ints, mach_msg_type_number_t *num_ints,
                                off_t **offsets,
                                mach_msg_type_number_t *num_offsets,
                                char **data, mach_msg_type_number_t *data_len)
{
    *ports_type = MACH_MSG_TYPE_COPY_SEND;

    if (! cred || ! cred->po->hook)
        return EOPNOTSUPP;
    else
    {
        error_t err;
        struct dev *dev = ((struct open *)cred->po->hook)->dev;
        struct store *store = dev->store;

        if (dev->enforced && !(store->flags & STORE_ENFORCED))
        {
            /* The --enforced switch tells us not to let anyone
               get at the device, no matter how trustable they are.  */
            size_t name_len = (store->name ? strlen (store->name) + 1 : 0);
            int i;
            *num_ports = 0;
            i = 0;
            (*ints)[i++] = STORAGE_OTHER;
            (*ints)[i++] = store->flags;
            (*ints)[i++] = store->block_size;
            (*ints)[i++] = 1;	/* num_runs */
            (*ints)[i++] = name_len;
            (*ints)[i++] = 0;	/* misc_len */
            *num_ints = i;
            i = 0;
            (*offsets)[i++] = 0;
            (*offsets)[i++] = store->size;
            *num_offsets = i;
            if (store->name)
                memcpy (*data, store->name, name_len);
            *data_len = name_len;
            return 0;
        }

        if (!cred->isroot
                && !store_is_securely_returnable (store, cred->po->openmodes))
        {
            struct store *clone;
            err = store_clone (store, &clone);
            if (! err)
            {
                err = store_set_flags (clone, STORE_INACTIVE);
                if (err == EINVAL)
                    err = EACCES;
                else
                    err = store_return (clone,
                                        ports, num_ports, ints, num_ints,
                                        offsets, num_offsets, data, data_len);
                store_free (clone);
            }
        }
        else
            err = store_return (store,
                                ports, num_ports, ints, num_ints,
                                offsets, num_offsets, data, data_len);

        return err;
    }
}