Example #1
0
bool_t
xdr_statfsokres(XDR *xdrs, nfsstatfsokres *objp)
{
  if (amuDebug(D_XDRTRACE))
    plog(XLOG_DEBUG, "xdr_statfsokres:");

  if (!xdr_u_int(xdrs, &objp->sfrok_tsize)) {
    return (FALSE);
  }
  if (!xdr_u_int(xdrs, &objp->sfrok_bsize)) {
    return (FALSE);
  }
  if (!xdr_u_int(xdrs, &objp->sfrok_blocks)) {
    return (FALSE);
  }
  if (!xdr_u_int(xdrs, &objp->sfrok_bfree)) {
    return (FALSE);
  }
  if (!xdr_u_int(xdrs, &objp->sfrok_bavail)) {
    return (FALSE);
  }
  return (TRUE);
}
Example #2
0
/*
 * Retry a mount
 */
static void
amfs_retry(int rc, int term, opaque_t arg)
{
  struct continuation *cp = (struct continuation *) arg;
  am_node *mp = cp->mp;
  int error = 0;

  dlog("Commencing retry for mount of %s", mp->am_path);

  new_ttl(mp);

  if ((cp->start + ALLOWED_MOUNT_TIME) < clocktime(NULL)) {
    /*
     * The entire mount has timed out.  Set the error code and skip past all
     * the mntfs's so that amfs_bgmount will not have any more
     * ways to try the mount, thus causing an error.
     */
    plog(XLOG_INFO, "mount of \"%s\" has timed out", mp->am_path);
    error = ETIMEDOUT;
    while (*cp->al)
      cp->al++;
    /* explicitly forbid further retries after timeout */
    cp->retry = FALSE;
  }
  if (error || !IN_PROGRESS(cp))
    error = amfs_bgmount(cp);
  else
    /* Normally it's amfs_bgmount() which frees the continuation. However, if
     * the mount is already in progress and we're in amfs_retry() for another
     * node we don't try mounting the filesystem once again. Still, we have
     * to free the continuation as we won't get called again and thus would
     * leak the continuation structure and our am_loc references.
     */
    free_continuation(cp);

  reschedule_timeout_mp();
}
Example #3
0
int
handle_vendorid(struct ph1handle *iph1, struct isakmp_gen *gen)
{
	int vid_numeric;

	vid_numeric = check_vendorid(gen);
	if (vid_numeric == VENDORID_UNKNOWN)
		return vid_numeric;

	iph1->vendorid_mask |= BIT(vid_numeric);

#ifdef ENABLE_NATT
	if (natt_vendorid(vid_numeric))
		natt_handle_vendorid(iph1, vid_numeric);
#endif
#ifdef ENABLE_HYBRID
	switch (vid_numeric) {
	case VENDORID_XAUTH:
		iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_XAUTH;
		break;
	case VENDORID_UNITY:
		iph1->mode_cfg->flags |= ISAKMP_CFG_VENDORID_UNITY;
		break;
	default:
		break;
	}
#endif
#ifdef ENABLE_DPD
	if (vid_numeric == VENDORID_DPD &&
	    (iph1->rmconf == NULL || iph1->rmconf->dpd)) {
		iph1->dpd_support = 1;
		plog(LLV_DEBUG, LOCATION, NULL, "remote supports DPD\n");
	}
#endif

	return vid_numeric;
}
Example #4
0
/**
 * Load a CRL
 */
static x509crl_t *builder_load_crl(certificate_type_t type, va_list args)
{
	chunk_t blob = chunk_empty;
	x509crl_t *crl;

	while (TRUE)
	{
		switch (va_arg(args, builder_part_t))
		{
			case BUILD_BLOB_ASN1_DER:
				blob = va_arg(args, chunk_t);
				continue;
			case BUILD_END:
				break;
			default:
				return NULL;
		}
		break;
	}
	if (blob.ptr)
	{
		crl = malloc_thing(x509crl_t);
		crl->next = NULL;
		crl->distributionPoints = linked_list_create();
		crl->crl = lib->creds->create(lib->creds,
							  		  CRED_CERTIFICATE, CERT_X509_CRL,
							  		  BUILD_BLOB_ASN1_DER, blob,
							  		  BUILD_END);
		if (crl->crl)
		{
			return crl;
		}
		plog("  error in X.509 crl");
		free_crl(crl);
	}
	return NULL;
}
Example #5
0
/*
 * Remove am from its place in the mount tree
 */
static void
remove_am(am_node *mp)
{
  /*
   * 1.  Consistency check
   */
  if (mp->am_child && mp->am_parent) {
    plog(XLOG_WARNING, "children of \"%s\" still exist - deleting anyway", mp->am_path);
  }

  /*
   * 2.  Update parent's child pointer
   */
  if (mp->am_parent && mp->am_parent->am_child == mp)
    mp->am_parent->am_child = mp->am_osib;

  /*
   * 3.  Unlink from sibling chain
   */
  if (mp->am_ysib)
    mp->am_ysib->am_osib = mp->am_osib;
  if (mp->am_osib)
    mp->am_osib->am_ysib = mp->am_ysib;
}
Example #6
0
bool_t
xdr_umntrequest(XDR *xdrs, umntrequest *objp)
{
#ifdef DEBUG
  amuDebug(D_XDRTRACE)
    plog(XLOG_DEBUG, "xdr_umntrequest:");
#endif /* DEBUG */

  if (!xdr_int(xdrs, &objp->isdirect))
    return (FALSE);

  if (!xdr_u_int(xdrs, (u_int *) &objp->devid))
    return (FALSE);

#ifdef HAVE_UMNTREQUEST_RDEVID
  if (!xdr_u_long(xdrs, &objp->rdevid))
    return (FALSE);
#endif /* HAVE_UMNTREQUEST_RDEVID */

  if (!xdr_pointer(xdrs, (char **) &objp->next, sizeof(umntrequest), (XDRPROC_T_TYPE) xdr_umntrequest))
    return (FALSE);

  return (TRUE);
}
Example #7
0
void CopyPhotosDialog::receivedPhotos_getInTarget(VKRequest *req)
{
    if((req->reqType!=VKRequest::Photos_get) ||
            (reqPhotosGetInTarget != req->reqId)){
        return;
    }
    reqPhotosGetInTarget = -1;
    plog(tr("Get target album photos description"));

    photosInTarget.clear();

    QDomDocument doc("Photos");
    doc.setContent(req->result);
    QDomElement docElem = doc.documentElement();
    QDomNodeList users = docElem.elementsByTagName ( "photo" );
    for(int i=0; i < users.count(); i++){
        QDomElement userElem = users.at(i).toElement();

        VKAlbumPhoto photo;

        photo.pid = userElem.elementsByTagName("pid").at(0).toElement().text();
        photo.aid = userElem.elementsByTagName("aid").at(0).toElement().text();
        photo.owner_id = userElem.elementsByTagName("owner_id").at(0).toElement().text();
        photo.src = userElem.elementsByTagName("src").at(0).toElement().text();
        photo.src_big = userElem.elementsByTagName("src_big").at(0).toElement().text();
        photo.src_small = userElem.elementsByTagName("src_small").at(0).toElement().text();
        photo.text = userElem.elementsByTagName("text").at(0).toElement().text();
        photo.src_xbig = userElem.elementsByTagName("src_xbig").at(0).toElement().text();
        photo.src_xxbig = userElem.elementsByTagName("src_xxbig").at(0).toElement().text();
        photo.cacheFileName = albumDir + photo.src_big.right(photo.src_big.length() - (photo.src_big.lastIndexOf("/")));

        photosInTarget.append( photo );
    }

    reqPhotosGet = m_vkEngine->reqPhotos_get(gidFrom, aidFrom);
}
Example #8
0
/*
 * allocate a peer-specified address from pool
 * returns pointer to struct of address if successful
 * returns 0 if address already used or any error
 *
 * caller must do LIST_INSERT_HEAD(&child_sa->rcf_lease_list, i, link_sa);
 */
struct rcf_address *
rc_addrpool_assign(struct rcf_addresspool *conf, int af, uint8_t *addr)
{
	size_t	addrsize;
	struct rcf_address_pool_item	*i;
	struct rcf_address	*a;

	if (!conf) {
		plog(PLOG_INTERR, PLOGLOC, NULL,
		     "no address pool specified\n");
		return 0;
	}

	addrsize = af_addrsize(af);
	if (addrsize == 0)
		return 0;
	for (i = LIST_FIRST(&conf->pool_list); i != NULL; i = LIST_NEXT(i, link)) {
		if (af != i->af)
			continue;

		if (memcmp(addr, i->start, addrsize) < 0 ||
		    memcmp(addr, i->end, addrsize) > 0)
			continue;	/* out of range, try next */

		if (addrpool_check(i, addr) != 0)
			continue;

		a = rc_address_new(af, addr, IPV6_ADDRESS_PREFIX_LEN, 0,
				   &i->lease_list);
		if (!a)
			return 0;	/* allocation failed */
		return a;
	}

	return 0;
}
Example #9
0
/*
 * Read a mount table into memory
 */
