diff options
author | Alexey Efimov <xeno@prnwatch.com> | 2022-02-21 17:00:04 +0300 |
---|---|---|
committer | Alexey Efimov <xeno@prnwatch.com> | 2022-02-21 17:00:04 +0300 |
commit | 7b18d121542023f9a06c68d4265932d0d97b7586 (patch) | |
tree | a3a5c1d01f6ed9144cdb987018416182b5921a2c | |
parent | 1f48d5a86f33a9f0f7364814271914f71b48d965 (diff) | |
download | ydb-7b18d121542023f9a06c68d4265932d0d97b7586.tar.gz |
initialize root domain with default user, groups and access rights KIKIMR-14361
ref:6beb48d94021d272c7da87fef709fcbc2aec8046
-rw-r--r-- | ydb/core/base/appdata.h | 1 | ||||
-rw-r--r-- | ydb/core/driver_lib/run/run.cpp | 2 | ||||
-rw-r--r-- | ydb/core/mind/hive/monitoring.cpp | 3 | ||||
-rw-r--r-- | ydb/core/protos/config.proto | 15 | ||||
-rw-r--r-- | ydb/core/testlib/test_client.cpp | 1 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard__init.cpp | 2 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard__init_root.cpp | 90 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp | 13 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_impl.cpp | 5 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_impl.h | 4 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_path.cpp | 8 | ||||
-rw-r--r-- | ydb/library/aclib/aclib.cpp | 10 | ||||
-rw-r--r-- | ydb/library/login/login.cpp | 2 | ||||
-rw-r--r-- | ydb/library/login/login.h | 5 | ||||
-rw-r--r-- | ydb/library/yaml_config/yaml_config_parser.cpp | 98 | ||||
-rw-r--r-- | ydb/tests/functional/ydb_cli/ya.make | 1 |
16 files changed, 234 insertions, 26 deletions
diff --git a/ydb/core/base/appdata.h b/ydb/core/base/appdata.h index c666f7468c0..2dae5a954b0 100644 --- a/ydb/core/base/appdata.h +++ b/ydb/core/base/appdata.h @@ -146,6 +146,7 @@ struct TAppData { NKikimrConfig::TDataShardConfig DataShardConfig; NKikimrConfig::TMeteringConfig MeteringConfig; NKikimrConfig::TCompactionConfig CompactionConfig; + NKikimrConfig::TDomainsConfig DomainsConfig; bool EnforceUserTokenRequirement = false; bool AllowHugeKeyValueDeletes = true; // delete when all clients limit deletes per request bool EnableKqpSpilling = false; diff --git a/ydb/core/driver_lib/run/run.cpp b/ydb/core/driver_lib/run/run.cpp index 1d735aa67da..039553e4cac 100644 --- a/ydb/core/driver_lib/run/run.cpp +++ b/ydb/core/driver_lib/run/run.cpp @@ -138,6 +138,7 @@ public: virtual void Initialize(NKikimr::TAppData* appData) override { + appData->DomainsConfig = Config.GetDomainsConfig(); // setup domain info appData->DomainsInfo = new TDomainsInfo(); for (const NKikimrConfig::TDomainsConfig::TDomain &domain : Config.GetDomainsConfig().GetDomain()) { @@ -189,7 +190,6 @@ public: } const auto& securityConfig(Config.GetDomainsConfig().GetSecurityConfig()); - appData->EnforceUserTokenRequirement = securityConfig.GetEnforceUserTokenRequirement(); if (securityConfig.AdministrationAllowedSIDsSize() > 0) { TVector<TString> administrationAllowedSIDs(securityConfig.GetAdministrationAllowedSIDs().begin(), securityConfig.GetAdministrationAllowedSIDs().end()); diff --git a/ydb/core/mind/hive/monitoring.cpp b/ydb/core/mind/hive/monitoring.cpp index 7e9a83b354e..ecd6a4c2c36 100644 --- a/ydb/core/mind/hive/monitoring.cpp +++ b/ydb/core/mind/hive/monitoring.cpp @@ -1495,7 +1495,8 @@ public: if (down && $(element).hasClass('glyphicon-ok')) { $(element).removeClass('glyphicon-ok'); element.inProgress = true; - $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetDown&down=1', success: function(){ $(element).addClass('glyphicon-remove'); element.inProgress = false; }}); + $.ajax({url:'app?TabletID=' + hiveId + '&node=' + nodeId + '&page=SetDown& + =1', success: function(){ $(element).addClass('glyphicon-remove'); element.inProgress = false; }}); } else if (!down && $(element).hasClass('glyphicon-remove')) { $(element).removeClass('glyphicon-remove'); element.inProgress = true; diff --git a/ydb/core/protos/config.proto b/ydb/core/protos/config.proto index 84d9f9e695f..643c61a92e7 100644 --- a/ydb/core/protos/config.proto +++ b/ydb/core/protos/config.proto @@ -217,6 +217,21 @@ message TDomainsConfig { repeated string DefaultUserSIDs = 4; optional string AllAuthenticatedUsers = 5; repeated string ViewerAllowedSIDs = 6; + + message TUser { + optional string Name = 1; + optional string Password = 2; + } + + message TGroup { + optional string Name = 1; + repeated string Members = 2; + } + + repeated TUser DefaultUsers = 15; + repeated TGroup DefaultGroups = 16; + repeated string DefaultAccess = 17; + optional string AllUsersGroup = 18; } repeated TDomain Domain = 1; diff --git a/ydb/core/testlib/test_client.cpp b/ydb/core/testlib/test_client.cpp index 99cb332737f..67799128cb0 100644 --- a/ydb/core/testlib/test_client.cpp +++ b/ydb/core/testlib/test_client.cpp @@ -218,6 +218,7 @@ namespace Tests { Runtime->GetAppData(nodeIdx).NetClassifierConfig.MergeFrom(Settings->NetClassifierConfig); Runtime->GetAppData(nodeIdx).StreamingConfig.MergeFrom(Settings->AppConfig.GetGRpcConfig().GetStreamingConfig()); Runtime->GetAppData(nodeIdx).EnforceUserTokenRequirement = Settings->AppConfig.GetDomainsConfig().GetSecurityConfig().GetEnforceUserTokenRequirement(); + Runtime->GetAppData(nodeIdx).DomainsConfig.MergeFrom(Settings->AppConfig.GetDomainsConfig()); SetupConfigurators(nodeIdx); SetupProxies(nodeIdx); } diff --git a/ydb/core/tx/schemeshard/schemeshard__init.cpp b/ydb/core/tx/schemeshard/schemeshard__init.cpp index 049afed7ac1..1560794a49d 100644 --- a/ydb/core/tx/schemeshard/schemeshard__init.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__init.cpp @@ -1371,7 +1371,7 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> { Y_VERIFY(rootPath->DomainPathId == Self->RootPathId()); Y_VERIFY(!IsStartWithSlash(rootPath->Name)); - Self->RootPathElemets = SplitPath(rootPath->Name); + Self->RootPathElements = SplitPath(rootPath->Name); Y_VERIFY(!rootPath->StepDropped); Self->PathsById[rootPath->PathId ] = rootPath; diff --git a/ydb/core/tx/schemeshard/schemeshard__init_root.cpp b/ydb/core/tx/schemeshard/schemeshard__init_root.cpp index 74399680cda..7085c109a3d 100644 --- a/ydb/core/tx/schemeshard/schemeshard__init_root.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__init_root.cpp @@ -23,7 +23,6 @@ struct TSchemeShard::TTxInitRoot : public TSchemeShard::TRwTxBase { const TDomainsInfo::TDomain& selfDomain = Self->GetDomainDescription(ctx); TString rootName = selfDomain.Name; - TString owner = BUILTIN_ACL_ROOT; LOG_NOTICE_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "TTxInitRoot DoExecute" @@ -36,9 +35,71 @@ struct TSchemeShard::TTxInitRoot : public TSchemeShard::TRwTxBase { Y_VERIFY(!Self->IsShemeShardConfigured()); Y_VERIFY_S(!rootName.empty(), "invalid root name in domain config"); - TVector<TString> rootPathElemets = SplitPath(rootName); - TString joinedRootPath = JoinPath(rootPathElemets); - Y_VERIFY_S(rootPathElemets.size() == 1, "invalid root name in domain config: " << rootName << " parts count: " << rootPathElemets.size()); + TVector<TString> rootPathElements = SplitPath(rootName); + TString joinedRootPath = JoinPath(rootPathElements); + Y_VERIFY_S(rootPathElements.size() == 1, "invalid root name in domain config: " << rootName << " parts count: " << rootPathElements.size()); + + TString owner; + const NKikimrConfig::TDomainsConfig::TSecurityConfig& securityConfig = Self->GetDomainsConfig().GetSecurityConfig(); + + for (const auto& defaultUser : securityConfig.GetDefaultUsers()) { + auto response = Self->LoginProvider.CreateUser({ + .User = defaultUser.GetName(), + .Password = defaultUser.GetPassword(), + }); + if (response.Error) { + LOG_ERROR_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, + "TTxInitRoot DoExecute" + << ", path: " << rootName + << ", error creating user: " << defaultUser.GetName() + << ", error: " << response.Error); + } else { + auto& sid = Self->LoginProvider.Sids[defaultUser.GetName()]; + db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType, Schema::LoginSids::SidHash>(sid.Type, sid.Hash); + if (owner.empty()) { + owner = defaultUser.GetName(); + } + } + } + + for (const auto& defaultGroup : securityConfig.GetDefaultGroups()) { + auto response = Self->LoginProvider.CreateGroup({ + .Group = defaultGroup.GetName(), + .Options = { + .CheckName = false + } + }); + if (response.Error) { + LOG_ERROR_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, + "TTxInitRoot DoExecute" + << ", path: " << rootName + << ", error creating group: " << defaultGroup.GetName() + << ", error: " << response.Error); + } else { + auto& sid = Self->LoginProvider.Sids[defaultGroup.GetName()]; + db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType>(sid.Type); + for (const auto& member : defaultGroup.GetMembers()) { + auto response = Self->LoginProvider.AddGroupMembership({ + .Group = defaultGroup.GetName(), + .Member = member, + }); + if (response.Error) { + LOG_ERROR_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, + "TTxInitRoot DoExecute" + << ", path: " << rootName + << ", error modifying group: " << defaultGroup.GetName() + << ", with member: " << member + << ", error: " << response.Error); + } else { + db.Table<Schema::LoginSidMembers>().Key(defaultGroup.GetName(), member).Update(); + } + } + } + } + + if (owner.empty()) { + owner = BUILTIN_ACL_ROOT; + } TPathElement::TPtr newPath = new TPathElement(Self->RootPathId(), Self->RootPathId(), Self->RootPathId(), joinedRootPath, owner); newPath->CreateTxId = TTxId(1); @@ -51,18 +112,27 @@ struct TSchemeShard::TTxInitRoot : public TSchemeShard::TRwTxBase { Self->NextLocalPathId = Self->RootPathId().LocalPathId + 1; Self->NextLocalShardIdx = 1; Self->ShardInfos.clear(); - Self->RootPathElemets = std::move(rootPathElemets); - + Self->RootPathElements = std::move(rootPathElements); TSubDomainInfo::TPtr newDomain = new TSubDomainInfo(0, Self->RootPathId()); newDomain->InitializeAsGlobal(Self->CreateRootProcessingParams(ctx)); Self->SubDomains[Self->RootPathId()] = newDomain; + NACLib::TDiffACL diffAcl; + for (const auto& defaultAccess : securityConfig.GetDefaultAccess()) { + NACLibProto::TACE ace; + NACLib::TACL::FromString(ace, defaultAccess); + diffAcl.AddAccess(ace); + } + newPath->ApplyACL(diffAcl.SerializeAsString()); + newDomain->UpdateSecurityState(Self->LoginProvider.GetSecurityState()); + Self->PersistUserAttributes(db, Self->RootPathId(), nullptr, newPath->UserAttrs); Self->PersistPath(db, newPath->PathId); Self->PersistUpdateNextPathId(db); Self->PersistUpdateNextShardIdx(db); Self->PersistStoragePools(db, Self->RootPathId(), *newDomain); + Self->PersistACL(db, newPath); Self->InitState = TTenantInitState::Done; Self->PersistInitState(db); @@ -224,9 +294,9 @@ struct TSchemeShard::TTxInitTenantSchemeShard : public TSchemeShard::TRwTxBase { return; } - TVector<TString> rootPathElemets = SplitPath(rootPath); + TVector<TString> rootPathElements = SplitPath(rootPath); - TString joinedRootPath = JoinPath(rootPathElemets); + TString joinedRootPath = JoinPath(rootPathElements); Y_VERIFY(!IsStartWithSlash(joinedRootPath)); //skip lead '/' @@ -260,7 +330,7 @@ struct TSchemeShard::TTxInitTenantSchemeShard : public TSchemeShard::TRwTxBase { return; } - if (rootPathElemets.size() <= 1) { + if (rootPathElements.size() <= 1) { Reply->Record.SetStatus(NKikimrScheme::StatusInvalidParameter); return; } @@ -284,7 +354,7 @@ struct TSchemeShard::TTxInitTenantSchemeShard : public TSchemeShard::TRwTxBase { Self->NextLocalShardIdx = 1; Self->ShardInfos.clear(); - Self->RootPathElemets = std::move(rootPathElemets); + Self->RootPathElements = std::move(rootPathElements); Self->ParentDomainId = TPathId(domainSchemeShard, domainPathId); Self->ParentDomainOwner = owner; diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp index 0b420f75b41..ecda4b08bfc 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation_alter_login.cpp @@ -30,16 +30,27 @@ public: if (Transaction.GetWorkingDir() != context.SS->LoginProvider.Audience) { result->SetStatus(NKikimrScheme::StatusPreconditionFailed, "Wrong working dir"); } else { + const NKikimrConfig::TDomainsConfig::TSecurityConfig& securityConfig = context.SS->GetDomainsConfig().GetSecurityConfig(); const NKikimrSchemeOp::TAlterLogin& alterLogin = Transaction.GetAlterLogin(); switch (alterLogin.GetAlterCase()) { case NKikimrSchemeOp::TAlterLogin::kCreateUser: { const auto& createUser = alterLogin.GetCreateUser(); - auto response = context.SS->LoginProvider.CreateUser({.User = createUser.GetUser(), .Password = createUser.GetPassword()}); + auto response = context.SS->LoginProvider.CreateUser( + {.User = createUser.GetUser(), .Password = createUser.GetPassword()}); if (response.Error) { result->SetStatus(NKikimrScheme::StatusPreconditionFailed, response.Error); } else { auto& sid = context.SS->LoginProvider.Sids[createUser.GetUser()]; db.Table<Schema::LoginSids>().Key(sid.Name).Update<Schema::LoginSids::SidType, Schema::LoginSids::SidHash>(sid.Type, sid.Hash); + if (securityConfig.HasAllUsersGroup()) { + auto response = context.SS->LoginProvider.AddGroupMembership({ + .Group = securityConfig.GetAllUsersGroup(), + .Member = createUser.GetUser(), + }); + if (!response.Error) { + db.Table<Schema::LoginSidMembers>().Key(securityConfig.GetAllUsersGroup(), createUser.GetUser()).Update(); + } + } result->SetStatus(NKikimrScheme::StatusSuccess); } break; diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.cpp b/ydb/core/tx/schemeshard/schemeshard_impl.cpp index 422a71af6fa..640c0b0775c 100644 --- a/ydb/core/tx/schemeshard/schemeshard_impl.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_impl.cpp @@ -3673,6 +3673,11 @@ const TDomainsInfo::TDomain& TSchemeShard::GetDomainDescription(const TActorCont return domain; } +const NKikimrConfig::TDomainsConfig& TSchemeShard::GetDomainsConfig() { + Y_VERIFY(AppData()); + return AppData()->DomainsConfig; +} + NKikimrSubDomains::TProcessingParams TSchemeShard::CreateRootProcessingParams(const TActorContext &ctx) { const auto& domain = GetDomainDescription(ctx); diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.h b/ydb/core/tx/schemeshard/schemeshard_impl.h index 473f3257200..a2954065d07 100644 --- a/ydb/core/tx/schemeshard/schemeshard_impl.h +++ b/ydb/core/tx/schemeshard/schemeshard_impl.h @@ -140,7 +140,7 @@ public: TParentDomainLink ParentDomainLink; TSubDomainsLinks SubDomainsLinks; - TVector<TString> RootPathElemets; + TVector<TString> RootPathElements; THashMap<TPathId, TPathElement::TPtr> PathsById; TLocalPathId NextLocalPathId = 0; @@ -1077,6 +1077,8 @@ private: static NTabletPipe::TClientConfig GetPipeClientConfig(); public: + static const NKikimrConfig::TDomainsConfig& GetDomainsConfig(); + static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::FLAT_SCHEMESHARD_ACTOR; } diff --git a/ydb/core/tx/schemeshard/schemeshard_path.cpp b/ydb/core/tx/schemeshard/schemeshard_path.cpp index 7535ee673c8..94e8e4f2140 100644 --- a/ydb/core/tx/schemeshard/schemeshard_path.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_path.cpp @@ -1173,11 +1173,11 @@ TPath& TPath::Dive(const TString& name) { return *this; } - if (Elements.empty() && NameParts.size() < SS->RootPathElemets.size()) { + if (Elements.empty() && NameParts.size() < SS->RootPathElements.size()) { NameParts.push_back(name); - if (NameParts.size() == SS->RootPathElemets.size() - && NameParts == SS->RootPathElemets) + if (NameParts.size() == SS->RootPathElements.size() + && NameParts == SS->RootPathElements) { Elements = {SS->PathsById.at(SS->RootPathId())}; NameParts = {Elements.front()->Name}; @@ -1246,7 +1246,7 @@ TPath TPath::ResolveWithInactive(TOperationId opId, const TString path, TSchemeS TPath headOpPath = Init(txState->TargetPathId, ss); - auto headPathNameParts = ss->RootPathElemets; + auto headPathNameParts = ss->RootPathElements; headPathNameParts.insert(headPathNameParts.end(), std::next(headOpPath.NameParts.begin()), headOpPath.NameParts.end()); if (headPathNameParts.size() + 1 == pathParts.size() diff --git a/ydb/library/aclib/aclib.cpp b/ydb/library/aclib/aclib.cpp index 946497ea303..d1fa5a1a925 100644 --- a/ydb/library/aclib/aclib.cpp +++ b/ydb/library/aclib/aclib.cpp @@ -16,7 +16,7 @@ std::pair<ui32, ui32>& operator |=(std::pair<ui32, ui32>& a, const std::pair<ui3 void TUserToken::SetGroupSIDs(const TVector<TString>& groupSIDs) { auto& hashTable = *MutableGroupSIDs(); auto& hashBuckets = *hashTable.MutableBuckets(); - int size(groupSIDs.size()); // we targeting for load factor ~1.0 + int size(groupSIDs.size()); // we are targeting for load factor of ~1.0 hashBuckets.Reserve(size); for (int i = 0; i < size; ++i) { hashBuckets.Add(); @@ -138,7 +138,7 @@ TSecurityObject::TSecurityObject(const TSID& owner, bool isContainer) ui32 TSecurityObject::GetEffectiveAccessRights(const TUserToken& user) const { if (HasOwnerSID() && user.IsExist(GetOwnerSID())) - return EAccessRights::GenericFull; // the owner always have access + return EAccessRights::GenericFull; // the owner always has access ui32 deniedAccessRights = EAccessRights::NoAccess; ui32 allowedAccessRights = EAccessRights::NoAccess; if (HasACL()) { @@ -162,7 +162,7 @@ ui32 TSecurityObject::GetEffectiveAccessRights(const TUserToken& user) const { bool TSecurityObject::CheckAccess(ui32 access, const TUserToken& user) const { if (HasOwnerSID() && user.IsExist(GetOwnerSID())) - return true; // the owner always have access + return true; // the owner always has access if (HasACL()) { ui32 accessRightsLeft = access; for (const NACLibProto::TACE& ace : GetACL().GetACE()) { @@ -174,10 +174,10 @@ bool TSecurityObject::CheckAccess(ui32 access, const TUserToken& user) const { return false; // deny entries have precedence over allow entries break; case EAccessType::Allow: - accessRightsLeft &= ~(accessRightsLeft & ace.GetAccessRight()); // some rights allowed + accessRightsLeft &= ~(accessRightsLeft & ace.GetAccessRight()); // some rights are allowed break; } - if (accessRightsLeft == 0) // all rights has been allowed + if (accessRightsLeft == 0) // all rights have been allowed return true; } } diff --git a/ydb/library/login/login.cpp b/ydb/library/login/login.cpp index b6fbc3c8f63..168d11a1ade 100644 --- a/ydb/library/login/login.cpp +++ b/ydb/library/login/login.cpp @@ -115,7 +115,7 @@ TLoginProvider::TRemoveUserResponse TLoginProvider::RemoveUser(const TRemoveUser TLoginProvider::TBasicResponse TLoginProvider::CreateGroup(const TCreateGroupRequest& request) { TBasicResponse response; - if (!CheckAllowedName(request.Group)) { + if (request.Options.CheckName && !CheckAllowedName(request.Group)) { response.Error = "Name is not allowed"; return response; } diff --git a/ydb/library/login/login.h b/ydb/library/login/login.h index c56f5a22883..96ef5d83183 100644 --- a/ydb/library/login/login.h +++ b/ydb/library/login/login.h @@ -77,7 +77,12 @@ public: }; struct TCreateGroupRequest : TBasicRequest { + struct TOptions { + bool CheckName = true; + }; + TString Group; + TOptions Options; }; struct TAddGroupMembershipRequest : TBasicRequest { diff --git a/ydb/library/yaml_config/yaml_config_parser.cpp b/ydb/library/yaml_config/yaml_config_parser.cpp index 148a4271aca..f292f1cc010 100644 --- a/ydb/library/yaml_config/yaml_config_parser.cpp +++ b/ydb/library/yaml_config/yaml_config_parser.cpp @@ -563,6 +563,103 @@ namespace NKikimr::NYaml { } } + void PrepareSecurityConfig(NJson::TJsonValue& json) { + Y_ENSURE(json.Has("domains_config")); + Y_ENSURE(json["domains_config"].IsMap()); + + NJson::TJsonValue& domainsConfig = json["domains_config"]; + NJson::TJsonValue& securityConfig = domainsConfig["security_config"]; + TString defaultUserName; + + if (securityConfig.Has("default_users")) { + NJson::TJsonValue& defaultUsers = securityConfig["default_users"]; + Y_ENSURE(defaultUsers.IsArray()); + Y_ENSURE(defaultUsers.GetArraySafe().size() > 0); + NJson::TJsonValue& defaultUser = defaultUsers.GetArraySafe()[0]; + Y_ENSURE(defaultUser.IsMap()); + defaultUserName = defaultUser["password"].GetStringRobust(); + } else { + NJson::TJsonValue& defaultUser = securityConfig["default_users"].AppendValue({}); + defaultUser["name"] = defaultUserName = "root"; + defaultUser["password"] = ""; + } + + if (!securityConfig.Has("default_groups")) { + NJson::TJsonValue& defaultGroups = securityConfig["default_groups"]; + + { + NJson::TJsonValue& defaultGroupAdmins = defaultGroups.AppendValue({}); + defaultGroupAdmins["name"] = "ADMINS"; + defaultGroupAdmins["members"].AppendValue(defaultUserName); + } + + { + NJson::TJsonValue& defaultGroupDatabaseAdmins = defaultGroups.AppendValue({}); + defaultGroupDatabaseAdmins["name"] = "DATABASE-ADMINS"; + defaultGroupDatabaseAdmins["members"].AppendValue("ADMINS"); + } + + { + NJson::TJsonValue& defaultGroupAccessAdmins = defaultGroups.AppendValue({}); + defaultGroupAccessAdmins["name"] = "ACCESS-ADMINS"; + defaultGroupAccessAdmins["members"].AppendValue("DATABASE-ADMINS"); + } + + { + NJson::TJsonValue& defaultGroupDdlAdmins = defaultGroups.AppendValue({}); + defaultGroupDdlAdmins["name"] = "DDL-ADMINS"; + defaultGroupDdlAdmins["members"].AppendValue("DATABASE-ADMINS"); + } + + { + NJson::TJsonValue& defaultGroupDataWriters = defaultGroups.AppendValue({}); + defaultGroupDataWriters["name"] = "DATA-WRITERS"; + defaultGroupDataWriters["members"].AppendValue("ADMINS"); + } + + { + NJson::TJsonValue& defaultGroupDataReaders = defaultGroups.AppendValue({}); + defaultGroupDataReaders["name"] = "DATA-READERS"; + defaultGroupDataReaders["members"].AppendValue("DATA-WRITERS"); + } + + { + NJson::TJsonValue& defaultGroupMetadataReaders = defaultGroups.AppendValue({}); + defaultGroupMetadataReaders["name"] = "METADATA-READERS"; + defaultGroupMetadataReaders["members"].AppendValue("DATA-READERS"); + defaultGroupMetadataReaders["members"].AppendValue("DDL-ADMINS"); + } + + { + NJson::TJsonValue& defaultGroupUsers = defaultGroups.AppendValue({}); + defaultGroupUsers["name"] = "USERS"; + defaultGroupUsers["members"].AppendValue("METADATA-READERS"); + defaultGroupUsers["members"].AppendValue("DATA-READERS"); + defaultGroupUsers["members"].AppendValue("DATA-WRITERS"); + defaultGroupUsers["members"].AppendValue("DDL-ADMINS"); + defaultGroupUsers["members"].AppendValue("ACCESS-ADMINS"); + defaultGroupUsers["members"].AppendValue("DATABASE-ADMINS"); + defaultGroupUsers["members"].AppendValue("ADMINS"); + defaultGroupUsers["members"].AppendValue(defaultUserName); + } + } + + if (!securityConfig.Has("all_users_group")) { + securityConfig["all_users_group"] = "USERS"; + } + + if (!securityConfig.Has("default_access")) { + NJson::TJsonValue& defaultAccess = securityConfig["default_access"]; + defaultAccess.AppendValue("+(ConnDB):USERS"); // ConnectDatabase + defaultAccess.AppendValue("+(DS|RA):METADATA-READERS"); // DescribeSchema | ReadAttributes + defaultAccess.AppendValue("+(SR):DATA-READERS"); // SelectRow + defaultAccess.AppendValue("+(UR|ER):DATA-WRITERS"); // UpdateRow | EraseRow + defaultAccess.AppendValue("+(CD|CT|WA|AS|RS):DDL-ADMINS"); // CreateDirectory | CreateTable | WriteAttributes | AlterSchema | RemoveSchema + defaultAccess.AppendValue("+(GAR):ACCESS-ADMINS"); // GrantAccessRights + defaultAccess.AppendValue("+(CDB|DDB):DATABASE-ADMINS"); // CreateDatabase | DropDatabase + } + } + void PrepareNameserviceConfig(NJson::TJsonValue& json) { if (json.Has("nameservice_config")) { Y_ENSURE(json["nameservice_config"].IsMap()); @@ -650,6 +747,7 @@ namespace NKikimr::NYaml { PrepareLogConfig(json); PrepareSystemTabletsInfo(json); PrepareDomainsConfig(json); + PrepareSecurityConfig(json); PrepareBootstrapConfig(json); ClearFields(json); } diff --git a/ydb/tests/functional/ydb_cli/ya.make b/ydb/tests/functional/ydb_cli/ya.make index cf8d4dae484..52de4170be6 100644 --- a/ydb/tests/functional/ydb_cli/ya.make +++ b/ydb/tests/functional/ydb_cli/ya.make @@ -7,7 +7,6 @@ TEST_SRCS( test_ydb_scripting.py ) -ENV(YDB_TOKEN="root@builtin") ENV(YDB_DRIVER_BINARY="ydb/apps/ydbd/ydbd") TIMEOUT(600) SIZE(MEDIUM) |