// NewFDBBackend constructs a FoundationDB backend storing keys in the
// top-level directory designated by path
161571
func NewFDBBackend(conf map[string]string, logger log.Logger) (physical.Backend, error) {
	// Get the top-level directory name
	path, ok := conf["path"]
	if !ok {
		path = "vault"
	}
	logger.Debug("config path set", "path", path)

	dirPath := strings.Split(strings.Trim(path, "/"), "/")

	// TLS support
	tlsCertFile, hasCertFile := conf["tls_cert_file"]
	tlsKeyFile, hasKeyFile := conf["tls_key_file"]
	tlsCAFile, hasCAFile := conf["tls_ca_file"]

	tlsEnabled := hasCertFile && hasKeyFile && hasCAFile

	if (hasCertFile || hasKeyFile || hasCAFile) && !tlsEnabled {
		return nil, fmt.Errorf("FoundationDB TLS requires all 3 of tls_cert_file, tls_key_file, and tls_ca_file")
	}

	tlsVerifyPeers, ok := conf["tls_verify_peers"]
	if !ok && tlsEnabled {
		return nil, fmt.Errorf("Required option tls_verify_peers not set in configuration")
	}

	// FoundationDB API version
	fdbApiVersionStr, ok := conf["api_version"]
	if !ok {
		return nil, fmt.Errorf("FoundationDB API version not specified")
	}

	fdbApiVersionInt, err := strconv.Atoi(fdbApiVersionStr)
	if err != nil {
		return nil, errwrap.Wrapf("failed to parse fdb_api_version parameter: {{err}}", err)
	}

	// Check requested FDB API version against minimum required API version
	if fdbApiVersionInt < minAPIVersion {
		return nil, fmt.Errorf("Configured FoundationDB API version lower than minimum required version: %d < %d", fdbApiVersionInt, minAPIVersion)
	}

	logger.Debug("FoundationDB API version set", "fdb_api_version", fdbApiVersionInt)

	// FoundationDB cluster file
	fdbClusterFile, ok := conf["cluster_file"]
	if !ok {
		return nil, fmt.Errorf("FoundationDB cluster file not specified")
	}

	haEnabled := false
	haEnabledStr, ok := conf["ha_enabled"]
	if ok {
		haEnabled, err = strconv.ParseBool(haEnabledStr)
		if err != nil {
			return nil, errwrap.Wrapf("failed to parse ha_enabled parameter: {{err}}", err)
		}
	}

	instanceUUID, err := uuid.GenerateUUID()
	if err != nil {
		return nil, errwrap.Wrapf("could not generate instance UUID: {{err}}", err)
	}
	logger.Debug("Instance UUID", "uuid", instanceUUID)

	if err := fdb.APIVersion(fdbApiVersionInt); err != nil {
		return nil, errwrap.Wrapf("failed to set FDB API version: {{err}}", err)
	}

	if tlsEnabled {
		opts := fdb.Options()

		tlsPassword, ok := conf["tls_password"]
		if ok {
			err := opts.SetTLSPassword(tlsPassword)
			if err != nil {
				return nil, errwrap.Wrapf("failed to set TLS password: {{err}}", err)
			}
		}

		err := opts.SetTLSCaPath(tlsCAFile)
		if err != nil {
			return nil, errwrap.Wrapf("failed to set TLS CA bundle path: {{err}}", err)
		}

		err = opts.SetTLSCertPath(tlsCertFile)
		if err != nil {
			return nil, errwrap.Wrapf("failed to set TLS certificate path: {{err}}", err)
		}

		err = opts.SetTLSKeyPath(tlsKeyFile)
		if err != nil {
			return nil, errwrap.Wrapf("failed to set TLS key path: {{err}}", err)
		}

		err = opts.SetTLSVerifyPeers([]byte(tlsVerifyPeers))
		if err != nil {
			return nil, errwrap.Wrapf("failed to set TLS peer verification criteria: {{err}}", err)
		}
	}

	db, err := fdb.Open(fdbClusterFile, []byte("DB"))
	if err != nil {
		return nil, errwrap.Wrapf(fmt.Sprintf("failed to open database with cluster file '%s': {{err}}", fdbClusterFile), err)
	}

	topDir, err := directory.CreateOrOpen(db, dirPath, nil)
	if err != nil {
		return nil, errwrap.Wrapf(fmt.Sprintf("failed to create/open top-level directory '%s': {{err}}", path), err)
	}

	// Setup the backend
	f := &FDBBackend{
		logger:        logger,
		haEnabled:     haEnabled,
		db:            db,
		metaKeysSpace: topDir.Sub(metaKeysNamespace),
		dataSpace:     topDir.Sub(dataNamespace),
		lockSpace:     topDir.Sub(lockNamespace),
		instanceUUID:  instanceUUID,
	}
	return f, nil
}
462586
func NewBackend(delegate audit.Backend, config BatchConfig) audit.Backend {
	var throttle flowcontrol.RateLimiter
	if config.ThrottleEnable {
		throttle = flowcontrol.NewTokenBucketRateLimiter(config.ThrottleQPS, config.ThrottleBurst)
	}
	return &bufferedBackend{
		delegateBackend: delegate,
		buffer:          make(chan *auditinternal.Event, config.BufferSize),
		maxBatchSize:    config.MaxBatchSize,
		maxBatchWait:    config.MaxBatchWait,
		asyncDelegate:   config.AsyncDelegate,
		shutdownCh:      make(chan struct{}),
		wg:              sync.WaitGroup{},
		throttle:        throttle,
	}
}
556765
func newEtcd3Backend(conf map[string]string, logger log.Logger) (physical.Backend, error) {
	// Get the etcd path form the configuration.
	path, ok := conf["path"]
	if !ok {
		path = "/vault"
	}

	// Ensure path is prefixed.
	if !strings.HasPrefix(path, "/") {
		path = "/" + path
	}

	endpoints, err := getEtcdEndpoints(conf)
	if err != nil {
		return nil, err
	}

	cfg := clientv3.Config{
		Endpoints: endpoints,
	}

	haEnabled := os.Getenv("ETCD_HA_ENABLED")
	if haEnabled == "" {
		haEnabled = conf["ha_enabled"]
	}
	if haEnabled == "" {
		haEnabled = "false"
	}
	haEnabledBool, err := strconv.ParseBool(haEnabled)
	if err != nil {
		return nil, fmt.Errorf("value [%v] of 'ha_enabled' could not be understood", haEnabled)
	}

	cert, hasCert := conf["tls_cert_file"]
	key, hasKey := conf["tls_key_file"]
	ca, hasCa := conf["tls_ca_file"]
	if (hasCert && hasKey) || hasCa {
		tls := transport.TLSInfo{
			TrustedCAFile: ca,
			CertFile:      cert,
			KeyFile:       key,
		}

		tlscfg, err := tls.ClientConfig()
		if err != nil {
			return nil, err
		}
		cfg.TLS = tlscfg
	}

	// Set credentials.
	username := os.Getenv("ETCD_USERNAME")
	if username == "" {
		username, _ = conf["username"]
	}

	password := os.Getenv("ETCD_PASSWORD")
	if password == "" {
		password, _ = conf["password"]
	}

	if username != "" && password != "" {
		cfg.Username = username
		cfg.Password = password
	}

	if maxReceive, ok := conf["max_receive_size"]; ok {
		// grpc converts this to uint32 internally, so parse as that to avoid passing invalid values
		val, err := strconv.ParseUint(maxReceive, 10, 32)
		if err != nil {
			return nil, errwrap.Wrapf(fmt.Sprintf("value of 'max_receive_size' (%v) could not be understood: {{err}}", maxReceive), err)
		}
		cfg.MaxCallRecvMsgSize = int(val)
	}

	etcd, err := clientv3.New(cfg)
	if err != nil {
		return nil, err
	}

	sReqTimeout := conf["request_timeout"]
	if sReqTimeout == "" {
		// etcd3 default request timeout is set to 5s. It should be long enough
		// for most cases, even with internal retry.
		sReqTimeout = "5s"
	}
	reqTimeout, err := parseutil.ParseDurationSecond(sReqTimeout)
	if err != nil {
		return nil, errwrap.Wrapf(fmt.Sprintf("value [%v] of 'request_timeout' could not be understood: {{err}}", sReqTimeout), err)
	}

	ssync, ok := conf["sync"]
	if !ok {
		ssync = "true"
	}
	sync, err := strconv.ParseBool(ssync)
	if err != nil {
		return nil, errwrap.Wrapf(fmt.Sprintf("value of 'sync' (%v) could not be understood: {{err}}", ssync), err)
	}

	if sync {
		ctx, cancel := context.WithTimeout(context.Background(), reqTimeout)
		err := etcd.Sync(ctx)
		cancel()
		if err != nil {
			return nil, err
		}
	}

	sLock := conf["lock_timeout"]
	if sLock == "" {
		// etcd3 default lease duration is 60s. set to 15s for faster recovery.
		sLock = "15s"
	}
	lock, err := parseutil.ParseDurationSecond(sLock)
	if err != nil {
		return nil, errwrap.Wrapf(fmt.Sprintf("value [%v] of 'lock_timeout' could not be understood: {{err}}", sLock), err)
	}

	return &EtcdBackend{
		path:           path,
		etcd:           etcd,
		permitPool:     physical.NewPermitPool(physical.DefaultParallelOperations),
		logger:         logger,
		haEnabled:      haEnabledBool,
		lockTimeout:    lock,
		requestTimeout: reqTimeout,
	}, nil
}
31431
func (daemon *Daemon) BuilderBackend() builder.Backend {
	return struct {
		*Daemon
		*images.ImageService
	}{daemon, daemon.imageService}
}
448349
func NewUserBackend(b *APIBackend) *UserBackend {
	return &UserBackend{
		Logger:                  b.Logger.With(zap.String("handler", "user")),
		UserService:             b.UserService,
		UserOperationLogService: b.UserOperationLogService,
		PasswordsService:        b.PasswordsService,
	}
}
582117
func ConfigFromBackend(coreBackend ...core.ConfigBackend) core.CryptoSuiteConfig {
	return &Config{backend: lookup.New(coreBackend...)}
}
361233
func NewDBPathsFromData(paths []string, target_sizes []uint64) []*DBPath {
	dbpaths := make([]*DBPath, len(paths))
	for i, path := range paths {
		targetSize := target_sizes[i]
		dbpaths[i] = NewDBPath(path, targetSize)
	}

	return dbpaths
}
186137
func NewHTTPBackend(id string, s HTTPBackendSettings) (*Backend, error) {
	if _, err := s.TransportSettings(); err != nil {
		return nil, err
	}
	return &Backend{
		Id:       id,
		Type:     HTTP,
		Settings: s,
	}, nil
}
714743
func (m *Module) GetBackend(dbname string) (backend, error) {
	ds, ok := m.config.Datasources[dbname]
	if !ok {
		return nil, fmt.Errorf("migrate: %q not configured", dbname)
	}

	migrations, err := m.getMigrationSource()
	if err != nil {
		return nil, err
	}

	// special case for parallelizing tests: add a suffix to the dbname
	if dbname == "test" {
		u, err := url.Parse(ds.DSN)
		if err != nil {
			return nil, err
		}
		database := strings.Trim(u.Path, "/")
		if m.suffixForTest == "" {
			m.suffixForTest = randomToken()
		}
		u.Path = database + "_" + m.suffixForTest
		ds.DSN = u.String()
	}
	switch ds.Driver {
	case "postgres":
		return &postgresBackend{ds, migrations}, nil
	case "mysql":
		return &mysqlBackend{ds, migrations}, nil
	}
	return nil, fmt.Errorf("migrate: unsupported driver %s", ds.Driver)
}
448557
func devServerBackend() backend.B {
	pwd := os.Getenv("PWD") // os.Getwd works funny with symlinks, use PWD
	candidates := []string{
		filepath.Join(pwd, devCfgDir),
		filepath.Join(filepath.Dir(pwd), devCfgDir),
	}
	for _, dir := range candidates {
		if _, err := os.Stat(dir); err == nil {
			fs, err := filesystem.New(dir)
			if err != nil {
				return erroring.New(err)
			}
			return &client.Backend{&testconfig.Provider{
				Base: fs,
			}}
		}
	}
	return erroring.New(fmt.Errorf("luci-config: could not find local configs in any of %s", candidates))
}
1084587
func NewLeveldbAuthBackend(filepath string) (b LeveldbAuthBackend, e error) {
	b.filepath = filepath
	if _, err := os.Stat(b.filepath); err == nil {
		db, err := leveldb.OpenFile(b.filepath, nil)
		defer db.Close()
		if err != nil {
			return b, fmt.Errorf("leveldbauthbackend: %v", err.Error())
		}
		data, err := db.Get([]byte("httpauth::userdata"), nil)
		err = json.Unmarshal(data, &b.users)
		if err != nil {
			b.users = make(map[string]UserData)
		}
	} else {
		return b, ErrMissingLeveldbBackend
	}
	if b.users == nil {
		b.users = make(map[string]UserData)
	}
	return b, nil
}
1248752
func makeBackingFsDev(home string) (string, error) {
	var stat unix.Stat_t
	if err := unix.Stat(home, &stat); err != nil {
		return "", err
	}

	backingFsBlockDev := path.Join(home, "backingFsBlockDev")
	// Re-create just in case someone copied the home directory over to a new device
	unix.Unlink(backingFsBlockDev)
	err := unix.Mknod(backingFsBlockDev, unix.S_IFBLK|0600, int(stat.Dev))
	switch err {
	case nil:
		return backingFsBlockDev, nil

	case unix.ENOSYS, unix.EPERM:
		return "", ErrQuotaNotSupported

	default:
		return "", errors.Wrapf(err, "failed to mknod %s", backingFsBlockDev)
	}
}
94111
func Backend(name string) backend.InitFn {
	backendsLock.Lock()
	defer backendsLock.Unlock()
	return backends[name]
}
1363973
func NewBackends(httpClient *http.Client) *Backends {
	apiConfig := &BackendConfig{HTTPClient: httpClient}
	uploadConfig := &BackendConfig{HTTPClient: httpClient}
	return &Backends{
		API:     GetBackendWithConfig(APIBackend, apiConfig),
		Uploads: GetBackendWithConfig(UploadsBackend, uploadConfig),
	}
}
844753
func NewPushNodeByPathToFrontendArgs(path string) *PushNodeByPathToFrontendArgs {
	args := new(PushNodeByPathToFrontendArgs)
	args.Path = path
	return args
}
536019
func NewPostgreSQLBackend(conf map[string]string, logger log.Logger) (physical.Backend, error) {
	// Get the PostgreSQL credentials to perform read/write operations.
	connURL, ok := conf["connection_url"]
	if !ok || connURL == "" {
		return nil, fmt.Errorf("missing connection_url")
	}

	unquoted_table, ok := conf["table"]
	if !ok {
		unquoted_table = "vault_kv_store"
	}
	quoted_table := pq.QuoteIdentifier(unquoted_table)

	maxParStr, ok := conf["max_parallel"]
	var maxParInt int
	var err error
	if ok {
		maxParInt, err = strconv.Atoi(maxParStr)
		if err != nil {
			return nil, errwrap.Wrapf("failed parsing max_parallel parameter: {{err}}", err)
		}
		if logger.IsDebug() {
			logger.Debug("max_parallel set", "max_parallel", maxParInt)
		}
	} else {
		maxParInt = physical.DefaultParallelOperations
	}

	// Create PostgreSQL handle for the database.
	db, err := sql.Open("postgres", connURL)
	if err != nil {
		return nil, errwrap.Wrapf("failed to connect to postgres: {{err}}", err)
	}
	db.SetMaxOpenConns(maxParInt)

	// Determine if we should use an upsert function (versions < 9.5)
	var upsert_required bool
	upsert_required_query := "SELECT current_setting('server_version_num')::int < 90500"
	if err := db.QueryRow(upsert_required_query).Scan(&upsert_required); err != nil {
		return nil, errwrap.Wrapf("failed to check for native upsert: {{err}}", err)
	}

	// Setup our put strategy based on the presence or absence of a native
	// upsert.
	var put_query string
	if upsert_required {
		put_query = "SELECT vault_kv_put($1, $2, $3, $4)"
	} else {
		put_query = "INSERT INTO " + quoted_table + " VALUES($1, $2, $3, $4)" +
			" ON CONFLICT (path, key) DO " +
			" UPDATE SET (parent_path, path, key, value) = ($1, $2, $3, $4)"
	}

	// Setup the backend.
	m := &PostgreSQLBackend{
		table:        quoted_table,
		client:       db,
		put_query:    put_query,
		get_query:    "SELECT value FROM " + quoted_table + " WHERE path = $1 AND key = $2",
		delete_query: "DELETE FROM " + quoted_table + " WHERE path = $1 AND key = $2",
		list_query: "SELECT key FROM " + quoted_table + " WHERE path = $1" +
			"UNION SELECT DISTINCT substring(substr(path, length($1)+1) from '^.*?/') FROM " +
			quoted_table + " WHERE parent_path LIKE $1 || '%'",
		logger:     logger,
		permitPool: physical.NewPermitPool(maxParInt),
	}

	return m, nil
}
864614
func NewEtcdBackend(conf map[string]string, logger log.Logger) (physical.Backend, error) {
	var (
		apiVersion string
		ok         bool
	)

	// v2 client can talk to both etcd2 and etcd3 thought API v2
	c, err := newEtcdV2Client(conf)
	if err != nil {
		return nil, errors.New("failed to create etcd client: " + err.Error())
	}

	remoteAPIVersion, err := getEtcdAPIVersion(c)
	if err != nil {
		return nil, errors.New("failed to get etcd API version: " + err.Error())
	}

	if apiVersion, ok = conf["etcd_api"]; !ok {
		apiVersion = os.Getenv("ETCD_API")
	}

	if apiVersion == "" {
		path, ok := conf["path"]
		if !ok {
			path = "/vault"
		}
		kAPI := client.NewKeysAPI(c)

		// keep using v2 if vault data exists in v2 and user does not explicitly
		// ask for v3.
		_, err := kAPI.Get(context.Background(), path, &client.GetOptions{})
		if errorIsMissingKey(err) {
			apiVersion = remoteAPIVersion
		} else if err == nil {
			apiVersion = "2"
		} else {
			return nil, errors.New("failed to check etcd status: " + err.Error())
		}
	}

	switch apiVersion {
	case "2", "etcd2", "v2":
		return newEtcd2Backend(conf, logger)
	case "3", "etcd3", "v3":
		if remoteAPIVersion == "2" {
			return nil, errors.New("etcd3 is required: etcd2 is running")
		}
		return newEtcd3Backend(conf, logger)
	default:
		return nil, EtcdVersionUnknown
	}
}