mntlist *
read_mtab(char *fs, const char *mnttabname)
{
  mntlist **mpp, *mhp;
  /* From: Piete Brooks <*****@*****.**> */
  int loc = 0;
  struct fs_data mountbuffer[NMOUNT], *fs_data;
  int ret;

  mpp = &mhp;
  while ((ret = getmountent(&loc, mountbuffer, NMOUNT)) > 0) {
    for (fs_data = mountbuffer; fs_data < &mountbuffer[ret]; fs_data++) {
      /*
       * Allocate a new slot
       */
      *mpp = ALLOC(struct mntlist);

      /*
       * Copy the data returned by getmntent
       */
      (*mpp)->mnt = mnt_dup(fs_data);

      /*
       * Move to next pointer
       */
      mpp = &(*mpp)->mnext;
    }
  }
  if (ret < 0) {
    plog(XLOG_ERROR, "getmountent: %m");
    return 0;
  }
  *mpp = NULL;

  return mhp;
}
int BitMapCheckEnd(void)
{
	if (gBitMapInited) {
#if _VBC_DEBUG_
		int maxdepth = 0;

		BMS_MaxDepth(gBMS_Root, 0, &maxdepth);
		plog("   %d full segments, %d segment nodes (max depth was %d nodes)\n",
		       gFullSegments, gSegmentNodes, maxdepth);
#endif
		free(gFullBitmapSegment);
		gFullBitmapSegment = NULL;

		free(gEmptyBitmapSegment);
		gEmptyBitmapSegment = NULL;

		bit_dealloc(gFullSegmentList);
		gFullSegmentList = NULL;

		BMS_DisposeTree();
		gBitMapInited = 0;
	}
	return (0);
}
Example #11
0
File: xutil.c Project: 0mp/freebsd
/*
 * Remove as many directories in the path as possible.
 * Give up if the directory doesn't appear to have
 * been created by Amd (not mode dr-x) or an rmdir
 * fails for any reason.
 */
void
rmdirs(char *dir)
{
  char *xdp = xstrdup(dir);
  char *dp;

  do {
    struct stat stb;
    /*
     * Try to find out whether this was
     * created by amd.  Do this by checking
     * for owner write permission.
     */
    if (stat(xdp, &stb) == 0 && (stb.st_mode & 0200) == 0) {
      if (rmdir(xdp) < 0) {
	if (errno != ENOTEMPTY &&
	    errno != EBUSY &&
	    errno != EEXIST &&
	    errno != EROFS &&
	    errno != EINVAL)
	  plog(XLOG_ERROR, "rmdir(%s): %m", xdp);
	break;
      } else {
	dlog("rmdir(%s)", xdp);
      }
    } else {
      break;
    }

    dp = strrchr(xdp, '/');
    if (dp)
      *dp = '\0';
  } while (dp && dp > xdp);

  XFREE(xdp);
}
Example #12
0
/*
 * Play a sound of type "event".
 */
static void play_sound(int event)
{
	Mix_Chunk *wave = NULL;
	int s;

	/* Paranoia */
	if (event < 0 || event >= MSG_MAX) return;

	/* Check there are samples for this event */
	if (!samples[event].num) return;

	/* Choose a random event */
	s = rand_int(samples[event].num);
	wave = samples[event].wavs[s];

	/* Try loading it, if it's not cached */
	if (!wave)
	{
		/* Verify it exists */
		const char *filename = samples[event].paths[s];
		if (!file_exists(filename)) return;

		/* Load */
		wave = Mix_LoadWAV(filename);
	}

	/* Check to see if we have a wave again */
	if (!wave)
	{
		plog("SDL sound load failed.");
		return;
	}

	/* Actually play the thing */
	Mix_PlayChannel(-1, wave, 0);
}
Example #13
0
/*
 * Mount a top level automount node
 * by calling lookup in the parent
 * (root) node which will cause the
 * automount node to be automounted.
 */
int
mount_auto_node(char *dir, opaque_t arg)
{
  int error = 0;
  am_node *mp = (am_node *) arg;
  am_node *new_mp;

  new_mp = mp->am_mnt->mf_ops->lookup_child(mp, dir, &error, VLOOK_CREATE);
  if (new_mp && error < 0) {
    /*
     * We can't allow the fileid of the root node to change.
     * Should be ok to force it to 1, always.
     */
    new_mp->am_gen = new_mp->am_fattr.na_fileid = 1;

    new_mp = mp->am_mnt->mf_ops->mount_child(new_mp, &error);
  }

  if (error > 0) {
    errno = error;		/* XXX */
    plog(XLOG_ERROR, "Could not mount %s: %m", dir);
  }
  return error;
}
Example #14
0
int
autofs_get_fh(am_node *mp)
{
    autofs_fh_t *fh;
    char buf[MAXHOSTNAMELEN];
    mntfs *mf = mp->am_al->al_mnt;
    struct utsname utsname;

    plog(XLOG_DEBUG, "autofs_get_fh for %s", mp->am_path);
    fh = ALLOC(autofs_fh_t);
    memset((voidp) fh, 0, sizeof(autofs_fh_t)); /* Paranoid */

    /*
     * SET MOUNT ARGS
     */
    if (uname(&utsname) < 0) {
        xstrlcpy(buf, "localhost.autofs", sizeof(buf));
    } else {
        xstrlcpy(buf, utsname.nodename, sizeof(buf));
        xstrlcat(buf, ".autofs", sizeof(buf));
    }
#ifdef HAVE_AUTOFS_ARGS_T_ADDR
    fh->addr.buf = xstrdup(buf);
    fh->addr.len = fh->addr.maxlen = strlen(buf);
#endif /* HAVE_AUTOFS_ARGS_T_ADDR */

    fh->direct = (mf->mf_fsflags & FS_DIRECT) ? 1 : 0;
    fh->rpc_to = 1;		/* XXX: arbitrary */
    fh->mount_to = mp->am_timeo;
    fh->path = mp->am_path;
    fh->opts = "";		/* XXX: arbitrary */
    fh->map = mp->am_path;	/* this is what we get back in readdir */

    mp->am_autofs_fh = fh;
    return 0;
}
Example #15
0
void
mf_mounted(mntfs *mf)
{
  int quoted;
  int wasmounted = mf->mf_flags & MFF_MOUNTED;

  if (!wasmounted) {
    /*
     * If this is a freshly mounted
     * filesystem then update the
     * mntfs structure...
     */
    mf->mf_flags |= MFF_MOUNTED;
    mf->mf_error = 0;

    /*
     * Do mounted callback
     */
    if (mf->mf_ops->mounted) {
      (*mf->mf_ops->mounted) (mf);
    }

    mf->mf_fo = 0;
  }

  /*
   * Log message
   */
  quoted = strchr(mf->mf_info, ' ') != 0;
  plog(XLOG_INFO, "%s%s%s %s fstype %s on %s",
       quoted ? "\"" : "",
       mf->mf_info,
       quoted ? "\"" : "",
       wasmounted ? "referenced" : "mounted",
       mf->mf_ops->fs_type, mf->mf_mount);
}
Example #16
0
// If we can't resolve the symbols, we assume it's because we don't have symbols
// so we'll try to download them and retry. If we can resolve symbols, we'll
// get the callstacks etc. and submit to our server for analysis.
void SubmitCrashInfo()
{
    if (!dir::Create(gSymbolsDir)) {
        plog("SubmitCrashInfo(): couldn't create symbols dir");
        return;
    }

    lf("SubmitCrashInfo(): start");
    lf(L"SubmitCrashInfo(): gSymbolPathW: '%s'", gSymbolPathW);
    if (!CrashHandlerCanUseNet()) {
        plog("SubmitCrashInfo(): internet access not allowed");
        return;
    }

    char *s = NULL;
    if (!dbghelp::Initialize(gSymbolPathW)) {
        plog("SubmitCrashInfo(): dbghelp::Initialize() failed");
        return;
    }

    if (!dbghelp::HasSymbols()) {
        if (!DownloadAndUnzipSymbols(gPdbZipPath, gSymbolsDir)) {
            plog("SubmitCrashInfo(): failed to download symbols");
            return;
        }

        if (!dbghelp::Initialize(gSymbolPathW, true)) {
            plog("SubmitCrashInfo(): second dbghelp::Initialize() failed");
            return;
        }
    }

    if (!dbghelp::HasSymbols()) {
        plog("SubmitCrashInfo(): HasSymbols() false after downloading symbols");
        return;
    }

    s = BuildCrashInfoText();
    if (!s)
        return;
    SendCrashInfo(s);
    gCrashHandlerAllocator->Free(s);
}
Example #17
0
/*
 * Check for various permissions on executable map without trying to
 * fork a new executable-map process.
 *
 * return: >0 (errno) if failed
 *          0 if ok
 */
