The branch, master has been updated via 8027283dd7c tests: Test ldap whoami exop via a00af01e656 ldap_server: Implement the rfc4532 whoami exop via e88332cbe41 ldb: Implement ldap_whoami in pyldb via 0575cc4b85f ldb: Allow extended operations through ildap via 8aab8d6cafd ldb: Add the RFC4532 LDB_EXTENDED_WHOAMI_OID definition from d5b8b804fe4 Add ROLE_IPA_DC into two more places
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 8027283dd7c55b611d0af19caccbdd98bb2fa264 Author: Volker Lendecke <v...@samba.org> Date: Fri Apr 21 16:04:30 2023 +0200 tests: Test ldap whoami exop Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Wed Apr 26 07:20:14 UTC 2023 on atb-devel-224 commit a00af01e656af291a3abf01f05dcc4db51db77d0 Author: Volker Lendecke <v...@samba.org> Date: Wed Nov 3 16:35:00 2021 +0100 ldap_server: Implement the rfc4532 whoami exop Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit e88332cbe41e817d74a411332c66f19aee6071e5 Author: Volker Lendecke <v...@samba.org> Date: Fri Mar 24 11:49:02 2023 +0100 ldb: Implement ldap_whoami in pyldb Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 0575cc4b85f65fbcd3fa7fc2c1961284ba1a02f0 Author: Volker Lendecke <v...@samba.org> Date: Fri Mar 24 11:48:31 2023 +0100 ldb: Allow extended operations through ildap Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 8aab8d6cafdd7d975b8f82692b8fad87723c5c6d Author: Volker Lendecke <v...@samba.org> Date: Wed Nov 10 16:29:59 2021 +0100 ldb: Add the RFC4532 LDB_EXTENDED_WHOAMI_OID definition Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/ldb-samba/ldb_ildap.c | 111 ++++++++++++++++++++++++++++++++++++ lib/ldb/include/ldb.h | 5 ++ lib/ldb/pyldb.c | 36 ++++++++++++ python/samba/tests/ldap_whoami.py | 38 ++++++++++++ source4/ldap_server/ldap_extended.c | 48 ++++++++++++++++ source4/selftest/tests.py | 1 + 6 files changed, 239 insertions(+) create mode 100644 python/samba/tests/ldap_whoami.py Changeset truncated at 500 lines: diff --git a/lib/ldb-samba/ldb_ildap.c b/lib/ldb-samba/ldb_ildap.c index d738d1da0cf..c3d872ebaa1 100644 --- a/lib/ldb-samba/ldb_ildap.c +++ b/lib/ldb-samba/ldb_ildap.c @@ -370,6 +370,67 @@ static void ildb_callback(struct ldap_request *req) break; + case LDAP_TAG_ExtendedRequest: { + + struct ldap_ExtendedResponse *ext_response = NULL; + struct ldb_reply *ares = NULL; + + if (req->replies[0]->type != LDAP_TAG_ExtendedResponse) { + ret = LDB_ERR_PROTOCOL_ERROR; + return; + } + ext_response = &req->replies[0]->r.ExtendedResponse; + + status = ldap_check_response(ac->ireq->conn, + &req->replies[0]->r.GeneralResult); + if (!NT_STATUS_IS_OK(status)) { + ret = ildb_map_error(ac->module, status); + request_done = true; + break; + } + + ares = talloc_zero(req, struct ldb_reply); + if (ares == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + request_done = true; + break; + } + + ares->type = LDB_REPLY_DONE; + + ares->response = talloc_zero(ares, struct ldb_extended); + if (ares->response == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + request_done = true; + break; + } + + ares->response->oid = + talloc_strdup(ares->response, ext_response->oid); + if (ares->response->oid == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + request_done = true; + break; + } + + if (ext_response->value != NULL) { + ares->response->data = + talloc_memdup(ares->response, + ext_response->value->data, + ext_response->value->length); + if (ares->response->data == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + request_done = true; + break; + } + } + + ares->controls = talloc_move(ares, &req->replies[0]->controls); + + ac->req->callback(ac->req, ares); + return; + } + default: ret = LDB_ERR_PROTOCOL_ERROR; break; @@ -665,6 +726,52 @@ static int ildb_rename(struct ildb_context *ac) return ildb_request_send(ac, msg); } +/* + * Issue an extended operation + */ +static int ildb_extended(struct ildb_context *ac) +{ + struct ldb_request *req = ac->req; + struct ldb_extended *extended_req = NULL; + struct ldap_message *msg = NULL; + DATA_BLOB *value = NULL; + + if (req->operation != LDB_EXTENDED) { + return LDB_ERR_OPERATIONS_ERROR; + } + extended_req = &req->op.extended; + + msg = new_ldap_message(req); + if (msg == NULL) { + goto nomem; + } + + if (extended_req->data != NULL) { + value = talloc(req, DATA_BLOB); + if (value == NULL) { + goto nomem; + } + *value = data_blob_talloc(value, + extended_req->data, + talloc_get_size(extended_req->data)); + if (value->data == NULL) { + goto nomem; + } + } + + *msg = (struct ldap_message){ + .type = LDAP_TAG_ExtendedRequest, + .r.ExtendedRequest.oid = extended_req->oid, + .r.ExtendedRequest.value = value, + .controls = req->controls, + }; + + return ildb_request_send(ac, msg); +nomem: + TALLOC_FREE(msg); + return LDB_ERR_OPERATIONS_ERROR; +} + static int ildb_start_trans(struct ldb_module *module) { /* TODO implement a local locking mechanism here */ @@ -770,6 +877,9 @@ static int ildb_handle_request(struct ldb_module *module, struct ldb_request *re case LDB_RENAME: ret = ildb_rename(ac); break; + case LDB_EXTENDED: + ret = ildb_extended(ac); + break; default: /* no other op supported */ ret = LDB_ERR_PROTOCOL_ERROR; @@ -786,6 +896,7 @@ static const struct ldb_module_ops ildb_ops = { .modify = ildb_handle_request, .del = ildb_handle_request, .rename = ildb_handle_request, + .extended = ildb_handle_request, /* .request = ildb_handle_request, */ .start_transaction = ildb_start_trans, .end_transaction = ildb_end_trans, diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h index 70dac7280bf..8bebd9fce1b 100644 --- a/lib/ldb/include/ldb.h +++ b/lib/ldb/include/ldb.h @@ -817,6 +817,11 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); */ #define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1" +/** + OID for RFC4532 "Who Am I" extended operation +*/ +#define LDB_EXTENDED_WHOAMI_OID "1.3.6.1.4.1.4203.1.11.3" + struct ldb_sd_flags_control { /* * request the owner 0x00000001 diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c index 45a53d94563..aa38e115ce4 100644 --- a/lib/ldb/pyldb.c +++ b/lib/ldb/pyldb.c @@ -2399,6 +2399,36 @@ static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args) return PyLong_FromLongLong(value); } +static PyObject *py_ldb_whoami(PyLdbObject *self, PyObject *args) +{ + struct ldb_context *ldb = pyldb_Ldb_AS_LDBCONTEXT(self); + struct ldb_result *res = NULL; + struct ldb_extended *ext_res = NULL; + size_t len = 0; + int ret; + + ret = ldb_extended(ldb, LDB_EXTENDED_WHOAMI_OID, NULL, &res); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); + + ext_res = res->extended; + if (ext_res == NULL) { + PyErr_SetString(PyExc_TypeError, "Got no exop reply"); + return NULL; + } + + if (strcmp(ext_res->oid, LDB_EXTENDED_WHOAMI_OID) != 0) { + PyErr_SetString(PyExc_TypeError, "Got wrong reply OID"); + return NULL; + } + + len = talloc_get_size(ext_res->data); + if (len == 0) { + Py_RETURN_NONE; + } + + return PyUnicode_FromStringAndSize(ext_res->data, len); +} + static const struct ldb_dn_extended_syntax test_dn_syntax = { .name = "TEST", @@ -2530,6 +2560,12 @@ static PyMethodDef py_ldb_methods[] = { { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS, "S.sequence_number(type) -> value\n" "Return the value of the sequence according to the requested type" }, + { "whoami", + (PyCFunction)py_ldb_whoami, + METH_NOARGS, + "S.whoami(type) -> value\n" + "Return the RFC4532 whoami string", + }, { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS, "S._register_test_extensions() -> None\n" "Register internal extensions used in testing" }, diff --git a/python/samba/tests/ldap_whoami.py b/python/samba/tests/ldap_whoami.py new file mode 100644 index 00000000000..378928e6379 --- /dev/null +++ b/python/samba/tests/ldap_whoami.py @@ -0,0 +1,38 @@ +# Unix SMB/CIFS implementation. +# Copyright (C) Volker Lendecke <v...@samba.org> 2023 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from samba import Ldb,tests +from samba.samba3 import param as s3param +from samba import (credentials,NTSTATUSError) +import os + +class LdapWhoami(tests.TestCase): + def test_ldap_whoami(self): + lp = s3param.get_context() + lp.load(os.getenv("SERVERCONFFILE")); + + domain=os.getenv("DOMAIN") + username=os.getenv("DC_USERNAME") + + creds = credentials.Credentials() + creds.guess(lp) + creds.set_domain(domain) + creds.set_username(username) + creds.set_password(os.getenv("DC_PASSWORD")) + + l=Ldb(f'ldap://{os.getenv("DC_SERVER_IP")}/', credentials=creds, lp=lp) + w=l.whoami() + self.assertEqual(w,f'u:{domain}\\{username}') diff --git a/source4/ldap_server/ldap_extended.c b/source4/ldap_server/ldap_extended.c index ee617ee9b1a..c37c9a9d89a 100644 --- a/source4/ldap_server/ldap_extended.c +++ b/source4/ldap_server/ldap_extended.c @@ -23,6 +23,8 @@ #include "lib/tls/tls.h" #include "samba/service_stream.h" #include "../lib/util/tevent_ntstatus.h" +#include "librpc/gen_ndr/auth.h" +#include "libcli/security/security_token.h" struct ldapsrv_starttls_postprocess_context { struct ldapsrv_connection *conn; @@ -151,11 +153,57 @@ struct ldapsrv_extended_operation { NTSTATUS (*fn)(struct ldapsrv_call *call, struct ldapsrv_reply *reply, const char **errorstr); }; +static NTSTATUS ldapsrv_whoami(struct ldapsrv_call *call, + struct ldapsrv_reply *reply, + const char **errstr) +{ + struct ldapsrv_connection *conn = call->conn; + struct auth_session_info *session_info = conn->session_info; + struct ldap_ExtendedResponse *ext_resp = + &reply->msg->r.ExtendedResponse; + + *errstr = NULL; + + if (!security_token_is_anonymous(session_info->security_token)) { + struct auth_user_info *uinfo = session_info->info; + DATA_BLOB *value = talloc_zero(call, DATA_BLOB); + + if (value == NULL) { + goto nomem; + } + + value->data = (uint8_t *)talloc_asprintf(value, + "u:%s\\%s", + uinfo->domain_name, + uinfo->account_name); + if (value->data == NULL) { + goto nomem; + } + value->length = talloc_get_size(value->data) - 1; + + ext_resp->value = value; + } + + ext_resp->response.resultcode = LDAP_SUCCESS; + ext_resp->response.errormessage = NULL; + + ldapsrv_queue_reply(call, reply); + + return NT_STATUS_OK; +nomem: + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); +} + + static struct ldapsrv_extended_operation extended_ops[] = { { .oid = LDB_EXTENDED_START_TLS_OID, .fn = ldapsrv_StartTLS, },{ + .oid = LDB_EXTENDED_WHOAMI_OID, + .fn = ldapsrv_whoami, + }, + { .oid = NULL, .fn = NULL, } diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index a0869c3a5de..19764a14397 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -1079,6 +1079,7 @@ planpythontestsuite("ad_dc_default:local", "samba.tests.dcerpc.unix") planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc") planpythontestsuite("ad_dc_default:local", "samba.tests.samba_tool.timecmd") planpythontestsuite("ad_dc_default:local", "samba.tests.samba_tool.join") +planpythontestsuite("ad_dc_default:local", "samba.tests.ldap_whoami") planpythontestsuite("ad_member_s3_join", "samba.tests.samba_tool.join_member") planpythontestsuite("ad_dc_default", "samba.tests.samba_tool.join_lmdb_size") -- Samba Shared Repository