Skip to content

Commit

Permalink
refactor kerberos plugin to use api_method
Browse files Browse the repository at this point in the history
This commit performs boiler-plate conversion of kerberos.py to
new api_method schema. kerberos.config and kerberos.update are
deliberately excluded at this point due to in-progress changes
to ConfigService api_method plumbing.
  • Loading branch information
anodos325 committed Oct 30, 2024
1 parent 26d7538 commit 0331106
Show file tree
Hide file tree
Showing 7 changed files with 361 additions and 120 deletions.
4 changes: 4 additions & 0 deletions src/middlewared/middlewared/api/v25_04_0/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .acme_protocol import * # noqa
from .acl import * # noqa
from .activedirectory import * # noqa
from .alert import * # noqa
from .alertservice import * # noqa
from .api_key import * # noqa
Expand All @@ -13,6 +14,9 @@
from .fcport import * # noqa
from .group import * # noqa
from .iscsi_auth import * # noqa
from .kerberos import * # noqa
from .kerberos_keytab import * # noqa
from .kerberos_realm import * # noqa
from .keychain import * # noqa
from .privilege import * # noqa
from .rdma import * # noqa
Expand Down
28 changes: 28 additions & 0 deletions src/middlewared/middlewared/api/v25_04_0/activedirectory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from middlewared.api.base import (
BaseModel,
NonEmptyString,
single_argument_args,
)
from middlewared.utils.directoryservices.krb5_constants import (
krb5ccache,
)
from pydantic import Field, Secret
from typing import Literal


__all__ = [
'ActivedirectoryLeaveArgs', 'ActivedirectoryLeaveResult',
]


class ActivedirectoryUsernamePassword(BaseModel):
username: NonEmptyString
password: Secret[NonEmptyString]


class ActivedirectoryLeaveArgs(BaseModel):
ad_cred: ActivedirectoryUsernamePassword


class ActivedirectoryLeaveResult(BaseModel):
result: Literal[True]
156 changes: 156 additions & 0 deletions src/middlewared/middlewared/api/v25_04_0/kerberos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
from middlewared.api.base import (
BaseModel,
NonEmptyString,
single_argument_args,
)
from middlewared.utils.directoryservices.krb5_constants import (
krb5ccache,
)
from pydantic import Field, Secret
from typing import Literal


__all__ = [
'KerberosKdestroyArgs', 'KerberosKdestroyResult',
'KerberosKinitArgs', 'KerberosKinitResult',
'KerberosKlistArgs', 'KerberosKlistResult',
'KerberosCheckTicketArgs', 'KerberosCheckTicketResult',
'KerberosGetCredArgs', 'KerberosGetCredResult',
]


class KerberosCredentialUsernamePassword(BaseModel):
""" Private API entry defined for normalization purposes """
username: NonEmptyString
password: Secret[NonEmptyString]


class KerberosCredentialKeytab(BaseModel):
""" Private API entry defined for normalization purposes """
kerberos_principal: NonEmptyString


class KerberosCcacheOptions(BaseModel):
""" Private API entry defined for normalization purposes """
ccache: Literal[
krb5ccache.SYSTEM.value,
krb5ccache.TEMP.value,
krb5ccache.USER.value,
] = krb5ccache.SYSTEM.value
cache_uid: int = 0


class KerberosKinitKdcOverride(BaseModel):
""" Private API entry defined for normalization purposes """
domain: str | None = None
kdc: str | None = None
libdefaults_aux: list[str] | None = None


class KerberosKinitOptions(KerberosCcacheOptions):
""" Private API entry defined for normalization purposes """
renewal_period: int = 7
lifetime: int = 0
kdc_override: KerberosKinitKdcOverride = Field(default=KerberosKinitKdcOverride())


class KerberosKlistOptions(KerberosCcacheOptions):
""" Private API entry defined for normalization purposes """
timeout: int = 10


@single_argument_args('kerberos_kinit')
class KerberosKinitArgs(BaseModel):
""" Private API entry defined for normalization purposes """
krb5_cred: KerberosCredentialUsernamePassword | KerberosCredentialKeytab
kinit_options: KerberosKinitOptions = Field(alias='kinit-options', default=KerberosKinitOptions())


class KerberosKinitResult(BaseModel):
""" Private API entry defined for normalization purposes """
result: Literal[None]


class KerberosKlistArgs(BaseModel):
""" Private API entry defined for normalization purposes """
klist_options: KerberosKlistOptions


class KerberosKlistEntry(BaseModel):
""" Private API entry defined for normalization purposes """
issued: int
expires: int
renew_until: int
client: NonEmptyString
server: NonEmptyString
etype: NonEmptyString
flags: list[str]


class KerberosKlistFull(BaseModel):
""" Private API entry defined for normalization purposes """
default_principal: NonEmptyString
ticket_cache: NonEmptyString
tickets: list[KerberosKlistEntry]


class KerberosKlistResult(BaseModel):
""" Private API entry defined for normalization purposes """
result: KerberosKlistFull


class KerberosKdestroyArgs(KerberosCcacheOptions):
""" Private API entry defined for normalization purposes """
pass


class KerberosKdestroyResult(BaseModel):
""" Private API entry defined for normalization purposes """
result: Literal[None]


class KerberosCheckTicketArgs(BaseModel):
""" Private API entry defined for normalization purposes """
kerberos_options: KerberosCcacheOptions = Field(alias='kerberos-options', default=KerberosCcacheOptions())
raise_error: bool = True