static int
exec_check_perm(char *map)
{
  struct stat sb;

  /* sanity and permission checks */
  if (!map) {
    dlog("exec_check_permission got a NULL map");
    return EINVAL;
  }
  if (stat(map, &sb)) {
    plog(XLOG_ERROR, "map \"%s\" stat failure: %m", map);
    return errno;
  }
  if (!S_ISREG(sb.st_mode)) {
    plog(XLOG_ERROR, "map \"%s\" should be regular file", map);
    return EINVAL;
  }
  if (sb.st_uid != 0) {
    plog(XLOG_ERROR, "map \"%s\" owned by uid %u (must be 0)", map, (u_int) sb.st_uid);
    return EACCES;
  }
  if (!(sb.st_mode & S_IXUSR)) {
    plog(XLOG_ERROR, "map \"%s\" should be executable", map);
    return EACCES;
  }
  if (sb.st_mode & (S_ISUID|S_ISGID)) {
    plog(XLOG_ERROR, "map \"%s\" should not be setuid/setgid", map);
    return EACCES;
  }
  if (sb.st_mode & S_IWOTH) {
    plog(XLOG_ERROR, "map \"%s\" should not be world writeable", map);
    return EACCES;
  }

  return 0;			/* all is well */
}
Example #18
0
void showConfig(Config config)
{
	LogLevel logLevel = initLoggerLevel();
	char *msg;
	plog("==== DISPLAY SIMEON CONFIG ==== \n", logLevel.INFO);
	msg= calloc(64, sizeof(char));
	sprintf(msg, "DEFAULT_PORT = %d\n", config.DEFAULT_PORT);
	plog(msg, logLevel.INFO);
	memset(msg, 0, 64);
	
	sprintf(msg, "VERBOSE = %d\n", config.VERBOSE);
	plog(msg, logLevel.INFO);
	memset(msg, 0, 64);

	sprintf(msg, "CONTROL_PORT = %d\n", config.CONTROL_PORT);
	plog(msg, logLevel.INFO);
	memset(msg, 0, 64);

	sprintf(msg, "LOGS_PATH = %s\n", config.LOGS_PATH);
	plog(msg, logLevel.INFO);
	memset(msg, 0, 64);
	plog("=============================== \n", 0);
	free(msg);
}
Example #19
0
/** Lookup information about the hostpair, and set things like bandwidth
 * relative crypto strength, compression and credentials.
 * 
 * @param IPsec Policy Query
 * @return void
 */
static void
info_lookuphostpair(struct ipsec_policy_cmd_query *ipcq)
{
    struct connection *c;
    struct state *p1st, *p2st;


    /* default result: no crypto */
    ipcq->strength  = IPSEC_PRIVACY_NONE;
    ipcq->bandwidth = IPSEC_QOS_WIRESPEED;
    ipcq->credential_count = 0;

#ifdef DEBUG
    {
	char sstr[ADDRTOT_BUF], dstr[ADDRTOT_BUF];

	addrtot(&ipcq->query_local,  0, sstr, sizeof(sstr));
	addrtot(&ipcq->query_remote, 0, dstr, sizeof(dstr));
	DBG_log("info request for %s -> %s", sstr, dstr);
    }
#endif

    /* okay, look up what connection handles this ip pair */

    c = find_connection_for_clients(NULL,
				    &ipcq->query_local,
				    &ipcq->query_remote,
				    ipcq->proto);
    if (c == NULL)
    {
	/* try reversing it */
	c = find_connection_for_clients(NULL,
					&ipcq->query_remote,
					&ipcq->query_local,
					ipcq->proto);
	if (c != NULL)
	{
	    ip_address tmp;
	    /* If it is reversed, swap it */
	    tmp = ipcq->query_local;
	    ipcq->query_local = ipcq->query_remote;
	    ipcq->query_remote = tmp;
	}
    }
    
    if (c == NULL)
    {
#ifdef DEBUG
	DBG_log("no connection found");
#endif
	return;	/* no crypto */
    }

    if (c->newest_ipsec_sa == SOS_NOBODY)
    {
	ip_subnet us, them;

	DBG_log("connection %s found, no ipsec state, looking again", c->name);
	addrtosubnet(&ipcq->query_local, &us);
	addrtosubnet(&ipcq->query_remote, &them);
	c = find_client_connection(c, &us, &them, 0, 0, 0, 0);

	if (c == NULL)
	    return;	/* no crypto */
    }

    DBG_log("connection %s[%ld] with state %u"
	, c->name, c->instance_serial
	, (unsigned int)c->newest_ipsec_sa);

    if (c->newest_ipsec_sa == SOS_NOBODY)
	return;	/* no crypto */

    /* we found a connection, try to lookup the state */
    p2st = state_with_serialno(c->newest_ipsec_sa);

    p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);

    if (p1st == NULL || p2st == NULL)
    {
	DBG_log("connection %s[%ld] has missing states %s %s"
	    , c->name, c->instance_serial
	    , (p1st ? "phase1" : "")
	    , (p2st ? "phase1" : ""));
	return;	/* no crypto */
    }

    /* if we have AH present, then record minimal info */
    if (p2st->st_ah.present)
    {
	ipcq->strength = IPSEC_PRIVACY_INTEGRAL;
	ipcq->auth_detail = p2st->st_esp.attrs.transattrs.integ_hash;
    }

    if (p2st->st_esp.present)
    {
	/*
	 * XXX-mcr Please do not shout at me about relative strengths
	 *         here. I'm not a cryptographer. I just diddle bits.
	 */
	switch (p2st->st_esp.attrs.transattrs.encrypt)
	{
	case ESP_NULL:
	    /* actually, do not change it if we set it from AH */
	    break;

	case ESP_DES:
	case ESP_DES_IV64:
	case ESP_DES_IV32:
	case ESP_RC4:
	    ipcq->strength = IPSEC_PRIVACY_ROT13;
	    break;
	    
	case ESP_RC5:
	case ESP_IDEA:
	case ESP_CAST:
	case ESP_BLOWFISH:
	case ESP_3DES:
	    ipcq->strength = IPSEC_PRIVACY_PRIVATE;
	    ipcq->bandwidth = IPSEC_QOS_VOIP;
	    break;

	case ESP_3IDEA:
	    ipcq->strength = IPSEC_PRIVACY_STRONG;
	    ipcq->bandwidth = IPSEC_QOS_INTERACTIVE;
	    break;

	case ESP_AES:
	    ipcq->strength = IPSEC_PRIVACY_STRONG;
	    ipcq->bandwidth = IPSEC_QOS_FTP;
	    break;
	}
	ipcq->esp_detail = p2st->st_esp.attrs.transattrs.encrypt;
    }

    if (p2st->st_ipcomp.present)
	ipcq->comp_detail = p2st->st_esp.attrs.transattrs.encrypt;

    /* now! the credentails that were used */
    /* for the moment we only have 1 credential, the DNS name,
     * because the DNS servers do not return the chain of SIGs yet
     */

    if(!c->spd.this.key_from_DNS_on_demand)
    {
	/* the key didn't come from the DNS in some way,
	 * so it must have been loaded locally.
	 */
	ipcq->credential_count = 1;
	ipcq->credentials[0].ii_type   = c->spd.this.id.kind;
	ipcq->credentials[0].ii_format = CERT_RAW_RSA;
    }
	
#if 0
    switch (c->spd.id.kind)
    {
    case ID_IPV4_ADDR:
    }
    if (c->gw_info == NULL)
    {
	plog("rcv_info: connection %s had NULL gw_info.", c->name);
	return
    }
