summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/ntlm/auth_sam.c87
-rw-r--r--source4/auth/pyauth.c64
-rw-r--r--source4/auth/sam.c84
-rw-r--r--source4/auth/session.c39
-rw-r--r--source4/auth/session.h14
-rw-r--r--source4/auth/wscript_build2
6 files changed, 209 insertions, 81 deletions
diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index 259efec8e5..645713286d 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -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,
diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c
index 2ef5ebb882..f8bf4d9862 100644
--- a/source4/auth/pyauth.c
+++ b/source4/auth/pyauth.c
@@ -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 },
};
diff --git a/source4/auth/sam.c b/source4/auth/sam.c
index fcb125660b..0a97d81b82 100644
--- a/source4/auth/sam.c
+++ b/source4/auth/sam.c
@@ -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;
+}
diff --git a/source4/auth/session.c b/source4/auth/session.c
index c4bd351b0e..124fdb989b 100644
--- a/source4/auth/session.c
+++ b/source4/auth/session.c
@@ -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.
*/
diff --git a/source4/auth/session.h b/source4/auth/session.h
index 39c818fbf2..caedbc8028 100644
--- a/source4/auth/session.h
+++ b/source4/auth/session.h
@@ -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);
diff --git a/source4/auth/wscript_build b/source4/auth/wscript_build
index 700a4a9ae4..0111774d2e 100644
--- a/source4/auth/wscript_build
+++ b/source4/auth/wscript_build
@@ -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'
)