s4-auth Add function to obtain any user's session_info from a given LDB
authorAndrew Bartlett <abartlet@samba.org>
Wed, 22 Dec 2010 06:17:07 +0000 (17:17 +1100)
committerAndrew Tridgell <tridge@samba.org>
Fri, 14 Jan 2011 05:39:32 +0000 (16:39 +1100)
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

source4/auth/ntlm/auth_sam.c
source4/auth/pyauth.c
source4/auth/sam.c
source4/auth/session.c
source4/auth/session.h
source4/auth/wscript_build

index 259efec8e5b9af06dcd44162782b095aae39153c..645713286d0034b192c93b9f87bb8109b01c9c3b 100644 (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,
index 2ef5ebb8829160afc0f6c505ed404ac4b837fd51..f8bf4d9862948bb790f5b9a537878af170527484 100644 (file)
 
 #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 },
 };
 
index fcb125660b30ff51d72aaf5471cdb6581d8e962a..0a97d81b8284e792de9270f82c18b5f4c7a638c0 100644 (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;
+}
index c4bd351b0e52ba22cd243f385583deddfe191db3..124fdb989b860c83436e291b29b0a14a49af1252 100644 (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.
  */
index 39c818fbf23c75d4781ce358a23abaf8f735ab12..caedbc802885af04c546eef5d303eaed309bf426 100644 (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);
index 700a4a9ae4db418f16fcfd6222ccbcc539b6c8dd..0111774d2e9054d49428236da006062d3aed7b6f 100644 (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'
        )