#endif

    ipcq->credential_count = 1;

    /* pull credentials out of gw_info */
    
    switch (p1st->st_peer_pubkey->dns_auth_level)
    {
    case DAL_UNSIGNED:
    case DAL_NOTSEC:
	/* these seem to be the same for this purpose */
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_type   = CERT_NONE;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn));
	break;
	
    case DAL_SIGNED:
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_format = CERT_DNS_SIGNED_KEY;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn));

	if (p1st->st_peer_pubkey->dns_sig != NULL)
	{
	    strncat(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig
		, p1st->st_peer_pubkey->dns_sig
		, sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig) - strlen(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig -1));
	}
	break;

    case DAL_LOCAL:
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_format = CERT_RAW_RSA;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_raw_key.id_name
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_raw_key.id_name));
	break;
    }
}
Example #20
0
int
gssapi_get_itoken(struct ph1handle *iph1, int *lenp)
{
	struct gssapi_ph1_state *gps;
	gss_buffer_desc empty, name_token;
	gss_buffer_t itoken, rtoken, dummy;
	OM_uint32 maj_stat, min_stat;
	gss_name_t partner;

	if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
		return -1;

	gps = gssapi_get_state(iph1);

	empty.length = 0;
	empty.value = NULL;
	dummy = &empty;

	if (iph1->approval != NULL && iph1->approval->gssid != NULL) {
		plog(LLV_DEBUG, LOCATION, NULL,
		    "using provided service '%.*s'\n",
		    iph1->approval->gssid->l, iph1->approval->gssid->v);
		name_token.length = iph1->approval->gssid->l;
		name_token.value = iph1->approval->gssid->v;
		maj_stat = gss_import_name(&min_stat, &name_token,
		    GSS_C_NO_OID, &partner);
		if (GSS_ERROR(maj_stat)) {
			gssapi_error(min_stat, LOCATION, "import of %.*s\n",
			    name_token.length, name_token.value);
			return -1;
		}
	} else
		if (gssapi_get_default_name(iph1, 1, &partner) < 0)
			return -1;

	rtoken = gps->gsscnt_p == 0 ? dummy : &gps->gss_p[gps->gsscnt_p - 1];
	itoken = &gps->gss[gps->gsscnt];

	gps->gss_status = gss_init_sec_context(&min_stat, gps->gss_cred,
	    &gps->gss_context, partner, GSS_C_NO_OID,
	    GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG |
		GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG,
	    0, GSS_C_NO_CHANNEL_BINDINGS, rtoken, NULL,
	    itoken, NULL, NULL);

	if (GSS_ERROR(gps->gss_status)) {
		gssapi_error(min_stat, LOCATION, "init_sec_context\n");
		maj_stat = gss_release_name(&min_stat, &partner);
		if (GSS_ERROR(maj_stat))
			gssapi_error(min_stat, LOCATION, "release name\n");
		return -1;
	}
	maj_stat = gss_release_name(&min_stat, &partner);
	if (GSS_ERROR(maj_stat))
		gssapi_error(min_stat, LOCATION, "release name\n");

	plog(LLV_DEBUG, LOCATION, NULL, "gss_init_sec_context status %x\n",
	    gps->gss_status);

	if (lenp)
		*lenp = itoken->length;

	if (itoken->length != 0)
		gps->gsscnt++;

	return 0;
}
Example #21
0
vchar_t *
gssapi_get_id(struct ph1handle *iph1)
{
	gss_buffer_desc id_buffer;
	gss_buffer_t id = &id_buffer;
	gss_name_t defname, canon_name;
	OM_uint32 min_stat, maj_stat;
	vchar_t *vmbuf;

	if (iph1->rmconf->proposal->gssid != NULL)
		return (vdup(iph1->rmconf->proposal->gssid));

	if (gssapi_get_default_name(iph1, 0, &defname) < 0)
		return NULL;

	maj_stat = gss_canonicalize_name(&min_stat, defname, GSS_C_NO_OID,
	    &canon_name);
	if (GSS_ERROR(maj_stat)) {
		gssapi_error(min_stat, LOCATION, "canonicalize name\n");
		maj_stat = gss_release_name(&min_stat, &defname);
		if (GSS_ERROR(maj_stat))
			gssapi_error(min_stat, LOCATION,
			    "release default name\n");
		return NULL;
	}
	maj_stat = gss_release_name(&min_stat, &defname);
	if (GSS_ERROR(maj_stat))
		gssapi_error(min_stat, LOCATION, "release default name\n");

	maj_stat = gss_export_name(&min_stat, canon_name, id);
	if (GSS_ERROR(maj_stat)) {
		gssapi_error(min_stat, LOCATION, "export name\n");
		maj_stat = gss_release_name(&min_stat, &canon_name);
		if (GSS_ERROR(maj_stat))
			gssapi_error(min_stat, LOCATION,
			    "release canonical name\n");
		return NULL;
	}
	maj_stat = gss_release_name(&min_stat, &canon_name);
	if (GSS_ERROR(maj_stat))
		gssapi_error(min_stat, LOCATION, "release canonical name\n");

#if 0
	/*
	 * XXXJRT Did this debug message ever work?  This is a GSS name
	 * blob at this point.
	 */
	plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n",
	    id->length, id->value);
#endif

	if (gssapi_gss2vmbuf(id, &vmbuf) < 0) {
		plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
		maj_stat = gss_release_buffer(&min_stat, id);
		if (GSS_ERROR(maj_stat))
			gssapi_error(min_stat, LOCATION, "release id buffer\n");
		return NULL;
	}
	maj_stat = gss_release_buffer(&min_stat, id);
	if (GSS_ERROR(maj_stat))
		gssapi_error(min_stat, LOCATION, "release id buffer\n");

	return vmbuf;
}
Example #22
0
/*
 * parse a conn section
 */
static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
{
	char *conn_name = (conn->name == NULL)? "%default":conn->name;

	for ( ; kw; kw = kw->next)
	{
		bool assigned = FALSE;

		kw_token_t token = kw->entry->token;

		if (token >= KW_LEFT_FIRST && token <= KW_LEFT_LAST)
		{
			kw_end(conn, &conn->left, token - KW_LEFT_FIRST + KW_END_FIRST
				,  kw, conn_name, cfg);
			continue;
		}
		else if (token >= KW_RIGHT_FIRST && token <= KW_RIGHT_LAST)
		{
			kw_end(conn, &conn->right, token - KW_RIGHT_FIRST + KW_END_FIRST
				 , kw, conn_name, cfg);
			continue;
		}

		if (token == KW_AUTO)
		{
			token = KW_CONN_SETUP;
		}
		else if (token == KW_ALSO)
		{
			if (cfg->parse_also)
			{
				also_t *also = malloc_thing(also_t);

				also->name = clone_str(kw->value);
				also->next = conn->also;
				conn->also = also;

				DBG(DBG_CONTROL,
					DBG_log("  also=%s", kw->value)
				)
			}
			continue;
		}

		if (token < KW_CONN_FIRST || token > KW_CONN_LAST)
		{
			plog("# unsupported keyword '%s' in conn '%s'"
				, kw->entry->name, conn_name);
			cfg->err++;
			continue;
		}

		if (!assign_arg(token, KW_CONN_FIRST, kw, (char *)conn, &assigned))
		{
			plog("  bad argument value in conn '%s'", conn_name);
			cfg->err++;
			continue;
		}

		if (assigned)
			continue;

		switch (token)
		{
		case KW_TYPE:
			conn->policy &= ~(POLICY_TUNNEL | POLICY_SHUNT_MASK);
			if (streq(kw->value, "tunnel"))
			{
				conn->policy |= POLICY_TUNNEL;
			}
			else if (streq(kw->value, "beet"))
			{
				conn->policy |= POLICY_BEET;
			}
			else if (streq(kw->value, "transport_proxy"))
			{
				conn->policy |= POLICY_PROXY;
			}
			else if (streq(kw->value, "passthrough") || streq(kw->value, "pass"))
			{
				conn->policy |= POLICY_SHUNT_PASS;
			}
			else if (streq(kw->value, "drop"))
			{
				conn->policy |= POLICY_SHUNT_DROP;
			}
			else if (streq(kw->value, "reject"))
			{
				conn->policy |= POLICY_SHUNT_REJECT;
			}
			else if (strcmp(kw->value, "transport") != 0)
			{
				plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
				cfg->err++;
			}
			break;
		case KW_PFS:
			KW_POLICY_FLAG("yes", "no", POLICY_PFS)
			break;
		case KW_COMPRESS:
			KW_POLICY_FLAG("yes", "no", POLICY_COMPRESS)
			break;
		case KW_PMTUDISC:
			if (streq(kw->value, "no"))
			{
				conn->xfrm_flags |= XFRM_STATE_NOPMTUDISC;
			}
			break;
		case KW_IPSECDEV:
			conn->dev = get_ifindex(kw->value);
			if (conn->dev < 0) {
				cfg->err++;
			}
			break;
		case KW_ECN:
			if (streq(kw->value, "no"))
			{
				conn->xfrm_flags |= XFRM_STATE_NOECN;
			}
			break;
		case KW_AUTH:
			KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE)
			break;
		case KW_AUTHBY:
			conn->policy &= ~(POLICY_ID_AUTH_MASK | POLICY_ENCRYPT);

			if (!(streq(kw->value, "never") || streq(kw->value, "eap")))
			{
				char *value = kw->value;
				char *second = strchr(kw->value, '|');

				if (second != NULL)
				{
					*second = '\0';
				}

				/* also handles the cases secret|rsasig and rsasig|secret */
				for (;;)
				{
					if (streq(value, "rsa")   || streq(value, "rsasig")   ||
						streq(value, "ecdsa") || streq(value, "ecdsasig") ||
						streq(value, "pubkey"))
					{
						conn->policy |= POLICY_PUBKEY | POLICY_ENCRYPT;
					}
					else if (streq(value, "secret") || streq(value, "psk"))
					{
						conn->policy |= POLICY_PSK | POLICY_ENCRYPT;
					}
					else if (streq(value, "xauthrsasig"))
					{
						conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT;
					}
					else if (streq(value, "xauthpsk"))
					{
						conn->policy |= POLICY_XAUTH_PSK | POLICY_ENCRYPT;
					}
					else
					{
						plog("# bad policy value: %s=%s", kw->entry->name, kw->value);
						cfg->err++;
						break;
					}
					if (second == NULL)
					{
						break;
					}
					value = second;
					second = NULL; /* traverse the loop no more than twice */
				}
			}
			break;
		case KW_EAP:
		{
			char *sep;

			/* check for vendor-type format */
			sep = strchr(kw->value, '-');
			if (sep)
			{
				*(sep++) = '\0';
				conn->eap_type = atoi(kw->value);
				conn->eap_vendor = atoi(sep);
				if (conn->eap_type == 0 || conn->eap_vendor == 0)
				{
					plog("# invalid EAP type: %s=%s", kw->entry->name, kw->value);
					cfg->err++;
				}
				break;
			}
			if (streq(kw->value, "aka"))
			{
				conn->eap_type = 23;
			}
			else if (streq(kw->value, "sim"))
			{
				conn->eap_type = 18;
			}
			else if (streq(kw->value, "md5"))
			{
				conn->eap_type = 4;
			}
			else if (streq(kw->value, "gtc"))
			{
				conn->eap_type = 6;
			}
			else if (streq(kw->value, "mschapv2"))
			{
				conn->eap_type = 26;
			}
			else if (streq(kw->value, "radius"))
			{	/* pseudo-type */
				conn->eap_type = 253;
			}
			else
			{
				conn->eap_type = atoi(kw->value);
				if (conn->eap_type == 0)
				{
					plog("# unknown EAP type: %s=%s", kw->entry->name, kw->value);
					cfg->err++;
				}
			}
			break;
		}
		case KW_KEYINGTRIES:
			if (streq(kw->value, "%forever"))
			{
				conn->sa_keying_tries = 0;
			}
			else
			{
				char *endptr;

				conn->sa_keying_tries = strtoul(kw->value, &endptr, 10);
				if (*endptr != '\0')
				{
					plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
		    		cfg->err++;
				}
			}
			break;
		case KW_REKEY:
			KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY)
			break;
		case KW_REAUTH:
			KW_POLICY_FLAG("no", "yes", POLICY_DONT_REAUTH)
			break;
		case KW_MOBIKE:
			KW_POLICY_FLAG("yes", "no", POLICY_MOBIKE)
			break;
		case KW_FORCEENCAPS:
			KW_POLICY_FLAG("yes", "no", POLICY_FORCE_ENCAP)
			break;
		case KW_MODECONFIG:
			KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH)
			break;
		case KW_XAUTH:
			KW_POLICY_FLAG("server", "client", POLICY_XAUTH_SERVER)
			break;
		default:
			break;
		}
	}