class KerberosGssCred(BaseModel):
""" Private API entry defined for normalization purposes """
name: NonEmptyString
name_type: NonEmptyString
name_type_oid: str
lifetime: int


class KerberosCheckTicketResult(BaseModel):
""" Private API entry defined for normalization purposes """
result: KerberosGssCred


class ADKinitParameters(BaseModel):
""" Private API entry defined for normalization purposes """
bindname: NonEmptyString
bindpw: Secret[NonEmptyString]
domainname: NonEmptyString
kerberos_principal: NonEmptyString


class LDAPKinitParameters(BaseModel):
""" Private API entry defined for normalization purposes """
binddn: NonEmptyString | None
bindpw: Secret[NonEmptyString | None]
kerberos_realm: int
kerberos_principal: str | None


@single_argument_args('kerberos_get_cred')
class KerberosGetCredArgs(BaseModel):
""" Private API entry defined for normalization purposes """
ds_type: Literal['ACTIVEDIRECTORY', 'LDAP', 'IPA']
conf: ADKinitParameters | LDAPKinitParameters


class KerberosGetCredResult(BaseModel):
""" Private API entry defined for normalization purposes """
result: KerberosCredentialUsernamePassword | KerberosCredentialKeytab
56 changes: 56 additions & 0 deletions src/middlewared/middlewared/api/v25_04_0/kerberos_keytab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from middlewared.api.base import (
BaseModel,
Excluded,
excluded_field,
ForUpdateMetaclass,
NonEmptyString,
)
from pydantic import Secret
from typing import Literal


__all__ = [
'KerberosKeytabEntry',
'KerberosKeytabCreateArgs', 'KerberosKeytabCreateResult',
'KerberosKeytabUpdateArgs', 'KerberosKeytabUpdateResult',
'KerberosKeytabDeleteArgs', 'KerberosKeytabDeleteResult',
]


class KerberosKeytabEntry(BaseModel):
id: int
file: Secret[NonEmptyString]
name: NonEmptyString


class KerberosKeytabCreate(KerberosKeytabEntry):
id: Excluded = excluded_field()


class KerberosKeytabUpdate(KerberosKeytabCreate, metaclass=ForUpdateMetaclass):
pass


class KerberosKeytabCreateArgs(BaseModel):
kerberos_keytab_create: KerberosKeytabCreate


class KerberosKeytabUpdateArgs(BaseModel):
id: int
kerberos_keytab_update: KerberosKeytabUpdate


class KerberosKeytabCreateResult(BaseModel):
result: KerberosKeytabEntry


class KerberosKeytabUpdateResult(BaseModel):
result: KerberosKeytabEntry


class KerberosKeytabDeleteArgs(BaseModel):
id: int


class KerberosKeytabDeleteResult(BaseModel):
result: Literal[True]
57 changes: 57 additions & 0 deletions src/middlewared/middlewared/api/v25_04_0/kerberos_realm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from middlewared.api.base import (
BaseModel,
Excluded,
excluded_field,
ForUpdateMetaclass,
NonEmptyString,
)
from typing import Literal


__all__ = [
'KerberosRealmEntry',
'KerberosRealmCreateArgs', 'KerberosRealmCreateResult',
'KerberosRealmUpdateArgs', 'KerberosRealmUpdateResult',
'KerberosRealmDeleteArgs', 'KerberosRealmDeleteResult',
]


class KerberosRealmEntry(BaseModel):
id: int
realm: NonEmptyString
kdc: list[str]
admin_server: list[str]
kpasswd_server: list[str]


class KerberosRealmCreate(KerberosRealmEntry):
id: Excluded = excluded_field()


class KerberosRealmUpdate(KerberosRealmCreate, metaclass=ForUpdateMetaclass):
pass


class KerberosRealmCreateArgs(BaseModel):
kerberos_realm_create: KerberosRealmCreate


class KerberosRealmUpdateArgs(BaseModel):
id: int
kerberos_realm_update: KerberosRealmUpdate


class KerberosRealmCreateResult(BaseModel):
result: KerberosRealmEntry


class KerberosRealmUpdateResult(BaseModel):
result: KerberosRealmEntry


class KerberosRealmDeleteArgs(BaseModel):
id: int


class KerberosRealmDeleteResult(BaseModel):
result: Literal[True]
13 changes: 10 additions & 3 deletions src/middlewared/middlewared/plugins/activedirectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import os
import contextlib

from middlewared.api import api_method
from middlewared.api.current import (
ActivedirectoryLeaveArgs, ActivedirectoryLeaveResult,
)
from middlewared.plugins.smb import SMBCmd
from middlewared.plugins.kerberos import krb5ccache
from middlewared.schema import (
Expand Down Expand Up @@ -776,8 +780,11 @@ async def lookup_dc(self, domain=None):
out = json.loads(lookup.stdout.decode())
return out

@accepts(Ref('kerberos_username_password'), roles=['DIRECTORY_SERVICE_WRITE'], audit='Active directory leave')
@returns()
@api_method(
ActivedirectoryLeaveArgs, ActivedirectoryLeaveResult,
roles=['DIRECTORY_SERVICE_WRITE'],
audit='Active directory leave',
)
@job(lock="AD_start_stop")
async def leave(self, job, data):
"""
Expand Down Expand Up @@ -880,4 +887,4 @@ async def leave(self, job, data):
await self.middleware.call('service.restart', 'cifs')
await self.middleware.call('service.restart', 'idmap')
job.set_progress(100, 'Successfully left activedirectory domain.')
return
return True
Loading

0 comments on commit 0331106

Please sign in to comment.