From 2009229c84e101bf7549276a7a5ac0cbe15d661c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Sep 2008 19:41:42 +0200 Subject: Make use of TALLOC_ZERO_P --- source3/libsmb/clientgen.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9d65fb4e94..8a5aedfde5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -464,13 +464,11 @@ struct cli_state *cli_initialise(void) return NULL; } - cli = talloc(NULL, struct cli_state); + cli = TALLOC_ZERO_P(NULL, struct cli_state); if (!cli) { return NULL; } - ZERO_STRUCTP(cli); - cli->port = 0; cli->fd = -1; cli->cnum = -1; -- cgit From 7e5f345cfe2f553bca65deccb4b47f19f9208a5b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 21 Sep 2008 18:09:55 +0200 Subject: Fix the build -- appweb is no more --- source3/samba4.m4 | 1 - 1 file changed, 1 deletion(-) (limited to 'source3') diff --git a/source3/samba4.m4 b/source3/samba4.m4 index c02d3d4b3b..728fd2d45d 100644 --- a/source3/samba4.m4 +++ b/source3/samba4.m4 @@ -95,7 +95,6 @@ m4_include(ntvfs/unixuid/config.m4) m4_include(auth/config.m4) m4_include(kdc/config.m4) m4_include(ntvfs/sysdep/config.m4) -m4_include(lib/appweb/config.m4) m4_include(nsswitch/config.m4) dnl Samba 4 files -- cgit From 2331c96d28fe713d37b421924e610eef80cc8d91 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 20 Sep 2008 17:02:00 +0200 Subject: build: rebuild only changed IDL files. Let"s see how this works now. Guenther --- source3/script/build_idl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/script/build_idl.sh b/source3/script/build_idl.sh index 8ff5dcd949..2027fd3937 100755 --- a/source3/script/build_idl.sh +++ b/source3/script/build_idl.sh @@ -19,7 +19,7 @@ for f in ${IDL_FILES}; do basename=`basename $f .idl` ndr="librpc/gen_ndr/ndr_$basename.c" - if [ -f $ndr ] && false; then + if [ -f $ndr ]; then if [ "x`find librpc/idl/$f -newer $ndr -print`" = "xlibrpc/idl/$f" ]; then list="$list librpc/idl/$f" fi -- cgit From 1f9624175ab35fe5c4012e931a165d422bf26fdb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 20 Sep 2008 17:00:30 +0200 Subject: netlogon: add init_netr_CryptPassword. Guenther --- source3/include/proto.h | 3 +++ source3/rpc_client/init_netlogon.c | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 2901911c70..bec5f10f3c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7427,6 +7427,9 @@ void init_netr_PasswordInfo(struct netr_PasswordInfo *r, const char *workstation, struct samr_Password lmpassword, struct samr_Password ntpassword); +void init_netr_CryptPassword(const char *pwd, + unsigned char session_key[16], + struct netr_CryptPassword *pwd_buf); /* The following definitions come from rpc_client/init_samr.c */ diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c index 61841953fc..e4c39e739e 100644 --- a/source3/rpc_client/init_netlogon.c +++ b/source3/rpc_client/init_netlogon.c @@ -391,3 +391,20 @@ void init_netr_PasswordInfo(struct netr_PasswordInfo *r, r->lmpassword = lmpassword; r->ntpassword = ntpassword; } + +/************************************************************************* + inits a netr_CryptPassword structure + *************************************************************************/ + +void init_netr_CryptPassword(const char *pwd, + unsigned char session_key[16], + struct netr_CryptPassword *pwd_buf) +{ + struct samr_CryptPassword password_buf; + + encode_pw_buffer(password_buf.data, pwd, STR_UNICODE); + + SamOEMhash(password_buf.data, session_key, 516); + memcpy(pwd_buf->data, password_buf.data, 512); + pwd_buf->length = IVAL(password_buf.data, 512); +} -- cgit From ca56c02d4bdfa26f5eda16c5621dcac67d7458ef Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 20 Sep 2008 17:01:20 +0200 Subject: netlogon: use init_netr_CryptPassword in "just_change_the_password" Guenther --- source3/libsmb/trusts_util.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 08a49930b4..9265c60665 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -57,24 +57,21 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX struct netr_Authenticator clnt_creds, srv_cred; struct netr_CryptPassword new_password; - struct samr_CryptPassword password_buf; netlogon_creds_client_step(cli->dc, &clnt_creds); - encode_pw_buffer(password_buf.data, new_trust_pwd_cleartext, STR_UNICODE); - - SamOEMhash(password_buf.data, cli->dc->sess_key, 516); - memcpy(new_password.data, password_buf.data, 512); - new_password.length = IVAL(password_buf.data, 512); + init_netr_CryptPassword(new_trust_pwd_cleartext, + cli->dc->sess_key, + &new_password); result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx, - cli->dc->remote_machine, - cli->dc->mach_acct, - sec_channel_type, - global_myname(), - &clnt_creds, - &srv_cred, - &new_password); + cli->dc->remote_machine, + cli->dc->mach_acct, + sec_channel_type, + global_myname(), + &clnt_creds, + &srv_cred, + &new_password); /* Always check returned credentials. */ if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { -- cgit From 6f9a83505fced805f5a4d4827ddf7300eda6aaa0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 20 Sep 2008 18:20:29 +0200 Subject: netlogon: refactor just_change_the_password a bit. Guenther --- source3/libsmb/trusts_util.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'source3') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 9265c60665..7897d51717 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -37,6 +37,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX { NTSTATUS result; uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; + struct netr_Authenticator clnt_creds, srv_cred; result = rpccli_netlogon_setup_creds(cli, cli->desthost, /* server name */ @@ -53,13 +54,12 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX return result; } + netlogon_creds_client_step(cli->dc, &clnt_creds); + if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) { - struct netr_Authenticator clnt_creds, srv_cred; struct netr_CryptPassword new_password; - netlogon_creds_client_step(cli->dc, &clnt_creds); - init_netr_CryptPassword(new_trust_pwd_cleartext, cli->dc->sess_key, &new_password); @@ -72,21 +72,15 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX &clnt_creds, &srv_cred, &new_password); - - /* Always check returned credentials. */ - if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { - DEBUG(0,("rpccli_netr_ServerPasswordSet2: " - "credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("rpccli_netr_ServerPasswordSet2 failed: %s\n", + nt_errstr(result))); + return result; } - } else { - struct netr_Authenticator clnt_creds, srv_cred; struct samr_Password new_password; - netlogon_creds_client_step(cli->dc, &clnt_creds); - cred_hash3(new_password.hash, new_trust_passwd_hash, cli->dc->sess_key, 1); @@ -99,19 +93,19 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX &clnt_creds, &srv_cred, &new_password); - - /* Always check returned credentials. */ - if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { - DEBUG(0,("rpccli_netr_ServerPasswordSet: " - "credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("rpccli_netr_ServerPasswordSet failed: %s\n", + nt_errstr(result))); + return result; } } - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", - nt_errstr(result))); + /* Always check returned credentials. */ + if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; } + return result; } -- cgit From e194ded26e716fad510191f85e67ff1d775bdcb8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 21 Sep 2008 18:57:26 +0200 Subject: netlogon: move password change code out to rpccli_netlogon_set_trust_password. Guenther --- source3/include/proto.h | 6 +++ source3/libsmb/trusts_util.c | 99 ++------------------------------------- source3/rpc_client/cli_netlogon.c | 91 +++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 94 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index bec5f10f3c..194548c082 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7049,6 +7049,12 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, DATA_BLOB lm_response, DATA_BLOB nt_response, struct netr_SamInfo3 **info3); +NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const unsigned char orig_trust_passwd_hash[16], + const char *new_trust_pwd_cleartext, + const unsigned char new_trust_passwd_hash[16], + uint32_t sec_channel_type); /* The following definitions come from rpc_client/cli_pipe.c */ diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 7897d51717..2f336f14e6 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -20,95 +20,6 @@ #include "includes.h" -/********************************************************* - Change the domain password on the PDC. - - Just changes the password betwen the two values specified. - - Caller must have the cli connected to the netlogon pipe - already. -**********************************************************/ - -static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - const unsigned char orig_trust_passwd_hash[16], - const char *new_trust_pwd_cleartext, - const unsigned char new_trust_passwd_hash[16], - uint32 sec_channel_type) -{ - NTSTATUS result; - uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; - struct netr_Authenticator clnt_creds, srv_cred; - - result = rpccli_netlogon_setup_creds(cli, - cli->desthost, /* server name */ - lp_workgroup(), /* domain */ - global_myname(), /* client name */ - global_myname(), /* machine account name */ - orig_trust_passwd_hash, - sec_channel_type, - &neg_flags); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", - nt_errstr(result))); - return result; - } - - netlogon_creds_client_step(cli->dc, &clnt_creds); - - if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) { - - struct netr_CryptPassword new_password; - - init_netr_CryptPassword(new_trust_pwd_cleartext, - cli->dc->sess_key, - &new_password); - - result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx, - cli->dc->remote_machine, - cli->dc->mach_acct, - sec_channel_type, - global_myname(), - &clnt_creds, - &srv_cred, - &new_password); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("rpccli_netr_ServerPasswordSet2 failed: %s\n", - nt_errstr(result))); - return result; - } - } else { - - struct samr_Password new_password; - - cred_hash3(new_password.hash, - new_trust_passwd_hash, - cli->dc->sess_key, 1); - - result = rpccli_netr_ServerPasswordSet(cli, mem_ctx, - cli->dc->remote_machine, - cli->dc->mach_acct, - sec_channel_type, - global_myname(), - &clnt_creds, - &srv_cred, - &new_password); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("rpccli_netr_ServerPasswordSet failed: %s\n", - nt_errstr(result))); - return result; - } - } - - /* Always check returned credentials. */ - if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { - DEBUG(0,("credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } - - return result; -} - /********************************************************* Change the domain password on the PDC. Store the password ourselves, but use the supplied password @@ -135,11 +46,11 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m E_md4hash(new_trust_passwd, new_trust_passwd_hash); - nt_status = just_change_the_password(cli, mem_ctx, - orig_trust_passwd_hash, - new_trust_passwd, - new_trust_passwd_hash, - sec_channel_type); + nt_status = rpccli_netlogon_set_trust_password(cli, mem_ctx, + orig_trust_passwd_hash, + new_trust_passwd, + new_trust_passwd_hash, + sec_channel_type); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index df87ed13d1..23618efd9f 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -538,3 +538,94 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, return result; } + +/********************************************************* + Change the domain password on the PDC. + + Just changes the password betwen the two values specified. + + Caller must have the cli connected to the netlogon pipe + already. +**********************************************************/ + +NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const unsigned char orig_trust_passwd_hash[16], + const char *new_trust_pwd_cleartext, + const unsigned char new_trust_passwd_hash[16], + uint32_t sec_channel_type) +{ + NTSTATUS result; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; + struct netr_Authenticator clnt_creds, srv_cred; + + result = rpccli_netlogon_setup_creds(cli, + cli->desthost, /* server name */ + lp_workgroup(), /* domain */ + global_myname(), /* client name */ + global_myname(), /* machine account name */ + orig_trust_passwd_hash, + sec_channel_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3,("rpccli_netlogon_set_trust_password: unable to setup creds (%s)!\n", + nt_errstr(result))); + return result; + } + + netlogon_creds_client_step(cli->dc, &clnt_creds); + + if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) { + + struct netr_CryptPassword new_password; + + init_netr_CryptPassword(new_trust_pwd_cleartext, + cli->dc->sess_key, + &new_password); + + result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx, + cli->dc->remote_machine, + cli->dc->mach_acct, + sec_channel_type, + global_myname(), + &clnt_creds, + &srv_cred, + &new_password); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("rpccli_netr_ServerPasswordSet2 failed: %s\n", + nt_errstr(result))); + return result; + } + } else { + + struct samr_Password new_password; + + cred_hash3(new_password.hash, + new_trust_passwd_hash, + cli->dc->sess_key, 1); + + result = rpccli_netr_ServerPasswordSet(cli, mem_ctx, + cli->dc->remote_machine, + cli->dc->mach_acct, + sec_channel_type, + global_myname(), + &clnt_creds, + &srv_cred, + &new_password); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("rpccli_netr_ServerPasswordSet failed: %s\n", + nt_errstr(result))); + return result; + } + } + + /* Always check returned credentials. */ + if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + + return result; +} + -- cgit From 73aebd7d070099d4d6d6da98817f42937bc7fd03 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 21 Sep 2008 20:39:17 +0200 Subject: Attempt to fix bug 5778 Jeff, Steve, please check! --- source3/client/mount.cifs.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3') diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 3b56e5f861..b7a76c6102 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -56,6 +56,10 @@ #endif /* _SAMBA_BUILD_ */ #endif /* MOUNT_CIFS_VENDOR_SUFFIX */ +#ifdef _SAMBA_BUILD_ +#include "include/config.h" +#endif + #ifndef MS_MOVE #define MS_MOVE 8192 #endif @@ -94,6 +98,8 @@ char * prefixpath = NULL; /* like strncpy but does not 0 fill the buffer and always null * terminates. bufsize is the size of the destination buffer */ + +#ifndef HAVE_STRLCPY static size_t strlcpy(char *d, const char *s, size_t bufsize) { size_t len = strlen(s); @@ -104,10 +110,13 @@ static size_t strlcpy(char *d, const char *s, size_t bufsize) d[len] = 0; return ret; } +#endif /* like strncat but does not 0 fill the buffer and always null * terminates. bufsize is the length of the buffer, which should * be one more than the maximum resulting string length */ + +#ifndef HAVE_STRLCAT static size_t strlcat(char *d, const char *s, size_t bufsize) { size_t len1 = strlen(d); @@ -126,6 +135,7 @@ static size_t strlcat(char *d, const char *s, size_t bufsize) } return ret; } +#endif /* BB finish BB -- cgit From bc794246df473b2e1a12694671afd51da14af5ad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 21 Sep 2008 23:57:59 +0200 Subject: Fix merged build. --- source3/samba4.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/samba4.mk b/source3/samba4.mk index 294eef8b8f..2646b12a0d 100644 --- a/source3/samba4.mk +++ b/source3/samba4.mk @@ -7,7 +7,7 @@ PARTLINK = $(PROG_LD) -r MDLD = $(SHLD) MDLD_FLAGS = $(LDSHFLAGS) -samba4srcdir = $(call abspath,$(srcdir)/../source4) +samba4srcdir = $(srcdir)/../source4 # Flags used for the samba 4 files # $(srcdir)/include is required for config.h @@ -83,7 +83,6 @@ libcmdlinesrcdir := $(samba4srcdir)/lib/cmdline poptsrcdir := $(samba4srcdir)/../lib/popt socketwrappersrcdir := $(samba4srcdir)/../lib/socket_wrapper nsswrappersrcdir := $(samba4srcdir)/../lib/nss_wrapper -appwebsrcdir := $(samba4srcdir)/lib/appweb libstreamsrcdir := $(samba4srcdir)/lib/stream libutilsrcdir := $(samba4srcdir)/lib/util libtdrsrcdir := $(samba4srcdir)/lib/tdr @@ -108,7 +107,6 @@ ntvfssrcdir := $(samba4srcdir)/ntvfs ntptrsrcdir := $(samba4srcdir)/ntptr clientsrcdir := $(samba4srcdir)/client libclisrcdir := $(samba4srcdir)/libcli -ejsscriptsrcdir := $(samba4srcdir)/scripting/ejs pyscriptsrcdir := $(samba4srcdir)/scripting/python kdcsrcdir := $(samba4srcdir)/kdc smbreadlinesrcdir := $(samba4srcdir)/lib/smbreadline @@ -116,6 +114,7 @@ ntp_signdsrcdir := $(samba4srcdir)/ntp_signd tdbsrcdir := $(samba4srcdir)/../lib/tdb ldbsrcdir := $(samba4srcdir)/lib/ldb tallocsrcdir := $(samba4srcdir)/../lib/talloc +comsrcdir := $(samba4srcdir)/lib/com override ASN1C = bin/asn1_compile4 override ET_COMPILER = bin/compile_et4 include samba4-data.mk -- cgit From 2c7cbb6b1d54c0463fd788002190ee673179f7c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 Sep 2008 23:46:10 +0200 Subject: s3: link libreplace/test/main.c into replacetort metze --- source3/Makefile.in | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 2300e4a20c..2ae7e15bf4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -953,6 +953,7 @@ REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \ @libreplacedir@/test/getifaddrs.o \ @libreplacedir@/test/os2_delete.o \ @libreplacedir@/test/strptime.o \ + @libreplacedir@/test/main.o \ $(LIBREPLACE_OBJ) NDRDUMP_OBJ = librpc/tools/ndrdump.o \ -- cgit From b7e2c74cef708dfaf7a22de8d68382b9a5f2cf57 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Sep 2008 00:21:26 +0200 Subject: s3: link @tallocdir@/testsuite_main.o into talloctort metze --- source3/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 2ae7e15bf4..8304981a1f 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -946,8 +946,8 @@ SHARESEC_OBJ = $(SHARESEC_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBSAMBA_OBJ) \ $(POPT_LIB_OBJ) -TALLOCTORT_OBJ = @tallocdir@/testsuite.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ - $(LIBSAMBA_OBJ) +TALLOCTORT_OBJ = @tallocdir@/testsuite.o @tallocdir@/testsuite_main.o \ + $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSAMBA_OBJ) REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \ @libreplacedir@/test/getifaddrs.o \ -- cgit From ba58d17e6981dcf6775c1706ff21afa6c5849ede Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 22 Sep 2008 19:31:44 +0200 Subject: netapi: fix case statement in example NetUserSetModals code. Guenther --- source3/lib/netapi/examples/user/user_modalsset.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3') diff --git a/source3/lib/netapi/examples/user/user_modalsset.c b/source3/lib/netapi/examples/user/user_modalsset.c index 57e1ef70ea..c6958a9012 100644 --- a/source3/lib/netapi/examples/user/user_modalsset.c +++ b/source3/lib/netapi/examples/user/user_modalsset.c @@ -95,6 +95,7 @@ int main(int argc, const char **argv) case 1: case 2: case 3: + break; case 1001: u1001.usrmod1001_min_passwd_len = 0; buffer = (uint8_t *)&u1001; -- cgit From b47953ea105a04a3d62259f1cbf5aea2f7910173 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 Sep 2008 17:24:37 +0200 Subject: netapi: add NetFile testsuite. Guenther --- source3/lib/netapi/tests/Makefile.in | 2 +- source3/lib/netapi/tests/common.h | 2 + source3/lib/netapi/tests/netapitest.c | 5 ++ source3/lib/netapi/tests/netfile.c | 143 ++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 source3/lib/netapi/tests/netfile.c (limited to 'source3') diff --git a/source3/lib/netapi/tests/Makefile.in b/source3/lib/netapi/tests/Makefile.in index 0145753212..659f82c9d8 100644 --- a/source3/lib/netapi/tests/Makefile.in +++ b/source3/lib/netapi/tests/Makefile.in @@ -44,7 +44,7 @@ bin/.dummy: CMDLINE_OBJ = common.o NETAPIBUFFER_OBJ = netapibuffer.o -NETAPITEST_OBJ = netapitest.o netlocalgroup.o netuser.o netgroup.o netdisplay.o netshare.o $(CMDLINE_OBJ) +NETAPITEST_OBJ = netapitest.o netlocalgroup.o netuser.o netgroup.o netdisplay.o netshare.o netfile.o $(CMDLINE_OBJ) bin/netapitest@EXEEXT@: $(BINARY_PREREQS) $(NETAPITEST_OBJ) @echo Linking $@ diff --git a/source3/lib/netapi/tests/common.h b/source3/lib/netapi/tests/common.h index 5a320321ba..9320840909 100644 --- a/source3/lib/netapi/tests/common.h +++ b/source3/lib/netapi/tests/common.h @@ -41,6 +41,8 @@ NET_API_STATUS netapitest_display(struct libnetapi_ctx *ctx, const char *hostname); NET_API_STATUS netapitest_share(struct libnetapi_ctx *ctx, const char *hostname); +NET_API_STATUS netapitest_file(struct libnetapi_ctx *ctx, + const char *hostname); #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) diff --git a/source3/lib/netapi/tests/netapitest.c b/source3/lib/netapi/tests/netapitest.c index 87144020f5..4a38f721d8 100644 --- a/source3/lib/netapi/tests/netapitest.c +++ b/source3/lib/netapi/tests/netapitest.c @@ -84,6 +84,11 @@ int main(int argc, const char **argv) goto out; } + status = netapitest_file(ctx, hostname); + if (status) { + goto out; + } + out: if (status != 0) { printf("testsuite failed with: %s\n", diff --git a/source3/lib/netapi/tests/netfile.c b/source3/lib/netapi/tests/netfile.c new file mode 100644 index 0000000000..36ee8288ee --- /dev/null +++ b/source3/lib/netapi/tests/netfile.c @@ -0,0 +1,143 @@ +/* + * Unix SMB/CIFS implementation. + * NetFile testsuite + * Copyright (C) Guenther Deschner 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 +#include +#include +#include +#include + +#include + +#include "common.h" + +static NET_API_STATUS test_netfileenum(const char *hostname, + uint32_t level) +{ + NET_API_STATUS status; + uint32_t entries_read = 0; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + uint8_t *buffer = NULL; + int i; + + struct FILE_INFO_2 *i2; + struct FILE_INFO_3 *i3; + + printf("testing NetFileEnum level %d\n", level); + + do { + status = NetFileEnum(hostname, + NULL, + NULL, + level, + &buffer, + (uint32_t)-1, + &entries_read, + &total_entries, + &resume_handle); + if (status == 0 || status == ERROR_MORE_DATA) { + switch (level) { + case 2: + i2 = (struct FILE_INFO_2 *)buffer; + break; + case 3: + i3 = (struct FILE_INFO_3 *)buffer; + break; + default: + return -1; + } + + for (i=0; i Date: Tue, 16 Sep 2008 16:04:31 +0200 Subject: netapi: add more fields to USER_INFO_X. Guenther --- source3/librpc/idl/libnetapi.idl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3') diff --git a/source3/librpc/idl/libnetapi.idl b/source3/librpc/idl/libnetapi.idl index 039dcf4152..f2f4a16c12 100644 --- a/source3/librpc/idl/libnetapi.idl +++ b/source3/librpc/idl/libnetapi.idl @@ -517,7 +517,9 @@ interface libnetapi uint32 usriX_code_page; string usriX_profile; string usriX_home_dir_drive; + uint32 usriX_user_id; uint32 usriX_primary_group_id; + uint32 usriX_password_expired; } USER_INFO_X; [nopush,nopull] NET_API_STATUS NetUserAdd( -- cgit From 92ebd6afc9a1979d5a08af1f7964032763d8fc5b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 16 Sep 2008 16:04:43 +0200 Subject: re-run make idl. Guenther --- source3/librpc/gen_ndr/libnetapi.h | 2 ++ source3/librpc/gen_ndr/ndr_libnetapi.c | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'source3') diff --git a/source3/librpc/gen_ndr/libnetapi.h b/source3/librpc/gen_ndr/libnetapi.h index 98da9e12ea..ae7acbf572 100644 --- a/source3/librpc/gen_ndr/libnetapi.h +++ b/source3/librpc/gen_ndr/libnetapi.h @@ -413,7 +413,9 @@ struct USER_INFO_X { uint32_t usriX_code_page; const char * usriX_profile; const char * usriX_home_dir_drive; + uint32_t usriX_user_id; uint32_t usriX_primary_group_id; + uint32_t usriX_password_expired; }; struct GROUP_USERS_INFO_0 { diff --git a/source3/librpc/gen_ndr/ndr_libnetapi.c b/source3/librpc/gen_ndr/ndr_libnetapi.c index a5266827b6..d7bf63e62f 100644 --- a/source3/librpc/gen_ndr/ndr_libnetapi.c +++ b/source3/librpc/gen_ndr/ndr_libnetapi.c @@ -1895,7 +1895,9 @@ _PUBLIC_ enum ndr_err_code ndr_push_USER_INFO_X(struct ndr_push *ndr, int ndr_fl NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_code_page)); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->usriX_profile)); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->usriX_home_dir_drive)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_user_id)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_primary_group_id)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_password_expired)); } if (ndr_flags & NDR_BUFFERS) { if (r->usriX_logon_hours) { @@ -1942,7 +1944,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_USER_INFO_X(struct ndr_pull *ndr, int ndr_fl NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_code_page)); NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->usriX_profile)); NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->usriX_home_dir_drive)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_user_id)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_primary_group_id)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_password_expired)); } if (ndr_flags & NDR_BUFFERS) { if (r->usriX_logon_hours) { @@ -1990,7 +1994,9 @@ _PUBLIC_ void ndr_print_USER_INFO_X(struct ndr_print *ndr, const char *name, con ndr_print_uint32(ndr, "usriX_code_page", r->usriX_code_page); ndr_print_string(ndr, "usriX_profile", r->usriX_profile); ndr_print_string(ndr, "usriX_home_dir_drive", r->usriX_home_dir_drive); + ndr_print_uint32(ndr, "usriX_user_id", r->usriX_user_id); ndr_print_uint32(ndr, "usriX_primary_group_id", r->usriX_primary_group_id); + ndr_print_uint32(ndr, "usriX_password_expired", r->usriX_password_expired); ndr->depth--; } -- cgit From 7d5fb989ac9942a6f3394853f6930d34ef6adf7b Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Fri, 19 Sep 2008 12:27:15 -0500 Subject: idmap_adex: Add new idmap plugin for support RFC2307 enabled AD forests. The adex idmap/nss_info plugin is an adapation of the Likewise Enterprise plugin with support for OU based cells removed (since the Windows pieces to manage the cells are not available). This plugin supports * The RFC2307 schema for users and groups. * Connections to trusted domains * Global catalog searches * Cross forest trusts * User and group aliases Prerequiste: Add the following attributes to the Partial Attribute Set in global catalog: * uidNumber * uid * gidNumber A basic config using the current trunk code would look like [global] idmap backend = adex idmap uid = 10000 - 19999 idmap gid = 20000 - 29999 idmap config US:backend = adex idmap config US:range = 20000 - 29999 winbind nss info = adex winbind normalize names = yes winbind refresh tickets = yes template homedir = /home/%D/%U template shell = /bin/bash --- source3/Makefile.in | 12 + source3/configure.in | 1 + source3/winbindd/idmap_adex/cell_util.c | 292 ++++++ source3/winbindd/idmap_adex/domain_util.c | 278 ++++++ source3/winbindd/idmap_adex/gc_util.c | 848 +++++++++++++++++ source3/winbindd/idmap_adex/idmap_adex.c | 460 +++++++++ source3/winbindd/idmap_adex/idmap_adex.h | 257 ++++++ source3/winbindd/idmap_adex/likewise_cell.c | 425 +++++++++ source3/winbindd/idmap_adex/provider_unified.c | 1180 ++++++++++++++++++++++++ 9 files changed, 3753 insertions(+) create mode 100644 source3/winbindd/idmap_adex/cell_util.c create mode 100644 source3/winbindd/idmap_adex/domain_util.c create mode 100644 source3/winbindd/idmap_adex/gc_util.c create mode 100644 source3/winbindd/idmap_adex/idmap_adex.c create mode 100644 source3/winbindd/idmap_adex/idmap_adex.h create mode 100644 source3/winbindd/idmap_adex/likewise_cell.c create mode 100644 source3/winbindd/idmap_adex/provider_unified.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 8304981a1f..1ce0ce9067 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -985,6 +985,14 @@ IDMAP_HASH_OBJ = \ winbindd/idmap_hash/idmap_hash.o \ winbindd/idmap_hash/mapfile.o +IDMAP_ADEX_OBJ = \ + winbindd/idmap_adex/idmap_adex.o \ + winbindd/idmap_adex/cell_util.o \ + winbindd/idmap_adex/likewise_cell.o \ + winbindd/idmap_adex/provider_unified.o \ + winbindd/idmap_adex/gc_util.o \ + winbindd/idmap_adex/domain_util.o + WINBINDD_OBJ1 = \ winbindd/winbindd.o \ winbindd/winbindd_user.o \ @@ -2218,6 +2226,10 @@ bin/hash.@SHLIBEXT@: $(BINARY_PREREQS) $(IDMAP_HASH_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(IDMAP_HASH_OBJ) +bin/adex.@SHLIBEXT@: $(BINARY_PREREQS) $(IDMAP_ADEX_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(IDMAP_ADEX_OBJ) + bin/tdb2.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_tdb2.o @echo "Building plugin $@" @$(SHLD_MODULE) winbindd/idmap_tdb2.o diff --git a/source3/configure.in b/source3/configure.in index 640afc47fb..d1000d9a52 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -6058,6 +6058,7 @@ SMB_MODULE(idmap_nss, winbindd/idmap_nss.o, "bin/nss.$SHLIBEXT", IDMAP) SMB_MODULE(idmap_rid, winbindd/idmap_rid.o, "bin/rid.$SHLIBEXT", IDMAP) SMB_MODULE(idmap_ad, winbindd/idmap_ad.o, "bin/ad.$SHLIBEXT", IDMAP) SMB_MODULE(idmap_hash, \$(IDMAP_HASH_OBJ), "bin/hash.$SHLIBEXT", IDMAP) +SMB_MODULE(idmap_adex, \$(IDMAP_ADEX_OBJ), "bin/adex.$SHLIBEXT", IDMAP) SMB_SUBSYSTEM(IDMAP, winbindd/idmap.o) SMB_MODULE(nss_info_template, winbindd/nss_info_template.o, "bin/template.$SHLIBEXT", NSS_INFO) diff --git a/source3/winbindd/idmap_adex/cell_util.c b/source3/winbindd/idmap_adex/cell_util.c new file mode 100644 index 0000000000..f5c08a0454 --- /dev/null +++ b/source3/winbindd/idmap_adex/cell_util.c @@ -0,0 +1,292 @@ +/* + * idmap_adex: Support for AD Forests + * + * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "idmap_adex.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +/********************************************************************** +**********************************************************************/ + + char *find_attr_string(char **list, size_t num_lines, const char *substr) +{ + int i; + int cmplen = strlen(substr); + + for (i = 0; i < num_lines; i++) { + /* make sure to avoid substring matches like uid + and uidNumber */ + if ((StrnCaseCmp(list[i], substr, cmplen) == 0) && + (list[i][cmplen] == '=')) { + /* Don't return an empty string */ + if (list[i][cmplen + 1] != '\0') + return &(list[i][cmplen + 1]); + + return NULL; + } + } + + return NULL; +} + +/********************************************************************** +**********************************************************************/ + + bool is_object_class(char **list, size_t num_lines, const char *substr) +{ + int i; + + for (i = 0; i < num_lines; i++) { + if (strequal(list[i], substr)) { + return true; + } + } + + return false; +} + +/********************************************************************** + Find out about the cell (e.g. use2307Attrs, etc...) +**********************************************************************/ + + NTSTATUS cell_lookup_settings(struct likewise_cell * cell) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + + /* Parameter check */ + + if (!cell) { + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Only supporting Forest-wide, schema based searches */ + + cell_set_flags(cell, LWCELL_FLAG_USE_RFC2307_ATTRS); + cell_set_flags(cell, LWCELL_FLAG_SEARCH_FOREST); + + cell->provider = &ccp_unified; + + nt_status = NT_STATUS_OK; + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("LWI: Failed to obtain cell settings (%s)\n", + nt_errstr(nt_status))); + } + + return nt_status; +} + + +static NTSTATUS cell_lookup_forest(struct likewise_cell *c) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct gc_info *gc = NULL; + + if (!c) { + return NT_STATUS_INVALID_PARAMETER; + } + + if ((gc = TALLOC_ZERO_P(NULL, struct gc_info)) == NULL) { + nt_status = NT_STATUS_NO_MEMORY; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Query the rootDSE for the forest root naming conect first. + Check that the a GC server for the forest has not already + been added */ + + nt_status = gc_find_forest_root(gc, cell_dns_domain(c)); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + c->forest_name = talloc_strdup(c, gc->forest_name); + BAIL_ON_PTR_ERROR(c->forest_name, nt_status); + +done: + if (gc) { + talloc_free(gc); + } + + return nt_status; +} + +/********************************************************************** +**********************************************************************/ + + NTSTATUS cell_locate_membership(ADS_STRUCT * ads) +{ + ADS_STATUS status; + char *domain_dn = ads_build_dn(lp_realm()); + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + DOM_SID sid; + struct likewise_cell *cell = NULL; + + /* In the Likewise plugin, I had to support the concept of cells + based on the machine's membership in an OU. However, now I'll + just assume our membership in the forest cell */ + + DEBUG(2, ("locate_cell_membership: Located membership " + "in cell \"%s\"\n", domain_dn)); + + if ((cell = cell_new()) == NULL) { + nt_status = NT_STATUS_NO_MEMORY; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + status = ads_domain_sid(ads, &sid); + if (!ADS_ERR_OK(status)) { + DEBUG(3,("locate_cell_membership: Failed to find " + "domain SID for %s\n", domain_dn)); + } + + /* save the SID and search base for our domain */ + + cell_set_dns_domain(cell, lp_realm()); + cell_set_connection(cell, ads); + cell_set_dn(cell, domain_dn); + cell_set_domain_sid(cell, &sid); + + /* Now save our forest root */ + + cell_lookup_forest(cell); + + /* Add the cell to the list */ + + if (!cell_list_add(cell)) { + nt_status = NT_STATUS_INSUFFICIENT_RESOURCES; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Done! */ + nt_status = NT_STATUS_OK; + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0,("LWI: Failed to locate cell membership (%s)\n", + nt_errstr(nt_status))); + } + + SAFE_FREE(domain_dn); + + return nt_status; +} + +/********************************************************************* + ********************************************************************/ + + int min_id_value(void) +{ + int id_val; + + id_val = lp_parm_int(-1, "lwidentity", "min_id_value", MIN_ID_VALUE); + + /* Still don't let it go below 50 */ + + return MAX(50, id_val); +} + +/******************************************************************** + *******************************************************************/ + + char *cell_dn_to_dns(const char *dn) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char *domain = NULL; + char *dns_name = NULL; + const char *tmp_dn; + char *buffer = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!dn || !*dn) { + goto done; + } + + tmp_dn = talloc_strdup(frame, dn); + BAIL_ON_PTR_ERROR(tmp_dn, nt_status); + + while (next_token_talloc(frame, &tmp_dn, &buffer, ",")) { + + /* skip everything up the where DC=... begins */ + if (StrnCaseCmp(buffer, "DC=", 3) != 0) + continue; + + if (!domain) { + domain = talloc_strdup(frame, &buffer[3]); + } else { + domain = talloc_asprintf_append(domain, ".%s", + &buffer[3]); + } + BAIL_ON_PTR_ERROR(domain, nt_status); + } + + dns_name = SMB_STRDUP(domain); + BAIL_ON_PTR_ERROR(dns_name, nt_status); + + nt_status = NT_STATUS_OK; + +done: + PRINT_NTSTATUS_ERROR(nt_status, "cell_dn_to_dns", 1); + + talloc_destroy(frame); + + return dns_name; +} + +/********************************************************************* + ********************************************************************/ + + NTSTATUS get_sid_type(ADS_STRUCT *ads, + LDAPMessage *msg, + enum lsa_SidType *type) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + uint32_t atype; + + if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) { + nt_status = NT_STATUS_INVALID_USER_BUFFER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + switch (atype &0xF0000000) { + case ATYPE_SECURITY_GLOBAL_GROUP: + *type = SID_NAME_DOM_GRP; + break; + case ATYPE_SECURITY_LOCAL_GROUP: + *type = SID_NAME_ALIAS; + break; + case ATYPE_NORMAL_ACCOUNT: + case ATYPE_WORKSTATION_TRUST: + case ATYPE_INTERDOMAIN_TRUST: + *type = SID_NAME_USER; + break; + default: + *type = SID_NAME_USE_NONE; + nt_status = NT_STATUS_INVALID_ACCOUNT_NAME; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + nt_status = NT_STATUS_OK; + +done: + return nt_status; +} diff --git a/source3/winbindd/idmap_adex/domain_util.c b/source3/winbindd/idmap_adex/domain_util.c new file mode 100644 index 0000000000..ab31ccef7a --- /dev/null +++ b/source3/winbindd/idmap_adex/domain_util.c @@ -0,0 +1,278 @@ +/* + * idmap_adex: Domain search interface + * + * Copyright (C) Gerald (Jerry) Carter 2007-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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "idmap_adex.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +struct dc_info { + struct dc_info *prev, *next; + char *dns_name; + struct likewise_cell *domain_cell; +}; + +static struct dc_info *_dc_server_list = NULL; + + +/********************************************************************** + *********************************************************************/ + +static struct dc_info *dc_list_head(void) +{ + return _dc_server_list; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS dc_add_domain(const char *domain) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct dc_info *dc = NULL; + + /* Check for duplicates */ + + dc = dc_list_head(); + while (dc) { + if (strequal (dc->dns_name, domain)) + break; + dc = dc->next; + } + + if (dc) { + DEBUG(10,("dc_add_domain: %s already in list\n", domain)); + return NT_STATUS_OK; + } + + dc = TALLOC_ZERO_P(NULL, struct dc_info); + BAIL_ON_PTR_ERROR(dc, nt_status); + + dc->dns_name = talloc_strdup(dc, domain); + BAIL_ON_PTR_ERROR(dc->dns_name, nt_status); + + DLIST_ADD_END(_dc_server_list, dc, struct dc_info*); + + nt_status = NT_STATUS_OK; + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_destroy(dc); + DEBUG(0,("LWI: Failed to add new DC connection for %s (%s)\n", + domain, nt_errstr(nt_status))); + } + + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + +static void dc_server_list_destroy(void) +{ + struct dc_info *dc = dc_list_head(); + + while (dc) { + struct dc_info *p = dc->next; + + cell_destroy(dc->domain_cell); + talloc_destroy(dc); + + dc = p; + } + + return; +} + + +/********************************************************************** + *********************************************************************/ + + NTSTATUS domain_init_list(void) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct winbindd_tdc_domain *domains = NULL; + size_t num_domains = 0; + int i; + + if (_dc_server_list != NULL) { + dc_server_list_destroy(); + } + + /* Add our domain */ + + nt_status = dc_add_domain(lp_realm()); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + if (!wcache_tdc_fetch_list(&domains, &num_domains)) { + nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Add all domains with an incoming trust path */ + + for (i=0; idomain_cell, search_base, + scope, expr, attrs, msg); + nt_status = ads_ntstatus(status); + + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + +static struct dc_info *dc_find_domain(const char *dns_domain) +{ + struct dc_info *dc = dc_list_head(); + + if (!dc) + return NULL; + + while (dc) { + if (strequal(dc->dns_name, dns_domain)) { + return dc; + } + + dc = dc->next; + } + + return NULL; +} + +/********************************************************************** + *********************************************************************/ + + NTSTATUS dc_search_domains(struct likewise_cell **cell, + LDAPMessage **msg, + const char *dn, + const DOM_SID *sid) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + TALLOC_CTX *frame = talloc_stackframe(); + char *dns_domain; + const char *attrs[] = { "*", NULL }; + struct dc_info *dc = NULL; + const char *base = NULL; + + if (!dn || !*dn) { + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + dns_domain = cell_dn_to_dns(dn); + BAIL_ON_PTR_ERROR(dns_domain, nt_status); + + if ((dc = dc_find_domain(dns_domain)) == NULL) { + nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Reparse the cell settings for the domain if necessary */ + + if (!dc->domain_cell) { + char *base_dn; + + base_dn = ads_build_dn(dc->dns_name); + BAIL_ON_PTR_ERROR(base_dn, nt_status); + + nt_status = cell_connect_dn(&dc->domain_cell, base_dn); + SAFE_FREE(base_dn); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = cell_lookup_settings(dc->domain_cell); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* By definition this is already part of a larger + forest-wide search scope */ + + cell_set_flags(dc->domain_cell, LWCELL_FLAG_SEARCH_FOREST); + } + + /* Check whether we are operating in non-schema or RFC2307 + mode */ + + if (cell_flags(dc->domain_cell) & LWCELL_FLAG_USE_RFC2307_ATTRS) { + nt_status = dc_do_search(dc, dn, LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, msg); + } else { + const char *sid_str = NULL; + char *filter = NULL; + + sid_str = sid_string_talloc(frame, sid); + BAIL_ON_PTR_ERROR(sid_str, nt_status); + + filter = talloc_asprintf(frame, "(keywords=backLink=%s)", + sid_str); + BAIL_ON_PTR_ERROR(filter, nt_status); + + base = cell_search_base(dc->domain_cell); + BAIL_ON_PTR_ERROR(base, nt_status); + + nt_status = dc_do_search(dc, base, LDAP_SCOPE_SUBTREE, + filter, attrs, msg); + } + BAIL_ON_NTSTATUS_ERROR(nt_status); + + *cell = dc->domain_cell; + +done: + talloc_destroy(CONST_DISCARD(char*, base)); + talloc_destroy(frame); + + return nt_status; +} diff --git a/source3/winbindd/idmap_adex/gc_util.c b/source3/winbindd/idmap_adex/gc_util.c new file mode 100644 index 0000000000..87dd3c058d --- /dev/null +++ b/source3/winbindd/idmap_adex/gc_util.c @@ -0,0 +1,848 @@ +/* + * idmap_adex: Global Catalog search interface + * + * Copyright (C) Gerald (Jerry) Carter 2007-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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "idmap_adex.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +static struct gc_info *_gc_server_list = NULL; + + +/********************************************************************** + *********************************************************************/ + +static struct gc_info *gc_list_head(void) +{ + return _gc_server_list; +} + +/********************************************************************** + Checks if either of the domains is a subdomain of the other + *********************************************************************/ + +static bool is_subdomain(const char* a, const char *b) +{ + char *s; + TALLOC_CTX *frame = talloc_stackframe(); + char *x, *y; + bool ret = false; + + /* Trivial cases */ + + if (!a && !b) + return true; + + if (!a || !b) + return false; + + /* Normalize the case */ + + x = talloc_strdup(frame, a); + y = talloc_strdup(frame, b); + if (!x || !y) { + ret = false; + goto done; + } + + strupper_m(x); + strupper_m(y); + + /* Exact match */ + + if (strcmp(x, y) == 0) { + ret = true; + goto done; + } + + /* Check for trailing substrings */ + + s = strstr_m(x, y); + if (s && (strlen(s) == strlen(y))) { + ret = true; + goto done; + } + + s = strstr_m(y, x); + if (s && (strlen(s) == strlen(x))) { + ret = true; + goto done; + } + +done: + talloc_destroy(frame); + + return ret; +} + +/********************************************************************** + *********************************************************************/ + + NTSTATUS gc_find_forest_root(struct gc_info *gc, const char *domain) +{ + ADS_STRUCT *ads = NULL; + ADS_STATUS ads_status; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct nbt_cldap_netlogon_5 cldap_reply; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!gc || !domain) { + return NT_STATUS_INVALID_PARAMETER; + } + + ZERO_STRUCT(cldap_reply); + + ads = ads_init(domain, NULL, NULL); + BAIL_ON_PTR_ERROR(ads, nt_status); + + ads->auth.flags = ADS_AUTH_NO_BIND; + ads_status = ads_connect(ads); + if (!ADS_ERR_OK(ads_status)) { + DEBUG(4, ("find_forest_root: ads_connect(%s) failed! (%s)\n", + domain, ads_errstr(ads_status))); + } + nt_status = ads_ntstatus(ads_status); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + if (!ads_cldap_netlogon_5(frame, + ads->config.ldap_server_name, + ads->config.realm, + &cldap_reply)) + { + DEBUG(4,("find_forest_root: Failed to get a CLDAP reply from %s!\n", + ads->server.ldap_server)); + nt_status = NT_STATUS_IO_TIMEOUT; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + gc->forest_name = talloc_strdup(gc, cldap_reply.forest); + BAIL_ON_PTR_ERROR(gc->forest_name, nt_status); + +done: + if (ads) { + ads_destroy(&ads); + } + + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS gc_add_forest(const char *domain) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct gc_info *gc = NULL; + struct gc_info *find_gc = NULL; + char *dn; + ADS_STRUCT *ads = NULL; + struct likewise_cell *primary_cell = NULL; + + primary_cell = cell_list_head(); + if (!primary_cell) { + nt_status = NT_STATUS_INVALID_SERVER_STATE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Check for duplicates based on domain name first as this + requires no connection */ + + find_gc = gc_list_head(); + while (find_gc) { + if (strequal (find_gc->forest_name, domain)) + break; + find_gc = find_gc->next; + } + + if (find_gc) { + DEBUG(10,("gc_add_forest: %s already in list\n", find_gc->forest_name)); + return NT_STATUS_OK; + } + + if ((gc = TALLOC_ZERO_P(NULL, struct gc_info)) == NULL) { + nt_status = NT_STATUS_NO_MEMORY; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Query the rootDSE for the forest root naming conect first. + Check that the a GC server for the forest has not already + been added */ + + nt_status = gc_find_forest_root(gc, domain); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + find_gc = gc_list_head(); + while (find_gc) { + if (strequal (find_gc->forest_name, gc->forest_name)) + break; + find_gc = find_gc->next; + } + + if (find_gc) { + DEBUG(10,("gc_add_forest: Forest %s already in list\n", + find_gc->forest_name)); + return NT_STATUS_OK; + } + + /* Not found, so add it here. Make sure we connect to + a DC in _this_ domain and not the forest root. */ + + dn = ads_build_dn(gc->forest_name); + BAIL_ON_PTR_ERROR(dn, nt_status); + + gc->search_base = talloc_strdup(gc, dn); + SAFE_FREE(dn); + BAIL_ON_PTR_ERROR(gc->search_base, nt_status); + +#if 0 + /* Can't use cell_connect_dn() here as there is no way to + specifiy the LWCELL_FLAG_GC_CELL flag setting for cell_connect() */ + + nt_status = cell_connect_dn(&gc->forest_cell, gc->search_base); + BAIL_ON_NTSTATUS_ERROR(nt_status); +#else + + gc->forest_cell = cell_new(); + BAIL_ON_PTR_ERROR(gc->forest_cell, nt_status); + + /* Set the DNS domain, dn, etc ... and add it to the list */ + + cell_set_dns_domain(gc->forest_cell, gc->forest_name); + cell_set_dn(gc->forest_cell, gc->search_base); + cell_set_flags(gc->forest_cell, LWCELL_FLAG_GC_CELL); +#endif + + /* It is possible to belong to a non-forest cell and a + non-provisioned forest (at our domain levele). In that + case, we should just inherit the flags from our primary + cell since the GC searches will match our own schema + model. */ + + if (strequal(primary_cell->forest_name, gc->forest_name) + || is_subdomain(primary_cell->dns_domain, gc->forest_name)) + { + cell_set_flags(gc->forest_cell, cell_flags(primary_cell)); + } else { + /* outside of our domain */ + + nt_status = cell_connect(gc->forest_cell); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = cell_lookup_settings(gc->forest_cell); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* Drop the connection now that we have the settings */ + + ads = cell_connection(gc->forest_cell); + ads_destroy(&ads); + cell_set_connection(gc->forest_cell, NULL); + } + + DLIST_ADD_END(_gc_server_list, gc, struct gc_info*); + + DEBUG(10,("gc_add_forest: Added %s to Global Catalog list of servers\n", + gc->forest_name)); + + nt_status = NT_STATUS_OK; + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_destroy(gc); + DEBUG(3,("LWI: Failed to add new GC connection for %s (%s)\n", + domain, nt_errstr(nt_status))); + } + + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + +static void gc_server_list_destroy(void) +{ + struct gc_info *gc = gc_list_head(); + + while (gc) { + struct gc_info *p = gc->next; + + cell_destroy(gc->forest_cell); + talloc_destroy(gc); + + gc = p; + } + + _gc_server_list = NULL; + + return; +} + +/********************************************************************** + Setup the initial list of forests and initial the forest cell + settings for each. FIXME!!! + *********************************************************************/ + + NTSTATUS gc_init_list(void) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct winbindd_tdc_domain *domains = NULL; + size_t num_domains = 0; + int i; + + if (_gc_server_list != NULL) { + gc_server_list_destroy(); + } + + if (!wcache_tdc_fetch_list(&domains, &num_domains)) { + nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Find our forest first. Have to try all domains here starting + with our own. gc_add_forest() filters duplicates */ + + nt_status = gc_add_forest(lp_realm()); + WARN_ON_NTSTATUS_ERROR(nt_status); + + for (i=0; iforest_cell, "", + LDAP_SCOPE_SUBTREE, filter, attrs, &m); + nt_status = ads_ntstatus(ads_status); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + *msg = m; + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(2,("LWI: Forest wide search %s failed (%s)\n", + filter, nt_errstr(nt_status))); + } + + return nt_status; +} + +/********************************************************************** + Search all forests via GC and return the results in an array of + ADS_STRUCT/LDAPMessage pairs. + *********************************************************************/ + + NTSTATUS gc_search_all_forests(const char *filter, + ADS_STRUCT ***ads_list, + LDAPMessage ***msg_list, + int *num_resp, uint32_t flags) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct gc_info *gc = NULL; + uint32_t test_flags = ADEX_GC_SEARCH_CHECK_UNIQUE; + + *ads_list = NULL; + *msg_list = NULL; + *num_resp = 0; + + if ((gc = gc_search_start()) == NULL) { + nt_status = NT_STATUS_INVALID_DOMAIN_STATE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + while (gc) { + LDAPMessage *m = NULL; + + nt_status = gc_search_forest(gc, &m, filter); + if (!NT_STATUS_IS_OK(nt_status)) { + gc = gc->next; + continue; + } + + nt_status = add_ads_result_to_array(cell_connection(gc->forest_cell), + m, ads_list, msg_list, + num_resp); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* If there can only be one match, then we are done */ + + if ((*num_resp > 0) && ((flags & test_flags) == test_flags)) { + break; + } + + gc = gc->next; + } + + if (*num_resp == 0) { + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + nt_status = NT_STATUS_OK; + +done: + return nt_status; +} + +/********************************************************************** + Search all forests via GC and return the results in an array of + ADS_STRUCT/LDAPMessage pairs. + *********************************************************************/ + + NTSTATUS gc_search_all_forests_unique(const char *filter, + ADS_STRUCT **ads, + LDAPMessage **msg) +{ + ADS_STRUCT **ads_list = NULL; + LDAPMessage **msg_list = NULL; + int num_resp; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + + nt_status = gc_search_all_forests(filter, &ads_list, + &msg_list, &num_resp, + ADEX_GC_SEARCH_CHECK_UNIQUE); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = check_result_unique(ads_list[0], msg_list[0]); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + *ads = ads_list[0]; + *msg = msg_list[0]; + +done: + /* Be care that we don't free the msg result being returned */ + + if (!NT_STATUS_IS_OK(nt_status)) { + free_result_array(ads_list, msg_list, num_resp); + } else { + talloc_destroy(ads_list); + talloc_destroy(msg_list); + } + + return nt_status; +} + +/********************************************************************* + ********************************************************************/ + + NTSTATUS gc_name_to_sid(const char *domain, + const char *name, + DOM_SID *sid, + enum lsa_SidType *sid_type) +{ + TALLOC_CTX *frame = talloc_stackframe(); + char *p, *name_user; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char *name_filter; + ADS_STRUCT *ads = NULL; + LDAPMessage *msg = NULL; + LDAPMessage *e = NULL; + char *dn = NULL; + char *dns_domain = NULL; + ADS_STRUCT **ads_list = NULL; + LDAPMessage **msg_list = NULL; + int num_resp = 0; + int i; + + /* Strip the "DOMAIN\" prefix if necessary and search for + a matching sAMAccountName in the forest */ + + if ((p = strchr_m( name, '\\' )) == NULL) + name_user = talloc_strdup( frame, name ); + else + name_user = talloc_strdup( frame, p+1 ); + BAIL_ON_PTR_ERROR(name_user, nt_status); + + name_filter = talloc_asprintf(frame, "(sAMAccountName=%s)", name_user); + BAIL_ON_PTR_ERROR(name_filter, nt_status); + + nt_status = gc_search_all_forests(name_filter, &ads_list, + &msg_list, &num_resp, 0); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* Assume failure until we know otherwise*/ + + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + + /* Match the domain name from the DN */ + + for (i=0; idomain_name)) { + if (!ads_pull_sid(ads, e, "objectSid", sid)) { + nt_status = NT_STATUS_INVALID_SID; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + talloc_destroy(domain_rec); + + nt_status = get_sid_type(ads, msg, sid_type); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* We're done! */ + nt_status = NT_STATUS_OK; + break; + } + + /* once more around thew merry-go-round */ + + talloc_destroy(domain_rec); + e = ads_next_entry(ads, e); + } + } + +done: + free_result_array(ads_list, msg_list, num_resp); + talloc_destroy(frame); + + return nt_status; +} + +/******************************************************************** + Pull an attribute string value + *******************************************************************/ + +static NTSTATUS get_object_account_name(ADS_STRUCT *ads, + LDAPMessage *msg, + char **name) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char *sam_name = NULL; + struct winbindd_tdc_domain *domain_rec = NULL; + char *dns_domain = NULL; + char *dn = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + int len; + + /* Check parameters */ + + if (!ads || !msg || !name) { + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* get the name and domain */ + + dn = ads_get_dn(ads, msg); + BAIL_ON_PTR_ERROR(dn, nt_status); + + DEBUG(10,("get_object_account_name: dn = \"%s\"\n", dn)); + + dns_domain = cell_dn_to_dns(dn); + SAFE_FREE(dn); + BAIL_ON_PTR_ERROR(dns_domain, nt_status); + + domain_rec = wcache_tdc_fetch_domain(frame, dns_domain); + SAFE_FREE(dns_domain); + + if (!domain_rec) { + nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + sam_name = ads_pull_string(ads, frame, msg, "sAMAccountName"); + BAIL_ON_PTR_ERROR(sam_name, nt_status); + + len = asprintf(name, "%s\\%s", domain_rec->domain_name, sam_name); + if (len == -1) { + *name = NULL; + BAIL_ON_PTR_ERROR((*name), nt_status); + } + + nt_status = NT_STATUS_OK; + +done: + talloc_destroy(frame); + + return nt_status; +} + +/********************************************************************* + ********************************************************************/ + + NTSTATUS gc_sid_to_name(const DOM_SID *sid, + char **name, + enum lsa_SidType *sid_type) +{ + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char *filter; + ADS_STRUCT *ads = NULL; + LDAPMessage *msg = NULL; + char *sid_string; + + *name = NULL; + + sid_string = sid_binstring(sid); + BAIL_ON_PTR_ERROR(sid_string, nt_status); + + filter = talloc_asprintf(frame, "(objectSid=%s)", sid_string); + SAFE_FREE(sid_string); + BAIL_ON_PTR_ERROR(filter, nt_status); + + nt_status = gc_search_all_forests_unique(filter, &ads, &msg); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = get_object_account_name(ads, msg, name); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = get_sid_type(ads, msg, sid_type); + BAIL_ON_NTSTATUS_ERROR(nt_status); + +done: + ads_msgfree(ads, msg); + talloc_destroy(frame); + + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + + NTSTATUS add_ads_result_to_array(ADS_STRUCT *ads, + LDAPMessage *msg, + ADS_STRUCT ***ads_list, + LDAPMessage ***msg_list, + int *size) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + ADS_STRUCT **ads_tmp = NULL; + LDAPMessage **msg_tmp = NULL; + int count = *size; + + if (!ads || !msg) { + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + +#if 0 + /* Don't add a response with no entries */ + + if (ads_count_replies(ads, msg) == 0) { + return NT_STATUS_OK; + } +#endif + + if (count == 0) { + ads_tmp = TALLOC_ARRAY(NULL, ADS_STRUCT*, 1); + BAIL_ON_PTR_ERROR(ads_tmp, nt_status); + + msg_tmp = TALLOC_ARRAY(NULL, LDAPMessage*, 1); + BAIL_ON_PTR_ERROR(msg_tmp, nt_status); + } else { + ads_tmp = TALLOC_REALLOC_ARRAY(*ads_list, *ads_list, ADS_STRUCT*, + count+1); + BAIL_ON_PTR_ERROR(ads_tmp, nt_status); + + msg_tmp = TALLOC_REALLOC_ARRAY(*msg_list, *msg_list, LDAPMessage*, + count+1); + BAIL_ON_PTR_ERROR(msg_tmp, nt_status); + } + + ads_tmp[count] = ads; + msg_tmp[count] = msg; + count++; + + *ads_list = ads_tmp; + *msg_list = msg_tmp; + *size = count; + + nt_status = NT_STATUS_OK; + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_destroy(ads_tmp); + talloc_destroy(msg_tmp); + } + + return nt_status; +} + +/********************************************************************** + Frees search results. Do not free the ads_list as these are + references back to the GC search structures. + *********************************************************************/ + + void free_result_array(ADS_STRUCT **ads_list, + LDAPMessage **msg_list, + int num_resp) +{ + int i; + + for (i=0; i 1) { + nt_status = NT_STATUS_DUPLICATE_NAME; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + nt_status = NT_STATUS_OK; + +done: + return nt_status; +} diff --git a/source3/winbindd/idmap_adex/idmap_adex.c b/source3/winbindd/idmap_adex/idmap_adex.c new file mode 100644 index 0000000000..23ab843e95 --- /dev/null +++ b/source3/winbindd/idmap_adex/idmap_adex.c @@ -0,0 +1,460 @@ +/* + * idmap_adex: Support for D Forests + * + * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "idmap_adex.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +#define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache" + +NTSTATUS init_module(void); + +/* + * IdMap backend + */ + +/******************************************************************** + Basic init function responsible for determining our current mode + (standalone or using Centeris Cells). This must return success or + it will be dropped from the idmap backend list. + *******************************************************************/ + +static NTSTATUS _idmap_adex_init(struct idmap_domain *dom, + const char *params) +{ + ADS_STRUCT *ads = NULL; + ADS_STATUS status; + static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + DOM_SID domain_sid; + fstring dcname; + struct sockaddr_storage ip; + struct likewise_cell *lwcell; + + if (NT_STATUS_IS_OK(init_status)) + return NT_STATUS_OK; + + /* Silently fail if we are not a member server in security = ads */ + + if ((lp_server_role() != ROLE_DOMAIN_MEMBER) || + (lp_security() != SEC_ADS)) { + init_status = NT_STATUS_INVALID_SERVER_STATE; + BAIL_ON_NTSTATUS_ERROR(init_status); + } + + /* fetch our domain SID first */ + + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + BAIL_ON_NTSTATUS_ERROR(init_status); + } + + /* reuse the same ticket cache as winbindd */ + + setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); + + /* Establish a connection to a DC */ + + if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) { + init_status = NT_STATUS_NO_MEMORY; + BAIL_ON_NTSTATUS_ERROR(init_status); + } + + ads->auth.password = + secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + ads->auth.realm = SMB_STRDUP(lp_realm()); + + /* get the DC name here to setup the server affinity cache and + local krb5.conf */ + + get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip); + + status = ads_connect(ads); + if (!ADS_ERR_OK(status)) { + DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n", + ads_errstr(status))); + } + init_status = ads_ntstatus(status); + BAIL_ON_NTSTATUS_ERROR(init_status); + + + /* Find out cell membership */ + + init_status = cell_locate_membership(ads); + if (!NT_STATUS_IS_OK(init_status)) { + DEBUG(0,("LWI: Fail to locate cell membership (%s).", + nt_errstr(init_status))); + goto done; + } + + /* Fill in the cell information */ + + lwcell = cell_list_head(); + + init_status = cell_lookup_settings(lwcell); + BAIL_ON_NTSTATUS_ERROR(init_status); + + /* Miscellaneous setup. E.g. set up the list of GC + servers and domain list for our forest (does not actually + connect). */ + + init_status = gc_init_list(); + BAIL_ON_NTSTATUS_ERROR(init_status); + + init_status = domain_init_list(); + BAIL_ON_NTSTATUS_ERROR(init_status); + +done: + if (!NT_STATUS_IS_OK(init_status)) { + DEBUG(1,("Likewise initialization failed (%s)\n", + nt_errstr(init_status))); + } + + /* cleanup */ + + if (!NT_STATUS_IS_OK(init_status)) { + cell_list_destroy(); + + /* init_status stores the failure reason but we need to + return success or else idmap_init() will drop us from the + backend list */ + return NT_STATUS_OK; + } + + init_status = NT_STATUS_OK; + + return init_status; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _idmap_adex_get_sid_from_id(struct + idmap_domain + *dom, struct + id_map + **ids) +{ + int i; + bool one_mapped = false; + bool all_mapped = true; + NTSTATUS nt_status; + struct likewise_cell *cell; + + nt_status = _idmap_adex_init(dom, NULL); + if (!NT_STATUS_IS_OK(nt_status)) + return nt_status; + + if ((cell = cell_list_head()) == NULL) { + return NT_STATUS_INVALID_SERVER_STATE; + } + + /* have to work through these one by one */ + for (i = 0; ids[i]; i++) { + NTSTATUS status; + status = cell->provider->get_sid_from_id(ids[i]->sid, + ids[i]->xid.id, + ids[i]->xid.type); + /* Fail if we cannot find any DC */ + if (NT_STATUS_EQUAL + (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { + return status; + } + + if (!NT_STATUS_IS_OK(status)) { + ids[i]->status = ID_UNMAPPED; + all_mapped = false; + continue; + } + + ids[i]->status = ID_MAPPED; + one_mapped = true; + } + + return NT_STATUS_OK; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _idmap_adex_get_id_from_sid(struct + idmap_domain + *dom, struct + id_map + **ids) +{ + int i; + bool one_mapped = false; + bool all_mapped = true; + NTSTATUS nt_status; + struct likewise_cell *cell; + + nt_status = _idmap_adex_init(dom, NULL); + if (!NT_STATUS_IS_OK(nt_status)) + return nt_status; + + if ((cell = cell_list_head()) == NULL) { + return NT_STATUS_INVALID_SERVER_STATE; + } + + /* have to work through these one by one */ + for (i = 0; ids[i]; i++) { + NTSTATUS status; + status = cell->provider->get_id_from_sid(&ids[i]->xid.id, + &ids[i]->xid. + type, ids[i]->sid); + /* Fail if we cannot find any DC */ + if (NT_STATUS_EQUAL + (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { + return status; + } + + if (!NT_STATUS_IS_OK(status)) { + ids[i]->status = ID_UNMAPPED; + all_mapped = false; + continue; + } + + ids[i]->status = ID_MAPPED; + one_mapped = true; + } + + return NT_STATUS_OK; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _idmap_adex_set_mapping(struct + idmap_domain + *dom, const struct + id_map *map) +{ + DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _idmap_adex_remove_mapping(struct + idmap_domain + *dom, const + struct + id_map + *map) +{ + DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n")); + return NT_STATUS_NOT_IMPLEMENTED; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _idmap_adex_dump(struct idmap_domain + *dom, struct id_map **maps, int *num_map) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _idmap_adex_close(struct idmap_domain + *dom) +{ + /* FIXME! need to do cleanup here */ + + return NT_STATUS_OK; +} + +/* + * IdMap NSS plugin + */ + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _nss_adex_init(struct nss_domain_entry + *e) +{ + return _idmap_adex_init(NULL, NULL); +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _nss_adex_get_info(struct + nss_domain_entry *e, + const DOM_SID * sid, + TALLOC_CTX * ctx, + ADS_STRUCT * ads, + LDAPMessage * msg, + char **homedir, + char **shell, char **gecos, gid_t * p_gid) +{ + NTSTATUS nt_status; + struct likewise_cell *cell; + + nt_status = _idmap_adex_init(NULL, NULL); + if (!NT_STATUS_IS_OK(nt_status)) + return nt_status; + + if ((cell = cell_list_head()) == NULL) { + return NT_STATUS_INVALID_SERVER_STATE; + } + + return cell->provider->get_nss_info(sid, ctx, homedir, + shell, gecos, p_gid); +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx, const char + *domain, const char + *name, char **alias) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct likewise_cell *cell = NULL; + + nt_status = _idmap_adex_init(NULL, NULL); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + if ((cell = cell_list_head()) == NULL) { + nt_status = NT_STATUS_INVALID_SERVER_STATE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + nt_status = cell->provider->map_to_alias(mem_ctx, domain, + name, alias); + + /* go ahead and allow the cache mgr to mark this in + negative cache */ + + if (!NT_STATUS_IS_OK(nt_status)) + nt_status = NT_STATUS_NONE_MAPPED; + +done: + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, const char + *domain, const char + *alias, char **name) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct likewise_cell *cell = NULL; + + nt_status = _idmap_adex_init(NULL, NULL); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + if ((cell = cell_list_head()) == NULL) { + nt_status = NT_STATUS_INVALID_SERVER_STATE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + + nt_status = cell->provider->map_from_alias(mem_ctx, domain, + alias, name); + + /* go ahead and allow the cache mgr to mark this in + negative cache */ + + if (!NT_STATUS_IS_OK(nt_status)) + nt_status = NT_STATUS_NONE_MAPPED; + +done: + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _nss_adex_close(void) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/********************************************************************** + *********************************************************************/ + +static struct idmap_methods adex_idmap_methods = { + + .init = _idmap_adex_init, + .unixids_to_sids = _idmap_adex_get_sid_from_id, + .sids_to_unixids = _idmap_adex_get_id_from_sid, + .set_mapping = _idmap_adex_set_mapping, + .remove_mapping = _idmap_adex_remove_mapping, + .dump_data = _idmap_adex_dump, + .close_fn = _idmap_adex_close +}; +static struct nss_info_methods adex_nss_methods = { + .init = _nss_adex_init, + .get_nss_info = _nss_adex_get_info, + .map_to_alias = _nss_adex_map_to_alias, + .map_from_alias = _nss_adex_map_from_alias, + .close_fn = _nss_adex_close +}; + +/********************************************************************** + Register with the idmap and idmap_nss subsystems. We have to protect + against the idmap and nss_info interfaces being in a half-registered + state. + **********************************************************************/ +NTSTATUS idmap_adex_init(void) +{ + static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL; + static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL; + if (!NT_STATUS_IS_OK(idmap_status)) { + idmap_status = + smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, + "adex", &adex_idmap_methods); + if (!NT_STATUS_IS_OK(idmap_status)) { + DEBUG(0, + ("idmap_centeris_init: Failed to register the adex" + "idmap plugin.\n")); + return idmap_status; + } + } + + if (!NT_STATUS_IS_OK(nss_status)) { + nss_status = + smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION, + "adex", &adex_nss_methods); + if (!NT_STATUS_IS_OK(nss_status)) { + DEBUG(0, + ("idmap_adex_init: Failed to register the adex" + "nss plugin.\n")); + return nss_status; + } + } + + return NT_STATUS_OK; +} + +NTSTATUS nss_info_adex_init(void) +{ + return idmap_adex_init(); +} diff --git a/source3/winbindd/idmap_adex/idmap_adex.h b/source3/winbindd/idmap_adex/idmap_adex.h new file mode 100644 index 0000000000..f91bba8d07 --- /dev/null +++ b/source3/winbindd/idmap_adex/idmap_adex.h @@ -0,0 +1,257 @@ +/* + * idmap_centeris: Support for Local IDs and Centeris Cell Structure + * + * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _IDMAP_ADEX_H +#define _IDMAP_ADEX_H + +#include "winbindd/winbindd.h" + +#define ADEX_CELL_RDN "$LikewiseIdentityCell" + +#define ADEX_OC_USER "centerisLikewiseUser" +#define ADEX_OC_GROUP "centerisLikewiseGroup" + +#define AD_USER "User" +#define AD_GROUP "Group" + +#define ADEX_OC_POSIX_USER "posixAccount" +#define ADEX_OC_POSIX_GROUP "posixGroup" + +#define ADEX_ATTR_UIDNUM "uidNumber" +#define ADEX_ATTR_GIDNUM "gidNUmber" +#define ADEX_ATTR_HOMEDIR "unixHomeDirectory" +#define ADEX_ATTR_USERPW "unixUserPassword" +#define ADEX_ATTR_GROUPALIAS "groupAlias" /* Not part of RFC2307 */ +#define ADEX_ATTR_SHELL "loginShell" +#define ADEX_ATTR_GECOS "gecos" +#define ADEX_ATTR_UID "uid" +#define ADEX_ATTR_DISPLAYNAME "displayName" + +#define MIN_ID_VALUE 100 + +#define BAIL_ON_NTSTATUS_ERROR(x) \ + do { \ + if (!NT_STATUS_IS_OK(x)) { \ + DEBUG(10,("Failed! (%s)\n", nt_errstr(x))); \ + goto done; \ + } \ + } \ + while (0); \ + +#define WARN_ON_NTSTATUS_ERROR(x) \ + do { \ + if (!NT_STATUS_IS_OK(x)) { \ + DEBUG(10,("Failure ignored! (%s)\n", nt_errstr(x))); \ + } \ + } \ + while (0); \ + +#define BAIL_ON_ADS_ERROR(x) \ + do { \ + if (!ADS_ERR_OK(x)) { \ + goto done; \ + } \ + } \ + while (0); + +#define BAIL_ON_PTR_ERROR(p, x) \ + do { \ + if ((p) == NULL ) { \ + DEBUG(10,("NULL pointer!\n")); \ + x = NT_STATUS_NO_MEMORY; \ + goto done; \ + } \ + } while (0); + +#define PRINT_NTSTATUS_ERROR(x, hdr, level) \ + do { \ + if (!NT_STATUS_IS_OK(x)) { \ + DEBUG(level,("LWI ("hdr"): %s\n", nt_errstr(x))); \ + } \ + } while(0); +/* + * Cell Provider API + */ + +struct cell_provider_api { + NTSTATUS(*get_sid_from_id) (DOM_SID * sid, + uint32_t id, enum id_type type); + NTSTATUS(*get_id_from_sid) (uint32_t * id, + enum id_type * type, const DOM_SID * sid); + NTSTATUS(*get_nss_info) (const DOM_SID * sid, + TALLOC_CTX * ctx, + char **homedir, + char **shell, char **gecos, gid_t * p_gid); + NTSTATUS(*map_to_alias) (TALLOC_CTX * mem_ctx, + const char *domain, + const char *name, char **alias); + NTSTATUS(*map_from_alias) (TALLOC_CTX * mem_ctx, + const char *domain, + const char *alias, char **name); +}; + +/* registered providers */ + +extern struct cell_provider_api ccp_unified; +extern struct cell_provider_api ccp_local; + +#define LWCELL_FLAG_USE_RFC2307_ATTRS 0x00000001 +#define LWCELL_FLAG_SEARCH_FOREST 0x00000002 +#define LWCELL_FLAG_GC_CELL 0x00000004 +#define LWCELL_FLAG_LOCAL_MODE 0x00000008 + +struct likewise_cell { + struct likewise_cell *prev, *next; + ADS_STRUCT *conn; + struct likewise_cell *gc_search_cell; + DOM_SID domain_sid; + char *dns_domain; + char *forest_name; + char *dn; + struct GUID *links; /* only held by owning cell */ + size_t num_links; + uint32_t flags; + struct cell_provider_api *provider; +}; + +/* Search flags used for Global Catalog API */ + +#define ADEX_GC_SEARCH_CHECK_UNIQUE 0x00000001 + +struct gc_info { + struct gc_info *prev, *next; + char *forest_name; + char *search_base; + struct likewise_cell *forest_cell; +}; + +/* Available functions outside of idmap_lwidentity.c */ + +/* cell_util.c */ + +char *find_attr_string(char **list, size_t num_lines, const char *substr); +bool is_object_class(char **list, size_t num_lines, const char *substr); +int min_id_value(void); +char *cell_dn_to_dns(const char *dn); +NTSTATUS get_sid_type(ADS_STRUCT *ads, + LDAPMessage *msg, + enum lsa_SidType *type); + +NTSTATUS cell_locate_membership(ADS_STRUCT * ads); +NTSTATUS cell_lookup_settings(struct likewise_cell * cell); +NTSTATUS cell_follow_links(struct likewise_cell *cell); +NTSTATUS cell_set_local_provider(void); + +/* likewise_cell.c */ + +struct likewise_cell *cell_new(void); +struct likewise_cell *cell_list_head(void); + +bool cell_list_add(struct likewise_cell *cell); +bool cell_list_remove(struct likewise_cell * cell); + +void cell_list_destroy(); +void cell_destroy(struct likewise_cell *c); +void cell_set_forest_searches(struct likewise_cell *c, + bool search); +void cell_set_dns_domain(struct likewise_cell *c, + const char *dns_domain); +void cell_set_connection(struct likewise_cell *c, + ADS_STRUCT *ads); +void cell_set_dn(struct likewise_cell *c, + const char *dn); +void cell_set_domain_sid(struct likewise_cell *c, + DOM_SID *sid); +void cell_set_flags(struct likewise_cell *c, uint32_t flags); +void cell_clear_flags(struct likewise_cell *c, uint32_t flags); + +const char* cell_search_base(struct likewise_cell *c); +const char *cell_dns_domain(struct likewise_cell *c); +ADS_STRUCT *cell_connection(struct likewise_cell *c); +bool cell_search_forest(struct likewise_cell *c); +ADS_STATUS cell_do_search(struct likewise_cell *c, + const char *search_base, + int scope, + const char *expr, + const char **attrs, + LDAPMessage ** msg); +uint32_t cell_flags(struct likewise_cell *c); + +NTSTATUS cell_connect_dn(struct likewise_cell **c, + const char *dn); +NTSTATUS cell_connect(struct likewise_cell *c); + + +/* gc_util.c */ + +NTSTATUS gc_init_list(void); + +NTSTATUS gc_find_forest_root(struct gc_info *gc, + const char *domain); + +struct gc_info *gc_search_start(void); + +NTSTATUS gc_search_forest(struct gc_info *gc, + LDAPMessage **msg, + const char *filter); + +NTSTATUS gc_search_all_forests(const char *filter, + ADS_STRUCT ***ads_list, + LDAPMessage ***msg_list, + int *num_resp, uint32_t flags); + +NTSTATUS gc_search_all_forests_unique(const char *filter, + ADS_STRUCT **ads, + LDAPMessage **msg); + +NTSTATUS gc_name_to_sid(const char *domain, + const char *name, + DOM_SID *sid, + enum lsa_SidType *sid_type); + +NTSTATUS gc_sid_to_name(const DOM_SID *sid, + char **name, + enum lsa_SidType *sid_type); + +NTSTATUS add_ads_result_to_array(ADS_STRUCT *ads, + LDAPMessage *msg, + ADS_STRUCT ***ads_list, + LDAPMessage ***msg_list, + int *size); + +void free_result_array(ADS_STRUCT **ads_list, + LDAPMessage **msg_list, + int num_resp); + +NTSTATUS check_result_unique(ADS_STRUCT *ads, + LDAPMessage *msg); + + +/* domain_util.c */ + +NTSTATUS domain_init_list(void); + +NTSTATUS dc_search_domains(struct likewise_cell **cell, + LDAPMessage **msg, + const char *dn, + const DOM_SID *user_sid); + + +#endif /* _IDMAP_ADEX_H */ diff --git a/source3/winbindd/idmap_adex/likewise_cell.c b/source3/winbindd/idmap_adex/likewise_cell.c new file mode 100644 index 0000000000..77eeee406b --- /dev/null +++ b/source3/winbindd/idmap_adex/likewise_cell.c @@ -0,0 +1,425 @@ +/* + * idmap_adex: Support for AD Forests + * + * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "idmap_adex.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +static struct likewise_cell *_lw_cell_list = NULL; + +/********************************************************************** + Return the current HEAD of the list + *********************************************************************/ + + struct likewise_cell *cell_list_head(void) +{ + return _lw_cell_list; +} + + +/********************************************************************** + *********************************************************************/ + + void cell_destroy(struct likewise_cell *c) +{ + if (!c) + return; + + if (c->conn) + ads_destroy(&c->conn); + + talloc_destroy(c); +} + +/********************************************************************** + Free all cell entries and reset the list head to NULL + *********************************************************************/ + + void cell_list_destroy(void) +{ + struct likewise_cell *p = _lw_cell_list; + + while (p) { + struct likewise_cell *q = p->next; + + cell_destroy(p); + + p = q; + } + + _lw_cell_list = NULL; + + return; +} + +/********************************************************************** + Add a new cell structure to the list + *********************************************************************/ + + struct likewise_cell* cell_new(void) +{ + struct likewise_cell *c; + + /* Each cell struct is a TALLOC_CTX* */ + + c = TALLOC_ZERO_P(NULL, struct likewise_cell); + if (!c) { + DEBUG(0,("cell_new: memory allocation failure!\n")); + return NULL; + } + + return c; +} + +/********************************************************************** + Add a new cell structure to the list + *********************************************************************/ + + bool cell_list_add(struct likewise_cell * cell) +{ + if (!cell) { + return false; + } + + /* Always add to the end */ + + DLIST_ADD_END(_lw_cell_list, cell, struct likewise_cell *); + + return true; +} + +/********************************************************************** + Add a new cell structure to the list + *********************************************************************/ + + bool cell_list_remove(struct likewise_cell * cell) +{ + if (!cell) { + return false; + } + + /* Remove and drop the cell structure */ + + DLIST_REMOVE(_lw_cell_list, cell); + talloc_destroy(cell); + + return true; +} + +/********************************************************************** + Set the containing DNS domain for a cell + *********************************************************************/ + + void cell_set_dns_domain(struct likewise_cell *c, const char *dns_domain) +{ + c->dns_domain = talloc_strdup(c, dns_domain); +} + +/********************************************************************** + Set ADS connection for a cell + *********************************************************************/ + + void cell_set_connection(struct likewise_cell *c, ADS_STRUCT *ads) +{ + c->conn = ads; +} + +/********************************************************************** + *********************************************************************/ + + void cell_set_flags(struct likewise_cell *c, uint32_t flags) +{ + c->flags |= flags; +} + +/********************************************************************** + *********************************************************************/ + + void cell_clear_flags(struct likewise_cell *c, uint32_t flags) +{ + c->flags &= ~flags; +} + +/********************************************************************** + Set the Cell's DN + *********************************************************************/ + + void cell_set_dn(struct likewise_cell *c, const char *dn) +{ + if ( c->dn) { + talloc_free(c->dn); + c->dn = NULL; + } + + c->dn = talloc_strdup(c, dn); +} + +/********************************************************************** + *********************************************************************/ + + void cell_set_domain_sid(struct likewise_cell *c, DOM_SID *sid) +{ + sid_copy(&c->domain_sid, sid); +} + +/* + * Query Routines + */ + +/********************************************************************** + *********************************************************************/ + + const char* cell_search_base(struct likewise_cell *c) +{ + if (!c) + return NULL; + + return talloc_asprintf(c, "cn=%s,%s", ADEX_CELL_RDN, c->dn); +} + +/********************************************************************** + *********************************************************************/ + + bool cell_search_forest(struct likewise_cell *c) +{ + uint32_t test_flags = LWCELL_FLAG_SEARCH_FOREST; + + return ((c->flags & test_flags) == test_flags); +} + +/********************************************************************** + *********************************************************************/ + + uint32_t cell_flags(struct likewise_cell *c) +{ + if (!c) + return 0; + + return c->flags; +} + +/********************************************************************** + *********************************************************************/ + + const char *cell_dns_domain(struct likewise_cell *c) +{ + if (!c) + return NULL; + + return c->dns_domain; +} + +/********************************************************************** + *********************************************************************/ + + ADS_STRUCT *cell_connection(struct likewise_cell *c) +{ + if (!c) + return NULL; + + return c->conn; +} + +/* + * Connection functions + */ + +/******************************************************************** + *******************************************************************/ + + NTSTATUS cell_connect(struct likewise_cell *c) +{ + ADS_STRUCT *ads = NULL; + ADS_STATUS ads_status; + fstring dc_name; + struct sockaddr_storage dcip; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + + /* have to at least have the AD domain name */ + + if (!c->dns_domain) { + nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* clear out any old information */ + + if (c->conn) { + ads_destroy(&c->conn); + c->conn = NULL; + } + + /* now setup the new connection */ + + ads = ads_init(c->dns_domain, NULL, NULL); + BAIL_ON_PTR_ERROR(ads, nt_status); + + ads->auth.password = + secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + ads->auth.realm = SMB_STRDUP(lp_realm()); + + /* Make the connection. We should already have an initial + TGT using the machine creds */ + + if (cell_flags(c) & LWCELL_FLAG_GC_CELL) { + ads_status = ads_connect_gc(ads); + } else { + /* Set up server affinity for normal cells and the client + site name cache */ + + if (!get_dc_name("", c->dns_domain, dc_name, &dcip)) { + nt_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + ads_status = ads_connect(ads); + } + + + c->conn = ads; + + nt_status = ads_ntstatus(ads_status); + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + ads_destroy(&ads); + c->conn = NULL; + } + + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + + NTSTATUS cell_connect_dn(struct likewise_cell **c, const char *dn) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct likewise_cell *new_cell = NULL; + char *dns_domain = NULL; + + if (*c || !dn) { + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + if ((new_cell = cell_new()) == NULL) { + nt_status = NT_STATUS_NO_MEMORY; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Set the DNS domain, dn, etc ... and add it to the list */ + + dns_domain = cell_dn_to_dns(dn); + cell_set_dns_domain(new_cell, dns_domain); + SAFE_FREE(dns_domain); + + cell_set_dn(new_cell, dn); + + nt_status = cell_connect(new_cell); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + *c = new_cell; + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("LWI: Failled to connect to cell \"%s\" (%s)\n", + dn ? dn : "NULL", nt_errstr(nt_status))); + talloc_destroy(new_cell); + } + + return nt_status; +} + + +/******************************************************************** + *******************************************************************/ + +#define MAX_SEARCH_COUNT 2 + + ADS_STATUS cell_do_search(struct likewise_cell *c, + const char *search_base, + int scope, + const char *expr, + const char **attrs, + LDAPMessage ** msg) +{ + int search_count = 0; + ADS_STATUS status; + NTSTATUS nt_status; + + /* check for a NULL connection */ + + if (!c->conn) { + nt_status = cell_connect(c); + if (!NT_STATUS_IS_OK(nt_status)) { + status = ADS_ERROR_NT(nt_status); + return status; + } + } + + DEBUG(10, ("cell_do_search: Base = %s, Filter = %s, Scope = %d, GC = %s\n", + search_base, expr, scope, + c->conn->server.gc ? "yes" : "no")); + + /* we try multiple times in case the ADS_STRUCT is bad + and we need to reconnect */ + + while (search_count < MAX_SEARCH_COUNT) { + *msg = NULL; + status = ads_do_search(c->conn, search_base, + scope, expr, attrs, msg); + if (ADS_ERR_OK(status)) { + return status; + } + + + DEBUG(5, ("cell_do_search: search[%d] failed (%s)\n", + search_count, ads_errstr(status))); + + search_count++; + + /* Houston, we have a problem */ + + if (status.error_type == ENUM_ADS_ERROR_LDAP) { + switch (status.err.rc) { + case LDAP_TIMELIMIT_EXCEEDED: + case LDAP_TIMEOUT: + case -1: /* we get this error if we cannot contact + the LDAP server */ + nt_status = cell_connect(c); + if (!NT_STATUS_IS_OK(nt_status)) { + status = ADS_ERROR_NT(nt_status); + return status; + } + break; + default: + /* we're all done here */ + return status; + } + } + } + + DEBUG(5, ("cell_do_search: exceeded maximum search count!\n")); + + return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); +} diff --git a/source3/winbindd/idmap_adex/provider_unified.c b/source3/winbindd/idmap_adex/provider_unified.c new file mode 100644 index 0000000000..f18534797e --- /dev/null +++ b/source3/winbindd/idmap_adex/provider_unified.c @@ -0,0 +1,1180 @@ +/* + * idmap_adex + * + * Provider for RFC2307 and SFU AD Forests + * + * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "idmap_adex.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +/* Information needed by the LDAP search filters */ + +enum filterType { SidFilter, IdFilter, AliasFilter }; + +struct lwcell_filter +{ + enum filterType ftype; + bool use2307; + union { + DOM_SID sid; + struct { + uint32_t id; + enum id_type type; + } id; + fstring alias; + } filter; +}; + +/******************************************************************** + *******************************************************************/ + +static char* build_id_filter(uint32_t id, + enum id_type type, + uint32_t search_flags) +{ + char *filter = NULL; + char *oc_filter, *attr_filter; + NTSTATUS nt_status; + TALLOC_CTX *frame = talloc_stackframe(); + bool use2307 = ((search_flags & LWCELL_FLAG_USE_RFC2307_ATTRS) + == LWCELL_FLAG_USE_RFC2307_ATTRS); + bool use_gc = ((search_flags & LWCELL_FLAG_SEARCH_FOREST) + == LWCELL_FLAG_SEARCH_FOREST); + const char *oc; + + /* Construct search filter for objectclass and attributes */ + + switch (type) { + case ID_TYPE_UID: + oc = ADEX_OC_USER; + if (use2307) { + oc = ADEX_OC_POSIX_USER; + if (use_gc) { + oc = AD_USER; + } + } + oc_filter = talloc_asprintf(frame, "objectclass=%s", oc); + attr_filter = talloc_asprintf(frame, "%s=%u", + ADEX_ATTR_UIDNUM, id); + break; + + case ID_TYPE_GID: + oc = ADEX_OC_GROUP; + if (use2307) { + oc = ADEX_OC_POSIX_GROUP; + if (use_gc) { + oc = AD_GROUP; + } + } + oc_filter = talloc_asprintf(frame, "objectclass=%s", oc); + attr_filter = talloc_asprintf(frame, "%s=%u", + ADEX_ATTR_GIDNUM, id); + break; + default: + return NULL; + } + + BAIL_ON_PTR_ERROR(oc_filter, nt_status); + BAIL_ON_PTR_ERROR(attr_filter, nt_status); + + /* Use "keywords=%s" for non-schema cells */ + + if (use2307) { + filter = talloc_asprintf(frame, "(&(%s)(%s))", + oc_filter, attr_filter); + } else { + filter = talloc_asprintf(frame, "(&(keywords=%s)(keywords=%s))", + oc_filter, attr_filter); + } + + talloc_destroy(oc_filter); + talloc_destroy(attr_filter); + +done: + /* Don't destroy the stackframe CTX since we are returning + memory from it */ + + return filter; +} + +/******************************************************************** + *******************************************************************/ + +static char* build_alias_filter(const char *alias, uint32_t search_flags) +{ + char *filter = NULL; + char *user_attr_filter, *group_attr_filter; + NTSTATUS nt_status; + TALLOC_CTX *frame = talloc_stackframe(); + bool use2307 = ((search_flags & LWCELL_FLAG_USE_RFC2307_ATTRS) + == LWCELL_FLAG_USE_RFC2307_ATTRS); + bool search_forest = ((search_flags & LWCELL_FLAG_SEARCH_FOREST) + == LWCELL_FLAG_SEARCH_FOREST); + + /* Construct search filter for objectclass and attributes */ + + user_attr_filter = talloc_asprintf(frame, "%s=%s", + ADEX_ATTR_UID, alias); + group_attr_filter = talloc_asprintf(frame, "%s=%s", + ADEX_ATTR_DISPLAYNAME, alias); + BAIL_ON_PTR_ERROR(user_attr_filter, nt_status); + BAIL_ON_PTR_ERROR(group_attr_filter, nt_status); + + /* Use "keywords=%s" for non-schema cells */ + + if (use2307) { + filter = talloc_asprintf(frame, + "(|(&(%s)(objectclass=%s))(&(%s)(objectclass=%s)))", + user_attr_filter, + search_forest ? AD_USER : ADEX_OC_POSIX_USER, + group_attr_filter, + search_forest ? AD_GROUP : ADEX_OC_POSIX_GROUP); + } else { + filter = talloc_asprintf(frame, + "(|(keywords=%s)(keywords=%s))", + user_attr_filter, + group_attr_filter); + } + + talloc_destroy(user_attr_filter); + talloc_destroy(group_attr_filter); + +done: + /* Don't destroy the stackframe CTX since we are returning + memory from it */ + + return filter; +} + + +/******************************************************************** + *******************************************************************/ + +static NTSTATUS search_cell(struct likewise_cell *c, + LDAPMessage **msg, + const struct lwcell_filter *fdata) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + TALLOC_CTX* frame = talloc_stackframe(); + char *filter = NULL; + const char *base = NULL; + ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + const char *attrs[] = { "*", NULL }; + int count; + char *sid_str; + + /* get the filter and other search parameters */ + + switch (fdata->ftype) { + case SidFilter: + sid_str = sid_string_talloc(frame, &fdata->filter.sid); + BAIL_ON_PTR_ERROR(sid_str, nt_status); + + filter = talloc_asprintf(frame, "(keywords=backLink=%s)", + sid_str); + break; + case IdFilter: + filter = build_id_filter(fdata->filter.id.id, + fdata->filter.id.type, + cell_flags(c)); + break; + case AliasFilter: + filter = build_alias_filter(fdata->filter.alias, + cell_flags(c)); + break; + default: + nt_status = NT_STATUS_INVALID_PARAMETER; + break; + } + BAIL_ON_PTR_ERROR(filter, nt_status); + + base = cell_search_base(c); + BAIL_ON_PTR_ERROR(base, nt_status); + + ads_status = cell_do_search(c, base, LDAP_SCOPE_SUBTREE, + filter, attrs, msg); + + nt_status = ads_ntstatus(ads_status); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* Now check that we got only one reply */ + + count = ads_count_replies(c->conn, *msg); + if (count < 1) { + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + if ( count > 1) { + nt_status = NT_STATUS_DUPLICATE_NAME; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + +done: + PRINT_NTSTATUS_ERROR(nt_status, "search_cell", 4); + + talloc_destroy(CONST_DISCARD(char*, base)); + talloc_destroy(frame); + + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + +static NTSTATUS search_domain(struct likewise_cell **cell, + LDAPMessage **msg, + const char *dn, + const DOM_SID *sid) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + TALLOC_CTX* frame = talloc_stackframe(); + int count; + + nt_status = dc_search_domains(cell, msg, dn, sid); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* Now check that we got only one reply */ + + count = ads_count_replies(cell_connection(*cell), *msg); + if (count < 1) { + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + if ( count > 1) { + nt_status = NT_STATUS_DUPLICATE_NAME; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + +done: + PRINT_NTSTATUS_ERROR(nt_status, "search_domain", 4); + talloc_destroy(frame); + + return nt_status; +} + + +/******************************************************************** + Check that a DN is within the forest scope. + *******************************************************************/ + +static bool check_forest_scope(const char *dn) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + TALLOC_CTX *frame = talloc_stackframe(); + char *p = NULL; + char *q = NULL; + char *dns_domain = NULL; + struct winbindd_tdc_domain *domain; + + /* If the DN does *not* contain "$LikewiseIdentityCell", + assume this is a schema mode forest and it is in the + forest scope by definition. */ + + if ((p = strstr_m(dn, ADEX_CELL_RDN)) == NULL) { + nt_status = NT_STATUS_OK; + goto done; + } + + /* If this is a non-schema forest, then make sure that the DN + is in the form "...,cn=$LikewiseIdentityCell,DC=..." */ + + if ((q = strchr_m(p, ',')) == NULL) { + nt_status = NT_STATUS_OBJECT_NAME_INVALID; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + q++; + if (StrnCaseCmp(q, "dc=", 3) != 0) { + nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + + dns_domain = cell_dn_to_dns(q); + BAIL_ON_PTR_ERROR(dns_domain, nt_status); + + domain = wcache_tdc_fetch_domain(frame, dns_domain); + if (!domain) { + nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + nt_status = NT_STATUS_OK; + +done: + talloc_destroy(frame); + SAFE_FREE(dns_domain); + + return NT_STATUS_IS_OK(nt_status); +} + + + +/******************************************************************** + Check that only one result was returned within the forest cell + scope. + *******************************************************************/ + +static NTSTATUS check_result_unique_scoped(ADS_STRUCT **ads_list, + LDAPMessage **msg_list, + int num_resp, + char **dn, + DOM_SID *user_sid) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + int i; + ADS_STRUCT *ads = NULL; + LDAPMessage *msg = NULL; + int count = 0; + char *entry_dn = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!dn || !user_sid) { + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + *dn = NULL; + + if (!ads_list || !msg_list || (num_resp == 0)) { + nt_status = NT_STATUS_NO_SUCH_FILE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Loop over all msgs */ + + for (i=0; i 1) { + nt_status = NT_STATUS_DUPLICATE_NAME; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + ads = ads_list[i]; + msg = e; + *dn = SMB_STRDUP(entry_dn); + BAIL_ON_PTR_ERROR((*dn), nt_status); + } + + e = ads_next_entry(ads_list[i], e); + SAFE_FREE(entry_dn); + } + } + + if (!ads || !msg) { + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* If we made is through the loop, then grab the user_sid and + run home to base */ + + /* + Try and get the SID from either objectSid or keywords. + We cannot use pull_sid() here since we want to try + both methods and not only one or the other (and we + have no full likewise_cell struct. + + Fail if both are unavailable + */ + + if (!ads_pull_sid(ads, msg, "objectSid", user_sid)) { + char **keywords; + char *s; + size_t num_lines = 0; + + keywords = ads_pull_strings(ads, frame, msg, "keywords", + &num_lines); + BAIL_ON_PTR_ERROR(keywords, nt_status); + + s = find_attr_string(keywords, num_lines, "backLink"); + if (!s) { + nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + if (!string_to_sid(user_sid, s)) { + nt_status = NT_STATUS_INVALID_SID; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + } + + nt_status = NT_STATUS_OK; + +done: + if (!NT_STATUS_IS_OK(nt_status)) { + SAFE_FREE(*dn); + } + + talloc_destroy(frame); + SAFE_FREE(entry_dn); + + return nt_status; +} + +/******************************************************************** + Search all forests. Each forest can have it's own forest-cell + settings so we have to generate the filter for each search. + We don't use gc_search_all_forests() since we may have a different + schema model in each forest and need to construct the search + filter for each GC search. + *******************************************************************/ + +static NTSTATUS search_forest(struct likewise_cell *forest_cell, + LDAPMessage **msg, + const struct lwcell_filter *fdata) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + TALLOC_CTX *frame = talloc_stackframe(); + char *filter = NULL; + char *dn = NULL; + struct gc_info *gc = NULL; + ADS_STRUCT **ads_list = NULL; + LDAPMessage **msg_list = NULL; + int num_resp = 0; + LDAPMessage *m; + DOM_SID user_sid; + struct likewise_cell *domain_cell = NULL; + + if ((gc = gc_search_start()) == NULL) { + nt_status = NT_STATUS_INVALID_DOMAIN_STATE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + while (gc) { + char *sid_binstr = NULL; + uint32_t flags = LWCELL_FLAG_SEARCH_FOREST; + + m = NULL; + + flags |= cell_flags(gc->forest_cell); + + switch (fdata->ftype) { + case SidFilter: + sid_binstr = sid_binstring(&fdata->filter.sid); + BAIL_ON_PTR_ERROR(sid_binstr, nt_status); + + filter = talloc_asprintf(frame, "(objectSid=%s)", sid_binstr); + SAFE_FREE(sid_binstr); + break; + case IdFilter: + filter = build_id_filter(fdata->filter.id.id, + fdata->filter.id.type, flags); + break; + case AliasFilter: + filter = build_alias_filter(fdata->filter.alias, flags); + break; + } + + /* First find the sparse object in GC */ + nt_status = gc_search_forest(gc, &m, filter); + if (!NT_STATUS_IS_OK(nt_status)) { + gc = gc->next; + continue; + } + + nt_status = add_ads_result_to_array(cell_connection(gc->forest_cell), + m, &ads_list, &msg_list, + &num_resp); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + gc = gc->next; + } + + /* Uniqueness check across forests */ + + nt_status = check_result_unique_scoped(ads_list, msg_list, num_resp, + &dn, &user_sid); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = search_domain(&domain_cell, &m, dn, &user_sid); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* Save the connection and results in the return parameters */ + + forest_cell->gc_search_cell = domain_cell; + *msg = m; + +done: + PRINT_NTSTATUS_ERROR(nt_status, "search_forest", 4); + + SAFE_FREE(dn); + + free_result_array(ads_list, msg_list, num_resp); + talloc_destroy(frame); + + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + +static NTSTATUS search_cell_list(struct likewise_cell **c, + LDAPMessage **m, + const struct lwcell_filter *fdata) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct likewise_cell *cell = NULL; + LDAPMessage *msg = NULL; + struct likewise_cell *result_cell = NULL; + + if ((cell = cell_list_head()) == NULL) { + nt_status = NT_STATUS_INVALID_SERVER_STATE; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + while (cell) { + /* Clear any previous GC search results */ + + cell->gc_search_cell = NULL; + + if (cell_search_forest(cell)) { + nt_status = search_forest(cell, &msg, fdata); + } else { + nt_status = search_cell(cell, &msg, fdata); + } + + /* Always point to the search result cell. + In forests this might be for another domain + which means the schema model may be different */ + + result_cell = cell->gc_search_cell ? + cell->gc_search_cell : cell; + + /* Check if we are done */ + + if (NT_STATUS_IS_OK(nt_status)) { + break; + } + + /* No luck. Free memory and hit the next cell. + Forest searches always set the gc_search_cell + so give preference to that connection if possible. */ + + ads_msgfree(cell_connection(result_cell), msg); + msg = NULL; + + cell = cell->next; + } + + /* This might be assigning NULL but that is ok as long as we + give back the proper error code */ + + *c = result_cell; + *m = msg; + +done: + PRINT_NTSTATUS_ERROR(nt_status, "search_cell_list", 3); + + return nt_status; +} + +/******************************************************************** + Pull the SID from an object which is always stored in the keywords + attribute as "backLink=S-1-5-21-..." + *******************************************************************/ + +static NTSTATUS pull_sid(struct likewise_cell *c, + LDAPMessage *msg, + DOM_SID *sid) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + TALLOC_CTX *frame = talloc_stackframe(); + ADS_STRUCT *ads = NULL; + + ads = cell_connection(c); + + /* + We have two ways of getting the sid: + (a) from the objectSID in case of a GC search, + (b) from backLink in the case of a cell search. + Pull the keywords attributes and grab the backLink. + */ + + if (!ads_pull_sid(ads, msg, "objectSid", sid)) { + char **keywords; + char *s; + size_t num_lines = 0; + + keywords = ads_pull_strings(ads, frame, msg, + "keywords", &num_lines); + BAIL_ON_PTR_ERROR(keywords, nt_status); + + s = find_attr_string(keywords, num_lines, "backLink"); + if (!s) { + nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + if (!string_to_sid(sid, s)) { + nt_status = NT_STATUS_INVALID_SID; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + } + + nt_status = NT_STATUS_OK; + +done: + talloc_destroy(frame); + + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + +static NTSTATUS get_object_type(struct likewise_cell *c, + LDAPMessage *msg, + enum id_type *type) +{ + TALLOC_CTX *ctx = talloc_stackframe(); + char **oc_list = NULL; + NTSTATUS nt_status = NT_STATUS_OK; + size_t list_size = 0; + char *s = NULL; + ADS_STRUCT *ads = NULL; + + ads = cell_connection(c); + + /* Deal with RFC 2307 support first */ + + if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) { + oc_list = ads_pull_strings(ads, ctx, msg, + "objectClass", &list_size); + if (!oc_list) { + nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto done; + } + + /* Check for posix classes and AD classes */ + + if (is_object_class(oc_list, list_size, ADEX_OC_POSIX_USER) + || is_object_class(oc_list, list_size, AD_USER)) { + *type = ID_TYPE_UID; + } else if (is_object_class(oc_list, list_size, ADEX_OC_POSIX_GROUP) + || is_object_class(oc_list, list_size, AD_GROUP)) { + *type = ID_TYPE_GID; + } else { + *type = ID_TYPE_NOT_SPECIFIED; + nt_status = NT_STATUS_INVALID_PARAMETER; + } + } else { + /* Default to non-schema mode */ + + oc_list = ads_pull_strings(ads, ctx, msg, + "keywords", &list_size); + if (!oc_list) { + nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto done; + } + + s = find_attr_string(oc_list, list_size, "objectClass"); + if (!s) { + nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto done; + } + + if (strequal(s, ADEX_OC_USER)) { + *type = ID_TYPE_UID; + } else if (strequal(s, ADEX_OC_GROUP)) { + *type = ID_TYPE_GID; + } else { + *type = ID_TYPE_NOT_SPECIFIED; + nt_status = NT_STATUS_INVALID_PARAMETER; + } + } + + nt_status = NT_STATUS_OK; + +done: + talloc_destroy(ctx); + + return nt_status; +} + +/******************************************************************** + Pull an attribute uint32_t value + *******************************************************************/ + +static NTSTATUS get_object_uint32(struct likewise_cell *c, + LDAPMessage *msg, + const char *attrib, + uint32_t *x) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char **keywords = NULL; + size_t list_size = 0; + TALLOC_CTX *frame = talloc_stackframe(); + ADS_STRUCT *ads = NULL; + + ads = cell_connection(c); + + /* Deal with RFC2307 schema */ + + if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) { + if (!ads_pull_uint32(ads, msg, attrib, x)) { + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + } else { + /* Non-schema mode */ + char *s = NULL; + uint32_t num; + + keywords = ads_pull_strings(ads, frame, msg, "keywords", + &list_size); + BAIL_ON_PTR_ERROR(keywords, nt_status); + + s = find_attr_string(keywords, list_size, attrib); + if (!s) { + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + num = strtoll(s, NULL, 10); + if (errno == ERANGE) { + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + *x = num; + } + + nt_status = NT_STATUS_OK; + +done: + talloc_destroy(frame); + + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + +static NTSTATUS get_object_id(struct likewise_cell *c, + LDAPMessage *msg, + enum id_type type, + uint32_t *id) +{ + NTSTATUS nt_status = NT_STATUS_OK; + const char *id_attr; + + /* Figure out which attribute we need to pull */ + + switch (type) { + case ID_TYPE_UID: + id_attr = ADEX_ATTR_UIDNUM; + break; + case ID_TYPE_GID: + id_attr = ADEX_ATTR_GIDNUM; + break; + default: + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + break; + } + + nt_status = get_object_uint32(c, msg, id_attr, id); + BAIL_ON_NTSTATUS_ERROR(nt_status); + +done: + return nt_status; +} + +/******************************************************************** + Pull the uid/gid and type from an object. This differs depending on + the cell flags. + *******************************************************************/ + +static NTSTATUS pull_id(struct likewise_cell *c, + LDAPMessage *msg, + uint32_t *id, + enum id_type *type) +{ + NTSTATUS nt_status; + + nt_status = get_object_type(c, msg, type); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = get_object_id(c, msg, *type, id); + BAIL_ON_NTSTATUS_ERROR(nt_status); + +done: + return nt_status; +} + +/******************************************************************** + Pull an attribute string value + *******************************************************************/ + +static NTSTATUS get_object_string(struct likewise_cell *c, + LDAPMessage *msg, + TALLOC_CTX *ctx, + const char *attrib, + char **string) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char **keywords = NULL; + size_t list_size = 0; + TALLOC_CTX *frame = talloc_stackframe(); + ADS_STRUCT *ads = NULL; + + *string = NULL; + + ads = cell_connection(c); + + /* Deal with RFC2307 schema */ + + if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) { + *string = ads_pull_string(ads, ctx, msg, attrib); + } else { + /* Non-schema mode */ + + char *s = NULL; + + keywords = ads_pull_strings(ads, frame, msg, + "keywords", &list_size); + if (!keywords) { + nt_status = NT_STATUS_NO_MEMORY; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + s = find_attr_string(keywords, list_size, attrib); + if (s) { + *string = talloc_strdup(ctx, s); + } + } + + if (!*string) { + nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + nt_status = NT_STATUS_OK; + +done: + talloc_destroy(frame); + + return nt_status; +} + +/******************************************************************** + Pull the struct passwd fields for a user + *******************************************************************/ + +static NTSTATUS pull_nss_info(struct likewise_cell *c, + LDAPMessage *msg, + TALLOC_CTX *ctx, + char **homedir, + char **shell, + char **gecos, + gid_t *p_gid) +{ + NTSTATUS nt_status; + + nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_HOMEDIR, homedir); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_SHELL, shell); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_GECOS, gecos); + /* Gecos is often not set so ignore failures */ + + nt_status = get_object_uint32(c, msg, ADEX_ATTR_GIDNUM, p_gid); + BAIL_ON_NTSTATUS_ERROR(nt_status); + +done: + return nt_status; +} + +/******************************************************************** + Pull the struct passwd fields for a user + *******************************************************************/ + +static NTSTATUS pull_alias(struct likewise_cell *c, + LDAPMessage *msg, + TALLOC_CTX *ctx, + char **alias) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + enum id_type type; + const char *attr = NULL; + + /* Figure out if this is a user or a group */ + + nt_status = get_object_type(c, msg, &type); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + switch (type) { + case ID_TYPE_UID: + attr = ADEX_ATTR_UID; + break; + case ID_TYPE_GID: + /* What is the group attr for RFC2307 Forests? */ + attr = ADEX_ATTR_DISPLAYNAME; + break; + default: + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + break; + } + + nt_status = get_object_string(c, msg, ctx, attr, alias); + BAIL_ON_NTSTATUS_ERROR(nt_status); + +done: + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + +static NTSTATUS _ccp_get_sid_from_id(DOM_SID * sid, + uint32_t id, enum id_type type) +{ + struct likewise_cell *cell = NULL; + LDAPMessage *msg = NULL; + NTSTATUS nt_status; + struct lwcell_filter filter; + + filter.ftype = IdFilter; + filter.filter.id.id = id; + filter.filter.id.type = type; + + nt_status = search_cell_list(&cell, &msg, &filter); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = pull_sid(cell, msg, sid); + BAIL_ON_NTSTATUS_ERROR(nt_status); + +done: + ads_msgfree(cell->conn, msg); + + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + +static NTSTATUS _ccp_get_id_from_sid(uint32_t * id, + enum id_type *type, + const DOM_SID * sid) +{ + struct likewise_cell *cell = NULL; + LDAPMessage *msg = NULL; + NTSTATUS nt_status; + struct lwcell_filter filter; + + filter.ftype = SidFilter; + sid_copy(&filter.filter.sid, sid); + + nt_status = search_cell_list(&cell, &msg, &filter); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = pull_id(cell, msg, id, type); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + if (*id < min_id_value()) { + nt_status = NT_STATUS_INVALID_PARAMETER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + +done: + ads_msgfree(cell->conn, msg); + + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + +static NTSTATUS _ccp_nss_get_info(const DOM_SID * sid, + TALLOC_CTX * ctx, + char **homedir, + char **shell, + char **gecos, gid_t * p_gid) +{ + struct likewise_cell *cell = NULL; + LDAPMessage *msg = NULL; + NTSTATUS nt_status; + struct lwcell_filter filter; + enum id_type type; + + filter.ftype = SidFilter; + sid_copy(&filter.filter.sid, sid); + + nt_status = search_cell_list(&cell, &msg, &filter); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = get_object_type(cell, msg, &type); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + if (type != ID_TYPE_UID) { + nt_status = NT_STATUS_NO_SUCH_USER; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + nt_status = pull_nss_info(cell, msg, ctx, homedir, shell, gecos, + (uint32_t*) p_gid); + BAIL_ON_NTSTATUS_ERROR(nt_status); + +done: + ads_msgfree(cell->conn, msg); + + return nt_status; +} + +/********************************************************************** + *********************************************************************/ + +static NTSTATUS _ccp_map_to_alias(TALLOC_CTX *ctx, + const char *domain, + const char *name, char **alias) +{ + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + DOM_SID sid; + struct likewise_cell *cell = NULL; + LDAPMessage *msg = NULL; + struct lwcell_filter filter; + enum lsa_SidType sid_type; + + /* Convert the name to a SID */ + + nt_status = gc_name_to_sid(domain, name, &sid, &sid_type); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* Find the user/group */ + + filter.ftype = SidFilter; + sid_copy(&filter.filter.sid, &sid); + + nt_status = search_cell_list(&cell, &msg, &filter); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* Pull the alias and return */ + + nt_status = pull_alias(cell, msg, ctx, alias); + BAIL_ON_NTSTATUS_ERROR(nt_status); + +done: + PRINT_NTSTATUS_ERROR(nt_status, "map_to_alias", 3); + + talloc_destroy(frame); + ads_msgfree(cell_connection(cell), msg); + + return nt_status; +} + +/********************************************************************** + Map from an alias name to the canonical, qualified name. + Ensure that the alias is only pull from the closest in which + the user or gorup is enabled in + *********************************************************************/ + +static NTSTATUS _ccp_map_from_alias(TALLOC_CTX *mem_ctx, + const char *domain, + const char *alias, char **name) +{ + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + DOM_SID sid; + struct likewise_cell *cell_alias = NULL; + LDAPMessage *msg_alias = NULL; + struct likewise_cell *cell_sid = NULL; + LDAPMessage *msg_sid = NULL; + struct lwcell_filter filter; + char *canonical_name = NULL; + enum lsa_SidType type; + + /* Find the user/group */ + + filter.ftype = AliasFilter; + fstrcpy(filter.filter.alias, alias); + + nt_status = search_cell_list(&cell_alias, &msg_alias, &filter); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + nt_status = pull_sid(cell_alias, msg_alias, &sid); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + /* Now search again for the SID according to the cell list. + Verify that the cell of both search results is the same + so that we only match an alias from the closest cell + in which a user/group has been instantied. */ + + filter.ftype = SidFilter; + sid_copy(&filter.filter.sid, &sid); + + nt_status = search_cell_list(&cell_sid, &msg_sid, &filter); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + if (cell_alias != cell_sid) { + nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND; + BAIL_ON_NTSTATUS_ERROR(nt_status); + } + + /* Finally do the GC sid/name conversion */ + + nt_status = gc_sid_to_name(&sid, &canonical_name, &type); + BAIL_ON_NTSTATUS_ERROR(nt_status); + + *name = talloc_strdup(mem_ctx, canonical_name); + BAIL_ON_PTR_ERROR((*name), nt_status); + + nt_status = NT_STATUS_OK; + +done: + PRINT_NTSTATUS_ERROR(nt_status, "map_from_alias", 3); + + ads_msgfree(cell_connection(cell_alias), msg_alias); + ads_msgfree(cell_connection(cell_sid), msg_sid); + + SAFE_FREE(canonical_name); + + talloc_destroy(frame); + + return nt_status; +} + +/******************************************************************** + *******************************************************************/ + +struct cell_provider_api ccp_unified = { + .get_sid_from_id = _ccp_get_sid_from_id, + .get_id_from_sid = _ccp_get_id_from_sid, + .get_nss_info = _ccp_nss_get_info, + .map_to_alias = _ccp_map_to_alias, + .map_from_alias = _ccp_map_from_alias +}; -- cgit From 6660ac5d0ab882e1fd70a72af96b1b1e815b4b14 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 23 Sep 2008 01:24:56 +0200 Subject: Fix make pch in the merged build --- source3/configure.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/configure.in b/source3/configure.in index d1000d9a52..f23f6b55be 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -6272,8 +6272,10 @@ fi SMBD_LIBS="$samba_dmapi_libs" AC_SUBST(SMBD_LIBS) +CFLAGS="${CFLAGS} \$(FLAGS)" + if test x$MERGED_BUILD != x1; then - CFLAGS="${CFLAGS} \$(FLAGS) -D_SAMBA_BUILD_=3" + CFLAGS="${CFLAGS} -D_SAMBA_BUILD_=3" fi AC_OUTPUT(Makefile -- cgit From f093ddbc111ccdfe0995d40d24bed94a3d62deb6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 02:41:44 +0200 Subject: s3-charset: add smb_iconv_convenience. Guenther --- source3/include/charset.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3') diff --git a/source3/include/charset.h b/source3/include/charset.h index 4d04b5a1a6..1c2a5fb5f0 100644 --- a/source3/include/charset.h +++ b/source3/include/charset.h @@ -18,6 +18,8 @@ along with this program. If not, see . */ +struct smb_iconv_convenience; + /* this defines the charset types used in samba */ typedef enum {CH_UTF16LE=0, CH_UTF16=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4, CH_UTF16BE=5} charset_t; -- cgit From 9421ecac33b79dcb56b685c2b17d32cff7524331 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 08:31:34 +0200 Subject: s3-nbt: fix nbt.idl in order to use shared nbt helper. Guenther --- source3/librpc/idl/nbt.idl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/librpc/idl/nbt.idl b/source3/librpc/idl/nbt.idl index 654f53c52f..99bffc8755 100644 --- a/source3/librpc/idl/nbt.idl +++ b/source3/librpc/idl/nbt.idl @@ -73,11 +73,11 @@ interface nbt nbt_name_type type; } nbt_name; - typedef [enum16bit] enum { + typedef [public,enum16bit] enum { NBT_QCLASS_IP = 0x01 } nbt_qclass; - typedef [enum16bit] enum { + typedef [public,enum16bit] enum { NBT_QTYPE_ADDRESS = 0x0001, NBT_QTYPE_NAMESERVICE = 0x0002, NBT_QTYPE_NULL = 0x000A, @@ -160,7 +160,7 @@ interface nbt uint8 data[length]; } nbt_rdata_data; - typedef [nodiscriminant] union { + typedef [nodiscriminant,public] union { [case(NBT_QTYPE_NETBIOS)] nbt_rdata_netbios netbios; [case(NBT_QTYPE_STATUS)] nbt_rdata_status status; [default] nbt_rdata_data data; -- cgit From c8858058e93aa5c44df5fd64f2844a34e240a0e9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 08:58:37 +0200 Subject: s3: re-run make idl. Guenther --- source3/librpc/gen_ndr/nbt.h | 2 +- source3/librpc/gen_ndr/ndr_nbt.c | 12 ++++++------ source3/librpc/gen_ndr/ndr_nbt.h | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'source3') diff --git a/source3/librpc/gen_ndr/nbt.h b/source3/librpc/gen_ndr/nbt.h index 62ad524a91..0943ee1a4d 100644 --- a/source3/librpc/gen_ndr/nbt.h +++ b/source3/librpc/gen_ndr/nbt.h @@ -221,7 +221,7 @@ union nbt_rdata { struct nbt_rdata_netbios netbios;/* [case(NBT_QTYPE_NETBIOS)] */ struct nbt_rdata_status status;/* [case(NBT_QTYPE_STATUS)] */ struct nbt_rdata_data data;/* [default] */ -}/* [nodiscriminant] */; +}/* [nodiscriminant,public] */; struct nbt_res_rec { struct nbt_name name; diff --git a/source3/librpc/gen_ndr/ndr_nbt.c b/source3/librpc/gen_ndr/ndr_nbt.c index 75667183a8..01cccd6742 100644 --- a/source3/librpc/gen_ndr/ndr_nbt.c +++ b/source3/librpc/gen_ndr/ndr_nbt.c @@ -77,13 +77,13 @@ _PUBLIC_ void ndr_print_nbt_name(struct ndr_print *ndr, const char *name, const ndr->depth--; } -static enum ndr_err_code ndr_push_nbt_qclass(struct ndr_push *ndr, int ndr_flags, enum nbt_qclass r) +_PUBLIC_ enum ndr_err_code ndr_push_nbt_qclass(struct ndr_push *ndr, int ndr_flags, enum nbt_qclass r) { NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r)); return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_nbt_qclass(struct ndr_pull *ndr, int ndr_flags, enum nbt_qclass *r) +_PUBLIC_ enum ndr_err_code ndr_pull_nbt_qclass(struct ndr_pull *ndr, int ndr_flags, enum nbt_qclass *r) { uint16_t v; NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v)); @@ -101,13 +101,13 @@ _PUBLIC_ void ndr_print_nbt_qclass(struct ndr_print *ndr, const char *name, enum ndr_print_enum(ndr, name, "ENUM", val, r); } -static enum ndr_err_code ndr_push_nbt_qtype(struct ndr_push *ndr, int ndr_flags, enum nbt_qtype r) +_PUBLIC_ enum ndr_err_code ndr_push_nbt_qtype(struct ndr_push *ndr, int ndr_flags, enum nbt_qtype r) { NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r)); return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_nbt_qtype(struct ndr_pull *ndr, int ndr_flags, enum nbt_qtype *r) +_PUBLIC_ enum ndr_err_code ndr_pull_nbt_qtype(struct ndr_pull *ndr, int ndr_flags, enum nbt_qtype *r) { uint16_t v; NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v)); @@ -496,7 +496,7 @@ _PUBLIC_ void ndr_print_nbt_rdata_data(struct ndr_print *ndr, const char *name, ndr->depth--; } -static enum ndr_err_code ndr_push_nbt_rdata(struct ndr_push *ndr, int ndr_flags, const union nbt_rdata *r) +_PUBLIC_ enum ndr_err_code ndr_push_nbt_rdata(struct ndr_push *ndr, int ndr_flags, const union nbt_rdata *r) { if (ndr_flags & NDR_SCALARS) { int level = ndr_push_get_switch_value(ndr, r); @@ -532,7 +532,7 @@ static enum ndr_err_code ndr_push_nbt_rdata(struct ndr_push *ndr, int ndr_flags, return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_nbt_rdata(struct ndr_pull *ndr, int ndr_flags, union nbt_rdata *r) +_PUBLIC_ enum ndr_err_code ndr_pull_nbt_rdata(struct ndr_pull *ndr, int ndr_flags, union nbt_rdata *r) { int level; level = ndr_pull_get_switch_value(ndr, r); diff --git a/source3/librpc/gen_ndr/ndr_nbt.h b/source3/librpc/gen_ndr/ndr_nbt.h index 6e9702d5d5..f6f3e3c899 100644 --- a/source3/librpc/gen_ndr/ndr_nbt.h +++ b/source3/librpc/gen_ndr/ndr_nbt.h @@ -13,7 +13,11 @@ void ndr_print_nbt_name_type(struct ndr_print *ndr, const char *name, enum nbt_n enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r); enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r); void ndr_print_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r); +enum ndr_err_code ndr_push_nbt_qclass(struct ndr_push *ndr, int ndr_flags, enum nbt_qclass r); +enum ndr_err_code ndr_pull_nbt_qclass(struct ndr_pull *ndr, int ndr_flags, enum nbt_qclass *r); void ndr_print_nbt_qclass(struct ndr_print *ndr, const char *name, enum nbt_qclass r); +enum ndr_err_code ndr_push_nbt_qtype(struct ndr_push *ndr, int ndr_flags, enum nbt_qtype r); +enum ndr_err_code ndr_pull_nbt_qtype(struct ndr_pull *ndr, int ndr_flags, enum nbt_qtype *r); void ndr_print_nbt_qtype(struct ndr_print *ndr, const char *name, enum nbt_qtype r); void ndr_print_nbt_name_question(struct ndr_print *ndr, const char *name, const struct nbt_name_question *r); void ndr_print_nb_flags(struct ndr_print *ndr, const char *name, uint16_t r); @@ -23,6 +27,8 @@ void ndr_print_nbt_statistics(struct ndr_print *ndr, const char *name, const str void ndr_print_nbt_status_name(struct ndr_print *ndr, const char *name, const struct nbt_status_name *r); void ndr_print_nbt_rdata_status(struct ndr_print *ndr, const char *name, const struct nbt_rdata_status *r); void ndr_print_nbt_rdata_data(struct ndr_print *ndr, const char *name, const struct nbt_rdata_data *r); +enum ndr_err_code ndr_push_nbt_rdata(struct ndr_push *ndr, int ndr_flags, const union nbt_rdata *r); +enum ndr_err_code ndr_pull_nbt_rdata(struct ndr_pull *ndr, int ndr_flags, union nbt_rdata *r); void ndr_print_nbt_rdata(struct ndr_print *ndr, const char *name, const union nbt_rdata *r); void ndr_print_nbt_res_rec(struct ndr_print *ndr, const char *name, const struct nbt_res_rec *r); enum ndr_err_code ndr_push_nbt_name_packet(struct ndr_push *ndr, int ndr_flags, const struct nbt_name_packet *r); -- cgit From c48186f507219e8732f02bdc2f835a7d8d02541c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 08:09:37 +0200 Subject: s3: use samba4 prototype for ndr_push/pull_struct_blob. Guenther --- source3/include/proto.h | 6 ++---- source3/libads/authdata.c | 14 +++++++------- source3/libads/cldap.c | 2 +- source3/librpc/ndr/ndr.c | 14 ++++++++++---- source3/libsmb/dsgetdcname.c | 4 ++-- source3/libsmb/samlogon_cache.c | 4 ++-- source3/smbd/notify_internal.c | 8 ++++---- source3/winbindd/winbindd_pam.c | 2 +- 8 files changed, 29 insertions(+), 25 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 194548c082..ddd3a573f2 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3960,16 +3960,14 @@ _PUBLIC_ enum ndr_err_code ndr_print_set_switch_value(struct ndr_print *ndr, con _PUBLIC_ uint32_t ndr_push_get_switch_value(struct ndr_push *ndr, const void *p); _PUBLIC_ uint32_t ndr_pull_get_switch_value(struct ndr_pull *ndr, const void *p); _PUBLIC_ uint32_t ndr_print_get_switch_value(struct ndr_print *ndr, const void *p); -_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, - ndr_pull_flags_fn_t fn); +_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, ndr_pull_flags_fn_t fn); _PUBLIC_ enum ndr_err_code ndr_pull_struct_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, ndr_pull_flags_fn_t fn); _PUBLIC_ enum ndr_err_code ndr_pull_union_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, uint32_t level, ndr_pull_flags_fn_t fn); _PUBLIC_ enum ndr_err_code ndr_pull_union_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, uint32_t level, ndr_pull_flags_fn_t fn); -_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, const void *p, - ndr_push_flags_fn_t fn); +_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const void *p, ndr_push_flags_fn_t fn); _PUBLIC_ enum ndr_err_code ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, uint32_t level, ndr_push_flags_fn_t fn); _PUBLIC_ size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t push); diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 0bde3e6984..40f051c851 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -108,7 +108,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, } ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data, - pac_data, + NULL, pac_data, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -124,7 +124,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, } ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data_raw, - pac_data_raw, + NULL, pac_data_raw, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -205,7 +205,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, /* We find the data blobs above, now we parse them to get at the exact portion we should zero */ ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, - kdc_sig_wipe, + NULL, kdc_sig_wipe, (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -215,7 +215,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, } ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe, - srv_sig_wipe, + NULL, srv_sig_wipe, (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -230,7 +230,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, /* and reencode, back into the same place it came from */ ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw, - kdc_sig_wipe, + NULL, kdc_sig_wipe, (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -239,7 +239,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, return status; } ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw, - srv_sig_wipe, + NULL, srv_sig_wipe, (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -250,7 +250,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, /* push out the whole structure, but now with zero'ed signatures */ ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw, - pac_data_raw, + NULL, pac_data_raw, (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 11565065af..73b28b523a 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -294,7 +294,7 @@ bool pull_mailslot_cldap_reply(TALLOC_CTX *mem_ctx, uint32_t nt_version_query = ((*nt_version) & 0x0000001f); uint16_t command = 0; - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, &command, + ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL, &command, (ndr_pull_flags_fn_t)ndr_pull_uint16); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; diff --git a/source3/librpc/ndr/ndr.c b/source3/librpc/ndr/ndr.c index d94d12e146..624024c94d 100644 --- a/source3/librpc/ndr/ndr.c +++ b/source3/librpc/ndr/ndr.c @@ -803,8 +803,11 @@ _PUBLIC_ uint32_t ndr_print_get_switch_value(struct ndr_print *ndr, const void * /* pull a struct from a blob using NDR */ -_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p, - ndr_pull_flags_fn_t fn) +_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, + TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + void *p, + ndr_pull_flags_fn_t fn) { struct ndr_pull *ndr; ndr = ndr_pull_init_blob(blob, mem_ctx); @@ -868,8 +871,11 @@ _PUBLIC_ enum ndr_err_code ndr_pull_union_blob_all(const DATA_BLOB *blob, TALLOC /* push a struct to a blob using NDR */ -_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, const void *p, - ndr_push_flags_fn_t fn) +_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, + TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + const void *p, + ndr_push_flags_fn_t fn) { struct ndr_push *ndr; ndr = ndr_push_init_ctx(mem_ctx); diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 2a445cbd5a..e822635546 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -331,7 +331,7 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx, return status; } - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &logon29, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &logon29, (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon_29); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); @@ -508,7 +508,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &r, (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon_29); data_blob_free(&blob); diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 4abe5bb6de..af4986fa9d 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -141,7 +141,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3) NDR_PRINT_DEBUG(netsamlogoncache_entry, &r); } - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &r, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &r, (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n")); @@ -197,7 +197,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID * blob = data_blob_const(data.dptr, data.dsize); - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &r, (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry); if (DEBUGLEVEL >= 10) { diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c index 84b8e1098e..06da717799 100644 --- a/source3/smbd/notify_internal.c +++ b/source3/smbd/notify_internal.c @@ -166,7 +166,7 @@ static NTSTATUS notify_load(struct notify_context *notify, struct db_record *rec status = NT_STATUS_OK; if (blob.length > 0) { enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->array, + ndr_err = ndr_pull_struct_blob(&blob, notify->array, NULL, notify->array, (ndr_pull_flags_fn_t)ndr_pull_notify_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -220,7 +220,7 @@ static NTSTATUS notify_save(struct notify_context *notify, struct db_record *rec tmp_ctx = talloc_new(notify); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, notify->array, (ndr_push_flags_fn_t)ndr_push_notify_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -258,7 +258,7 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data return; } - ndr_err = ndr_pull_struct_blob(data, tmp_ctx, &ev, + ndr_err = ndr_pull_struct_blob(data, tmp_ctx, NULL, &ev, (ndr_pull_flags_fn_t)ndr_pull_notify_event); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -561,7 +561,7 @@ static NTSTATUS notify_send(struct notify_context *notify, struct notify_entry * tmp_ctx = talloc_new(notify); - ndr_err = ndr_push_struct_blob(&data, tmp_ctx, &ev, + ndr_err = ndr_push_struct_blob(&data, tmp_ctx, NULL, &ev, (ndr_push_flags_fn_t)ndr_push_notify_event); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index d9104ca600..9ff3899661 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -127,7 +127,7 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx, DATA_BLOB blob; enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info3, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, info3, (ndr_push_flags_fn_t)ndr_push_netr_SamInfo3); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0,("append_info3_as_ndr: failed to append\n")); -- cgit From 83c042583b8a18fbb41e1fa8402ac91490941cff Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 08:59:19 +0200 Subject: s3-nbt: refer to ../libcli/nbt in nbt.idl. Guenther --- source3/librpc/idl/nbt.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/librpc/idl/nbt.idl b/source3/librpc/idl/nbt.idl index 99bffc8755..da1eb2ef3f 100644 --- a/source3/librpc/idl/nbt.idl +++ b/source3/librpc/idl/nbt.idl @@ -10,7 +10,7 @@ import "misc.idl", "security.idl", "svcctl.idl", "samr.idl"; [ -helper("libcli/nbt/libnbt.h") +helper("../libcli/nbt/libnbt.h") ] interface nbt { -- cgit From 9f8813e4d4f4963e6ec15e1886e03421c782f638 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 08:59:40 +0200 Subject: s3: re-run make idl. Guenther --- source3/librpc/gen_ndr/ndr_nbt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/librpc/gen_ndr/ndr_nbt.h b/source3/librpc/gen_ndr/ndr_nbt.h index f6f3e3c899..f70d1ba8df 100644 --- a/source3/librpc/gen_ndr/ndr_nbt.h +++ b/source3/librpc/gen_ndr/ndr_nbt.h @@ -6,7 +6,7 @@ #ifndef _HEADER_NDR_nbt #define _HEADER_NDR_nbt -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" #define NDR_NBT_CALL_COUNT (0) void ndr_print_nbt_operation(struct ndr_print *ndr, const char *name, uint16_t r); void ndr_print_nbt_name_type(struct ndr_print *ndr, const char *name, enum nbt_name_type r); -- cgit From 7f5aef542ae07e5b53a2372c41b6da4e1123459b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 08:34:22 +0200 Subject: s3-nbt: use ../libcli/nbt helper. Guenther --- source3/Makefile.in | 2 +- source3/include/proto.h | 17 ----------------- 2 files changed, 1 insertion(+), 18 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 1ce0ce9067..94d8d50da8 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -376,7 +376,7 @@ LIBADS_SERVER_OBJ = libads/kerberos_verify.o libads/authdata.o \ SECRETS_OBJ = passdb/secrets.o passdb/machine_sid.o -LIBNBT_OBJ = libcli/nbt/nbtname.o \ +LIBNBT_OBJ = ../libcli/nbt/nbtname.o \ librpc/gen_ndr/ndr_nbt.o \ librpc/gen_ndr/ndr_svcctl.o diff --git a/source3/include/proto.h b/source3/include/proto.h index ddd3a573f2..a2772384c5 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2204,23 +2204,6 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads, char **returned_principal); -/* The following definitions come from libcli/nbt/nbtname.c */ - -_PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s); -_PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s); -_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s); -_PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r); -_PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r); -_PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname); -_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name); -_PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name); -_PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, - struct nbt_name *n, const char *name, int type); -_PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name); -_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r); -_PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r); -_PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r); - /* The following definitions come from libgpo/gpext/gpext.c */ struct gp_extension *get_gp_extension_list(void); -- cgit From fd3ba988dca5014a9a2d5636506265c084e5db97 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 09:49:56 +0200 Subject: s3-nbt: fix remaining callers of ndr_push/pull_struct_blob. Guenther --- source3/lib/messages_local.c | 4 ++-- source3/lib/secdesc.c | 4 ++-- source3/libnet/libnet_dssync_keytab.c | 6 +++--- source3/libnet/libnet_samsync.c | 4 ++-- source3/libsmb/clidgram.c | 2 +- source3/modules/vfs_acl_xattr.c | 4 ++-- source3/modules/vfs_xattr_tdb.c | 4 ++-- source3/utils/net_rpc_registry.c | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) (limited to 'source3') diff --git a/source3/lib/messages_local.c b/source3/lib/messages_local.c index f436afc2ff..9f7f88f783 100644 --- a/source3/lib/messages_local.c +++ b/source3/lib/messages_local.c @@ -160,7 +160,7 @@ static NTSTATUS messaging_tdb_fetch(TDB_CONTEXT *msg_tdb, blob = data_blob_const(data.dptr, data.dsize); ndr_err = ndr_pull_struct_blob( - &blob, result, result, + &blob, result, NULL, result, (ndr_pull_flags_fn_t)ndr_pull_messaging_array); SAFE_FREE(data.dptr); @@ -203,7 +203,7 @@ static NTSTATUS messaging_tdb_store(TDB_CONTEXT *msg_tdb, } ndr_err = ndr_push_struct_blob( - &blob, mem_ctx, array, + &blob, mem_ctx, NULL, array, (ndr_push_flags_fn_t)ndr_push_messaging_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index 44ae23271e..4965200bc1 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -249,7 +249,7 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx, enum ndr_err_code ndr_err; ndr_err = ndr_push_struct_blob( - &blob, mem_ctx, secdesc, + &blob, mem_ctx, NULL, secdesc, (ndr_push_flags_fn_t)ndr_push_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -285,7 +285,7 @@ NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len, blob = data_blob_const(data, len); ndr_err = ndr_pull_struct_blob( - &blob, result, result, + &blob, result, NULL, result, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source3/libnet/libnet_dssync_keytab.c b/source3/libnet/libnet_dssync_keytab.c index 6ba2c3aa41..e762ecbe49 100644 --- a/source3/libnet/libnet_dssync_keytab.c +++ b/source3/libnet/libnet_dssync_keytab.c @@ -86,7 +86,7 @@ static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx, old_utdv = talloc(mem_ctx, struct replUpToDateVectorBlob); ndr_err = ndr_pull_struct_blob(&entry->password, old_utdv, - old_utdv, + NULL, old_utdv, (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); @@ -124,7 +124,7 @@ static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx, NDR_PRINT_DEBUG(replUpToDateVectorBlob, new_utdv); } - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, new_utdv, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, new_utdv, (ndr_push_flags_fn_t)ndr_push_replUpToDateVectorBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -236,7 +236,7 @@ static NTSTATUS parse_supplemental_credentials(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto done; } - ndr_err = ndr_pull_struct_blob(&scpk_blob, mem_ctx, pkb, + ndr_err = ndr_pull_struct_blob(&scpk_blob, mem_ctx, NULL, pkb, (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c index daf27ffb51..64dcf6de51 100644 --- a/source3/libnet/libnet_samsync.c +++ b/source3/libnet/libnet_samsync.c @@ -65,7 +65,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, user->user_private_info.SensitiveData = data.data; user->user_private_info.DataLength = data.length; - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, &keys, + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, NULL, &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { dump_data(10, data.data, data.length); @@ -397,7 +397,7 @@ NTSTATUS pull_netr_AcctLockStr(TALLOC_CTX *mem_ctx, blob = data_blob_const(r->array, r->length); - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, str, + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, str, (ndr_pull_flags_fn_t)ndr_pull_netr_AcctLockStr); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 8b35a69def..8ee3507a04 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -181,7 +181,7 @@ bool send_getdc_request(TALLOC_CTX *mem_ctx, NDR_PRINT_DEBUG(nbt_ntlogon_packet, &packet); } - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &packet, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &packet, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index fd59310755..a2f3477b76 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -38,7 +38,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, size_t sd_size; struct timespec ts; - ndr_err = ndr_pull_struct_blob(pblob, ctx, &xacl, + ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl, (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -245,7 +245,7 @@ static NTSTATUS create_acl_blob(SEC_DESC *psd, DATA_BLOB *pblob) unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr); ndr_err = ndr_push_struct_blob( - pblob, ctx, &xacl, + pblob, ctx, NULL, &xacl, (ndr_push_flags_fn_t)ndr_push_xattr_NTACL); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 7b5e510747..c707a1828f 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -48,7 +48,7 @@ static NTSTATUS xattr_tdb_pull_attrs(TALLOC_CTX *mem_ctx, blob = data_blob_const(data->dptr, data->dsize); ndr_err = ndr_pull_struct_blob( - &blob, result, result, + &blob, result, NULL, result, (ndr_pull_flags_fn_t)ndr_pull_tdb_xattrs); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -74,7 +74,7 @@ static NTSTATUS xattr_tdb_push_attrs(TALLOC_CTX *mem_ctx, enum ndr_err_code ndr_err; ndr_err = ndr_push_struct_blob( - &blob, mem_ctx, attribs, + &blob, mem_ctx, NULL, attribs, (ndr_push_flags_fn_t)ndr_push_tdb_xattrs); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c index 124af00b57..005e3ca556 100644 --- a/source3/utils/net_rpc_registry.c +++ b/source3/utils/net_rpc_registry.c @@ -1186,7 +1186,7 @@ static NTSTATUS rpc_registry_getsd_internal(struct net_context *c, blob.data = sd->data; blob.length = sd->size; - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc, + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &sec_desc, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); -- cgit From 6c8c5d7113fda1a0d6a843f2564e84e2a3daf4c2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 22 Sep 2008 10:34:57 +0200 Subject: [s3]winbind_util: fix an implicit cast compile warning. Michael --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index e7b6576317..b296465ed5 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1160,7 +1160,7 @@ void parse_add_domuser(void *buf, char *domuser, int *len) } } - safe_strcpy(buf, user, *len); + safe_strcpy((char *)buf, user, *len); } /* Ensure an incoming username from NSS is fully qualified. Replace the -- cgit From f0dccdca6a9da4440406f9cccd76805cad87d7e6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 22 Sep 2008 14:51:51 +0200 Subject: [s3]winbindd: fix a comment typo Michael --- source3/winbindd/winbindd_async.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c index 1481aed8e1..7500bcbe5b 100644 --- a/source3/winbindd/winbindd_async.c +++ b/source3/winbindd/winbindd_async.c @@ -366,7 +366,7 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success, /******************************************************************** The lookup name call first contacts a DC in its own domain - and fallbacks to contact a DC in the forest in our domain doesn't + and fallbacks to contact a DC if the forest in our domain doesn't know the name. ********************************************************************/ -- cgit From e401ce6de79e696d8dda7b56568b1565d2e21f62 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 22 Sep 2008 10:36:32 +0200 Subject: [s3]winbindd_util: add prototype for fill_domain_username_talloc(). A talloc version of fill_domain_username(). Michael --- source3/winbindd/winbindd_proto.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3') diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 4774bc8106..3836c46e36 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -569,6 +569,10 @@ bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, void parse_add_domuser(void *buf, char *domuser, int *len); bool canonicalize_username(fstring username_inout, fstring domain, fstring user); void fill_domain_username(fstring name, const char *domain, const char *user, bool can_assume); +char *fill_domain_username_talloc(TALLOC_CTX *ctx, + const char *domain, + const char *user, + bool can_assume); const char *get_winbind_pipe_dir(void) ; char *get_winbind_priv_pipe_dir(void) ; int open_winbindd_socket(void); -- cgit From 1b9c2ccb1f1ba4d67ee0d82f4ff89b0abd62cbe2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 22 Sep 2008 10:37:11 +0200 Subject: [s3]winbindd_util: add fill_domain_username_talloc(). A talloc version of fill_domain_username(). Michael --- source3/winbindd/winbindd_util.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'source3') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index b296465ed5..5b5ca41a74 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1213,6 +1213,33 @@ void fill_domain_username(fstring name, const char *domain, const char *user, bo } } +/** + * talloc version of fill_domain_username() + * return NULL on talloc failure. + */ +char *fill_domain_username_talloc(TALLOC_CTX *mem_ctx, + const char *domain, + const char *user, + bool can_assume) +{ + char *tmp_user, *name; + + tmp_user = talloc_strdup(mem_ctx, user); + strlower_m(tmp_user); + + if (can_assume && assume_domain(domain)) { + name = tmp_user; + } else { + name = talloc_asprintf(mem_ctx, "%s%c%s", + domain, + *lp_winbind_separator(), + tmp_user); + TALLOC_FREE(tmp_user); + } + + return name; +} + /* * Winbindd socket accessor functions */ -- cgit From 1f8a7739ace7715b20c9b8c72732ab1ff689b552 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 21 Sep 2008 01:20:32 +0200 Subject: [s3]winbindd_rpc: add domain prefix to username in lookup_groupmem(). This makes the output of "getent group" of a domain group show the domain prefix with "security = domain". Michael --- source3/winbindd/winbindd_rpc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index df80ad8029..9fbea8e45b 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -854,7 +854,10 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, } for (r=0; rname, + tmp_names.names[r].string, + true); (*name_types)[i+r] = tmp_types.ids[r]; } -- cgit From 49145bfefae54672c5d4cccdbb9dd33e1cd89b88 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 22 Sep 2008 10:39:37 +0200 Subject: [s3]winbindd_ads: honour "winbind use default domain" in lookup_groupmem(). This fixes the output of "getent group" when "winbind use default domain = yes" with security = ads. Michael --- source3/winbindd/winbindd_ads.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 894e7866b3..1febddf110 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -1023,10 +1023,11 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, DEBUG(10,("ads: lookup_groupmem: got sid %s from " "cache\n", sid_string_dbg(&sid))); sid_copy(&(*sid_mem)[*num_names], &sid); - (*names)[*num_names] = talloc_asprintf(*names, "%s%c%s", - domain_name, - *lp_winbind_separator(), - name ); + (*names)[*num_names] = fill_domain_username_talloc( + *names, + domain_name, + name, + true); (*name_types)[*num_names] = name_type; (*num_names)++; @@ -1071,11 +1072,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, { sid_copy(&(*sid_mem)[*num_names], &sid_mem_nocache[i]); - (*names)[*num_names] = talloc_asprintf( *names, - "%s%c%s", - domains_nocache[i], - *lp_winbind_separator(), - names_nocache[i] ); + (*names)[*num_names] = + fill_domain_username_talloc( + *names, + domains_nocache[i], + names_nocache[i], + true); (*name_types)[*num_names] = name_types_nocache[i]; (*num_names)++; } -- cgit From 4205fab500927a4248fda622e1c338b7e791617f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 21 Sep 2008 02:06:44 +0200 Subject: [s3]winbindd_group: sanely handle NULL domain in add_member(). Michael --- source3/winbindd/winbindd_group.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c index 088f946877..b2bba09537 100644 --- a/source3/winbindd/winbindd_group.c +++ b/source3/winbindd/winbindd_group.c @@ -35,7 +35,11 @@ static void add_member(const char *domain, const char *user, { fstring name; - fill_domain_username(name, domain, user, True); + if (domain != NULL) { + fill_domain_username(name, domain, user, True); + } else { + fstrcpy(name, user); + } safe_strcat(name, ",", sizeof(name)-1); string_append(pp_members, name); *p_num_members += 1; -- cgit From 4432967532897cc90ce7d7b11fab6f6f88f8bfc0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 21 Sep 2008 02:07:43 +0200 Subject: [s3]winbindd_group: don't list the domain twice when expanding internal aliases Before this, "getent group builtin\\administrators" expanded domain group members in the form DOMAIN\domain\user. Michael --- source3/winbindd/winbindd_group.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c index b2bba09537..f2b6fbefb5 100644 --- a/source3/winbindd/winbindd_group.c +++ b/source3/winbindd/winbindd_group.c @@ -140,7 +140,7 @@ static void add_expanded_sid(const DOM_SID *sid, continue; } - add_member(domain->name, names[i], pp_members, p_num_members); + add_member(NULL, names[i], pp_members, p_num_members); } done: -- cgit From 05e0966d85e7b6c61c88edb4633d0dda40959f01 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 23 Sep 2008 10:04:17 +0200 Subject: s3-nbt: remove old samba3 libcli/nbt copy. Guenther --- source3/libcli/nbt/libnbt.h | 353 ------------------------ source3/libcli/nbt/nbtname.c | 626 ------------------------------------------- 2 files changed, 979 deletions(-) delete mode 100644 source3/libcli/nbt/libnbt.h delete mode 100644 source3/libcli/nbt/nbtname.c (limited to 'source3') diff --git a/source3/libcli/nbt/libnbt.h b/source3/libcli/nbt/libnbt.h deleted file mode 100644 index d37a17c192..0000000000 --- a/source3/libcli/nbt/libnbt.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a raw async NBT library - - Copyright (C) Andrew Tridgell 2005 - - 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 . -*/ - -#ifndef __LIBNBT_H__ -#define __LIBNBT_H__ - -#include "librpc/gen_ndr/nbt.h" -#include "librpc/ndr/libndr.h" - -/* - possible states for pending requests -*/ -enum nbt_request_state {NBT_REQUEST_SEND, - NBT_REQUEST_WAIT, - NBT_REQUEST_DONE, - NBT_REQUEST_TIMEOUT, - NBT_REQUEST_ERROR}; - -/* - a nbt name request -*/ -struct nbt_name_request { - struct nbt_name_request *next, *prev; - - enum nbt_request_state state; - - NTSTATUS status; - - /* the socket this was on */ - struct nbt_name_socket *nbtsock; - - /* where to send the request */ - struct socket_address *dest; - - /* timeout between retries */ - int timeout; - - /* how many retries to send on timeout */ - int num_retries; - - /* whether we have received a WACK */ - bool received_wack; - - /* the timeout event */ - struct timed_event *te; - - /* the name transaction id */ - uint16_t name_trn_id; - - /* is it a reply? */ - bool is_reply; - - /* the encoded request */ - DATA_BLOB encoded; - - /* shall we allow multiple replies? */ - bool allow_multiple_replies; - - unsigned int num_replies; - struct nbt_name_reply { - struct nbt_name_packet *packet; - struct socket_address *dest; - } *replies; - - /* information on what to do on completion */ - struct { - void (*fn)(struct nbt_name_request *); - void *_private; - } async; -}; - - - -/* - context structure for operations on name queries -*/ -struct nbt_name_socket { - struct socket_context *sock; - struct event_context *event_ctx; -/* - struct smb_iconv_convenience *iconv_convenience; -*/ - /* a queue of requests pending to be sent */ - struct nbt_name_request *send_queue; - - /* the fd event */ - struct fd_event *fde; - - /* mapping from name_trn_id to pending event */ - struct idr_context *idr; - - /* how many requests are waiting for a reply */ - uint16_t num_pending; - - /* what to do with incoming request packets */ - struct { - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *); - void *_private; - } incoming; - - /* what to do with unexpected replies */ - struct { - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *); - void *_private; - } unexpected; -}; - - -/* a simple name query */ -struct nbt_name_query { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - bool broadcast; - bool wins_lookup; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - int16_t num_addrs; - const char **reply_addrs; - } out; -}; - -/* a simple name status query */ -struct nbt_name_status { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - struct nbt_rdata_status status; - } out; -}; - -/* a name registration request */ -struct nbt_name_register { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool register_demand; - bool broadcast; - bool multi_homed; - uint32_t ttl; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -/* a send 3 times then demand name broadcast name registration */ -struct nbt_name_register_bcast { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - uint32_t ttl; - } in; -}; - - -/* wins name register with multiple wins servers to try and multiple - addresses to register */ -struct nbt_name_register_wins { - struct { - struct nbt_name name; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - uint16_t nb_flags; - uint32_t ttl; - } in; - struct { - const char *wins_server; - uint8_t rcode; - } out; -}; - - - -/* a name refresh request */ -struct nbt_name_refresh { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool broadcast; - uint32_t ttl; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -/* wins name refresh with multiple wins servers to try and multiple - addresses to register */ -struct nbt_name_refresh_wins { - struct { - struct nbt_name name; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - uint16_t nb_flags; - uint32_t ttl; - } in; - struct { - const char *wins_server; - uint8_t rcode; - } out; -}; - - -/* a name release request */ -struct nbt_name_release { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool broadcast; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx); - /*, - struct smb_iconv_convenience *iconv_convenience);*/ -struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, - struct nbt_name_query *io); -NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io); -NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io); -struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, - struct nbt_name_status *io); -NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io); -NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io); - -NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname); -NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name); -NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name); -void nbt_choose_called_name(TALLOC_CTX *mem_ctx, struct nbt_name *n, const char *name, int type); -char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name); -NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io); -NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io); -NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io); -NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io); -NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io); -NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io); -struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register *io); -NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io); - -struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, - struct nbt_name_release *io); - -NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io); - -NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *), - void *_private); -NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, - struct socket_address *dest, - struct nbt_name_packet *request); - - -NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *); -NDR_SCALAR_PROTO(nbt_string, const char *); -NDR_BUFFER_PROTO(nbt_name, struct nbt_name); -NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode); - -struct composite_context; -struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_bcast *io); -NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c); -struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_wins *io); -NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io); -struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh_wins *io); -NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io); - - -#endif /* __LIBNBT_H__ */ diff --git a/source3/libcli/nbt/nbtname.c b/source3/libcli/nbt/nbtname.c deleted file mode 100644 index fbb9550655..0000000000 --- a/source3/libcli/nbt/nbtname.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - manipulate nbt name structures - - Copyright (C) Andrew Tridgell 2005 - - 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 . -*/ - -/* - see rfc1002 for the detailed format of compressed names -*/ - -#include "includes.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "librpc/gen_ndr/ndr_misc.h" - -/* don't allow an unlimited number of name components */ -#define MAX_COMPONENTS 10 - -/** - print a nbt string -*/ -_PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s) -{ - ndr_print_string(ndr, name, s); -} - -/* - pull one component of a nbt_string -*/ -static enum ndr_err_code ndr_pull_component(struct ndr_pull *ndr, - uint8_t **component, - uint32_t *offset, - uint32_t *max_offset) -{ - uint8_t len; - uint_t loops = 0; - while (loops < 5) { - if (*offset >= ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - len = ndr->data[*offset]; - if (len == 0) { - *offset += 1; - *max_offset = MAX(*max_offset, *offset); - *component = NULL; - return NDR_ERR_SUCCESS; - } - if ((len & 0xC0) == 0xC0) { - /* its a label pointer */ - if (1 + *offset >= ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - *max_offset = MAX(*max_offset, *offset + 2); - *offset = ((len&0x3F)<<8) | ndr->data[1 + *offset]; - *max_offset = MAX(*max_offset, *offset); - loops++; - continue; - } - if ((len & 0xC0) != 0) { - /* its a reserved length field */ - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - if (*offset + len + 2 > ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - *component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len); - NDR_ERR_HAVE_NO_MEMORY(*component); - *offset += len + 1; - *max_offset = MAX(*max_offset, *offset); - return NDR_ERR_SUCCESS; - } - - /* too many pointers */ - return ndr_pull_error(ndr, NDR_ERR_STRING, "BAD NBT NAME component"); -} - -/** - pull a nbt_string from the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) -{ - uint32_t offset = ndr->offset; - uint32_t max_offset = offset; - unsigned num_components; - char *name; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - name = NULL; - - /* break up name into a list of components */ - for (num_components=0;num_componentsoffset = max_offset; - - return NDR_ERR_SUCCESS; -} - -/** - push a nbt string to the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) -{ - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - while (s && *s) { - enum ndr_err_code ndr_err; - char *compname; - size_t complen; - uint32_t offset; - - /* see if we have pushed the remaing string allready, - * if so we use a label pointer to this string - */ - ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - uint8_t b[2]; - - if (offset > 0x3FFF) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "offset for nbt string label pointer %u[%08X] > 0x00003FFF", - offset, offset); - } - - b[0] = 0xC0 | (offset>>8); - b[1] = (offset & 0xFF); - - return ndr_push_bytes(ndr, b, 2); - } - - complen = strcspn(s, "."); - - /* we need to make sure the length fits into 6 bytes */ - if (complen >= 0x3F) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "component length %u[%08X] > 0x00003F", - (unsigned)complen, (unsigned)complen); - } - - compname = talloc_asprintf(ndr, "%c%*.*s", - (unsigned char)complen, - (unsigned char)complen, - (unsigned char)complen, s); - NDR_ERR_HAVE_NO_MEMORY(compname); - - /* remember the current componemt + the rest of the string - * so it can be reused later - */ - NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset)); - - /* push just this component into the blob */ - NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1)); - talloc_free(compname); - - s += complen; - if (*s == '.') s++; - } - - /* if we reach the end of the string and have pushed the last component - * without using a label pointer, we need to terminate the string - */ - return ndr_push_bytes(ndr, (const uint8_t *)"", 1); -} - - -/* - decompress a 'compressed' name component - */ -static bool decompress_name(char *name, enum nbt_name_type *type) -{ - int i; - for (i=0;name[2*i];i++) { - uint8_t c1 = name[2*i]; - uint8_t c2 = name[1+(2*i)]; - if (c1 < 'A' || c1 > 'P' || - c2 < 'A' || c2 > 'P') { - return false; - } - name[i] = ((c1-'A')<<4) | (c2-'A'); - } - name[i] = 0; - if (i == 16) { - *type = (enum nbt_name_type)(name[15]); - name[15] = 0; - i--; - } else { - *type = NBT_NAME_CLIENT; - } - - /* trim trailing spaces */ - for (;i>0 && name[i-1]==' ';i--) { - name[i-1] = 0; - } - - return true; -} - - -/* - compress a name component - */ -static uint8_t *compress_name(TALLOC_CTX *mem_ctx, - const uint8_t *name, enum nbt_name_type type) -{ - uint8_t *cname; - int i; - uint8_t pad_char; - - if (strlen((const char *)name) > 15) { - return NULL; - } - - cname = talloc_array(mem_ctx, uint8_t, 33); - if (cname == NULL) return NULL; - - for (i=0;name[i];i++) { - cname[2*i] = 'A' + (name[i]>>4); - cname[1+2*i] = 'A' + (name[i]&0xF); - } - if (strcmp((const char *)name, "*") == 0) { - pad_char = 0; - } else { - pad_char = ' '; - } - for (;i<15;i++) { - cname[2*i] = 'A' + (pad_char>>4); - cname[1+2*i] = 'A' + (pad_char&0xF); - } - - pad_char = type; - cname[2*i] = 'A' + (pad_char>>4); - cname[1+2*i] = 'A' + (pad_char&0xF); - - cname[32] = 0; - return cname; -} - - -/** - pull a nbt name from the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) -{ - uint8_t *scope; - char *cname; - const char *s; - bool ok; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - NDR_CHECK(ndr_pull_nbt_string(ndr, ndr_flags, &s)); - - scope = (uint8_t *)strchr(s, '.'); - if (scope) { - *scope = 0; - r->scope = talloc_strdup(ndr->current_mem_ctx, (const char *)&scope[1]); - NDR_ERR_HAVE_NO_MEMORY(r->scope); - } else { - r->scope = NULL; - } - - cname = discard_const_p(char, s); - - /* the first component is limited to 16 bytes in the DOS charset, - which is 32 in the 'compressed' form */ - if (strlen(cname) > 32) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "NBT NAME cname > 32"); - } - - /* decompress the first component */ - ok = decompress_name(cname, &r->type); - if (!ok) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "NBT NAME failed to decompress"); - } - - r->name = talloc_strdup(ndr->current_mem_ctx, cname); - NDR_ERR_HAVE_NO_MEMORY(r->name); - - talloc_free(cname); - - return NDR_ERR_SUCCESS; -} - -/** - push a nbt name to the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) -{ - uint8_t *cname, *fullname; - enum ndr_err_code ndr_err; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - if (strlen(r->name) > 15) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "nbt_name longer as 15 chars: %s", - r->name); - } - - cname = compress_name(ndr, (const uint8_t *)r->name, r->type); - NDR_ERR_HAVE_NO_MEMORY(cname); - - if (r->scope) { - fullname = (uint8_t *)talloc_asprintf(ndr, "%s.%s", cname, r->scope); - NDR_ERR_HAVE_NO_MEMORY(fullname); - talloc_free(cname); - } else { - fullname = cname; - } - - ndr_err = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname); - - return ndr_err; -} - - -/** - copy a nbt name structure -*/ -_PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname) -{ - *newname = *name; - newname->name = talloc_strdup(mem_ctx, newname->name); - NT_STATUS_HAVE_NO_MEMORY(newname->name); - newname->scope = talloc_strdup(mem_ctx, newname->scope); - if (name->scope) { - NT_STATUS_HAVE_NO_MEMORY(newname->scope); - } - return NT_STATUS_OK; -} - -/** - push a nbt name into a blob -*/ -_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name) -{ - enum ndr_err_code ndr_err; - - ndr_err = ndr_push_struct_blob(blob, mem_ctx, name, (ndr_push_flags_fn_t)ndr_push_nbt_name); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - - return NT_STATUS_OK; -} - -/** - pull a nbt name from a blob -*/ -_PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name) -{ - enum ndr_err_code ndr_err; - - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, name, - (ndr_pull_flags_fn_t)ndr_pull_nbt_name); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - - return NT_STATUS_OK; -} - - -/** - choose a name to use when calling a server in a NBT session request. - we use heuristics to see if the name we have been given is a IP - address, or a too-long name. If it is then use *SMBSERVER, or a - truncated name -*/ -_PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, - struct nbt_name *n, const char *name, int type) -{ - n->scope = NULL; - n->type = type; - - if ((name == NULL) || is_ipaddress(name)) { - n->name = "*SMBSERVER"; - return; - } - if (strlen(name) > 15) { - const char *p = strchr(name, '.'); - char *s; - if (p - name > 15) { - n->name = "*SMBSERVER"; - return; - } - s = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name)); - n->name = talloc_strdup_upper(mem_ctx, s); - return; - } - - n->name = talloc_strdup_upper(mem_ctx, name); -} - - -/* - escape a string into a form containing only a small set of characters, - the rest is hex encoded. This is similar to URL encoding -*/ -static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) -{ - int i, len; - char *ret; - const char *valid_chars = "_-.$@ "; -#define NBT_CHAR_ALLOW(c) (isalnum((unsigned char)c) || strchr(valid_chars, c)) - - for (len=i=0;s[i];i++,len++) { - if (!NBT_CHAR_ALLOW(s[i])) { - len += 2; - } - } - - ret = talloc_array(mem_ctx, char, len+1); - if (ret == NULL) return NULL; - - for (len=i=0;s[i];i++) { - if (NBT_CHAR_ALLOW(s[i])) { - ret[len++] = s[i]; - } else { - snprintf(&ret[len], 4, "%%%02x", (unsigned char)s[i]); - len += 3; - } - } - ret[len] = 0; - - return ret; -} - - -/** - form a string for a NBT name -*/ -_PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) -{ - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - char *ret; - if (name->scope) { - ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s", - nbt_hex_encode(tmp_ctx, name->name), - name->type, - nbt_hex_encode(tmp_ctx, name->scope)); - } else { - ret = talloc_asprintf(mem_ctx, "%s<%02x>", - nbt_hex_encode(tmp_ctx, name->name), - name->type); - } - talloc_free(tmp_ctx); - return ret; -} - -/** - pull a nbt name, WINS Replication uses another on wire format for nbt name -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r) -{ - struct nbt_name *r; - uint8_t *namebuf; - uint32_t namebuf_len; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &namebuf_len)); - if (namebuf_len < 1 || namebuf_len > 255) { - return ndr_pull_error(ndr, NDR_ERR_ALLOC, "value out of range"); - } - NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); - - NDR_PULL_ALLOC(ndr, r); - - /* oh wow, what a nasty bug in windows ... */ - if (namebuf[0] == 0x1b && namebuf_len >= 16) { - namebuf[0] = namebuf[15]; - namebuf[15] = 0x1b; - } - - if (namebuf_len < 17) { - r->type = 0x00; - - r->name = talloc_strndup(r, (char *)namebuf, namebuf_len); - if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); - - r->scope= NULL; - - talloc_free(namebuf); - *_r = r; - return NDR_ERR_SUCCESS; - } - - r->type = namebuf[15]; - - namebuf[15] = '\0'; - trim_string((char *)namebuf, NULL, " "); - r->name = talloc_strdup(r, (char *)namebuf); - if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); - - if (namebuf_len > 18) { - r->scope = talloc_strndup(r, (char *)(namebuf+17), namebuf_len-17); - if (!r->scope) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); - } else { - r->scope = NULL; - } - - talloc_free(namebuf); - *_r = r; - return NDR_ERR_SUCCESS; -} - -/** - push a nbt name, WINS Replication uses another on wire format for nbt name -*/ -_PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) -{ - uint8_t *namebuf; - uint32_t namebuf_len; - uint32_t _name_len; - uint32_t scope_len = 0; - - if (r == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, - "wrepl_nbt_name NULL pointer"); - } - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - _name_len = strlen(r->name); - if (_name_len > 15) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "wrepl_nbt_name longer as 15 chars: %s", - r->name); - } - - if (r->scope) { - scope_len = strlen(r->scope); - } - if (scope_len > 238) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "wrepl_nbt_name scope longer as 238 chars: %s", - r->scope); - } - - namebuf = (uint8_t *)talloc_asprintf(ndr, "%-15s%c%s", - r->name, 'X', - (r->scope?r->scope:"")); - if (!namebuf) return ndr_push_error(ndr, NDR_ERR_ALLOC, "out of memory"); - - namebuf_len = strlen((char *)namebuf) + 1; - - /* - * we need to set the type here, and use a place-holder in the talloc_asprintf() - * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results - */ - namebuf[15] = r->type; - - /* oh wow, what a nasty bug in windows ... */ - if (r->type == 0x1b) { - namebuf[15] = namebuf[0]; - namebuf[0] = 0x1b; - } - - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, namebuf_len)); - NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); - - talloc_free(namebuf); - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r) -{ - char *s = nbt_name_string(ndr, r); - ndr_print_string(ndr, name, s); - talloc_free(s); -} -- cgit