Example #23
0
static int
gssapi_init(struct ph1handle *iph1)
{
	struct gssapi_ph1_state *gps;
	gss_buffer_desc id_token, cred_token;
	gss_buffer_t cred = &cred_token;
	gss_name_t princ, canon_princ;
	OM_uint32 maj_stat, min_stat;

	gps = racoon_calloc(1, sizeof (struct gssapi_ph1_state));
	if (gps == NULL) {
		plog(LLV_ERROR, LOCATION, NULL, "racoon_calloc failed\n");
		return -1;
	}
	gps->gss_context = GSS_C_NO_CONTEXT;
	gps->gss_cred = GSS_C_NO_CREDENTIAL;

	gssapi_set_state(iph1, gps);

	if (iph1->rmconf->proposal->gssid != NULL) {
		id_token.length = iph1->rmconf->proposal->gssid->l;
		id_token.value = iph1->rmconf->proposal->gssid->v;
		maj_stat = gss_import_name(&min_stat, &id_token, GSS_C_NO_OID,
		    &princ);
		if (GSS_ERROR(maj_stat)) {
			gssapi_error(min_stat, LOCATION, "import name\n");
			gssapi_free_state(iph1);
			return -1;
		}
	} else
		gssapi_get_default_name(iph1, 0, &princ);

	maj_stat = gss_canonicalize_name(&min_stat, princ, GSS_C_NO_OID,
	    &canon_princ);
	if (GSS_ERROR(maj_stat)) {
		gssapi_error(min_stat, LOCATION, "canonicalize name\n");
		maj_stat = gss_release_name(&min_stat, &princ);
		if (GSS_ERROR(maj_stat))
			gssapi_error(min_stat, LOCATION, "release princ\n");
		gssapi_free_state(iph1);
		return -1;
	}
	maj_stat = gss_release_name(&min_stat, &princ);
	if (GSS_ERROR(maj_stat))
		gssapi_error(min_stat, LOCATION, "release princ\n");

	maj_stat = gss_export_name(&min_stat, canon_princ, cred);
	if (GSS_ERROR(maj_stat)) {
		gssapi_error(min_stat, LOCATION, "export name\n");
		maj_stat = gss_release_name(&min_stat, &canon_princ);
		if (GSS_ERROR(maj_stat))
			gssapi_error(min_stat, LOCATION,
			    "release canon_princ\n");
		gssapi_free_state(iph1);
		return -1;
	}

#if 0
	/*
	 * XXXJRT Did this debug message ever work?  This is a GSS name
	 * blob at this point.
	 */
	plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n",
	    cred->length, cred->value);
