mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +03:00
s4-auth Add function to obtain any user's session_info from a given LDB
This will be a building block for a tokenGroups test, which can compare against a remote server (in particular the rootDSE) against what we would calculate the tokenGroups to be. (this meant moving some parts out of the auth_sam code into the containing library) Andrew Bartlett
This commit is contained in:
committed by
Andrew Tridgell
parent
c82269cf86
commit
ece6eae4d8
@ -353,87 +353,16 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
|
||||
}
|
||||
|
||||
|
||||
/* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available, and for tokenGroups in the DSDB stack.
|
||||
|
||||
Supply either a principal or a DN
|
||||
*/
|
||||
NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
|
||||
struct auth_context *auth_context,
|
||||
const char *principal,
|
||||
struct ldb_dn *user_dn,
|
||||
struct auth_serversupplied_info **server_info)
|
||||
/* Wrapper for the auth subsystem pointer */
|
||||
NTSTATUS authsam_get_server_info_principal_wrapper(TALLOC_CTX *mem_ctx,
|
||||
struct auth_context *auth_context,
|
||||
const char *principal,
|
||||
struct ldb_dn *user_dn,
|
||||
struct auth_serversupplied_info **server_info)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
DATA_BLOB user_sess_key = data_blob(NULL, 0);
|
||||
DATA_BLOB lm_sess_key = data_blob(NULL, 0);
|
||||
|
||||
struct ldb_message *msg;
|
||||
struct ldb_dn *domain_dn;
|
||||
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (principal) {
|
||||
nt_status = sam_get_results_principal(auth_context->sam_ctx, tmp_ctx, principal,
|
||||
user_attrs, &domain_dn, &msg);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
talloc_free(tmp_ctx);
|
||||
return nt_status;
|
||||
}
|
||||
} else if (user_dn) {
|
||||
struct dom_sid *user_sid, *domain_sid;
|
||||
int ret;
|
||||
/* pull the user attributes */
|
||||
ret = dsdb_search_one(auth_context->sam_ctx, tmp_ctx, &msg, user_dn,
|
||||
LDB_SCOPE_BASE, user_attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
|
||||
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_NO_SUCH_USER;
|
||||
} else if (ret != LDB_SUCCESS) {
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||
}
|
||||
|
||||
user_sid = samdb_result_dom_sid(msg, msg, "objectSid");
|
||||
|
||||
nt_status = dom_sid_split_rid(tmp_ctx, user_sid, &domain_sid, NULL);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
domain_dn = samdb_search_dn(auth_context->sam_ctx, mem_ctx, NULL,
|
||||
"(&(objectSid=%s)(objectClass=domain))",
|
||||
ldap_encode_ndr_dom_sid(tmp_ctx, domain_sid));
|
||||
if (!domain_dn) {
|
||||
DEBUG(3, ("authsam_get_server_info_principal: Failed to find domain with: SID %s\n",
|
||||
dom_sid_string(tmp_ctx, domain_sid)));
|
||||
return NT_STATUS_NO_SUCH_USER;
|
||||
}
|
||||
|
||||
} else {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
nt_status = authsam_make_server_info(tmp_ctx, auth_context->sam_ctx,
|
||||
lpcfg_netbios_name(auth_context->lp_ctx),
|
||||
lpcfg_workgroup(auth_context->lp_ctx),
|
||||
domain_dn,
|
||||
msg,
|
||||
user_sess_key, lm_sess_key,
|
||||
server_info);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
talloc_free(tmp_ctx);
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
talloc_steal(mem_ctx, *server_info);
|
||||
talloc_free(tmp_ctx);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
return authsam_get_server_info_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx,
|
||||
principal, user_dn, server_info);
|
||||
}
|
||||
|
||||
static const struct auth_operations sam_ignoredomain_ops = {
|
||||
.name = "sam_ignoredomain",
|
||||
.get_challenge = auth_get_challenge_not_implemented,
|
||||
|
@ -18,13 +18,15 @@
|
||||
|
||||
#include <Python.h>
|
||||
#include "includes.h"
|
||||
#include "libcli/util/pyerrors.h"
|
||||
#include "param/param.h"
|
||||
#include "pyauth.h"
|
||||
#include "pyldb.h"
|
||||
#include "auth/system_session_proto.h"
|
||||
#include "auth/session.h"
|
||||
#include "param/pyparam.h"
|
||||
#include "libcli/security/security.h"
|
||||
|
||||
|
||||
static PyTypeObject PyAuthSession = {
|
||||
.tp_name = "AuthSession",
|
||||
.tp_basicsize = sizeof(py_talloc_Object),
|
||||
@ -102,9 +104,69 @@ static PyObject *py_admin_session(PyObject *module, PyObject *args)
|
||||
return PyAuthSession_FromSession(session);
|
||||
}
|
||||
|
||||
static PyObject *py_user_session(PyObject *module, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
struct auth_session_info *session;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
const char * const kwnames[] = { "ldb", "lp_ctx", "principal", "dn", "session_info_flags" };
|
||||
struct ldb_context *ldb_ctx;
|
||||
PyObject *py_ldb = Py_None;
|
||||
PyObject *py_dn = Py_None;
|
||||
PyObject *py_lp_ctx = Py_None;
|
||||
struct loadparm_context *lp_ctx = NULL;
|
||||
struct ldb_dn *user_dn;
|
||||
char *principal = NULL;
|
||||
int session_info_flags; /* This is an int, because that's what
|
||||
* we need for the python
|
||||
* PyArg_ParseTupleAndKeywords */
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OzOi",
|
||||
discard_const_p(char *, kwnames),
|
||||
&py_ldb, &py_lp_ctx, &principal, &py_dn, &session_info_flags)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem_ctx = talloc_new(NULL);
|
||||
if (mem_ctx == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ldb_ctx = PyLdb_AsLdbContext(py_ldb);
|
||||
|
||||
if (py_dn == Py_None) {
|
||||
user_dn = NULL;
|
||||
} else {
|
||||
if (!PyObject_AsDn(ldb_ctx, py_dn, ldb_ctx, &user_dn)) {
|
||||
talloc_free(mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
|
||||
if (lp_ctx == NULL) {
|
||||
talloc_free(mem_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nt_status = authsam_get_session_info_principal(mem_ctx, lp_ctx, ldb_ctx, principal, user_dn,
|
||||
session_info_flags, &session);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
talloc_free(mem_ctx);
|
||||
PyErr_NTSTATUS_IS_ERR_RAISE(nt_status);
|
||||
}
|
||||
|
||||
talloc_steal(NULL, session);
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
return PyAuthSession_FromSession(session);
|
||||
}
|
||||
|
||||
static PyMethodDef py_auth_methods[] = {
|
||||
{ "system_session", (PyCFunction)py_system_session, METH_VARARGS, NULL },
|
||||
{ "admin_session", (PyCFunction)py_admin_session, METH_VARARGS, NULL },
|
||||
{ "user_session", (PyCFunction)py_user_session, METH_VARARGS, NULL },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "libcli/security/security.h"
|
||||
#include "auth/auth_sam.h"
|
||||
#include "dsdb/common/util.h"
|
||||
#include "libcli/ldap/ldap_ndr.h"
|
||||
#include "param/param.h"
|
||||
|
||||
#define KRBTGT_ATTRS \
|
||||
/* required for the krb5 kdc */ \
|
||||
@ -503,3 +505,85 @@ NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available, and for tokenGroups in the DSDB stack.
|
||||
|
||||
Supply either a principal or a DN
|
||||
*/
|
||||
NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct ldb_context *sam_ctx,
|
||||
const char *principal,
|
||||
struct ldb_dn *user_dn,
|
||||
struct auth_serversupplied_info **server_info)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
DATA_BLOB user_sess_key = data_blob(NULL, 0);
|
||||
DATA_BLOB lm_sess_key = data_blob(NULL, 0);
|
||||
|
||||
struct ldb_message *msg;
|
||||
struct ldb_dn *domain_dn;
|
||||
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (principal) {
|
||||
nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal,
|
||||
user_attrs, &domain_dn, &msg);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
talloc_free(tmp_ctx);
|
||||
return nt_status;
|
||||
}
|
||||
} else if (user_dn) {
|
||||
struct dom_sid *user_sid, *domain_sid;
|
||||
int ret;
|
||||
/* pull the user attributes */
|
||||
ret = dsdb_search_one(sam_ctx, tmp_ctx, &msg, user_dn,
|
||||
LDB_SCOPE_BASE, user_attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
|
||||
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_NO_SUCH_USER;
|
||||
} else if (ret != LDB_SUCCESS) {
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||
}
|
||||
|
||||
user_sid = samdb_result_dom_sid(msg, msg, "objectSid");
|
||||
|
||||
nt_status = dom_sid_split_rid(tmp_ctx, user_sid, &domain_sid, NULL);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
domain_dn = samdb_search_dn(sam_ctx, mem_ctx, NULL,
|
||||
"(&(objectSid=%s)(objectClass=domain))",
|
||||
ldap_encode_ndr_dom_sid(tmp_ctx, domain_sid));
|
||||
if (!domain_dn) {
|
||||
DEBUG(3, ("authsam_get_server_info_principal: Failed to find domain with: SID %s\n",
|
||||
dom_sid_string(tmp_ctx, domain_sid)));
|
||||
return NT_STATUS_NO_SUCH_USER;
|
||||
}
|
||||
|
||||
} else {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
nt_status = authsam_make_server_info(tmp_ctx, sam_ctx,
|
||||
lpcfg_netbios_name(lp_ctx),
|
||||
lpcfg_workgroup(lp_ctx),
|
||||
domain_dn,
|
||||
msg,
|
||||
user_sess_key, lm_sess_key,
|
||||
server_info);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
talloc_free(tmp_ctx);
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
talloc_steal(mem_ctx, *server_info);
|
||||
talloc_free(tmp_ctx);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "auth/auth.h"
|
||||
#include "auth/auth_sam.h"
|
||||
#include "libcli/security/security.h"
|
||||
#include "libcli/auth/libcli_auth.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
@ -195,6 +196,44 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Produce a session_info for an arbitary DN or principal in the local
|
||||
* DB, assuming the local DB holds all the groups
|
||||
*
|
||||
* Supply either a principal or a DN
|
||||
*/
|
||||
NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct ldb_context *sam_ctx,
|
||||
const char *principal,
|
||||
struct ldb_dn *user_dn,
|
||||
uint32_t session_info_flags,
|
||||
struct auth_session_info **session_info)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
struct auth_serversupplied_info *server_info;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
nt_status = authsam_get_server_info_principal(tmp_ctx, lp_ctx, sam_ctx,
|
||||
principal, user_dn,
|
||||
&server_info);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
talloc_free(tmp_ctx);
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
nt_status = auth_generate_session_info(tmp_ctx, lp_ctx, sam_ctx,
|
||||
server_info, session_info_flags,
|
||||
session_info);
|
||||
|
||||
if (NT_STATUS_IS_OK(nt_status)) {
|
||||
talloc_steal(mem_ctx, *session_info);
|
||||
}
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* prints a struct auth_session_info security token to debug output.
|
||||
*/
|
||||
|
@ -30,7 +30,9 @@ struct auth_session_info {
|
||||
|
||||
#include "librpc/gen_ndr/netlogon.h"
|
||||
|
||||
struct tevent_context;
|
||||
struct ldb_context;
|
||||
struct ldb_dn;
|
||||
/* Create a security token for a session SYSTEM (the most
|
||||
* trusted/prvilaged account), including the local machine account as
|
||||
* the off-host credentials */
|
||||
@ -48,6 +50,18 @@ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
|
||||
NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct auth_session_info **_session_info);
|
||||
/* Produce a session_info for an arbitary DN or principal in the local
|
||||
* DB, assuming the local DB holds all the groups
|
||||
*
|
||||
* Supply either a principal or a DN
|
||||
*/
|
||||
NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct ldb_context *sam_ctx,
|
||||
const char *principal,
|
||||
struct ldb_dn *user_dn,
|
||||
uint32_t session_info_flags,
|
||||
struct auth_session_info **session_info);
|
||||
|
||||
struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
|
||||
struct loadparm_context *lp_ctx);
|
||||
|
@ -48,7 +48,7 @@ bld.SAMBA_SUBSYSTEM('auth_sam_reply',
|
||||
bld.SAMBA_PYTHON('pyauth',
|
||||
source='pyauth.c',
|
||||
public_deps='auth_system_session',
|
||||
deps='samdb pytalloc-util pyparam_util',
|
||||
deps='samdb pytalloc-util pyparam_util pyldb-util',
|
||||
realname='samba/auth.so'
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user