diff options
author | Simo Sorce <idra@samba.org> | 2010-07-19 13:48:31 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2010-07-19 13:48:31 -0400 |
commit | f9f3358348229b14d368316e327cfd2a4cb48c7c (patch) | |
tree | 9fb61c2ed61dd1ff93a64fc4498a4ec8d3a0607d | |
parent | 7e4de49bfceed18c81abf93703a61d0a22617a24 (diff) | |
parent | 630a2eb68af0d523a1bb4451bbaa75d2ba47d252 (diff) | |
download | samba-f9f3358348229b14d368316e327cfd2a4cb48c7c.tar.gz samba-f9f3358348229b14d368316e327cfd2a4cb48c7c.tar.bz2 samba-f9f3358348229b14d368316e327cfd2a4cb48c7c.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
44 files changed, 617 insertions, 350 deletions
diff --git a/buildtools/wafsamba/samba_pidl.py b/buildtools/wafsamba/samba_pidl.py index b932f59d77..521222dc5c 100644 --- a/buildtools/wafsamba/samba_pidl.py +++ b/buildtools/wafsamba/samba_pidl.py @@ -79,6 +79,13 @@ def SAMBA_PIDL(bld, pname, source, # gen_ndr directory we end up generating identical output in gen_ndr for the old # build system and the new one. That makes keeping things in sync much easier. # eventually we should drop the gen_ndr files in git, but in the meanwhile this works + + found_dir = bld.path.find_dir(output_dir) + if not 'abspath' in dir(found_dir): + Logs.error('Unable to find pidl output directory %s' % + os.path.normpath(os.path.join(bld.curdir, output_dir))) + sys.exit(1) + outdir = bld.path.find_dir(output_dir).abspath(t.env) if symlink and not os.path.lexists(outdir): diff --git a/docs-xml/smbdotconf/misc/ctdblocktimewarnthreshold.xml b/docs-xml/smbdotconf/misc/ctdblocktimewarnthreshold.xml index 149d8d67e3..a3289a93bc 100644 --- a/docs-xml/smbdotconf/misc/ctdblocktimewarnthreshold.xml +++ b/docs-xml/smbdotconf/misc/ctdblocktimewarnthreshold.xml @@ -4,13 +4,25 @@ advanced="1" xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> <description> - <para>In a cluster, ctdb is very unhappy if tdb database locks - are held for extended periods of time. This parameter adds a - warning threshold in milliseconds. If Samba holds a lock for - longer that ctdb locktime warn threshold milliseconds, a debug - level 0 message is printed when the lock is released. This is - mainly a debugging aid for post-mortem analysis.</para> - <para>If this parameter is set to 0, no message is printed.</para> + + <para> + In a cluster environment using Samba and ctdb it is critical + that locks on central ctdb-hosted databases like locking.tdb + are not held for long. With the current Samba architecture + it happens that Samba takes a lock and while holding that + lock makes file system calls into the shared cluster file + system. This option makes Samba warn if it detects that it + has held locks for the specified number of milliseconds. If + this happens, <emphasis>smbd</emphasis> will emit a debug level 0 + message into its logs and potentially into syslog. The most likely + reason for such a log message is that an operation of the cluster + file system Samba exports is taking longer than expected. + The messages are meant as a debugging aid for potential + cluster problems. + </para> + + <para>The default value of 0 disables this logging.</para> + </description> <value type="default">0</value> </samba:parameter> diff --git a/docs-xml/smbdotconf/misc/logwriteablefilesonexit.xml b/docs-xml/smbdotconf/misc/logwriteablefilesonexit.xml index 1c75457803..9d2b750943 100644 --- a/docs-xml/smbdotconf/misc/logwriteablefilesonexit.xml +++ b/docs-xml/smbdotconf/misc/logwriteablefilesonexit.xml @@ -5,10 +5,17 @@ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> <description> <para> - This boolean option controls whether at exit time the server - dumps a list of files with debug level 0 that were still open - for write. This is an administrative aid to find the files - that were potentially corrupt if the network connection died. + When the network connection between a CIFS client and Samba + dies, Samba has no option but to simply shut down the server + side of the network connection. If this happens, there is a + risk of data corruption because the Windows client did not + complete all write operations that the Windows application + requested. Setting this option to "yes" makes smbd log with + a level 0 message a list of all files that have been opened + for writing when the network connection died. Those are the + files that are potentially corrupted. It is meant as an aid + for the administrator to give him a list of files to do + consistency checks on. </para> </description> diff --git a/docs-xml/smbdotconf/security/usernamemapcachetime.xml b/docs-xml/smbdotconf/security/usernamemapcachetime.xml index 5461cb1a6c..4361b1896d 100644 --- a/docs-xml/smbdotconf/security/usernamemapcachetime.xml +++ b/docs-xml/smbdotconf/security/usernamemapcachetime.xml @@ -4,13 +4,22 @@ type="integer" xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> <description> - <para>This option controls if and how long the result of the - <smbconfoption name="username map"/> and - <smbconfoption name="username map script"/> across smbds in gencache. - If set to non-zero, it denotes the number of seconds the output of - both mappings will be cached.</para> - <para>This option is mainly useful for heavy-weight - <smbconfoption name="username map script"/> scripts.</para> + <para> + Mapping usernames with the <smbconfoption name="username map"/> + or <smbconfoption name="username map script"/> + features of Samba can be relatively expensive. + During login of a user, the mapping is done several times. + In particular, calling the <smbconfoption name="username map script"/> + can slow down logins if external databases have to be queried from + the script being called. + </para> + + <para> + The parameter <smbconfoption name="username map cache time"/> + controls a mapping cache. It specifies the number of seconds a + mapping from the username map file or script is to be efficiently cached. + The default of 0 means no caching is done. + </para> </description> <value type="default">0</value> diff --git a/docs-xml/smbdotconf/tuning/smb2maxread.xml b/docs-xml/smbdotconf/tuning/smb2maxread.xml deleted file mode 100644 index a3abbbc4ca..0000000000 --- a/docs-xml/smbdotconf/tuning/smb2maxread.xml +++ /dev/null @@ -1,13 +0,0 @@ -<samba:parameter name="smb2 max read" - context="G" - advanced="1" developer="1" - xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> -<description> - <para>This sets the maximum read size in bytes for a single SMB2 read request. - It exists to allow the Samba developers to experiment with different - size requests for tuning purposes. - </para> -</description> - -<value type="default">65536</value> -</samba:parameter> diff --git a/docs-xml/smbdotconf/tuning/smb2maxtrans.xml b/docs-xml/smbdotconf/tuning/smb2maxtrans.xml deleted file mode 100644 index 4e6fee0e75..0000000000 --- a/docs-xml/smbdotconf/tuning/smb2maxtrans.xml +++ /dev/null @@ -1,13 +0,0 @@ -<samba:parameter name="smb2 max trans" - context="G" - advanced="1" developer="1" - xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> -<description> - <para>This sets the maximum read size in bytes for a single SMB2 transact request. - It exists to allow the Samba developers to experiment with different - size requests for tuning purposes. - </para> -</description> - -<value type="default">65536</value> -</samba:parameter> diff --git a/docs-xml/smbdotconf/tuning/smb2maxwrite.xml b/docs-xml/smbdotconf/tuning/smb2maxwrite.xml deleted file mode 100644 index 5085dba435..0000000000 --- a/docs-xml/smbdotconf/tuning/smb2maxwrite.xml +++ /dev/null @@ -1,13 +0,0 @@ -<samba:parameter name="smb2 max write" - context="G" - advanced="1" developer="1" - xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> -<description> - <para>This sets the maximum read size in bytes for a single SMB2 write request. - It exists to allow the Samba developers to experiment with different - size requests for tuning purposes. - </para> -</description> - -<value type="default">65536</value> -</samba:parameter> diff --git a/librpc/gen_ndr/README b/librpc/gen_ndr/README index 0c1fd160a5..5ccb89db5d 100644 --- a/librpc/gen_ndr/README +++ b/librpc/gen_ndr/README @@ -1 +1,4 @@ This contains the generated files from PIDL for the IDL files in ../idl/*.idl + +DO NOT REMOVE THIS FILE. The waf 1.5 build relies on this directory +existing in the source tree. diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm index 0ea43e48ad..04475d26c9 100644 --- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm +++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm @@ -257,10 +257,19 @@ sub ParseInterface($) pidl ""; if (not has_property($if, "no_srv_register")) { - pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);"; - pidl "NTSTATUS rpc_$if->{NAME}_init(void)"; + pidl_hdr "struct rpc_srv_callbacks;"; + pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb);"; + pidl "NTSTATUS rpc_$if->{NAME}_init(const struct rpc_srv_callbacks *rpc_srv_cb)"; pidl "{"; - pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct));"; + pidl "\treturn rpc_srv_register(SMB_RPC_INTERFACE_VERSION, \"$if->{NAME}\", \"$if->{NAME}\", \&ndr_table_$if->{NAME}, api_$if->{NAME}_cmds, sizeof(api_$if->{NAME}_cmds) / sizeof(struct api_struct), rpc_srv_cb);"; + pidl "}"; + + pidl ""; + + pidl_hdr "NTSTATUS rpc_$if->{NAME}_shutdown(void);"; + pidl "NTSTATUS rpc_$if->{NAME}_shutdown(void)"; + pidl "{"; + pidl "\treturn rpc_srv_unregister(\&ndr_table_$if->{NAME});"; pidl "}"; } pidl_hdr "#endif /* __SRV_$uif\__ */"; diff --git a/source3/auth/auth.c b/source3/auth/auth.c index a52dab9f01..5dc1d970d6 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -322,38 +322,40 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, Clear out a auth_context, and destroy the attached TALLOC_CTX ***************************************************************************/ -static void free_auth_context(struct auth_context **auth_context) +static int auth_context_destructor(void *ptr) { - auth_methods *auth_method; + struct auth_context *ctx = talloc_get_type(ptr, struct auth_context); + struct auth_methods *am; - if (*auth_context) { - /* Free private data of context's authentication methods */ - for (auth_method = (*auth_context)->auth_method_list; auth_method; auth_method = auth_method->next) { - TALLOC_FREE(auth_method->private_data); - } - talloc_destroy(*auth_context); - *auth_context = NULL; + /* Free private data of context's authentication methods */ + for (am = ctx->auth_method_list; am; am = am->next) { + TALLOC_FREE(am->private_data); } + + return 0; } /*************************************************************************** Make a auth_info struct ***************************************************************************/ -static NTSTATUS make_auth_context(struct auth_context **auth_context) +static NTSTATUS make_auth_context(struct auth_context **auth_context) { - *auth_context = TALLOC_ZERO_P(talloc_autofree_context(), - struct auth_context); - if (!*auth_context) { + struct auth_context *ctx; + + ctx = talloc_zero(talloc_autofree_context(), struct auth_context); + if (!ctx) { DEBUG(0,("make_auth_context: talloc failed!\n")); return NT_STATUS_NO_MEMORY; } - (*auth_context)->check_ntlm_password = check_ntlm_password; - (*auth_context)->get_ntlm_challenge = get_ntlm_challenge; - (*auth_context)->free = free_auth_context; + ctx->check_ntlm_password = check_ntlm_password; + ctx->get_ntlm_challenge = get_ntlm_challenge; + + talloc_set_destructor((TALLOC_CTX *)ctx, auth_context_destructor); + *auth_context = ctx; return NT_STATUS_OK; } diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c index e90036f3ff..cdd4096654 100644 --- a/source3/auth/auth_compat.c +++ b/source3/auth/auth_compat.c @@ -59,7 +59,7 @@ NTSTATUS check_plaintext_password(const char *smb_name, nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context, user_info, server_info); - (plaintext_auth_context->free)(&plaintext_auth_context); + TALLOC_FREE(plaintext_auth_context); free_user_info(&user_info); return nt_status; } diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index ba7efbf48e..bebb86ee17 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -24,7 +24,6 @@ #include "../libcli/auth/ntlmssp.h" struct auth_ntlmssp_state { - TALLOC_CTX *mem_ctx; struct auth_context *auth_context; struct auth_serversupplied_info *server_info; struct ntlmssp_state *ntlmssp_state; @@ -241,29 +240,33 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, if (auth_ntlmssp_state->server_info->user_session_key.length) { DEBUG(10, ("Got NT session key of length %u\n", (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length)); - *user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, + *user_session_key = data_blob_talloc(auth_ntlmssp_state, auth_ntlmssp_state->server_info->user_session_key.data, auth_ntlmssp_state->server_info->user_session_key.length); } if (auth_ntlmssp_state->server_info->lm_session_key.length) { DEBUG(10, ("Got LM session key of length %u\n", (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length)); - *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, + *lm_session_key = data_blob_talloc(auth_ntlmssp_state, auth_ntlmssp_state->server_info->lm_session_key.data, auth_ntlmssp_state->server_info->lm_session_key.length); } return nt_status; } +static int auth_ntlmssp_state_destructor(void *ptr); + NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state) { NTSTATUS nt_status; - TALLOC_CTX *mem_ctx; bool is_standalone; const char *netbios_name; const char *netbios_domain; const char *dns_name; char *dns_domain; + struct auth_ntlmssp_state *ans; + struct ntlmssp_state *ntlmssp_state; + struct auth_context *auth_context; if ((enum server_types)lp_server_role() == ROLE_STANDALONE) { is_standalone = true; @@ -280,63 +283,51 @@ NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state) } dns_name = get_mydnsfullname(); - mem_ctx = talloc_init("AUTH NTLMSSP context"); - - *auth_ntlmssp_state = TALLOC_ZERO_P(mem_ctx, struct auth_ntlmssp_state); - if (!*auth_ntlmssp_state) { + ans = talloc_zero(NULL, struct auth_ntlmssp_state); + if (!ans) { DEBUG(0,("auth_ntlmssp_start: talloc failed!\n")); - talloc_destroy(mem_ctx); + TALLOC_FREE(ntlmssp_state); return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(*auth_ntlmssp_state); - - (*auth_ntlmssp_state)->mem_ctx = mem_ctx; - - nt_status = ntlmssp_server_start(NULL, + nt_status = ntlmssp_server_start(ans, is_standalone, netbios_name, netbios_domain, dns_name, dns_domain, - &(*auth_ntlmssp_state)->ntlmssp_state); + &ans->ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } - if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*auth_ntlmssp_state)->auth_context))) { + nt_status = make_auth_context_subsystem(&auth_context); + if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } + ans->auth_context = talloc_steal(ans, auth_context); - (*auth_ntlmssp_state)->ntlmssp_state->callback_private = (*auth_ntlmssp_state); - (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; - (*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; - (*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; - (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password; + ans->ntlmssp_state->callback_private = ans; + ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; + ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; + ans->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; + ans->ntlmssp_state->check_password = auth_ntlmssp_check_password; + talloc_set_destructor((TALLOC_CTX *)ans, auth_ntlmssp_state_destructor); + + *auth_ntlmssp_state = ans; return NT_STATUS_OK; } -void auth_ntlmssp_end(struct auth_ntlmssp_state **auth_ntlmssp_state) +static int auth_ntlmssp_state_destructor(void *ptr) { - TALLOC_CTX *mem_ctx; + struct auth_ntlmssp_state *ans; - if (*auth_ntlmssp_state == NULL) { - return; - } + ans = talloc_get_type(ptr, struct auth_ntlmssp_state); - mem_ctx = (*auth_ntlmssp_state)->mem_ctx; - if ((*auth_ntlmssp_state)->ntlmssp_state) { - ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state); - } - if ((*auth_ntlmssp_state)->auth_context) { - ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context); - } - if ((*auth_ntlmssp_state)->server_info) { - TALLOC_FREE((*auth_ntlmssp_state)->server_info); - } - talloc_destroy(mem_ctx); - *auth_ntlmssp_state = NULL; + TALLOC_FREE(ans->server_info); + TALLOC_FREE(ans->ntlmssp_state); + return 0; } NTSTATUS auth_ntlmssp_update(struct auth_ntlmssp_state *auth_ntlmssp_state, diff --git a/source3/include/auth.h b/source3/include/auth.h index 17257b3433..b7089b8c0a 100644 --- a/source3/include/auth.h +++ b/source3/include/auth.h @@ -115,7 +115,6 @@ struct auth_context { const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **server_info); NTSTATUS (*nt_status_squash)(NTSTATUS nt_status); - void (*free)(struct auth_context **auth_context); }; typedef struct auth_methods diff --git a/source3/include/proto.h b/source3/include/proto.h index 9471f63195..d9f9ab96d4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -66,7 +66,6 @@ bool auth_ntlmssp_negotiated_seal(struct auth_ntlmssp_state *auth_ntlmssp_state) void auth_ntlmssp_want_sign(struct auth_ntlmssp_state *auth_ntlmssp_state); void auth_ntlmssp_want_seal(struct auth_ntlmssp_state *auth_ntlmssp_state); NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state); -void auth_ntlmssp_end(struct auth_ntlmssp_state **auth_ntlmssp_state); NTSTATUS auth_ntlmssp_update(struct auth_ntlmssp_state *auth_ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) ; NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *auth_ntlmssp_state, @@ -3102,7 +3101,6 @@ void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *featur void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature); NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB in, DATA_BLOB *out) ; -void ntlmssp_end(struct ntlmssp_state **ntlmssp_state); DATA_BLOB ntlmssp_weaken_keys(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx); NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, bool is_standalone, @@ -5049,6 +5047,22 @@ void *_policy_handle_find(struct pipes_struct *p, (_access_granted), #_type, __location__, (_pstatus)) +/* The following definitions come from rpc_server/srv_rpc_register.c */ + +struct rpc_srv_callbacks { + bool (*init)(void *private_data); + bool (*shutdown)(void *private_data); + void *private_data; +}; + +NTSTATUS rpc_srv_register(int version, const char *clnt, + const char *srv, + const struct ndr_interface_table *iface, + const struct api_struct *cmds, int size, + const struct rpc_srv_callbacks *rpc_srv_cb); + +NTSTATUS rpc_srv_unregister(const struct ndr_interface_table *iface); + /* The following definitions come from rpc_server/srv_pipe.c */ bool create_next_pdu(pipes_struct *p); @@ -5058,10 +5072,6 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct ndr_syntax_id *interface, const struct api_struct *cmds, int size); -NTSTATUS rpc_srv_register(int version, const char *clnt, - const char *srv, - const struct ndr_interface_table *iface, - const struct api_struct *cmds, int size); bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax); bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt); bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 04b9a71d76..a37d1e8474 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -106,7 +106,7 @@ static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads) struct ntlmssp_state *ntlmssp_state = (struct ntlmssp_state *)ads->ldap.wrap_private_data; - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); ads->ldap.wrap_ops = NULL; ads->ldap.wrap_private_data = NULL; @@ -209,7 +209,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) ber_bvfree(scred); } - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); return ADS_ERROR(rc); } if (scred) { @@ -221,7 +221,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) } else { - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); data_blob_free(&blob_out); return ADS_ERROR_NT(nt_status); } @@ -233,7 +233,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if (!spnego_parse_challenge(blob, &blob_in, &tmp_blob)) { - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); data_blob_free(&blob); DEBUG(3,("Failed to parse challenges\n")); return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -243,7 +243,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, &blob_in)) { - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); data_blob_free(&blob); DEBUG(3,("Failed to parse auth response\n")); return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -266,11 +266,11 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads) if (!ADS_ERR_OK(status)) { DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n", ads_errstr(status))); - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); return status; } } else { - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); } return ADS_ERROR(rc); diff --git a/source3/librpc/gen_ndr/README b/source3/librpc/gen_ndr/README new file mode 100644 index 0000000000..5ccb89db5d --- /dev/null +++ b/source3/librpc/gen_ndr/README @@ -0,0 +1,4 @@ +This contains the generated files from PIDL for the IDL files in ../idl/*.idl + +DO NOT REMOVE THIS FILE. The waf 1.5 build relies on this directory +existing in the source tree. diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 06a6f7e683..8d4c1901c1 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -969,7 +969,7 @@ static int cli_session_setup_ntlmssp_state_destructor( struct cli_session_setup_ntlmssp_state *state) { if (state->ntlmssp_state != NULL) { - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); } return 0; } @@ -1079,7 +1079,7 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) return; } TALLOC_FREE(subreq); - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); tevent_req_done(req); return; } @@ -1122,7 +1122,7 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { TALLOC_FREE(subreq); - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); tevent_req_nterror(req, status); return; } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 228d19536e..a0dc39be3e 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -275,23 +275,6 @@ NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, } /** - * End an NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State, free()ed by this function - */ - -void ntlmssp_end(struct ntlmssp_state **ntlmssp_state) -{ - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); - TALLOC_FREE(*ntlmssp_state); - - *ntlmssp_state = NULL; - return; -} - -/** * Determine correct target name flags for reply, given server role * and negotiated flags * diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 92d7fef651..4610850638 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -371,7 +371,7 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es) if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { if (es->s.ntlmssp_state) { - ntlmssp_end(&es->s.ntlmssp_state); + TALLOC_FREE(es->s.ntlmssp_state); } } #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) diff --git a/source3/m4/aclocal.m4 b/source3/m4/aclocal.m4 index f7f3497a23..3ca44bd496 100644 --- a/source3/m4/aclocal.m4 +++ b/source3/m4/aclocal.m4 @@ -30,9 +30,17 @@ AC_DEFUN(SMB_MODULE, AC_MSG_RESULT([shared]) [$6] string_shared_modules="$string_shared_modules $1" + elif test x"$DEST" = xSTATIC && test x"$4" = xRPC; then + [init_static_modules_]translit([$4], [A-Z], [a-z])="$[init_static_modules_]translit([$4], [A-Z], [a-z]) $1_init(NULL);" + [decl_static_modules_]translit([$4], [A-Z], [a-z])="$[decl_static_modules_]translit([$4], [A-Z], [a-z]) extern NTSTATUS $1_init(const struct rpc_srv_callbacks *rpc_srv_cb);" + string_static_modules="$string_static_modules $1" + $4_STATIC="$$4_STATIC $2" + AC_SUBST($4_STATIC) + [$5] + AC_MSG_RESULT([static]) elif test x"$DEST" = xSTATIC; then [init_static_modules_]translit([$4], [A-Z], [a-z])="$[init_static_modules_]translit([$4], [A-Z], [a-z]) $1_init();" - [decl_static_modules_]translit([$4], [A-Z], [a-z])="$[decl_static_modules_]translit([$4], [A-Z], [a-z]) extern NTSTATUS $1_init(void);" + [decl_static_modules_]translit([$4], [A-Z], [a-z])="$[decl_static_modules_]translit([$4], [A-Z], [a-z]) extern NTSTATUS $1_init(void);" string_static_modules="$string_static_modules $1" $4_STATIC="$$4_STATIC $2" AC_SUBST($4_STATIC) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a61200a104..8dd9386eab 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2704,7 +2704,7 @@ NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth) { - ntlmssp_end(&auth->a_u.ntlmssp_state); + TALLOC_FREE(auth->a_u.ntlmssp_state); return 0; } diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index ebd37241a6..a57836aa75 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -1380,7 +1380,7 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p, user_info, &server_info); } - (auth_context->free)(&auth_context); + TALLOC_FREE(auth_context); free_user_info(&user_info); DEBUG(5,("%s: check_password returned status %s\n", diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a7a5f4d676..a56a6345cc 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -85,12 +85,7 @@ static void dump_pdu_region(const char *name, int v, static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth) { - struct auth_ntlmssp_state *a = auth->a_u.auth_ntlmssp_state; - - if (a) { - auth_ntlmssp_end(&a); - } - auth->a_u.auth_ntlmssp_state = NULL; + TALLOC_FREE(auth->a_u.auth_ntlmssp_state); } static DATA_BLOB generic_session_key(void) diff --git a/source3/rpc_server/srv_pipe_register.c b/source3/rpc_server/srv_pipe_register.c index 757e4fbe72..3753596a2b 100644 --- a/source3/rpc_server/srv_pipe_register.c +++ b/source3/rpc_server/srv_pipe_register.c @@ -31,11 +31,26 @@ struct rpc_table { struct ndr_syntax_id rpc_interface; const struct api_struct *cmds; uint32_t n_cmds; + bool (*shutdown_fn)(void *private_data); + void *shutdown_data; }; static struct rpc_table *rpc_lookup; static uint32_t rpc_lookup_size; +static struct rpc_table *rpc_srv_get_pipe_by_id(const struct ndr_syntax_id *id) +{ + uint32_t i; + + for (i = 0; i < rpc_lookup_size; i++) { + if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) { + return &rpc_lookup[i]; + } + } + + return NULL; +} + bool rpc_srv_pipe_exists_by_id(const struct ndr_syntax_id *id) { uint32_t i; @@ -150,7 +165,8 @@ bool rpc_srv_get_pipe_interface_by_cli_name(const char *cli_name, NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv, const struct ndr_interface_table *iface, - const struct api_struct *cmds, int size) + const struct api_struct *cmds, int size, + const struct rpc_srv_callbacks *rpc_srv_cb) { struct rpc_table *rpc_entry; @@ -166,12 +182,10 @@ NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv, return NT_STATUS_OBJECT_TYPE_MISMATCH; } - /* TODO: - * - * we still need to make sure that don't register the same commands twice!!! - * - * --metze - */ + /* Don't register the same command twice */ + if (rpc_srv_pipe_exists_by_id(&iface->syntax_id)) { + return NT_STATUS_OK; + } /* * We use a temporary variable because this call can fail and @@ -196,5 +210,32 @@ NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv, rpc_entry->cmds = cmds; rpc_entry->n_cmds = size; + if (rpc_srv_cb != NULL) { + rpc_entry->shutdown_fn = rpc_srv_cb->shutdown; + rpc_entry->shutdown_data = rpc_srv_cb->private_data; + + if (rpc_srv_cb->init != NULL && + !rpc_srv_cb->init(rpc_srv_cb->private_data)) { + DEBUG(0, ("rpc_srv_register: Failed to call the %s " + "init function!\n", srv)); + return NT_STATUS_UNSUCCESSFUL; + } + } + + return NT_STATUS_OK; +} + +NTSTATUS rpc_srv_unregister(const struct ndr_interface_table *iface) +{ + struct rpc_table *rpc_entry = rpc_srv_get_pipe_by_id(&iface->syntax_id); + + if (rpc_entry != NULL && rpc_entry->shutdown_fn != NULL) { + if (!rpc_entry->shutdown_fn(rpc_entry->shutdown_data)) { + DEBUG(0, ("rpc_srv_unregister: Failed to call the %s " + "init function!\n", rpc_entry->pipe.srv)); + return NT_STATUS_UNSUCCESSFUL; + } + } + return NT_STATUS_OK; } diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 755d3d9718..4d73216854 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -33,8 +33,7 @@ static void get_challenge(struct smbd_server_connection *sconn, uint8 buff[8]) if (sconn->smb1.negprot.auth_context) { DEBUG(3, ("get challenge: is this a secondary negprot? " "sconn->negprot.auth_context is non-NULL!\n")); - sconn->smb1.negprot.auth_context->free( - &sconn->smb1.negprot.auth_context); + TALLOC_FREE(sconn->smb1.negprot.auth_context); } DEBUG(10, ("get challenge: creating negprot_global_auth_context\n")); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2bd333ab30..996417b51e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -120,7 +120,7 @@ void invalidate_vuid(struct smbd_server_connection *sconn, uint16 vuid) session_yield(vuser); if (vuser->auth_ntlmssp_state) { - auth_ntlmssp_end(&vuser->auth_ntlmssp_state); + TALLOC_FREE(vuser->auth_ntlmssp_state); } DLIST_REMOVE(sconn->smb1.sessions.validated_users, vuser); diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c index 171e809b44..ad785a4588 100644 --- a/source3/smbd/seal.c +++ b/source3/smbd/seal.c @@ -101,7 +101,7 @@ static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec) */ if (ec->auth_ntlmssp_state) { - auth_ntlmssp_end(&ec->auth_ntlmssp_state); + TALLOC_FREE(ec->auth_ntlmssp_state); /* The auth_ntlmssp_end killed this already. */ ec->es->s.ntlmssp_state = NULL; } diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c index 97394aea96..1a330994b8 100644 --- a/source3/smbd/server_exit.c +++ b/source3/smbd/server_exit.c @@ -75,8 +75,7 @@ static void exit_server_common(enum server_exit_reason how, change_to_root_user(); if (sconn && sconn->smb1.negprot.auth_context) { - struct auth_context *a = sconn->smb1.negprot.auth_context; - a->free(&sconn->smb1.negprot.auth_context); + TALLOC_FREE(sconn->smb1.negprot.auth_context); } if (lp_log_writeable_files_on_exit()) { diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 52fcd282a6..27eb4f6c48 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -150,14 +150,14 @@ static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_in } if (!make_user_info_guest(&user_info)) { - (auth_context->free)(&auth_context); + TALLOC_FREE(auth_context); return NT_STATUS_NO_MEMORY; } nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info); - (auth_context->free)(&auth_context); + TALLOC_FREE(auth_context); free_user_info(&user_info); return nt_status; } @@ -708,7 +708,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req, if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* NB. This is *NOT* an error case. JRA */ if (do_invalidate) { - auth_ntlmssp_end(auth_ntlmssp_state); + TALLOC_FREE(*auth_ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { /* Kill the intermediate vuid */ invalidate_vuid(sconn, vuid); @@ -828,7 +828,7 @@ static void reply_spnego_negotiate(struct smb_request *req, #endif if (*auth_ntlmssp_state) { - auth_ntlmssp_end(auth_ntlmssp_state); + TALLOC_FREE(*auth_ntlmssp_state); } if (kerb_mech) { @@ -1751,8 +1751,7 @@ void reply_sesssetup_and_X(struct smb_request *req) user_info, &server_info); - (plaintext_auth_context->free)( - &plaintext_auth_context); + TALLOC_FREE(plaintext_auth_context); } } } diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 493e74802d..4d0f03259b 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -550,7 +550,7 @@ static NTSTATUS smbd_smb2_spnego_negotiate(struct smbd_smb2_session *session, NTSTATUS status; /* Ensure we have no old NTLM state around. */ - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); status = parse_spnego_mechanisms(in_security_buffer, &secblob_in, &kerb_mech); @@ -621,7 +621,7 @@ static NTSTATUS smbd_smb2_spnego_negotiate(struct smbd_smb2_session *session, if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); TALLOC_FREE(session); } return status; @@ -653,7 +653,7 @@ static NTSTATUS smbd_smb2_common_ntlmssp_auth_return(struct smbd_smb2_session *s session->compat_vuser = talloc_zero(session, user_struct); if (session->compat_vuser == NULL) { - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); TALLOC_FREE(session); return NT_STATUS_NO_MEMORY; } @@ -682,7 +682,7 @@ static NTSTATUS smbd_smb2_common_ntlmssp_auth_return(struct smbd_smb2_session *s DEBUG(1, ("smb2: Failed to claim session " "for vuid=%d\n", session->compat_vuser->vuid)); - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); TALLOC_FREE(session); return NT_STATUS_LOGON_FAILURE; } @@ -793,7 +793,7 @@ static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session, if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); data_blob_free(&auth); TALLOC_FREE(session); return status; @@ -808,7 +808,7 @@ static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session, secblob_out.data, secblob_out.length); if (secblob_out.data && out_security_buffer->data == NULL) { - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); TALLOC_FREE(session); return NT_STATUS_NO_MEMORY; } @@ -858,7 +858,7 @@ static NTSTATUS smbd_smb2_raw_ntlmssp_auth(struct smbd_smb2_session *session, secblob_out.data, secblob_out.length); if (secblob_out.data && out_security_buffer->data == NULL) { - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); TALLOC_FREE(session); return NT_STATUS_NO_MEMORY; } @@ -872,7 +872,7 @@ static NTSTATUS smbd_smb2_raw_ntlmssp_auth(struct smbd_smb2_session *session, status = setup_ntlmssp_server_info(session, status); if (!NT_STATUS_IS_OK(status)) { - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); TALLOC_FREE(session); return status; } @@ -971,7 +971,7 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req, /* Unknown packet type. */ DEBUG(1,("Unknown packet type %u in smb2 sessionsetup\n", (unsigned int)in_security_buffer.data[0] )); - auth_ntlmssp_end(&session->auth_ntlmssp_state); + TALLOC_FREE(session->auth_ntlmssp_state); TALLOC_FREE(session); return NT_STATUS_LOGON_FAILURE; } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index e7887cca71..bfdc369b15 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -656,7 +656,7 @@ static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntl if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not start NTLMSSP client: %s\n", nt_errstr(status))); - ntlmssp_end(client_ntlmssp_state); + TALLOC_FREE(*client_ntlmssp_state); return status; } @@ -665,7 +665,7 @@ static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntl if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set username: %s\n", nt_errstr(status))); - ntlmssp_end(client_ntlmssp_state); + TALLOC_FREE(*client_ntlmssp_state); return status; } @@ -674,7 +674,7 @@ static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntl if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set domain: %s\n", nt_errstr(status))); - ntlmssp_end(client_ntlmssp_state); + TALLOC_FREE(*client_ntlmssp_state); return status; } @@ -684,7 +684,7 @@ static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntl if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set password: %s\n", nt_errstr(status))); - ntlmssp_end(client_ntlmssp_state); + TALLOC_FREE(*client_ntlmssp_state); return status; } } @@ -854,7 +854,7 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, if (strncmp(buf, "YR", 2) == 0) { if (state->ntlmssp_state) - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); state->svr_state = SERVER_INITIAL; } else if (strncmp(buf, "KK", 2) == 0) { /* No special preprocessing required */ @@ -916,7 +916,7 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); } else if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); @@ -1010,7 +1010,7 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, if (strncmp(buf, "YR", 2) == 0) { if (state->ntlmssp_state) - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); state->cli_state = CLIENT_INITIAL; } else if (strncmp(buf, "TT", 2) == 0) { /* No special preprocessing required */ @@ -1102,13 +1102,13 @@ static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, DEBUG(10, ("NTLMSSP OK!\n")); state->cli_state = CLIENT_FINISHED; if (state->ntlmssp_state) - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); } else { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); state->cli_state = CLIENT_ERROR; if (state->ntlmssp_state) - ntlmssp_end(&state->ntlmssp_state); + TALLOC_FREE(state->ntlmssp_state); } data_blob_free(&request); @@ -1223,7 +1223,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, if (strncmp(buf, "YR", 2) == 0) { if (ntlmssp_state) - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); } else if (strncmp(buf, "KK", 2) == 0) { ; } else { @@ -1288,7 +1288,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, x_fprintf(x_stdout, "BH Client wants a new " "NTLMSSP challenge, but " "already got one\n"); - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); return; } @@ -1394,7 +1394,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, if (NT_STATUS_IS_OK(status)) { user = SMB_STRDUP(ntlmssp_state->user); domain = SMB_STRDUP(ntlmssp_state->domain); - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); } } @@ -1495,7 +1495,7 @@ static bool manage_client_ntlmssp_init(struct spnego_data spnego) NT_STATUS_IS_OK(status)) ) { DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n", nt_errstr(status))); - ntlmssp_end(&client_ntlmssp_state); + TALLOC_FREE(client_ntlmssp_state); return False; } @@ -1528,13 +1528,13 @@ static void manage_client_ntlmssp_targ(struct spnego_data spnego) if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) { x_fprintf(x_stdout, "NA\n"); - ntlmssp_end(&client_ntlmssp_state); + TALLOC_FREE(client_ntlmssp_state); return; } if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) { x_fprintf(x_stdout, "AF\n"); - ntlmssp_end(&client_ntlmssp_state); + TALLOC_FREE(client_ntlmssp_state); return; } @@ -1549,7 +1549,7 @@ static void manage_client_ntlmssp_targ(struct spnego_data spnego) x_fprintf(x_stdout, "BH Expected MORE_PROCESSING_REQUIRED from " "ntlmssp_client_update\n"); data_blob_free(&request); - ntlmssp_end(&client_ntlmssp_state); + TALLOC_FREE(client_ntlmssp_state); return; } @@ -1798,7 +1798,7 @@ static void manage_gss_spnego_client_request(struct ntlm_auth_state *state, "negResult\n"); } - ntlmssp_end(&client_ntlmssp_state); + TALLOC_FREE(client_ntlmssp_state); goto out; } diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 7e1eb3e714..9efa8ed984 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -1291,8 +1291,8 @@ int main(int argc, char **argv, char **envp) winbindd_register_handlers(); - rpc_lsarpc_init(); - rpc_samr_init(); + rpc_lsarpc_init(NULL); + rpc_samr_init(NULL); if (!init_system_info()) { DEBUG(0,("ERROR: failed to setup system user info.\n")); diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index c5a760af05..6a265ccaf0 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -136,7 +136,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username, status = NT_STATUS_OK; done: - ntlmssp_end(&ntlmssp_state); + TALLOC_FREE(ntlmssp_state); return status; } diff --git a/source3/wscript b/source3/wscript index 0b31563343..66bddcf858 100644 --- a/source3/wscript +++ b/source3/wscript @@ -321,12 +321,20 @@ utimensat vsyslog _write __write __xstat conf.env[shared_env] = [] if p in static_list: decl_list="" - for entry in static_list[p]: - decl_list += "extern NTSTATUS %s_init(void); " % entry - conf.env[static_env].append('%s' % entry.upper()) - decl_list = decl_list.rstrip() - conf.DEFINE('static_decl_%s' % p, decl_list) - conf.DEFINE('static_init_%s' % p, '{ %s_init(); }' % '_init(); '.join(static_list[p])) + if p == "rpc": + for entry in static_list[p]: + decl_list += "extern NTSTATUS %s_init(const struct rpc_srv_callbacks *rpc_srv_cb); " % entry + conf.env[static_env].append('%s' % entry.upper()) + decl_list = decl_list.rstrip() + conf.DEFINE('static_decl_%s' % p, decl_list) + conf.DEFINE('static_init_%s' % p, '{ %s_init(NULL); }' % '_init(NULL); '.join(static_list[p])) + else: + for entry in static_list[p]: + decl_list += "extern NTSTATUS %s_init(void); " % entry + conf.env[static_env].append('%s' % entry.upper()) + decl_list = decl_list.rstrip() + conf.DEFINE('static_decl_%s' % p, decl_list) + conf.DEFINE('static_init_%s' % p, '{ %s_init(); }' % '_init(); '.join(static_list[p])) else: conf.DEFINE('static_decl_%s' % p, '') conf.DEFINE('static_init_%s' % p, '{}') diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index 5d63670621..b8ed7ca3e1 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -1,7 +1,7 @@ -/* - Unix SMB/CIFS mplementation. +/* + Unix SMB/CIFS implementation. DSDB schema header - + Copyright (C) Stefan Metzmacher <metze@samba.org> 2006-2007 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2008 @@ -9,15 +9,15 @@ 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 <http://www.gnu.org/licenses/>. - + */ #include "includes.h" @@ -32,7 +32,7 @@ /* override the name to attribute handler function */ -const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, +const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, void *private_data, const char *name) { @@ -96,17 +96,20 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem for (attr = schema->attributes; attr; attr = attr->next) { const char *syntax = attr->syntax->ldb_syntax; - + if (!syntax) { syntax = attr->syntax->ldap_oid; } - /* Write out a rough approximation of the schema as an @ATTRIBUTES value, for bootstrapping */ + /* + * Write out a rough approximation of the schema + * as an @ATTRIBUTES value, for bootstrapping + */ if (strcmp(syntax, LDB_SYNTAX_INTEGER) == 0) { ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "INTEGER"); } else if (strcmp(syntax, LDB_SYNTAX_DIRECTORY_STRING) == 0) { ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "CASE_INSENSITIVE"); - } + } if (ret != LDB_SUCCESS) { break; } @@ -124,7 +127,10 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem return ret; } - /* Try to avoid churning the attributes too much - we only want to do this if they have changed */ + /* + * Try to avoid churning the attributes too much, + * we only want to do this if they have changed + */ ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL, NULL); if (ret == LDB_ERR_NO_SUCH_OBJECT) { @@ -136,8 +142,12 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem ret = LDB_SUCCESS; /* Annoyingly added to our search results */ ldb_msg_remove_attr(res->msgs[0], "distinguishedName"); - - mod_msg = ldb_msg_diff(ldb, res->msgs[0], msg); + + ret = ldb_msg_difference(ldb, mem_ctx, + res->msgs[0], msg, &mod_msg); + if (ret != LDB_SUCCESS) { + goto op_error; + } if (mod_msg->num_elements > 0) { ret = dsdb_replace(ldb, mod_msg, 0); } @@ -153,7 +163,7 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem return ret; } - /* Now write out the indexs, as found in the schema (if they have changed) */ + /* Now write out the indexes, as found in the schema (if they have changed) */ ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE, NULL, NULL); @@ -167,7 +177,11 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem /* Annoyingly added to our search results */ ldb_msg_remove_attr(res_idx->msgs[0], "distinguishedName"); - mod_msg = ldb_msg_diff(ldb, res_idx->msgs[0], msg_idx); + ret = ldb_msg_difference(ldb, mem_ctx, + res_idx->msgs[0], msg_idx, &mod_msg); + if (ret != LDB_SUCCESS) { + goto op_error; + } if (mod_msg->num_elements > 0) { ret = dsdb_replace(ldb, mod_msg, 0); } @@ -354,17 +368,16 @@ int dsdb_setup_schema_inversion(struct ldb_context *ldb, struct dsdb_schema *sch * order as an integer in the dsdb_class (for sorting * objectClass lists efficiently) */ - /* Walk the list of scheam classes */ - + /* Walk the list of schema classes */ + /* Create a 'total possible superiors' on each class */ return LDB_SUCCESS; } /** - * Attach the schema to an opaque pointer on the ldb, so ldb modules - * can find it + * Attach the schema to an opaque pointer on the ldb, + * so ldb modules can find it */ - int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) { struct dsdb_schema *old_schema; @@ -461,7 +474,7 @@ int dsdb_set_global_schema(struct ldb_context *ldb) /* Set the new attributes based on the new schema */ ret = dsdb_schema_set_attributes(ldb, global_schema, false /* Don't write attributes, it's expensive */); if (ret == LDB_SUCCESS) { - /* Keep a reference to this schema, just incase the original copy is replaced */ + /* Keep a reference to this schema, just in case the original copy is replaced */ if (talloc_reference(ldb, global_schema) == NULL) { return ldb_oom(ldb); } @@ -503,7 +516,10 @@ struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb, TALLOC_CTX *referen if (schema_in->refresh_fn && !schema_in->refresh_in_progress) { if (!talloc_reference(tmp_ctx, schema_in)) { - /* ensure that the schema_in->refresh_in_progress remains valid for the right amount of time */ + /* + * ensure that the schema_in->refresh_in_progress + * remains valid for the right amount of time + */ talloc_free(tmp_ctx); return NULL; } @@ -548,9 +564,11 @@ void dsdb_make_schema_global(struct ldb_context *ldb, struct dsdb_schema *schema dsdb_set_global_schema(ldb); } -/* When loading the schema from LDIF files, we don't get the extended DNs. - - We need to set these up, so that from the moment we start the provision, the defaultObjectCategory links are set up correctly. +/** + * When loading the schema from LDIF files, we don't get the extended DNs. + * + * We need to set these up, so that from the moment we start the provision, + * the defaultObjectCategory links are set up correctly. */ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *schema) { @@ -575,7 +593,7 @@ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *sc talloc_free(dn); return LDB_ERR_CONSTRAINT_VIOLATION; } - + status = GUID_to_ndr_blob(&target_class->objectGUID, dn, &guid); if (!NT_STATUS_IS_OK(status)) { talloc_free(dn); @@ -589,11 +607,11 @@ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *sc return LDB_SUCCESS; } -/** +/** * Add an element to the schema (attribute or class) from an LDB message */ -WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_schema *schema, - struct ldb_message *msg) +WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_schema *schema, + struct ldb_message *msg) { if (samdb_find_attribute(ldb, msg, "objectclass", "attributeSchema") != NULL) { @@ -649,11 +667,10 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const } talloc_steal(mem_ctx, ldif); - msg = ldb_msg_canonicalize(ldb, ldif->msg); - if (!msg) { + ret = ldb_msg_normalize(ldb, mem_ctx, ldif->msg, &msg); + if (ret != LDB_SUCCESS) { goto nomem; } - talloc_steal(mem_ctx, msg); talloc_free(ldif); prefix_val = ldb_msg_find_ldb_val(msg, "prefixMap"); @@ -675,14 +692,12 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const goto failed; } - /* - * load the attribute and class definitions outof df - */ + /* load the attribute and class definitions out of df */ while ((ldif = ldb_ldif_read_string(ldb, &df))) { talloc_steal(mem_ctx, ldif); - msg = ldb_msg_canonicalize(ldb, ldif->msg); - if (!msg) { + ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &msg); + if (ret != LDB_SUCCESS) { goto nomem; } diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 877f283491..3a0ca464a4 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -795,15 +795,17 @@ int ldb_request(struct ldb_context *ldb, struct ldb_request *req) ret = module->ops->search(module, req); break; case LDB_ADD: - /* we have to canonicalise here, as so many places + /* + * we have to normalize here, as so many places * in modules and backends assume we don't have two - * elements with the same name */ - req->op.add.message = ldb_msg_canonicalize(ldb, req->op.add.message); - if (!req->op.add.message) { + * elements with the same name + */ + ret = ldb_msg_normalize(ldb, req, req->op.add.message, + discard_const(&req->op.add.message)); + if (ret != LDB_SUCCESS) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } - talloc_steal(req, req->op.add.message); FIRST_OP(ldb, add); ret = module->ops->add(module, req); break; diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 4d0149af8f..8cf2584413 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -114,58 +114,94 @@ struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v) return v2; } -/* - add an empty element to a message -*/ -int ldb_msg_add_empty( struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el) +/** + * Adds new empty element to msg->elements + */ +static int _ldb_msg_add_el(struct ldb_message *msg, + struct ldb_message_element **return_el) { struct ldb_message_element *els; - els = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements+1); + /* + * TODO: Find out a way to assert on input parameters. + * msg and return_el must be valid + */ + + els = talloc_realloc(msg, msg->elements, + struct ldb_message_element, msg->num_elements + 1); if (!els) { errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } - els[msg->num_elements].values = NULL; - els[msg->num_elements].num_values = 0; - els[msg->num_elements].flags = flags; - els[msg->num_elements].name = talloc_strdup(els, attr_name); - if (!els[msg->num_elements].name) { - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } + ZERO_STRUCT(els[msg->num_elements]); msg->elements = els; msg->num_elements++; + *return_el = &els[msg->num_elements-1]; + + return LDB_SUCCESS; +} + +/** + * Add an empty element with a given name to a message + */ +int ldb_msg_add_empty(struct ldb_message *msg, + const char *attr_name, + int flags, + struct ldb_message_element **return_el) +{ + int ret; + struct ldb_message_element *el; + + ret = _ldb_msg_add_el(msg, &el); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* initialize newly added element */ + el->flags = flags; + el->name = talloc_strdup(msg->elements, attr_name); + if (!el->name) { + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + if (return_el) { - *return_el = &els[msg->num_elements-1]; + *return_el = el; } return LDB_SUCCESS; } -/* - add an empty element to a message -*/ +/** + * Adds an element to a message. + * + * NOTE: Ownership of ldb_message_element fields + * is NOT transferred. Thus, if *el pointer + * is invalidated for some reason, this will + * corrupt *msg contents also + */ int ldb_msg_add(struct ldb_message *msg, const struct ldb_message_element *el, int flags) { + int ret; + struct ldb_message_element *el_new; /* We have to copy this, just in case *el is a pointer into * what ldb_msg_add_empty() is about to realloc() */ struct ldb_message_element el_copy = *el; - if (ldb_msg_add_empty(msg, el->name, flags, NULL) != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + + ret = _ldb_msg_add_el(msg, &el_new); + if (ret != LDB_SUCCESS) { + return ret; } - msg->elements[msg->num_elements-1] = el_copy; - msg->elements[msg->num_elements-1].flags = flags; + el_new->flags = flags; + el_new->name = el_copy.name; + el_new->num_values = el_copy.num_values; + el_new->values = el_copy.values; return LDB_SUCCESS; } @@ -541,36 +577,64 @@ failed: } -/* - canonicalise a message, merging elements of the same name -*/ +/** + * Canonicalize a message, merging elements of the same name + */ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, const struct ldb_message *msg) { + int ret; + struct ldb_message *msg2; + + /* + * Preserve previous behavior and allocate + * *msg2 into *ldb context + */ + ret = ldb_msg_normalize(ldb, ldb, msg, &msg2); + if (ret != LDB_SUCCESS) { + return NULL; + } + + return msg2; +} + +/** + * Canonicalize a message, merging elements of the same name + */ +int ldb_msg_normalize(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + struct ldb_message **_msg_out) +{ unsigned int i; struct ldb_message *msg2; - msg2 = ldb_msg_copy(ldb, msg); - if (msg2 == NULL) return NULL; + msg2 = ldb_msg_copy(mem_ctx, msg); + if (msg2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } ldb_msg_sort_elements(msg2); - for (i=1;i<msg2->num_elements;i++) { + for (i=1; i < msg2->num_elements; i++) { struct ldb_message_element *el1 = &msg2->elements[i-1]; struct ldb_message_element *el2 = &msg2->elements[i]; + if (ldb_msg_element_compare_name(el1, el2) == 0) { - el1->values = talloc_realloc(msg2->elements, el1->values, struct ldb_val, - el1->num_values + el2->num_values); + el1->values = talloc_realloc(msg2->elements, + el1->values, struct ldb_val, + el1->num_values + el2->num_values); if (el1->num_values + el2->num_values > 0 && el1->values == NULL) { - return NULL; + talloc_free(msg2); + return LDB_ERR_OPERATIONS_ERROR; } memcpy(el1->values + el1->num_values, el2->values, sizeof(struct ldb_val) * el2->num_values); el1->num_values += el2->num_values; talloc_free(discard_const_p(char, el2->name)); - if (i+1<msg2->num_elements) { - memmove(el2, el2+1, sizeof(struct ldb_message_element) * + if ((i+1) < msg2->num_elements) { + memmove(el2, el2+1, sizeof(struct ldb_message_element) * (msg2->num_elements - (i+1))); } msg2->num_elements--; @@ -578,39 +642,81 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, } } - return msg2; + *_msg_out = msg2; + return LDB_SUCCESS; } -/* - return a ldb_message representing the differences between msg1 and msg2. If you - then use this in a ldb_modify() call it can be used to save edits to a message -*/ +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call, + * it can be used to save edits to a message + */ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, struct ldb_message *msg1, struct ldb_message *msg2) { + int ldb_ret; struct ldb_message *mod; - struct ldb_message_element *el; + + ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod); + if (ldb_ret != LDB_SUCCESS) { + return NULL; + } + + return mod; +} + +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call it can be used to save edits to a message + * + * Result message is constructed as follows: + * - LDB_FLAG_MOD_ADD - elements found only in msg2 + * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 + * Value for msg2 element is used + * - LDB_FLAG_MOD_DELETE - elements found only in msg2 + * + * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR + */ +int ldb_msg_difference(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg1, + struct ldb_message *msg2, + struct ldb_message **_msg_out) +{ + int ldb_res; unsigned int i; + struct ldb_message *mod; + struct ldb_message_element *el; + TALLOC_CTX *temp_ctx; - mod = ldb_msg_new(ldb); + temp_ctx = talloc_new(mem_ctx); + if (!temp_ctx) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = ldb_msg_new(temp_ctx); if (mod == NULL) { - return NULL; + goto failed; } mod->dn = msg1->dn; mod->num_elements = 0; mod->elements = NULL; - msg2 = ldb_msg_canonicalize(ldb, msg2); - if (msg2 == NULL) { - talloc_free(mod); - return NULL; + /* + * Canonicalize *msg2 so we have no repeated elements + * Resulting message is allocated in *mod's mem context, + * as we are going to move some elements from *msg2 to + * *mod object later + */ + ldb_res = ldb_msg_normalize(ldb, mod, msg2, &msg2); + if (ldb_res != LDB_SUCCESS) { + goto failed; } - - /* look in msg2 to find elements that need to be added - or modified */ + + /* look in msg2 to find elements that need to be added or modified */ for (i=0;i<msg2->num_elements;i++) { el = ldb_msg_find_element(msg1, msg2->elements[i].name); @@ -618,11 +724,11 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, continue; } - if (ldb_msg_add(mod, - &msg2->elements[i], - el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != LDB_SUCCESS) { - talloc_free(mod); - return NULL; + ldb_res = ldb_msg_add(mod, + &msg2->elements[i], + el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD); + if (ldb_res != LDB_SUCCESS) { + goto failed; } } @@ -630,18 +736,28 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, for (i=0;i<msg1->num_elements;i++) { el = ldb_msg_find_element(msg2, msg1->elements[i].name); if (el == NULL) { - if (ldb_msg_add_empty(mod, - msg1->elements[i].name, - LDB_FLAG_MOD_DELETE, NULL) != LDB_SUCCESS) { - talloc_free(mod); - return NULL; + ldb_res = ldb_msg_add_empty(mod, + msg1->elements[i].name, + LDB_FLAG_MOD_DELETE, NULL); + if (ldb_res != LDB_SUCCESS) { + goto failed; } } } - return mod; + /* steal resulting message into supplied context */ + talloc_steal(mem_ctx, mod); + *_msg_out = mod; + + talloc_free(temp_ctx); + return LDB_SUCCESS; + +failed: + talloc_free(temp_ctx); + return LDB_ERR_OPERATIONS_ERROR; } + int ldb_msg_sanity_check(struct ldb_context *ldb, const struct ldb_message *msg) { diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 039f70895a..b3d874e36f 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -86,6 +86,14 @@ struct ldb_val { #ifndef PRINTF_ATTRIBUTE #define PRINTF_ATTRIBUTE(a,b) #endif + +#ifndef _DEPRECATED_ +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif /*! \endcond */ /* opaque ldb_dn structures, see ldb_dn.c for internals */ @@ -1851,13 +1859,56 @@ struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, const struct ldb_message *msg); +/* + * ldb_msg_canonicalize() is now depreciated + * Please use ldb_msg_normalize() instead + * + * NOTE: Returned ldb_message object is allocated + * into *ldb's context. Callers are recommended + * to steal the returned object into a TALLOC_CTX + * with short lifetime. + */ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, - const struct ldb_message *msg); + const struct ldb_message *msg) _DEPRECATED_; + +int ldb_msg_normalize(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + struct ldb_message **_msg_out); +/* + * ldb_msg_diff() is now depreciated + * Please use ldb_msg_difference() instead + * + * NOTE: Returned ldb_message object is allocated + * into *ldb's context. Callers are recommended + * to steal the returned object into a TALLOC_CTX + * with short lifetime. + */ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, struct ldb_message *msg1, - struct ldb_message *msg2); + struct ldb_message *msg2) _DEPRECATED_; + +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call, + * it can be used to save edits to a message + * + * Result message is constructed as follows: + * - LDB_FLAG_MOD_ADD - elements found only in msg2 + * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have + * different value in msg1 + * Value for msg2 element is used + * - LDB_FLAG_MOD_DELETE - elements found only in msg2 + * + * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR + */ +int ldb_msg_difference(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg1, + struct ldb_message *msg2, + struct ldb_message **_msg_out); /** Tries to find a certain string attribute in a message diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c index 12af9c5450..2225327bbe 100644 --- a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c +++ b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c @@ -687,14 +687,21 @@ static int lsqlite3_search_callback(void *result, int col_num, char **cols, char /* call the async callback for the last entry * except the first time */ if (ac->current_eid != 0) { - msg = ldb_msg_canonicalize(ldb, msg); - if (!msg) return SQLITE_ABORT; + ret = ldb_msg_normalize(ldb, ac->req, msg, &msg); + if (ret != LDB_SUCCESS) { + return SQLITE_ABORT; + } ret = ldb_module_send_entry(ac->req, msg, NULL); if (ret != LDB_SUCCESS) { ac->callback_failed = true; + /* free msg object */ + TALLOC_FREE(msg); return SQLITE_ABORT; } + + /* free msg object */ + TALLOC_FREE(msg); } /* start over */ @@ -960,8 +967,10 @@ int lsql_search(struct lsql_context *ctx) /* complete the last message if any */ if (ctx->ares) { - ctx->ares->message = ldb_msg_canonicalize(ldb, ctx->ares->message); - if (ctx->ares->message == NULL) { + ret = ldb_msg_normalize(ldb, ctx->ares, + ctx->ares->message, + &ctx->ares->message); + if (ret != LDB_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index f27ab3dd95..19123c3c24 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -1035,9 +1035,11 @@ static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args) static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) { + int ldb_ret; PyObject *py_msg_old; PyObject *py_msg_new; struct ldb_message *diff; + struct ldb_context *ldb; PyObject *py_ret; if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new)) @@ -1053,14 +1055,20 @@ static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) return NULL; } - diff = ldb_msg_diff(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg_old), PyLdbMessage_AsMessage(py_msg_new)); - if (!diff) { + ldb = PyLdb_AsLdbContext(self); + ldb_ret = ldb_msg_difference(ldb, ldb, + PyLdbMessage_AsMessage(py_msg_old), + PyLdbMessage_AsMessage(py_msg_new), + &diff); + if (ldb_ret != LDB_SUCCESS) { PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff"); return NULL; } py_ret = PyLdbMessage_FromMessage(diff); + talloc_unlink(ldb, diff); + return py_ret; } diff --git a/source4/lib/ldb/tools/ldbadd.c b/source4/lib/ldb/tools/ldbadd.c index e057b873a8..42470656fb 100644 --- a/source4/lib/ldb/tools/ldbadd.c +++ b/source4/lib/ldb/tools/ldbadd.c @@ -1,4 +1,4 @@ -/* +/* ldb database library Copyright (C) Andrew Tridgell 2004 @@ -6,7 +6,7 @@ ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released ** under the LGPL - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -40,7 +40,7 @@ static struct ldb_cmdline *options; static void usage(void) { - printf("Usage: ldbadd <options> <ldif...>\n"); + printf("Usage: ldbadd <options> <ldif...>\n"); printf("Adds records to a ldb, reading ldif the specified list of files\n\n"); ldb_cmdline_help("ldbadd", stdout); exit(1); @@ -68,7 +68,15 @@ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) break; } - ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg); + ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg); + if (ret != LDB_SUCCESS) { + fprintf(stderr, + "ERR: Message canonicalize failed - %s\n", + ldb_strerror(ret)); + failures++; + ldb_ldif_read_free(ldb, ldif); + continue; + } ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); if (ret != LDB_SUCCESS) { @@ -134,6 +142,6 @@ int main(int argc, const char **argv) talloc_free(mem_ctx); printf("Added %d records with %d failures\n", count, failures); - + return ret; } diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index f28964b06a..4deeb30ee9 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -1,4 +1,4 @@ -/* +/* ldb database library Copyright (C) Andrew Tridgell 2004 @@ -6,7 +6,7 @@ ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released ** under the LGPL - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -45,10 +45,10 @@ static struct ldb_cmdline *options; /* - debug routine + debug routine */ -static void ldif_write_msg(struct ldb_context *ldb, - FILE *f, +static void ldif_write_msg(struct ldb_context *ldb, + FILE *f, enum ldb_changetype changetype, struct ldb_message *msg) { @@ -62,21 +62,22 @@ static void ldif_write_msg(struct ldb_context *ldb, modify a database record so msg1 becomes msg2 returns the number of modified elements */ -static int modify_record(struct ldb_context *ldb, +static int modify_record(struct ldb_context *ldb, struct ldb_message *msg1, struct ldb_message *msg2, struct ldb_control **req_ctrls) { + int ret; struct ldb_message *mod; - mod = ldb_msg_diff(ldb, msg1, msg2); - if (mod == NULL) { + if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) { fprintf(stderr, "Failed to calculate message differences\n"); return -1; } - if (mod->num_elements == 0) { - return 0; + ret = mod->num_elements; + if (ret == 0) { + goto done; } if (options->verbose > 0) { @@ -84,12 +85,15 @@ static int modify_record(struct ldb_context *ldb, } if (ldb_modify_ctrl(ldb, mod, req_ctrls) != 0) { - fprintf(stderr, "failed to modify %s - %s\n", + fprintf(stderr, "failed to modify %s - %s\n", ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb)); - return -1; + ret = -1; + goto done; } - return mod->num_elements; +done: + talloc_free(mod); + return ret; } /* @@ -184,7 +188,7 @@ static int merge_edits(struct ldb_context *ldb, /* save a set of messages as ldif to a file */ -static int save_ldif(struct ldb_context *ldb, +static int save_ldif(struct ldb_context *ldb, FILE *f, struct ldb_message **msgs, unsigned int count) { unsigned int i; @@ -305,7 +309,7 @@ int main(int argc, const char **argv) options = ldb_cmdline_process(ldb, argc, argv, usage); /* the check for '=' is for compatibility with ldapsearch */ - if (options->argc > 0 && + if (options->argc > 0 && strchr(options->argv[0], '=')) { expression = options->argv[0]; options->argv++; diff --git a/source4/librpc/gen_ndr/README b/source4/librpc/gen_ndr/README index 0c1fd160a5..5ccb89db5d 100644 --- a/source4/librpc/gen_ndr/README +++ b/source4/librpc/gen_ndr/README @@ -1 +1,4 @@ This contains the generated files from PIDL for the IDL files in ../idl/*.idl + +DO NOT REMOVE THIS FILE. The waf 1.5 build relies on this directory +existing in the source tree. diff --git a/source4/torture/rpc/dssync.c b/source4/torture/rpc/dssync.c index 5e5929f734..860c3ebfcf 100644 --- a/source4/torture/rpc/dssync.c +++ b/source4/torture/rpc/dssync.c @@ -538,8 +538,10 @@ static bool test_analyse_objects(struct torture_context *tctx, } } - drs_msg = ldb_msg_canonicalize(ldb, objs->objects[i].msg); - talloc_steal(search_req, drs_msg); + ret = ldb_msg_normalize(ldb, search_req, + objs->objects[i].msg, &drs_msg); + torture_assert(tctx, ret == LDB_SUCCESS, + "ldb_msg_normalize() has failed"); for (j=0; j < drs_msg->num_elements; j++) { if (drs_msg->elements[j].num_values == 0) { @@ -575,8 +577,9 @@ static bool test_analyse_objects(struct torture_context *tctx, } - new_msg = ldb_msg_diff(ldb, drs_msg, ldap_msg); - talloc_steal(search_req, new_msg); + ret = ldb_msg_difference(ldb, search_req, + drs_msg, ldap_msg, &new_msg); + torture_assert(tctx, ret == LDB_SUCCESS, "ldb_msg_difference() has failed"); if (new_msg->num_elements != 0) { char *s; struct ldb_ldif ldif; @@ -585,7 +588,9 @@ static bool test_analyse_objects(struct torture_context *tctx, s = ldb_ldif_write_string(ldb, new_msg, &ldif); s = talloc_asprintf(tctx, "\n# Difference in between DRS and LDAP objects: \n%s\n", s); - ldif.msg = ldb_msg_diff(ldb, ldap_msg, drs_msg); + ret = ldb_msg_difference(ldb, search_req, + ldap_msg, drs_msg, &ldif.msg); + torture_assert(tctx, ret == LDB_SUCCESS, "ldb_msg_difference() has failed"); s = talloc_asprintf_append(s, "\n# Difference in between LDAP and DRS objects: \n%s\n", ldb_ldif_write_string(ldb, new_msg, &ldif)); |