#endif

	maj_stat = gss_release_buffer(&min_stat, cred);
	if (GSS_ERROR(maj_stat))
		gssapi_error(min_stat, LOCATION, "release cred buffer\n");

	maj_stat = gss_acquire_cred(&min_stat, canon_princ, GSS_C_INDEFINITE,
	    GSS_C_NO_OID_SET, GSS_C_BOTH, &gps->gss_cred, NULL, NULL);
	if (GSS_ERROR(maj_stat)) {
		gssapi_error(min_stat, LOCATION, "acquire cred\n");
		maj_stat = gss_release_name(&min_stat, &canon_princ);
		if (GSS_ERROR(maj_stat))
			gssapi_error(min_stat, LOCATION,
			    "release canon_princ\n");
		gssapi_free_state(iph1);
		return -1;
	}
	maj_stat = gss_release_name(&min_stat, &canon_princ);
	if (GSS_ERROR(maj_stat))
		gssapi_error(min_stat, LOCATION, "release canon_princ\n");

	return 0;
}
Example #24
0
int
natt_process_natd(struct ikev2_sa *ike_sa, struct ikev2payl_notify *n,
		  int use_spi_r)
{
	unsigned int type;
	uint8_t *n_data = NULL;
	rc_vchar_t *hash = NULL;
	struct sockaddr *addr = NULL;
	int ret;

	type = get_notify_type(n);
	n_data = get_notify_data(n);

	switch (type) {
	case IKEV2_NAT_DETECTION_SOURCE_IP:
		addr = ike_sa->remote;
		break;

	case IKEV2_NAT_DETECTION_DESTINATION_IP:
		addr = ike_sa->local;
		break;

	default:
		plog(PLOG_DEBUG, PLOGLOC, NULL, "invalid notify type\n");
		plog(PLOG_DEBUG, PLOGLOC, NULL, "type=%u\n", type);
		return -1;
	}

	hash = natt_create_hash(&ike_sa->index, addr, use_spi_r);
	if (hash == NULL) {
		return -1;
	}

	ret = memcmp(n_data, hash->v, hash->l);

	rc_vfree(hash);

	switch (type) {
	case IKEV2_NAT_DETECTION_SOURCE_IP:
		if (ret != 0) {
			ike_sa->peer_behind_nat = TRUE;
		} else {
			ike_sa->peer_behind_nat = FALSE;
		}
		break;

	case IKEV2_NAT_DETECTION_DESTINATION_IP:
		if (ret != 0) {
			ike_sa->behind_nat = TRUE;

			if (ike_sa->natk_timer) {
				SCHED_KILL(ike_sa->natk_timer);
			}

			ike_sa->natk_timer =
				sched_new(ikev2_natk_interval(ike_sa->rmconf),
					  natt_natk_callback, ike_sa);
			if (ike_sa->natk_timer == NULL) {
				plog(PLOG_INTERR, PLOGLOC, NULL,
				     "failed to rc_vmalloc for natk_timer\n");
				return -1;
			}
		} else {
			ike_sa->behind_nat = FALSE;
		}
		break;

	default:
		plog(PLOG_DEBUG, PLOGLOC, NULL, "invalid notify type\n");
		plog(PLOG_DEBUG, PLOGLOC, NULL, "type=%d\n", type);
		return -1;
	}

	return 0;
}
Example #25
0
static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
				   kw_list_t *kw, char *conn_name, starter_config_t *cfg)
{
	err_t ugh = NULL;
	bool assigned = FALSE;
	bool has_port_wildcard;        /* set if port is %any */

	char *name  = kw->entry->name;
	char *value = kw->value;

	if (!assign_arg(token, KW_END_FIRST, kw, (char *)end, &assigned))
		goto err;

	/* post processing of some keywords that were assigned automatically */
	switch (token)
	{
	case KW_SUBNET:
		if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0)
		||  (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0))
		{
			/* used by pluto only */
			end->has_virt = TRUE;
		}
		else
		{
			ip_subnet net;
			char *pos;
			int len = 0;

			end->has_client = TRUE;
			conn->tunnel_addr_family = ip_version(value);

			pos = strchr(value, ',');
			if (pos)
			{
				len = pos - value;
			}
			ugh = ttosubnet(value, len, ip_version(value), &net);
			if (ugh != NULL)
			{
				plog("# bad subnet: %s=%s [%s]", name, value, ugh);
				goto err;
			}
		}
		break;
	case KW_SOURCEIP:
		if (end->has_natip)
		{
			plog("# natip and sourceip cannot be defined at the same time");
			goto err;
		}
		if (value[0] == '%')
		{
			if (streq(value, "%modeconfig") || streq(value, "%modecfg") ||
				streq(value, "%config") || streq(value, "%cfg"))
			{
				/* request ip via config payload */
				free(end->sourceip);
				end->sourceip = NULL;
				end->sourceip_mask = 1;
			}
			else
			{	/* %poolname, strip %, serve ip requests */
				free(end->sourceip);
				end->sourceip = clone_str(value+1);
				end->sourceip_mask = 0;
			}
			end->modecfg = TRUE;
		}
		else
		{
			char *pos;
			ip_address addr;
			ip_subnet net;

			conn->tunnel_addr_family = ip_version(value);
			pos = strchr(value, '/');

			if (pos)
			{	/* CIDR notation, address pool */
				ugh = ttosubnet(value, 0, conn->tunnel_addr_family, &net);
				if (ugh != NULL)
				{
					plog("# bad subnet: %s=%s [%s]", name, value, ugh);
					goto err;
				 }
				*pos = '\0';
				free(end->sourceip);
				end->sourceip = clone_str(value);
				end->sourceip_mask = atoi(pos + 1);
			}
			else
			{	/* fixed srcip */
				ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr);
				if (ugh != NULL)
				{
					plog("# bad addr: %s=%s [%s]", name, value, ugh);
					goto err;
				}
				end->sourceip_mask = (conn->tunnel_addr_family == AF_INET) ?
									  32 : 128;
			}
		}
		conn->policy |= POLICY_TUNNEL;
		break;
	case KW_SENDCERT:
		if (end->sendcert == CERT_YES_SEND)
		{
			end->sendcert = CERT_ALWAYS_SEND;
		}
		else if (end->sendcert == CERT_NO_SEND)
		{
			end->sendcert = CERT_NEVER_SEND;
		}
		break;
	default:
		break;
	}

	if (assigned)
		return;

	/* individual processing of keywords that were not assigned automatically */
	switch (token)
	{
	case KW_HOST:
		if (streq(value, "%defaultroute"))
		{
			if (cfg->defaultroute.defined)
			{
				end->addr    = cfg->defaultroute.addr;
				end->nexthop = cfg->defaultroute.nexthop;
			}
			else if (!cfg->defaultroute.supported)
			{
				plog("%%defaultroute not supported, fallback to %%any");
			}
			else
			{
				plog("# default route not known: %s=%s", name, value);
				goto err;
			}
		}
		else if (streq(value, "%any") || streq(value, "%any4"))
		{
			anyaddr(conn->addr_family, &end->addr);
		}
		else if (streq(value, "%any6"))
		{
			conn->addr_family = AF_INET6;
			anyaddr(conn->addr_family, &end->addr);
		}
		else if (streq(value, "%group"))
		{
			ip_address any;

			conn->policy |= POLICY_GROUP | POLICY_TUNNEL;
			anyaddr(conn->addr_family, &end->addr);
			anyaddr(conn->tunnel_addr_family, &any);
			end->has_client = TRUE;
		}
		else
		{
			/* check for allow_any prefix */
			if (value[0] == '%')
			{
				end->allow_any = TRUE;
				value++;
			}
			conn->addr_family = ip_version(value);
			ugh = ttoaddr(value, 0, conn->addr_family, &end->addr);
			if (ugh != NULL)
			{
				plog("# bad addr: %s=%s [%s]", name, value, ugh);
				if (streq(ugh, "does not look numeric and name lookup failed"))
				{
					end->dns_failed = TRUE;
					anyaddr(conn->addr_family, &end->addr);
				}
				else
				{
					goto err;
				}
			}
		}
		break;
	case KW_NEXTHOP:
		if (streq(value, "%defaultroute"))
		{
			if (cfg->defaultroute.defined)
			{
				end->nexthop = cfg->defaultroute.nexthop;
			}
			else
			{
				plog("# default route not known: %s=%s", name, value);
				goto err;
			}
		}
		else if (streq(value, "%direct"))
		{
			ugh = anyaddr(conn->addr_family, &end->nexthop);
		}
		else
		{
			conn->addr_family = ip_version(value);
			ugh = ttoaddr(value, 0, conn->addr_family, &end->nexthop);
		}
		if (ugh != NULL)
		{
			plog("# bad addr: %s=%s [%s]", name, value, ugh);
			goto err;
		}
		break;
	case KW_SUBNETWITHIN:
	{
		ip_subnet net;

		end->has_client = TRUE;
		end->has_client_wildcard = TRUE;
		conn->tunnel_addr_family = ip_version(value);

		ugh = ttosubnet(value, 0, ip_version(value), &net);
		if (ugh != NULL)
		{
			plog("# bad subnet: %s=%s [%s]", name, value, ugh);
			goto err;
		}
		end->subnet = clone_str(value);
		break;
	}
	case KW_PROTOPORT:
		ugh = ttoprotoport(value, 0, &end->protocol, &end->port, &has_port_wildcard);
		end->has_port_wildcard = has_port_wildcard;
		break;
	case KW_NATIP:
		if (end->sourceip)
		{
			plog("# natip and sourceip cannot be defined at the same time");
			goto err;
		}
		if (streq(value, "%defaultroute"))
		{
			char buf[64];

			if (cfg->defaultroute.defined)
			{
				addrtot(&cfg->defaultroute.addr, 0, buf, sizeof(buf));
				end->sourceip = clone_str(buf);
			}
			else
			{
				plog("# default route not known: %s=%s", name, value);
				goto err;
			}
		}
		else
		{
			ip_address addr;

			conn->tunnel_addr_family = ip_version(value);
			ugh = ttoaddr(value, 0, conn->tunnel_addr_family, &addr);
			if (ugh != NULL)
			{
				plog("# bad addr: %s=%s [%s]", name, value, ugh);
				goto err;
			}
			end->sourceip = clone_str(value);
		}
		end->has_natip = TRUE;
		conn->policy |= POLICY_TUNNEL;
		break;
	default:
		break;
	}
	return;

err:
	plog("  bad argument value in conn '%s'", conn_name);
	cfg->err++;
}
Example #26
0
/*
 * Try to locate a key using NIS+.
 */
