The branch, master has been updated via 916cc7b s4-dsdb Add PAC validation test to tokengroups test. via 6d93af4 s4-pyauth Fix AuthContext wrapper via a7e238d s4-auth Allow NULL methods to be specified to auth_context_create_methods() via 75835d3 s4-dsdb Add a test of the tokenGroups behaviour on the user's DN. via 902e183 s4-gensec Remove special case 'for SASL' that is not required any more. from b42afa0 tdb: Added doxygen documentation.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 916cc7be85f08c4781c93417af69420b29b5783e Author: Andrew Bartlett <abart...@samba.org> Date: Wed Jan 19 22:29:49 2011 +1100 s4-dsdb Add PAC validation test to tokengroups test. This confirms that the groups obtained from a Kerberos PAC match those that a manual search of a target LDAP server would reveal. This should allow mixing of a KDC specified by krb5.conf to test Samba or Windows alternatly. Andrew Bartlett Autobuild-User: Andrew Bartlett <abart...@samba.org> Autobuild-Date: Wed Jan 19 13:13:48 CET 2011 on sn-devel-104 commit 6d93af433ebda866bfa8af04621d9c7f189d11e0 Author: Andrew Bartlett <abart...@samba.org> Date: Wed Jan 19 22:29:08 2011 +1100 s4-pyauth Fix AuthContext wrapper commit a7e238d3227347fa8ebcb5813d6a1811f038670f Author: Andrew Bartlett <abart...@samba.org> Date: Wed Jan 19 22:27:51 2011 +1100 s4-auth Allow NULL methods to be specified to auth_context_create_methods() This allows us to init an auth context that isn't going to do any NTLM authentication, but is used by other subsystems. Andrew Bartlett commit 75835d3f2fc445beae93e462b05d6fa1914815c0 Author: Andrew Bartlett <abart...@samba.org> Date: Wed Jan 19 14:55:36 2011 +1100 s4-dsdb Add a test of the tokenGroups behaviour on the user's DN. Andrew Bartlett commit 902e18329f7f7ed7b38f0596f5a6368c7d0cd9ac Author: Andrew Bartlett <abart...@samba.org> Date: Wed Jan 19 14:54:36 2011 +1100 s4-gensec Remove special case 'for SASL' that is not required any more. I've examined the code paths involved, and it appears an alternative fix has been made in the ldap_server/ldap_bind.c code, and there is no code path that uses this behaviour. Andrew Bartlett ----------------------------------------------------------------------- Summary of changes: source4/auth/gensec/gensec_gssapi.c | 13 ---- source4/auth/ntlm/auth.c | 17 +---- source4/auth/pyauth.c | 15 ++++- source4/dsdb/tests/python/token_group.py | 106 +++++++++++++++++++++++++---- source4/selftest/tests.py | 2 +- 5 files changed, 108 insertions(+), 45 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index e807f77..132ea7d 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -535,19 +535,6 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, /* We may have been invoked as SASL, so there * is more work to do */ if (gensec_gssapi_state->sasl) { - /* Due to a very subtle interaction - * with SASL and the LDAP libs, we - * must ensure the data pointer is - * != NULL, but the length is 0. - * - * This ensures we send a 'zero - * length' (rather than NULL) response - */ - - if (!out->data) { - out->data = (uint8_t *)talloc_strdup(out_mem_ctx, "\0"); - } - gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG; return NT_STATUS_MORE_PROCESSING_REQUIRED; } else { diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 7f355d7..1a98fb4 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -122,12 +122,10 @@ _PUBLIC_ NTSTATUS auth_get_server_info_principal(TALLOC_CTX *mem_ctx, continue; } - NT_STATUS_NOT_OK_RETURN(nt_status); - - break; + return nt_status; } - return NT_STATUS_OK; + return NT_STATUS_NOT_IMPLEMENTED; } /** @@ -437,11 +435,6 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** auth_init(); - if (!methods) { - DEBUG(0,("auth_context_create: No auth method list!?\n")); - return NT_STATUS_INTERNAL_ERROR; - } - if (!ev) { DEBUG(0,("auth_context_create: called with out event context\n")); return NT_STATUS_INTERNAL_ERROR; @@ -463,7 +456,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** ctx->sam_ctx = samdb_connect(ctx, ctx->event_ctx, ctx->lp_ctx, system_session(ctx->lp_ctx), 0); } - for (i=0; methods[i] ; i++) { + for (i=0; methods && methods[i] ; i++) { struct auth_method_context *method; method = talloc(ctx, struct auth_method_context); @@ -480,10 +473,6 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** DLIST_ADD_END(ctx->methods, method, struct auth_method_context *); } - if (!ctx->methods) { - return NT_STATUS_INTERNAL_ERROR; - } - ctx->check_password = auth_check_password; ctx->get_challenge = auth_get_challenge; ctx->set_challenge = auth_context_set_challenge; diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c index a603053..26de2c3 100644 --- a/source4/auth/pyauth.c +++ b/source4/auth/pyauth.c @@ -269,7 +269,7 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec PyObject *py_methods = Py_None; TALLOC_CTX *mem_ctx; struct auth_context *auth_context; - struct messaging_context *messaging_context; + struct messaging_context *messaging_context = NULL; struct loadparm_context *lp_ctx; struct tevent_context *ev; struct ldb_context *ldb; @@ -301,7 +301,9 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec return NULL; } - messaging_context = py_talloc_get_type(py_messaging_ctx, struct messaging_context); + if (py_messaging_ctx != Py_None) { + messaging_context = py_talloc_get_type(py_messaging_ctx, struct messaging_context); + } if (py_methods == Py_None && py_ldb == Py_None) { nt_status = auth_context_create(mem_ctx, ev, messaging_context, lp_ctx, &auth_context); @@ -370,6 +372,13 @@ void initauth(void) if (PyType_Ready(&PyAuthSession) < 0) return; + PyAuthContext.tp_base = PyTalloc_GetObjectType(); + if (PyAuthContext.tp_base == NULL) + return; + + if (PyType_Ready(&PyAuthContext) < 0) + return; + m = Py_InitModule3("auth", py_auth_methods, "Authentication and authorization support."); if (m == NULL) @@ -377,6 +386,8 @@ void initauth(void) Py_INCREF(&PyAuthSession); PyModule_AddObject(m, "AuthSession", (PyObject *)&PyAuthSession); + Py_INCREF(&PyAuthContext); + PyModule_AddObject(m, "AuthContext", (PyObject *)&PyAuthContext); #define ADD_FLAG(val) PyModule_AddObject(m, #val, PyInt_FromLong(val)) ADD_FLAG(AUTH_SESSION_INFO_DEFAULT_GROUPS); diff --git a/source4/dsdb/tests/python/token_group.py b/source4/dsdb/tests/python/token_group.py index ee90dd4..a35f183 100755 --- a/source4/dsdb/tests/python/token_group.py +++ b/source4/dsdb/tests/python/token_group.py @@ -16,10 +16,14 @@ import samba.getopt as options from samba.auth import system_session from samba import ldb from samba.samdb import SamDB +from samba.auth import AuthContext from samba.ndr import ndr_pack, ndr_unpack +from samba import gensec +from samba.credentials import Credentials from subunit.run import SubunitTestRunner import unittest +import samba.tests from samba.dcerpc import security from samba.auth import AUTH_SESSION_INFO_DEFAULT_GROUPS, AUTH_SESSION_INFO_AUTHENTICATED, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES @@ -43,14 +47,30 @@ url = args[0] lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) -class TokenTest(unittest.TestCase): +class TokenTest(samba.tests.TestCase): def setUp(self): super(TokenTest, self).setUp() self.ldb = samdb self.base_dn = samdb.domain_dn() - def test_TokenGroups(self): + res = self.ldb.search("", scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) + self.assertEquals(len(res), 1) + + self.user_sid_dn = "<SID=%s>" % str(ndr_unpack(samba.dcerpc.security.dom_sid, res[0]["tokenGroups"][0])) + + session_info_flags = ( AUTH_SESSION_INFO_DEFAULT_GROUPS | + AUTH_SESSION_INFO_AUTHENTICATED | + AUTH_SESSION_INFO_SIMPLE_PRIVILEGES) + session = samba.auth.user_session(self.ldb, lp_ctx=lp, dn=self.user_sid_dn, + session_info_flags=session_info_flags) + + token = session.security_token + self.user_sids = [] + for s in token.sids: + self.user_sids.append(str(s)) + + def test_rootDSE_tokenGroups(self): """Testing rootDSE tokengroups against internal calculation""" if not url.startswith("ldap"): self.fail(msg="This test is only valid on ldap") @@ -63,26 +83,82 @@ class TokenTest(unittest.TestCase): for sid in res[0]['tokenGroups']: tokengroups.append(str(ndr_unpack(samba.dcerpc.security.dom_sid, sid))) - print("Geting token from user session") - session_info_flags = ( AUTH_SESSION_INFO_DEFAULT_GROUPS | - AUTH_SESSION_INFO_AUTHENTICATED | - AUTH_SESSION_INFO_SIMPLE_PRIVILEGES) - session = samba.auth.user_session(self.ldb, lp_ctx=lp, dn="<SID=%s>" % tokengroups[0], - session_info_flags=session_info_flags) + sidset1 = set(tokengroups) + sidset2 = set(self.user_sids) + if len(sidset1.difference(sidset2)): + print("token sids don't match") + print("tokengroups: %s" % tokengroups) + print("calculated : %s" % self.user_sids); + print("difference : %s" % sidset1.difference(sidset2)) + self.fail(msg="calculated groups don't match against rootDSE tokenGroups") + + def test_dn_tokenGroups(self): + print("Geting tokenGroups from user DN") + res = self.ldb.search(self.user_sid_dn, scope=ldb.SCOPE_BASE, attrs=["tokenGroups"]) + self.assertEquals(len(res), 1) + + dn_tokengroups = [] + for sid in res[0]['tokenGroups']: + dn_tokengroups.append(str(ndr_unpack(samba.dcerpc.security.dom_sid, sid))) + + sidset1 = set(dn_tokengroups) + sidset2 = set(self.user_sids) + if len(sidset1.difference(sidset2)): + print("token sids don't match") + print("tokengroups: %s" % tokengroups) + print("calculated : %s" % sids); + print("difference : %s" % sidset1.difference(sidset2)) + self.fail(msg="calculated groups don't match against user DN tokenGroups") + + def test_pac_groups(self): + settings = {} + settings["lp_ctx"] = lp + settings["target_hostname"] = lp.get("netbios name") + + gensec_client = gensec.Security.start_client(settings) + gensec_client.set_credentials(creds) + gensec_client.want_feature(gensec.FEATURE_SEAL) + gensec_client.start_mech_by_sasl_name("GSSAPI") + + auth_context = AuthContext(lp_ctx=lp, ldb=self.ldb, methods=[]) + + gensec_server = gensec.Security.start_server(settings, auth_context) + machine_creds = Credentials() + machine_creds.guess(lp) + machine_creds.set_machine_account(lp) + gensec_server.set_credentials(machine_creds) + + gensec_server.want_feature(gensec.FEATURE_SEAL) + gensec_server.start_mech_by_sasl_name("GSSAPI") + + client_finished = False + server_finished = False + server_to_client = None + + """Run the actual call loop""" + while client_finished == False and server_finished == False: + if not client_finished: + print "running client gensec_update" + (client_finished, client_to_server) = gensec_client.update(server_to_client) + if not server_finished: + print "running server gensec_update" + (server_finished, server_to_client) = gensec_server.update(client_to_server) + + session = gensec_server.session_info() token = session.security_token - sids = [] + pac_sids = [] for s in token.sids: - sids.append(str(s)) - sidset1 = set(tokengroups) - sidset2 = set(sids) - if sidset1 != sidset2: + pac_sids.append(str(s)) + + sidset1 = set(pac_sids) + sidset2 = set(self.user_sids) + if len(sidset1.difference(sidset2)): print("token sids don't match") print("tokengroups: %s" % tokengroups) print("calculated : %s" % sids); print("difference : %s" % sidset1.difference(sidset2)) - self.fail(msg="token groups don't match") - + self.fail(msg="calculated groups don't match against user PAC tokenGroups") if not "://" in url: diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 413d86d..6e2ade1 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -499,7 +499,7 @@ planpythontestsuite("none", "subunit") planpythontestsuite("dc:local", "samba.tests.dcerpc.rpcecho") plantestsuite_idlist("samba.tests.dcerpc.registry", "dc:local", [subunitrun, "$LISTOPT", '-U"$USERNAME%$PASSWORD"', "samba.tests.dcerpc.registry"]) plantestsuite("samba4.ldap.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '-W', '$DOMAIN']) -plantestsuite("samba4.tokengroups.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '-W', '$DOMAIN']) +plantestsuite("samba4.tokengroups.python(dc)", "dc:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/token_group.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '-W', '$DOMAIN']) plantestsuite("samba4.sam.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/sam.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '-W', '$DOMAIN']) plansambapythontestsuite("samba4.schemaInfo.python(dc)", "dc", os.path.join(samba4srcdir, 'dsdb/tests/python'), 'dsdb_schema_info', extra_args=['-U"$DOMAIN/$DC_USERNAME%$DC_PASSWORD"']) plantestsuite("samba4.urgent_replication.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/urgent_replication.py"), '$PREFIX_ABS/dc/private/sam.ldb'], allow_empty_output=True) -- Samba Shared Repository