1
0
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:
Andrew Bartlett
2010-12-22 17:17:07 +11:00
committed by Andrew Tridgell
parent c82269cf86
commit ece6eae4d8
6 changed files with 209 additions and 81 deletions

View File

@ -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,

View File

@ -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 },
};

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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);

View File

@ -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'
)