int
nisplus_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
{
  nis_result *result;
  int error = 0;
  struct nisplus_search_callback_data data;
  nis_name index;
  char *org;		/* if map does not have ".org_dir" then append it */
  size_t l;

  org = strstr(map, NISPLUS_ORGDIR);
  if (org == NULL)
    org = NISPLUS_ORGDIR;
  else
    org = "";

  /* make some room for the NIS index */
  l = sizeof('[')		/* for opening selection criteria */
    + sizeof(NISPLUS_KEY)
    + strlen(key)
    + sizeof(']')		/* for closing selection criteria */
    + sizeof(',')		/* + 1 for , separator */
    + strlen(map)
    + sizeof(NISPLUS_ORGDIR);
  index = xmalloc(l);
  if (index == NULL) {
    plog(XLOG_ERROR,
	 "Unable to create index %s: %s",
	 map,
	 strerror(ENOMEM));
    return ENOMEM;
  }
  xsnprintf(index, l, "[%s%s],%s%s", NISPLUS_KEY, key, map, org);

  data.key = key;
  data.value = NULL;

  dlog("NISplus search for %s", index);

  result = nis_list(index,
		    EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH,
		    (int (*)()) nisplus_search_callback,
		    &data);

  /* free off the NIS index */
  XFREE(index);

  if (result == NULL) {
    plog(XLOG_ERROR, "nisplus_search: %s: %s", map, strerror(ENOMEM));
    return ENOMEM;
  }

  /*
   * Do something interesting with the return code
   */
  switch (result->status) {
  case NIS_SUCCESS:
  case NIS_CBRESULTS:

    if (data.value == NULL) {
      nis_object *value = result->objects.objects_val;
      dlog("NISplus search found <nothing>");
      dlog("NISplus search for %s: %s(%d)",
	   map, nis_sperrno(result->status), result->status);

      if (value != NULL)
	data.value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1));
    }

    if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX)) {
      *val = sun_entry2amd(key, data.value);
      XFREE(data.value);	/* strnsave malloc'ed it above */
    } else
      *val = data.value;

    if (*val) {
      error = 0;
      dlog("NISplus search found %s", *val);
    } else {
      error = ENOENT;
      dlog("NISplus search found nothing");
    }

    *tp = 0;
    break;

  case NIS_NOSUCHNAME:
    dlog("NISplus search returned %d", result->status);
    error = ENOENT;
    break;

  default:
    plog(XLOG_ERROR, "nisplus_search: %s: %s", map, nis_sperrno(result->status));
    error = EIO;
    break;
  }
  nis_freeresult(result);

  return error;
}
Example #27
0
/*
 * Return the home directory pathname for the user with uid "userid".
 */
char *
homedir(int userid, int groupid)
{
  static char linkval[MAXPATHLEN + 1];
  static struct timeval tp;
  uid2home_t *found;
  char *homename;
  struct stat homestat;
  int old_groupid, old_userid;

  clock_valid = 0;		/* invalidate logging clock */

  if ((found = plt_search(userid)) == (uid2home_t *) NULL) {
    return alt_spooldir;	/* use alt spool for unknown uid */
  }
  homename = found->home;

  if (homename[0] != '/' || homename[1] == '\0') {
    found->last_status = 1;
    return alt_spooldir;	/* use alt spool for / or rel. home */
  }
  if ((int) userid == 0)	/* force all uid 0 to use root's home */
    sprintf(linkval, "%s/%s", root_home, home_subdir);
  else
    sprintf(linkval, "%s/%s", homename, home_subdir);

  if (noverify) {
    found->last_status = 0;
    return linkval;
  }

  /*
   * To optimize hlfsd, we don't actually check the validity of the
   * symlink if it has been checked in the last N seconds.  It is
   * very likely that the link, machine, and filesystem are still
   * valid, as long as N is small.  But if N is large, that may not be
   * true.  That's why the default N is 5 minutes, but we allow the
   * user to override this value via a command line option.  Note that
   * we do not update the last_access_time each time it is accessed,
   * but only once every N seconds.
   */
  if (gettimeofday(&tp, (struct timezone *) NULL) < 0) {
    tp.tv_sec = 0;
  } else {
    if ((tp.tv_sec - found->last_access_time) < cache_interval) {
      if (found->last_status == 0) {
	return linkval;
      } else {
	return alt_spooldir;
      }
    } else {
      found->last_access_time = tp.tv_sec;
    }
  }

#ifdef DEBUG
  /*
   * only run this forking code if asked for -D fork
   * or if did not ask for -D nofork
   */
  amuDebug(D_FORK) {
#endif /* DEBUG */
    /* fork child to process request if none in progress */
    if (found->child && kill(found->child, 0))
      found->child = 0;

    if (found->child)
      delay(found, 5);		/* wait a bit if in progress */
    if (found->child) {		/* better safe than sorry - maybe */
      found->last_status = 1;
      return alt_spooldir;
    }
    if ((found->child = fork()) < 0) {
      found->last_status = 1;
      return alt_spooldir;
    }
    if (found->child) {		/* PARENT */
#ifdef DEBUG
      if (lastchild)
	plog(XLOG_INFO, "cache spill uid = %ld, pid = %ld, home = %s",
	     (long) lastchild->uid, (long) lastchild->child,
	     lastchild->home);
#endif /* DEBUG */
      lastchild = found;
      return (char *) NULL;	/* return NULL to parent, so it can continue */
    }
#ifdef DEBUG
  }				/* end of Debug(D_FORK) */
#endif /* DEBUG */

  /*
   * CHILD: (or parent if -D nofork)
   *
   * Check and create dir if needed.
   * Check disk space and/or quotas too.
   *
   * We don't need to set the _last_status field of found after the fork
   * in the child, b/c that information would be later determined in
   * nfsproc_readlink_2() and the correct exit status would be returned
   * to the parent upon SIGCHLD in interlock().
   *
   */
  am_set_mypid();		/* for logging routines */
  if ((old_groupid = setgid(groupid)) < 0) {
    plog(XLOG_WARNING, "could not setgid to %d: %m", groupid);
    return linkval;
  }
  if ((old_userid = seteuid(userid)) < 0) {
    plog(XLOG_WARNING, "could not seteuid to %d: %m", userid);
    setgid(old_groupid);
    return linkval;
  }
  if (hlfsd_stat(linkval, &homestat) < 0) {
    if (errno == ENOENT) {	/* make the spool dir if possible */
      /* don't use recursive mkdirs here */
      if (mkdir(linkval, PERS_SPOOLMODE) < 0) {
	seteuid(old_userid);
	setgid(old_groupid);
	plog(XLOG_WARNING, "can't make directory %s: %m", linkval);
	return alt_spooldir;
      }
      /* fall through to testing the disk space / quota */
    } else {			/* the home dir itself must not exist then */
      seteuid(old_userid);
      setgid(old_groupid);
      plog(XLOG_WARNING, "bad link to %s: %m", linkval);
      return alt_spooldir;
    }
  }

  /*
   * If gets here, then either the spool dir in the home dir exists,
   * or it was just created.  In either case, we now need to
   * test if we can create a small file and write at least one
   * byte into it.  This will test that we have both enough inodes
   * and disk blocks to spare, or they fall within the user's quotas too.
   * We are still seteuid to the user at this point.
   */
  if (hlfsd_diskspace(linkval) < 0) {
    seteuid(old_userid);
    setgid(old_groupid);
    plog(XLOG_WARNING, "no more space in %s: %m", linkval);
    return alt_spooldir;
  } else {
    seteuid(old_userid);
    setgid(old_groupid);
    return linkval;
  }
}
Example #28
0
/* perform record reading/parsing of individual passwd database records */
static struct passwd *
hlfsd_getpwent(void)
{
  char buf[256], *cp;

  /* check if to perform standard unix function */
  if (!passwdfile) {
    return getpwent();
  }

  clock_valid = 0;		/* invalidate logging clock */

  /* return here to read another entry */
readent:

  /* return NULL if reached end of file */
  if (feof(passwd_fp))
    return NULL;

  pw_name[0] = pw_dir[0] = '\0';

  /* read records */
  buf[0] = '\0';
  fgets(buf, 256, passwd_fp);
  passwd_line++;
  if (!buf || buf[0] == '\0')
    goto readent;

  /* read user name */
  cp = strtok(buf, ":");
  if (!cp || cp[0] == '\0') {
    plog(XLOG_ERROR, "no user name on line %d of %s", passwd_line, passwdfile);
    goto readent;
  }
  strcpy(pw_name, cp);		/* will show up in passwd_ent.pw_name */

  /* skip passwd */
  strtok(NULL, ":");

  /* read uid */
  cp = strtok(NULL, ":");
  if (!cp || cp[0] == '\0') {
    plog(XLOG_ERROR, "no uid on line %d of %s", passwd_line, passwdfile);
    goto readent;
  }
  passwd_ent.pw_uid = atoi(cp);

  /* skip gid and gcos */
  strtok(NULL, ":");
  strtok(NULL, ":");

  /* read home dir */
  cp = strtok(NULL, ":");
  if (!cp || cp[0] == '\0') {
    plog(XLOG_ERROR, "no home dir on line %d of %s", passwd_line,  passwdfile);
    goto readent;
  }
  strcpy(pw_dir, cp);	/* will show up in passwd_ent.pw_dir */

  /* the rest of the fields are unimportant and not being considered */

  plog(XLOG_USER, "hlfsd_getpwent: name=%s, uid=%ld, dir=%s",
       passwd_ent.pw_name, (long) passwd_ent.pw_uid, passwd_ent.pw_dir);

  return &passwd_ent;
}
Example #29
0
int
autofs_mount_fs(am_node *mp, mntfs *mf)
{
  char *target, *target2 = NULL;
  int err = 0;

  if (mf->mf_flags & MFF_ON_AUTOFS) {
    if ((err = mkdir(mp->am_path, 0555)))
      return errno;
  }

  /*
   * For sublinks, we could end up here with an already mounted f/s.
   * Don't do anything in that case.
   */
  if (!(mf->mf_flags & MFF_MOUNTED))
    err = mf->mf_ops->mount_fs(mp, mf);

  if (err) {
    if (mf->mf_flags & MFF_ON_AUTOFS)
      rmdir(mp->am_path);
    return err;
  }

  if (mf->mf_flags & MFF_ON_AUTOFS)
    /* Nothing else to do */
    return 0;

  if (mp->am_link)
    target = mp->am_link;
  else
    target = mf->mf_fo->opt_fs;

#ifdef MNT2_GEN_OPT_BIND
  if (bind_works && gopt.flags & CFM_AUTOFS_USE_LOFS) {
    struct stat buf;

    /*
     * HACK ALERT!
     *
     * Since the bind mount mechanism doesn't allow mountpoint crossing,
     * we _must_ use symlinks for the host mount case. Otherwise we end up
     * with a bunch of empty mountpoints...
     */
    if (mf->mf_ops == &amfs_host_ops)
      goto use_symlink;

    if (target[0] != '/')
      target2 = str3cat(NULL, mp->am_parent->am_path, "/", target);
    else
      target2 = strdup(target);

    /*
     * We need to stat() the destination, because the bind mount does not
     * follow symlinks and/or allow for non-existent destinations.
     * We fall back to symlinks if there are problems.
     *
     * We also need to temporarily change pgrp, otherwise our stat() won't
     * trigger whatever cascading mounts are needed.
     *
     * WARNING: we will deadlock if this function is called from the master
     * amd process and it happens to trigger another auto mount. Therefore,
     * this function should be called only from a child amd process, or
     * at the very least it should not be called from the parent unless we
     * know for sure that it won't cause a recursive mount. We refuse to
     * cause the recursive mount anyway if called from the parent amd.
     */
    if (!foreground) {
      pid_t pgrp = getpgrp();
      setpgrp();
      err = stat(target2, &buf);
      if ((err = setpgid(0, pgrp))) {
	plog(XLOG_ERROR, "autofs: cannot restore pgrp: %s", strerror(errno));
	plog(XLOG_ERROR, "autofs: aborting the mount");
	goto out;
      }
      if (err)
	goto use_symlink;
    }
    if ((err = lstat(target2, &buf)))
      goto use_symlink;
    if (S_ISLNK(buf.st_mode))
      goto use_symlink;

    plog(XLOG_INFO, "autofs: bind-mounting %s -> %s", mp->am_path, target2);
    mkdir(mp->am_path, 0555);
    err = mount_lofs(mp->am_path, target2, mf->mf_mopts, 1);
    if (err) {
      rmdir(mp->am_path);
      plog(XLOG_INFO, "autofs: bind-mounting %s -> %s failed", mp->am_path, target2);
      goto use_symlink;
    }
    goto out;
  }
#endif /* MNT2_GEN_OPT_BIND */
 use_symlink:
  plog(XLOG_INFO, "autofs: symlinking %s -> %s", mp->am_path, target);
  err = symlink(target, mp->am_path);

 out:
  if (target2)
    XFREE(target2);

  if (err)
    return errno;
  return 0;
}
Example #30
0
/*
 * Handle an amd restart.
 *
 * Scan through the mount list finding all "interesting" mount points.
 * Next hack up partial data structures and add the mounted file
 * system to the list of known filesystems.  This will leave a
 * dangling reference to that filesystems, so when the filesystem is
 * finally inherited, an extra "free" must be done on it.
 *
 * This module relies on internal details of other components.  If
 * you change something else make *sure* restart() still works.
 */
