From bb4e9d72dd7de46ae4635ff5fbe5427b2a93e7cc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 2 Oct 2008 19:31:56 +0200 Subject: s4:blackbox/test_ldb: test search by and metze --- testprogs/blackbox/test_ldb.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/testprogs/blackbox/test_ldb.sh b/testprogs/blackbox/test_ldb.sh index 1774dbc7a3..5209abeb2c 100755 --- a/testprogs/blackbox/test_ldb.sh +++ b/testprogs/blackbox/test_ldb.sh @@ -180,4 +180,29 @@ if [ x"$st" != x"0" ]; then failed=`expr $failed + $st` fi +echo "Getting HEX GUID/SID of $BASEDN" +HEXDN=`bin/ldbsearch $CONFIGURATION $options -b "$BASEDN" -H $p://$SERVER -s base "(objectClass=*)" --controls=extended_dn:1:0 | grep 'dn: ' | cut -d ' ' -f2-` +HEXGUID=`echo "$HEXDN" | cut -d ';' -f1` +HEXSID=`echo "$HEXDN" | cut -d ';' -f2` +echo "HEXGUID[$HEXGUID]" +echo "HEXSID[$HEXSID]" + +echo "Getting STR GUID/SID of $BASEDN" +STRDN=`bin/ldbsearch $CONFIGURATION $options -b "$BASEDN" -H $p://$SERVER -s base "(objectClass=*)" --controls=extended_dn:1:1 | grep 'dn: ' | cut -d ' ' -f2-` +echo "STRDN: $STRDN" +STRGUID=`echo "$STRDN" | cut -d ';' -f1` +STRSID=`echo "$STRDN" | cut -d ';' -f2` +echo "STRGUID[$STRGUID]" +echo "STRSID[$STRSID]" + +SPECIALDNS="$HEXGUID $HEXSID $STRGUID $STRSID" +for SPDN in $SPECIALDNS; do + echo "Search for $SPDN" + nentries=`bin/ldbsearch $options $CONFIGURATION -H $p://$SERVER -s base -b "$SPDN" '(objectClass=*)' | grep "dn: $BASEDN" | wc -l` + if [ $nentries -lt 1 ]; then + echo "Special search returned 0 items" + failed=`expr $failed + 1` + fi +done + exit $failed -- cgit From f3ba7fc0b973ea66ee57fe0e1be73b3bcefc07fb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 22 Sep 2008 19:23:21 +0200 Subject: Store a local schannel key in secrets.tdb --- source3/include/proto.h | 2 ++ source3/include/secrets.h | 2 ++ source3/passdb/secrets.c | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 7cdcba19ab..41544da8c9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6421,6 +6421,8 @@ bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx, struct dcinfo **ppdc); bool secrets_store_generic(const char *owner, const char *key, const char *secret); char *secrets_fetch_generic(const char *owner, const char *key); +bool secrets_store_local_schannel_key(uint8_t schannel_key[16]); +bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16]); /* The following definitions come from passdb/util_builtin.c */ diff --git a/source3/include/secrets.h b/source3/include/secrets.h index d9f457558b..3c8e2ccf81 100644 --- a/source3/include/secrets.h +++ b/source3/include/secrets.h @@ -45,6 +45,8 @@ #define SECRETS_LDAP_BIND_PW "SECRETS/LDAP_BIND_PW" +#define SECRETS_LOCAL_SCHANNEL_KEY "SECRETS/LOCAL_SCHANNEL_KEY" + /* Authenticated user info is stored in secrets.tdb under these keys */ #define SECRETS_AUTH_USER "SECRETS/AUTH_USER" diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 4527ae7127..306d4d0a35 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -259,6 +259,31 @@ bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid) return True; } +bool secrets_store_local_schannel_key(uint8_t schannel_key[16]) +{ + return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY, schannel_key, 16); +} + +bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16]) +{ + size_t size = 0; + uint8_t *key; + + key = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY, &size); + if (key == NULL) { + return false; + } + + if (size != 16) { + SAFE_FREE(key); + return false; + } + + memcpy(schannel_key, key, 16); + SAFE_FREE(key); + return true; +} + /** * Form a key for fetching the machine trust account sec channel type * -- cgit From 2f6026248ec9a84f6a263622f1753e98c89eb543 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 22 Sep 2008 19:24:59 +0200 Subject: Add dyn_NCALRPCDIR --- source3/Makefile.in | 2 ++ source3/dynconfig.c | 1 + source3/include/dynconfig.h | 4 ++++ source3/m4/check_path.m4 | 19 +++++++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/source3/Makefile.in b/source3/Makefile.in index 61e946e7cd..1bb2b87a4a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -127,6 +127,7 @@ LOGFILEBASE = @logfilebase@ CONFIGFILE = $(CONFIGDIR)/smb.conf LMHOSTSFILE = $(CONFIGDIR)/lmhosts CTDBDIR = @ctdbdir@ +NCALRPCDIR = @ncalrpcdir@ # This is where smbpasswd et al go PRIVATEDIR = @privatedir@ @@ -166,6 +167,7 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ -DLOGFILEBASE=\"$(LOGFILEBASE)\" \ -DSHLIBEXT=\"@SHLIBEXT@\" \ -DCTDBDIR=\"$(CTDBDIR)\" \ + -DNCALRPCDIR=\"$(NCALRPCDIR)\" \ -DCONFIGDIR=\"$(CONFIGDIR)\" \ -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \ -DCACHEDIR=\"$(CACHEDIR)\" \ diff --git a/source3/dynconfig.c b/source3/dynconfig.c index 3a54507599..6125f9944c 100644 --- a/source3/dynconfig.c +++ b/source3/dynconfig.c @@ -77,6 +77,7 @@ DEFINE_DYN_CONFIG_PARAM(MODULESDIR) DEFINE_DYN_CONFIG_PARAM(SHLIBEXT) DEFINE_DYN_CONFIG_PARAM(LOCKDIR) DEFINE_DYN_CONFIG_PARAM(PIDDIR) +DEFINE_DYN_CONFIG_PARAM(NCALRPCDIR) DEFINE_DYN_CONFIG_PARAM(SMB_PASSWD_FILE) DEFINE_DYN_CONFIG_PARAM(PRIVATE_DIR) diff --git a/source3/include/dynconfig.h b/source3/include/dynconfig.h index 758bde33cc..8267064f23 100644 --- a/source3/include/dynconfig.h +++ b/source3/include/dynconfig.h @@ -71,6 +71,10 @@ const char *get_dyn_PIDDIR(void); const char *set_dyn_PIDDIR(const char *newpath); bool is_default_dyn_PIDDIR(void); +const char *get_dyn_NCALRPCDIR(void); +const char *set_dyn_NCALRPCDIR(const char *newpath); +bool is_default_dyn_NCALRPCDIR(void); + const char *get_dyn_SMB_PASSWD_FILE(void); const char *set_dyn_SMB_PASSWD_FILE(const char *newpath); bool is_default_dyn_SMB_PASSWD_FILE(void); diff --git a/source3/m4/check_path.m4 b/source3/m4/check_path.m4 index 7aa8c213e0..40a97d3674 100644 --- a/source3/m4/check_path.m4 +++ b/source3/m4/check_path.m4 @@ -18,6 +18,7 @@ AC_PREFIX_DEFAULT(/usr/local/samba) rootsbindir="\${SBINDIR}" lockdir="\${VARDIR}/locks" piddir="\${VARDIR}/locks" +ncalrpcdir="\${VARDIR}/ncalrpc" test "${mandir}" || mandir="\${prefix}/man" logfilebase="\${VARDIR}" privatedir="\${prefix}/private" @@ -46,6 +47,7 @@ AC_ARG_WITH(fhs, codepagedir="\${MODULESDIR}" statedir="\${VARDIR}/lib/samba" cachedir="\${VARDIR}/lib/samba" + ncalrpcdir="\${VARDIR}/ncalrpc" AC_DEFINE(FHS_COMPATIBLE, 1, [Whether to use fully FHS-compatible paths]) ;; esac]) @@ -114,6 +116,22 @@ AC_ARG_WITH(piddir, ;; esac]) +################################################# +# set ncalrpc directory location +AC_ARG_WITH(ncalprcdir, +[AS_HELP_STRING([--with-ncalprcdir=DIR], [Where to put ncalrpc sockets ($ac_default_prefix/var/ncalrpc)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-ncalrpcdir called without argument - will use default]) + ;; + * ) + ncalrpcdir="$withval" + ;; + esac]) + ################################################# # set SWAT directory location AC_ARG_WITH(swatdir, @@ -227,6 +245,7 @@ AC_ARG_WITH(mandir, AC_SUBST(configdir) AC_SUBST(lockdir) AC_SUBST(piddir) +AC_SUBST(ncalrpcdir) AC_SUBST(logfilebase) AC_SUBST(ctdbdir) AC_SUBST(privatedir) -- cgit From 439086099ad97a49c93102af1e6edafabea64b6f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 22 Sep 2008 19:29:05 +0200 Subject: Add netlogond auth method This authenticates against a local running samba4 using SamLogonEx. We retrieve the machine password using samba4's mymachinepwd script and store the schannel key for re-use in secrets.tdb. --- source3/Makefile.in | 5 + source3/auth/auth_netlogond.c | 321 ++++++++++++++++++++++++++++++++++++++++++ source3/configure.in | 3 +- source3/include/proto.h | 2 + 4 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 source3/auth/auth_netlogond.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 1bb2b87a4a..eb6a05cba5 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -638,6 +638,7 @@ AUTH_SERVER_OBJ = auth/auth_server.o AUTH_UNIX_OBJ = auth/auth_unix.o AUTH_WINBIND_OBJ = auth/auth_winbind.o AUTH_SCRIPT_OBJ = auth/auth_script.o +AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/token_util.o \ auth/auth_compat.o auth/auth_ntlmssp.o \ @@ -2197,6 +2198,10 @@ bin/script.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_SCRIPT_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(AUTH_SCRIPT_OBJ) +bin/netlogond.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_NETLOGOND_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(AUTH_NETLOGOND_OBJ) + bin/smbserver.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_SERVER_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(AUTH_SERVER_OBJ) diff --git a/source3/auth/auth_netlogond.c b/source3/auth/auth_netlogond.c new file mode 100644 index 0000000000..a57f3b74a3 --- /dev/null +++ b/source3/auth/auth_netlogond.c @@ -0,0 +1,321 @@ +/* + Unix SMB/CIFS implementation. + Authenticate against a netlogon pipe listening on a unix domain socket + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx, + const struct auth_context *auth_context, + const char *ncalrpc_sockname, + uint8_t schannel_key[16], + const auth_usersupplied_info *user_info, + struct netr_SamInfo3 **pinfo3, + NTSTATUS *schannel_bind_result) +{ + struct rpc_pipe_client *p; + struct cli_pipe_auth_data *auth; + struct netr_SamInfo3 *info3 = NULL; + NTSTATUS status; + + *schannel_bind_result = NT_STATUS_OK; + + status = rpc_pipe_open_ncalrpc(talloc_tos(), ncalrpc_sockname, + &ndr_table_netlogon.syntax_id, &p); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("rpc_pipe_open_ncalrpc failed: %s\n", + nt_errstr(status))); + return status; + } + + status = rpccli_schannel_bind_data(p, lp_workgroup(), + PIPE_AUTH_LEVEL_PRIVACY, + schannel_key, &auth); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("rpccli_schannel_bind_data failed: %s\n", + nt_errstr(status))); + TALLOC_FREE(p); + return status; + } + + status = rpc_pipe_bind(p, auth); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("rpc_pipe_bind failed: %s\n", nt_errstr(status))); + TALLOC_FREE(p); + *schannel_bind_result = status; + return status; + } + + /* + * We have to fake a struct dcinfo, so that + * rpccli_netlogon_sam_network_logon_ex can decrypt the session keys. + */ + + p->dc = talloc(p, struct dcinfo); + if (p->dc == NULL) { + DEBUG(0, ("talloc failed\n")); + TALLOC_FREE(p); + return NT_STATUS_NO_MEMORY; + } + + memcpy(p->dc->sess_key, schannel_key, 16); + + status = rpccli_netlogon_sam_network_logon_ex( + p, p, + user_info->logon_parameters,/* flags such as 'allow + * workstation logon' */ + global_myname(), /* server name */ + user_info->smb_name, /* user name logging on. */ + user_info->client_domain, /* domain name */ + user_info->wksta_name, /* workstation name */ + (uchar *)auth_context->challenge.data, /* 8 byte challenge. */ + user_info->lm_resp, /* lanman 24 byte response */ + user_info->nt_resp, /* nt 24 byte response */ + &info3); /* info3 out */ + + DEBUG(10, ("rpccli_netlogon_sam_network_logon_ex returned %s\n", + nt_errstr(status))); + + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(p); + return status; + } + + *pinfo3 = talloc_move(mem_ctx, &info3); + + TALLOC_FREE(p); + return NT_STATUS_OK; +} + +static char *mymachinepw(TALLOC_CTX *mem_ctx) +{ + fstring pwd; + const char *script; + char *to_free = NULL; + ssize_t nread; + int ret, fd; + + script = lp_parm_const_string( + GLOBAL_SECTION_SNUM, "auth_netlogond", "machinepwscript", + NULL); + + if (script == NULL) { + to_free = talloc_asprintf(talloc_tos(), "%s/%s", + get_dyn_SBINDIR(), "mymachinepw"); + script = to_free; + } + if (script == NULL) { + return NULL; + } + + ret = smbrun(script, &fd); + DEBUG(ret ? 0 : 3, ("mymachinepw: Running the command `%s' gave %d\n", + script, ret)); + TALLOC_FREE(to_free); + + if (ret != 0) { + return NULL; + } + + pwd[sizeof(pwd)-1] = '\0'; + + nread = read(fd, pwd, sizeof(pwd)-1); + close(fd); + + if (nread <= 0) { + DEBUG(3, ("mymachinepwd: Could not read password\n")); + return NULL; + } + + DEBUG(0, ("pwd: %d [%s]\n", (int)nread, pwd)); + + if (pwd[nread-1] == '\n') { + pwd[nread-1] = '\0'; + } + + return talloc_strdup(mem_ctx, pwd); +} + +static NTSTATUS check_netlogond_security(const struct auth_context *auth_context, + void *my_private_data, + TALLOC_CTX *mem_ctx, + const auth_usersupplied_info *user_info, + auth_serversupplied_info **server_info) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct netr_SamInfo3 *info3 = NULL; + struct rpc_pipe_client *p; + struct cli_pipe_auth_data *auth; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; + char *plaintext_machinepw; + uint8_t machine_password[16]; + uint8_t schannel_key[16]; + NTSTATUS schannel_bind_result, status; + struct named_mutex *mutex; + const char *ncalrpcsock; + + ncalrpcsock = lp_parm_const_string( + GLOBAL_SECTION_SNUM, "auth_netlogond", "socket", NULL); + + if (ncalrpcsock == NULL) { + ncalrpcsock = talloc_asprintf(talloc_tos(), "%s/%s", + get_dyn_NCALRPCDIR(), "DEFAULT"); + } + + if (ncalrpcsock == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + if (!secrets_fetch_local_schannel_key(schannel_key)) { + goto new_key; + } + + status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock, + schannel_key, user_info, &info3, + &schannel_bind_result); + + DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status))); + + if (NT_STATUS_IS_OK(status)) { + goto okay; + } + + if (NT_STATUS_IS_OK(schannel_bind_result)) { + /* + * This is a real failure from the DC + */ + goto done; + } + + new_key: + + mutex = grab_named_mutex(talloc_tos(), "LOCAL_SCHANNEL_KEY", 60); + if (mutex == NULL) { + DEBUG(10, ("Could not get mutex LOCAL_SCHANNEL_KEY\n")); + status = NT_STATUS_ACCESS_DENIED; + goto done; + } + + DEBUG(10, ("schannel bind failed, setting up new key\n")); + + status = rpc_pipe_open_ncalrpc(talloc_tos(), ncalrpcsock, + &ndr_table_netlogon.syntax_id, &p); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("rpc_pipe_open_ncalrpc failed: %s\n", + nt_errstr(status))); + goto done; + } + + status = rpccli_anon_bind_data(p, &auth); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("rpccli_anon_bind_data failed: %s\n", + nt_errstr(status))); + goto done; + } + + status = rpc_pipe_bind(p, auth); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("rpc_pipe_bind failed: %s\n", nt_errstr(status))); + goto done; + } + + TALLOC_FREE(auth); + + plaintext_machinepw = mymachinepw(talloc_tos()); + if (plaintext_machinepw == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + E_md4hash(plaintext_machinepw, machine_password); + + TALLOC_FREE(plaintext_machinepw); + + status = rpccli_netlogon_setup_creds( + p, global_myname(), lp_workgroup(), global_myname(), + global_myname(), machine_password, SEC_CHAN_BDC, &neg_flags); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("rpccli_netlogon_setup_creds failed: %s\n", + nt_errstr(status))); + goto done; + } + + memcpy(schannel_key, p->dc->sess_key, 16); + secrets_store_local_schannel_key(schannel_key); + + TALLOC_FREE(p); + + /* + * Retry the authentication with the mutex held. This way nobody else + * can step on our toes. + */ + + status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock, + schannel_key, user_info, &info3, + &schannel_bind_result); + + DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status))); + + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + okay: + + status = make_server_info_info3(mem_ctx, user_info->smb_name, + user_info->domain, server_info, + info3); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("make_server_info_info3 failed: %s\n", + nt_errstr(status))); + TALLOC_FREE(frame); + return status; + } + + status = NT_STATUS_OK; + + done: + TALLOC_FREE(frame); + return status; +} + +/* module initialisation */ +static NTSTATUS auth_init_netlogond(struct auth_context *auth_context, + const char *param, + auth_methods **auth_method) +{ + if (!make_auth_methods(auth_context, auth_method)) { + return NT_STATUS_NO_MEMORY; + } + + (*auth_method)->name = "netlogond"; + (*auth_method)->auth = check_netlogond_security; + return NT_STATUS_OK; +} + +NTSTATUS auth_netlogond_init(void) +{ + smb_register_auth(AUTH_INTERFACE_VERSION, "netlogond", + auth_init_netlogond); + return NT_STATUS_OK; +} diff --git a/source3/configure.in b/source3/configure.in index 545a5653de..1eba4a0a58 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -404,7 +404,7 @@ AC_SUBST(DYNEXP) dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl2 rpc_ntsvcs2 rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin vfs_default nss_info_template" +default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl2 rpc_ntsvcs2 rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_acl_xattr vfs_smb_traffic_analyzer" @@ -6077,6 +6077,7 @@ SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH) SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH) SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH) SMB_MODULE(auth_script, \$(AUTH_SCRIPT_OBJ), "bin/script.$SHLIBEXT", AUTH) +SMB_MODULE(auth_netlogond, \$(AUTH_NETLOGOND_OBJ), "bin/netlogond.$SHLIBEXT", AUTH) SMB_SUBSYSTEM(AUTH,auth/auth.o) SMB_MODULE(vfs_default, \$(VFS_DEFAULT_OBJ), "bin/default.$SHLIBEXT", VFS) diff --git a/source3/include/proto.h b/source3/include/proto.h index 41544da8c9..30e309cd4e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -46,6 +46,8 @@ bool password_ok(const char *smb_name, DATA_BLOB password_blob); void attempt_machine_password_change(void); NTSTATUS auth_domain_init(void); +NTSTATUS auth_netlogond_init(void); + /* The following definitions come from auth/auth_ntlmssp.c */ NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state); -- cgit From 6aa8613b11b596fed115849262e96524b84a8fbe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 6 Oct 2008 10:57:13 +0200 Subject: Log in the parent winbind log where a request is going --- source3/winbindd/winbindd_dual.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 1600f05eb1..f6a9c1f26d 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -120,6 +120,10 @@ void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, SMB_ASSERT(continuation != NULL); + DEBUG(10, ("Sending request to child pid %d (domain=%s)\n", + (int)child->pid, + (child->domain != NULL) ? child->domain->name : "''")); + state = TALLOC_P(mem_ctx, struct winbindd_async_request); if (state == NULL) { -- cgit From f4095b62a8030cb9d929bb113f3488f3917b8f9b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 6 Oct 2008 14:49:10 +0200 Subject: If name_to_fqdn fails, retry with the dns domain the DC gave us This is a workaround for the cases where you want to join under a netbios name that is different from your hostname, i.e. a name that can not be found in /etc/hosts or dns. In these cases, name_to_fqdn fails or gives invalid results. --- source3/libnet/libnet_join.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index a39dee676f..ab8af0be6b 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -357,10 +357,15 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, strupper_m(spn); spn_array[0] = spn; - if (name_to_fqdn(my_fqdn, r->in.machine_name) && - !strequal(my_fqdn, r->in.machine_name)) { + if (!name_to_fqdn(my_fqdn, r->in.machine_name) + || (strchr(my_fqdn, '.') == NULL)) { + fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, + r->out.dns_domain_name); + } + + strlower_m(my_fqdn); - strlower_m(my_fqdn); + if (!strequal(my_fqdn, r->in.machine_name)) { spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn); if (!spn) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); -- cgit From 999b69d176a967aad8b6a871632d1869757181aa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Oct 2008 02:27:09 +0200 Subject: s4:gensec: pass down want_features to the spnego backend mech metze --- source4/auth/gensec/gensec.c | 8 +++++++- source4/auth/gensec/gensec.h | 2 ++ source4/auth/gensec/spnego.c | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index 0edb34d740..5d57383d2a 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -490,6 +490,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, NT_STATUS_HAVE_NO_MEMORY(*gensec_security); (*gensec_security)->ops = NULL; + (*gensec_security)->private_data = NULL; ZERO_STRUCT((*gensec_security)->target); ZERO_STRUCT((*gensec_security)->peer_addr); @@ -525,6 +526,7 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, (*gensec_security)->private_data = NULL; (*gensec_security)->subcontext = true; + (*gensec_security)->want_features = parent->want_features; (*gensec_security)->event_ctx = parent->event_ctx; (*gensec_security)->msg_ctx = parent->msg_ctx; (*gensec_security)->lp_ctx = parent->lp_ctx; @@ -1015,7 +1017,11 @@ _PUBLIC_ NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_C _PUBLIC_ void gensec_want_feature(struct gensec_security *gensec_security, uint32_t feature) { - gensec_security->want_features |= feature; + if (!gensec_security->ops || !gensec_security->ops->want_feature) { + gensec_security->want_features |= feature; + return; + } + gensec_security->ops->want_feature(gensec_security, feature); } /** diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index 84fc26d127..0b31882ddd 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -133,6 +133,8 @@ struct gensec_security_ops { NTSTATUS (*session_key)(struct gensec_security *gensec_security, DATA_BLOB *session_key); NTSTATUS (*session_info)(struct gensec_security *gensec_security, struct auth_session_info **session_info); + void (*want_feature)(struct gensec_security *gensec_security, + uint32_t feature); bool (*have_feature)(struct gensec_security *gensec_security, uint32_t feature); bool enabled; diff --git a/source4/auth/gensec/spnego.c b/source4/auth/gensec/spnego.c index 1855e0583d..bf991616bd 100644 --- a/source4/auth/gensec/spnego.c +++ b/source4/auth/gensec/spnego.c @@ -1094,6 +1094,20 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA return NT_STATUS_INVALID_PARAMETER; } +static void gensec_spnego_want_feature(struct gensec_security *gensec_security, + uint32_t feature) +{ + struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data; + + if (!spnego_state || !spnego_state->sub_sec_security) { + gensec_security->want_features |= feature; + return; + } + + gensec_want_feature(spnego_state->sub_sec_security, + feature); +} + static bool gensec_spnego_have_feature(struct gensec_security *gensec_security, uint32_t feature) { @@ -1133,6 +1147,7 @@ static const struct gensec_security_ops gensec_spnego_security_ops = { .unwrap_packets = gensec_spnego_unwrap_packets, .session_key = gensec_spnego_session_key, .session_info = gensec_spnego_session_info, + .want_feature = gensec_spnego_want_feature, .have_feature = gensec_spnego_have_feature, .enabled = true, .priority = GENSEC_SPNEGO -- cgit From 9e492b1ba2ccf2d7c62ef7295b33260687e3aeae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 6 Oct 2008 19:39:53 +0200 Subject: s4:rpc_server: tell the gensec layer that we want to do header signing Note: header signing is still off by default, as the gensec backends don't support it together with seal yet. metze --- source4/rpc_server/dcesrv_auth.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 52d5631cfd..bef7e4be78 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -95,6 +95,10 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } + if (call->conn->state_flags & DCESRV_CALL_STATE_FLAG_HEADER_SIGNING) { + gensec_want_feature(auth->gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER); + } + return true; } -- cgit From 338f658a5a300e21cc69b1a84ebbdc7d63262448 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Mon, 6 Oct 2008 11:34:45 -0500 Subject: idmap_adex: Add log messages to dc_add_domain for easier debugging. Part of continue work on BUG 5806. --- source3/winbindd/idmap_adex/domain_util.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source3/winbindd/idmap_adex/domain_util.c b/source3/winbindd/idmap_adex/domain_util.c index ab31ccef7a..6851503cc8 100644 --- a/source3/winbindd/idmap_adex/domain_util.c +++ b/source3/winbindd/idmap_adex/domain_util.c @@ -49,6 +49,12 @@ static NTSTATUS dc_add_domain(const char *domain) NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct dc_info *dc = NULL; + if (!domain) { + return NT_STATUS_INVALID_PARAMETER; + } + + DEBUG(10,("dc_add_domain: Attempting to add domain %s\n", domain)); + /* Check for duplicates */ dc = dc_list_head(); @@ -73,6 +79,8 @@ static NTSTATUS dc_add_domain(const char *domain) nt_status = NT_STATUS_OK; + DEBUG(5,("dc_add_domain: Successfully added %s\n", domain)); + done: if (!NT_STATUS_IS_OK(nt_status)) { talloc_destroy(dc); -- cgit From 2a35985283be45adbba63b5d7ced8499bcb64f59 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Mon, 6 Oct 2008 11:47:57 -0500 Subject: idmap_adex: Add more debugging to the basic search function. Log the dn of all located entries in order to verify search results. --- source3/winbindd/idmap_adex/likewise_cell.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source3/winbindd/idmap_adex/likewise_cell.c b/source3/winbindd/idmap_adex/likewise_cell.c index 77eeee406b..7723b3e015 100644 --- a/source3/winbindd/idmap_adex/likewise_cell.c +++ b/source3/winbindd/idmap_adex/likewise_cell.c @@ -389,6 +389,24 @@ done: status = ads_do_search(c->conn, search_base, scope, expr, attrs, msg); if (ADS_ERR_OK(status)) { + if (DEBUGLEVEL >= 10) { + LDAPMessage *e = NULL; + + int n = ads_count_replies(c->conn, *msg); + + DEBUG(10,("cell_do_search: Located %d entries\n", n)); + + for (e=ads_first_entry(c->conn, *msg); + e!=NULL; + e = ads_next_entry(c->conn, e)) + { + char *dn = ads_get_dn(c->conn, e); + + DEBUGADD(10,(" dn: %s\n", dn ? dn : "")); + SAFE_FREE(dn); + } + } + return status; } -- cgit From c412a930ad19da866503e6d8ccb71fb3191fc6d2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Oct 2008 16:25:59 -0700 Subject: Fix Domain Trust creation with Windows 2008 (and many other tools) A dITConentRules attribute (unlike objectClasses) must not contain a 'SUP'. The ADSI layer in Windows would download the whole schema, and validate it. Thanks to the team at Microsoft for very long debugging session to find this. Andrew Bartlett --- source4/dsdb/schema/schema_description.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/schema/schema_description.c b/source4/dsdb/schema/schema_description.c index 6884c5284e..e152f44b97 100644 --- a/source4/dsdb/schema/schema_description.c +++ b/source4/dsdb/schema/schema_description.c @@ -309,7 +309,11 @@ char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_clas class->lDAPDisplayName, (const char **)aux_class_list, NULL, - class->subClassOf, + NULL, /* Must not specify a + * SUP (subclass) in + * ditContentRules + * per MS-ADTS + * 3.1.1.3.1.1.1 */ -1, must_attr_list, may_attr_list); talloc_free(tmp_ctx); return schema_description; -- cgit From 7d9f18609b25463d306c0c150fe0da7f065860fd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Oct 2008 16:36:04 -0700 Subject: Remove DESCRIPTION from generated schema lines. This is not permitted in the AD aggregate schema, and more trouble than it is worth in the OpenLDAP schema due to escaping issues. Andrew Bartlett --- source4/dsdb/schema/schema_description.c | 21 +-------------------- source4/utils/ad2oLschema.c | 14 ++++++++++---- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/source4/dsdb/schema/schema_description.c b/source4/dsdb/schema/schema_description.c index e152f44b97..c3c37b4653 100644 --- a/source4/dsdb/schema/schema_description.c +++ b/source4/dsdb/schema/schema_description.c @@ -33,7 +33,6 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx, const char *seperator, const char *oid, const char *name, - const char *description, const char *equality, const char *substring, const char *syntax, @@ -46,15 +45,6 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx, "NAME '%s'%s", name, seperator); IF_NULL_FAIL_RET(schema_entry); - if (description) { -#if 0 - /* Need a way to escape ' characters from the description */ - schema_entry = talloc_asprintf_append(schema_entry, - "DESC '%s'%s", description, seperator); - IF_NULL_FAIL_RET(schema_entry); -#endif - } - if (equality) { schema_entry = talloc_asprintf_append(schema_entry, "EQUALITY %s%s", equality, seperator); @@ -104,7 +94,7 @@ char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_att " ", attribute->attributeID_oid, attribute->lDAPDisplayName, - NULL, NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax), + NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax), attribute->isSingleValued, attribute->systemOnly); talloc_free(tmp_ctx); @@ -149,7 +139,6 @@ char *schema_class_description(TALLOC_CTX *mem_ctx, const char *oid, const char *name, const char **auxillary_classes, - const char *description, const char *subClassOf, int objectClassCategory, char **must, @@ -164,12 +153,6 @@ char *schema_class_description(TALLOC_CTX *mem_ctx, "NAME '%s'%s", name, seperator); IF_NULL_FAIL_RET(schema_entry); - if (description) { - schema_entry = talloc_asprintf_append(schema_entry, - "DESC '%s'%s", description, seperator); - IF_NULL_FAIL_RET(schema_entry); - } - if (auxillary_classes) { schema_entry = talloc_asprintf_append(schema_entry, "AUX ( "); @@ -262,7 +245,6 @@ char *schema_class_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_class * " ", class->governsID_oid, class->lDAPDisplayName, - NULL, NULL, class->subClassOf, class->objectClassCategory, @@ -308,7 +290,6 @@ char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_clas class->governsID_oid, class->lDAPDisplayName, (const char **)aux_class_list, - NULL, NULL, /* Must not specify a * SUP (subclass) in * ditContentRules diff --git a/source4/utils/ad2oLschema.c b/source4/utils/ad2oLschema.c index 3c2ffe7a00..c579112b45 100644 --- a/source4/utils/ad2oLschema.c +++ b/source4/utils/ad2oLschema.c @@ -221,7 +221,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch for (attribute=schema->attributes; attribute; attribute = attribute->next) { const char *name = attribute->lDAPDisplayName; - const char *description = attribute->adminDescription; const char *oid = attribute->attributeID_oid; const char *syntax = attribute->attributeSyntax_oid; const char *equality = NULL, *substring = NULL; @@ -270,7 +269,16 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch } } - schema_entry = schema_attribute_description(mem_ctx, target, seperator, oid, name, description, equality, substring, syntax, single_value, false); + schema_entry = schema_attribute_description(mem_ctx, + target, + seperator, + oid, + name, + equality, + substring, + syntax, + single_value, + false); if (schema_entry == NULL) { ret.failures++; @@ -291,7 +299,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch /* This is already sorted to have 'top' and similar classes first */ for (objectclass=schema->classes; objectclass; objectclass = objectclass->next) { const char *name = objectclass->lDAPDisplayName; - const char *description = objectclass->adminDescription; const char *oid = objectclass->governsID_oid; const char *subClassOf = objectclass->subClassOf; int objectClassCategory = objectclass->objectClassCategory; @@ -356,7 +363,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch oid, name, NULL, - description, subClassOf, objectClassCategory, must, -- cgit From c0240d78351e489c5aca7e729aac045157080088 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Oct 2008 10:25:46 -0700 Subject: Remove compleatly bogus rename test in partitions module. --- source4/dsdb/samdb/ldb_modules/partition.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index 8e4483a78e..b452b66d56 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -589,7 +589,6 @@ static int partition_delete(struct ldb_module *module, struct ldb_request *req) /* rename */ static int partition_rename(struct ldb_module *module, struct ldb_request *req) { - int i, matched = -1; /* Find backend */ struct dsdb_control_current_partition *backend, *backend2; @@ -619,22 +618,6 @@ static int partition_rename(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_AFFECTS_MULTIPLE_DSAS; } - for (i=0; data && data->partitions && data->partitions[i]; i++) { - if (ldb_dn_compare_base(data->partitions[i]->dn, req->op.rename.olddn) == 0) { - matched = i; - } - } - - if (matched > 0) { - ldb_asprintf_errstring(module->ldb, - "Cannot rename from %s to %s, subtree rename would cross partition %s: %s", - ldb_dn_get_linearized(req->op.rename.olddn), - ldb_dn_get_linearized(req->op.rename.newdn), - ldb_dn_get_linearized(data->partitions[matched]->dn), - ldb_strerror(LDB_ERR_AFFECTS_MULTIPLE_DSAS)); - return LDB_ERR_AFFECTS_MULTIPLE_DSAS; - } - return partition_replicate(module, req, req->op.rename.olddn); } -- cgit From 8256717c766fb8e145c2f4b5acb3502f4d7c57d9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Sep 2008 14:24:58 -0700 Subject: Implement 'type unknown' names in the CrackNames code. This guesses the type by running each of the possible options. Andrew Bartlett --- source4/dsdb/samdb/cracknames.c | 58 ++++++++++++++++++++++++++------ source4/librpc/idl/drsuapi.idl | 2 +- source4/torture/rpc/drsuapi_cracknames.c | 1 + 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c index e02e8d81a6..ca87159c58 100644 --- a/source4/dsdb/samdb/cracknames.c +++ b/source4/dsdb/samdb/cracknames.c @@ -356,15 +356,7 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, const char *result_filter = NULL; struct ldb_dn *name_dn = NULL; - struct smb_krb5_context *smb_krb5_context; - ret = smb_krb5_init_context(mem_ctx, - ldb_get_event_context(sam_ctx), - (struct loadparm_context *)ldb_get_opaque(sam_ctx, "loadparm"), - &smb_krb5_context); - - if (ret) { - return WERR_NOMEM; - } + struct smb_krb5_context *smb_krb5_context = NULL; info1->status = DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR; info1->dns_domain_name = NULL; @@ -380,6 +372,30 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, /* here we need to set the domain_filter and/or the result_filter */ switch (format_offered) { + case DRSUAPI_DS_NAME_FORMAT_UNKNOWN: + { + int i; + enum drsuapi_DsNameFormat formats[] = { + DRSUAPI_DS_NAME_FORMAT_FQDN_1779, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, + DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, DRSUAPI_DS_NAME_FORMAT_CANONICAL, + DRSUAPI_DS_NAME_FORMAT_GUID, DRSUAPI_DS_NAME_FORMAT_DISPLAY, + DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL, + DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY, + DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX + }; + WERROR werr; + for (i=0; i < ARRAY_SIZE(formats); i++) { + werr = DsCrackNameOneName(sam_ctx, mem_ctx, format_flags, formats[i], format_desired, name, info1); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + if (info1->status != DRSUAPI_DS_NAME_STATUS_NOT_FOUND) { + return werr; + } + } + return werr; + } + case DRSUAPI_DS_NAME_FORMAT_CANONICAL: case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: { @@ -534,6 +550,16 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, case DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL: { krb5_principal principal; char *unparsed_name; + + ret = smb_krb5_init_context(mem_ctx, + ldb_get_event_context(sam_ctx), + (struct loadparm_context *)ldb_get_opaque(sam_ctx, "loadparm"), + &smb_krb5_context); + + if (ret) { + return WERR_NOMEM; + } + ret = krb5_parse_name(smb_krb5_context->krb5_context, name, &principal); if (ret) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; @@ -560,6 +586,16 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, krb5_principal principal; char *unparsed_name_short; char *service; + + ret = smb_krb5_init_context(mem_ctx, + ldb_get_event_context(sam_ctx), + (struct loadparm_context *)ldb_get_opaque(sam_ctx, "loadparm"), + &smb_krb5_context); + + if (ret) { + return WERR_NOMEM; + } + ret = krb5_parse_name(smb_krb5_context->krb5_context, name, &principal); if (ret == 0 && principal->name.name_string.len < 2) { info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; @@ -1265,7 +1301,7 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx, const char **nt4_domain, const char **nt4_account) { - uint32_t format_offered = DRSUAPI_DS_NAME_FORMAT_UKNOWN; + uint32_t format_offered = DRSUAPI_DS_NAME_FORMAT_UNKNOWN; /* Handle anonymous bind */ if (!name || !*name) { @@ -1282,6 +1318,8 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx, format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT; } else if (strchr_m(name, '/')) { format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL; + } else { + return NT_STATUS_NO_SUCH_USER; } return crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, format_offered, name, nt4_domain, nt4_account); diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl index 76858b2d5c..a41bc9cf19 100644 --- a/source4/librpc/idl/drsuapi.idl +++ b/source4/librpc/idl/drsuapi.idl @@ -877,7 +877,7 @@ interface drsuapi } drsuapi_DsNameFlags; typedef [v1_enum] enum { - DRSUAPI_DS_NAME_FORMAT_UKNOWN = 0, + DRSUAPI_DS_NAME_FORMAT_UNKNOWN = 0, DRSUAPI_DS_NAME_FORMAT_FQDN_1779 = 1, DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT = 2, DRSUAPI_DS_NAME_FORMAT_DISPLAY = 3, diff --git a/source4/torture/rpc/drsuapi_cracknames.c b/source4/torture/rpc/drsuapi_cracknames.c index fbda69df57..a9a614953d 100644 --- a/source4/torture/rpc/drsuapi_cracknames.c +++ b/source4/torture/rpc/drsuapi_cracknames.c @@ -39,6 +39,7 @@ static bool test_DsCrackNamesMatrix(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, bool ret = true; struct drsuapi_DsCrackNames r; enum drsuapi_DsNameFormat formats[] = { + DRSUAPI_DS_NAME_FORMAT_UNKNOWN, DRSUAPI_DS_NAME_FORMAT_FQDN_1779, DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, DRSUAPI_DS_NAME_FORMAT_DISPLAY, -- cgit From 8cdb3ebe27814629cb17d2a438c89780c5cecfdf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Oct 2008 13:10:11 -0700 Subject: Clarify use of manual parsers in trustInOutBlob (drsblobs.idl) --- source4/librpc/idl/drsblobs.idl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source4/librpc/idl/drsblobs.idl b/source4/librpc/idl/drsblobs.idl index 31fe8a359e..4274d2000a 100644 --- a/source4/librpc/idl/drsblobs.idl +++ b/source4/librpc/idl/drsblobs.idl @@ -409,21 +409,23 @@ interface drsblobs { [size_is(1)] AuthenticationInformation array[]; } AuthenticationInformationArray; + /* This is nopull,nopush because we pass count down to the + * manual parser of AuthenticationInformationArray */ typedef [public,nopull,nopush,noprint,gensize] struct { uint32 count; [relative] AuthenticationInformationArray *current; [relative] AuthenticationInformationArray *previous; } trustAuthInOutBlob; + void decode_trustAuthInOut( + [in] trustAuthInOutBlob blob + ); + typedef [public,gensize] struct { uint32 count; [relative] AuthenticationInformation *current[count]; } trustCurrentPasswords; - void decode_trustAuthInOut( - [in] trustAuthInOutBlob blob - ); - typedef [public,nopull] struct { uint8 confounder[512]; [subcontext(0),subcontext_size(outgoing_size)] trustCurrentPasswords outgoing; -- cgit From 8e1c0470d72ca85d837bbdd4aec0ca2f27a7a29f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Oct 2008 13:10:35 -0700 Subject: Add in secure channel type used by AD trusts --- source4/librpc/idl/misc.idl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source4/librpc/idl/misc.idl b/source4/librpc/idl/misc.idl index 8331977398..791b86466c 100644 --- a/source4/librpc/idl/misc.idl +++ b/source4/librpc/idl/misc.idl @@ -30,9 +30,11 @@ interface misc /* Only SEC_CHAN_WKSTA can forward requests to other domains. */ typedef [public] enum { - SEC_CHAN_WKSTA = 2, - SEC_CHAN_DOMAIN = 4, - SEC_CHAN_BDC = 6 + SEC_CHAN_NULL = 0, + SEC_CHAN_WKSTA = 2, + SEC_CHAN_DNS_DOMAIN = 3, + SEC_CHAN_DOMAIN = 4, + SEC_CHAN_BDC = 6 } netr_SchannelType; /* SAM database types */ -- cgit From 99d0eb4fb701c500f0175ca9a38482160bdb08e4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Oct 2008 13:11:11 -0700 Subject: Make RPC-LSA test for enumeration conditions more strict --- source4/torture/rpc/lsa.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index efbdecab13..245ed1e41b 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -1899,7 +1899,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, /* NO_MORE_ENTRIES is allowed */ if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) { - return true; + if (domains.count == 0) { + return true; + } + printf("EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); + return false; } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { /* Windows 2003 gets this off by one on the first run */ if (r.out.domains->count < 3 || r.out.domains->count > 4) { @@ -1950,7 +1954,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p, /* NO_MORE_ENTRIES is allowed */ if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) { - return true; + if (domains_ex.count == 0) { + return true; + } + printf("EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n"); + return false; } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) { /* Windows 2003 gets this off by one on the first run */ if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) { @@ -2115,7 +2123,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, /* Try different trust types too */ - /* 1 == downleven (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */ + /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */ trustinfo.trust_type = (((i / 3) + 1) % 3) + 1; trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION; @@ -2160,6 +2168,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status)); ret = false; } else if (!q.out.info) { + printf("QueryTrustedDomainInfo level 1 failed to return an info pointer\n"); ret = false; } else { if (strcmp(q.out.info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) { @@ -2188,11 +2197,13 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, /* now that we have some domains to look over, we can test the enum calls */ if (!test_EnumTrustDom(p, mem_ctx, handle)) { + printf("test_EnumTrustDom failed\n"); ret = false; } for (i=0; i<12; i++) { if (!test_DeleteTrustedDomainBySid(p, mem_ctx, handle, domsid[i])) { + printf("test_DeleteTrustedDomainBySid failed\n"); ret = false; } } -- cgit From 1a29fd1cf5436c850c7de180668a7a33f9b034d8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Oct 2008 13:12:15 -0700 Subject: Store trusted domain passwords in the LSA server --- source4/rpc_server/lsa/dcesrv_lsa.c | 68 ++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 5e3be84cc5..836fd8dc62 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -727,13 +727,46 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } + + if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) { + if (auth_struct.incoming.count > 1) { + return NT_STATUS_INVALID_PARAMETER; + } + } } if (auth_struct.incoming.count) { + int i; + struct trustAuthInOutBlob incoming; + + incoming.count = auth_struct.incoming.count; + incoming.current = talloc(mem_ctx, struct AuthenticationInformationArray); + if (!incoming.current) { + return NT_STATUS_NO_MEMORY; + } + + incoming.current->array = *auth_struct.incoming.current; + if (!incoming.current->array) { + return NT_STATUS_NO_MEMORY; + } + + incoming.previous = talloc(mem_ctx, struct AuthenticationInformationArray); + if (!incoming.previous) { + return NT_STATUS_NO_MEMORY; + } + incoming.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, incoming.count); + if (!incoming.previous->array) { + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < incoming.count; i++) { + incoming.previous->array[i].LastUpdateTime = 0; + incoming.previous->array[i].AuthType = 0; + } ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), - &auth_struct.incoming, - (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); + &incoming, + (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } @@ -742,10 +775,37 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc } if (auth_struct.outgoing.count) { + int i; + struct trustAuthInOutBlob outgoing; + + outgoing.count = auth_struct.outgoing.count; + outgoing.current = talloc(mem_ctx, struct AuthenticationInformationArray); + if (!outgoing.current) { + return NT_STATUS_NO_MEMORY; + } + + outgoing.current->array = *auth_struct.outgoing.current; + if (!outgoing.current->array) { + return NT_STATUS_NO_MEMORY; + } + + outgoing.previous = talloc(mem_ctx, struct AuthenticationInformationArray); + if (!outgoing.previous) { + return NT_STATUS_NO_MEMORY; + } + outgoing.previous->array = talloc_array(mem_ctx, struct AuthenticationInformation, outgoing.count); + if (!outgoing.previous->array) { + return NT_STATUS_NO_MEMORY; + } + + for (i = 0; i < outgoing.count; i++) { + outgoing.previous->array[i].LastUpdateTime = 0; + outgoing.previous->array[i].AuthType = 0; + } ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), - &auth_struct.outgoing, - (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); + &outgoing, + (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } -- cgit From 320d402180ac2d8505aec2664feaddbd63e5b17e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Oct 2008 13:31:22 -0700 Subject: Start implementing AD-style trusted domains in Samba4's NETLOGON server --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 52 +++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index d5f7d2afae..b948d1210e 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -87,6 +87,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca const char *attrs[] = {"unicodePwd", "userAccountControl", "objectSid", NULL}; + const char *trust_dom_attrs[] = {"flatname", NULL}; + const char *account_name; + ZERO_STRUCTP(r->out.credentials); *r->out.rid = 0; *r->out.negotiate_flags = *r->in.negotiate_flags; @@ -101,10 +104,54 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca if (sam_ctx == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } + + if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { + char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name); + char *flatname; + if (!encoded_account) { + return NT_STATUS_NO_MEMORY; + } + + /* Kill the trailing dot */ + if (encoded_account[strlen(encoded_account)-1] == '.') { + encoded_account[strlen(encoded_account)-1] = '\0'; + } + + /* pull the user attributes */ + num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs, + "(&(trustPartner=%s)(objectclass=trustedDomain))", + encoded_account); + + if (num_records == 0) { + DEBUG(3,("Couldn't find trust [%s] in samdb.\n", + encoded_account)); + return NT_STATUS_ACCESS_DENIED; + } + + if (num_records > 1) { + DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name)); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL); + if (!flatname) { + /* No flatname for this trust - we can't proceed */ + return NT_STATUS_ACCESS_DENIED; + } + account_name = talloc_asprintf(mem_ctx, "%s$", flatname); + + if (!account_name) { + return NT_STATUS_NO_MEMORY; + } + + } else { + account_name = r->in.account_name; + } + /* pull the user attributes */ num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs, "(&(sAMAccountName=%s)(objectclass=user))", - r->in.account_name); + ldb_binary_encode_string(mem_ctx, account_name)); if (num_records == 0) { DEBUG(3,("Couldn't find user [%s] in samdb.\n", @@ -130,7 +177,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control)); return NT_STATUS_ACCESS_DENIED; } - } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) { + } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || + r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) { DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control)); -- cgit From 912209ac84395ef0e2fca0556b1e4bec34367b5c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 1 Oct 2008 16:00:33 -0700 Subject: Use the trust password version as kvno for trusts in Kerberos. --- source4/kdc/hdb-samba4.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index d7317f17d4..818c4a12fd 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -717,6 +717,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, enum ndr_err_code ndr_err; int i, ret, trust_direction_flags; + uint32_t kvno; private = talloc(mem_ctx, struct hdb_ldb_private); if (!private) { @@ -764,6 +765,12 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, goto out; } + for (i=0; i < password_blob.count; i++) { + if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_VERSION) { + entry_ex->entry.kvno = password_blob.current->array[i].AuthInfo.version.version; + } + } + for (i=0; i < password_blob.count; i++) { if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { password_utf16 = data_blob_const(password_blob.current->array[i].AuthInfo.clear.password, -- cgit From 6a5547742f0b87017e4d21c80ec8facece6688d0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 2 Oct 2008 11:29:34 -0700 Subject: Allow the PAC to be passed along during cross-realm authentication --- source4/heimdal/kdc/krb5tgs.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index 19dff5e01d..d557da2a5b 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -1393,6 +1393,8 @@ tgs_build_reply(krb5_context context, char opt_str[128]; int signedpath = 0; + Key *tkey; + memset(&sessionkey, 0, sizeof(sessionkey)); memset(&adtkt, 0, sizeof(adtkt)); krb5_data_zero(&rspac); @@ -1630,26 +1632,22 @@ server_lookup: } /* check PAC if not cross realm and if there is one */ - if (!cross_realm) { - Key *tkey; - - ret = hdb_enctype2key(context, &krbtgt->entry, - krbtgt_etype, &tkey); - if(ret) { - kdc_log(context, config, 0, + ret = hdb_enctype2key(context, &krbtgt->entry, + krbtgt_etype, &tkey); + if(ret) { + kdc_log(context, config, 0, "Failed to find key for krbtgt PAC check"); - goto out; - } + goto out; + } - ret = check_PAC(context, config, cp, - client, server, ekey, &tkey->key, - tgt, &rspac, &signedpath); - if (ret) { - kdc_log(context, config, 0, - "Verify PAC failed for %s (%s) from %s with %s", - spn, cpn, from, krb5_get_err_text(context, ret)); - goto out; - } + ret = check_PAC(context, config, cp, + client, server, ekey, &tkey->key, + tgt, &rspac, &signedpath); + if (ret) { + kdc_log(context, config, 0, + "Verify PAC failed for %s (%s) from %s with %s", + spn, cpn, from, krb5_get_err_text(context, ret)); + goto out; } /* also check the krbtgt for signature */ -- cgit From c3b28c7a81c04a0f019b6c1e543a65d6d48b0b2c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 2 Oct 2008 11:30:14 -0700 Subject: Fix cross-realm authentication in Samba4's KDC. --- source4/kdc/hdb-samba4.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 818c4a12fd..5b7f55822e 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -758,7 +758,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, goto out; } - ndr_err = ndr_pull_struct_blob_all(password_val, mem_ctx, private->iconv_convenience, &password_blob, + ndr_err = ndr_pull_struct_blob(password_val, mem_ctx, private->iconv_convenience, &password_blob, (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { ret = EINVAL; @@ -813,6 +813,8 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, entry_ex->entry.keys.len++; } + entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal))); + ret = copy_Principal(principal, entry_ex->entry.principal); if (ret) { krb5_clear_error_string(context); @@ -1155,7 +1157,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, msg[0], realm_ref_msg_1[0], entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); + krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed"); } return ret; @@ -1193,7 +1195,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, principal, direction, msg[0], entry_ex); if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); + krb5_warnx(context, "LDB_fetch: trust_message2entry failed"); } return ret; -- cgit From e0a4d7f467d9727563adaaa97961edd06886490e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Oct 2008 16:36:49 -0700 Subject: Set default trust kvno to -1 --- source4/kdc/hdb-samba4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 5b7f55822e..51f464cd09 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -717,7 +717,6 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, enum ndr_err_code ndr_err; int i, ret, trust_direction_flags; - uint32_t kvno; private = talloc(mem_ctx, struct hdb_ldb_private); if (!private) { @@ -765,6 +764,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, goto out; } + entry_ex->entry.kvno = -1; for (i=0; i < password_blob.count; i++) { if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_VERSION) { entry_ex->entry.kvno = password_blob.current->array[i].AuthInfo.version.version; -- cgit From f19086872ec734fff3f2119712ff24117bec4e5e Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 6 Oct 2008 16:41:46 -0700 Subject: Fixed "declaration shadows global declaration" warnings. The patch simply uses a more descriptive variable name for tcp_seq. ../lib/socket_wrapper/socket_wrapper.c:753: warning: declaration of 'tcp_seq' shadows a global declaration /usr/include/netinet/tcp.h:40: warning: shadowed declaration is here ../lib/socket_wrapper/socket_wrapper.c: In function `swrap_marshall_packet': ../lib/socket_wrapper/socket_wrapper.c:919: warning: declaration of 'tcp_seq' shadows a global declaration /usr/include/netinet/tcp.h:40: warning: shadowed declaration is here --- lib/socket_wrapper/socket_wrapper.c | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index e8d27adc37..ecb6142cfc 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -750,7 +750,7 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval, int socket_type, const unsigned char *payload, size_t payload_len, - unsigned long tcp_seq, + unsigned long tcp_seq_num, unsigned long tcp_ack, unsigned char tcp_ctl, int unreachable, @@ -852,7 +852,7 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval, case SOCK_STREAM: packet->ip.p.tcp.source_port = src_port; packet->ip.p.tcp.dest_port = dest_port; - packet->ip.p.tcp.seq_num = htonl(tcp_seq); + packet->ip.p.tcp.seq_num = htonl(tcp_seq_num); packet->ip.p.tcp.ack_num = htonl(tcp_ack); packet->ip.p.tcp.hdr_length = 0x50; /* 5 * 32 bit words */ packet->ip.p.tcp.control = tcp_ctl; @@ -916,7 +916,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, { const struct sockaddr_in *src_addr; const struct sockaddr_in *dest_addr; - unsigned long tcp_seq = 0; + unsigned long tcp_seq_num = 0; unsigned long tcp_ack = 0; unsigned char tcp_ctl = 0; int unreachable = 0; @@ -937,7 +937,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_snd; + tcp_seq_num = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x02; /* SYN */ @@ -951,7 +951,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_rcv; + tcp_seq_num = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x12; /** SYN,ACK */ @@ -966,7 +966,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)addr; /* Unreachable: resend the data of SWRAP_CONNECT_SEND */ - tcp_seq = si->io.pck_snd - 1; + tcp_seq_num = si->io.pck_snd - 1; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x02; /* SYN */ unreachable = 1; @@ -979,7 +979,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_snd; + tcp_seq_num = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x10; /* ACK */ @@ -991,7 +991,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_rcv; + tcp_seq_num = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x02; /* SYN */ @@ -1005,7 +1005,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_snd; + tcp_seq_num = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x12; /* SYN,ACK */ @@ -1019,7 +1019,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq = si->io.pck_rcv; + tcp_seq_num = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x10; /* ACK */ @@ -1029,7 +1029,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_snd; + tcp_seq_num = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x18; /* PSH,ACK */ @@ -1047,7 +1047,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, buf, len, packet_len); } - tcp_seq = si->io.pck_rcv; + tcp_seq_num = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /** RST,ACK */ @@ -1061,7 +1061,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return NULL; } - tcp_seq = si->io.pck_rcv; + tcp_seq_num = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /* RST,ACK */ @@ -1071,7 +1071,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_rcv; + tcp_seq_num = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x18; /* PSH,ACK */ @@ -1087,7 +1087,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return NULL; } - tcp_seq = si->io.pck_rcv; + tcp_seq_num = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /* RST,ACK */ @@ -1123,7 +1123,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_snd; + tcp_seq_num = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x11; /* FIN, ACK */ @@ -1137,7 +1137,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_rcv; + tcp_seq_num = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x11; /* FIN,ACK */ @@ -1151,7 +1151,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq = si->io.pck_snd; + tcp_seq_num = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x10; /* ACK */ @@ -1164,7 +1164,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return swrap_packet_init(&tv, src_addr, dest_addr, si->type, (const unsigned char *)buf, len, - tcp_seq, tcp_ack, tcp_ctl, unreachable, + tcp_seq_num, tcp_ack, tcp_ctl, unreachable, packet_len); } -- cgit From cde1b09d68e496f8f531336088433e9546b2864d Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 6 Oct 2008 17:09:48 -0700 Subject: Fixed build warning "passing arg from incompatible pointer type" The fix explicitly makes the conversion from timeval to time_t using the existing time utility functions. Compiling modules/vfs_smb_traffic_analyzer.c modules/vfs_smb_traffic_analyzer.c: In function `smb_traffic_analyzer_send_data': modules/vfs_smb_traffic_analyzer.c:173: warning: passing arg 1 of `localtime' from incompatible pointer type --- source3/modules/vfs_smb_traffic_analyzer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c index ff61768495..9b4c1b3e25 100644 --- a/source3/modules/vfs_smb_traffic_analyzer.c +++ b/source3/modules/vfs_smb_traffic_analyzer.c @@ -156,6 +156,7 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, { struct refcounted_sock *rf_sock = NULL; struct timeval tv; + time_t tv_sec; struct tm *tm = NULL; int seconds; char *str = NULL; @@ -170,7 +171,8 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, } GetTimeOfDay(&tv); - tm=localtime(&tv.tv_sec); + tv_sec = convert_timespec_to_time_t(convert_timeval_to_timespec(tv)); + tm = localtime(&tv_sec); if (!tm) { return; } -- cgit From abf00f710dc3a4b3fab8058a4c4f0df37b1baac4 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 7 Oct 2008 10:56:30 -0700 Subject: Changed variable name from f19086872ec734fff3f2119712ff24117bec4e5e to match v3-[23]-test --- lib/socket_wrapper/socket_wrapper.c | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index ecb6142cfc..9d61976950 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -750,7 +750,7 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval, int socket_type, const unsigned char *payload, size_t payload_len, - unsigned long tcp_seq_num, + unsigned long tcp_seqno, unsigned long tcp_ack, unsigned char tcp_ctl, int unreachable, @@ -852,7 +852,7 @@ static struct swrap_packet *swrap_packet_init(struct timeval *tval, case SOCK_STREAM: packet->ip.p.tcp.source_port = src_port; packet->ip.p.tcp.dest_port = dest_port; - packet->ip.p.tcp.seq_num = htonl(tcp_seq_num); + packet->ip.p.tcp.seq_num = htonl(tcp_seqno); packet->ip.p.tcp.ack_num = htonl(tcp_ack); packet->ip.p.tcp.hdr_length = 0x50; /* 5 * 32 bit words */ packet->ip.p.tcp.control = tcp_ctl; @@ -916,7 +916,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, { const struct sockaddr_in *src_addr; const struct sockaddr_in *dest_addr; - unsigned long tcp_seq_num = 0; + unsigned long tcp_seqno = 0; unsigned long tcp_ack = 0; unsigned char tcp_ctl = 0; int unreachable = 0; @@ -937,7 +937,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq_num = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x02; /* SYN */ @@ -951,7 +951,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq_num = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x12; /** SYN,ACK */ @@ -966,7 +966,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)addr; /* Unreachable: resend the data of SWRAP_CONNECT_SEND */ - tcp_seq_num = si->io.pck_snd - 1; + tcp_seqno = si->io.pck_snd - 1; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x02; /* SYN */ unreachable = 1; @@ -979,7 +979,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq_num = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x10; /* ACK */ @@ -991,7 +991,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq_num = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x02; /* SYN */ @@ -1005,7 +1005,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)addr; - tcp_seq_num = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x12; /* SYN,ACK */ @@ -1019,7 +1019,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)addr; - tcp_seq_num = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x10; /* ACK */ @@ -1029,7 +1029,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq_num = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x18; /* PSH,ACK */ @@ -1047,7 +1047,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, buf, len, packet_len); } - tcp_seq_num = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /** RST,ACK */ @@ -1061,7 +1061,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return NULL; } - tcp_seq_num = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /* RST,ACK */ @@ -1071,7 +1071,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)si->peername; - tcp_seq_num = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x18; /* PSH,ACK */ @@ -1087,7 +1087,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return NULL; } - tcp_seq_num = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x14; /* RST,ACK */ @@ -1123,7 +1123,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq_num = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x11; /* FIN, ACK */ @@ -1137,7 +1137,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, dest_addr = (const struct sockaddr_in *)si->myname; src_addr = (const struct sockaddr_in *)si->peername; - tcp_seq_num = si->io.pck_rcv; + tcp_seqno = si->io.pck_rcv; tcp_ack = si->io.pck_snd; tcp_ctl = 0x11; /* FIN,ACK */ @@ -1151,7 +1151,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, src_addr = (const struct sockaddr_in *)si->myname; dest_addr = (const struct sockaddr_in *)si->peername; - tcp_seq_num = si->io.pck_snd; + tcp_seqno = si->io.pck_snd; tcp_ack = si->io.pck_rcv; tcp_ctl = 0x10; /* ACK */ @@ -1164,7 +1164,7 @@ static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, return swrap_packet_init(&tv, src_addr, dest_addr, si->type, (const unsigned char *)buf, len, - tcp_seq_num, tcp_ack, tcp_ctl, unreachable, + tcp_seqno, tcp_ack, tcp_ctl, unreachable, packet_len); } -- cgit From 2024d87cf5ffa0633225ed189fa48f0f56151e7e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Oct 2008 14:43:42 -0700 Subject: Make map_errno_from_nt_status() a generic call, not just a cli specific one. Remove some unused calls from vfs_acl_xattr. Test for SD's on existing files. Jeremy. --- source3/include/proto.h | 1 + source3/lib/errmap_unix.c | 136 ++++++++++++++++++++++++++++++++++++++ source3/libsmb/clierror.c | 140 +--------------------------------------- source3/modules/vfs_acl_xattr.c | 58 ++++++++++------- 4 files changed, 175 insertions(+), 160 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 30e309cd4e..d7acdcb910 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -515,6 +515,7 @@ void display_set_stderr(void); /* The following definitions come from lib/errmap_unix.c */ NTSTATUS map_nt_error_from_unix(int unix_error); +int map_errno_from_nt_status(NTSTATUS status); /* The following definitions come from lib/events.c */ diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c index 2cd2386c5c..9adb237096 100644 --- a/source3/lib/errmap_unix.c +++ b/source3/lib/errmap_unix.c @@ -128,3 +128,139 @@ NTSTATUS map_nt_error_from_unix(int unix_error) /* Default return */ return NT_STATUS_ACCESS_DENIED; } + +/* Return a UNIX errno from a NT status code */ +static const struct { + NTSTATUS status; + int error; +} nt_errno_map[] = { + {NT_STATUS_ACCESS_VIOLATION, EACCES}, + {NT_STATUS_INVALID_HANDLE, EBADF}, + {NT_STATUS_ACCESS_DENIED, EACCES}, + {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, + {NT_STATUS_OBJECT_PATH_NOT_FOUND, ENOENT}, + {NT_STATUS_SHARING_VIOLATION, EBUSY}, + {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, + {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, + {NT_STATUS_PATH_NOT_COVERED, ENOENT}, + {NT_STATUS_UNSUCCESSFUL, EINVAL}, + {NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, + {NT_STATUS_IN_PAGE_ERROR, EFAULT}, + {NT_STATUS_BAD_NETWORK_NAME, ENOENT}, +#ifdef EDQUOT + {NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, + {NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, + {NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, + {NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, +#endif +#ifdef ETIME + {NT_STATUS_TIMER_NOT_CANCELED, ETIME}, +#endif + {NT_STATUS_INVALID_PARAMETER, EINVAL}, + {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, + {NT_STATUS_NO_SUCH_FILE, ENOENT}, +#ifdef ENODATA + {NT_STATUS_END_OF_FILE, ENODATA}, +#endif +#ifdef ENOMEDIUM + {NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM}, + {NT_STATUS_NO_MEDIA, ENOMEDIUM}, +#endif + {NT_STATUS_NONEXISTENT_SECTOR, ESPIPE}, + {NT_STATUS_NO_MEMORY, ENOMEM}, + {NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE}, + {NT_STATUS_NOT_MAPPED_VIEW, EINVAL}, + {NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE}, + {NT_STATUS_ACCESS_DENIED, EACCES}, + {NT_STATUS_BUFFER_TOO_SMALL, ENOBUFS}, + {NT_STATUS_WRONG_PASSWORD, EACCES}, + {NT_STATUS_LOGON_FAILURE, EACCES}, + {NT_STATUS_INVALID_WORKSTATION, EACCES}, + {NT_STATUS_INVALID_LOGON_HOURS, EACCES}, + {NT_STATUS_PASSWORD_EXPIRED, EACCES}, + {NT_STATUS_ACCOUNT_DISABLED, EACCES}, + {NT_STATUS_DISK_FULL, ENOSPC}, + {NT_STATUS_INVALID_PIPE_STATE, EPIPE}, + {NT_STATUS_PIPE_BUSY, EPIPE}, + {NT_STATUS_PIPE_DISCONNECTED, EPIPE}, + {NT_STATUS_PIPE_NOT_AVAILABLE, ENOSYS}, + {NT_STATUS_FILE_IS_A_DIRECTORY, EISDIR}, + {NT_STATUS_NOT_SUPPORTED, ENOSYS}, + {NT_STATUS_NOT_A_DIRECTORY, ENOTDIR}, + {NT_STATUS_DIRECTORY_NOT_EMPTY, ENOTEMPTY}, + {NT_STATUS_NETWORK_UNREACHABLE, ENETUNREACH}, + {NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH}, + {NT_STATUS_CONNECTION_ABORTED, ECONNABORTED}, + {NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED}, + {NT_STATUS_TOO_MANY_LINKS, EMLINK}, + {NT_STATUS_NETWORK_BUSY, EBUSY}, + {NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, +#ifdef ELIBACC + {NT_STATUS_DLL_NOT_FOUND, ELIBACC}, +#endif + {NT_STATUS_PIPE_BROKEN, EPIPE}, + {NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED}, + {NT_STATUS_NETWORK_ACCESS_DENIED, EACCES}, + {NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE}, +#ifdef EPROTO + {NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO}, +#endif + {NT_STATUS_FLOAT_OVERFLOW, ERANGE}, + {NT_STATUS_FLOAT_UNDERFLOW, ERANGE}, + {NT_STATUS_INTEGER_OVERFLOW, ERANGE}, + {NT_STATUS_MEDIA_WRITE_PROTECTED, EROFS}, + {NT_STATUS_PIPE_CONNECTED, EISCONN}, + {NT_STATUS_MEMORY_NOT_ALLOCATED, EFAULT}, + {NT_STATUS_FLOAT_INEXACT_RESULT, ERANGE}, + {NT_STATUS_ILL_FORMED_PASSWORD, EACCES}, + {NT_STATUS_PASSWORD_RESTRICTION, EACCES}, + {NT_STATUS_ACCOUNT_RESTRICTION, EACCES}, + {NT_STATUS_PORT_CONNECTION_REFUSED, ECONNREFUSED}, + {NT_STATUS_NAME_TOO_LONG, ENAMETOOLONG}, + {NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN}, + {NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED}, + {NT_STATUS_CONNECTION_RESET, ENETRESET}, +#ifdef ENOTUNIQ + {NT_STATUS_IP_ADDRESS_CONFLICT1, ENOTUNIQ}, + {NT_STATUS_IP_ADDRESS_CONFLICT2, ENOTUNIQ}, +#endif + {NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE}, + {NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT}, + {NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE}, + {NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, + {NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, + {NT_STATUS_RETRY, EAGAIN}, +#ifdef ENOTUNIQ + {NT_STATUS_DUPLICATE_NAME, ENOTUNIQ}, +#endif +#ifdef ECOMM + {NT_STATUS_NET_WRITE_FAULT, ECOMM}, +#endif +#ifdef EXDEV + {NT_STATUS_NOT_SAME_DEVICE, EXDEV}, +#endif + {NT_STATUS(0), 0} +}; + +int map_errno_from_nt_status(NTSTATUS status) +{ + int i; + DEBUG(10,("map_errno_from_nt_status: 32 bit codes: code=%08x\n", + NT_STATUS_V(status))); + + /* Status codes without this bit set are not errors */ + + if (!(NT_STATUS_V(status) & 0xc0000000)) { + return 0; + } + + for (i=0;nt_errno_map[i].error;i++) { + if (NT_STATUS_V(nt_errno_map[i].status) == + NT_STATUS_V(status)) { + return nt_errno_map[i].error; + } + } + + /* for all other cases - a default code */ + return EINVAL; +} diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 36746419f7..54f8a7a43c 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -236,142 +236,6 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) *ecode = SVAL(cli->inbuf,smb_err); } -/* Return a UNIX errno from a NT status code */ -static const struct { - NTSTATUS status; - int error; -} nt_errno_map[] = { - {NT_STATUS_ACCESS_VIOLATION, EACCES}, - {NT_STATUS_INVALID_HANDLE, EBADF}, - {NT_STATUS_ACCESS_DENIED, EACCES}, - {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, - {NT_STATUS_OBJECT_PATH_NOT_FOUND, ENOENT}, - {NT_STATUS_SHARING_VIOLATION, EBUSY}, - {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, - {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, - {NT_STATUS_PATH_NOT_COVERED, ENOENT}, - {NT_STATUS_UNSUCCESSFUL, EINVAL}, - {NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, - {NT_STATUS_IN_PAGE_ERROR, EFAULT}, - {NT_STATUS_BAD_NETWORK_NAME, ENOENT}, -#ifdef EDQUOT - {NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, - {NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, - {NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, - {NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, -#endif -#ifdef ETIME - {NT_STATUS_TIMER_NOT_CANCELED, ETIME}, -#endif - {NT_STATUS_INVALID_PARAMETER, EINVAL}, - {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, - {NT_STATUS_NO_SUCH_FILE, ENOENT}, -#ifdef ENODATA - {NT_STATUS_END_OF_FILE, ENODATA}, -#endif -#ifdef ENOMEDIUM - {NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM}, - {NT_STATUS_NO_MEDIA, ENOMEDIUM}, -#endif - {NT_STATUS_NONEXISTENT_SECTOR, ESPIPE}, - {NT_STATUS_NO_MEMORY, ENOMEM}, - {NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE}, - {NT_STATUS_NOT_MAPPED_VIEW, EINVAL}, - {NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE}, - {NT_STATUS_ACCESS_DENIED, EACCES}, - {NT_STATUS_BUFFER_TOO_SMALL, ENOBUFS}, - {NT_STATUS_WRONG_PASSWORD, EACCES}, - {NT_STATUS_LOGON_FAILURE, EACCES}, - {NT_STATUS_INVALID_WORKSTATION, EACCES}, - {NT_STATUS_INVALID_LOGON_HOURS, EACCES}, - {NT_STATUS_PASSWORD_EXPIRED, EACCES}, - {NT_STATUS_ACCOUNT_DISABLED, EACCES}, - {NT_STATUS_DISK_FULL, ENOSPC}, - {NT_STATUS_INVALID_PIPE_STATE, EPIPE}, - {NT_STATUS_PIPE_BUSY, EPIPE}, - {NT_STATUS_PIPE_DISCONNECTED, EPIPE}, - {NT_STATUS_PIPE_NOT_AVAILABLE, ENOSYS}, - {NT_STATUS_FILE_IS_A_DIRECTORY, EISDIR}, - {NT_STATUS_NOT_SUPPORTED, ENOSYS}, - {NT_STATUS_NOT_A_DIRECTORY, ENOTDIR}, - {NT_STATUS_DIRECTORY_NOT_EMPTY, ENOTEMPTY}, - {NT_STATUS_NETWORK_UNREACHABLE, ENETUNREACH}, - {NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH}, - {NT_STATUS_CONNECTION_ABORTED, ECONNABORTED}, - {NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED}, - {NT_STATUS_TOO_MANY_LINKS, EMLINK}, - {NT_STATUS_NETWORK_BUSY, EBUSY}, - {NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, -#ifdef ELIBACC - {NT_STATUS_DLL_NOT_FOUND, ELIBACC}, -#endif - {NT_STATUS_PIPE_BROKEN, EPIPE}, - {NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED}, - {NT_STATUS_NETWORK_ACCESS_DENIED, EACCES}, - {NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE}, -#ifdef EPROTO - {NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO}, -#endif - {NT_STATUS_FLOAT_OVERFLOW, ERANGE}, - {NT_STATUS_FLOAT_UNDERFLOW, ERANGE}, - {NT_STATUS_INTEGER_OVERFLOW, ERANGE}, - {NT_STATUS_MEDIA_WRITE_PROTECTED, EROFS}, - {NT_STATUS_PIPE_CONNECTED, EISCONN}, - {NT_STATUS_MEMORY_NOT_ALLOCATED, EFAULT}, - {NT_STATUS_FLOAT_INEXACT_RESULT, ERANGE}, - {NT_STATUS_ILL_FORMED_PASSWORD, EACCES}, - {NT_STATUS_PASSWORD_RESTRICTION, EACCES}, - {NT_STATUS_ACCOUNT_RESTRICTION, EACCES}, - {NT_STATUS_PORT_CONNECTION_REFUSED, ECONNREFUSED}, - {NT_STATUS_NAME_TOO_LONG, ENAMETOOLONG}, - {NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN}, - {NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED}, - {NT_STATUS_CONNECTION_RESET, ENETRESET}, -#ifdef ENOTUNIQ - {NT_STATUS_IP_ADDRESS_CONFLICT1, ENOTUNIQ}, - {NT_STATUS_IP_ADDRESS_CONFLICT2, ENOTUNIQ}, -#endif - {NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE}, - {NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT}, - {NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE}, - {NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, - {NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, - {NT_STATUS_RETRY, EAGAIN}, -#ifdef ENOTUNIQ - {NT_STATUS_DUPLICATE_NAME, ENOTUNIQ}, -#endif -#ifdef ECOMM - {NT_STATUS_NET_WRITE_FAULT, ECOMM}, -#endif -#ifdef EXDEV - {NT_STATUS_NOT_SAME_DEVICE, EXDEV}, -#endif - {NT_STATUS(0), 0} -}; - -/**************************************************************************** - The following mappings need tidying up and moving into libsmb/errormap.c... -****************************************************************************/ - -static int cli_errno_from_nt(NTSTATUS status) -{ - int i; - DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", NT_STATUS_V(status))); - - /* Status codes without this bit set are not errors */ - - if (!(NT_STATUS_V(status) & 0xc0000000)) { - return 0; - } - - for (i=0;nt_errno_map[i].error;i++) { - if (NT_STATUS_V(nt_errno_map[i].status) == - NT_STATUS_V(status)) return nt_errno_map[i].error; - } - - /* for all other cases - a default code */ - return EINVAL; -} /* Return a UNIX errno appropriate for the error received in the last packet. */ @@ -382,7 +246,7 @@ int cli_errno(struct cli_state *cli) if (cli_is_nt_error(cli)) { status = cli_nt_error(cli); - return cli_errno_from_nt(status); + return map_errno_from_nt_status(status); } if (cli_is_dos_error(cli)) { @@ -391,7 +255,7 @@ int cli_errno(struct cli_state *cli) cli_dos_error(cli, &eclass, &ecode); status = dos_to_ntstatus(eclass, ecode); - return cli_errno_from_nt(status); + return map_errno_from_nt_status(status); } /* diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index a2f3477b76..80e44e51fc 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -133,26 +133,6 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, return NT_STATUS_OK; } -static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode) -{ - return SMB_VFS_NEXT_MKDIR(handle, path, mode); -} - -static int rmdir_acl_xattr(vfs_handle_struct *handle, const char *path) -{ - return SMB_VFS_NEXT_RMDIR(handle, path); -} - -static int open_acl_xattr(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) -{ - return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); -} - -static int unlink_acl_xattr(vfs_handle_struct *handle, const char *fname) -{ - return SMB_VFS_NEXT_UNLINK(handle, fname); -} - static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, files_struct *fsp, const char *name, @@ -198,6 +178,42 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, return status; } +static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + return SMB_VFS_NEXT_MKDIR(handle, path, mode); +} + +/********************************************************************* + * Currently this only works for existing files. Need to work on + * inheritance for new files. +*********************************************************************/ + +static int open_acl_xattr(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) +{ + uint32_t access_granted = 0; + SEC_DESC *pdesc = NULL; + NTSTATUS status = get_nt_acl_xattr_internal(handle, + NULL, + fname, + (OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION), + &pdesc); + if (NT_STATUS_IS_OK(status)) { + /* See if we can access it. */ + if (!se_access_check(pdesc, + handle->conn->server_info->ptok, + fsp->access_mask, + &access_granted, + &status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + } + + return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); +} + static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) { @@ -312,9 +328,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, static vfs_op_tuple skel_op_tuples[] = { {SMB_VFS_OP(mkdir_acl_xattr), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT}, - {SMB_VFS_OP(rmdir_acl_xattr), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(open_acl_xattr), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT}, - {SMB_VFS_OP(unlink_acl_xattr),SMB_VFS_OP_UNLINK,SMB_VFS_LAYER_TRANSPARENT}, /* NT File ACL operations */ -- cgit