Skip to content

Commit 13d738d

Browse files
authored
Fix modify samaccountname (#969)
1 parent 1478576 commit 13d738d

7 files changed

Lines changed: 83 additions & 17 deletions

File tree

.kerberos/config_server.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@ async def force_pw_principal(self, name: str, **dbargs) -> None:
188188
:param str name: principal
189189
"""
190190

191+
@abstractmethod
192+
async def rename_princ(self, name: str, new_name: str) -> None:
193+
"""Rename principal.
194+
195+
:param str name: original name
196+
:param str new_name: new name
197+
"""
198+
191199
@abstractmethod
192200
async def modify_principal(
193201
self,
@@ -272,6 +280,19 @@ async def add_princ(
272280
partial(princ.modify, attributes=128),
273281
)
274282

283+
async def rename_princ(self, name: str, new_name: str) -> None:
284+
"""Rename principal.
285+
286+
:param str name: original name
287+
:param str new_name: new name
288+
"""
289+
await self.loop.run_in_executor(
290+
self.pool,
291+
self.client.rename_principal,
292+
name,
293+
new_name,
294+
)
295+
275296
async def _get_raw_principal(self, name: str) -> PrincipalProtocol:
276297
principal = await self.loop.run_in_executor(
277298
self.pool,
@@ -640,6 +661,25 @@ async def create_or_update_princ_password(
640661
await kadmin.create_or_update_princ_pw(name, password)
641662

642663

664+
@principal_router.put(
665+
"/rename",
666+
status_code=status.HTTP_202_ACCEPTED,
667+
response_class=Response,
668+
)
669+
async def rename_princ(
670+
kadmin: Annotated[AbstractKRBManager, Depends(get_kadmin)],
671+
name: Annotated[str, Body()],
672+
new_name: Annotated[str, Body()],
673+
) -> None:
674+
"""Rename principal.
675+
676+
:param Annotated[AbstractKRBManager, Depends kadmin: kadmin abstract
677+
:param Annotated[str, Body name: principal name
678+
:param Annotated[str, Body new_name: principal new name
679+
"""
680+
await kadmin.rename_princ(name, new_name)
681+
682+
643683
@principal_router.put(
644684
"/modify",
645685
status_code=status.HTTP_202_ACCEPTED,

app/ldap_protocol/kerberos/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ async def modify_princ(
188188
password: str | None = None,
189189
) -> None: ...
190190

191+
@abstractmethod
192+
async def rename_princ(
193+
self,
194+
name: str,
195+
new_name: str,
196+
) -> None: ...
197+
191198
@backoff.on_exception(
192199
backoff.constant,
193200
(

app/ldap_protocol/kerberos/client.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ async def modify_princ(
103103
) -> None:
104104
"""Rename request."""
105105
response = await self.client.put(
106-
"principal",
106+
"principal/modify",
107107
json={
108-
"name": name,
108+
"principal_name": name,
109109
"new_name": new_name,
110110
"algorithms": algorithms,
111111
"password": password,
@@ -114,6 +114,20 @@ async def modify_princ(
114114
if response.status_code != 202:
115115
raise krb_exc.KRBAPIModifyPrincipalError(response.text)
116116

117+
@logger_wraps()
118+
async def rename_princ(
119+
self,
120+
name: str,
121+
new_name: str,
122+
) -> None:
123+
"""Rename request."""
124+
response = await self.client.put(
125+
"principal/rename",
126+
json={"name": name, "new_name": new_name},
127+
)
128+
if response.status_code != 202:
129+
raise krb_exc.KRBAPIModifyPrincipalError(response.text)
130+
117131
@logger_wraps()
118132
async def ktadd(
119133
self,

app/ldap_protocol/kerberos/stub.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ async def modify_princ(
5454
password: str | None = None,
5555
) -> None: ...
5656

57+
@logger_wraps(is_stub=True)
58+
async def rename_princ(
59+
self,
60+
name: str,
61+
new_name: str,
62+
) -> None: ...
63+
5764
@logger_wraps(is_stub=True)
5865
async def ktadd(self, names: list[str], is_rand_key: bool) -> NoReturn: # noqa: ARG002
5966
raise KRBAPIPrincipalNotFoundError

app/ldap_protocol/ldap_requests/modify.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,10 @@ async def handle(
216216
)
217217
return
218218

219-
if directory.rdname in names:
219+
if (
220+
directory.rdname != "krbprincipalname"
221+
and directory.rdname in names
222+
):
220223
yield ModifyResponse(result_code=LDAPCodes.NOT_ALLOWED_ON_RDN)
221224
return
222225

@@ -935,11 +938,9 @@ async def _add( # noqa: C901
935938
new_user_principal_name = f"{new_sam_account_name}@{base_dir.name}" # noqa: E501 # fmt: skip
936939

937940
if directory.user.sam_account_name != new_sam_account_name:
938-
await kadmin.modify_princ(
941+
await kadmin.rename_princ(
939942
directory.user.sam_account_name,
940943
new_sam_account_name,
941-
algorithms=None,
942-
password=None,
943944
)
944945

945946
directory.user.user_principal_name = new_user_principal_name # noqa: E501 # fmt: skip
@@ -1043,17 +1044,13 @@ async def _modify_computer_samaccountname(
10431044
raise ModifyForbiddenError("Old sAMAccountName value not found.")
10441045

10451046
if old_sam_account_name != new_sam_account_name:
1046-
await kadmin.modify_princ(
1047+
await kadmin.rename_princ(
10471048
f"host/{old_sam_account_name}",
10481049
f"host/{new_sam_account_name}",
1049-
algorithms=None,
1050-
password=None,
10511050
)
1052-
await kadmin.modify_princ(
1051+
await kadmin.rename_princ(
10531052
f"host/{old_sam_account_name}.{base_dir.name}",
10541053
f"host/{new_sam_account_name}.{base_dir.name}",
1055-
algorithms=None,
1056-
password=None,
10571054
)
10581055

10591056
async def _get_base_dir(

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ async def get_kadmin(self) -> AsyncIterator[AsyncMock]:
195195
kadmin.add_principal = AsyncMock()
196196
kadmin.del_principal = AsyncMock()
197197
kadmin.modify_princ = AsyncMock()
198+
kadmin.rename_princ = AsyncMock()
198199
kadmin.create_or_update_principal_pw = AsyncMock()
199200
kadmin.change_principal_password = AsyncMock()
200201
kadmin.lock_principal = AsyncMock()

tests/test_api/test_main/test_router/test_modify.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ async def test_api_correct_modify_user_samaccountname(
101101
data = response.json()
102102
assert isinstance(data, dict)
103103
assert data.get("resultCode") == LDAPCodes.SUCCESS
104-
assert kadmin.modify_princ.call_args.args == ("new_user", "NEW user name") # type: ignore
104+
assert kadmin.rename_princ.call_args.args == ("new_user", "NEW user name") # type: ignore
105105

106106
response = await http_client.post(
107107
"entry/search",
@@ -160,7 +160,7 @@ async def test_api_correct_modify_user_userprincipalname(
160160
data = response.json()
161161
assert isinstance(data, dict)
162162
assert data.get("resultCode") == LDAPCodes.SUCCESS
163-
assert kadmin.modify_princ.call_args.args == ("new_user", "newbiguser") # type: ignore
163+
assert kadmin.rename_princ.call_args.args == ("new_user", "newbiguser") # type: ignore
164164

165165
response = await http_client.post(
166166
"entry/search",
@@ -219,12 +219,12 @@ async def test_api_correct_modify_computer_samaccountname_replace(
219219

220220
assert isinstance(data, dict)
221221
assert data.get("resultCode") == LDAPCodes.SUCCESS
222-
assert kadmin.modify_princ.call_count == 2 # type: ignore
223-
assert kadmin.modify_princ.call_args_list[0].args == ( # type: ignore
222+
assert kadmin.rename_princ.call_count == 2 # type: ignore
223+
assert kadmin.rename_princ.call_args_list[0].args == ( # type: ignore
224224
"host/mycomputer",
225225
"host/maincomputer",
226226
)
227-
assert kadmin.modify_princ.call_args_list[1].args == ( # type: ignore
227+
assert kadmin.rename_princ.call_args_list[1].args == ( # type: ignore
228228
"host/mycomputer.md.test",
229229
"host/maincomputer.md.test",
230230
)

0 commit comments

Comments
 (0)