void
restart(void)
{
  /*
   * Read the existing mount table
   */
  mntlist *ml, *mlp;

  /*
   * For each entry, find nfs, ufs or auto mounts
   * and create a partial am_node to represent it.
   */
  for (mlp = ml = read_mtab("restart", mnttab_file_name);
       mlp;
       mlp = mlp->mnext) {
    mntent_t *me = mlp->mnt;
    am_ops *fs_ops = 0;
    if (STREQ(me->mnt_type, MNTTAB_TYPE_UFS)) {
      /*
       * UFS entry
       */
      fs_ops = &ufs_ops;
    } else if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS)) {
      /*
       * NFS entry, or possibly an Amd entry...
       * The mnt_fsname for daemon mount points is
       * 	host:(pidXXX)
       * or (seen on Solaris)
       *        host:daemon(pidXXX)
       */
      char *colon = strchr(me->mnt_fsname, ':');

      if (colon && strstr(colon, "(pid")) {
	plog(XLOG_WARNING, "%s is an existing automount point", me->mnt_dir);
	fs_ops = &amfs_link_ops;
      } else {
	fs_ops = &nfs_ops;
      }
#ifdef MNTTAB_TYPE_NFS3
    } else if (STREQ(me->mnt_type, MNTTAB_TYPE_NFS3)) {
      fs_ops = &nfs_ops;
#endif /* MNTTAB_TYPE_NFS3 */
#ifdef MNTTAB_TYPE_LOFS
    } else if (STREQ(me->mnt_type, MNTTAB_TYPE_LOFS)) {
      fs_ops = &lofs_ops;
#endif /* MNTTAB_TYPE_LOFS */
#ifdef MNTTAB_TYPE_CDFS
    } else if (STREQ(me->mnt_type, MNTTAB_TYPE_CDFS)) {
      fs_ops = &cdfs_ops;
#endif /* MNTTAB_TYPE_CDFS */
#ifdef MNTTAB_TYPE_PCFS
    } else if (STREQ(me->mnt_type, MNTTAB_TYPE_PCFS)) {
      fs_ops = &pcfs_ops;
#endif /* MNTTAB_TYPE_PCFS */
#ifdef MNTTAB_TYPE_MFS
    } else if (STREQ(me->mnt_type, MNTTAB_TYPE_MFS)) {
      /*
       * MFS entry.  Fake with a symlink.
       */
      fs_ops = &amfs_link_ops;
#endif /* MNTTAB_TYPE_MFS */
    } else {
      /*
       * Catch everything else with symlinks to
       * avoid recursive mounts.  This is debatable...
       */
      fs_ops = &amfs_link_ops;
    }

    /*
     * If we found something to do
     */
    if (fs_ops) {
      mntfs *mf;
      am_opts mo;
      char *cp;
      cp = strchr(me->mnt_fsname, ':');

      /*
       * Partially fake up an opts structure
       */
      memset(&mo, 0, sizeof(mo));
      mo.opt_rhost = 0;
      mo.opt_rfs = 0;
      if (cp) {
	*cp = '\0';
	mo.opt_rhost = strdup(me->mnt_fsname);
	mo.opt_rfs = strdup(cp + 1);
	*cp = ':';
      } else if (fs_ops->ffserver == find_nfs_srvr) {
	/*
	 * Prototype 4.4 BSD used to end up here -
	 * might as well keep the workaround for now
	 */
	plog(XLOG_WARNING, "NFS server entry assumed to be %s:/", me->mnt_fsname);
	mo.opt_rhost = strdup(me->mnt_fsname);
	mo.opt_rfs = strdup("/");
	me->mnt_fsname = str3cat(me->mnt_fsname, mo.opt_rhost, ":", "/");
      }
      mo.opt_fs = me->mnt_dir;
      mo.opt_opts = me->mnt_opts;

      /*
       * Make a new mounted filesystem
       */
      mf = find_mntfs(fs_ops, &mo, me->mnt_dir,
		      me->mnt_fsname, "", me->mnt_opts, "");
      if (mf->mf_refc == 1) {
	mf->mf_flags |= MFF_RESTART | MFF_MOUNTED;
	mf->mf_error = 0;	/* Already mounted correctly */
	mf->mf_fo = 0;
	/*
	 * If the restarted type is a link then
	 * don't time out.
	 */
	if (fs_ops == &amfs_link_ops || fs_ops == &ufs_ops)
	  mf->mf_flags |= MFF_RSTKEEP;
	if (fs_ops->fs_init) {
	  /*
	   * Don't care whether this worked since
	   * it is checked again when the fs is
	   * inherited.
	   */
	  (void) (*fs_ops->fs_init) (mf);
	}
	plog(XLOG_INFO, "%s restarted fstype %s on %s",
	     me->mnt_fsname, fs_ops->fs_type, me->mnt_dir);
      } else {
	/* Something strange happened - two mounts at the same place! */
	free_mntfs(mf);
      }
      /*
       * Clean up mo
       */
      if (mo.opt_rhost)
	XFREE(mo.opt_rhost);
      if (mo.opt_rfs)
	XFREE(mo.opt_rfs);
    }
  }

  /*
   * Free the mount list
   */
  free_mntlist(ml);
}